diff --git a/README.md b/README.md index 23b717fb65..bd70580d8c 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ These projects push the boundaries of MobilityDB and connect it with the Postgre * [MobilityDB-AWS](https://github.com/MobilityDB/MobilityDB-AWS): MobilityDB on Amazon Web Services * [MobilityDB-Azure](https://github.com/MobilityDB/MobilityDB-Azure): MobilityDB on Azure +* [MobilityDB-GCP](https://github.com/MobilityDB/MobilityDB-GCP): MobilityDB on Google Cloud Platform ### Visualization diff --git a/meos/CMakeLists.txt b/meos/CMakeLists.txt index 4123ad651a..8d9ac3d5a8 100644 --- a/meos/CMakeLists.txt +++ b/meos/CMakeLists.txt @@ -131,7 +131,6 @@ set(PROJECT_OBJECTS "$") set(PROJECT_OBJECTS ${PROJECT_OBJECTS} "$") if(MEOS) set(PROJECT_OBJECTS ${PROJECT_OBJECTS} "$") - set(PROJECT_OBJECTS ${PROJECT_OBJECTS} "$") endif() if(NPOINT) message(STATUS "Including network points") diff --git a/meos/examples/01_meos_hello_world.c b/meos/examples/01_meos_hello_world.c index 524fd01313..17970bc262 100644 --- a/meos/examples/01_meos_hello_world.c +++ b/meos/examples/01_meos_hello_world.c @@ -37,7 +37,7 @@ * @endcode */ -#include /* for printf */ +#include /* for printf */ #include /* for free */ /* Include the MEOS API header */ #include @@ -45,7 +45,7 @@ int main() { /* Initialize MEOS */ - meos_initialize(NULL); + meos_initialize(NULL, NULL); /* Input temporal points in WKT format */ char *inst_wkt = "POINT(1 1)@2000-01-01"; diff --git a/meos/examples/02_meos_read_ais.c b/meos/examples/02_meos_read_ais.c index 462cbc084e..0bd45b9320 100644 --- a/meos/examples/02_meos_read_ais.c +++ b/meos/examples/02_meos_read_ais.c @@ -67,7 +67,7 @@ typedef struct int main(void) { /* Initialize MEOS */ - meos_initialize('UTC'); + meos_initialize('UTC', NULL); /* You may substitute the full file path in the first argument of fopen */ FILE *file = fopen("aisinput.csv", "r"); diff --git a/meos/examples/03_meos_assemble_ais.c b/meos/examples/03_meos_assemble_ais.c index 72f242cda5..1c9f4fb8a7 100644 --- a/meos/examples/03_meos_assemble_ais.c +++ b/meos/examples/03_meos_assemble_ais.c @@ -87,7 +87,7 @@ typedef struct int main(void) { /* Initialize MEOS */ - meos_initialize("UTC"); + meos_initialize("UTC", NULL); /* Get start time */ clock_t t; diff --git a/meos/examples/03_meos_assemble_berlinmod.c b/meos/examples/03_meos_assemble_berlinmod.c index 9c7ccb16fc..c8463b6877 100644 --- a/meos/examples/03_meos_assemble_berlinmod.c +++ b/meos/examples/03_meos_assemble_berlinmod.c @@ -99,7 +99,7 @@ typedef struct int main(void) { /* Initialize MEOS */ - meos_initialize(NULL); + meos_initialize(NULL, NULL); /* Get start time */ clock_t t; @@ -151,7 +151,7 @@ int main(void) /* Transform the string representing the timestamp into a timestamp value */ rec.t = pg_timestamp_in(timestamp_buffer, -1); /* Transform the string representing the trip into a temporal value */ - TInstant *inst = tgeompointinst_make(rec.point, rec.t); + TInstant *inst = tpointinst_make(rec.point, rec.t); if (read == 6) { diff --git a/meos/examples/04_meos_store_ais.c b/meos/examples/04_meos_store_ais.c index cae0a213f1..787a3d2c38 100644 --- a/meos/examples/04_meos_store_ais.c +++ b/meos/examples/04_meos_store_ais.c @@ -150,7 +150,7 @@ main(int argc, char **argv) ***************************************************************************/ /* Initialize MEOS */ - meos_initialize(NULL); + meos_initialize(NULL, NULL); /* You may substitute the full file path in the first argument of fopen */ FILE *file = fopen("aisinput.csv", "r"); diff --git a/meos/examples/04_meos_stream_ais.c b/meos/examples/04_meos_stream_ais.c index b1711fa9aa..577684a267 100644 --- a/meos/examples/04_meos_stream_ais.c +++ b/meos/examples/04_meos_stream_ais.c @@ -226,7 +226,7 @@ main(int argc, char **argv) ***************************************************************************/ /* Initialize MEOS */ - meos_initialize(NULL); + meos_initialize(NULL, NULL); /* You may substitute the full file path in the first argument of fopen */ FILE *file = fopen("aisinput.csv", "r"); diff --git a/meos/examples/04_meos_stream_file_ais.c b/meos/examples/04_meos_stream_file_ais.c index aa0e3086ec..38fe4659b2 100644 --- a/meos/examples/04_meos_stream_file_ais.c +++ b/meos/examples/04_meos_stream_file_ais.c @@ -143,7 +143,7 @@ main(int argc, char **argv) ***************************************************************************/ /* Initialize MEOS */ - meos_initialize(NULL); + meos_initialize(NULL, NULL); /* You may substitute the full file path in the first argument of fopen */ FILE *fileIn = fopen("aisinput.csv", "r"); diff --git a/meos/examples/05_meos_disassemble_berlinmod.c b/meos/examples/05_meos_disassemble_berlinmod.c index e7c22d806e..22410070ae 100644 --- a/meos/examples/05_meos_disassemble_berlinmod.c +++ b/meos/examples/05_meos_disassemble_berlinmod.c @@ -88,7 +88,7 @@ int main(void) int curr_inst[MAX_NO_TRIPS]; /* Initialize MEOS */ - meos_initialize(NULL); + meos_initialize(NULL, NULL); /* You may substitute the full file path in the first argument of fopen */ FILE *file = fopen("trips.csv", "r"); diff --git a/meos/examples/06_meos_clip_berlinmod.c b/meos/examples/06_meos_clip_berlinmod.c index 61c4c8a1bc..12972fae80 100644 --- a/meos/examples/06_meos_clip_berlinmod.c +++ b/meos/examples/06_meos_clip_berlinmod.c @@ -289,7 +289,7 @@ matrix_print(double distance[NO_VEHICLES + 1][NO_COMMUNES + 3], int main(void) { /* Initialize MEOS */ - meos_initialize(NULL); + meos_initialize(NULL, NULL); /* Read communes file */ read_communes(); diff --git a/meos/examples/07_meos_tile_berlinmod.c b/meos/examples/07_meos_tile_berlinmod.c index cb0ca695b7..8ca5315a69 100644 --- a/meos/examples/07_meos_tile_berlinmod.c +++ b/meos/examples/07_meos_tile_berlinmod.c @@ -88,7 +88,7 @@ int main(void) int i, j, k; /* Initialize MEOS */ - meos_initialize(NULL); + meos_initialize(NULL, NULL); /* Compute the spatial tiles for trips */ int no_rows, no_cols, *no_cells; diff --git a/meos/examples/08_meos_simplify_berlinmod.c b/meos/examples/08_meos_simplify_berlinmod.c index 11e259eac8..f250003f10 100644 --- a/meos/examples/08_meos_simplify_berlinmod.c +++ b/meos/examples/08_meos_simplify_berlinmod.c @@ -87,7 +87,7 @@ int main(void) int i = 0, j; /* Initialize MEOS */ - meos_initialize(NULL); + meos_initialize(NULL, NULL); /* Substitute the full file path in the first argument of fopen */ FILE *file = fopen("trips.csv", "r"); diff --git a/meos/examples/09_meos_aggregate_berlinmod.c b/meos/examples/09_meos_aggregate_berlinmod.c index 95a34c7f7e..ba2efe52d0 100644 --- a/meos/examples/09_meos_aggregate_berlinmod.c +++ b/meos/examples/09_meos_aggregate_berlinmod.c @@ -74,7 +74,7 @@ int main(void) char trip_buffer[MAX_LENGTH_TRIP]; /* Initialize MEOS */ - meos_initialize(NULL); + meos_initialize(NULL, NULL); /* You may substitute the full file path in the first argument of fopen */ FILE *file = fopen("trips.csv", "r"); diff --git a/meos/examples/meos_assemble_ais_full.c b/meos/examples/meos_assemble_ais_full.c index ff7389260b..90aee6cf66 100644 --- a/meos/examples/meos_assemble_ais_full.c +++ b/meos/examples/meos_assemble_ais_full.c @@ -118,7 +118,7 @@ typedef struct int main(void) { /* Initialize MEOS */ - meos_initialize("UTC"); + meos_initialize("UTC", NULL); /* Get start time */ clock_t t; diff --git a/meos/examples/meos_assemble_tfloat.c b/meos/examples/meos_assemble_tfloat.c index 7219dfabe6..945b1b3193 100644 --- a/meos/examples/meos_assemble_tfloat.c +++ b/meos/examples/meos_assemble_tfloat.c @@ -56,7 +56,7 @@ int main(void) { /* Initialize MEOS */ - meos_initialize(NULL); + meos_initialize(NULL, NULL); /* Get start time */ clock_t tm; diff --git a/meos/examples/meos_assemble_tpoint.c b/meos/examples/meos_assemble_tpoint.c index 48546fdcfc..5342abd981 100644 --- a/meos/examples/meos_assemble_tpoint.c +++ b/meos/examples/meos_assemble_tpoint.c @@ -61,7 +61,7 @@ int main(void) { /* Initialize MEOS */ - meos_initialize(NULL); + meos_initialize(NULL, NULL); /* Get start time */ clock_t time; diff --git a/meos/examples/meos_assemble_ttext.c b/meos/examples/meos_assemble_ttext.c index e77284f01d..6e58c60727 100644 --- a/meos/examples/meos_assemble_ttext.c +++ b/meos/examples/meos_assemble_ttext.c @@ -61,7 +61,7 @@ int main(void) { /* Initialize MEOS */ - meos_initialize(NULL); + meos_initialize(NULL, NULL); /* Get start time */ clock_t tm; diff --git a/meos/examples/meos_expand_ais.c b/meos/examples/meos_expand_ais.c index 8e7d8a9ff2..ec6977001b 100644 --- a/meos/examples/meos_expand_ais.c +++ b/meos/examples/meos_expand_ais.c @@ -80,7 +80,7 @@ typedef struct int main(void) { /* Initialize MEOS */ - meos_initialize("UTC"); + meos_initialize("UTC", NULL); /* Get start time */ clock_t t; diff --git a/meos/examples/meos_expand_floatspanset.c b/meos/examples/meos_expand_floatspanset.c index 45785fc08a..bbda15cc6b 100644 --- a/meos/examples/meos_expand_floatspanset.c +++ b/meos/examples/meos_expand_floatspanset.c @@ -68,7 +68,7 @@ typedef struct int main(void) { /* Initialize MEOS */ - meos_initialize(""); + meos_initialize("", NULL); /* Get start time */ clock_t t; diff --git a/meos/examples/meos_expand_intspan.c b/meos/examples/meos_expand_intspan.c index 5cbc02b0b9..03521d63d5 100644 --- a/meos/examples/meos_expand_intspan.c +++ b/meos/examples/meos_expand_intspan.c @@ -66,7 +66,7 @@ typedef struct int main(void) { /* Initialize MEOS */ - meos_initialize(""); + meos_initialize("", NULL); /* Get start time */ clock_t t; diff --git a/meos/examples/meos_expand_textset.c b/meos/examples/meos_expand_textset.c index 45fb3723e6..809513fab1 100644 --- a/meos/examples/meos_expand_textset.c +++ b/meos/examples/meos_expand_textset.c @@ -66,7 +66,7 @@ typedef struct int main(void) { /* Initialize MEOS */ - meos_initialize(""); + meos_initialize("", NULL); /* Get start time */ clock_t t; diff --git a/meos/examples/meos_expand_tfloat.c b/meos/examples/meos_expand_tfloat.c index 4569f28acc..2c41d72b83 100644 --- a/meos/examples/meos_expand_tfloat.c +++ b/meos/examples/meos_expand_tfloat.c @@ -57,7 +57,7 @@ int main(void) { /* Initialize MEOS */ - meos_initialize(NULL); + meos_initialize(NULL, NULL); /* Get start time */ clock_t tm; diff --git a/meos/examples/meos_expand_tpoint.c b/meos/examples/meos_expand_tpoint.c index d890ade7fb..182e042fc3 100644 --- a/meos/examples/meos_expand_tpoint.c +++ b/meos/examples/meos_expand_tpoint.c @@ -70,7 +70,7 @@ int main(void) { /* Initialize MEOS */ - meos_initialize(NULL); + meos_initialize(NULL, NULL); /* Get start time */ clock_t time; diff --git a/meos/examples/meos_expand_ttext.c b/meos/examples/meos_expand_ttext.c index 696ead5e25..90376eac07 100644 --- a/meos/examples/meos_expand_ttext.c +++ b/meos/examples/meos_expand_ttext.c @@ -67,7 +67,7 @@ int main(void) { /* Initialize MEOS */ - meos_initialize(NULL); + meos_initialize(NULL, NULL); /* Get start time */ clock_t tm; diff --git a/meos/examples/meos_geos_clip.c b/meos/examples/meos_geos_clip.c index caa53079e4..16011ff4f6 100644 --- a/meos/examples/meos_geos_clip.c +++ b/meos/examples/meos_geos_clip.c @@ -33,16 +33,16 @@ static void geos_message_handler(const char* fmt, ...) { - va_list ap; - va_start(ap, fmt); - vprintf (fmt, ap); - va_end(ap); + va_list ap; + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); } int main() { /* Initialize MEOS */ - meos_initialize(NULL); + meos_initialize(NULL, NULL); /* Send notice and error messages to our stdout handler */ initGEOS(geos_message_handler, geos_message_handler); diff --git a/meos/examples/meos_gserialized_inout.c b/meos/examples/meos_gserialized_inout.c index ea723bd911..3b28b89629 100644 --- a/meos/examples/meos_gserialized_inout.c +++ b/meos/examples/meos_gserialized_inout.c @@ -44,7 +44,7 @@ int main() { /* Initialize MEOS */ - meos_initialize(); + meos_initialize(NULL, NULL); /* Input geometries in WKT format */ char *point_wkt = "POINT(1 1)"; @@ -104,9 +104,9 @@ int main() char *polygon_hexwkb = gserialized_as_hexwkb(polygon, "XDR"); /* Revert generated GeoJSON strings into geometries */ - GSERIALIZED *point3 = gserialized_from_hexewkb(point_hexwkb); - GSERIALIZED *linestring3 = gserialized_from_hexewkb(linestring_hexwkb); - GSERIALIZED *polygon3 = gserialized_from_hexewkb(polygon_hexwkb); + GSERIALIZED *point3 = geometry_from_hexewkb(point_hexwkb); + GSERIALIZED *linestring3 = geometry_from_hexewkb(linestring_hexwkb); + GSERIALIZED *polygon3 = geometry_from_hexewkb(polygon_hexwkb); /* Ensure that the reverted types are equal to the original ones */ if (! pgis_gserialized_same(point, point3)) diff --git a/meos/examples/meos_tpointseq_make.c b/meos/examples/meos_tpointseq_make.c index 6e002926e8..12e4376034 100644 --- a/meos/examples/meos_tpointseq_make.c +++ b/meos/examples/meos_tpointseq_make.c @@ -54,7 +54,7 @@ int main() TimestampTz times[MAX_COUNT]; /* Initialize MEOS */ - meos_initialize(); + meos_initialize(NULL, NULL); for (int i = 0; i < 4; i++) times[i] = pg_timestamptz_in(times_str[i], -1); diff --git a/meos/include/general/error.h b/meos/include/general/error.h new file mode 100644 index 0000000000..75e3f7fcf0 --- /dev/null +++ b/meos/include/general/error.h @@ -0,0 +1,77 @@ +/***************************************************************************** + * + * This MobilityDB code is provided under The PostgreSQL License. + * Copyright (c) 2016-2023, Université libre de Bruxelles and MobilityDB + * contributors + * + * MobilityDB includes portions of PostGIS version 3 source code released + * under the GNU General Public License (GPLv2 or later). + * Copyright (c) 2001-2023, PostGIS contributors + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without a written + * agreement is hereby granted, provided that the above copyright notice and + * this paragraph and the following two paragraphs appear in all copies. + * + * IN NO EVENT SHALL UNIVERSITE LIBRE DE BRUXELLES BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING + * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, + * EVEN IF UNIVERSITE LIBRE DE BRUXELLES HAS BEEN ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * UNIVERSITE LIBRE DE BRUXELLES SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON + * AN "AS IS" BASIS, AND UNIVERSITE LIBRE DE BRUXELLES HAS NO OBLIGATIONS TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + *****************************************************************************/ + +/** + * @file + * @brief Error handling. + */ + +/* C */ +#include +/* MEOS */ +#include + +typedef enum +{ + MEOS_SUCCESS = 0, // Successful operation + + MEOS_ERR_INTERNAL_ERROR = 1, // Unspecified internal error + MEOS_ERR_INTERNAL_TYPE_ERROR = 2, // Internal type error + MEOS_ERR_VALUE_OUT_OF_RANGE = 3, // Internal out of range error + MEOS_ERR_DIVISION_BY_ZERO = 4, // Internal division by zero error + MEOS_ERR_MEMORY_ALLOC_ERROR = 5, // Internal malloc error + MEOS_ERR_AGGREGATION_ERROR = 6, // Internal aggregation error + MEOS_ERR_DIRECTORY_ERROR = 7, // Internal directory error + MEOS_ERR_FILE_ERROR = 8, // Internal file error + + MEOS_ERR_INVALID_ARG = 10, // Invalid argument + MEOS_ERR_INVALID_ARG_TYPE = 11, // Invalid argument type + MEOS_ERR_INVALID_ARG_VALUE = 12, // Invalid argument value + + MEOS_ERR_MFJSON_INPUT = 20, // MFJSON input error + MEOS_ERR_MFJSON_OUTPUT = 21, // MFJSON output error + MEOS_ERR_TEXT_INPUT = 22, // Text input error + MEOS_ERR_TEXT_OUTPUT = 23, // Text output error + MEOS_ERR_WKB_INPUT = 24, // WKB input error + MEOS_ERR_WKB_OUTPUT = 25, // WKB output error + MEOS_ERR_GEOJSON_INPUT = 26, // GEOJSON input error + MEOS_ERR_GEOJSON_OUTPUT = 27, // GEOJSON output error + +} errorCode; + +extern void meos_error(int errlevel, int errcode, char *format, ...); + +/* Set or read error level */ + +extern int mobdb_errno(void); +extern int mobdb_errno_set(int err); +extern int mobdb_errno_restore(int err); +extern int mobdb_errno_reset(void); + +/*****************************************************************************/ \ No newline at end of file diff --git a/meos/include/general/meos_catalog.h b/meos/include/general/meos_catalog.h index 194837566b..3866d01249 100644 --- a/meos/include/general/meos_catalog.h +++ b/meos/include/general/meos_catalog.h @@ -218,12 +218,12 @@ extern bool set_type(meosType type); extern bool numset_type(meosType type); extern bool timeset_type(meosType type); extern bool set_spantype(meosType type); -extern void ensure_set_spantype(meosType type); +extern bool ensure_set_spantype(meosType type); extern bool alphanumset_type(meosType settype); extern bool geoset_type(meosType type); -extern void ensure_geoset_type(meosType type); +extern bool ensure_geoset_type(meosType type); extern bool spatialset_type(meosType type); -extern void ensure_spatialset_type(meosType type); +extern bool ensure_spatialset_type(meosType type); extern bool span_basetype(meosType type); extern bool span_canon_basetype(meosType type); @@ -231,7 +231,7 @@ extern bool span_type(meosType type); extern bool span_bbox_type(meosType type); extern bool numspan_basetype(meosType type); extern bool numspan_type(meosType type); -extern void ensure_numspan_type(meosType type); +extern bool ensure_numspan_type(meosType type); extern bool timespan_basetype(meosType type); extern bool timespan_type(meosType type); @@ -248,15 +248,17 @@ extern int16 basetype_length(meosType basetype); extern bool talphanum_type(meosType type); extern bool talpha_type(meosType temptype); extern bool tnumber_type(meosType temptype); -extern void ensure_tnumber_type(meosType temptype); +extern bool ensure_tnumber_type(meosType temptype); extern bool tnumber_basetype(meosType basetype); extern bool tnumber_settype(meosType settype); extern bool tnumber_spantype(meosType settype); extern bool tnumber_spansettype(meosType spansettype); extern bool tspatial_type(meosType temptype); +extern bool ensure_tspatial_type(meosType temptype); extern bool tspatial_basetype(meosType basetype); extern bool tgeo_type(meosType type); -extern void ensure_tgeo_type(meosType type); +extern bool ensure_tgeo_type(meosType type); +extern bool ensure_tnumber_tgeo_type(meosType type); /*****************************************************************************/ diff --git a/meos/include/general/set.h b/meos/include/general/set.h index 14ec6a15ec..3300aaf7b1 100644 --- a/meos/include/general/set.h +++ b/meos/include/general/set.h @@ -80,9 +80,9 @@ typedef struct /* General functions */ -extern void ensure_set_has_type(const Set *s, meosType settype); -extern void ensure_same_set_type(const Set *s1, const Set *s2); -extern void ensure_same_set_basetype(const Set *s, meosType basetype); +extern bool ensure_set_has_type(const Set *s, meosType settype); +extern bool ensure_same_set_type(const Set *s1, const Set *s2); +extern bool ensure_same_set_basetype(const Set *s, meosType basetype); extern bool set_find_value(const Set *s, Datum, int *loc); /*****************************************************************************/ diff --git a/meos/include/general/span.h b/meos/include/general/span.h index fa766e8ac8..a5a75e7cee 100644 --- a/meos/include/general/span.h +++ b/meos/include/general/span.h @@ -77,9 +77,9 @@ typedef struct /* General functions */ -extern void ensure_span_has_type(const Span *s, meosType spantype); -extern void ensure_same_span_type(const Span *s1, const Span *s2); -extern void ensure_same_span_basetype(const Span *s, meosType basetype); +extern bool ensure_span_has_type(const Span *s, meosType spantype); +extern bool ensure_same_span_type(const Span *s1, const Span *s2); +extern bool ensure_same_span_basetype(const Span *s, meosType basetype); extern void span_deserialize(const Span *s, SpanBound *lower, SpanBound *upper); extern Span *span_serialize(SpanBound *lower, SpanBound *upper); diff --git a/meos/include/general/spanset.h b/meos/include/general/spanset.h index 72bd66dca1..4bc8d2a525 100644 --- a/meos/include/general/spanset.h +++ b/meos/include/general/spanset.h @@ -43,10 +43,10 @@ /* General functions */ -extern void ensure_spanset_has_type(const SpanSet *ss, meosType spansettype); -extern void ensure_same_spanset_type(const SpanSet *ss1, const SpanSet *ss2); -extern void ensure_same_spanset_spantype(const SpanSet *ss, const Span *s); -extern void ensure_same_spanset_basetype(const SpanSet *ss, meosType basetype); +extern bool ensure_spanset_has_type(const SpanSet *ss, meosType spansettype); +extern bool ensure_same_spanset_type(const SpanSet *ss1, const SpanSet *ss2); +extern bool ensure_same_spanset_spantype(const SpanSet *ss, const Span *s); +extern bool ensure_same_spanset_basetype(const SpanSet *ss, meosType basetype); extern bool spanset_find_value(const SpanSet *ss, Datum v, int *loc); extern const Span *spanset_sp_n(const SpanSet *ss, int index); diff --git a/meos/include/general/tbox.h b/meos/include/general/tbox.h index 51b6e1d339..b8e26fdae8 100644 --- a/meos/include/general/tbox.h +++ b/meos/include/general/tbox.h @@ -52,9 +52,9 @@ /* Parameter tests */ -extern void ensure_has_X_tbox(const TBox *box); -extern void ensure_has_T_tbox(const TBox *box); -extern void ensure_same_dimensionality_tbox(const TBox *box1, const TBox *box2); +extern bool ensure_has_X_tbox(const TBox *box); +extern bool ensure_has_T_tbox(const TBox *box); +extern bool ensure_same_dimensionality_tbox(const TBox *box1, const TBox *box2); /* Casting */ diff --git a/meos/include/general/temporal.h b/meos/include/general/temporal.h index f9c971936d..8b6b5268a2 100644 --- a/meos/include/general/temporal.h +++ b/meos/include/general/temporal.h @@ -37,6 +37,7 @@ /* PostgreSQL */ #include /* MEOS */ +#include "general/error.h" #include "general/meos_catalog.h" #include "general/span.h" #include "general/set.h" @@ -353,20 +354,26 @@ typedef Datum (*datum_func3) (Datum, Datum, Datum); extern bool temptype_subtype(int16 subtype); extern bool temptype_subtype_all(int16 subtype); -extern void ensure_valid_interpolation(meosType temptype, interpType interp); -extern void ensure_continuous(const Temporal *temp); -extern void ensure_continuous_interpolation(int16 flags); -extern void ensure_discrete_interpolation(int16 flags); -extern void ensure_nonlinear_interpolation(int16 flags); -extern void ensure_common_dimension(int16 flags1, int16 flags2); -extern void ensure_temporal_has_type(const Temporal *temp, meosType temptype); -extern void ensure_same_temporal_type(const Temporal *temp1, +extern const char *tempsubtype_name(int8 subtype); +extern bool ensure_not_null(void *ptr); +extern bool ensure_one_not_null(void *ptr1, void *ptr2); +extern bool ensure_valid_interpolation(meosType temptype, interpType interp); +extern bool ensure_continuous(const Temporal *temp); +extern bool ensure_continuous_interpolation(int16 flags); +extern bool ensure_discrete_interpolation(int16 flags); +extern bool ensure_nonlinear_interpolation(int16 flags); +extern bool ensure_common_dimension(int16 flags1, int16 flags2); +extern bool ensure_temporal_has_type(const Temporal *temp, meosType temptype); +extern bool ensure_same_temporal_type(const Temporal *temp1, const Temporal *temp2); -extern void ensure_same_temporal_basetype(const Temporal *temp, +extern bool ensure_same_temporal_basetype(const Temporal *temp, meosType basetype); -extern void ensure_non_negative(int i); -extern void ensure_positive_datum(Datum size, meosType basetype); -extern void ensure_valid_duration(const Interval *duration); +extern bool ensure_non_negative(int i); +extern bool ensure_positive(int i); +extern bool positive_datum(Datum size, meosType basetype); +extern bool ensure_positive_datum(Datum size, meosType basetype); +extern bool valid_duration(const Interval *duration); +extern bool ensure_valid_duration(const Interval *duration); /* General functions */ diff --git a/meos/include/general/temporal_boxops.h b/meos/include/general/temporal_boxops.h index 7b9411fb9f..cb5e651d1c 100644 --- a/meos/include/general/temporal_boxops.h +++ b/meos/include/general/temporal_boxops.h @@ -48,7 +48,7 @@ /* Functions on generic bounding boxes of temporal types */ extern bool bbox_type(meosType bboxtype); -extern void ensure_bbox_type(meosType bboxtype); +extern bool ensure_bbox_type(meosType bboxtype); extern size_t bbox_get_size(meosType bboxtype); extern int bbox_max_dims(meosType bboxtype); extern size_t temporal_max_header_size(void); diff --git a/meos/include/general/time_aggfuncs.h b/meos/include/general/time_aggfuncs.h index b49db77f36..fefc7773cd 100644 --- a/meos/include/general/time_aggfuncs.h +++ b/meos/include/general/time_aggfuncs.h @@ -42,7 +42,7 @@ extern Datum datum_sum_int32(Datum l, Datum r); -extern void ensure_same_timetype_skiplist(SkipList *state, uint8 subtype); +extern bool ensure_same_timetype_skiplist(SkipList *state, uint8 subtype); /*****************************************************************************/ diff --git a/meos/include/general/tsequence.h b/meos/include/general/tsequence.h index 87cd782c50..9d25247968 100644 --- a/meos/include/general/tsequence.h +++ b/meos/include/general/tsequence.h @@ -46,7 +46,7 @@ extern int tcontseq_find_timestamp(const TSequence *seq, TimestampTz t); extern int tdiscseq_find_timestamp(const TSequence *seq, TimestampTz t); -extern void tsequence_make_valid1(const TInstant **instants, int count, +extern bool tsequence_make_valid1(const TInstant **instants, int count, bool lower_inc, bool upper_inc, interpType interp); extern TSequence *tsequence_make1_exp(const TInstant **instants, int count, int maxcount, bool lower_inc, bool upper_inc, interpType interp, @@ -102,10 +102,10 @@ extern char *tsequence_to_string(const TSequence *seq, int maxdd, /* Constructor functions */ -extern void ensure_increasing_timestamps(const TInstant *inst1, +extern bool ensure_increasing_timestamps(const TInstant *inst1, const TInstant *inst2, bool strict); extern void bbox_expand(const void *box1, void *box2, meosType temptype); -extern void ensure_valid_tinstarr(const TInstant **instants, int count, +extern bool ensure_valid_tinstarr(const TInstant **instants, int count, bool merge, interpType interp); /* Transformation functions */ diff --git a/meos/include/general/type_parser.h b/meos/include/general/type_parser.h index 656669f4ca..409579a3bb 100644 --- a/meos/include/general/type_parser.h +++ b/meos/include/general/type_parser.h @@ -42,17 +42,18 @@ /*****************************************************************************/ -extern void ensure_end_input(const char **str, bool end, const char *type); - +extern bool ensure_end_input(const char **str, const char *type); extern void p_whitespace(const char **str); extern bool p_obrace(const char **str); +extern bool ensure_obrace(const char **str, const char *type); extern bool p_cbrace(const char **str); +extern bool ensure_cbrace(const char **str, const char *type); extern bool p_obracket(const char **str); extern bool p_cbracket(const char **str); extern bool p_oparen(const char **str); -extern void ensure_oparen(const char **str, const char *type); +extern bool ensure_oparen(const char **str, const char *type); extern bool p_cparen(const char **str); -extern void ensure_cparen(const char **str, const char *type); +extern bool ensure_cparen(const char **str, const char *type); extern bool p_comma(const char **str); extern Datum temporal_basetype_parse(const char **str, meosType basetypid); extern double double_parse(const char **str); diff --git a/meos/include/meos.h b/meos/include/meos.h index f235e9e8e8..0667f4fbe2 100644 --- a/meos/include/meos.h +++ b/meos/include/meos.h @@ -281,7 +281,14 @@ typedef struct * Initialization of the MEOS library *****************************************************************************/ -extern void meos_initialize(const char *tz_str); +/* Definition of error handler function */ +typedef void (*error_handler_fn)(int, int, char *); + +extern void meos_initialize_timezone(const char *name); +extern void meos_initialize_error_handler(error_handler_fn err_handler); +extern void meos_finalize_timezone(void); + +extern void meos_initialize(const char *tz_str, error_handler_fn err_handler); extern void meos_finalize(void); /***************************************************************************** @@ -319,20 +326,21 @@ extern DateADT pg_to_date(text *date_txt, text *fmt); * Functions for input/output and manipulation of PostGIS types *****************************************************************************/ -extern bytea *gserialized_as_ewkb(const GSERIALIZED *geom, char *type); -extern char *gserialized_as_ewkt(const GSERIALIZED *geom, int precision); -extern char *gserialized_as_geojson(const GSERIALIZED *geom, int option, int precision, char *srs); -extern char *gserialized_as_hexewkb(const GSERIALIZED *geom, const char *type); -extern char *gserialized_as_text(const GSERIALIZED *geom, int precision); +extern GSERIALIZED *geography_from_hexewkb(const char *wkt); +extern GSERIALIZED *geometry_from_hexewkb(const char *wkt); +extern bytea *gserialized_as_ewkb(const GSERIALIZED *gs, char *type); +extern char *gserialized_as_ewkt(const GSERIALIZED *gs, int precision); +extern char *gserialized_as_geojson(const GSERIALIZED *gs, int option, int precision, char *srs); +extern char *gserialized_as_hexewkb(const GSERIALIZED *gs, const char *type); +extern char *gserialized_as_text(const GSERIALIZED *gs, int precision); extern GSERIALIZED *gserialized_from_ewkb(const bytea *bytea_wkb, int32 srid); extern GSERIALIZED *gserialized_from_geojson(const char *geojson); -extern GSERIALIZED *gserialized_from_hexewkb(const char *wkt); +extern char *gserialized_out(const GSERIALIZED *gs); extern GSERIALIZED *geometry_from_text(char *wkt, int srid); extern GSERIALIZED *geography_from_text(char *wkt, int srid); extern GSERIALIZED *pgis_geography_in(char *input, int32 geom_typmod); extern GSERIALIZED *pgis_geometry_in(char *input, int32 geom_typmod); -extern char *gserialized_out(const GSERIALIZED *geom); -extern bool pgis_gserialized_same(const GSERIALIZED *geom1, const GSERIALIZED *geom2); +extern bool pgis_gserialized_same(const GSERIALIZED *gs1, const GSERIALIZED *geom2); /***************************************************************************** * Functions for set and span types @@ -404,7 +412,6 @@ extern Span *span_copy(const Span *s); extern SpanSet *spanset_copy(const SpanSet *ps); extern SpanSet *spanset_make(Span *spans, int count, bool normalize); extern SpanSet *spanset_make_exp(Span *spans, int count, int maxcount, bool normalize, bool ordered); -extern SpanSet *spanset_make_free(Span *spans, int count, bool normalize); extern Set *textset_make(const text **values, int count); extern Set *timestampset_make(const TimestampTz *values, int count); @@ -418,8 +425,7 @@ extern SpanSet *bigint_to_bigintspanset(int i); extern Set *float_to_floatset(double d); extern Span *float_to_floatspan(double d); extern SpanSet *float_to_floatspanset(double d); -extern Set *geog_to_geogset(GSERIALIZED *gs); -extern Set *geom_to_geomset(GSERIALIZED *gs); +extern Set *geo_to_geoset(GSERIALIZED *gs); extern Set *int_to_intset(int i); extern Span *int_to_intspan(int i); extern SpanSet *int_to_intspanset(int i); @@ -992,21 +998,16 @@ extern TInstant *tfloatinst_make(double d, TimestampTz t); extern TSequence *tfloatseq_from_base_period(double d, const Span *p, interpType interp); extern TSequence *tfloatseq_from_base_timestampset(double d, const Set *ts); extern TSequenceSet *tfloatseqset_from_base_periodset(double d, const SpanSet *ps, interpType interp); -extern Temporal *tgeogpoint_from_base_temp(const GSERIALIZED *gs, const Temporal *temp); -extern TInstant *tgeogpointinst_make(const GSERIALIZED *gs, TimestampTz t); -extern TSequence *tgeogpointseq_from_base_period(const GSERIALIZED *gs, const Span *p, interpType interp); -extern TSequence *tgeogpointseq_from_base_timestampset(const GSERIALIZED *gs, const Set *ts); -extern TSequenceSet *tgeogpointseqset_from_base_periodset(const GSERIALIZED *gs, const SpanSet *ps, interpType interp); -extern Temporal *tgeompoint_from_base_temp(const GSERIALIZED *gs, const Temporal *temp); -extern TInstant *tgeompointinst_make(const GSERIALIZED *gs, TimestampTz t); -extern TSequence *tgeompointseq_from_base_period(const GSERIALIZED *gs, const Span *p, interpType interp); -extern TSequence *tgeompointseq_from_base_timestampset(const GSERIALIZED *gs, const Set *ts); -extern TSequenceSet *tgeompointseqset_from_base_periodset(const GSERIALIZED *gs, const SpanSet *ps, interpType interp); extern Temporal *tint_from_base_temp(int i, const Temporal *temp); extern TInstant *tintinst_make(int i, TimestampTz t); extern TSequence *tintseq_from_base_period(int i, const Span *p); extern TSequence *tintseq_from_base_timestampset(int i, const Set *ts); extern TSequenceSet *tintseqset_from_base_periodset(int i, const SpanSet *ps); +extern Temporal *tpoint_from_base_temp(const GSERIALIZED *gs, const Temporal *temp); +extern TInstant *tpointinst_make(const GSERIALIZED *gs, TimestampTz t); +extern TSequence *tpointseq_from_base_period(const GSERIALIZED *gs, const Span *p, interpType interp); +extern TSequence *tpointseq_from_base_timestampset(const GSERIALIZED *gs, const Set *ts); +extern TSequenceSet *tpointseqset_from_base_periodset(const GSERIALIZED *gs, const SpanSet *ps, interpType interp); extern TSequence *tsequence_make(const TInstant **instants, int count, bool lower_inc, bool upper_inc, interpType interp, bool normalize); extern TSequence *tsequence_make_exp(const TInstant **instants, int count, int maxcount, bool lower_inc, bool upper_inc, interpType interp, bool normalize); extern TSequenceSet *tsequenceset_make(const TSequence **sequences, int count, bool normalize); @@ -1244,16 +1245,14 @@ extern bool tfloat_always_lt(const Temporal *temp, double d); extern bool tfloat_ever_eq(const Temporal *temp, double d); extern bool tfloat_ever_le(const Temporal *temp, double d); extern bool tfloat_ever_lt(const Temporal *temp, double d); -extern bool tgeogpoint_always_eq(const Temporal *temp, GSERIALIZED *gs);; -extern bool tgeogpoint_ever_eq(const Temporal *temp, GSERIALIZED *gs);; -extern bool tgeompoint_always_eq(const Temporal *temp, GSERIALIZED *gs); -extern bool tgeompoint_ever_eq(const Temporal *temp, GSERIALIZED *gs);; extern bool tint_always_eq(const Temporal *temp, int i); extern bool tint_always_le(const Temporal *temp, int i); extern bool tint_always_lt(const Temporal *temp, int i); extern bool tint_ever_eq(const Temporal *temp, int i); extern bool tint_ever_le(const Temporal *temp, int i); extern bool tint_ever_lt(const Temporal *temp, int i); +extern bool tpoint_always_eq(const Temporal *temp, const GSERIALIZED *gs);; +extern bool tpoint_ever_eq(const Temporal *temp, const GSERIALIZED *gs);; extern bool ttext_always_eq(const Temporal *temp, text *txt); extern bool ttext_always_le(const Temporal *temp, text *txt); extern bool ttext_always_lt(const Temporal *temp, text *txt); @@ -1274,18 +1273,14 @@ extern bool temporal_lt(const Temporal *temp1, const Temporal *temp2); extern bool temporal_ne(const Temporal *temp1, const Temporal *temp2); extern Temporal *teq_bool_tbool(bool b, const Temporal *temp); extern Temporal *teq_float_tfloat(double d, const Temporal *temp); -extern Temporal *teq_geo_tpoint(const GSERIALIZED *geo, const Temporal *tpoint); extern Temporal *teq_int_tint(int i, const Temporal *temp); -extern Temporal *teq_point_tgeogpoint(const GSERIALIZED *gs, const Temporal *temp); -extern Temporal *teq_point_tgeompoint(const GSERIALIZED *gs, const Temporal *temp); +extern Temporal *teq_point_tpoint(const GSERIALIZED *gs, const Temporal *temp); extern Temporal *teq_tbool_bool(const Temporal *temp, bool b); extern Temporal *teq_temporal_temporal(const Temporal *temp1, const Temporal *temp2); extern Temporal *teq_text_ttext(const text *txt, const Temporal *temp); extern Temporal *teq_tfloat_float(const Temporal *temp, double d); -extern Temporal *teq_tgeogpoint_point(const Temporal *temp, const GSERIALIZED *gs); -extern Temporal *teq_tgeompoint_point(const Temporal *temp, const GSERIALIZED *gs); +extern Temporal *teq_tpoint_point(const Temporal *temp, const GSERIALIZED *gs); extern Temporal *teq_tint_int(const Temporal *temp, int i); -extern Temporal *teq_tpoint_geo(const Temporal *tpoint, const GSERIALIZED *geo); extern Temporal *teq_ttext_text(const Temporal *temp, const text *txt); extern Temporal *tge_float_tfloat(double d, const Temporal *temp); extern Temporal *tge_int_tint(int i, const Temporal *temp); @@ -1317,18 +1312,14 @@ extern Temporal *tlt_tint_int(const Temporal *temp, int i); extern Temporal *tlt_ttext_text(const Temporal *temp, const text *txt); extern Temporal *tne_bool_tbool(bool b, const Temporal *temp); extern Temporal *tne_float_tfloat(double d, const Temporal *temp); -extern Temporal *tne_geo_tpoint(const GSERIALIZED *geo, const Temporal *tpoint); extern Temporal *tne_int_tint(int i, const Temporal *temp); -extern Temporal *tne_point_tgeogpoint(const GSERIALIZED *gs, const Temporal *temp); -extern Temporal *tne_point_tgeompoint(const GSERIALIZED *gs, const Temporal *temp); +extern Temporal *tne_point_tpoint(const GSERIALIZED *gs, const Temporal *temp); extern Temporal *tne_tbool_bool(const Temporal *temp, bool b); extern Temporal *tne_temporal_temporal(const Temporal *temp1, const Temporal *temp2); extern Temporal *tne_text_ttext(const text *txt, const Temporal *temp); extern Temporal *tne_tfloat_float(const Temporal *temp, double d); -extern Temporal *tne_tgeogpoint_point(const Temporal *temp, const GSERIALIZED *gs); -extern Temporal *tne_tgeompoint_point(const Temporal *temp, const GSERIALIZED *gs); +extern Temporal *tne_tpoint_point(const Temporal *temp, const GSERIALIZED *gs); extern Temporal *tne_tint_int(const Temporal *temp, int i); -extern Temporal *tne_tpoint_geo(const Temporal *tpoint, const GSERIALIZED *geo); extern Temporal *tne_ttext_text(const Temporal *temp, const text *txt); /***************************************************************************** diff --git a/meos/include/meos_internal.h b/meos/include/meos_internal.h index 1257539215..ec25bd6a5e 100644 --- a/meos/include/meos_internal.h +++ b/meos/include/meos_internal.h @@ -585,7 +585,7 @@ extern TSequenceSet *tnumberseqset_abs(const TSequenceSet *ss); extern TSequence *tnumberseq_angular_difference(const TSequence *seq); extern TSequence *tnumberseqset_angular_difference(const TSequenceSet *ss); extern TSequence *tnumberseq_delta_value(const TSequence *seq); -extern TSequenceSet *tnumberseqset_delta_value(const TSequenceSet *ss); +extern TSequenceSet *tnumberseqset_delta_value(const TSequenceSet *ss); extern SpanSet *tnumberinst_valuespans(const TInstant *inst); extern SpanSet *tnumberseq_valuespans(const TSequence *seq); extern SpanSet *tnumberseqset_valuespans(const TSequenceSet *ss); @@ -712,7 +712,7 @@ extern TSequence *tsequence_at_period(const TSequence *seq, const Span *p); extern TInstant *tsequence_at_timestamp(const TSequence *seq, TimestampTz t); extern TSequenceSet *tsequence_restrict_minmax(const TSequence *seq, bool min, bool atfunc); extern Temporal *tsequence_restrict_period(const TSequence *seq, const Span *p, bool atfunc); -extern TSequenceSet *tsequence_restrict_periodset(const TSequence *seq, const SpanSet *ps, bool atfunc); +extern Temporal *tsequence_restrict_periodset(const TSequence *seq, const SpanSet *ps, bool atfunc); extern TInstant *tsequence_restrict_timestamp(const TSequence *seq, TimestampTz t, bool atfunc); extern TSequence *tsequence_restrict_timestampset(const TSequence *seq, const Set *ts, bool atfunc); extern TSequenceSet *tsequence_restrict_value(const TSequence *seq, Datum value, bool atfunc); @@ -755,8 +755,6 @@ extern bool tinstant_always_lt(const TInstant *inst, Datum value); extern bool tinstant_ever_eq(const TInstant *inst, Datum value); extern bool tinstant_ever_le(const TInstant *inst, Datum value); extern bool tinstant_ever_lt(const TInstant *inst, Datum value); -extern bool tpoint_always_eq(const Temporal *temp, Datum value); -extern bool tpoint_ever_eq(const Temporal *temp, Datum value); extern bool tpointinst_always_eq(const TInstant *inst, Datum value); extern bool tpointinst_ever_eq(const TInstant *inst, Datum value); extern bool tpointseq_always_eq(const TSequence *seq, Datum value); diff --git a/meos/include/npoint/tnpoint_spatialfuncs.h b/meos/include/npoint/tnpoint_spatialfuncs.h index 8da433eeb8..ebe0ca8e16 100644 --- a/meos/include/npoint/tnpoint_spatialfuncs.h +++ b/meos/include/npoint/tnpoint_spatialfuncs.h @@ -44,9 +44,9 @@ /* Parameter tests */ -extern void ensure_same_srid_tnpoint_stbox(const Temporal *temp, +extern bool ensure_same_srid_tnpoint_stbox(const Temporal *temp, const STBox *box); -extern void ensure_same_rid_tnpointinst(const TInstant *inst1, +extern bool ensure_same_rid_tnpointinst(const TInstant *inst1, const TInstant *inst2); /* Interpolation functions */ diff --git a/meos/include/point/pgis_call.h b/meos/include/point/pgis_call.h index 7f9e631905..63338c69cb 100644 --- a/meos/include/point/pgis_call.h +++ b/meos/include/point/pgis_call.h @@ -61,25 +61,25 @@ extern LWGEOM *box3d_to_lwgeom(BOX3D *box); /* Functions adapted from lwgeom_functions_basic.c */ /* The implementation of this function changed in PostGIS version 3.2 */ -extern GSERIALIZED *gserialized_boundary(const GSERIALIZED *geom1); -extern GSERIALIZED *gserialized_shortestline2d(const GSERIALIZED *geom1, - const GSERIALIZED *geom2); -extern GSERIALIZED *gserialized_shortestline3d(const GSERIALIZED *geom1, - const GSERIALIZED *geom2); -extern double gserialized_distance(const GSERIALIZED *geom1, - const GSERIALIZED *geom2); -extern double gserialized_3Ddistance(const GSERIALIZED *geom1, - const GSERIALIZED *geom2); -extern bool gserialized_3Dintersects(const GSERIALIZED *geom1, - const GSERIALIZED *geom2); -extern bool gserialized_dwithin(const GSERIALIZED *geom1, - const GSERIALIZED *geom2, double tolerance); -extern bool gserialized_dwithin3d(const GSERIALIZED *geom1, - const GSERIALIZED *geom2, double tolerance); -extern bool gserialized_relate_pattern(const GSERIALIZED *geom1, - const GSERIALIZED *geom2, char *patt); +extern GSERIALIZED *gserialized_boundary(const GSERIALIZED *gs); +extern GSERIALIZED *gserialized_shortestline2d(const GSERIALIZED *gs1, + const GSERIALIZED *s2); +extern GSERIALIZED *gserialized_shortestline3d(const GSERIALIZED *gs1, + const GSERIALIZED *s2); +extern double gserialized_distance(const GSERIALIZED *gs1, + const GSERIALIZED *gs2); +extern double gserialized_3Ddistance(const GSERIALIZED *gs1, + const GSERIALIZED *gs2); +extern bool gserialized_3Dintersects(const GSERIALIZED *gs1, + const GSERIALIZED *gs2); +extern bool gserialized_dwithin(const GSERIALIZED *gs1, + const GSERIALIZED *gs2, double tolerance); +extern bool gserialized_dwithin3d(const GSERIALIZED *gs1, + const GSERIALIZED *gs2, double tolerance); +extern bool gserialized_relate_pattern(const GSERIALIZED *gs1, + const GSERIALIZED *gs2, char *patt); extern GSERIALIZED *gserialized_reverse(const GSERIALIZED *geom); -extern bool gserialized_azimuth(GSERIALIZED *geom1, GSERIALIZED *geom2, +extern bool gserialized_azimuth(GSERIALIZED *gs1, GSERIALIZED *gs2, double *result); /* Functions adapted from lwgeom_geos.c */ @@ -87,14 +87,14 @@ extern bool gserialized_azimuth(GSERIALIZED *geom1, GSERIALIZED *geom2, extern GEOSGeometry *POSTGIS2GEOS(const GSERIALIZED *pglwgeom); extern GSERIALIZED *GEOS2POSTGIS(GEOSGeom geom, char want3d); -extern bool gserialized_spatialrel(const GSERIALIZED *geom1, - const GSERIALIZED *geom2, spatialRel rel); -extern GSERIALIZED *gserialized_intersection(const GSERIALIZED *geom1, - const GSERIALIZED *geom2); +extern bool gserialized_spatialrel(const GSERIALIZED *gs1, + const GSERIALIZED *gs2, spatialRel rel); +extern GSERIALIZED *gserialized_intersection(const GSERIALIZED *gs1, + const GSERIALIZED *gs2); extern GSERIALIZED *gserialized_array_union(GSERIALIZED **gsarr, int nelems); extern GSERIALIZED *gserialized_convex_hull(const GSERIALIZED *geom); -extern double gserialized_hausdorffdistance(const GSERIALIZED *geom1, - const GSERIALIZED *geom2); +extern double gserialized_hausdorffdistance(const GSERIALIZED *gs1, + const GSERIALIZED *gs2); /* Functions adapted from geography_measurement.c */ @@ -106,9 +106,6 @@ extern double gserialized_geog_distance(const GSERIALIZED *g1, /* Functions adapted from geography_inout.c */ -extern GSERIALIZED *gserialized_geog_in(char *str, int32 geog_typmod); -extern char *gserialized_geog_out(GSERIALIZED *g); - extern GSERIALIZED *gserialized_geog_from_geom(GSERIALIZED *geom); extern GSERIALIZED *gserialized_geom_from_geog(GSERIALIZED *g_ser); @@ -121,10 +118,10 @@ extern GSERIALIZED *gserialized_line_substring(GSERIALIZED *geom, double from, /* Functions adapted from lwgeom_lrs.c */ -extern LWGEOM *lwgeom_line_interpolate_point(LWGEOM *lwgeom, double fraction, +extern LWGEOM *lwgeom_line_interpolate_point(LWGEOM *geom, double fraction, int32_t srid, char repeat); -extern double gserialized_line_locate_point(GSERIALIZED *geom1, - GSERIALIZED *geom2); +extern double gserialized_line_locate_point(GSERIALIZED *gs1, + GSERIALIZED *gs2); /* Functions adapted from lwgeom_ogc.c */ diff --git a/meos/include/point/stbox.h b/meos/include/point/stbox.h index 8869db6da6..61f5b7ab62 100644 --- a/meos/include/point/stbox.h +++ b/meos/include/point/stbox.h @@ -54,8 +54,8 @@ /* Parameter tests */ -extern void ensure_has_X_stbox(const STBox *box); -extern void ensure_has_T_stbox(const STBox *box); +extern bool ensure_has_X_stbox(const STBox *box); +extern bool ensure_has_T_stbox(const STBox *box); /* Set an STBox from a */ diff --git a/meos/include/point/tpoint.h b/meos/include/point/tpoint.h index 66736c3f5c..e4a0213cf5 100644 --- a/meos/include/point/tpoint.h +++ b/meos/include/point/tpoint.h @@ -79,8 +79,8 @@ extern GSERIALIZED * gserialized_copy(const GSERIALIZED *g); /* Temporal comparisons */ -extern Temporal *tcomp_tpoint_point(const Temporal *temp, const GSERIALIZED *gs, - Datum (*func)(Datum, Datum, meosType), bool invert); +extern Temporal *tcomp_tpoint_point_int(const Temporal *temp, + const GSERIALIZED *gs, Datum (*func)(Datum, Datum, meosType), bool invert); /*****************************************************************************/ diff --git a/meos/include/point/tpoint_spatialfuncs.h b/meos/include/point/tpoint_spatialfuncs.h index fa1b56894c..7664bc894e 100644 --- a/meos/include/point/tpoint_spatialfuncs.h +++ b/meos/include/point/tpoint_spatialfuncs.h @@ -81,29 +81,32 @@ extern Datum geom_intersection2d(Datum geom1, Datum geom2); /* Parameter tests */ -extern void ensure_spatial_validity(const Temporal *temp1, +extern bool ensure_spatial_validity(const Temporal *temp1, const Temporal *temp2); -extern void ensure_not_geodetic(int16 flags); -extern void ensure_same_geodetic(int16 flags1, int16 flags2); -extern void ensure_same_srid(int32_t srid1, int32_t srid2); -extern void ensure_same_srid_stbox_gs(const STBox *box, const GSERIALIZED *gs); -extern void ensure_same_dimensionality(int16 flags1, int16 flags2); -extern void ensure_same_spatial_dimensionality(int16 flags1, int16 flags2); -extern void ensure_same_spatial_dimensionality_temp_box(int16 flags1, int16 flags2); -extern void ensure_same_dimensionality_gs(const GSERIALIZED *gs1, +extern bool ensure_not_geodetic(int16 flags); +extern bool ensure_same_geodetic(int16 flags1, int16 flags2); +extern bool ensure_same_srid(int32_t srid1, int32_t srid2); +extern bool ensure_same_srid_stbox_gs(const STBox *box, const GSERIALIZED *gs); +extern bool ensure_same_dimensionality(int16 flags1, int16 flags2); +extern bool same_spatial_dimensionality(int16 flags1, int16 flags2); +extern bool ensure_same_spatial_dimensionality(int16 flags1, int16 flags2); +extern bool ensure_same_spatial_dimensionality_temp_box(int16 flags1, int16 flags2); +extern bool ensure_same_dimensionality_gs(const GSERIALIZED *gs1, const GSERIALIZED *gs2); -extern void ensure_same_dimensionality_tpoint_gs(const Temporal *temp, +extern bool same_dimensionality_tpoint_gs(const Temporal *temp, const GSERIALIZED *gs); -extern void ensure_same_spatial_dimensionality_stbox_gs(const STBox *box1, +extern bool ensure_same_dimensionality_tpoint_gs(const Temporal *temp, const GSERIALIZED *gs); -extern void ensure_has_Z(int16 flags); -extern void ensure_has_not_Z(int16 flags); -extern void ensure_has_Z_gs(const GSERIALIZED *gs); -extern void ensure_has_not_Z_gs(const GSERIALIZED *gs); -extern void ensure_has_M_gs(const GSERIALIZED *gs); -extern void ensure_has_not_M_gs(const GSERIALIZED *gs); -extern void ensure_point_type(const GSERIALIZED *gs); -extern void ensure_non_empty(const GSERIALIZED *gs); +extern bool ensure_same_spatial_dimensionality_stbox_gs(const STBox *box, + const GSERIALIZED *gs); +extern bool ensure_has_Z(int16 flags); +extern bool ensure_has_not_Z(int16 flags); +extern bool ensure_has_Z_gs(const GSERIALIZED *gs); +extern bool ensure_has_not_Z_gs(const GSERIALIZED *gs); +extern bool ensure_has_M_gs(const GSERIALIZED *gs); +extern bool ensure_has_not_M_gs(const GSERIALIZED *gs); +extern bool ensure_point_type(const GSERIALIZED *gs); +extern bool ensure_non_empty(const GSERIALIZED *gs); /* Functions derived from PostGIS to increase floating-point precision */ @@ -144,7 +147,7 @@ extern bool geopoint_collinear(Datum value1, Datum value2, Datum value3, extern LWGEOM **lwpointarr_remove_duplicates(LWGEOM **points, int count, int *newcount); -extern LWGEOM *lwpointarr_make_trajectory(LWGEOM **lwpoints, int count, +extern LWGEOM *lwpointarr_make_trajectory(LWGEOM **points, int count, interpType interp); extern LWLINE *lwline_make(Datum value1, Datum value2); extern LWGEOM *lwcoll_from_points_lines(LWGEOM **points, LWGEOM **lines, diff --git a/meos/include/postgis_ext_defs.in.h b/meos/include/postgis_ext_defs.in.h index aa526a14a6..669d7501eb 100644 --- a/meos/include/postgis_ext_defs.in.h +++ b/meos/include/postgis_ext_defs.in.h @@ -398,8 +398,6 @@ extern LWPOINT *lwpoint_make(int32_t srid, int hasz, int hasm, const POINT4D *p) extern LWGEOM *lwgeom_from_gserialized(const GSERIALIZED *g); extern GSERIALIZED *gserialized_from_lwgeom(LWGEOM *geom, size_t *size); -extern LWPOINT *lwgeom_as_lwpoint(const LWGEOM *lwgeom); - extern int32_t lwgeom_get_srid(const LWGEOM *geom); extern double lwpoint_get_x(const LWPOINT *point); diff --git a/meos/postgres/timezone/pgtz.c b/meos/postgres/timezone/pgtz.c index 8083a1f169..692b27e4d8 100644 --- a/meos/postgres/timezone/pgtz.c +++ b/meos/postgres/timezone/pgtz.c @@ -417,27 +417,18 @@ pg_tzset_offset(long gmtoffset) * Initialize timezone cache */ void -meos_timezone_initialize(const char *name) -{ - session_timezone = pg_tzset(name); - if (! session_timezone) - elog(ERROR, "Failed to initialize local timezone"); - return; -} - -/* - * Initialize timezone library - */ -void -meos_initialize(const char *tz_str) +meos_initialize_timezone(const char *tz_str) { if (tz_str == NULL || strlen(tz_str) == 0) /* fetch local timezone */ tz_str = select_default_timezone(NULL); if (tz_str == NULL) - meos_timezone_initialize("GMT"); - else - meos_timezone_initialize(tz_str); + /* default timezone */ + tz_str = "GMT"; + + session_timezone = pg_tzset(tz_str); + if (! session_timezone) + elog(ERROR, "Failed to initialize local timezone"); return; } @@ -445,9 +436,10 @@ meos_initialize(const char *tz_str) * Free the timezone cache */ void -meos_finalize(void) +meos_finalize_timezone(void) { if (session_timezone) tzcache_destroy(timezone_cache); return; } +/*****************************************************************************/ diff --git a/meos/src/general/CMakeLists.txt b/meos/src/general/CMakeLists.txt index 60e0a04180..7798193ce9 100644 --- a/meos/src/general/CMakeLists.txt +++ b/meos/src/general/CMakeLists.txt @@ -1,6 +1,7 @@ add_library(general OBJECT basetype_inout.c doublen.c + error.c lifting.c meos_catalog.c pg_types.c diff --git a/meos/src/general/basetype_inout.c b/meos/src/general/basetype_inout.c index d02444c110..d1004be017 100644 --- a/meos/src/general/basetype_inout.c +++ b/meos/src/general/basetype_inout.c @@ -154,6 +154,10 @@ parse_bool_with_len(const char *value, size_t len, bool *result) bool bool_in(const char *in_str) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) in_str)) + return false; + const char *str; size_t len; bool result; @@ -172,7 +176,8 @@ bool_in(const char *in_str) if (parse_bool_with_len(str, len, &result)) return result; - elog(ERROR, "invalid input syntax for type %s: \"%s\"", "boolean", in_str); + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "invalid input syntax for type %s: \"%s\"", "boolean", in_str); /* not reached */ return false; @@ -364,8 +369,11 @@ float8_in_opt_error(char *num, const char *type_name, const char *orig_string) * strtod() on different platforms. */ if (*num == '\0') - elog(ERROR, "invalid input syntax for type %s: \"%s\"", type_name, - orig_string); + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "invalid input syntax for type %s: \"%s\"", type_name, orig_string); + return 0; + } errno = 0; val = strtod(num, &endptr); @@ -435,16 +443,20 @@ float8_in_opt_error(char *num, const char *type_name, const char *orig_string) */ if (val == 0.0 || val >= HUGE_VAL || val <= -HUGE_VAL) { - char *errnumber = strdup(num); + char *errnumber = strdup(num); errnumber[endptr - num] = '\0'; - elog(ERROR, "\"%s\" is out of range for type double precision", - errnumber); + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "\"%s\" is out of range for type double precision", errnumber); pfree(errnumber); + return DBL_MAX; } } else - elog(ERROR, "invalid input syntax for type %s: \"%s\"", - type_name, orig_string); + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "invalid input syntax for type %s: \"%s\"", type_name, orig_string); + return DBL_MAX; + } } /* skip trailing whitespace */ @@ -476,8 +488,7 @@ float8_in(const char *num, const char *type_name, const char *orig_string) char * float8_out(double num, int maxdd) { - /* Ensure validity of the arguments */ - ensure_non_negative(maxdd); + assert(maxdd >= 0); char *ascii = palloc(OUT_DOUBLE_BUFFER_SIZE); lwprint_double(num, maxdd, ascii); diff --git a/meos/src/general/doublen.c b/meos/src/general/doublen.c index 5398727c20..7148f03a6c 100644 --- a/meos/src/general/doublen.c +++ b/meos/src/general/doublen.c @@ -75,9 +75,8 @@ double2_make(double a, double b) char * double2_out(const double2 *d, int maxdd) { - /* Ensure validity of the arguments */ assert(d != NULL); - ensure_non_negative(maxdd); + assert(maxdd >= 0); char *astr = float8_out(d->a, maxdd); char *bstr = float8_out(d->b, maxdd); @@ -160,9 +159,8 @@ double3_make(double a, double b, double c) char * double3_out(const double3 *d, int maxdd) { - /* Ensure validity of the arguments */ assert(d != NULL); - ensure_non_negative(maxdd); + assert(maxdd >= 0); char *astr = float8_out(d->a, maxdd); char *bstr = float8_out(d->b, maxdd); @@ -253,9 +251,8 @@ double4_make(double a, double b, double c, double d) char * double4_out(const double4 *d, int maxdd) { - /* Ensure validity of the arguments */ assert(d != NULL); - ensure_non_negative(maxdd); + assert(maxdd >= 0); char *astr = float8_out(d->a, maxdd); char *bstr = float8_out(d->b, maxdd); diff --git a/meos/src/general/error.c b/meos/src/general/error.c new file mode 100644 index 0000000000..eceb0c4847 --- /dev/null +++ b/meos/src/general/error.c @@ -0,0 +1,228 @@ +/***************************************************************************** + * + * This MobilityDB code is provided under The PostgreSQL License. + * Copyright (c) 2016-2023, Université libre de Bruxelles and MobilityDB + * contributors + * + * MobilityDB includes portions of PostGIS version 3 source code released + * under the GNU General Public License (GPLv2 or later). + * Copyright (c) 2001-2023, PostGIS contributors + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without a written + * agreement is hereby granted, provided that the above copyright notice and + * this paragraph and the following two paragraphs appear in all copies. + * + * IN NO EVENT SHALL UNIVERSITE LIBRE DE BRUXELLES BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING + * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, + * EVEN IF UNIVERSITE LIBRE DE BRUXELLES HAS BEEN ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * UNIVERSITE LIBRE DE BRUXELLES SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON + * AN "AS IS" BASIS, AND UNIVERSITE LIBRE DE BRUXELLES HAS NO OBLIGATIONS TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + *****************************************************************************/ + +/** + * @file + * @brief MEOS error handling inspired by GEOS and Proj + * https://github.com/libgeos/geos/blob/main/capi/geos_c.h.in + * https://github.com/OSGeo/PROJ/blob/master/src/4D_api.cpp + */ + +#include "general/error.h" + +/* C */ +#include +#include +/* C */ +#include +#if ! MEOS + #include +#endif /* ! MEOS */ + +/*****************************************************************************/ + +/** + * @brief Global variable that keeps the last error number. + */ +int _meos_errno = 0; + +/** + * @brief Read an error number + */ +static int +meos_errno(void) +{ + return _meos_errno; +} + +/** + * @brief Set an error number + */ +int +meos_errno_set(int err) +{ + /* Use #meos_errno_reset to explicitly clear the error status */ + if (err == 0) + return 0; + + meos_errno_set(err); + errno = err; + return err; +} + +/** + * @brief Set an error number + * + * Use #meos_errno_restore when the current function succeeds, but the + * error flag was set on entry, and stored/reset using #meos_errno_reset + * in order to monitor for new errors. + * See usage example under #meos_errno_reset() + */ +int +meos_errno_restore(int err) +{ + if (err == 0) + return 0; + meos_errno_set(err); + return 0; +} + +/** + * @brief Clears errno. + * @return Returns the previous value of the errno, for convenient reset/restore + * operations + * + * @code + * int foo(void) + * { + * // errno may be set on entry, but we need to reset it to be able to + * // check for errors from "do_something()" + * int last_errno = meos_errno_reset(); + * + * // local failure + * if (0==P) + * return meos_errno_set(42); + * + * // call to function that may fail + * do_something(); + * + * // failure in do_something? - keep latest error status + * if (meos_errno()) + * return meos_errno(); + * + * // success - restore previous error status, return 0 + * return meos_errno_restore(last_errno); + * } + * @endcode + */ + +int meos_errno_reset(void) +{ + int last_errno = meos_errno(); + meos_errno_set(0); + errno = 0; + return last_errno; +} + +/*****************************************************************************/ + +/** + * @brief Global variable that keeps the error handler function + */ +void (*_error_handler)(int, int, char *) = NULL; + +#if MEOS +/** + * @brief Default error handler function that prints the error to stderr and + * exits if error level is equal to `ERROR` + */ +void +default_error_handler(int errlevel, int errcode __attribute((__unused__)), + char *text) +{ + fprintf(stderr, "%s", text); + fprintf(stderr, "\n"); + if (errlevel == ERROR) + exit(EXIT_FAILURE); + return; +} + +/** + * @brief Error handler function that sets the errno + */ +void +error_handler_errno(int errlevel __attribute((__unused__)), int errcode, + char *text) +{ + perror(text); + meos_errno_set(errcode); + return; +} + +/* + * Initialize error handler function + */ +void +meos_initialize_error_handler(error_handler_fn err_handler) +{ + if (err_handler) + _error_handler = err_handler; + else + _error_handler = &default_error_handler; + return; +} +#endif /* MEOS */ + +/*****************************************************************************/ + +/** + * @brief Function handling error messages + */ +void +meos_error(int errlevel, int errcode, char *errmsg, ...) +{ + char buffer[1024]; + va_list args; + va_start(args, errmsg); + vsprintf(buffer, errmsg, args); + /* Execute the error handler function */ + if (_error_handler) + _error_handler(errlevel, errcode, buffer); + else + elog(errlevel, "%s", buffer); + va_end(args); + return; +} + +/*****************************************************************************/ + +#if MEOS +/* + * Initialize MEOS library + */ +void +meos_initialize(const char *tz_str, error_handler_fn err_handler) +{ + meos_initialize_timezone(tz_str); + meos_initialize_error_handler(err_handler); + return; +} + +/* + * Free the timezone cache + */ +void +meos_finalize(void) +{ + meos_finalize_timezone(); + return; +} +#endif /* MEOS */ + +/*****************************************************************************/ diff --git a/meos/src/general/lifting.c b/meos/src/general/lifting.c index 099abc55b9..3d004be96d 100644 --- a/meos/src/general/lifting.c +++ b/meos/src/general/lifting.c @@ -111,8 +111,11 @@ * resvalue = (*lfinfo->func)(temporalinst_value(inst), lfinfo->param[0]); * resvalue = (*lfinfo->func)(temporalinst_value(inst), lfinfo->param[0]); * else - * elog(ERROR, "Number of function parameters not supported: %u", - * lfinfo->numparam); + * { + * meos_error(ERROR, MEOS_ERR_INTERNAL_ERROR, + * "Number of function parameters not supported: %u", lfinfo->numparam); + * return NULL; + * } * TInstant *result = tinstant_make(resvalue, lfinfo->restype, inst->t); * DATUM_FREE(resvalue, temptype_basetype(lfinfo->restype)); * return result; diff --git a/meos/src/general/meos_catalog.c b/meos/src/general/meos_catalog.c index 2b64ae8099..562515192e 100644 --- a/meos/src/general/meos_catalog.c +++ b/meos/src/general/meos_catalog.c @@ -37,6 +37,7 @@ /* C */ #include +#include /* PostgreSQL */ #include #if POSTGRESQL_VERSION_NUMBER >= 130000 @@ -194,8 +195,9 @@ temptype_basetype(meosType temptype) return _temptype_catalog[i].basetype; } /* We only arrive here on error */ - elog(ERROR, "type %u is not a temporal type", temptype); - return T_UNKNOWN; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "type %u is not a temporal type", temptype); + return T_UNKNOWN; } /** @@ -211,8 +213,9 @@ spantype_basetype(meosType spantype) return _spantype_catalog[i].basetype; } /* We only arrive here on error */ - elog(ERROR, "type %u is not a span type", spantype); - return T_UNKNOWN; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "type %u is not a span type", spantype); + return T_UNKNOWN; } /** @@ -228,8 +231,9 @@ spansettype_spantype(meosType spansettype) return _spansettype_catalog[i].spantype; } /* We only arrive here on error */ - elog(ERROR, "type %u is not a span set type", spansettype); - return T_UNKNOWN; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "type %u is not a span set type", spansettype); + return T_UNKNOWN; } /** @@ -245,8 +249,9 @@ basetype_spantype(meosType basetype) return _spantype_catalog[i].spantype; } /* We only arrive here on error */ - elog(ERROR, "type %u is not a span type", basetype); - return T_UNKNOWN; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "type %u is not a span type", basetype); + return T_UNKNOWN; } /** @@ -262,8 +267,9 @@ spantype_spansettype(meosType spantype) return _spansettype_catalog[i].spansettype; } /* We only arrive here on error */ - elog(ERROR, "type %u is not a span type", spantype); - return T_UNKNOWN; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "type %u is not a span type", spantype); + return T_UNKNOWN; } /** @@ -279,8 +285,9 @@ settype_basetype(meosType settype) return _settype_catalog[i].basetype; } /* We only arrive here on error */ - elog(ERROR, "type %u is not a set type", settype); - return T_UNKNOWN; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "type %u is not a set type", settype); + return T_UNKNOWN; } /** @@ -296,8 +303,9 @@ basetype_settype(meosType basetype) return _settype_catalog[i].settype; } /* We only arrive here on error */ - elog(ERROR, "type %u is not a set type", basetype); - return T_UNKNOWN; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "type %u is not a set type", basetype); + return T_UNKNOWN; } /***************************************************************************** @@ -384,8 +392,9 @@ basetype_length(meosType type) if (type == T_NPOINT) return sizeof(Npoint); #endif - elog(ERROR, "unknown base type: %d", type); - return 0; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown base type: %d", type); + return SHRT_MAX; /* make compiler quiet */ } #ifdef DEBUG_BUILD @@ -507,12 +516,16 @@ set_spantype(meosType type) /** * @brief Ensure that a set value is a set type with a span as a bounding box */ -void +bool ensure_set_spantype(meosType type) { if (! set_spantype(type)) - elog(ERROR, "The set value must be a number or timestamp set"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "The set value must be a number or timestamp set"); + return false; + } + return true; } /** @@ -541,12 +554,16 @@ geoset_type(meosType type) /** * @brief Ensure that a set value is a geo set */ -void +bool ensure_geoset_type(meosType type) { if (! geoset_type(type)) - elog(ERROR, "The set value must be a geo set"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "The set value must be a geo set"); + return false; + } + return true; } /** @@ -564,12 +581,16 @@ spatialset_type(meosType type) /** * @brief Ensure that a temporal value is a temporal number */ -void +bool ensure_spatialset_type(meosType type) { if (! spatialset_type(type)) - elog(ERROR, "The set value must be a spatial set"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "The set value must be a spatial set"); + return false; + } + return true; } #endif /* MEOS */ @@ -650,12 +671,16 @@ numspan_type(meosType type) /** * @brief Ensure that a span is a numeric span type */ -void +bool ensure_numspan_type(meosType type) { if (! numspan_type(type)) - elog(ERROR, "The span value must be a numeric span type"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "The span value must be a numeric span type"); + return false; + } + return true; } /** @@ -818,12 +843,16 @@ tnumber_type(meosType type) /** * @brief Ensure that a temporal value is a temporal number */ -void +bool ensure_tnumber_type(meosType type) { if (! tnumber_type(type)) - elog(ERROR, "The temporal value must be a temporal number"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "The temporal value must be a temporal number"); + return false; + } + return true; } /** @@ -880,6 +909,22 @@ tspatial_type(meosType type) return false; } +/** + * @brief Ensure that a temporal value is a temporal point or network point + */ +bool +ensure_tspatial_type(meosType type) +{ + if (! tspatial_type(type)) + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "The temporal value must be a temporal point type"); + return false; + } + return true; +} + + /** * @brief Return true if the type is a base type of a spatiotemporal type * @note This function is used for features common to all spatiotemporal types, @@ -911,12 +956,31 @@ tgeo_type(meosType type) /** * @brief Ensure that a temporal value is a temporal point type */ -void +bool ensure_tgeo_type(meosType type) { if (! tgeo_type(type)) - elog(ERROR, "The temporal value must be a temporal point type"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "The temporal value must be a temporal point type"); + return false; + } + return true; +} + +/** + * @brief Ensure that a temporal value is a temporal point type + */ +bool +ensure_tnumber_tgeo_type(meosType type) +{ + if (! tnumber_type(type) && ! tgeo_type(type)) + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "The temporal value must be a temporal number or a temporal point type"); + return false; + } + return true; } /*****************************************************************************/ diff --git a/meos/src/general/pg_types.c b/meos/src/general/pg_types.c index 6aa63fd1f8..b1375dbc75 100644 --- a/meos/src/general/pg_types.c +++ b/meos/src/general/pg_types.c @@ -124,7 +124,10 @@ pg_dsin(float8 arg1) errno = 0; result = sin(arg1); if (errno != 0 || isinf(arg1)) - elog(ERROR, "input is out of range"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, "input is out of range"); + return DBL_MAX; + } if (unlikely(isinf(result))) float_overflow_error(); @@ -162,7 +165,10 @@ pg_dcos(float8 arg1) errno = 0; result = cos(arg1); if (errno != 0 || isinf(arg1)) - elog(ERROR, "input is out of range"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, "input is out of range"); + return DBL_MAX; + } if (unlikely(isinf(result))) float_overflow_error(); @@ -231,6 +237,10 @@ pg_datan2(float8 arg1, float8 arg2) DateADT pg_date_in(const char *str) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return DATEVAL_NOEND; + DateADT date; fsec_t fsec; struct pg_tm tt, *tm = &tt; @@ -285,13 +295,21 @@ pg_date_in(const char *str) /* Prevent overflow in Julian-day routines */ if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday)) - elog(ERROR, "date out of range: \"%s\"", str); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, + "date out of range: \"%s\"", str); + return DATEVAL_NOEND; + } date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE; /* Now check for just-out-of-range dates */ if (!IS_VALID_DATE(date)) - elog(ERROR, "date out of range: \"%s\"", str); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, + "date out of range: \"%s\"", str); + return DATEVAL_NOEND; + } return date; } @@ -379,6 +397,10 @@ MEOSAdjustTimeForTypmod(TimeADT *time, int32 typmod) TimeADT pg_time_in(const char *str, int32 typmod) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return DT_NOEND; + TimeADT result; fsec_t fsec; struct pg_tm tt, *tm = &tt; @@ -434,7 +456,6 @@ pg_time_out(TimeADT time) #if ! MEOS /** - * @ingroup libmeos_pg_types * @brief Convert a string into a timestamp with timezone. * @note PostgreSQL function: Datum timestamptz_in(PG_FUNCTION_ARGS) */ @@ -486,8 +507,10 @@ MEOSAdjustTimestampForTypmodError(Timestamp *time, int32 typmod, bool *error) return false; } - elog(ERROR, "timestamp(%d) precision must be between %d and %d", + meos_error(ERROR, MEOS_ERR_INVALID_ARG, + "timestamp(%d) precision must be between %d and %d", typmod, 0, MAX_TIMESTAMP_PRECISION); + return false; } if (*time >= INT64CONST(0)) @@ -519,6 +542,10 @@ MEOSAdjustTimestampForTypmod(Timestamp *time, int32 typmod) TimestampTz timestamp_in_common(const char *str, int32 typmod, bool withtz) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return DT_NOEND; + TimestampTz result; fsec_t fsec; struct pg_tm tt, @@ -563,7 +590,11 @@ timestamp_in_common(const char *str, int32 typmod, bool withtz) tm2timestamp(tm, fsec, &tz, &result) : tm2timestamp(tm, fsec, NULL, &result); if (status != 0) - elog(ERROR, "timestamp out of range: \"%s\"", str); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, + "timestamp out of range: \"%s\"", str); + return DT_NOEND; + } break; } case DTK_EPOCH: @@ -579,7 +610,8 @@ timestamp_in_common(const char *str, int32 typmod, bool withtz) break; default: - elog(ERROR, "unexpected dtype %d while parsing timestamp%s \"%s\"", + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "unexpected dtype %d while parsing timestamp%s \"%s\"", dtype, (withtz) ? "tz" : "", str); TIMESTAMP_NOEND(result); } @@ -614,7 +646,6 @@ pg_timestamp_in(const char *str, int32 typmod) #if ! MEOS /** - * @ingroup libmeos_pg_types * @brief Convert a timestamp with timezone to a string. * @note PostgreSQL function: Datum timestamptz_out(PG_FUNCTION_ARGS) */ @@ -647,7 +678,10 @@ timestamp_out_common(TimestampTz dt, bool withtz) else if (! withtz && timestamp2tm(dt, NULL, tm, &fsec, NULL, NULL) == 0) EncodeDateTime(tm, fsec, false, 0, NULL, DateStyle, buf); else - elog(ERROR, "timestamp out of range"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, "timestamp out of range"); + return NULL; + } result = pstrdup(buf); return result; @@ -818,14 +852,19 @@ AdjustIntervalForTypmod(Interval *interval, int32 typmod) /* fractional-second rounding will be dealt with below */ } else - elog(ERROR, "unrecognized interval typmod: %d", typmod); + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "unrecognized interval typmod: %d", typmod); /* Need to adjust sub-second precision? */ if (precision != INTERVAL_FULL_PRECISION) { if (precision < 0 || precision > MAX_INTERVAL_PRECISION) - elog(ERROR, "interval(%d) precision must be between %d and %d", - precision, 0, MAX_INTERVAL_PRECISION); + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "interval(%d) precision must be between %d and %d", + precision, 0, MAX_INTERVAL_PRECISION); + return; + } if (interval->time >= INT64CONST(0)) { @@ -903,12 +942,17 @@ pg_interval_in(const char *str, int32 typmod) { case DTK_DELTA: if (tm2interval(tm, fsec, result) != 0) - elog(ERROR, "interval out of range"); + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, + "interval out of range"); + pfree(result); + return NULL; break; default: - elog(ERROR, "unexpected dtype %d while parsing interval \"%s\"", - dtype, str); + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "unexpected dtype %d while parsing interval \"%s\"", dtype, str); + pfree(result); + return NULL; } AdjustIntervalForTypmod(result, typmod); @@ -932,7 +976,10 @@ pg_interval_make(int32 years, int32 months, int32 weeks, int32 days, int32 hours * inputs as well, but it's not entirely clear what limits to apply. */ if (isinf(secs) || isnan(secs)) - elog(ERROR, "interval out of range"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, "interval out of range"); + return NULL; + } result = (Interval *) palloc(sizeof(Interval)); result->month = years * MONTHS_PER_YEAR + months; @@ -959,7 +1006,11 @@ pg_interval_out(const Interval *span) char buf[MAXDATELEN + 1]; if (interval2tm(*span, tm, &fsec) != 0) - elog(ERROR, "could not convert interval to tm"); + { + meos_error(ERROR, MEOS_ERR_INTERNAL_ERROR, + "could not convert interval to tm"); + return NULL; + } EncodeInterval(tm, fsec, IntervalStyle, buf); @@ -985,13 +1036,19 @@ pg_interval_mul(const Interval *span, double factor) result_double = span->month * factor; if (isnan(result_double) || result_double > INT_MAX || result_double < INT_MIN) - elog(ERROR, "interval out of range"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, "interval out of range"); + return NULL; + } result->month = (int32) result_double; result_double = span->day * factor; if (isnan(result_double) || result_double > INT_MAX || result_double < INT_MIN) - elog(ERROR, "interval out of range"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, "interval out of range"); + return NULL; + } result->day = (int32) result_double; /* @@ -1033,7 +1090,10 @@ pg_interval_mul(const Interval *span, double factor) result->day += (int32) month_remainder_days; result_double = rint(span->time * factor + sec_remainder * USECS_PER_SEC); if (isnan(result_double) || !FLOAT8_FITS_IN_INT64(result_double)) - elog(ERROR, "interval out of range"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, "interval out of range"); + return NULL; + } result->time = (int64) result_double; return result; @@ -1058,17 +1118,26 @@ pg_interval_pl(const Interval *span1, const Interval *span2) /* overflow check copied from int4pl */ if (SAMESIGN(span1->month, span2->month) && ! SAMESIGN(result->month, span1->month)) - elog(ERROR, "interval out of range"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, "interval out of range"); + return NULL; + } result->day = span1->day + span2->day; if (SAMESIGN(span1->day, span2->day) && ! SAMESIGN(result->day, span1->day)) - elog(ERROR, "interval out of range"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, "interval out of range"); + return NULL; + } result->time = span1->time + span2->time; if (SAMESIGN(span1->time, span2->time) && ! SAMESIGN(result->time, span1->time)) - elog(ERROR, "interval out of range"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, "interval out of range"); + return NULL; + } return result; } @@ -1102,7 +1171,11 @@ pg_timestamp_pl_interval(TimestampTz timestamp, const Interval *span) fsec_t fsec; if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0) - elog(ERROR, "timestamp out of range"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, + "timestamp out of range"); + return DT_NOEND; + } tm->tm_mon += span->month; if (tm->tm_mon > MONTHS_PER_YEAR) @@ -1121,7 +1194,11 @@ pg_timestamp_pl_interval(TimestampTz timestamp, const Interval *span) tm->tm_mday = (day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]); if (tm2timestamp(tm, fsec, NULL, ×tamp) != 0) - elog(ERROR, "timestamp out of range"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, + "timestamp out of range"); + return DT_NOEND; + } } if (span->day != 0) @@ -1132,20 +1209,32 @@ pg_timestamp_pl_interval(TimestampTz timestamp, const Interval *span) int julian; if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL, NULL) != 0) - elog(ERROR, "timestamp out of range"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, + "timestamp out of range"); + return DT_NOEND; + } /* Add days by converting to and from Julian */ julian = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) + span->day; j2date(julian, &tm->tm_year, &tm->tm_mon, &tm->tm_mday); if (tm2timestamp(tm, fsec, NULL, ×tamp) != 0) - elog(ERROR, "timestamp out of range"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, + "timestamp out of range"); + return DT_NOEND; + } } timestamp += span->time; if (!IS_VALID_TIMESTAMP(timestamp)) - elog(ERROR, "timestamp out of range"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, + "timestamp out of range"); + return DT_NOEND; + } result = timestamp; } @@ -1212,8 +1301,13 @@ pg_interval_justify_hours(const Interval *span) Interval * pg_timestamp_mi(TimestampTz dt1, TimestampTz dt2) { + /* Ensure validity of the arguments */ if (TIMESTAMP_NOT_FINITE(dt1) || TIMESTAMP_NOT_FINITE(dt2)) - elog(ERROR, "cannot subtract infinite timestamps"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, + "cannot subtract infinite timestamps"); + return NULL; + } Interval interval; interval.time = dt1 - dt2; @@ -1263,6 +1357,11 @@ interval_cmp_value(const Interval *interval) int pg_interval_cmp(const Interval *interval1, const Interval *interval2) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) interval1) || + ! ensure_not_null((void *) interval2)) + return INT_MAX; + INT128 span1 = interval_cmp_value(interval1); INT128 span2 = interval_cmp_value(interval2); return int128_compare(span1, span2); diff --git a/meos/src/general/set.c b/meos/src/general/set.c index f228ffb7b5..12c4c755d3 100644 --- a/meos/src/general/set.c +++ b/meos/src/general/set.c @@ -37,6 +37,8 @@ /* C */ #include +#include +#include /* PostgreSQL */ #include #include @@ -62,25 +64,33 @@ /** * @brief Ensure that a set value is of a set type */ -void +bool ensure_set_has_type(const Set *s, meosType settype) { if (s->settype != settype) - elog(ERROR, "The set value must be of type %s", meostype_name(settype)); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "The set value must be of type %s", meostype_name(settype)); + return false; + } + return true; } /** * @brief Ensure that the set arguments have the same type in order to be able * to apply operations to them */ -void +bool ensure_same_set_type(const Set *s1, const Set *s2) { if (s1->settype != s2->settype) - elog(ERROR, "Operation on mixed set types: %s and %s", + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "Operation on mixed set types: %s and %s", meostype_name(s1->settype), meostype_name(s2->settype)); - return; + return false; + } + return true; } #if MEOS @@ -89,13 +99,17 @@ ensure_same_set_type(const Set *s1, const Set *s2) * @param[in] s Input value * @param[in] basetype Input base type */ -void +bool ensure_same_set_basetype(const Set *s, meosType basetype) { if (s->basetype != basetype) - elog(ERROR, "Operation on mixed set and base types: %s and %s", + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "Operation on mixed set and base types: %s and %s", meostype_name(s->settype), meostype_name(basetype)); - return; + return false; + } + return true; } #endif /* MEOS */ @@ -201,7 +215,9 @@ set_in(const char *str, meosType settype) Set * intset_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return set_parse(&str, T_INTSET); } @@ -212,7 +228,9 @@ intset_in(const char *str) Set * bigintset_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return set_parse(&str, T_BIGINTSET); } @@ -223,7 +241,9 @@ bigintset_in(const char *str) Set * floatset_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return set_parse(&str, T_FLOATSET); } @@ -234,7 +254,9 @@ floatset_in(const char *str) Set * textset_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return set_parse(&str, T_TEXTSET); } @@ -245,7 +267,9 @@ textset_in(const char *str) Set * timestampset_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return set_parse(&str, T_TSTZSET); } @@ -256,7 +280,9 @@ timestampset_in(const char *str) Set * geomset_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return set_parse(&str, T_GEOMSET); } @@ -267,7 +293,9 @@ geomset_in(const char *str) Set * geogset_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return set_parse(&str, T_GEOGSET); } #endif /* MEOS */ @@ -291,9 +319,8 @@ set_basetype_quotes(meosType type) char * set_out_fn(const Set *s, int maxdd, outfunc value_out) { - /* Ensure validity of the arguments */ assert(s != NULL); - ensure_non_negative(maxdd); + assert(maxdd >= 0); char **strings = palloc(sizeof(char *) * s->count); size_t outlen = 0; @@ -327,8 +354,9 @@ set_out(const Set *s, int maxdd) char * intset_out(const Set *s) { - assert(s); - ensure_set_has_type(s, T_INTSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_INTSET)) + return NULL; return set_out(s, 0); } @@ -339,8 +367,9 @@ intset_out(const Set *s) char * bigintset_out(const Set *s) { - assert(s); - ensure_set_has_type(s, T_BIGINTSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_BIGINTSET)) + return NULL; return set_out(s, 0); } @@ -351,8 +380,9 @@ bigintset_out(const Set *s) char * floatset_out(const Set *s, int maxdd) { - assert(s); - ensure_set_has_type(s, T_FLOATSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_FLOATSET)) + return NULL; return set_out(s, maxdd); } @@ -363,8 +393,9 @@ floatset_out(const Set *s, int maxdd) char * textset_out(const Set *s) { - assert(s); - ensure_set_has_type(s, T_TEXTSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_TEXTSET)) + return NULL; return set_out(s, 0); } @@ -375,8 +406,9 @@ textset_out(const Set *s) char * timestampset_out(const Set *s) { - assert(s); - ensure_set_has_type(s, T_TSTZSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_TSTZSET)) + return NULL; return set_out(s, 0); } @@ -387,8 +419,9 @@ timestampset_out(const Set *s) char * geoset_out(const Set *s, int maxdd) { - assert(s); - ensure_geoset_type(s->settype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_geoset_type(s->settype)) + return NULL; return set_out(s, maxdd); } #endif /* MEOS */ @@ -401,8 +434,9 @@ geoset_out(const Set *s, int maxdd) char * geoset_as_text(const Set *s, int maxdd) { - assert(s); - ensure_geoset_type(s->settype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_geoset_type(s->settype)) + return NULL; return set_out_fn(s, maxdd, &wkt_out); } @@ -414,8 +448,9 @@ geoset_as_text(const Set *s, int maxdd) char * geoset_as_ewkt(const Set *s, int maxdd) { - assert(s); - ensure_geoset_type(s->settype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_geoset_type(s->settype)) + return NULL; return set_out_fn(s, maxdd, &ewkt_out); } @@ -433,8 +468,9 @@ set_bbox_size(meosType settype) return 0; if (spatialset_type(settype)) return sizeof(STBox); - elog(ERROR, "unknown set_bbox_size function for set type: %d", settype); - return 0; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown set_bbox_size function for set type: %d", settype); + return SIZE_MAX; } /** @@ -459,7 +495,8 @@ valuearr_compute_bbox(const Datum *values, meosType basetype, int count, npointarr_set_stbox(values, count, (STBox *) box); #endif else - elog(ERROR, "unknown set type for computing bounding box: %d", basetype); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown set type for computing bounding box: %d", basetype); return; } @@ -564,10 +601,11 @@ set_make_exp(const Datum *values, int count, int maxcount, meosType basetype, { /* Test that the geometry is not empty */ GSERIALIZED *gs2 = DatumGetGserializedP(values[i]); - ensure_point_type(gs2); - ensure_same_srid(srid, gserialized_get_srid(gs2)); - ensure_same_dimensionality_gs(gs1, gs2); - ensure_non_empty(gs2); + if (! ensure_point_type(gs2) || + ! ensure_same_srid(srid, gserialized_get_srid(gs2)) || + ! ensure_same_dimensionality_gs(gs1, gs2) || + ! ensure_non_empty(gs2)) + return NULL; } } @@ -702,8 +740,10 @@ set_make(const Datum *values, int count, meosType basetype, bool ordered) Set * intset_make(const int *values, int count) { - assert(values); - assert(count > 0); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) values) || ! ensure_positive(count)) + return NULL; + Datum *datums = palloc(sizeof(Datum *) * count); for (int i = 0; i < count; ++i) datums[i] = Int32GetDatum(values[i]); @@ -717,8 +757,10 @@ intset_make(const int *values, int count) Set * bigintset_make(const int64 *values, int count) { - assert(values); - assert(count > 0); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) values) || !ensure_positive(count)) + return NULL; + Datum *datums = palloc(sizeof(Datum *) * count); for (int i = 0; i < count; ++i) datums[i] = Int64GetDatum(values[i]); @@ -732,8 +774,10 @@ bigintset_make(const int64 *values, int count) Set * floatset_make(const double *values, int count) { - assert(values); - assert(count > 0); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) values) || ! ensure_positive(count)) + return NULL; + Datum *datums = palloc(sizeof(Datum *) * count); for (int i = 0; i < count; ++i) datums[i] = Float8GetDatum(values[i]); @@ -747,8 +791,10 @@ floatset_make(const double *values, int count) Set * textset_make(const text **values, int count) { - assert(values); - assert(count > 0); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) values) || ! ensure_positive(count)) + return NULL; + Datum *datums = palloc(sizeof(Datum *) * count); for (int i = 0; i < count; ++i) datums[i] = PointerGetDatum(values[i]); @@ -762,8 +808,10 @@ textset_make(const text **values, int count) Set * timestampset_make(const TimestampTz *values, int count) { - assert(values); - assert(count > 0); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) values) || ! ensure_positive(count)) + return NULL; + Datum *datums = palloc(sizeof(Datum *) * count); for (int i = 0; i < count; ++i) datums[i] = TimestampTzGetDatum(values[i]); @@ -777,13 +825,16 @@ timestampset_make(const TimestampTz *values, int count) Set * geoset_make(const GSERIALIZED **values, int count) { - assert(values); - assert(count > 0); - bool geodetic = (bool) FLAGS_GET_GEODETIC(values[0]->gflags); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) values) || ! ensure_positive(count)) + return NULL; + Datum *datums = palloc(sizeof(Datum *) * count); for (int i = 0; i < count; ++i) datums[i] = PointerGetDatum(values[i]); - return set_make(datums, count, geodetic ? T_GEOMETRY : T_GEOGRAPHY, ORDERED); + meosType geotype = FLAGS_GET_GEODETIC(values[0]->gflags) ? + T_GEOMETRY : T_GEOGRAPHY; + return set_make(datums, count, geotype, ORDERED); } #endif /* MEOS */ @@ -817,7 +868,9 @@ set_make_free(Datum *values, int count, meosType basetype, bool ordered) Set * set_copy(const Set *s) { - assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return NULL; Set *result = palloc(VARSIZE(s)); memcpy(result, s, VARSIZE(s)); return result; @@ -883,7 +936,9 @@ float_to_floatset(double d) Set * text_to_textset(text *txt) { - assert(txt); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) txt)) + return NULL; Datum v = PointerGetDatum(txt); return set_make(&v, 1, T_TEXT, ORDERED); } @@ -902,28 +957,18 @@ timestamp_to_tstzset(TimestampTz t) /** * @ingroup libmeos_setspan_cast - * @brief Cast a text as a set - * @sqlop @p :: - */ -Set * -geom_to_geomset(GSERIALIZED *gs) -{ - assert(gs); - Datum v = PointerGetDatum(gs); - return set_make(&v, 1, T_GEOMETRY, ORDERED); -} - -/** - * @ingroup libmeos_setspan_cast - * @brief Cast a text as a set + * @brief Cast a geometry/geograph as a geoset * @sqlop @p :: */ Set * -geog_to_geogset(GSERIALIZED *gs) +geo_to_geoset(GSERIALIZED *gs) { - assert(gs); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs)) + return NULL; Datum v = PointerGetDatum(gs); - return set_make(&v, 1, T_GEOGRAPHY, ORDERED); + meosType geotype = FLAGS_GET_GEODETIC(gs->gflags) ? T_GEOGRAPHY : T_GEOMETRY; + return set_make(&v, 1, geotype, ORDERED); } #endif /* MEOS */ @@ -934,8 +979,7 @@ geog_to_geogset(GSERIALIZED *gs) void set_set_span(const Set *set, Span *s) { - assert(set); - assert(s); + assert(set); assert(s); span_set(SET_VAL_N(set, MINIDX), SET_VAL_N(set, set->MAXIDX), true, true, set->basetype, s); return; @@ -953,8 +997,10 @@ set_set_span(const Set *set, Span *s) STBox * spatialset_stbox(const Set *s) { - assert(s); - ensure_spatialset_type(s->settype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_spatialset_type(s->settype)) + return NULL; + STBox *result = palloc(sizeof(STBox)); spatialset_set_stbox(s, result); return result; @@ -968,7 +1014,7 @@ spatialset_stbox(const Set *s) void spatialset_set_stbox(const Set *s, STBox *box) { - assert(s); + assert(s); assert(box); assert(spatialset_type(s->settype)); memset(box, 0, sizeof(STBox)); memcpy(box, SET_BBOX_PTR(s), sizeof(STBox)); @@ -1002,8 +1048,10 @@ set_mem_size(const Set *s) Span * set_span(const Set *s) { - assert(s); - ensure_set_spantype(s->settype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_spantype(s->settype)) + return NULL; + Span *result = palloc(sizeof(Span)); set_set_span(s, result); return result; @@ -1017,7 +1065,9 @@ set_span(const Set *s) int set_num_values(const Set *s) { - assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return -1; return s->count; } @@ -1042,8 +1092,9 @@ set_start_value(const Set *s) int intset_start_value(const Set *s) { - assert(s); - ensure_set_has_type(s, T_INTSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_INTSET)) + return INT_MAX; int result = DatumGetInt32(SET_VAL_N(s, 0)); return result; } @@ -1056,8 +1107,9 @@ intset_start_value(const Set *s) int64 bigintset_start_value(const Set *s) { - assert(s); - ensure_set_has_type(s, T_BIGINTSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_BIGINTSET)) + return INT_MAX; int64 result = DatumGetInt64(SET_VAL_N(s, 0)); return result; } @@ -1070,8 +1122,9 @@ bigintset_start_value(const Set *s) double floatset_start_value(const Set *s) { - assert(s); - ensure_set_has_type(s, T_FLOATSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_FLOATSET)) + return DBL_MAX; double result = DatumGetFloat8(SET_VAL_N(s, 0)); return result; } @@ -1084,8 +1137,9 @@ floatset_start_value(const Set *s) text * textset_start_value(const Set *s) { - assert(s); - ensure_set_has_type(s, T_TEXTSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_TEXTSET)) + return NULL; text *result = DatumGetTextP(SET_VAL_N(s, 0)); return result; } @@ -1098,8 +1152,9 @@ textset_start_value(const Set *s) TimestampTz timestampset_start_timestamp(const Set *s) { - assert(s); - ensure_set_has_type(s, T_TSTZSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_TSTZSET)) + return DT_NOEND; TimestampTz result = DatumGetTimestampTz(SET_VAL_N(s, 0)); return result; } @@ -1112,8 +1167,9 @@ timestampset_start_timestamp(const Set *s) GSERIALIZED * geoset_start_value(const Set *s) { - assert(s); - ensure_geoset_type(s->settype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_geoset_type(s->settype)) + return NULL; GSERIALIZED *result = DatumGetGserializedP(SET_VAL_N(s, 0)); return result; } @@ -1140,8 +1196,9 @@ set_end_value(const Set *s) int intset_end_value(const Set *s) { - assert(s); - ensure_set_has_type(s, T_INTSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_INTSET)) + return INT_MAX; int result = DatumGetInt32(SET_VAL_N(s, 0)); return result; } @@ -1154,8 +1211,9 @@ intset_end_value(const Set *s) int64 bigintset_end_value(const Set *s) { - assert(s); - ensure_set_has_type(s, T_BIGINTSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_BIGINTSET)) + return INT_MAX; int64 result = DatumGetInt64(SET_VAL_N(s, s->count - 1)); return result; } @@ -1168,8 +1226,9 @@ bigintset_end_value(const Set *s) double floatset_end_value(const Set *s) { - assert(s); - ensure_set_has_type(s, T_FLOATSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_FLOATSET)) + return DBL_MAX; double result = DatumGetFloat8(SET_VAL_N(s, s->count - 1)); return result; } @@ -1182,8 +1241,9 @@ floatset_end_value(const Set *s) text * textset_end_value(const Set *s) { - assert(s); - ensure_set_has_type(s, T_TEXTSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_TEXTSET)) + return NULL; text *result = DatumGetTextP(SET_VAL_N(s, s->count - 1)); return result; } @@ -1196,8 +1256,9 @@ textset_end_value(const Set *s) TimestampTz timestampset_end_timestamp(const Set *s) { - assert(s); - ensure_set_has_type(s, T_TSTZSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_TSTZSET)) + return DT_NOEND; TimestampTz result = DatumGetTimestampTz(SET_VAL_N(s, s->count - 1)); return result; } @@ -1210,8 +1271,9 @@ timestampset_end_timestamp(const Set *s) GSERIALIZED * geoset_end_value(const Set *s) { - assert(s); - ensure_geoset_type(s->settype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_geoset_type(s->settype)) + return NULL; GSERIALIZED *result = DatumGetGserializedP(SET_VAL_N(s, s->count - 1)); return result; } @@ -1251,9 +1313,9 @@ set_value_n(const Set *s, int n, Datum *result) bool intset_value_n(const Set *s, int n, int *result) { - assert(s); assert(result); - ensure_set_has_type(s, T_INTSET); - if (n < 1 || n > s->count) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_set_has_type(s, T_INTSET) || n < 1 || n > s->count) return false; *result = DatumGetInt32(SET_VAL_N(s, n - 1)); return true; @@ -1272,9 +1334,9 @@ intset_value_n(const Set *s, int n, int *result) bool bigintset_value_n(const Set *s, int n, int64 *result) { - assert(s); assert(result); - ensure_set_has_type(s, T_BIGINTSET); - if (n < 1 || n > s->count) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_set_has_type(s, T_BIGINTSET) || n < 1 || n > s->count) return false; *result = DatumGetInt64(SET_VAL_N(s, n - 1)); return true; @@ -1293,9 +1355,9 @@ bigintset_value_n(const Set *s, int n, int64 *result) bool floatset_value_n(const Set *s, int n, double *result) { - assert(s); assert(result); - ensure_set_has_type(s, T_FLOATSET); - if (n < 1 || n > s->count) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_set_has_type(s, T_FLOATSET) || n < 1 || n > s->count) return false; *result = DatumGetFloat8(SET_VAL_N(s, n - 1)); return true; @@ -1314,9 +1376,9 @@ floatset_value_n(const Set *s, int n, double *result) bool textset_value_n(const Set *s, int n, text **result) { - assert(s); assert(result); - ensure_set_has_type(s, T_TEXTSET); - if (n < 1 || n > s->count) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_set_has_type(s, T_TEXTSET) || n < 1 || n > s->count) return false; *result = DatumGetTextP(SET_VAL_N(s, n - 1)); return true; @@ -1335,9 +1397,9 @@ textset_value_n(const Set *s, int n, text **result) bool timestampset_timestamp_n(const Set *s, int n, TimestampTz *result) { - assert(s); assert(result); - ensure_set_has_type(s, T_TSTZSET); - if (n < 1 || n > s->count) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_set_has_type(s, T_TSTZSET) || n < 1 || n > s->count) return false; *result = DatumGetTimestampTz(SET_VAL_N(s, n - 1)); return true; @@ -1356,9 +1418,9 @@ timestampset_timestamp_n(const Set *s, int n, TimestampTz *result) bool geoset_value_n(const Set *s, int n, GSERIALIZED **result) { - assert(s); assert(result); - ensure_geoset_type(s->settype); - if (n < 1 || n > s->count) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_geoset_type(s->settype) ||n < 1 || n > s->count) return false; *result = DatumGetGserializedP(SET_VAL_N(s, n - 1)); return true; @@ -1389,8 +1451,10 @@ set_values(const Set *s) int * intset_values(const Set *s) { - assert(s); - ensure_set_has_type(s, T_INTSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_INTSET)) + return NULL; + int *result = palloc(sizeof(int) * s->count); for (int i = 0; i < s->count; i++) result[i] = DatumGetInt32(SET_VAL_N(s, i)); @@ -1405,8 +1469,10 @@ intset_values(const Set *s) int64 * bigintset_values(const Set *s) { - assert(s); - ensure_set_has_type(s, T_BIGINTSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_BIGINTSET)) + return NULL; + int64 *result = palloc(sizeof(int64) * s->count); for (int i = 0; i < s->count; i++) result[i] = DatumGetInt64(SET_VAL_N(s, i)); @@ -1421,8 +1487,10 @@ bigintset_values(const Set *s) double * floatset_values(const Set *s) { - assert(s); - ensure_set_has_type(s, T_FLOATSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_FLOATSET)) + return NULL; + double *result = palloc(sizeof(double) * s->count); for (int i = 0; i < s->count; i++) result[i] = DatumGetFloat8(SET_VAL_N(s, i)); @@ -1437,8 +1505,10 @@ floatset_values(const Set *s) text ** textset_values(const Set *s) { - assert(s); - ensure_set_has_type(s, T_TEXTSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_TEXTSET)) + return NULL; + text **result = palloc(sizeof(text *) * s->count); for (int i = 0; i < s->count; i++) result[i] = DatumGetTextP(SET_VAL_N(s, i)); @@ -1453,8 +1523,10 @@ textset_values(const Set *s) TimestampTz * timestampset_values(const Set *s) { - assert(s); - ensure_set_has_type(s, T_TSTZSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_TSTZSET)) + return NULL; + TimestampTz *result = palloc(sizeof(TimestampTz) * s->count); for (int i = 0; i < s->count; i++) result[i] = DatumGetTimestampTz(SET_VAL_N(s, i)); @@ -1469,8 +1541,10 @@ timestampset_values(const Set *s) GSERIALIZED ** geoset_values(const Set *s) { - assert(s); - ensure_geoset_type(s->settype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_geoset_type(s->settype)) + return NULL; + GSERIALIZED **result = palloc(sizeof(GSERIALIZED *) * s->count); for (int i = 0; i < s->count; i++) result[i] = DatumGetGserializedP(SET_VAL_N(s, i)); @@ -1486,8 +1560,10 @@ geoset_values(const Set *s) int geoset_srid(const Set *s) { - assert(s); - ensure_geoset_type(s->settype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_geoset_type(s->settype)) + return SRID_INVALID; + GSERIALIZED *gs = DatumGetGserializedP(SET_VAL_N(s, 0)); return gserialized_get_srid(gs); } @@ -1504,9 +1580,9 @@ Set * floatset_round(const Set *s, int maxdd) { /* Ensure validity of the arguments */ - assert(s); - ensure_set_has_type(s, T_FLOATSET); - ensure_non_negative(maxdd); + if (! ensure_not_null((void *) s) || ! ensure_set_has_type(s, T_FLOATSET) || + ! ensure_non_negative(maxdd)) + return NULL; Set *result = set_copy(s); Datum size = Int32GetDatum(maxdd); @@ -1523,9 +1599,9 @@ Set * geoset_round(const Set *s, int maxdd) { /* Ensure validity of the arguments */ - assert(s); - ensure_geoset_type(s->settype); - ensure_non_negative(maxdd); + if (! ensure_not_null((void *) s) || ! ensure_geoset_type(s->settype) || + ! ensure_non_negative(maxdd)) + return NULL; Datum *values = palloc(sizeof(Datum) * s->count); Datum size = Int32GetDatum(maxdd); @@ -1568,12 +1644,14 @@ Set * timestampset_shift_tscale(const Set *s, const Interval *shift, const Interval *duration) { - assert(shift || duration); - if (duration) - ensure_valid_duration(duration); - ensure_set_has_type(s, T_TSTZSET); - Set *result = set_copy(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_set_has_type(s, T_TSTZSET) || + ! ensure_one_not_null((void *) shift, (void *) duration) || + (duration && ! ensure_valid_duration(duration))) + return NULL; + Set *result = set_copy(s); /* Set the first and last instants */ TimestampTz lower, lower1, upper, upper1; lower = lower1 = DatumGetTimestampTz(SET_VAL_N(s, 0)); @@ -1615,8 +1693,11 @@ timestampset_shift_tscale(const Set *s, const Interval *shift, bool set_eq(const Set *s1, const Set *s2) { - assert(s1); assert(s2); - ensure_same_set_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_set_type(s1, s2)) + return false; + if (s1->count != s2->count) return false; /* s1 and s2 have the same number of values */ @@ -1654,8 +1735,11 @@ set_ne(const Set *s1, const Set *s2) int set_cmp(const Set *s1, const Set *s2) { - assert(s1); assert(s2); - ensure_same_set_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_set_type(s1, s2)) + return INT_MAX; + int count = Min(s1->count, s2->count); int result = 0; for (int i = 0; i < count; i++) @@ -1739,7 +1823,10 @@ set_gt(const Set *s1, const Set *s2) uint32 set_hash(const Set *s) { - assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return INT_MAX; + uint32 result = 1; for (int i = 0; i < s->count; i++) { @@ -1758,7 +1845,10 @@ set_hash(const Set *s) uint64 set_hash_extended(const Set *s, uint64 seed) { - assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return INT_MAX; + uint64 result = 1; for (int i = 0; i < s->count; i++) { diff --git a/meos/src/general/set_aggfuncs_meos.c b/meos/src/general/set_aggfuncs_meos.c index dc606acdd3..741f7e888c 100644 --- a/meos/src/general/set_aggfuncs_meos.c +++ b/meos/src/general/set_aggfuncs_meos.c @@ -77,7 +77,8 @@ set_expand_bbox(Datum d, meosType basetype, void *box) } #endif else - elog(ERROR, "unknown set type for expanding bounding box: %d", basetype); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown set type for expanding bounding box: %d", basetype); return; } diff --git a/meos/src/general/set_ops.c b/meos/src/general/set_ops.c index d42f95ff99..185a70fa45 100644 --- a/meos/src/general/set_ops.c +++ b/meos/src/general/set_ops.c @@ -52,6 +52,7 @@ bool bbox_overlaps_set_set(const Set *s1, const Set *s2) { + assert(s1); assert(s2); assert(s1->settype == s2->settype); Datum min1 = SET_VAL_N(s1, MINIDX); Datum min2 = SET_VAL_N(s2, MINIDX); @@ -69,6 +70,7 @@ bbox_overlaps_set_set(const Set *s1, const Set *s2) bool bbox_contains_set_set(const Set *s1, const Set *s2) { + assert(s1); assert(s2); assert(s1->settype == s2->settype); Datum min1 = SET_VAL_N(s1, MINIDX); Datum min2 = SET_VAL_N(s2, MINIDX); @@ -196,8 +198,9 @@ contains_set_value(const Set *s, Datum d, meosType basetype) bool contains_intset_int(const Set *s, int i) { - assert(s); - ensure_same_set_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT4)) + return false; return contains_set_value(s, Int32GetDatum(i), T_INT4); } @@ -209,8 +212,9 @@ contains_intset_int(const Set *s, int i) bool contains_bigintset_bigint(const Set *s, int64 i) { - assert(s); - ensure_same_set_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT8)) + return false; return contains_set_value(s, Int64GetDatum(i), T_INT8); } @@ -222,8 +226,9 @@ contains_bigintset_bigint(const Set *s, int64 i) bool contains_floatset_float(const Set *s, double d) { - assert(s); - ensure_same_set_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_FLOAT8)) + return false; return contains_set_value(s, Float8GetDatum(d), T_FLOAT8); } @@ -235,8 +240,9 @@ contains_floatset_float(const Set *s, double d) bool contains_textset_text(const Set *s, text *t) { - assert(s); - ensure_same_set_basetype(s, T_TEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_TEXT)) + return false; return contains_set_value(s, PointerGetDatum(t), T_TEXT); } @@ -248,8 +254,10 @@ contains_textset_text(const Set *s, text *t) bool contains_timestampset_timestamp(const Set *s, TimestampTz t) { - assert(s); - ensure_same_set_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_set_basetype(s, T_TIMESTAMPTZ)) + return false; return contains_set_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -262,8 +270,11 @@ contains_timestampset_timestamp(const Set *s, TimestampTz t) bool contains_set_set(const Set *s1, const Set *s2) { - assert(s1); assert(s2); - ensure_same_set_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_set_type(s1, s2)) + return false; + /* Bounding box test */ if (! bbox_contains_set_set(s1, s2)) return false; @@ -309,8 +320,9 @@ contained_value_set(Datum d, meosType basetype, const Set *s) bool contained_int_intset(int i, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT4)) + return false; return contained_value_set(Int32GetDatum(i), T_INT4, s); } @@ -322,8 +334,9 @@ contained_int_intset(int i, const Set *s) bool contained_bigint_bigintset(int64 i, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT8)) + return false; return contained_value_set(Int64GetDatum(i), T_INT8, s); } @@ -335,8 +348,9 @@ contained_bigint_bigintset(int64 i, const Set *s) bool contained_float_floatset(double d, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_FLOAT8)) + return false; return contained_value_set(Float8GetDatum(d), T_FLOAT8, s); } @@ -348,8 +362,9 @@ contained_float_floatset(double d, const Set *s) bool contained_text_textset(text *txt, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_TEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_TEXT)) + return false; return contained_value_set(PointerGetDatum(txt), T_TEXT, s); } @@ -361,8 +376,10 @@ contained_text_textset(text *txt, const Set *s) bool contained_timestamp_timestampset(TimestampTz t, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_set_basetype(s, T_TIMESTAMPTZ)) + return false; return contains_set_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -383,15 +400,18 @@ contained_set_set(const Set *s1, const Set *s2) *****************************************************************************/ /** - * @ingroup libmeos_setspan"_topo + * @ingroup libmeos_setspan_topo * @brief Return true if two sets overlap. * @sqlop @p && */ bool overlaps_set_set(const Set *s1, const Set *s2) { - assert(s1); assert(s2); - ensure_same_set_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_set_type(s1, s2)) + return false; + /* Bounding box test */ if (! bbox_overlaps_set_set(s1, s2)) return false; @@ -437,8 +457,9 @@ left_value_set(Datum d, meosType basetype, const Set *s) bool left_int_intset(int i, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT4)) + return false; return left_value_set(Int32GetDatum(i), T_INT4, s); } @@ -450,8 +471,9 @@ left_int_intset(int i, const Set *s) bool left_bigint_bigintset(int64 i, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT8)) + return false; return left_value_set(Int64GetDatum(i), T_INT8, s); } @@ -463,8 +485,9 @@ left_bigint_bigintset(int64 i, const Set *s) bool left_float_floatset(double d, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_FLOAT8)) + return false; return left_value_set(Float8GetDatum(d), T_FLOAT8, s); } @@ -476,8 +499,10 @@ left_float_floatset(double d, const Set *s) bool left_text_textset(text *txt, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_TEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) txt) || + ! ensure_same_set_basetype(s, T_TEXT)) + return false; return left_value_set(PointerGetDatum(txt), T_TEXT, s); } @@ -489,8 +514,10 @@ left_text_textset(text *txt, const Set *s) bool before_timestamp_timestampset(TimestampTz t, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_set_basetype(s, T_TIMESTAMPTZ)) + return false; return left_value_set(TimestampTzGetDatum(t), T_TIMESTAMPTZ, s); } #endif /* MEOS */ @@ -516,8 +543,9 @@ left_set_value(const Set *s, Datum d, meosType basetype) bool left_intset_int(const Set *s, int i) { - assert(s); - ensure_same_set_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT4)) + return false; return left_set_value(s, Int32GetDatum(i), T_INT4); } @@ -530,8 +558,9 @@ left_intset_int(const Set *s, int i) bool left_bigintset_bigint(const Set *s, int64 i) { - assert(s); - ensure_same_set_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT8)) + return false; return left_set_value(s, Int64GetDatum(i), T_INT8); } @@ -543,8 +572,9 @@ left_bigintset_bigint(const Set *s, int64 i) bool left_floatset_float(const Set *s, double d) { - assert(s); - ensure_same_set_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_FLOAT8)) + return false; return left_set_value(s, Float8GetDatum(d), T_FLOAT8); } @@ -556,8 +586,10 @@ left_floatset_float(const Set *s, double d) bool left_textset_text(const Set *s, text *txt) { - assert(s); - ensure_same_set_basetype(s, T_TEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) txt) || + ! ensure_same_set_basetype(s, T_TEXT)) + return false; return left_set_value(s, PointerGetDatum(txt), T_TEXT); } @@ -569,8 +601,10 @@ left_textset_text(const Set *s, text *txt) bool before_timestampset_timestamp(const Set *s, TimestampTz t) { - assert(s); - ensure_same_set_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_set_basetype(s, T_TIMESTAMPTZ)) + return false; return left_set_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -583,8 +617,10 @@ before_timestampset_timestamp(const Set *s, TimestampTz t) bool left_set_set(const Set *s1, const Set *s2) { - assert(s1); assert(s2); - ensure_same_set_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_set_type(s1, s2)) + return false; Datum d1 = SET_VAL_N(s1, s1->count - 1); Datum d2 = SET_VAL_N(s2, 0); return (datum_lt(d1, d2, s1->basetype)); @@ -613,8 +649,9 @@ right_value_set(Datum d, meosType basetype, const Set *s) bool right_int_intset(int i, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT4)) + return false; return left_set_value(s, Int32GetDatum(i), T_INT4); } @@ -627,8 +664,9 @@ right_int_intset(int i, const Set *s) bool right_bigint_bigintset(int64 i, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT8)) + return false; return left_set_value(s, Int64GetDatum(i), T_INT4); } @@ -640,8 +678,9 @@ right_bigint_bigintset(int64 i, const Set *s) bool right_float_floatset(double d, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_FLOAT8)) + return false; return left_set_value(s, Float8GetDatum(d), T_FLOAT8); } @@ -653,8 +692,10 @@ right_float_floatset(double d, const Set *s) bool right_text_textset(text *txt, const Set *s) { - assert(txt); assert(s); - ensure_same_set_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) txt) || ! ensure_not_null((void *) s) || + !ensure_same_set_basetype(s, T_TIMESTAMPTZ)) + return false; return left_set_value(s, PointerGetDatum(txt), T_TEXT); } @@ -666,8 +707,10 @@ right_text_textset(text *txt, const Set *s) bool after_timestamp_timestampset(TimestampTz t, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_set_basetype(s, T_TIMESTAMPTZ)) + return false; return left_set_value(s, TimestampTzGetDatum(t), T_TEXT); } #endif /* MEOS */ @@ -692,8 +735,9 @@ right_set_value(const Set *s, Datum d, meosType basetype) bool right_intset_int(const Set *s, int i) { - assert(s); - ensure_same_set_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) && ! ensure_same_set_basetype(s, T_INT4)) + return false; return right_set_value(s, Int32GetDatum(i), T_INT4); } @@ -706,8 +750,9 @@ right_intset_int(const Set *s, int i) bool right_bigintset_bigint(const Set *s, int64 i) { - assert(s); - ensure_same_set_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT8)) + return false; return right_set_value(s, Int64GetDatum(i), T_INT8); } @@ -719,8 +764,9 @@ right_bigintset_bigint(const Set *s, int64 i) bool right_floatset_float(const Set *s, double d) { - assert(s); - ensure_same_set_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_FLOAT8)) + return false; return right_set_value(s, Float8GetDatum(d), T_FLOAT8); } @@ -732,8 +778,10 @@ right_floatset_float(const Set *s, double d) bool right_textset_text(const Set *s, text *txt) { - assert(s); assert(txt); - ensure_same_set_basetype(s, T_TEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) txt) || + ! ensure_same_set_basetype(s, T_TEXT)) + return false; return right_set_value(s, PointerGetDatum(txt), T_TEXT); } @@ -745,8 +793,10 @@ right_textset_text(const Set *s, text *txt) bool after_timestampset_timestamp(const Set *s, TimestampTz t) { - assert(s); - ensure_same_set_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_set_basetype(s, T_TIMESTAMPTZ)) + return false; return right_set_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -760,8 +810,10 @@ after_timestampset_timestamp(const Set *s, TimestampTz t) bool right_set_set(const Set *s1, const Set *s2) { - assert(s1); assert(s2); - ensure_same_set_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_set_type(s1, s2)) + return false; return left_set_set(s2, s1); } @@ -790,8 +842,9 @@ overleft_value_set(Datum d, meosType basetype, const Set *s) bool overleft_int_intset(int i, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT4)) + return false; return overleft_value_set(Int32GetDatum(i), T_INT4, s); } @@ -804,8 +857,9 @@ overleft_int_intset(int i, const Set *s) bool overleft_bigint_bigintset(int64 i, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT8)) + return false; return overleft_value_set(Int64GetDatum(i), T_INT8, s); } @@ -817,8 +871,9 @@ overleft_bigint_bigintset(int64 i, const Set *s) bool overleft_float_floatset(double d, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_FLOAT8)) + return false; return overleft_value_set(Float8GetDatum(d), T_FLOAT8, s); } @@ -830,8 +885,10 @@ overleft_float_floatset(double d, const Set *s) bool overleft_text_textset(text *txt, const Set *s) { - assert(txt); assert(s); - ensure_same_set_basetype(s, T_TEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) txt) || ! ensure_not_null((void *) s) || + ! ensure_same_set_basetype(s, T_TEXT)) + return false; return overleft_value_set(PointerGetDatum(txt), T_TEXT, s); } @@ -843,8 +900,10 @@ overleft_text_textset(text *txt, const Set *s) bool overbefore_timestamp_timestampset(TimestampTz t, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_set_basetype(s, T_TIMESTAMPTZ)) + return false; return overleft_value_set(TimestampTzGetDatum(t), T_TIMESTAMPTZ, s); } #endif /* MEOS */ @@ -871,8 +930,9 @@ overleft_set_value(const Set *s, Datum d, meosType basetype) bool overleft_intset_int(const Set *s, int i) { - assert(s); - ensure_same_set_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT4)) + return false; return overleft_set_value(s, Int32GetDatum(i), T_INT4); } @@ -885,8 +945,9 @@ overleft_intset_int(const Set *s, int i) bool overleft_bigintset_bigint(const Set *s, int64 i) { - assert(s); - ensure_same_set_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT8)) + return false; return overleft_set_value(s, Int64GetDatum(i), T_INT8); } @@ -898,8 +959,9 @@ overleft_bigintset_bigint(const Set *s, int64 i) bool overleft_floatset_float(const Set *s, double d) { - assert(s); - ensure_same_set_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_FLOAT8)) + return false; return overleft_set_value(s, Float8GetDatum(d), T_FLOAT8); } @@ -911,8 +973,10 @@ overleft_floatset_float(const Set *s, double d) bool overleft_textset_text(const Set *s, text *txt) { - assert(s); assert(txt); - ensure_same_set_basetype(s, T_TEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) txt) || + ! ensure_same_set_basetype(s, T_TEXT)) + return false; return overleft_set_value(s, PointerGetDatum(txt), T_TEXT); } @@ -924,8 +988,10 @@ overleft_textset_text(const Set *s, text *txt) bool overbefore_timestampset_timestamp(const Set *s, TimestampTz t) { - assert(s); - ensure_same_set_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_set_basetype(s, T_TIMESTAMPTZ)) + return false; return overleft_set_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -939,8 +1005,10 @@ overbefore_timestampset_timestamp(const Set *s, TimestampTz t) bool overleft_set_set(const Set *s1, const Set *s2) { - assert(s1); assert(s2); - ensure_same_set_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_set_type(s1, s2)) + return false; Datum d1 = SET_VAL_N(s1, s1->count - 1); Datum d2 = SET_VAL_N(s2, s2->count - 1); return datum_le(d1, d2, s1->basetype); @@ -972,8 +1040,9 @@ overright_value_set(Datum d, meosType basetype, const Set *s) bool overright_int_intset(int i, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT4)) + return false; return overright_value_set(Int32GetDatum(i), T_INT4, s); } @@ -986,8 +1055,9 @@ overright_int_intset(int i, const Set *s) bool overright_bigint_bigintset(int64 i, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) && ! ensure_same_set_basetype(s, T_INT8)) + return false; return overright_value_set(Int64GetDatum(i), T_INT8, s); } @@ -1000,8 +1070,9 @@ overright_bigint_bigintset(int64 i, const Set *s) bool overright_float_floatset(double d, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_FLOAT8)) + return false; return overright_value_set(Float8GetDatum(d), T_FLOAT8, s); } @@ -1013,8 +1084,10 @@ overright_float_floatset(double d, const Set *s) bool overafter_timestamp_timestampset(TimestampTz t, const Set *s) { - assert(s); - ensure_same_set_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_set_basetype(s, T_TIMESTAMPTZ)) + return false; return overright_value_set(TimestampTzGetDatum(t), T_TIMESTAMPTZ, s); } #endif /* MEOS */ @@ -1041,8 +1114,9 @@ overright_set_value(const Set *s, Datum d, meosType basetype) bool overright_intset_int(const Set *s, int i) { - assert(s); - ensure_same_set_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT4)) + return false; return overright_set_value(s, Int32GetDatum(i), T_INT4); } @@ -1055,8 +1129,9 @@ overright_intset_int(const Set *s, int i) bool overright_bigintset_bigint(const Set *s, int64 i) { - assert(s); - ensure_same_set_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT8)) + return false; return overright_set_value(s, Int64GetDatum(i), T_INT8); } @@ -1068,8 +1143,9 @@ overright_bigintset_bigint(const Set *s, int64 i) bool overright_floatset_float(const Set *s, double d) { - assert(s); - ensure_same_set_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_FLOAT8)) + return false; return overright_set_value(s, Float8GetDatum(d), T_FLOAT8); } @@ -1081,8 +1157,9 @@ overright_floatset_float(const Set *s, double d) bool overright_textset_text(const Set *s, text *txt) { - assert(s); - ensure_same_set_basetype(s, T_TEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_TEXT)) + return false; return overright_set_value(s, PointerGetDatum(txt), T_TEXT); } @@ -1094,8 +1171,10 @@ overright_textset_text(const Set *s, text *txt) bool overafter_timestampset_timestamp(const Set *s, TimestampTz t) { - assert(s); - ensure_same_set_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_set_basetype(s, T_TIMESTAMPTZ)) + return false; return overright_set_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -1109,8 +1188,11 @@ overafter_timestampset_timestamp(const Set *s, TimestampTz t) bool overright_set_set(const Set *s1, const Set *s2) { - assert(s1); assert(s2); - ensure_same_set_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_set_type(s1, s2)) + return false; + Datum d1 = SET_VAL_N(s1, 0); Datum d2 = SET_VAL_N(s2, 0); return datum_ge(d1, d2, s1->basetype); @@ -1161,8 +1243,9 @@ union_set_value(const Set *s, Datum d, meosType basetype) Set * union_intset_int(const Set *s, int i) { - assert(s); - ensure_same_set_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT4)) + return NULL; return union_set_value(s, Int32GetDatum(i), T_INT4); } @@ -1174,8 +1257,9 @@ union_intset_int(const Set *s, int i) Set * union_bigintset_bigint(const Set *s, int64 i) { - assert(s); - ensure_same_set_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT8)) + return NULL; return union_set_value(s, Int64GetDatum(i), T_INT8); } @@ -1187,8 +1271,9 @@ union_bigintset_bigint(const Set *s, int64 i) Set * union_floatset_float(const Set *s, double d) { - assert(s); - ensure_same_set_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_FLOAT8)) + return NULL; return union_set_value(s, Float8GetDatum(d), T_FLOAT8); } @@ -1200,8 +1285,10 @@ union_floatset_float(const Set *s, double d) Set * union_textset_text(const Set *s, text *txt) { - assert(s); - ensure_same_set_basetype(s, T_TEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) txt) || + ! ensure_same_set_basetype(s, T_TEXT)) + return NULL; return union_set_value(s, PointerGetDatum(txt), T_TEXT); } @@ -1213,8 +1300,10 @@ union_textset_text(const Set *s, text *txt) Set * union_timestampset_timestamp(const Set *s, const TimestampTz t) { - assert(s); - ensure_same_set_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_set_basetype(s, T_TIMESTAMPTZ)) + return NULL; return union_set_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -1227,8 +1316,10 @@ union_timestampset_timestamp(const Set *s, const TimestampTz t) Set * union_set_set(const Set *s1, const Set *s2) { - assert(s1); assert(s2); - ensure_same_set_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_set_type(s1, s2)) + return NULL; return setop_set_set(s1, s2, UNION); } @@ -1241,8 +1332,7 @@ union_set_set(const Set *s1, const Set *s2) * @brief Compute the intersection of a set and a value */ bool -intersection_set_value(const Set *s, Datum d, meosType basetype, - Datum *result) +intersection_set_value(const Set *s, Datum d, meosType basetype, Datum *result) { assert(s); assert(result); assert(s->basetype == basetype); @@ -1262,8 +1352,11 @@ intersection_set_value(const Set *s, Datum d, meosType basetype, bool intersection_intset_int(const Set *s, int i, int *result) { - assert(s); assert(result); - ensure_same_set_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_same_set_basetype(s, T_INT4)) + return false; + Datum v; bool found = intersection_set_value(s, Int32GetDatum(i), T_INT4, &v); *result = DatumGetInt32(v); @@ -1279,8 +1372,11 @@ intersection_intset_int(const Set *s, int i, int *result) bool intersection_bigintset_bigint(const Set *s, int64 i, int64 *result) { - assert(s); assert(result); - ensure_same_set_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_same_set_basetype(s, T_INT8)) + return false; + Datum v; bool found = intersection_set_value(s, Int64GetDatum(i), T_INT8, &v); *result = DatumGetInt64(v); @@ -1296,8 +1392,11 @@ intersection_bigintset_bigint(const Set *s, int64 i, int64 *result) bool intersection_floatset_float(const Set *s, double d, double *result) { - assert(s); assert(result); - ensure_same_set_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_same_set_basetype(s, T_FLOAT8)) + return false; + Datum v; bool found = intersection_set_value(s, Float8GetDatum(d), T_FLOAT8, &v); *result = DatumGetInt32(v); @@ -1312,8 +1411,11 @@ intersection_floatset_float(const Set *s, double d, double *result) bool intersection_textset_text(const Set *s, const text *txt, text **result) { - assert(s); assert(result); - ensure_same_set_basetype(s, T_TEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_same_set_basetype(s, T_TEXT)) + return false; + Datum v; bool found = intersection_set_value(s, PointerGetDatum(txt), T_TEXT, &v); *result = DatumGetTextP(v); @@ -1330,8 +1432,11 @@ bool intersection_timestampset_timestamp(const Set *s, TimestampTz t, TimestampTz *result) { - assert(s); assert(result); - ensure_same_set_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_same_set_basetype(s, T_TIMESTAMPTZ)) + return false; + Datum v; bool found = intersection_set_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ, &v); @@ -1348,8 +1453,10 @@ intersection_timestampset_timestamp(const Set *s, TimestampTz t, Set * intersection_set_set(const Set *s1, const Set *s2) { - assert(s1); assert(s2); - ensure_same_set_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_set_type(s1, s2)) + return NULL; return setop_set_set(s1, s2, INTER); } @@ -1383,8 +1490,11 @@ minus_value_set(Datum d, meosType basetype, const Set *s, Datum *result) bool minus_int_intset(int i, const Set *s, int *result) { - assert(s); assert(result); - ensure_same_set_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_same_set_basetype(s, T_INT4)) + return false; + Datum v; bool found = minus_value_set(Int32GetDatum(i), T_INT4, s, &v); *result = DatumGetInt32(v); @@ -1400,8 +1510,11 @@ minus_int_intset(int i, const Set *s, int *result) bool minus_bigint_bigintset(int64 i, const Set *s, int64 *result) { - assert(s); assert(result); - ensure_same_set_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_same_set_basetype(s, T_INT8)) + return false; + Datum v; bool found = minus_value_set(Int64GetDatum(i), T_INT8, s, &v); *result = DatumGetInt64(v); @@ -1416,8 +1529,11 @@ minus_bigint_bigintset(int64 i, const Set *s, int64 *result) bool minus_float_floatset(double d, const Set *s, double *result) { - assert(s); assert(result); - ensure_same_set_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_same_set_basetype(s, T_FLOAT8)) + return false; + Datum v; bool found = minus_value_set(Float8GetDatum(d), T_FLOAT8, s, &v); *result = DatumGetFloat8(v); @@ -1432,8 +1548,11 @@ minus_float_floatset(double d, const Set *s, double *result) bool minus_text_textset(const text *txt, const Set *s, text **result) { - assert(s); assert(result); - ensure_same_set_basetype(s, T_TEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_same_set_basetype(s, T_TEXT)) + return false; + Datum v; bool found = minus_value_set(PointerGetDatum(txt), T_TEXT, s, &v); *result = DatumGetTextP(v); @@ -1475,8 +1594,9 @@ minus_set_value(const Set *s, Datum d, meosType basetype) Set * minus_intset_int(const Set *s, int i) { - assert(s); - ensure_same_set_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT4)) + return NULL; return minus_set_value(s, Int32GetDatum(i), T_INT4); } @@ -1488,8 +1608,9 @@ minus_intset_int(const Set *s, int i) Set * minus_bigintset_bigint(const Set *s, int64 i) { - assert(s); - ensure_same_set_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT8)) + return NULL; return minus_set_value(s, Int64GetDatum(i), T_INT8); } @@ -1501,8 +1622,9 @@ minus_bigintset_bigint(const Set *s, int64 i) Set * minus_floatset_float(const Set *s, double d) { - assert(s); - ensure_same_set_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_FLOAT8)) + return NULL; return minus_set_value(s, Float8GetDatum(d), T_FLOAT8); } @@ -1514,8 +1636,10 @@ minus_floatset_float(const Set *s, double d) Set * minus_textset_text(const Set *s, const text *txt) { - assert(s); - ensure_same_set_basetype(s, T_TEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) txt) || + ! ensure_same_set_basetype(s, T_TEXT)) + return NULL; return minus_set_value(s, PointerGetDatum(txt), T_TEXT); } @@ -1527,8 +1651,11 @@ minus_textset_text(const Set *s, const text *txt) Set * minus_timestampset_timestamp(const Set *s, TimestampTz t) { - assert(s); - ensure_same_set_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_set_basetype(s, T_TIMESTAMPTZ)) + return NULL; + /* Bounding box test */ Span s1; set_set_span(s, &s1); @@ -1556,8 +1683,10 @@ minus_timestampset_timestamp(const Set *s, TimestampTz t) Set * minus_set_set(const Set *s1, const Set *s2) { - assert(s1); assert(s2); - ensure_same_set_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_set_type(s1, s2)) + return NULL; return setop_set_set(s1, s2, MINUS); } @@ -1588,8 +1717,9 @@ distance_set_value(const Set *s, Datum d, meosType basetype) double distance_intset_int(const Set *s, int i) { - assert(s); - ensure_same_set_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT4)) + return -1.0; return distance_set_value(s, Int32GetDatum(i), T_INT4); } @@ -1602,8 +1732,9 @@ distance_intset_int(const Set *s, int i) double distance_bigintset_bigint(const Set *s, int64 i) { - assert(s); - ensure_same_set_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_INT8)) + return -1.0; return distance_set_value(s, Int64GetDatum(i), T_INT8); } @@ -1615,8 +1746,9 @@ distance_bigintset_bigint(const Set *s, int64 i) double distance_floatset_float(const Set *s, double d) { - assert(s); - ensure_same_set_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_set_basetype(s, T_FLOAT8)) + return -1.0; return distance_set_value(s, Float8GetDatum(d), T_FLOAT8); } @@ -1628,8 +1760,10 @@ distance_floatset_float(const Set *s, double d) double distance_timestampset_timestamp(const Set *s, TimestampTz t) { - assert(s); - ensure_same_set_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_set_basetype(s, T_TIMESTAMPTZ)) + return -1.0; return distance_set_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } @@ -1641,8 +1775,11 @@ distance_timestampset_timestamp(const Set *s, TimestampTz t) double distance_set_set(const Set *s1, const Set *s2) { - assert(s1); assert(s2); - ensure_same_set_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_set_type(s1, s2)) + return -1.0; + Span sp1, sp2; set_set_span(s1, &sp1); set_set_span(s2, &sp2); diff --git a/meos/src/general/skiplist.c b/meos/src/general/skiplist.c index ca0d50e2d5..b1f59314db 100644 --- a/meos/src/general/skiplist.c +++ b/meos/src/general/skiplist.c @@ -41,6 +41,7 @@ /* C */ #include +#include #include /* PostgreSQL */ #include @@ -150,7 +151,11 @@ skiplist_alloc(SkipList *list) * fit within MaxAllocSize. If this maximum has been previously reached * and more capacity is required, an error is generated. */ if (list->capacity == (int) floor(MaxAllocSize / sizeof(SkipListElem))) - elog(ERROR, "No more memory available to compute the aggregation"); + { + meos_error(ERROR, MEOS_ERR_MEMORY_ALLOC_ERROR, + "No more memory available to compute the aggregation"); + return INT_MAX; + } if (sizeof(SkipListElem) * (list->capacity << 2) > MaxAllocSize) list->capacity = (int) floor(MaxAllocSize / sizeof(SkipListElem)); else @@ -272,7 +277,7 @@ skiplist_print(const SkipList *list) cur = e->next[0]; } sprintf(buf+len, "}\n"); - elog(WARNING, "SKIPLIST: %s", buf); + meos_error(WARNING, 0, "SKIPLIST: %s", buf); } #endif @@ -451,10 +456,18 @@ skiplist_splice(SkipList *list, void **values, int count, datum_func2 func, Temporal *temp1 = (Temporal *) skiplist_headval(list); Temporal *temp2 = (Temporal *) values[0]; if (temp1->subtype != temp2->subtype) - elog(ERROR, "Cannot aggregate temporal values of different type"); + { + meos_error(ERROR, MEOS_ERR_AGGREGATION_ERROR, + "Cannot aggregate temporal values of different type"); + return; + } if (MEOS_FLAGS_GET_LINEAR(temp1->flags) != MEOS_FLAGS_GET_LINEAR(temp2->flags)) - elog(ERROR, "Cannot aggregate temporal values of different interpolation"); + { + meos_error(ERROR, MEOS_ERR_AGGREGATION_ERROR, + "Cannot aggregate temporal values of different interpolation"); + return; + } /* Compute the span of the new values */ Span p; diff --git a/meos/src/general/span.c b/meos/src/general/span.c index 1f79414ab4..94c5081bfb 100644 --- a/meos/src/general/span.c +++ b/meos/src/general/span.c @@ -37,6 +37,8 @@ /* C */ #include +#include +#include /* PostgreSQL */ #if POSTGRESQL_VERSION_NUMBER >= 130000 #include @@ -59,36 +61,48 @@ /** * @brief Ensure that a span value is of a span type */ -void +bool ensure_span_has_type(const Span *s, meosType spantype) { if (s->spantype != spantype) - elog(ERROR, "The span value must be of type %s", meostype_name(spantype)); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "The span value must be of type %s", meostype_name(spantype)); + return false; + } + return true; } /** * @brief Ensure that the span values have the same type */ -void +bool ensure_same_span_type(const Span *s1, const Span *s2) { if (s1->spantype != s2->spantype) - elog(ERROR, "Operation on mixed span types: %s and %s", + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "Operation on mixed span types: %s and %s", meostype_name(s1->spantype), meostype_name(s2->spantype)); - return; + return false; + } + return true; } /** * @brief Ensure that a span value has the same base type as the given one */ -void +bool ensure_same_span_basetype(const Span *s, meosType basetype) { if (s->basetype != basetype) - elog(ERROR, "Operation on mixed span and base types: %s and %s", + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "Operation on mixed span and base types: %s and %s", meostype_name(s->spantype), meostype_name(basetype)); - return; + return false; + } + return true; } /** @@ -301,7 +315,9 @@ span_in(const char *str, meosType spantype) Span * intspan_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return span_in(str, T_INTSPAN); } @@ -312,7 +328,9 @@ intspan_in(const char *str) Span * bigintspan_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return span_in(str, T_BIGINTSPAN); } @@ -323,7 +341,9 @@ bigintspan_in(const char *str) Span * floatspan_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return span_in(str, T_FLOATSPAN); } @@ -334,7 +354,9 @@ floatspan_in(const char *str) Span * period_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return span_in(str, T_TSTZSPAN); } #endif /* MEOS */ @@ -367,9 +389,8 @@ unquote(char *str) char * span_out(const Span *s, int maxdd) { - /* Ensure validity of the arguments */ assert(s); - ensure_non_negative(maxdd); + assert(maxdd >= 0); char *lower = unquote(basetype_out(s->lower, s->basetype, maxdd)); char *upper = unquote(basetype_out(s->upper, s->basetype, maxdd)); @@ -389,8 +410,9 @@ span_out(const Span *s, int maxdd) char * intspan_out(const Span *s) { - assert(s); - ensure_span_has_type(s, T_INTSPAN); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_has_type(s, T_INTSPAN)) + return NULL; return span_out(s, 0); } @@ -401,8 +423,9 @@ intspan_out(const Span *s) char * bigintspan_out(const Span *s) { - assert(s); - ensure_span_has_type(s, T_BIGINTSPAN); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_has_type(s, T_BIGINTSPAN)) + return NULL; return span_out(s, 0); } @@ -413,8 +436,9 @@ bigintspan_out(const Span *s) char * floatspan_out(const Span *s, int maxdd) { - assert(s); - ensure_span_has_type(s, T_FLOATSPAN); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_has_type(s, T_FLOATSPAN)) + return NULL; return span_out(s, maxdd); } @@ -425,8 +449,9 @@ floatspan_out(const Span *s, int maxdd) char * period_out(const Span *s) { - assert(s); - ensure_span_has_type(s, T_TSTZSPAN); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_has_type(s, T_TSTZSPAN)) + return NULL; return span_out(s, 0); } #endif /* MEOS */ @@ -557,11 +582,19 @@ span_set(Datum lower, Datum upper, bool lower_inc, bool upper_inc, int cmp = datum_cmp(lower, upper, basetype); /* error check: if lower bound value is above upper, it's wrong */ if (cmp > 0) - elog(ERROR, "Span lower bound must be less than or equal to span upper bound"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Span lower bound must be less than or equal to span upper bound"); + return; + } /* error check: if bounds are equal, and not both inclusive, span is empty */ if (cmp == 0 && !(lower_inc && upper_inc)) - elog(ERROR, "Span cannot be empty"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Span cannot be empty"); + return; + } /* Note: zero-fill is required here, just as in heap tuples */ memset(s, 0, sizeof(Span)); @@ -582,7 +615,9 @@ span_set(Datum lower, Datum upper, bool lower_inc, bool upper_inc, Span * span_copy(const Span *s) { - assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return NULL; Span *result = palloc(sizeof(Span)); memcpy((char *) result, (char *) s, sizeof(Span)); return result; @@ -684,8 +719,9 @@ timestamp_to_period(TimestampTz t) int intspan_lower(const Span *s) { - assert(s); - ensure_span_has_type(s, T_INTSPAN); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_has_type(s, T_INTSPAN)) + return INT_MAX; return DatumGetInt32(s->lower); } @@ -697,8 +733,9 @@ intspan_lower(const Span *s) int bigintspan_lower(const Span *s) { - assert(s); - ensure_span_has_type(s, T_BIGINTSPAN); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_has_type(s, T_BIGINTSPAN)) + return INT_MAX; return DatumGetInt64(s->lower); } @@ -710,8 +747,9 @@ bigintspan_lower(const Span *s) double floatspan_lower(const Span *s) { - assert(s); - ensure_span_has_type(s, T_FLOATSPAN); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_has_type(s, T_FLOATSPAN)) + return DBL_MAX; return DatumGetFloat8(s->lower); } @@ -723,8 +761,9 @@ floatspan_lower(const Span *s) TimestampTz period_lower(const Span *s) { - assert(s); - ensure_span_has_type(s, T_TSTZSPAN); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_has_type(s, T_TSTZSPAN)) + return DT_NOEND; return TimestampTzGetDatum(s->lower); } @@ -736,8 +775,9 @@ period_lower(const Span *s) int intspan_upper(const Span *s) { - assert(s); - ensure_span_has_type(s, T_INTSPAN); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_has_type(s, T_INTSPAN)) + return INT_MAX; return Int32GetDatum(s->upper); } @@ -749,8 +789,9 @@ intspan_upper(const Span *s) int bigintspan_upper(const Span *s) { - assert(s); - ensure_span_has_type(s, T_BIGINTSPAN); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_has_type(s, T_BIGINTSPAN)) + return INT_MAX; return Int64GetDatum(s->upper); } @@ -762,8 +803,9 @@ bigintspan_upper(const Span *s) double floatspan_upper(const Span *s) { - assert(s); - ensure_span_has_type(s, T_FLOATSPAN); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_has_type(s, T_FLOATSPAN)) + return DBL_MAX; return DatumGetFloat8(s->upper); } @@ -775,8 +817,9 @@ floatspan_upper(const Span *s) TimestampTz period_upper(const Span *s) { - assert(s); - ensure_span_has_type(s, T_TSTZSPAN); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_has_type(s, T_TSTZSPAN)) + return DT_NOEND; return TimestampTzGetDatum(s->upper); } @@ -788,7 +831,9 @@ period_upper(const Span *s) bool span_lower_inc(const Span *s) { - assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return false; return s->lower_inc; } @@ -800,7 +845,9 @@ span_lower_inc(const Span *s) bool span_upper_inc(const Span *s) { - assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return false; return s->upper_inc; } #endif /* MEOS */ @@ -813,7 +860,9 @@ span_upper_inc(const Span *s) double span_width(const Span *s) { - assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return -1.0; return distance_value_value(s->lower, s->upper, s->basetype); } @@ -825,8 +874,9 @@ span_width(const Span *s) Interval * period_duration(const Span *s) { - assert(s); - ensure_span_has_type(s, T_TSTZSPAN); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_has_type(s, T_TSTZSPAN)) + return NULL; return pg_timestamp_mi(s->upper, s->lower); } @@ -858,9 +908,9 @@ Span * floatspan_round(const Span *s, int maxdd) { /* Ensure validity of the arguments */ - assert(s); - ensure_span_has_type(s, T_FLOATSPAN); - ensure_non_negative(maxdd); + if (! ensure_not_null((void *) s) || ! ensure_span_has_type(s, T_FLOATSPAN) || + ! ensure_non_negative(maxdd)) + return NULL; Span *result = palloc(sizeof(Span)); floatspan_round_int(s, Int32GetDatum(maxdd), result); @@ -877,8 +927,9 @@ floatspan_round(const Span *s, int maxdd) Span * intspan_floatspan(const Span *s) { - assert(s); - ensure_span_has_type(s, T_INTSPAN); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_has_type(s, T_INTSPAN)) + return NULL; Span *result = malloc(sizeof(Span)); intspan_set_floatspan(s, result); return result; @@ -891,8 +942,9 @@ intspan_floatspan(const Span *s) Span * floatspan_intspan(const Span *s) { - assert(s); - ensure_span_has_type(s, T_FLOATSPAN); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_has_type(s, T_FLOATSPAN)) + return NULL; Span *result = malloc(sizeof(Span)); floatspan_set_intspan(s, result); return result; @@ -935,14 +987,14 @@ floatspan_set_intspan(const Span *s1, Span *s2) #endif /* MEOS */ /** - * @ingroup libmeos_setspan_transf + * @ingroup libmeos_internal_setspan_transf * @brief Expand the second span with the first one */ void span_expand(const Span *s1, Span *s2) { - assert(s1); assert(s2); - ensure_same_span_type(s1, s2); + assert(s1); assert(s2); assert(s1->spantype == s2->spantype); + int cmp1 = datum_cmp(s2->lower, s1->lower, s1->basetype); int cmp2 = datum_cmp(s2->upper, s1->upper, s1->basetype); bool lower1 = cmp1 < 0 || (cmp1 == 0 && (s2->lower_inc || ! s1->lower_inc)); @@ -981,8 +1033,8 @@ lower_upper_shift_tscale(const Interval *shift, const Interval *duration, { assert(shift || duration); assert(lower && upper); - if (duration) - ensure_valid_duration(duration); + if (duration && ! ensure_valid_duration(duration)) + return; bool instant = (*lower == *upper); if (shift) @@ -1005,6 +1057,7 @@ void period_delta_scale(Span *s, TimestampTz origin, TimestampTz delta, double scale) { assert(s); + TimestampTz lower = DatumGetTimestampTz(s->lower); TimestampTz upper = DatumGetTimestampTz(s->upper); /* The default value when there is not shift is 0 */ @@ -1064,10 +1117,11 @@ Span * period_shift_tscale(const Span *s, const Interval *shift, const Interval *duration) { - ensure_span_has_type(s, T_TSTZSPAN); - assert(shift || duration); - if (duration) - ensure_valid_duration(duration); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_span_has_type(s, T_TSTZSPAN) || + ! ensure_one_not_null((void *) shift, (void *) duration) || + (duration && ! ensure_valid_duration(duration))) + return NULL; /* Copy the input period to the result */ Span *result = span_copy(s); @@ -1093,8 +1147,11 @@ period_shift_tscale(const Span *s, const Interval *shift, bool span_eq(const Span *s1, const Span *s2) { - assert(s1); assert(s2); - ensure_same_span_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_span_type(s1, s2)) + return false; + if (s1->lower != s2->lower || s1->upper != s2->upper || s1->lower_inc != s2->lower_inc || s1->upper_inc != s2->upper_inc) return false; @@ -1124,8 +1181,11 @@ span_ne(const Span *s1, const Span *s2) int span_cmp(const Span *s1, const Span *s2) { - assert(s1); assert(s2); - ensure_same_span_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_span_type(s1, s2)) + return INT_MAX; + int cmp = datum_cmp(s1->lower, s2->lower, s1->basetype); if (cmp != 0) return cmp; @@ -1199,6 +1259,10 @@ span_gt(const Span *s1, const Span *s2) uint32 span_hash(const Span *s) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return INT_MAX; + /* Create flags from the lower_inc and upper_inc values */ char flags = '\0'; if (s->lower_inc) @@ -1233,6 +1297,10 @@ span_hash(const Span *s) uint64 span_hash_extended(const Span *s, uint64 seed) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return INT_MAX; + uint64 result; char flags = '\0'; uint64 type_hash; diff --git a/meos/src/general/span_ops.c b/meos/src/general/span_ops.c index bc0bd5d3af..a4eee8376f 100644 --- a/meos/src/general/span_ops.c +++ b/meos/src/general/span_ops.c @@ -34,6 +34,7 @@ /* C */ #include +#include #include /* PostgreSQL */ #include @@ -116,8 +117,9 @@ contains_span_value(const Span *s, Datum d, meosType basetype) bool contains_intspan_int(const Span *s, int i) { - assert(s); - ensure_same_span_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT4)) + return false; return contains_span_value(s, Int32GetDatum(i), T_INT4); } @@ -129,8 +131,9 @@ contains_intspan_int(const Span *s, int i) bool contains_bigintspan_bigint(const Span *s, int64 i) { - assert(s); - ensure_same_span_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT8)) + return false; return contains_span_value(s, Int64GetDatum(i), T_INT8); } @@ -142,8 +145,9 @@ contains_bigintspan_bigint(const Span *s, int64 i) bool contains_floatspan_float(const Span *s, double d) { - assert(s); - ensure_same_span_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_FLOAT8)) + return false; return contains_span_value(s, Float8GetDatum(d), T_FLOAT8); } #endif /* MEOS */ @@ -156,8 +160,10 @@ contains_floatspan_float(const Span *s, double d) bool contains_period_timestamp(const Span *s, TimestampTz t) { - assert(s); - ensure_same_span_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_span_basetype(s, T_TIMESTAMPTZ)) + return false; return contains_span_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } @@ -169,8 +175,11 @@ contains_period_timestamp(const Span *s, TimestampTz t) bool contains_span_span(const Span *s1, const Span *s2) { - assert(s1); assert(s2); - ensure_same_span_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_span_type(s1, s2)) + return false; + int c1 = datum_cmp(s1->lower, s2->lower, s1->basetype); int c2 = datum_cmp(s1->upper, s2->upper, s1->basetype); if ( @@ -204,8 +213,9 @@ contained_value_span(Datum d, meosType basetype, const Span *s) bool contained_int_intspan(int i, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT4)) + return false; return contains_span_value(s, Int32GetDatum(i), T_INT4); } @@ -217,8 +227,9 @@ contained_int_intspan(int i, const Span *s) bool contained_bigint_bigintspan(int64 i, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT8)) + return false; return contains_span_value(s, Int64GetDatum(i), T_INT8); } @@ -230,8 +241,9 @@ contained_bigint_bigintspan(int64 i, const Span *s) bool contained_float_floatspan(double d, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_FLOAT8)) + return false; return contains_span_value(s, Float8GetDatum(d), T_FLOAT8); } @@ -243,8 +255,10 @@ contained_float_floatspan(double d, const Span *s) bool contained_timestamp_period(TimestampTz t, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_span_basetype(s, T_TIMESTAMPTZ)) + return false; return contains_span_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -272,8 +286,11 @@ contained_span_span(const Span *s1, const Span *s2) bool overlaps_span_span(const Span *s1, const Span *s2) { - assert(s1); assert(s2); - ensure_same_span_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_span_type(s1, s2)) + return false; + int cmp1 = datum_cmp(s1->lower, s2->upper, s1->basetype); int cmp2 = datum_cmp(s2->lower, s1->upper, s1->basetype); if ( @@ -310,8 +327,9 @@ adjacent_span_value(const Span *s, Datum d, meosType basetype) bool adjacent_intspan_int(const Span *s, int i) { - assert(s); - ensure_same_span_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT4)) + return false; return adjacent_span_value(s, Int32GetDatum(i), T_INT4); } @@ -323,8 +341,9 @@ adjacent_intspan_int(const Span *s, int i) bool adjacent_bigintspan_bigint(const Span *s, int64 i) { - assert(s); - ensure_same_span_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT8)) + return false; return adjacent_span_value(s, Int64GetDatum(i), T_INT8); } @@ -336,8 +355,9 @@ adjacent_bigintspan_bigint(const Span *s, int64 i) bool adjacent_floatspan_float(const Span *s, double d) { - assert(s); - ensure_same_span_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_FLOAT8)) + return false; return adjacent_span_value(s, Float8GetDatum(d), T_FLOAT8); } @@ -349,8 +369,10 @@ adjacent_floatspan_float(const Span *s, double d) bool adjacent_period_timestamp(const Span *s, TimestampTz t) { - assert(s); - ensure_same_span_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_span_basetype(s, T_TIMESTAMPTZ)) + return false; return adjacent_span_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -363,8 +385,11 @@ adjacent_period_timestamp(const Span *s, TimestampTz t) bool adjacent_span_span(const Span *s1, const Span *s2) { - assert(s1); assert(s2); - ensure_same_span_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_span_type(s1, s2)) + return false; + /* * Two spans A..B and C..D are adjacent if and only if * B is adjacent to C, or D is adjacent to A. @@ -401,21 +426,24 @@ left_value_span(Datum d, meosType basetype, const Span *s) bool left_int_intspan(int i, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT4)) + return false; return left_value_span(Int32GetDatum(i), T_INT4, s); } /** * @ingroup libmeos_setspan_pos - * @brief Return true if a big integer is strictly to the left of a big integer span. + * @brief Return true if a big integer is strictly to the left of a big integer + * span. * @sqlop @p << */ bool left_bigint_bigintspan(int64 i, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT8)) + return false; return left_value_span(Int64GetDatum(i), T_INT8, s); } @@ -427,8 +455,9 @@ left_bigint_bigintspan(int64 i, const Span *s) bool left_float_floatspan(double d, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_FLOAT8)) + return false; return left_value_span(Float8GetDatum(d), T_FLOAT8, s); } @@ -440,8 +469,10 @@ left_float_floatspan(double d, const Span *s) bool before_timestamp_period(TimestampTz t, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_span_basetype(s, T_TIMESTAMPTZ)) + return false; return left_value_span(TimestampTzGetDatum(t), T_TIMESTAMPTZ, s); } #endif /* MEOS */ @@ -467,8 +498,9 @@ left_span_value(const Span *s, Datum d, meosType basetype) bool left_intspan_int(const Span *s, int i) { - assert(s); - ensure_same_span_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT4)) + return false; return left_span_value(s, Int32GetDatum(i), T_INT4); } @@ -480,8 +512,9 @@ left_intspan_int(const Span *s, int i) bool left_bigintspan_bigint(const Span *s, int64 i) { - assert(s); - ensure_same_span_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT8)) + return false; return left_span_value(s, Int64GetDatum(i), T_INT8); } @@ -493,8 +526,9 @@ left_bigintspan_bigint(const Span *s, int64 i) bool left_floatspan_float(const Span *s, double d) { - assert(s); - ensure_same_span_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_FLOAT8)) + return false; return left_span_value(s, Float8GetDatum(d), T_FLOAT8); } @@ -506,8 +540,10 @@ left_floatspan_float(const Span *s, double d) bool before_period_timestamp(const Span *s, TimestampTz t) { - assert(s); - ensure_same_span_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_span_basetype(s, T_TIMESTAMPTZ)) + return false; return left_span_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -520,8 +556,11 @@ before_period_timestamp(const Span *s, TimestampTz t) bool left_span_span(const Span *s1, const Span *s2) { - assert(s1); assert(s2); - ensure_same_span_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_span_type(s1, s2)) + return false; + int cmp = datum_cmp(s1->upper, s2->lower, s1->basetype); return (cmp < 0 || (cmp == 0 && (! s1->upper_inc || ! s2->lower_inc))); } @@ -549,21 +588,24 @@ right_value_span(Datum d, meosType basetype, const Span *s) bool right_int_intspan(int i, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT4)) + return false; return left_span_value(s, DatumGetInt32(i), T_INT4); } /** * @ingroup libmeos_setspan_pos - * @brief Return true if a big integer is strictly to the right of a big integer span. + * @brief Return true if a big integer is strictly to the right of a big + * integer span. * @sqlop @p >> */ bool right_bigint_bigintspan(int64 i, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT8)) + return false; return left_span_value(s, DatumGetInt64(i), T_INT8); } @@ -575,8 +617,9 @@ right_bigint_bigintspan(int64 i, const Span *s) bool right_float_floatspan(double d, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_FLOAT8)) + return false; return left_span_value(s, DatumGetFloat8(d), T_FLOAT8); } @@ -588,8 +631,10 @@ right_float_floatspan(double d, const Span *s) bool after_timestamp_period(TimestampTz t, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_span_basetype(s, T_TIMESTAMPTZ)) + return false; return left_span_value(s, DatumGetTimestampTz(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -613,21 +658,24 @@ right_span_value(const Span *s, Datum d, meosType basetype) bool right_intspan_int(const Span *s, int i) { - assert(s); - ensure_same_span_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT4)) + return false; return left_value_span(DatumGetInt32(i), T_INT4, s); } /** * @ingroup libmeos_setspan_pos - * @brief Return true if a big integer span is strictly to the right of a big integer + * @brief Return true if a big integer span is strictly to the right of a big + * integer * @sqlop @p >> */ bool right_bigintspan_bigint(const Span *s, int64 i) { - assert(s); - ensure_same_span_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT8)) + return false; return left_value_span(DatumGetInt64(i), T_INT8, s); } @@ -639,8 +687,9 @@ right_bigintspan_bigint(const Span *s, int64 i) bool right_floatspan_float(const Span *s, double d) { - assert(s); - ensure_same_span_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_FLOAT8)) + return false; return left_value_span(DatumGetFloat8(d), T_FLOAT8, s); } @@ -652,8 +701,10 @@ right_floatspan_float(const Span *s, double d) bool after_period_timestamp(const Span *s, TimestampTz t) { - assert(s); - ensure_same_span_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_span_basetype(s, T_TIMESTAMPTZ)) + return false; return left_value_span(DatumGetTimestampTz(t), T_TIMESTAMPTZ, s); } #endif /* MEOS */ @@ -688,27 +739,31 @@ overleft_value_span(Datum d, meosType basetype, const Span *s) #if MEOS /** * @ingroup libmeos_setspan_pos - * @brief Return true if an integer does not extend to the right of an integer span. + * @brief Return true if an integer does not extend to the right of an integer + * span. * @sqlop @p &< */ bool overleft_int_intspan(int i, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT4)) + return false; return overleft_value_span(Int32GetDatum(i), T_INT4, s); } /** * @ingroup libmeos_setspan_pos - * @brief Return true if a big integer does not extend to the right of a big integer span. + * @brief Return true if a big integer does not extend to the right of a big + * integer span. * @sqlop @p &< */ bool overleft_bigint_bigintspan(int64 i, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT8)) + return false; return overleft_value_span(Int64GetDatum(i), T_INT8, s); } @@ -720,8 +775,9 @@ overleft_bigint_bigintspan(int64 i, const Span *s) bool overleft_float_floatspan(double d, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_FLOAT8)) + return false; return overleft_value_span(Float8GetDatum(d), T_FLOAT8, s); } @@ -733,8 +789,10 @@ overleft_float_floatspan(double d, const Span *s) bool overbefore_timestamp_period(TimestampTz t, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_span_basetype(s, T_TIMESTAMPTZ)) + return false; return overleft_value_span(TimestampTzGetDatum(t), T_TIMESTAMPTZ, s); } #endif /* MEOS */ @@ -763,21 +821,24 @@ overleft_span_value(const Span *s, Datum d, meosType basetype) bool overleft_intspan_int(const Span *s, int i) { - assert(s); - ensure_same_span_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT4)) + return false; return overleft_span_value(s, Int32GetDatum(i), T_INT4); } /** * @ingroup libmeos_setspan_pos - * @brief Return true if a big integer span does not extend to the right of a big integer. + * @brief Return true if a big integer span does not extend to the right of a + * big integer. * @sqlop @p &< */ bool overleft_bigintspan_bigint(const Span *s, int64 i) { - assert(s); - ensure_same_span_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT8)) + return false; return overleft_span_value(s, Int64GetDatum(i), T_INT8); } @@ -789,8 +850,9 @@ overleft_bigintspan_bigint(const Span *s, int64 i) bool overleft_floatspan_float(const Span *s, double d) { - assert(s); - ensure_same_span_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) && ! ensure_same_span_basetype(s, T_FLOAT8)) + return false; return overleft_span_value(s, Float8GetDatum(d), T_FLOAT8); } @@ -802,8 +864,10 @@ overleft_floatspan_float(const Span *s, double d) bool overbefore_period_timestamp(const Span *s, TimestampTz t) { - assert(s); - ensure_same_span_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_span_basetype(s, T_TIMESTAMPTZ)) + return false; return overleft_span_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -816,8 +880,10 @@ overbefore_period_timestamp(const Span *s, TimestampTz t) bool overleft_span_span(const Span *s1, const Span *s2) { - assert(s1); assert(s2); - ensure_same_span_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_span_type(s1, s2)) + return false; int cmp = datum_cmp(s1->upper, s2->upper, s1->basetype); return (cmp < 0 || (cmp == 0 && (! s1->upper_inc || s2->upper_inc))); } @@ -841,14 +907,16 @@ overright_value_span(Datum d, meosType basetype, const Span *s) #if MEOS /** * @ingroup libmeos_setspan_pos - * @brief Return true if an integer does not extend to the left of an integer span. + * @brief Return true if an integer does not extend to the left of an integer + * span. * @sqlop @p &> */ bool overright_int_intspan(int i, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT4)) + return false; return overright_value_span(Int32GetDatum(i), T_INT4, s); } @@ -860,8 +928,9 @@ overright_int_intspan(int i, const Span *s) bool overright_bigint_bigintspan(int64 i, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT8)) + return false; return overright_value_span(Int64GetDatum(i), T_INT8, s); } @@ -873,8 +942,9 @@ overright_bigint_bigintspan(int64 i, const Span *s) bool overright_float_floatspan(double d, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_FLOAT8)) + return false; return overright_value_span(Float8GetDatum(d), T_FLOAT8, s); } @@ -886,8 +956,10 @@ overright_float_floatspan(double d, const Span *s) bool overafter_timestamp_period(TimestampTz t, const Span *s) { - assert(s); - ensure_same_span_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_span_basetype(s, T_TIMESTAMPTZ)) + return false; return overright_value_span(TimestampTzGetDatum(t), T_TIMESTAMPTZ, s); } #endif /* MEOS */ @@ -912,8 +984,9 @@ overright_span_value(const Span *s, Datum d, meosType basetype) bool overright_intspan_int(const Span *s, int i) { - assert(s); - ensure_same_span_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT4)) + return false; return overright_span_value(s, Int32GetDatum(i), T_INT4); } @@ -925,8 +998,9 @@ overright_intspan_int(const Span *s, int i) bool overright_bigintspan_bigint(const Span *s, int64 i) { - assert(s); - ensure_same_span_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) ||! ensure_same_span_basetype(s, T_INT8)) + return false; return overright_span_value(s, Int64GetDatum(i), T_INT8); } @@ -938,8 +1012,9 @@ overright_bigintspan_bigint(const Span *s, int64 i) bool overright_floatspan_float(const Span *s, double d) { - assert(s); - ensure_same_span_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_FLOAT8)) + return false; return overright_span_value(s, Float8GetDatum(d), T_FLOAT8); } @@ -951,8 +1026,10 @@ overright_floatspan_float(const Span *s, double d) bool overafter_period_timestamp(const Span *s, TimestampTz t) { - assert(s); - ensure_same_span_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_span_basetype(s, T_TIMESTAMPTZ)) + return false; return overright_span_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -965,8 +1042,11 @@ overafter_period_timestamp(const Span *s, TimestampTz t) bool overright_span_span(const Span *s1, const Span *s2) { - assert(s1); assert(s2); - ensure_same_span_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_span_type(s1, s2)) + return false; + int cmp = datum_cmp(s2->lower, s1->lower, s1->basetype); return (cmp < 0 || (cmp == 0 && (! s1->lower_inc || s2->lower_inc))); } @@ -985,8 +1065,7 @@ overright_span_span(const Span *s1, const Span *s2) void bbox_union_span_span(const Span *s1, const Span *s2, Span *result) { - assert(s1); assert(s2); - ensure_same_span_type(s1, s2); + assert(s1); assert(s2); assert(s1->spantype == s2->spantype); memset(result, 0, sizeof(Span)); memcpy(result, s1, sizeof(Span)); span_expand(s2, result); @@ -1017,8 +1096,9 @@ union_span_value(const Span *s, Datum d, meosType basetype) SpanSet * union_intspan_int(const Span *s, int i) { - assert(s); - ensure_same_span_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT4)) + return NULL; return union_span_value(s, Int32GetDatum(i), T_INT4); } @@ -1030,8 +1110,9 @@ union_intspan_int(const Span *s, int i) SpanSet * union_bigintspan_bigint(const Span *s, int64 i) { - assert(s); - ensure_same_span_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT8)) + return NULL; return union_span_value(s, Int64GetDatum(i), T_INT8); } @@ -1043,8 +1124,9 @@ union_bigintspan_bigint(const Span *s, int64 i) SpanSet * union_floatspan_float(const Span *s, double d) { - assert(s); - ensure_same_span_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_FLOAT8)) + return NULL; return union_span_value(s, Float8GetDatum(d), T_FLOAT8); } @@ -1056,8 +1138,10 @@ union_floatspan_float(const Span *s, double d) SpanSet * union_period_timestamp(const Span *s, TimestampTz t) { - assert(s); - ensure_same_span_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_span_basetype(s, T_TIMESTAMPTZ)) + return NULL; return union_span_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -1070,8 +1154,11 @@ union_period_timestamp(const Span *s, TimestampTz t) SpanSet * union_span_span(const Span *s1, const Span *s2) { - assert(s1); assert(s2); - ensure_same_span_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_span_type(s1, s2)) + return NULL; + /* If the spans do not overlap */ if (! overlaps_span_span(s1, s2) && !adjacent_span_span(s1, s2)) @@ -1127,8 +1214,10 @@ intersection_span_value(const Span *s, Datum d, meosType basetype, bool intersection_intspan_int(const Span *s, int i, int *result) { - assert(s); - ensure_same_span_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT4)) + return false; + if (! contains_span_value(s, Int32GetDatum(i), T_INT4)) return false; *result = i; @@ -1144,8 +1233,10 @@ intersection_intspan_int(const Span *s, int i, int *result) bool intersection_bigintspan_bigint(const Span *s, int64 i, int64 *result) { - assert(s); - ensure_same_span_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT8)) + return false; + if (! contains_span_value(s, Int64GetDatum(i), T_INT8)) return false; *result = i; @@ -1161,8 +1252,10 @@ intersection_bigintspan_bigint(const Span *s, int64 i, int64 *result) bool intersection_floatspan_float(const Span *s, double d, double *result) { - assert(s); - ensure_same_span_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_FLOAT8)) + return false; + if (! contains_span_value(s, Float8GetDatum(d), T_FLOAT8)) return false; *result = d; @@ -1179,8 +1272,11 @@ bool intersection_period_timestamp(const Span *s, TimestampTz t, TimestampTz *result) { - assert(s); - ensure_same_span_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_span_basetype(s, T_TIMESTAMPTZ)) + return false; + if (! contains_span_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ)) return false; *result = t; @@ -1197,8 +1293,7 @@ intersection_period_timestamp(const Span *s, TimestampTz t, bool inter_span_span(const Span *s1, const Span *s2, Span *result) { - assert(s1); assert(s2); - ensure_same_span_type(s1, s2); + assert(s1); assert(s2); assert(s1->spantype == s2->spantype); /* Bounding box test */ if (! overlaps_span_span(s1, s2)) return false; @@ -1222,8 +1317,11 @@ inter_span_span(const Span *s1, const Span *s2, Span *result) Span * intersection_span_span(const Span *s1, const Span *s2) { - assert(s1); assert(s2); - ensure_same_span_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_span_type(s1, s2)) + return NULL; + Span result; if (! inter_span_span(s1, s2, &result)) return NULL; @@ -1259,8 +1357,11 @@ minus_value_span(Datum d, meosType basetype, const Span *s, bool minus_int_intspan(int i, const Span *s, int *result) { - assert(s); - ensure_same_span_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_same_span_basetype(s, T_INT4)) + return false; + Datum v; bool found = minus_value_span(Int32GetDatum(i), T_INT4, s, &v); *result = DatumGetInt32(v); @@ -1276,8 +1377,11 @@ minus_int_intspan(int i, const Span *s, int *result) bool minus_bigint_bigintspan(int64 i, const Span *s, int64 *result) { - assert(s); - ensure_same_span_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_same_span_basetype(s, T_INT8)) + return false; + Datum v; bool found = minus_value_span(Int64GetDatum(i), T_INT8, s, &v); *result = DatumGetInt64(v); @@ -1292,8 +1396,11 @@ minus_bigint_bigintspan(int64 i, const Span *s, int64 *result) bool minus_float_floatspan(double d, const Span *s, double *result) { - assert(s); - ensure_same_span_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_same_span_basetype(s, T_FLOAT8)) + return false; + Datum v; bool found = minus_value_span(Float8GetDatum(d), T_FLOAT8, s, &v); *result = DatumGetFloat8(v); @@ -1308,8 +1415,11 @@ minus_float_floatspan(double d, const Span *s, double *result) bool minus_timestamp_period(TimestampTz t, const Span *s, TimestampTz *result) { - assert(s); - ensure_same_span_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) result) || + ! ensure_same_span_basetype(s, T_TIMESTAMPTZ)) + return false; + Datum v; bool res = minus_value_span(TimestampTzGetDatum(t), T_TIMESTAMPTZ, s, &v); *result = DatumGetTimestampTz(v); @@ -1388,8 +1498,9 @@ minus_span_value(const Span *s, Datum d, meosType basetype) SpanSet * minus_intspan_int(const Span *s, int i) { - assert(s); - ensure_same_span_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT4)) + return NULL; return minus_span_value(s, Int32GetDatum(i), T_INT4); } @@ -1401,8 +1512,9 @@ minus_intspan_int(const Span *s, int i) SpanSet * minus_bigintspan_bigint(const Span *s, int64 i) { - assert(s); - ensure_same_span_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT8)) + return NULL; return minus_span_value(s, Int64GetDatum(i), T_INT8); } @@ -1414,8 +1526,9 @@ minus_bigintspan_bigint(const Span *s, int64 i) SpanSet * minus_floatspan_float(const Span *s, double d) { - assert(s); - ensure_same_span_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_FLOAT8)) + return NULL; return minus_span_value(s, Float8GetDatum(d), T_FLOAT8); } @@ -1427,8 +1540,10 @@ minus_floatspan_float(const Span *s, double d) SpanSet * minus_period_timestamp(const Span *s, TimestampTz t) { - assert(s); - ensure_same_span_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_span_basetype(s, T_TIMESTAMPTZ)) + return NULL; return minus_span_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -1506,8 +1621,11 @@ minus_span_span_iter(const Span *s1, const Span *s2, Span *result) SpanSet * minus_span_span(const Span *s1, const Span *s2) { - assert(s1); assert(s2); - ensure_same_span_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_span_type(s1, s2)) + return NULL; + Span spans[2]; int count = minus_span_span_iter(s1, s2, spans); if (count == 0) @@ -1537,8 +1655,9 @@ distance_value_value(Datum l, Datum r, meosType type) /* Distance in seconds if the base type is TimestampTz */ return (double) (llabs((DatumGetTimestampTz(l) - DatumGetTimestampTz(r)))) / USECS_PER_SEC; - elog(ERROR, "Unknown types for distance between values of type: %d", type); - return 0; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "Unknown types for distance between values of type: %d", type); + return DBL_MAX; } /** @@ -1575,8 +1694,9 @@ distance_span_value(const Span *s, Datum d, meosType basetype) double distance_intspan_int(const Span *s, int i) { - assert(s); - ensure_same_span_basetype(s, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT4)) + return -1.0; return distance_span_value(s, Int32GetDatum(i), T_INT4); } @@ -1589,8 +1709,9 @@ distance_intspan_int(const Span *s, int i) double distance_bigintspan_bigint(const Span *s, int64 i) { - assert(s); - ensure_same_span_basetype(s, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_INT8)) + return -1.0; return distance_span_value(s, Int64GetDatum(i), T_INT8); } @@ -1602,8 +1723,9 @@ distance_bigintspan_bigint(const Span *s, int64 i) double distance_floatspan_float(const Span *s, double d) { - assert(s); - ensure_same_span_basetype(s, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_same_span_basetype(s, T_FLOAT8)) + return -1.0; return distance_span_value(s, Float8GetDatum(d), T_FLOAT8); } @@ -1616,8 +1738,10 @@ distance_floatspan_float(const Span *s, double d) double distance_period_timestamp(const Span *s, TimestampTz t) { - assert(s); - ensure_same_span_basetype(s, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || + ! ensure_same_span_basetype(s, T_TIMESTAMPTZ)) + return -1.0; return distance_span_value(s, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -1630,8 +1754,11 @@ distance_period_timestamp(const Span *s, TimestampTz t) double distance_span_span(const Span *s1, const Span *s2) { - assert(s1); assert(s2); - ensure_same_span_type(s1, s2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s1) || ! ensure_not_null((void *) s2) || + ! ensure_same_span_type(s1, s2)) + return -1.0; + /* If the spans intersect return 0 */ if (overlaps_span_span(s1, s2)) return 0.0; diff --git a/meos/src/general/spanset.c b/meos/src/general/spanset.c index 44483aede1..ce7999258f 100644 --- a/meos/src/general/spanset.c +++ b/meos/src/general/spanset.c @@ -36,6 +36,8 @@ /* C */ #include +#include +#include /* PostgreSQL */ #include #include @@ -57,45 +59,61 @@ /** * @brief Ensure that a span value is of a span type */ -void +bool ensure_spanset_has_type(const SpanSet *ss, meosType spansettype) { if (ss->spansettype != spansettype) - elog(ERROR, "The span set value must be of type %s", meostype_name(spansettype)); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "The span set value must be of type %s", meostype_name(spansettype)); + return false; + } + return true; } /** * @brief Ensure that the span set values have the same type */ -void +bool ensure_same_spanset_type(const SpanSet *ss1, const SpanSet *ss2) { if (ss1->spansettype != ss2->spansettype) - elog(ERROR, "Operation on mixed span set types"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "Operation on mixed span set types"); + return false; + } + return true; } /** * @brief Ensure that a span set and a span value have the same span type */ -void +bool ensure_same_spanset_spantype(const SpanSet *ss, const Span *s) { if (ss->spantype != s->spantype) - elog(ERROR, "Operation on mixed span set and span types"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "Operation on mixed span set and span types"); + return false; + } + return true; } /** * @brief Ensure that a span set value has the same base type as the given one */ -void +bool ensure_same_spanset_basetype(const SpanSet *ss, meosType basetype) { if (ss->basetype != basetype) - elog(ERROR, "Operation on mixed span set and base types"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "Operation on mixed span set and base types"); + return false; + } + return true; } /** @@ -191,7 +209,9 @@ spanset_in(const char *str, meosType spansettype) SpanSet * intspanset_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return spanset_parse(&str, T_INTSPANSET); } @@ -202,7 +222,9 @@ intspanset_in(const char *str) SpanSet * bigintspanset_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return spanset_parse(&str, T_BIGINTSPANSET); } @@ -213,7 +235,9 @@ bigintspanset_in(const char *str) SpanSet * floatspanset_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return spanset_parse(&str, T_FLOATSPANSET); } @@ -224,7 +248,9 @@ floatspanset_in(const char *str) SpanSet * periodset_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return spanset_parse(&str, T_TSTZSPANSET); } #endif /* MEOS */ @@ -238,7 +264,7 @@ spanset_out(const SpanSet *ss, int maxdd) { /* Ensure validity of the arguments */ assert(ss); - ensure_non_negative(maxdd); + assert(maxdd >= 0); char **strings = palloc(sizeof(char *) * ss->count); size_t outlen = 0; @@ -260,8 +286,10 @@ spanset_out(const SpanSet *ss, int maxdd) char * intspanset_out(const SpanSet *ss) { - assert(ss); - ensure_spanset_has_type(ss, T_INTSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_INTSPANSET)) + return NULL; return spanset_out(ss, 0); } @@ -272,8 +300,10 @@ intspanset_out(const SpanSet *ss) char * bigintspanset_out(const SpanSet *ss) { - assert(ss); - ensure_spanset_has_type(ss, T_BIGINTSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_BIGINTSPANSET)) + return NULL; return spanset_out(ss, 0); } @@ -284,8 +314,10 @@ bigintspanset_out(const SpanSet *ss) char * floatspanset_out(const SpanSet *ss, int maxdd) { - assert(ss); - ensure_spanset_has_type(ss, T_FLOATSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_FLOATSPANSET)) + return NULL; return spanset_out(ss, maxdd); } @@ -296,8 +328,10 @@ floatspanset_out(const SpanSet *ss, int maxdd) char * periodset_out(const SpanSet *ss) { - assert(ss); - ensure_spanset_has_type(ss, T_TSTZSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_TSTZSPANSET)) + return NULL; return spanset_out(ss, 0); } #endif /* MEOS */ @@ -307,7 +341,7 @@ periodset_out(const SpanSet *ss) ****************************************************************************/ /** - * @ingroup libmeos_setspan_constructor + * @ingroup libmeos_internal_setspan_constructor * @brief Construct a span set from an array of disjoint spans enabling the * data structure to expand. * @@ -342,7 +376,11 @@ spanset_make_exp(Span *spans, int count, int maxcount, bool normalize, int cmp = datum_cmp(spans[i].upper, spans[i + 1].lower, spans[i].basetype); if (cmp > 0 || (cmp == 0 && spans[i].upper_inc && spans[i + 1].lower_inc)) - elog(ERROR, "Invalid value for span set"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Invalid value for span set"); + return NULL; + } } } @@ -388,6 +426,9 @@ spanset_make_exp(Span *spans, int count, int maxcount, bool normalize, SpanSet * spanset_make(Span *spans, int count, bool normalize) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) spans) || ! ensure_positive(count)) + return NULL; return spanset_make_exp(spans, count, count, normalize, true); } @@ -400,7 +441,6 @@ spanset_make(Span *spans, int count, bool normalize) * @param[in] count Number of elements in the array * @param[in] normalize True if the resulting value should be normalized. * @see spanset_make - * @sqlfunc spanset() */ SpanSet * spanset_make_free(Span *spans, int count, bool normalize) @@ -419,7 +459,10 @@ spanset_make_free(Span *spans, int count, bool normalize) SpanSet * spanset_copy(const SpanSet *ss) { - assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss)) + return NULL; + SpanSet *result = palloc(VARSIZE(ss)); memcpy(result, ss, VARSIZE(ss)); return result; @@ -497,7 +540,10 @@ timestamp_to_periodset(TimestampTz t) SpanSet * set_to_spanset(const Set *s) { - assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return NULL; + Span *spans = palloc(sizeof(Span) * s->count); for (int i = 0; i < s->count; i++) { @@ -515,7 +561,9 @@ set_to_spanset(const Set *s) SpanSet * span_to_spanset(const Span *s) { - assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return NULL; return spanset_make((Span *) s, 1, NORMALIZE_NO); } @@ -550,11 +598,12 @@ SpanSet * periodset_shift_tscale(const SpanSet *ss, const Interval *shift, const Interval *duration) { - assert(ss); - ensure_spanset_has_type(ss, T_TSTZSPANSET); - assert(shift || duration); - if (duration) - ensure_valid_duration(duration); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_TSTZSPANSET) || + ! ensure_one_not_null((void *) shift, (void *) duration) || + (duration && ! ensure_valid_duration(duration))) + return NULL; /* Copy the input period set to the output period set */ SpanSet *result = spanset_copy(ss); @@ -571,16 +620,17 @@ periodset_shift_tscale(const SpanSet *ss, const Interval *shift, } /** - * @ingroup libmeos_internal_setspan_transf + * @ingroup libmeos_setspan_transf * @brief Set the precision of the float span set to the number of decimal places. */ SpanSet * floatspanset_round(const SpanSet *ss, int maxdd) { /* Ensure validity of the arguments */ - assert(ss); - ensure_spanset_has_type(ss, T_FLOATSPANSET); - ensure_non_negative(maxdd); + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_FLOATSPANSET) || + ! ensure_non_negative(maxdd)) + return NULL; Span *spans = palloc(sizeof(Span) * ss->count); Datum size = Int32GetDatum(maxdd); @@ -618,7 +668,10 @@ spanset_mem_size(const SpanSet *ss) Span * spanset_span(const SpanSet *ss) { - assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss)) + return NULL; + Span *result = palloc(sizeof(Span)); memcpy(result, &ss->span, sizeof(Span)); return result; @@ -632,8 +685,10 @@ spanset_span(const SpanSet *ss) int intspanset_lower(const SpanSet *ss) { - assert(ss); - ensure_spanset_has_type(ss, T_INTSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_INTSPANSET)) + return INT_MAX; return DatumGetInt32(ss->elems[0].lower); } @@ -645,8 +700,10 @@ intspanset_lower(const SpanSet *ss) int bigintspanset_lower(const SpanSet *ss) { - assert(ss); - ensure_spanset_has_type(ss, T_BIGINTSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_BIGINTSPANSET)) + return INT_MAX; return DatumGetInt64(ss->elems[0].lower); } @@ -658,8 +715,10 @@ bigintspanset_lower(const SpanSet *ss) double floatspanset_lower(const SpanSet *ss) { - assert(ss); - ensure_spanset_has_type(ss, T_FLOATSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_FLOATSPANSET)) + return DBL_MAX; return Float8GetDatum(ss->elems[0].lower); } @@ -671,8 +730,10 @@ floatspanset_lower(const SpanSet *ss) TimestampTz periodset_lower(const SpanSet *ss) { - assert(ss); - ensure_spanset_has_type(ss, T_TSTZSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_TSTZSPANSET)) + return DT_NOEND; return TimestampTzGetDatum(ss->elems[0].lower); } @@ -684,8 +745,10 @@ periodset_lower(const SpanSet *ss) int intspanset_upper(const SpanSet *ss) { - assert(ss); - ensure_spanset_has_type(ss, T_INTSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_INTSPANSET)) + return INT_MAX; return Int32GetDatum(ss->elems[ss->count - 1].upper); } @@ -697,8 +760,10 @@ intspanset_upper(const SpanSet *ss) int bigintspanset_upper(const SpanSet *ss) { - assert(ss); - ensure_spanset_has_type(ss, T_BIGINTSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_BIGINTSPANSET)) + return INT_MAX; return Int64GetDatum(ss->elems[ss->count - 1].upper); } @@ -710,8 +775,10 @@ bigintspanset_upper(const SpanSet *ss) double floatspanset_upper(const SpanSet *ss) { - assert(ss); - ensure_spanset_has_type(ss, T_FLOATSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_FLOATSPANSET)) + return DBL_MAX; return Float8GetDatum(ss->elems[ss->count - 1].upper); } @@ -723,8 +790,10 @@ floatspanset_upper(const SpanSet *ss) TimestampTz periodset_upper(const SpanSet *ss) { - assert(ss); - ensure_spanset_has_type(ss, T_TSTZSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_TSTZSPANSET)) + return DT_NOEND; return TimestampTzGetDatum(ss->elems[ss->count - 1].upper); } #endif /* MEOS */ @@ -737,7 +806,9 @@ periodset_upper(const SpanSet *ss) bool spanset_lower_inc(const SpanSet *ss) { - assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss)) + return false; return ss->elems[0].lower_inc; } @@ -749,7 +820,9 @@ spanset_lower_inc(const SpanSet *ss) bool spanset_upper_inc(const SpanSet *ss) { - assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss)) + return false; return ss->elems[ss->count - 1].upper_inc; } @@ -761,7 +834,10 @@ spanset_upper_inc(const SpanSet *ss) double spanset_width(const SpanSet *ss) { - assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss)) + return -1.0; + double result = 0; for (int i = 0; i < ss->count; i++) { @@ -779,8 +855,11 @@ spanset_width(const SpanSet *ss) Interval * periodset_duration(const SpanSet *ss, bool boundspan) { - assert(ss); - ensure_spanset_has_type(ss, T_TSTZSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_TSTZSPANSET)) + return NULL; + if (boundspan) return pg_timestamp_mi(ss->span.upper, ss->span.lower); @@ -805,8 +884,11 @@ periodset_duration(const SpanSet *ss, bool boundspan) int periodset_num_timestamps(const SpanSet *ss) { - assert(ss); - ensure_spanset_has_type(ss, T_TSTZSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_TSTZSPANSET)) + return -1; + const Span *p = spanset_sp_n(ss, 0); TimestampTz prev = p->lower; bool start = false; @@ -843,8 +925,11 @@ periodset_num_timestamps(const SpanSet *ss) TimestampTz periodset_start_timestamp(const SpanSet *ss) { - assert(ss); - ensure_spanset_has_type(ss, T_TSTZSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_TSTZSPANSET)) + return DT_NOEND; + const Span *p = spanset_sp_n(ss, 0); return p->lower; } @@ -857,8 +942,11 @@ periodset_start_timestamp(const SpanSet *ss) TimestampTz periodset_end_timestamp(const SpanSet *ss) { - assert(ss); - ensure_spanset_has_type(ss, T_TSTZSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_spanset_has_type(ss, T_TSTZSPANSET)) + return DT_NOEND; + const Span *p = spanset_sp_n(ss, ss->count - 1); return p->upper; } @@ -876,8 +964,11 @@ periodset_end_timestamp(const SpanSet *ss) bool periodset_timestamp_n(const SpanSet *ss, int n, TimestampTz *result) { - assert(ss); assert(result); - ensure_spanset_has_type(ss, T_TSTZSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) result) || + ! ensure_spanset_has_type(ss, T_TSTZSPANSET)) + return false; + int pernum = 0; const Span *p = spanset_sp_n(ss, pernum); TimestampTz d = p->lower; @@ -927,8 +1018,11 @@ periodset_timestamp_n(const SpanSet *ss, int n, TimestampTz *result) TimestampTz * periodset_timestamps(const SpanSet *ss, int *count) { - assert(ss); assert(count); - ensure_spanset_has_type(ss, T_TSTZSPANSET); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) count) || + ! ensure_spanset_has_type(ss, T_TSTZSPANSET)) + return NULL; + TimestampTz *result = palloc(sizeof(TimestampTz) * 2 * ss->count); const Span *p = spanset_sp_n(ss, 0); result[0] = p->lower; @@ -955,7 +1049,9 @@ periodset_timestamps(const SpanSet *ss, int *count) int spanset_num_spans(const SpanSet *ss) { - assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss)) + return -1; return ss->count; } @@ -967,7 +1063,10 @@ spanset_num_spans(const SpanSet *ss) Span * spanset_start_span(const SpanSet *ss) { - assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss)) + return NULL; + Span *result = span_copy(spanset_sp_n(ss, 0)); return result; } @@ -980,7 +1079,10 @@ spanset_start_span(const SpanSet *ss) Span * spanset_end_span(const SpanSet *ss) { - assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss)) + return NULL; + Span *result = span_copy(spanset_sp_n(ss, ss->count - 1)); return result; } @@ -993,7 +1095,10 @@ spanset_end_span(const SpanSet *ss) Span * spanset_span_n(const SpanSet *ss, int i) { - assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss)) + return NULL; + Span *result = NULL; if (i >= 1 && i <= ss->count) result = span_copy(spanset_sp_n(ss, i - 1)); @@ -1008,7 +1113,10 @@ spanset_span_n(const SpanSet *ss, int i) const Span ** spanset_spans(const SpanSet *ss) { - assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss)) + return NULL; + const Span **spans = palloc(sizeof(Span *) * ss->count); for (int i = 0; i < ss->count; i++) spans[i] = spanset_sp_n(ss, i); @@ -1028,8 +1136,11 @@ spanset_spans(const SpanSet *ss) bool spanset_eq(const SpanSet *ss1, const SpanSet *ss2) { - assert(ss1); assert(ss2); - ensure_same_spanset_type(ss1, ss2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss1) || ! ensure_not_null((void *) ss2) || + ! ensure_same_spanset_type(ss1, ss2)) + return false; + if (ss1->count != ss2->count) return false; /* ss1 and ss2 have the same number of SpanSet */ @@ -1066,8 +1177,11 @@ spanset_ne(const SpanSet *ss1, const SpanSet *ss2) int spanset_cmp(const SpanSet *ss1, const SpanSet *ss2) { - assert(ss1); assert(ss2); - ensure_same_spanset_type(ss1, ss2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss1) || ! ensure_not_null((void *) ss2) || + ! ensure_same_spanset_type(ss1, ss2)) + return INT_MAX; + int count1 = ss1->count; int count2 = ss2->count; int count = count1 < count2 ? count1 : count2; @@ -1153,7 +1267,10 @@ spanset_gt(const SpanSet *ss1, const SpanSet *ss2) uint32 spanset_hash(const SpanSet *ss) { - assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss)) + return INT_MAX; + uint32 result = 1; for (int i = 0; i < ss->count; i++) { @@ -1172,7 +1289,10 @@ spanset_hash(const SpanSet *ss) uint64 spanset_hash_extended(const SpanSet *ss, uint64 seed) { - assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss)) + return INT_MAX; + uint64 result = 1; for (int i = 0; i < ss->count; i++) { diff --git a/meos/src/general/spanset_ops.c b/meos/src/general/spanset_ops.c index 45603931e1..110ddc7603 100644 --- a/meos/src/general/spanset_ops.c +++ b/meos/src/general/spanset_ops.c @@ -60,7 +60,10 @@ TimestampTz timestamp_tprecision(TimestampTz t, const Interval *duration, TimestampTz torigin) { - ensure_valid_duration(duration); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) duration) || + ! ensure_valid_duration(duration)) + return DT_NOEND; TimestampTz result = timestamptz_bucket(t, duration, torigin); return result; } @@ -75,8 +78,11 @@ timestamp_tprecision(TimestampTz t, const Interval *duration, Span * period_tprecision(const Span *s, const Interval *duration, TimestampTz torigin) { - assert(s->basetype == T_TIMESTAMPTZ); - ensure_valid_duration(duration); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) duration) || + ! ensure_span_has_type(s, T_TSTZSPAN) || !ensure_valid_duration(duration)) + return NULL; + int64 tunits = interval_units(duration); TimestampTz lower = DatumGetTimestampTz(s->lower); TimestampTz upper = DatumGetTimestampTz(s->upper); @@ -100,8 +106,12 @@ SpanSet * periodset_tprecision(const SpanSet *ss, const Interval *duration, TimestampTz torigin) { - assert(ss->basetype == T_TIMESTAMPTZ); - ensure_valid_duration(duration); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) duration) || + ! ensure_spanset_has_type(ss, T_TSTZSPANSET) || + ! ensure_valid_duration(duration)) + return NULL; + int64 tunits = interval_units(duration); TimestampTz lower = DatumGetTimestampTz(ss->span.lower); TimestampTz upper = DatumGetTimestampTz(ss->span.upper); @@ -164,8 +174,10 @@ contains_spanset_value(const SpanSet *ss, Datum d, meosType basetype) bool contains_intspanset_int(const SpanSet *ss, int i) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT4)) + return false; return contains_spanset_value(ss, Int32GetDatum(i), T_INT4); } @@ -177,8 +189,10 @@ contains_intspanset_int(const SpanSet *ss, int i) bool contains_bigintspanset_bigint(const SpanSet *ss, int64 i) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT8)) + return false; return contains_spanset_value(ss, Int64GetDatum(i), T_INT8); } @@ -190,8 +204,10 @@ contains_bigintspanset_bigint(const SpanSet *ss, int64 i) bool contains_floatspanset_float(const SpanSet *ss, double d) { - assert(ss); - ensure_same_spanset_basetype(ss, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_FLOAT8)) + return false; return contains_spanset_value(ss, Float8GetDatum(d), T_FLOAT8); } #endif /* MEOS */ @@ -204,8 +220,10 @@ contains_floatspanset_float(const SpanSet *ss, double d) bool contains_periodset_timestamp(const SpanSet *ss, TimestampTz t) { - assert(ss); - ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ)) + return false; return contains_spanset_value(ss, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } @@ -217,8 +235,11 @@ contains_periodset_timestamp(const SpanSet *ss, TimestampTz t) bool contains_spanset_span(const SpanSet *ss, const Span *s) { - assert(ss); - ensure_same_spanset_spantype(ss, s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) s) || + ! ensure_same_spanset_spantype(ss, s)) + return false; + /* Bounding box test */ if (! contains_span_span(&ss->span, s)) return false; @@ -248,8 +269,11 @@ contains_span_spanset(const Span *s, const SpanSet *ss) bool contains_spanset_spanset(const SpanSet *ss1, const SpanSet *ss2) { - assert(ss1); assert(ss2); - ensure_same_spanset_type(ss1, ss2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss1) || ! ensure_not_null((void *) ss2) || + ! ensure_same_spanset_type(ss1, ss2)) + return false; + /* Bounding box test */ if (! contains_span_span(&ss1->span, &ss2->span)) return false; @@ -307,8 +331,10 @@ contained_value_spanset(Datum d, meosType basetype, const SpanSet *ss) bool contained_int_intspanset(int i, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT4)) + return false; return contained_value_spanset(Int32GetDatum(i), T_INT4, ss); } @@ -320,8 +346,10 @@ contained_int_intspanset(int i, const SpanSet *ss) bool contained_bigint_bigintspanset(int64 i, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT8)) + return false; return contained_value_spanset(Int64GetDatum(i), T_INT8, ss); } @@ -333,8 +361,10 @@ contained_bigint_bigintspanset(int64 i, const SpanSet *ss) bool contained_float_floatspanset(double d, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_basetype(ss, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_FLOAT8)) + return false; return contained_value_spanset(Float8GetDatum(d), T_FLOAT8, ss); } @@ -346,8 +376,10 @@ contained_float_floatspanset(double d, const SpanSet *ss) bool contained_timestamp_periodset(TimestampTz t, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ)) + return false; return contained_value_spanset(TimestampTzGetDatum(t), T_TIMESTAMPTZ, ss); } #endif /* MEOS */ @@ -397,8 +429,11 @@ contained_spanset_spanset(const SpanSet *ss1, const SpanSet *ss2) bool overlaps_spanset_span(const SpanSet *ss, const Span *s) { - assert(ss); - ensure_same_spanset_spantype(ss, s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) s) || + ! ensure_same_spanset_spantype(ss, s)) + return false; + /* Bounding box test */ if (! overlaps_span_span(s, &ss->span)) return false; @@ -425,8 +460,11 @@ overlaps_spanset_span(const SpanSet *ss, const Span *s) bool overlaps_spanset_spanset(const SpanSet *ss1, const SpanSet *ss2) { - assert(ss1); assert(ss2); - ensure_same_spanset_type(ss1, ss2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss1) || ! ensure_not_null((void *) ss2) || + ! ensure_same_spanset_type(ss1, ss2)) + return false; + /* Bounding box test */ if (! overlaps_span_span(&ss1->span, &ss2->span)) return false; @@ -482,8 +520,10 @@ adjacent_spanset_value(const SpanSet *ss, Datum d, meosType basetype) bool adjacent_intspanset_int(const SpanSet *ss, int i) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT4)) + return false; return adjacent_spanset_value(ss, Int32GetDatum(i), T_INT4); } @@ -495,8 +535,10 @@ adjacent_intspanset_int(const SpanSet *ss, int i) bool adjacent_bigintspanset_bigint(const SpanSet *ss, int64 i) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT8)) + return false; return adjacent_spanset_value(ss, Int64GetDatum(i), T_INT8); } @@ -508,8 +550,10 @@ adjacent_bigintspanset_bigint(const SpanSet *ss, int64 i) bool adjacent_floatspanset_float(const SpanSet *ss, double d) { - assert(ss); - ensure_same_spanset_basetype(ss, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_FLOAT8)) + return false; return adjacent_spanset_value(ss, Float8GetDatum(d), T_FLOAT8); } @@ -521,8 +565,10 @@ adjacent_floatspanset_float(const SpanSet *ss, double d) bool adjacent_periodset_timestamp(const SpanSet *ss, TimestampTz t) { - assert(ss); - ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ)) + return false; return adjacent_spanset_value(ss, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -535,8 +581,11 @@ adjacent_periodset_timestamp(const SpanSet *ss, TimestampTz t) bool adjacent_spanset_span(const SpanSet *ss, const Span *s) { - assert(ss); - ensure_same_spanset_spantype(ss, s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) s) || + ! ensure_same_spanset_spantype(ss, s)) + return false; + const Span *s1 = spanset_sp_n(ss, 0); const Span *s2 = spanset_sp_n(ss, ss->count - 1); /* @@ -555,8 +604,11 @@ adjacent_spanset_span(const SpanSet *ss, const Span *s) bool adjacent_spanset_spanset(const SpanSet *ss1, const SpanSet *ss2) { - assert(ss1); assert(ss2); - ensure_same_spanset_type(ss1, ss2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss1) || ! ensure_not_null((void *) ss2) || + ! ensure_same_spanset_type(ss1, ss2)) + return false; + const Span *startps1 = spanset_sp_n(ss1, 0); const Span *endps1 = spanset_sp_n(ss1, ss1->count - 1); const Span *startps2 = spanset_sp_n(ss2, 0); @@ -594,8 +646,10 @@ left_value_spanset(Datum d, meosType basetype, const SpanSet *ss) bool left_int_intspanset(int i, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT4)) + return false; return left_value_spanset(Int32GetDatum(i), T_INT4, ss); } @@ -608,8 +662,10 @@ left_int_intspanset(int i, const SpanSet *ss) bool left_bigint_bigintspanset(int64 i, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT8)) + return false; return left_value_spanset(Int64GetDatum(i), T_INT8, ss); } @@ -621,8 +677,10 @@ left_bigint_bigintspanset(int64 i, const SpanSet *ss) bool left_float_floatspanset(double d, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_basetype(ss, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_FLOAT8)) + return false; return left_value_spanset(Float8GetDatum(d), T_FLOAT8, ss); } @@ -634,8 +692,10 @@ left_float_floatspanset(double d, const SpanSet *ss) bool before_timestamp_periodset(TimestampTz t, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ)) + return false; return left_value_spanset(TimestampTzGetDatum(t), T_TIMESTAMPTZ, ss); } #endif /* MEOS */ @@ -648,8 +708,11 @@ before_timestamp_periodset(TimestampTz t, const SpanSet *ss) bool left_span_spanset(const Span *s, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_spantype(ss, s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) s) || + ! ensure_same_spanset_spantype(ss, s)) + return false; + const Span *s1 = spanset_sp_n(ss, 0); return left_span_span(s, s1); } @@ -676,8 +739,10 @@ left_spanset_value(const SpanSet *ss, Datum d, meosType basetype) bool left_intspanset_int(const SpanSet *ss, int i) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT4)) + return false; return left_spanset_value(ss, Int32GetDatum(i), T_INT4); } @@ -690,8 +755,10 @@ left_intspanset_int(const SpanSet *ss, int i) bool left_bigintspanset_bigint(const SpanSet *ss, int64 i) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT8)) + return false; return left_spanset_value(ss, Int64GetDatum(i), T_INT8); } @@ -703,8 +770,10 @@ left_bigintspanset_bigint(const SpanSet *ss, int64 i) bool left_floatspanset_float(const SpanSet *ss, double d) { - assert(ss); - ensure_same_spanset_basetype(ss, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_FLOAT8)) + return false; return left_spanset_value(ss, Float8GetDatum(d), T_FLOAT8); } @@ -716,8 +785,10 @@ left_floatspanset_float(const SpanSet *ss, double d) bool before_periodset_timestamp(const SpanSet *ss, TimestampTz t) { - assert(ss); - ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ)) + return false; return left_spanset_value(ss, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -730,8 +801,11 @@ before_periodset_timestamp(const SpanSet *ss, TimestampTz t) bool left_spanset_span(const SpanSet *ss, const Span *s) { - assert(ss); - ensure_same_spanset_spantype(ss, s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) s) || + ! ensure_same_spanset_spantype(ss, s)) + return false; + const Span *s1 = spanset_sp_n(ss, ss->count - 1); return left_span_span(s1, s); } @@ -745,8 +819,11 @@ left_spanset_span(const SpanSet *ss, const Span *s) bool left_spanset_spanset(const SpanSet *ss1, const SpanSet *ss2) { - assert(ss1); assert(ss2); - ensure_same_spanset_type(ss1, ss2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss1) || ! ensure_not_null((void *) ss2) || + ! ensure_same_spanset_type(ss1, ss2)) + return false; + const Span *s1 = spanset_sp_n(ss1, ss1->count - 1); const Span *s2 = spanset_sp_n(ss2, 0); return left_span_span(s1, s2); @@ -931,8 +1008,10 @@ overleft_spanset_value(const SpanSet *ss, Datum d, meosType basetype) bool overleft_intspanset_int(const SpanSet *ss, int i) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT4)) + return false; return overleft_spanset_value(ss, Int32GetDatum(i), T_INT4); } @@ -945,8 +1024,10 @@ overleft_intspanset_int(const SpanSet *ss, int i) bool overleft_bigintspanset_bigint(const SpanSet *ss, int64 i) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT8)) + return false; return overleft_spanset_value(ss, Int64GetDatum(i), T_INT8); } @@ -959,8 +1040,10 @@ overleft_bigintspanset_bigint(const SpanSet *ss, int64 i) bool overleft_floatspanset_float(const SpanSet *ss, double d) { - assert(ss); - ensure_same_spanset_basetype(ss, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_FLOAT8)) + return false; return overleft_spanset_value(ss, Float8GetDatum(d), T_FLOAT8); } @@ -972,8 +1055,10 @@ overleft_floatspanset_float(const SpanSet *ss, double d) bool overbefore_periodset_timestamp(const SpanSet *ss, TimestampTz t) { - assert(ss); - ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ)) + return false; return overleft_spanset_value(ss, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -1000,8 +1085,10 @@ overleft_value_spanset(Datum d, meosType basetype, const SpanSet *ss) bool overleft_int_intspanset(int i, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT4)) + return false; return overleft_value_spanset(Int32GetDatum(i), T_INT4, ss); } @@ -1014,8 +1101,10 @@ overleft_int_intspanset(int i, const SpanSet *ss) bool overleft_bigint_bigintspanset(int64 i, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT8)) + return false; return overleft_value_spanset(Int64GetDatum(i), T_INT8, ss); } @@ -1027,8 +1116,10 @@ overleft_bigint_bigintspanset(int64 i, const SpanSet *ss) bool overleft_float_floatspanset(double d, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_basetype(ss, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_FLOAT8)) + return false; return overleft_value_spanset(Float8GetDatum(d), T_FLOAT8, ss); } @@ -1040,8 +1131,10 @@ overleft_float_floatspanset(double d, const SpanSet *ss) bool overbefore_timestamp_periodset(TimestampTz t, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ)) + return false; return overleft_value_spanset(TimestampTzGetDatum(t), T_TIMESTAMPTZ, ss); } #endif /* MEOS */ @@ -1054,8 +1147,11 @@ overbefore_timestamp_periodset(TimestampTz t, const SpanSet *ss) bool overleft_span_spanset(const Span *s, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_spantype(ss, s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) s) || + ! ensure_same_spanset_spantype(ss, s)) + return false; + const Span *s1 = spanset_sp_n(ss, ss->count - 1); return overleft_span_span(s, s1); } @@ -1068,8 +1164,11 @@ overleft_span_spanset(const Span *s, const SpanSet *ss) bool overleft_spanset_span(const SpanSet *ss, const Span *s) { - assert(ss); - ensure_same_spanset_spantype(ss, s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) s) || + ! ensure_same_spanset_spantype(ss, s)) + return false; + const Span *s1 = spanset_sp_n(ss, ss->count - 1); return overleft_span_span(s1, s); } @@ -1083,8 +1182,11 @@ overleft_spanset_span(const SpanSet *ss, const Span *s) bool overleft_spanset_spanset(const SpanSet *ss1, const SpanSet *ss2) { - assert(ss1); assert(ss2); - ensure_same_spanset_type(ss1, ss2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss1) || ! ensure_not_null((void *) ss2) || + ! ensure_same_spanset_type(ss1, ss2)) + return false; + const Span *s1 = spanset_sp_n(ss1, ss1->count - 1); const Span *s2 = spanset_sp_n(ss2, ss2->count - 1); return overleft_span_span(s1, s2); @@ -1116,8 +1218,10 @@ overright_value_spanset(Datum d, meosType basetype, const SpanSet *ss) bool overright_int_intspanset(int i, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT4)) + return false; return overright_value_spanset(Int32GetDatum(i), T_INT4, ss); } @@ -1130,8 +1234,10 @@ overright_int_intspanset(int i, const SpanSet *ss) bool overright_bigint_bigintspanset(int64 i, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT8)) + return false; return overright_value_spanset(Int64GetDatum(i), T_INT8, ss); } @@ -1143,8 +1249,10 @@ overright_bigint_bigintspanset(int64 i, const SpanSet *ss) bool overright_float_floatspanset(double d, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_basetype(ss, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_FLOAT8)) + return false; return overright_value_spanset(Float8GetDatum(d), T_FLOAT8, ss); } @@ -1156,8 +1264,10 @@ overright_float_floatspanset(double d, const SpanSet *ss) bool overafter_timestamp_periodset(TimestampTz t, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ)) + return false; return overright_value_spanset(TimestampTzGetDatum(t), T_TIMESTAMPTZ, ss); } #endif /* MEOS */ @@ -1170,8 +1280,11 @@ overafter_timestamp_periodset(TimestampTz t, const SpanSet *ss) bool overright_span_spanset(const Span *s, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_spantype(ss, s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) s) || + ! ensure_same_spanset_spantype(ss, s)) + return false; + const Span *s1 = spanset_sp_n(ss, 0); return overright_span_span(s, s1); } @@ -1198,8 +1311,10 @@ overright_spanset_value(const SpanSet *ss, Datum d, meosType basetype) bool overright_intspanset_int(const SpanSet *ss, int i) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT4)) + return false; return overright_spanset_value(ss, Int32GetDatum(i), T_INT4); } @@ -1212,8 +1327,10 @@ overright_intspanset_int(const SpanSet *ss, int i) bool overright_bigintspanset_bigint(const SpanSet *ss, int64 i) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT8)) + return false; return overright_spanset_value(ss, Int64GetDatum(i), T_INT8); } @@ -1225,8 +1342,10 @@ overright_bigintspanset_bigint(const SpanSet *ss, int64 i) bool overright_floatspanset_float(const SpanSet *ss, double d) { - assert(ss); - ensure_same_spanset_basetype(ss, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_FLOAT8)) + return false; return overright_spanset_value(ss, Float8GetDatum(d), T_FLOAT8); } @@ -1238,8 +1357,10 @@ overright_floatspanset_float(const SpanSet *ss, double d) bool overafter_periodset_timestamp(const SpanSet *ss, TimestampTz t) { - assert(ss); - ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ)) + return false; return overright_spanset_value(ss, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -1252,8 +1373,11 @@ overafter_periodset_timestamp(const SpanSet *ss, TimestampTz t) bool overright_spanset_span(const SpanSet *ss, const Span *s) { - assert(ss); - ensure_same_spanset_spantype(ss, s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) s) || + ! ensure_same_spanset_spantype(ss, s)) + return false; + const Span *s1 = spanset_sp_n(ss, 0); return overright_span_span(s1, s); } @@ -1267,8 +1391,11 @@ overright_spanset_span(const SpanSet *ss, const Span *s) bool overright_spanset_spanset(const SpanSet *ss1, const SpanSet *ss2) { - assert(ss1); assert(ss2); - ensure_same_spanset_type(ss1, ss2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss1) || ! ensure_not_null((void *) ss2) || + ! ensure_same_spanset_type(ss1, ss2)) + return false; + const Span *s1 = spanset_sp_n(ss1, 0); const Span *s2 = spanset_sp_n(ss2, 0); return overright_span_span(s1, s2); @@ -1301,8 +1428,10 @@ union_spanset_value(const SpanSet *ss, Datum d, meosType basetype) SpanSet * union_intspanset_int(const SpanSet *ss, int i) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT4)) + return NULL; return union_spanset_value(ss, Int32GetDatum(i), T_INT4); } @@ -1314,8 +1443,10 @@ union_intspanset_int(const SpanSet *ss, int i) SpanSet * union_bigintspanset_bigint(const SpanSet *ss, int64 i) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT8)) + return NULL; return union_spanset_value(ss, Int64GetDatum(i), T_INT8); } @@ -1327,8 +1458,10 @@ union_bigintspanset_bigint(const SpanSet *ss, int64 i) SpanSet * union_floatspanset_float(const SpanSet *ss, double d) { - assert(ss); - ensure_same_spanset_basetype(ss, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_FLOAT8)) + return NULL; return union_spanset_value(ss, Float8GetDatum(d), T_FLOAT8); } @@ -1340,8 +1473,10 @@ union_floatspanset_float(const SpanSet *ss, double d) SpanSet * union_periodset_timestamp(SpanSet *ss, TimestampTz t) { - assert(ss); - ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ)) + return NULL; return union_spanset_value(ss, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -1354,8 +1489,11 @@ union_periodset_timestamp(SpanSet *ss, TimestampTz t) SpanSet * union_spanset_span(const SpanSet *ss, const Span *s) { - assert(ss); - ensure_same_spanset_spantype(ss, s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) s) || + ! ensure_same_spanset_spantype(ss, s)) + return NULL; + /* Transform the span into a span set */ SpanSet *ss1 = span_to_spanset(s); /* Call the function for the span set */ @@ -1372,8 +1510,11 @@ union_spanset_span(const SpanSet *ss, const Span *s) SpanSet * union_spanset_spanset(const SpanSet *ss1, const SpanSet *ss2) { - assert(ss1); assert(ss2); - ensure_same_spanset_type(ss1, ss2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss1) || ! ensure_not_null((void *) ss2) || + ! ensure_same_spanset_type(ss1, ss2)) + return NULL; + Span *spans = palloc(sizeof(Span) * (ss1->count + ss2->count)); int i = 0, j = 0, nspans = 0; while (i < ss1->count && j < ss2->count) @@ -1489,8 +1630,11 @@ intersection_spanset_value(const SpanSet *ss, Datum d, meosType basetype, bool intersection_intspanset_int(const SpanSet *ss, int i, int *result) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) result) || + ! ensure_same_spanset_basetype(ss, T_INT4)) + return false; + if (! contains_spanset_value(ss, Int32GetDatum(i), T_INT4)) return false; *result = i; @@ -1505,8 +1649,11 @@ intersection_intspanset_int(const SpanSet *ss, int i, int *result) bool intersection_bigintspanset_bigint(const SpanSet *ss, int64 i, int64 *result) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) result) || + ! ensure_same_spanset_basetype(ss, T_INT8)) + return false; + if (! contains_spanset_value(ss, Int64GetDatum(i), T_INT8)) return false; *result = i; @@ -1522,8 +1669,11 @@ intersection_bigintspanset_bigint(const SpanSet *ss, int64 i, int64 *result) bool intersection_floatspanset_float(const SpanSet *ss, double d, double *result) { - assert(ss); - ensure_same_spanset_basetype(ss, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) result) || + ! ensure_same_spanset_basetype(ss, T_FLOAT8)) + return false; + if (! contains_spanset_value(ss, Float8GetDatum(d), T_FLOAT8)) return false; *result = d; @@ -1540,8 +1690,11 @@ bool intersection_periodset_timestamp(const SpanSet *ss, TimestampTz t, TimestampTz *result) { - assert(ss); - ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) result) || + ! ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ)) + return false; + if (! contains_spanset_value(ss, TimestampTzGetDatum(t), T_TIMESTAMPTZ)) return false; *result = t; @@ -1557,8 +1710,11 @@ intersection_periodset_timestamp(const SpanSet *ss, TimestampTz t, SpanSet * intersection_spanset_span(const SpanSet *ss, const Span *s) { - assert(ss); - ensure_same_spanset_spantype(ss, s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) s) || + ! ensure_same_spanset_spantype(ss, s)) + return NULL; + /* Bounding box test */ if (! overlaps_span_span(s, &ss->span)) return NULL; @@ -1596,8 +1752,11 @@ intersection_spanset_span(const SpanSet *ss, const Span *s) SpanSet * intersection_spanset_spanset(const SpanSet *ss1, const SpanSet *ss2) { - assert(ss1); assert(ss2); - ensure_same_spanset_type(ss1, ss2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss1) || ! ensure_not_null((void *) ss2) || + ! ensure_same_spanset_type(ss1, ss2)) + return NULL; + /* Bounding box test */ Span s; if (! inter_span_span(&ss1->span, &ss2->span, &s)) @@ -1663,8 +1822,11 @@ minus_value_spanset(Datum d, meosType basetype, const SpanSet *ss, bool minus_int_intspanset(int i, const SpanSet *ss, int *result) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT4)) + return false; + Datum v; bool found = minus_value_spanset(Int32GetDatum(i), T_INT4, ss, &v); *result = DatumGetInt32(v); @@ -1680,8 +1842,11 @@ minus_int_intspanset(int i, const SpanSet *ss, int *result) bool minus_bigint_bigintspanset(int64 i, const SpanSet *ss, int64 *result) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) result) || + ! ensure_same_spanset_basetype(ss, T_INT8)) + return false; + Datum v; bool found = minus_value_spanset(Int64GetDatum(i), T_INT8, ss, &v); *result = DatumGetInt64(v); @@ -1697,8 +1862,11 @@ minus_bigint_bigintspanset(int64 i, const SpanSet *ss, int64 *result) bool minus_float_floatspanset(double d, const SpanSet *ss, double *result) { - assert(ss); - ensure_same_spanset_basetype(ss, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) result) || + ! ensure_same_spanset_basetype(ss, T_FLOAT8)) + return false; + Datum v; bool found = minus_value_spanset(Float8GetDatum(d), T_FLOAT8, ss, &v); *result = DatumGetFloat8(v); @@ -1715,8 +1883,11 @@ bool minus_timestamp_periodset(TimestampTz t, const SpanSet *ss, TimestampTz *result) { - assert(ss); - ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) result) || + ! ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ)) + return false; + Datum v; bool res = minus_value_spanset(TimestampTzGetDatum(t), T_TIMESTAMPTZ, ss, &v); @@ -1775,8 +1946,11 @@ minus_span_spanset_iter(const Span *s, const SpanSet *ss, int from, int to, SpanSet * minus_span_spanset(const Span *s, const SpanSet *ss) { - assert(ss); - ensure_same_spanset_spantype(ss, s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) s) || + ! ensure_same_spanset_spantype(ss, s)) + return NULL; + /* Bounding box test */ if (! overlaps_span_span(s, &ss->span)) return spanset_make((Span *) s, 1, false); @@ -1828,8 +2002,10 @@ minus_spanset_value(const SpanSet *ss, Datum d, meosType basetype) SpanSet * minus_intspanset_int(const SpanSet *ss, int i) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT4)) + return NULL; return minus_spanset_value(ss, Int32GetDatum(i), T_INT4); } @@ -1841,8 +2017,10 @@ minus_intspanset_int(const SpanSet *ss, int i) SpanSet * minus_bigintspanset_bigint(const SpanSet *ss, int64 i) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT8)) + return NULL; return minus_spanset_value(ss, Int64GetDatum(i), T_INT8); } @@ -1854,8 +2032,10 @@ minus_bigintspanset_bigint(const SpanSet *ss, int64 i) SpanSet * minus_floatspanset_float(const SpanSet *ss, double d) { - assert(ss); - ensure_same_spanset_basetype(ss, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_FLOAT8)) + return NULL; return minus_spanset_value(ss, Float8GetDatum(d), T_FLOAT8); } @@ -1867,8 +2047,10 @@ minus_floatspanset_float(const SpanSet *ss, double d) SpanSet * minus_periodset_timestamp(const SpanSet *ss, TimestampTz t) { - assert(ss); - ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ)) + return NULL; return minus_spanset_value(ss, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -1881,8 +2063,11 @@ minus_periodset_timestamp(const SpanSet *ss, TimestampTz t) SpanSet * minus_spanset_span(const SpanSet *ss, const Span *s) { - assert(ss); - ensure_same_spanset_spantype(ss, s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) s) || + ! ensure_same_spanset_spantype(ss, s)) + return NULL; + /* Bounding box test */ if (! overlaps_span_span(&ss->span, s)) return spanset_copy(ss); @@ -1911,8 +2096,11 @@ minus_spanset_span(const SpanSet *ss, const Span *s) SpanSet * minus_spanset_spanset(const SpanSet *ss1, const SpanSet *ss2) { - assert(ss1); assert(ss2); - ensure_same_spanset_type(ss1, ss2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss1) || ! ensure_not_null((void *) ss2) || + ! ensure_same_spanset_type(ss1, ss2)) + return NULL; + /* Bounding box test */ if (! overlaps_span_span(&ss1->span, &ss2->span)) return spanset_copy(ss1); @@ -1987,8 +2175,10 @@ distance_spanset_value(const SpanSet *ss, Datum d, meosType basetype) double distance_intspanset_int(const SpanSet *ss, int i) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT4)) + return -1.0; return distance_spanset_value(ss, Int32GetDatum(i), T_INT4); } @@ -2001,8 +2191,10 @@ distance_intspanset_int(const SpanSet *ss, int i) double distance_bigintspanset_bigint(const SpanSet *ss, int64 i) { - assert(ss); - ensure_same_spanset_basetype(ss, T_INT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_INT8)) + return -1.0; return distance_spanset_value(ss, Int64GetDatum(i), T_INT8); } @@ -2014,8 +2206,10 @@ distance_bigintspanset_bigint(const SpanSet *ss, int64 i) double distance_floatspanset_float(const SpanSet *ss, double d) { - assert(ss); - ensure_same_spanset_basetype(ss, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_FLOAT8)) + return -1.0; return distance_spanset_value(ss, Float8GetDatum(d), T_FLOAT8); } @@ -2028,8 +2222,10 @@ distance_floatspanset_float(const SpanSet *ss, double d) double distance_periodset_timestamp(const SpanSet *ss, TimestampTz t) { - assert(ss); - ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_basetype(ss, T_TIMESTAMPTZ)) + return -1.0; return distance_spanset_value(ss, TimestampTzGetDatum(t), T_TIMESTAMPTZ); } #endif /* MEOS */ @@ -2042,8 +2238,10 @@ distance_periodset_timestamp(const SpanSet *ss, TimestampTz t) double distance_spanset_span(const SpanSet *ss, const Span *s) { - assert(ss); - ensure_same_spanset_spantype(ss, s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || + ! ensure_same_spanset_spantype(ss, s)) + return -1.0; return distance_span_span(&ss->span, s); } @@ -2055,8 +2253,10 @@ distance_spanset_span(const SpanSet *ss, const Span *s) double distance_spanset_spanset(const SpanSet *ss1, const SpanSet *ss2) { - assert(ss1); assert(ss2); - ensure_same_spanset_type(ss1, ss2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss1) || ! ensure_not_null((void *) ss2) || + ! ensure_same_spanset_type(ss1, ss2)) + return -1.0; return distance_span_span(&ss1->span, &ss2->span); } diff --git a/meos/src/general/tbool_boolops.c b/meos/src/general/tbool_boolops.c index 056c7e6ad6..b233d5382f 100644 --- a/meos/src/general/tbool_boolops.c +++ b/meos/src/general/tbool_boolops.c @@ -85,8 +85,11 @@ datum_not(Datum d) Temporal * tnot_tbool(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TBOOL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TBOOL)) + return NULL; + LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); lfinfo.func = (varfunc) &datum_not; @@ -104,8 +107,8 @@ tnot_tbool(const Temporal *temp) Temporal * boolop_tbool_bool(const Temporal *temp, Datum b, datum_func2 func, bool invert) { - assert(temp); - assert(temp->temptype == T_TBOOL); + assert(temp); assert(temp->temptype == T_TBOOL); + LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); lfinfo.func = (varfunc) func; @@ -148,8 +151,11 @@ boolop_tbool_tbool(const Temporal *temp1, const Temporal *temp2, SpanSet * tbool_when_true(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TBOOL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TBOOL)) + return NULL; + Temporal *temp1 = temporal_restrict_value(temp, BoolGetDatum(true), REST_AT); if (! temp1) return NULL; diff --git a/meos/src/general/tbool_boolops_meos.c b/meos/src/general/tbool_boolops_meos.c index 2869e987b7..35889f7bbc 100644 --- a/meos/src/general/tbool_boolops_meos.c +++ b/meos/src/general/tbool_boolops_meos.c @@ -34,8 +34,6 @@ #include "general/tbool_boolops.h" -/* C */ -#include /* MEOS */ #include "general/temporaltypes.h" @@ -51,8 +49,10 @@ Temporal * tand_bool_tbool(bool b, const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_BOOL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_BOOL)) + return NULL; return boolop_tbool_bool(temp, b, &datum_and, INVERT); } @@ -64,8 +64,10 @@ tand_bool_tbool(bool b, const Temporal *temp) Temporal * tand_tbool_bool(const Temporal *temp, bool b) { - assert(temp); - ensure_temporal_has_type(temp, T_BOOL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_BOOL)) + return NULL; return boolop_tbool_bool(temp, b, &datum_and, INVERT_NO); } @@ -77,7 +79,10 @@ tand_tbool_bool(const Temporal *temp, bool b) Temporal * tand_tbool_tbool(const Temporal *temp1, const Temporal *temp2) { - ensure_same_temporal_type(temp1, temp2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return NULL; return boolop_tbool_tbool(temp1, temp2, &datum_and); } @@ -93,8 +98,10 @@ tand_tbool_tbool(const Temporal *temp1, const Temporal *temp2) Temporal * tor_bool_tbool(bool b, const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_BOOL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_BOOL)) + return NULL; return boolop_tbool_bool(temp, b, &datum_or, INVERT); } @@ -106,8 +113,10 @@ tor_bool_tbool(bool b, const Temporal *temp) Temporal * tor_tbool_bool(const Temporal *temp, bool b) { - assert(temp); - ensure_temporal_has_type(temp, T_BOOL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_BOOL)) + return NULL; return boolop_tbool_bool(temp, b, &datum_or, INVERT_NO); } @@ -119,8 +128,10 @@ tor_tbool_bool(const Temporal *temp, bool b) Temporal * tor_tbool_tbool(const Temporal *temp1, const Temporal *temp2) { - assert(temp1); assert(temp2); - ensure_same_temporal_type(temp1, temp2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return NULL; return boolop_tbool_tbool(temp1, temp2, &datum_or); } diff --git a/meos/src/general/tbox.c b/meos/src/general/tbox.c index 1c45eabbbf..f2990cb8cb 100644 --- a/meos/src/general/tbox.c +++ b/meos/src/general/tbox.c @@ -36,6 +36,7 @@ /* C */ #include +#include /* MEOS */ #include #include @@ -55,34 +56,49 @@ /** * @brief Ensure that a temporal box has X values */ -void +bool ensure_has_X_tbox(const TBox *box) { assert(box); if (! MEOS_FLAGS_GET_X(box->flags)) - elog(ERROR, "The box must have value dimension"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The box must have value dimension"); + return false; + } + return true; } /** * @brief Ensure that a temporal box has T values */ -void +bool ensure_has_T_tbox(const TBox *box) { assert(box); if (! MEOS_FLAGS_GET_T(box->flags)) - elog(ERROR, "The box must have time dimension"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The box must have time dimension"); + return false; + } + return true; } /** * @brief Ensure that a temporal boxes have the same dimensionality */ -void +bool ensure_same_dimensionality_tbox(const TBox *box1, const TBox *box2) { if (MEOS_FLAGS_GET_X(box1->flags) != MEOS_FLAGS_GET_X(box2->flags) || MEOS_FLAGS_GET_T(box1->flags) != MEOS_FLAGS_GET_T(box2->flags)) - elog(ERROR, "The boxes must be of the same dimensionality"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The boxes must be of the same dimensionality"); + return false; + } + return true; } /***************************************************************************** @@ -104,7 +120,9 @@ ensure_same_dimensionality_tbox(const TBox *box1, const TBox *box2) TBox * tbox_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return tbox_parse(&str); } @@ -116,8 +134,8 @@ char * tbox_out(const TBox *box, int maxdd) { /* Ensure validity of the arguments */ - assert(box); - ensure_non_negative(maxdd); + if (! ensure_not_null((void *) box) || ! ensure_non_negative(maxdd)) + return NULL; static size_t size = MAXTBOXLEN + 1; char *result = palloc(size); @@ -202,7 +220,10 @@ tbox_set(const Span *s, const Span *p, TBox *box) TBox * tbox_copy(const TBox *box) { - assert(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box)) + return NULL; + TBox *result = palloc(sizeof(TBox)); memcpy(result, box, sizeof(TBox)); return result; @@ -272,7 +293,9 @@ number_period_to_tbox(Datum d, meosType basetype, const Span *s) TBox * int_period_to_tbox(int i, const Span *s) { - assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return NULL; return number_period_to_tbox(Int32GetDatum(i), T_INT4, s); } @@ -284,7 +307,9 @@ int_period_to_tbox(int i, const Span *s) TBox * float_period_to_tbox(double d, const Span *s) { - assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return NULL; return number_period_to_tbox(Float8GetDatum(d), T_FLOAT8, s); } #endif /* MEOS */ @@ -297,8 +322,10 @@ float_period_to_tbox(double d, const Span *s) TBox * span_timestamp_to_tbox(const Span *s, TimestampTz t) { - assert(s); - ensure_numspan_type(s->spantype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_numspan_type(s->spantype)) + return NULL; + Datum dt = TimestampTzGetDatum(t); Span p; span_set(dt, dt, true, true, T_TIMESTAMPTZ, &p); @@ -313,10 +340,11 @@ span_timestamp_to_tbox(const Span *s, TimestampTz t) TBox * span_period_to_tbox(const Span *s, const Span *p) { - assert(s); assert(p); - ensure_numspan_type(s->spantype); - ensure_span_has_type(p, T_TSTZSPAN); - assert(p->basetype == T_TIMESTAMPTZ); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) p) || + ! ensure_numspan_type(s->spantype) || + ! ensure_span_has_type(p, T_TSTZSPAN)) + return NULL; return tbox_make(s, p); } @@ -447,7 +475,10 @@ numset_set_tbox(const Set *s, TBox *box) TBox * numset_to_tbox(const Set *s) { - assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return NULL; + TBox *result = palloc(sizeof(TBox)); numset_set_tbox(s, result); return result; @@ -478,7 +509,10 @@ timestampset_set_tbox(const Set *s, TBox *box) TBox * timestampset_to_tbox(const Set *s) { - assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return NULL; + TBox *result = palloc(sizeof(TBox)); timestampset_set_tbox(s, result); return result; @@ -507,7 +541,10 @@ numspan_set_tbox(const Span *s, TBox *box) TBox * numspan_to_tbox(const Span *s) { - assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return NULL; + TBox *result = palloc(sizeof(TBox)); numspan_set_tbox(s, result); return result; @@ -519,10 +556,10 @@ numspan_to_tbox(const Span *s) * @brief Set a temporal box from a period. */ void -period_set_tbox(const Span *p, TBox *box) +period_set_tbox(const Span *s, TBox *box) { - assert(p); assert(box); - tbox_set(NULL, p, box); + assert(s); assert(box); + tbox_set(NULL, s, box); return; } @@ -534,11 +571,14 @@ period_set_tbox(const Span *p, TBox *box) * @sqlop @p :: */ TBox * -period_to_tbox(const Span *p) +period_to_tbox(const Span *s) { - assert(p); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return NULL; + TBox *result = palloc(sizeof(TBox)); - period_set_tbox(p, result); + period_set_tbox(s, result); return result; } @@ -564,7 +604,10 @@ numspanset_set_tbox(const SpanSet *ss, TBox *box) TBox * numspanset_to_tbox(const SpanSet *ss) { - assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss)) + return NULL; + TBox *result = palloc(sizeof(TBox)); numspanset_set_tbox(ss, result); return result; @@ -591,7 +634,10 @@ periodset_set_tbox(const SpanSet *ss, TBox *box) TBox * periodset_to_tbox(const SpanSet *ss) { - assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss)) + return NULL; + TBox *result = palloc(sizeof(TBox)); periodset_set_tbox(ss, result); return result; @@ -608,7 +654,10 @@ periodset_to_tbox(const SpanSet *ss) Span * tbox_to_floatspan(const TBox *box) { - assert(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box)) + return NULL; + if (! MEOS_FLAGS_GET_X(box->flags)) return NULL; if (box->span.basetype == T_FLOAT8) @@ -627,7 +676,10 @@ tbox_to_floatspan(const TBox *box) Span * tbox_to_period(const TBox *box) { - assert(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box)) + return NULL; + if (! MEOS_FLAGS_GET_T(box->flags)) return NULL; return span_copy(&box->period); @@ -645,7 +697,9 @@ tbox_to_period(const TBox *box) bool tbox_hasx(const TBox *box) { - assert(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box)) + return false; bool result = MEOS_FLAGS_GET_X(box->flags); return result; } @@ -658,7 +712,9 @@ tbox_hasx(const TBox *box) bool tbox_hast(const TBox *box) { - assert(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box)) + return false; bool result = MEOS_FLAGS_GET_T(box->flags); return result; } @@ -673,7 +729,10 @@ tbox_hast(const TBox *box) bool tbox_xmin(const TBox *box, double *result) { - assert(box); assert(result); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_X(box->flags)) return false; *result = datum_double(box->span.lower, box->span.basetype); @@ -690,7 +749,10 @@ tbox_xmin(const TBox *box, double *result) bool tbox_xmin_inc(const TBox *box, bool *result) { - assert(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_X(box->flags)) return false; *result = DatumGetBool(box->span.lower_inc); @@ -707,7 +769,10 @@ tbox_xmin_inc(const TBox *box, bool *result) bool tbox_xmax(const TBox *box, double *result) { - assert(box); assert(result); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_X(box->flags)) return false; if (box->span.basetype == T_INT4) @@ -728,7 +793,10 @@ tbox_xmax(const TBox *box, double *result) bool tbox_xmax_inc(const TBox *box, bool *result) { - assert(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_X(box->flags)) return false; *result = DatumGetBool(box->span.upper_inc); @@ -745,7 +813,10 @@ tbox_xmax_inc(const TBox *box, bool *result) bool tbox_tmin(const TBox *box, TimestampTz *result) { - assert(box); assert(result); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_T(box->flags)) return false; *result = DatumGetTimestampTz(box->period.lower); @@ -762,7 +833,10 @@ tbox_tmin(const TBox *box, TimestampTz *result) bool tbox_tmin_inc(const TBox *box, bool *result) { - assert(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_T(box->flags)) return false; *result = DatumGetBool(box->period.lower_inc); @@ -779,7 +853,10 @@ tbox_tmin_inc(const TBox *box, bool *result) bool tbox_tmax(const TBox *box, TimestampTz *result) { - assert(box); assert(result); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_T(box->flags)) return false; *result = DatumGetTimestampTz(box->period.upper); @@ -796,7 +873,10 @@ tbox_tmax(const TBox *box, TimestampTz *result) bool tbox_tmax_inc(const TBox *box, bool *result) { - assert(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_T(box->flags)) return false; *result = DatumGetBool(box->period.upper_inc); @@ -830,8 +910,10 @@ tbox_expand(const TBox *box1, TBox *box2) TBox * tbox_expand_value(const TBox *box, const double d) { - assert(box); - ensure_has_X_tbox(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_has_X_tbox(box)) + return NULL; + TBox *result = tbox_copy(box); result->span.lower = Float8GetDatum(DatumGetFloat8(result->span.lower) - d); result->span.upper = Float8GetDatum(DatumGetFloat8(result->span.upper) + d); @@ -846,8 +928,11 @@ tbox_expand_value(const TBox *box, const double d) TBox * tbox_expand_time(const TBox *box, const Interval *interval) { - assert(box); assert(interval); - ensure_has_T_tbox(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) interval) || + ! ensure_has_T_tbox(box)) + return NULL; + TBox *result = tbox_copy(box); TimestampTz tmin = pg_timestamp_mi_interval(DatumGetTimestampTz( box->period.lower), interval); @@ -859,6 +944,7 @@ tbox_expand_time(const TBox *box, const Interval *interval) } /** + * @ingroup libmeos_box_transf * @brief Set the precision of the value dimension of the temporal box to * the number of decimal places. */ @@ -866,9 +952,9 @@ TBox * tbox_round(const TBox *box, int maxdd) { /* Ensure validity of the arguments */ - assert(box); - ensure_has_X_tbox(box); - ensure_non_negative(maxdd); + if (! ensure_not_null((void *) box) || ! ensure_has_X_tbox(box) || + ! ensure_non_negative(maxdd)) + return NULL; TBox *result = tbox_copy(box); Datum size = Int32GetDatum(maxdd); @@ -907,7 +993,8 @@ static void topo_tbox_tbox_init(const TBox *box1, const TBox *box2, bool *hasx, bool *hast) { assert(box1); assert(box2); assert(hasx); assert(hast); - ensure_common_dimension(box1->flags, box2->flags); + if (! ensure_common_dimension(box1->flags, box2->flags)) + return; *hasx = MEOS_FLAGS_GET_X(box1->flags) && MEOS_FLAGS_GET_X(box2->flags); *hast = MEOS_FLAGS_GET_T(box1->flags) && MEOS_FLAGS_GET_T(box2->flags); return; @@ -921,7 +1008,10 @@ topo_tbox_tbox_init(const TBox *box1, const TBox *box2, bool *hasx, bool *hast) bool contains_tbox_tbox(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2)) + return false; + bool hasx, hast; topo_tbox_tbox_init(box1, box2, &hasx, &hast); if (hasx && ! contains_span_span(&box1->span, &box2->span)) @@ -950,7 +1040,10 @@ contained_tbox_tbox(const TBox *box1, const TBox *box2) bool overlaps_tbox_tbox(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) && ! ensure_not_null((void *) box2)) + return false; + bool hasx, hast; topo_tbox_tbox_init(box1, box2, &hasx, &hast); if (hasx && ! overlaps_span_span(&box1->span, &box2->span)) @@ -968,7 +1061,10 @@ overlaps_tbox_tbox(const TBox *box1, const TBox *box2) bool same_tbox_tbox(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2)) + return false; + bool hasx, hast; topo_tbox_tbox_init(box1, box2, &hasx, &hast); if (hasx && ! span_eq(&box1->span, &box2->span)) @@ -986,7 +1082,10 @@ same_tbox_tbox(const TBox *box1, const TBox *box2) bool adjacent_tbox_tbox(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2)) + return false; + bool hasx, hast; topo_tbox_tbox_init(box1, box2, &hasx, &hast); /* Boxes are adjacent if they are adjacent in at least one dimension */ @@ -1011,9 +1110,10 @@ adjacent_tbox_tbox(const TBox *box1, const TBox *box2) bool left_tbox_tbox(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); - ensure_has_X_tbox(box1); - ensure_has_X_tbox(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_X_tbox(box1) || ! ensure_has_X_tbox(box2)) + return false; return left_span_span(&box1->span, &box2->span); } @@ -1026,9 +1126,10 @@ left_tbox_tbox(const TBox *box1, const TBox *box2) bool overleft_tbox_tbox(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); - ensure_has_X_tbox(box1); - ensure_has_X_tbox(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_X_tbox(box1) || ! ensure_has_X_tbox(box2)) + return false; return overleft_span_span(&box1->span, &box2->span); } @@ -1041,9 +1142,10 @@ overleft_tbox_tbox(const TBox *box1, const TBox *box2) bool right_tbox_tbox(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); - ensure_has_X_tbox(box1); - ensure_has_X_tbox(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_X_tbox(box1) || ! ensure_has_X_tbox(box2)) + return false; return right_span_span(&box1->span, &box2->span); } @@ -1056,9 +1158,11 @@ right_tbox_tbox(const TBox *box1, const TBox *box2) bool overright_tbox_tbox(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); - ensure_has_X_tbox(box1); - ensure_has_X_tbox(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_X_tbox(box1) || ! ensure_has_X_tbox(box2)) + return false; + return overright_span_span(&box1->span, &box2->span); } @@ -1071,9 +1175,10 @@ overright_tbox_tbox(const TBox *box1, const TBox *box2) bool before_tbox_tbox(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); - ensure_has_T_tbox(box1); - ensure_has_T_tbox(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_T_tbox(box1) || ! ensure_has_T_tbox(box2)) + return false; return left_span_span(&box1->period, &box2->period); } @@ -1086,9 +1191,10 @@ before_tbox_tbox(const TBox *box1, const TBox *box2) bool overbefore_tbox_tbox(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); - ensure_has_T_tbox(box1); - ensure_has_T_tbox(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_T_tbox(box1) || ! ensure_has_T_tbox(box2)) + return false; return overleft_span_span(&box1->period, &box2->period); } @@ -1101,9 +1207,10 @@ overbefore_tbox_tbox(const TBox *box1, const TBox *box2) bool after_tbox_tbox(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); - ensure_has_T_tbox(box1); - ensure_has_T_tbox(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_T_tbox(box1) || ! ensure_has_T_tbox(box2)) + return false; return right_span_span(&box1->period, &box2->period); } @@ -1116,9 +1223,10 @@ after_tbox_tbox(const TBox *box1, const TBox *box2) bool overafter_tbox_tbox(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); - ensure_has_T_tbox(box1); - ensure_has_T_tbox(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_T_tbox(box1) || ! ensure_has_T_tbox(box2)) + return false; return overright_span_span(&box1->period, &box2->period); } @@ -1134,11 +1242,18 @@ overafter_tbox_tbox(const TBox *box1, const TBox *box2) TBox * union_tbox_tbox(const TBox *box1, const TBox *box2, bool strict) { - assert(box1); assert(box2); - ensure_same_dimensionality_tbox(box1, box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_same_dimensionality_tbox(box1, box2)) + return NULL; + /* The union of boxes that do not intersect cannot be represented by a box */ if (strict && ! overlaps_tbox_tbox(box1, box2)) - elog(ERROR, "Result of box union would not be contiguous"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Result of box union would not be contiguous"); + return NULL; + } bool hasx = MEOS_FLAGS_GET_X(box1->flags); bool hast = MEOS_FLAGS_GET_T(box1->flags); @@ -1188,7 +1303,10 @@ inter_tbox_tbox(const TBox *box1, const TBox *box2, TBox *result) TBox * intersection_tbox_tbox(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2)) + return NULL; + TBox *result = palloc(sizeof(TBox)); if (! inter_tbox_tbox(box1, box2, result)) { @@ -1211,7 +1329,10 @@ intersection_tbox_tbox(const TBox *box1, const TBox *box2) bool tbox_eq(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2)) + return false; + if (MEOS_FLAGS_GET_X(box1->flags) != MEOS_FLAGS_GET_X(box2->flags) || MEOS_FLAGS_GET_T(box1->flags) != MEOS_FLAGS_GET_T(box2->flags)) return false; @@ -1245,7 +1366,10 @@ tbox_ne(const TBox *box1, const TBox *box2) int tbox_cmp(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2)) + return INT_MAX; + bool hasx, hast; tbox_tbox_flags(box1, box2, &hasx, &hast); int cmp; @@ -1280,7 +1404,6 @@ tbox_cmp(const TBox *box1, const TBox *box2) bool tbox_lt(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); int cmp = tbox_cmp(box1, box2); return cmp < 0; } @@ -1294,7 +1417,6 @@ tbox_lt(const TBox *box1, const TBox *box2) bool tbox_le(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); int cmp = tbox_cmp(box1, box2); return cmp <= 0; } @@ -1308,7 +1430,6 @@ tbox_le(const TBox *box1, const TBox *box2) bool tbox_ge(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); int cmp = tbox_cmp(box1, box2); return cmp >= 0; } @@ -1321,7 +1442,6 @@ tbox_ge(const TBox *box1, const TBox *box2) bool tbox_gt(const TBox *box1, const TBox *box2) { - assert(box1); assert(box2); int cmp = tbox_cmp(box1, box2); return cmp > 0; } diff --git a/meos/src/general/temporal.c b/meos/src/general/temporal.c index a379a617b3..27d8f714a4 100644 --- a/meos/src/general/temporal.c +++ b/meos/src/general/temporal.c @@ -36,6 +36,8 @@ /* C */ #include +#include +#include /* POSTGRESQL */ #if POSTGRESQL_VERSION_NUMBER >= 160000 #include "varatt.h" @@ -58,10 +60,68 @@ #include "npoint/tnpoint_spatialfuncs.h" #endif +/***************************************************************************** + * Global variables + *****************************************************************************/ + +#define MEOS_SUBTYPE_STR_MAXLEN 12 + +/** + * @brief Array storing the string representation of the concrete subtypes of + * temporal types + */ +static char *_tempsubtypeName[] = +{ + "Any subtype", + "Instant", + "Sequence", + "SequenceSet" +}; + +/** + * @brief Return the string representation of the subtype of the temporal type + * corresponding to the enum value + */ +const char * +tempsubtype_name(int8 subtype) +{ + return _tempsubtypeName[subtype]; +} + /***************************************************************************** * Parameter tests *****************************************************************************/ +/** + * @brief Ensure that the pointer is not null + */ +bool +ensure_not_null(void *ptr) +{ + if (ptr == NULL) + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG, + "Null pointer not allowed"); + return false; + } + return true; +} + +/** + * @brief Ensure that at least one of the pointers is not null + */ +bool +ensure_one_not_null(void *ptr1, void *ptr2) +{ + if (ptr1 == NULL && ptr2 == NULL) + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG, + "At least one pointer must be not null"); + return false; + } + return true; +} + #if DEBUG_BUILD /** * @brief Ensure that the subtype of a temporal value is valid @@ -93,23 +153,31 @@ temptype_subtype_all(int16 subtype) /** * @brief Ensure that a temporal value has discrete interpolation */ -void +bool ensure_discrete_interpolation(int16 flags) { if (! MEOS_FLAGS_GET_DISCRETE(flags)) - elog(ERROR, "The temporal value must have discrete interpolation"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal value must have discrete interpolation"); + return false; + } + return true; } /** * @brief Ensure that a temporal value has continuous interpolation */ -void +bool ensure_continuous_interpolation(int16 flags) { if (! MEOS_FLAGS_GET_CONTINUOUS(flags)) - elog(ERROR, "The temporal value must have continuous interpolation"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal value must have continuous interpolation"); + return false; + } + return true; } #endif /* not used */ @@ -117,86 +185,129 @@ ensure_continuous_interpolation(int16 flags) * @brief Ensure that the interpolation is valid * @note Used for the constructor functions */ -void +bool ensure_valid_interpolation(meosType temptype, interpType interp) { if (interp == LINEAR && ! temptype_continuous(temptype)) - elog(ERROR, "The temporal type cannot have linear interpolation"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal type cannot have linear interpolation"); + return false; + } + return true; } /** * @brief Ensure that the subtype of temporal type is a sequence (set) */ -void +bool ensure_continuous(const Temporal *temp) { assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT || MEOS_FLAGS_GET_DISCRETE(temp->flags)) - elog(ERROR, "Input must be a temporal continuous sequence (set)"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "Input must be a temporal continuous sequence (set)"); + return false; + } + return true; } /** * @brief Ensure that two temporal values have the same interpolation * @param[in] temp1,temp2 Input values */ -void +bool ensure_same_interpolation(const Temporal *temp1, const Temporal *temp2) { interpType interp1 = MEOS_FLAGS_GET_INTERP(temp1->flags); interpType interp2 = MEOS_FLAGS_GET_INTERP(temp2->flags); if (interp1 != interp2) - elog(ERROR, "The temporal values must have the same interpolation"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal values must have the same interpolation"); + return false; + } + return true; } /** * @brief Ensure that a temporal value does not have linear interpolation */ -void +bool ensure_nonlinear_interpolation(int16 flags) { if (MEOS_FLAGS_GET_LINEAR(flags)) - elog(ERROR, "The temporal value cannot have linear interpolation"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal value cannot have linear interpolation"); + return false; + } + return true; } /** * @brief Ensure that two temporal values have at least one common dimension * based on their flags */ -void +bool ensure_common_dimension(int16 flags1, int16 flags2) { if (MEOS_FLAGS_GET_X(flags1) != MEOS_FLAGS_GET_X(flags2) && - MEOS_FLAGS_GET_T(flags1) != MEOS_FLAGS_GET_T(flags2)) - elog(ERROR, "The temporal values must have at least one common dimension"); - return; + MEOS_FLAGS_GET_T(flags1) != MEOS_FLAGS_GET_T(flags2)) + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal values must have at least one common dimension"); + return false; + } + return true; } /** * @brief Ensure that a temporal value is of a temporal type */ -void +bool ensure_temporal_has_type(const Temporal *temp, meosType temptype) { if (temp->temptype != temptype) - elog(ERROR, "The temporal value must be of type %s", meostype_name(temptype)); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "The temporal value must be of type %s", meostype_name(temptype)); + return false; + } + return true; } /** * @brief Ensure that two temporal values have the same temporal type * @param[in] temp1,temp2 Input values */ -void +bool ensure_same_temporal_type(const Temporal *temp1, const Temporal *temp2) { if (temp1->temptype != temp2->temptype) - elog(ERROR, "Operation on mixed temporal types: %s and %s", + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "Operation on mixed temporal types: %s and %s", meostype_name(temp1->temptype), meostype_name(temp2->temptype)); - return; + return false; + } + return true; +} + +/** + * @brief Ensure that a temporal value is of a temporal type + */ +bool +ensure_temporal_has_subtype(const Temporal *temp, uint8 subtype) +{ + if (temp->subtype != subtype) + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "The temporal value must be of subtype %s", tempsubtype_name(subtype)); + return false; + } + return true; } /** @@ -204,71 +315,120 @@ ensure_same_temporal_type(const Temporal *temp1, const Temporal *temp2) * @param[in] temp Input value * @param[in] basetype Input base type */ -void +bool ensure_same_temporal_basetype(const Temporal *temp, meosType basetype) { if (temptype_basetype(temp->temptype) != basetype) - elog(ERROR, "Operation on mixed temporal type and base type"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "Operation on mixed temporal type and base type: %s, %s", + meostype_name(temp->temptype), meostype_name(basetype)); + return false; + } + return true; } /*****************************************************************************/ /** - * @brief Ensure that the number is positive + * @brief Ensure that the number is positive or zero */ -void +bool ensure_non_negative(int i) { if (i < 0) - elog(ERROR, "The value cannot be negative: %d", i); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The value cannot be negative: %d", i); + return false; + } + return true; } /** - * @brief Ensure that the number is strictly positive + * @brief Ensure that the number is positive */ -void -ensure_positive_datum(Datum size, meosType basetype) +bool +ensure_positive(int i) { - assert(span_basetype(basetype)); - if (basetype == T_INT4) + if (i <= 0) { - int isize = DatumGetInt32(size); - if (isize <= 0) - elog(ERROR, "The value must be strictly positive: %d", isize); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The value must be strictly positive: %d", i); + return false; } - else if (basetype == T_FLOAT8) - { - double dsize = DatumGetFloat8(size); - if (dsize <= 0.0) - elog(ERROR, "The value must be strictly positive: %f", dsize); - } - else /* basetype == T_TIMESTAMPTZ */ + return true; +} + +/** + * @brief Return true if the number is strictly positive + */ +bool +positive_datum(Datum size, meosType basetype) +{ + assert(span_basetype(basetype)); + if (basetype == T_INT4 && DatumGetInt32(size) <= 0) + return false; + else if (basetype == T_FLOAT8 && DatumGetFloat8(size) <= 0.0) + return false; + /* basetype == T_TIMESTAMPTZ */ + else if (DatumGetInt64(size) <= 0) + return false; + return true; +} + +/** + * @brief Ensure that the number is strictly positive + */ +bool +ensure_positive_datum(Datum size, meosType basetype) +{ + if (! positive_datum(size, basetype)) { - int64 isize = DatumGetInt64(size); - if (isize <= 0) - elog(ERROR, "The value must be strictly positive: " INT64_FORMAT "", isize); + char str[256]; + if (basetype == T_INT4) + sprintf(str, "%d", DatumGetInt32(size)); + else if (basetype == T_FLOAT8) + sprintf(str, "%f", DatumGetFloat8(size)); + else /* basetype == T_TIMESTAMPTZ */ + sprintf(str, INT64_FORMAT, DatumGetInt64(size)); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The value must be strictly positive: %s", str); + return false; } - return; + return true; } /** - * @brief Ensure that the interval is a positive and absolute duration + * @brief Return true if the interval is a positive and absolute duration */ -void -ensure_valid_duration(const Interval *duration) +bool +valid_duration(const Interval *duration) { if (duration->month != 0) - { - elog(ERROR, "Interval defined in terms of month, year, century, etc. not supported"); - } + return false; Interval intervalzero; memset(&intervalzero, 0, sizeof(Interval)); - int cmp = pg_interval_cmp(duration, &intervalzero); - if (cmp <= 0) - elog(ERROR, "The interval must be positive"); - return; + if (pg_interval_cmp(duration, &intervalzero) <= 0) + return false; + return true; +} + +/** + * @brief Ensure that the interval is a positive and absolute duration + */ +bool +ensure_valid_duration(const Interval *duration) +{ + if (valid_duration(duration)) + return true; + if (duration->month != 0) + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Interval defined in terms of month, year, century, etc. not supported"); + else + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The interval must be positive"); + return false; } /***************************************************************************** @@ -447,7 +607,9 @@ temporal_in(const char *str, meosType temptype) Temporal * tbool_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return temporal_parse(&str, T_TBOOL); } @@ -459,7 +621,9 @@ tbool_in(const char *str) Temporal * tint_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return temporal_parse(&str, T_TINT); } @@ -470,7 +634,9 @@ tint_in(const char *str) Temporal * tfloat_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return temporal_parse(&str, T_TFLOAT); } @@ -481,7 +647,9 @@ tfloat_in(const char *str) Temporal * ttext_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return temporal_parse(&str, T_TTEXT); } #endif /* MEOS */ @@ -493,9 +661,8 @@ ttext_in(const char *str) char * temporal_out(const Temporal *temp, int maxdd) { - /* Ensure validity of the arguments */ assert(temp); - ensure_non_negative(maxdd); + assert(maxdd >= 0); char *result; assert(temptype_subtype(temp->subtype)); @@ -517,7 +684,9 @@ temporal_out(const Temporal *temp, int maxdd) char * tbool_out(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; return temporal_out(temp, 0); } @@ -529,7 +698,9 @@ tbool_out(const Temporal *temp) char * tint_out(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; return temporal_out(temp, 0); } @@ -540,7 +711,9 @@ tint_out(const Temporal *temp) char * tfloat_out(const Temporal *temp, int maxdd) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_non_negative(maxdd)) + return NULL; return temporal_out(temp, maxdd); } @@ -551,7 +724,9 @@ tfloat_out(const Temporal *temp, int maxdd) char * ttext_out(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; return temporal_out(temp, 0); } @@ -563,7 +738,9 @@ ttext_out(const Temporal *temp) char * tpoint_out(const Temporal *temp, int maxdd) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_non_negative(maxdd)) + return NULL; return temporal_out(temp, maxdd); } #endif /* MEOS */ @@ -579,7 +756,10 @@ tpoint_out(const Temporal *temp, int maxdd) Temporal * temporal_copy(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; + Temporal *result = palloc(VARSIZE(temp)); memcpy(result, temp, VARSIZE(temp)); return result; @@ -600,6 +780,21 @@ tdiscseq_from_base_temp(Datum value, meosType temptype, const TSequence *seq) NORMALIZE_NO); } +/** + * @brief Construct a temporal discrete sequence from a base value and a + * timestamp set. + */ +TSequence * +tsequence_from_base_temp(Datum value, meosType temptype, const TSequence *seq) +{ + assert(seq); + TSequence *result = MEOS_FLAGS_GET_DISCRETE(seq->flags) ? + tdiscseq_from_base_temp(value, temptype, seq) : + tsequence_from_base_period(value, temptype, &seq->period, + temptype_continuous(temptype) ? LINEAR : STEP); + return result; +} + /** * @brief Construct a temporal sequence set from a base value and the time * frame of another temporal sequence set. The interpolation of the result is @@ -641,12 +836,8 @@ temporal_from_base_temp(Datum value, meosType temptype, const Temporal *temp) result = (Temporal *) tinstant_make(value, temptype, ((TInstant *) temp)->t); else if (temp->subtype == TSEQUENCE) - result = MEOS_FLAGS_GET_DISCRETE(temp->flags) ? - (Temporal *) tdiscseq_from_base_temp(value, temptype, - (TSequence *) temp) : - (Temporal *) tsequence_from_base_period(value, temptype, - &((TSequence *) temp)->period, - temptype_continuous(temptype) ? LINEAR : STEP); + result = (Temporal *) tsequence_from_base_temp(value, temptype, + (TSequence *) temp); else /* temp->subtype == TSEQUENCESET */ result = (Temporal *) tsequenceset_from_base_temp(value, temptype, (TSequenceSet *) temp); @@ -662,7 +853,9 @@ temporal_from_base_temp(Datum value, meosType temptype, const Temporal *temp) Temporal * tbool_from_base_temp(bool b, const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; return temporal_from_base_temp(BoolGetDatum(b), T_TBOOL, temp); } @@ -674,7 +867,9 @@ tbool_from_base_temp(bool b, const Temporal *temp) Temporal * tint_from_base_temp(int i, const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; return temporal_from_base_temp(Int32GetDatum(i), T_TINT, temp); } @@ -686,7 +881,9 @@ tint_from_base_temp(int i, const Temporal *temp) Temporal * tfloat_from_base_temp(double d, const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; return temporal_from_base_temp(Float8GetDatum(d), T_TFLOAT, temp); } @@ -698,7 +895,9 @@ tfloat_from_base_temp(double d, const Temporal *temp) Temporal * ttext_from_base_temp(const text *txt, const Temporal *temp) { - assert(temp); assert(txt); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt)) + return NULL; return temporal_from_base_temp(PointerGetDatum(txt), T_TTEXT, temp); } @@ -708,23 +907,14 @@ ttext_from_base_temp(const text *txt, const Temporal *temp) * of another temporal value. */ Temporal * -tgeompoint_from_base_temp(const GSERIALIZED *gs, const Temporal *temp) +tpoint_from_base_temp(const GSERIALIZED *gs, const Temporal *temp) { - assert(temp); assert(gs); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + gserialized_is_empty(gs)) + return NULL; return temporal_from_base_temp(PointerGetDatum(gs), T_TGEOMPOINT, temp); } - -/** - * @ingroup libmeos_temporal_constructor - * @brief Construct a temporal geographic point from a point and the time frame - * of another temporal value. - */ -Temporal * -tgeogpoint_from_base_temp(const GSERIALIZED *gs, const Temporal *temp) -{ - assert(temp); assert(gs); - return temporal_from_base_temp(PointerGetDatum(gs), T_TGEOGPOINT, temp); -} #endif /* MEOS */ /***************************************************************************** @@ -746,14 +936,15 @@ temporal_append_tinstant(Temporal *temp, const TInstant *inst, double maxdist, Interval *maxt, bool expand) { /* Validity tests */ - assert(temp); assert(inst); - ensure_same_temporal_type(temp, (Temporal *) inst); - if (inst->subtype != TINSTANT) - elog(ERROR, "The second argument must be of instant subtype"); + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) inst) || + ! ensure_same_temporal_type(temp, (Temporal *) inst) || + ! ensure_temporal_has_subtype((Temporal *) inst, TINSTANT) || + ! ensure_spatial_validity(temp, (const Temporal *) inst)) + return NULL; + /* The test to ensure the increasing timestamps must be done in the * subtype function since the inclusive/exclusive bounds must be * taken into account for temporal sequences and sequence sets */ - ensure_spatial_validity(temp, (const Temporal *) inst); Temporal *result; assert(temptype_subtype(temp->subtype)); @@ -780,15 +971,16 @@ Temporal * temporal_append_tsequence(Temporal *temp, const TSequence *seq, bool expand) { /* Validity tests */ - assert(temp); assert(seq); - ensure_same_temporal_type(temp, (Temporal *) seq); - if (seq->subtype != TSEQUENCE) - elog(ERROR, "The second argument must be of sequence subtype"); - ensure_same_interpolation(temp, (Temporal *) seq); + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) seq) || + ! ensure_same_temporal_type(temp, (Temporal *) seq) || + ! ensure_temporal_has_subtype((Temporal *) seq, TSEQUENCE) || + ! ensure_same_interpolation(temp, (Temporal *) seq) || + ! ensure_spatial_validity(temp, (Temporal *) seq)) + return NULL; + /* The test to ensure the increasing timestamps must be done in the * subtype function since the inclusive/exclusive bounds must be * taken into account for temporal sequences and sequence sets */ - ensure_spatial_validity(temp, (Temporal *) seq); interpType interp2 = MEOS_FLAGS_GET_INTERP(seq->flags); Temporal *result; @@ -891,7 +1083,7 @@ Temporal * temporal_merge(const Temporal *temp1, const Temporal *temp2) { Temporal *result; - /* Can't do anything with null inputs */ + /* Cannot do anything with null inputs */ if (! temp1 && ! temp2) return NULL; /* One argument is null, return a copy of the other temporal */ @@ -900,8 +1092,11 @@ temporal_merge(const Temporal *temp1, const Temporal *temp2) if (! temp2) return temporal_copy(temp1); + /* Ensure validity of the arguments */ + if (! ensure_same_temporal_type(temp1, temp2)) + return NULL; + /* Convert to the same subtype */ - ensure_same_temporal_type(temp1, temp2); Temporal *new1, *new2; temporal_convert_same_subtype(temp1, temp2, &new1, &new2); @@ -965,13 +1160,12 @@ temporalarr_convert_subtype(Temporal **temparr, int count, uint8 subtype, Temporal * temporal_merge_array(Temporal **temparr, int count) { - assert(temparr); - assert(count > 0); + /* Ensure validity of the arguments */ + if( ! ensure_not_null((void *) temparr) || ! ensure_positive(count)) + return NULL; + if (count == 1) - { - Temporal *result = temporal_copy(temparr[0]); - return result; - } + return temporal_copy(temparr[0]); /* Ensure all values have the same interpolation and, if they are spatial, * have the same SRID and dimensionality, and determine subtype of the @@ -996,8 +1190,8 @@ temporal_merge_array(Temporal **temparr, int count) subtype = newsubtype; interp |= newinterp; } - if (spatial) - ensure_spatial_validity(temparr[0], temparr[i]); + if (spatial && ! ensure_spatial_validity(temparr[0], temparr[i])) + return NULL; } /* Convert all temporal values to a single subtype if needed */ Temporal **newtemps; @@ -1052,8 +1246,11 @@ datum_float_to_int(Datum d) Temporal * tint_to_tfloat(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TINT)) + return NULL; + LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); lfinfo.func = (varfunc) datum_int_to_float; @@ -1072,10 +1269,16 @@ tint_to_tfloat(const Temporal *temp) Temporal * tfloat_to_tint(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return NULL; if (MEOS_FLAGS_GET_LINEAR(temp->flags)) - elog(ERROR, "Cannot cast temporal float with linear interpolation to temporal integer"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Cannot cast temporal float with linear interpolation to temporal integer"); + return NULL; + } LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); @@ -1115,7 +1318,10 @@ temporal_set_period(const Temporal *temp, Span *s) Span * temporal_to_period(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; + Span *result = palloc(sizeof(Span)); temporal_set_period(temp, result); return result; @@ -1154,8 +1360,11 @@ tnumber_set_span(const Temporal *temp, Span *s) Span * tnumber_to_span(const Temporal *temp) { - assert(temp); - ensure_tnumber_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_tnumber_type(temp->temptype)) + return NULL; + Span *result = palloc(sizeof(Span)); tnumber_set_span(temp, result); return result; @@ -1170,8 +1379,11 @@ tnumber_to_span(const Temporal *temp) TBox * tnumber_to_tbox(const Temporal *temp) { - assert(temp); - ensure_tnumber_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_tnumber_type(temp->temptype)) + return NULL; + TBox *result = palloc(sizeof(TBox)); temporal_set_bbox(temp, result); return result; @@ -1194,11 +1406,9 @@ temporal_restart(Temporal *temp, int count) assert(temp); assert(count > 0); assert(temptype_subtype(temp->subtype)); - if (temp->subtype == TINSTANT) - { - elog(ERROR, "Input must be a temporal sequence (set)"); - } - else if (temp->subtype == TSEQUENCE) + assert(temp->subtype != TINSTANT); + + if (temp->subtype == TSEQUENCE) tsequence_restart((TSequence *) temp, count); else /* temp->subtype == TSEQUENCESET */ tsequenceset_restart((TSequenceSet *) temp, count); @@ -1214,7 +1424,10 @@ temporal_restart(Temporal *temp, int count) Temporal * temporal_to_tinstant(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; + Temporal *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -1234,7 +1447,10 @@ temporal_to_tinstant(const Temporal *temp) Temporal * temporal_to_tsequence(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; + Temporal *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -1255,7 +1471,10 @@ temporal_to_tsequence(const Temporal *temp) Temporal * temporal_to_tsequenceset(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; + Temporal *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -1276,8 +1495,11 @@ temporal_to_tsequenceset(const Temporal *temp) Temporal * temporal_set_interp(const Temporal *temp, interpType interp) { - assert(temp); - ensure_valid_interpolation(temp->temptype, interp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_valid_interpolation(temp->temptype, interp)) + return NULL; + Temporal *result; if (temp->subtype == TINSTANT) result = (Temporal *) tinstant_to_tsequence((TInstant *) temp, interp); @@ -1302,10 +1524,11 @@ Temporal * temporal_shift_tscale(const Temporal *temp, const Interval *shift, const Interval *duration) { - assert(temp); - assert(shift || duration); - if (duration) - ensure_valid_duration(duration); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_one_not_null((void *) shift, (void *) duration) || + (duration && ! ensure_valid_duration(duration))) + return NULL; Temporal *result; assert(temptype_subtype(temp->subtype)); @@ -1330,7 +1553,6 @@ temporal_shift_tscale(const Temporal *temp, const Interval *shift, Temporal * temporal_shift(const Temporal *temp, const Interval *shift) { - assert(temp); assert(shift); return temporal_shift_tscale(temp, shift, NULL); } @@ -1341,7 +1563,6 @@ temporal_shift(const Temporal *temp, const Interval *shift) Temporal * temporal_tscale(const Temporal *temp, const Interval *duration) { - assert(temp); assert(duration); return temporal_shift_tscale(temp, NULL, duration); } #endif /* MEOS */ @@ -1361,7 +1582,7 @@ tinstant_tprecision(const TInstant *inst, const Interval *duration, TimestampTz torigin) { assert(inst); assert(duration); - ensure_valid_duration(duration); + assert(valid_duration(duration)); TimestampTz lower = timestamptz_bucket(inst->t, duration, torigin); Datum value = tinstant_value(inst); TInstant *result = tinstant_make(value, inst->temptype, lower); @@ -1378,6 +1599,7 @@ temporal_tprecision_agg_values(const Temporal *temp) { assert(temp); assert(tnumber_type(temp->temptype) || tgeo_type(temp->temptype)); + Datum result; if (tnumber_type(temp->temptype)) result = Float8GetDatum(tnumber_twavg(temp)); @@ -1399,7 +1621,7 @@ tsequence_tprecision(const TSequence *seq, const Interval *duration, assert(seq); assert(duration); assert(seq->temptype == T_TINT || seq->temptype == T_TFLOAT || seq->temptype == T_TGEOMPOINT || seq->temptype == T_TGEOGPOINT ); - ensure_valid_duration(duration); + assert(valid_duration(duration)); int64 tunits = interval_units(duration); TimestampTz lower = DatumGetTimestampTz(seq->period.lower); TimestampTz upper = DatumGetTimestampTz(seq->period.upper); @@ -1493,7 +1715,7 @@ tsequenceset_tprecision(const TSequenceSet *ss, const Interval *duration, TimestampTz torigin) { assert(ss); assert(duration); - ensure_valid_duration(duration); + assert(valid_duration(duration)); int64 tunits = interval_units(duration); TimestampTz lower = DatumGetTimestampTz(ss->period.lower); TimestampTz upper = DatumGetTimestampTz(ss->period.upper); @@ -1539,7 +1761,10 @@ Temporal * temporal_tprecision(const Temporal *temp, const Interval *duration, TimestampTz torigin) { - assert(temp); assert(duration); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) duration)) + return NULL; + Temporal *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -1567,7 +1792,7 @@ tinstant_tsample(const TInstant *inst, const Interval *duration, TimestampTz torigin) { assert(inst); assert(duration); - ensure_valid_duration(duration); + assert(valid_duration(duration)); TimestampTz lower = timestamptz_bucket(inst->t, duration, torigin); if (timestamp_cmp_internal(lower, inst->t) == 0) return tinstant_copy(inst); @@ -1671,7 +1896,7 @@ tsequence_tsample(const TSequence *seq, const Interval *duration, TimestampTz torigin) { assert(seq); assert(duration); - ensure_valid_duration(duration); + assert(valid_duration(duration)); int64 tunits = interval_units(duration); TimestampTz lower = DatumGetTimestampTz(seq->period.lower); TimestampTz upper = DatumGetTimestampTz(seq->period.upper); @@ -1698,7 +1923,7 @@ tsequenceset_tsample(const TSequenceSet *ss, const Interval *duration, TimestampTz torigin) { assert(ss); assert(duration); - ensure_valid_duration(duration); + assert(valid_duration(duration)); int64 tunits = interval_units(duration); TimestampTz lower = tsequenceset_start_timestamp(ss); TimestampTz upper = tsequenceset_end_timestamp(ss); @@ -1729,7 +1954,10 @@ Temporal * temporal_tsample(const Temporal *temp, const Interval *duration, TimestampTz torigin) { - assert(temp); assert(duration); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) duration)) + return NULL; + Temporal *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -1748,7 +1976,6 @@ temporal_tsample(const Temporal *temp, const Interval *duration, * Accessor functions *****************************************************************************/ -#define MEOS_SUBTYPE_STR_MAXLEN 12 #define MEOS_INTERP_STR_MAXLEN 9 #if MEOS @@ -1773,15 +2000,13 @@ temporal_mem_size(const Temporal *temp) char * temporal_subtype(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; + char *result = palloc(sizeof(char) * MEOS_SUBTYPE_STR_MAXLEN); assert(temptype_subtype(temp->subtype)); - if (temp->subtype == TINSTANT) - strcpy(result, "Instant"); - else if (temp->subtype == TSEQUENCE) - strcpy(result, "Sequence"); - else /* temp->subtype == TSEQUENCESET */ - strcpy(result, "SequenceSet"); + strcpy(result, _tempsubtypeName[temp->subtype]); return result; } @@ -1794,7 +2019,10 @@ temporal_subtype(const Temporal *temp) char * temporal_interp(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; + char *result = palloc(sizeof(char) * MEOS_INTERP_STR_MAXLEN); assert(temptype_subtype(temp->subtype)); interpType interp = MEOS_FLAGS_GET_INTERP(temp->flags); @@ -1832,7 +2060,7 @@ temporal_set_bbox(const Temporal *temp, void *box) } /** - * @ingroup libmeos_temporal_accessor + * @ingroup libmeos_internal_temporal_accessor * @brief Return the array of distinct base values of a temporal value. * @sqlfunc values */ @@ -1840,6 +2068,7 @@ Datum * temporal_values(const Temporal *temp, int *count) { assert(temp); assert(count); + Datum *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -1860,8 +2089,11 @@ temporal_values(const Temporal *temp, int *count) bool * tbool_values(const Temporal *temp, int *count) { - assert(temp); assert(count); - ensure_temporal_has_type(temp, T_TBOOL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) count) || + ! ensure_temporal_has_type(temp, T_TBOOL)) + return NULL; + Datum *datumarr = temporal_values(temp, count); bool *result = palloc(sizeof(bool) * *count); for (int i = 0; i < *count; i++) @@ -1878,8 +2110,11 @@ tbool_values(const Temporal *temp, int *count) int * tint_values(const Temporal *temp, int *count) { - assert(temp); assert(count); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) count) || + ! ensure_temporal_has_type(temp, T_TINT)) + return NULL; + Datum *datumarr = temporal_values(temp, count); int *result = palloc(sizeof(int) * *count); for (int i = 0; i < *count; i++) @@ -1896,8 +2131,11 @@ tint_values(const Temporal *temp, int *count) double * tfloat_values(const Temporal *temp, int *count) { - assert(temp); assert(count); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) count) || + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return NULL; + Datum *datumarr = temporal_values(temp, count); double *result = palloc(sizeof(double) * *count); for (int i = 0; i < *count; i++) @@ -1914,8 +2152,11 @@ tfloat_values(const Temporal *temp, int *count) text ** ttext_values(const Temporal *temp, int *count) { - assert(temp); assert(count); - ensure_temporal_has_type(temp, T_TTEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) count) || + ! ensure_temporal_has_type(temp, T_TTEXT)) + return NULL; + Datum *datumarr = temporal_values(temp, count); text **result = palloc(sizeof(text *) * *count); for (int i = 0; i < *count; i++) @@ -1932,8 +2173,11 @@ ttext_values(const Temporal *temp, int *count) GSERIALIZED ** tpoint_values(const Temporal *temp, int *count) { - assert(temp); assert(count); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) count) || + ! ensure_tgeo_type(temp->temptype)) + return NULL; + Datum *datumarr = temporal_values(temp, count); GSERIALIZED **result = palloc(sizeof(GSERIALIZED *) * *count); for (int i = 0; i < *count; i++) @@ -1951,8 +2195,11 @@ tpoint_values(const Temporal *temp, int *count) SpanSet * tnumber_valuespans(const Temporal *temp) { - assert(temp); - ensure_tnumber_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_tnumber_type(temp->temptype)) + return NULL; + SpanSet *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -1972,7 +2219,10 @@ tnumber_valuespans(const Temporal *temp) SpanSet * temporal_time(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; + SpanSet *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -2016,8 +2266,10 @@ temporal_start_value(const Temporal *temp) bool tbool_start_value(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TBOOL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TBOOL)) + return false; return DatumGetBool(temporal_start_value(temp)); } @@ -2029,8 +2281,10 @@ tbool_start_value(const Temporal *temp) int tint_start_value(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + !ensure_temporal_has_type(temp, T_TINT)) + return INT_MAX; return DatumGetInt32(temporal_start_value(temp)); } @@ -2042,8 +2296,10 @@ tint_start_value(const Temporal *temp) double tfloat_start_value(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return DBL_MAX; return DatumGetFloat8(temporal_start_value(temp)); } @@ -2055,8 +2311,10 @@ tfloat_start_value(const Temporal *temp) text * ttext_start_value(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TTEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TTEXT)) + return NULL; return DatumGetTextP(temporal_start_value(temp)); } @@ -2068,8 +2326,10 @@ ttext_start_value(const Temporal *temp) GSERIALIZED * tpoint_start_value(const Temporal *temp) { - assert(temp); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_tgeo_type(temp->temptype)) + return NULL; return DatumGetGserializedP(temporal_start_value(temp)); } #endif /* MEOS */ @@ -2107,8 +2367,10 @@ temporal_end_value(const Temporal *temp) bool tbool_end_value(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TBOOL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TBOOL)) + return false; return DatumGetBool(temporal_end_value(temp)); } @@ -2120,8 +2382,10 @@ tbool_end_value(const Temporal *temp) int tint_end_value(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TINT)) + return INT_MAX; return DatumGetInt32(temporal_end_value(temp)); } @@ -2133,8 +2397,10 @@ tint_end_value(const Temporal *temp) double tfloat_end_value(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return DBL_MAX; return DatumGetFloat8(temporal_end_value(temp)); } @@ -2146,8 +2412,10 @@ tfloat_end_value(const Temporal *temp) text * ttext_end_value(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TTEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TTEXT)) + return NULL; return DatumGetTextP(temporal_end_value(temp)); } @@ -2159,8 +2427,10 @@ ttext_end_value(const Temporal *temp) GSERIALIZED * tpoint_end_value(const Temporal *temp) { - assert(temp); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_tgeo_type(temp->temptype)) + return NULL; return DatumGetGserializedP(temporal_end_value(temp)); } #endif /* MEOS */ @@ -2194,8 +2464,10 @@ temporal_min_value(const Temporal *temp) int tint_min_value(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TINT)) + return INT_MAX; return DatumGetInt32(temporal_min_value(temp)); } @@ -2207,8 +2479,10 @@ tint_min_value(const Temporal *temp) double tfloat_min_value(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return DBL_MAX; return DatumGetFloat8(temporal_min_value(temp)); } @@ -2220,8 +2494,10 @@ tfloat_min_value(const Temporal *temp) text * ttext_min_value(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TTEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TTEXT)) + return NULL; return DatumGetTextP(temporal_min_value(temp)); } #endif /* MEOS */ @@ -2256,8 +2532,10 @@ temporal_max_value(const Temporal *temp) int tint_max_value(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TINT)) + return INT_MAX; return DatumGetInt32(temporal_max_value(temp)); } @@ -2269,8 +2547,10 @@ tint_max_value(const Temporal *temp) double tfloat_max_value(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return DBL_MAX; return DatumGetFloat8(temporal_max_value(temp)); } @@ -2282,8 +2562,10 @@ tfloat_max_value(const Temporal *temp) text * ttext_max_value(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TTEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TTEXT)) + return NULL; return DatumGetTextP(temporal_max_value(temp)); } #endif /* MEOS */ @@ -2302,7 +2584,10 @@ ttext_max_value(const Temporal *temp) const TInstant * temporal_min_instant(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; + const TInstant *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -2323,7 +2608,10 @@ temporal_min_instant(const Temporal *temp) const TInstant * temporal_max_instant(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; + const TInstant *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -2343,7 +2631,10 @@ temporal_max_instant(const Temporal *temp) Interval * temporal_duration(const Temporal *temp, bool boundspan) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; + Interval *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT || @@ -2364,8 +2655,10 @@ temporal_duration(const Temporal *temp, bool boundspan) int temporal_num_sequences(const Temporal *temp) { - assert(temp); - ensure_continuous(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_continuous(temp)) + return -1; + int result = 1; if (temp->subtype == TSEQUENCESET) result = ((TSequenceSet *) temp)->count; @@ -2380,8 +2673,10 @@ temporal_num_sequences(const Temporal *temp) TSequence * temporal_start_sequence(const Temporal *temp) { - assert(temp); - ensure_continuous(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_continuous(temp)) + return NULL; + TSequence *result; if (temp->subtype == TSEQUENCE) result = tsequence_copy((TSequence *) temp); @@ -2401,8 +2696,10 @@ temporal_start_sequence(const Temporal *temp) TSequence * temporal_end_sequence(const Temporal *temp) { - assert(temp); - ensure_continuous(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_continuous(temp)) + return NULL; + TSequence *result; if (temp->subtype == TSEQUENCE) result = tsequence_copy((TSequence *) temp); @@ -2423,8 +2720,10 @@ temporal_end_sequence(const Temporal *temp) TSequence * temporal_sequence_n(const Temporal *temp, int i) { - assert(temp); - ensure_continuous(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_continuous(temp)) + return NULL; + TSequence *result = NULL; if (temp->subtype == TSEQUENCE) { @@ -2448,9 +2747,12 @@ temporal_sequence_n(const Temporal *temp, int i) TSequence ** temporal_sequences(const Temporal *temp, int *count) { - assert(temp); assert(count); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) count) || + ! ensure_continuous(temp)) + return NULL; + TSequence **result; - ensure_continuous(temp); if (temp->subtype == TSEQUENCE) { result = tsequence_sequences((TSequence *) temp, count); @@ -2472,9 +2774,15 @@ temporal_sequences(const Temporal *temp, int *count) TSequence ** temporal_segments(const Temporal *temp, int *count) { - assert(temp); assert(count); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) count)) + return NULL; if (temp->subtype == TINSTANT) - elog(ERROR, "The temporal value must be of subtype sequence (set)"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "The temporal value must be of subtype sequence (set)"); + return NULL; + } TSequence **result; if (temp->subtype == TSEQUENCE) @@ -2492,7 +2800,10 @@ temporal_segments(const Temporal *temp, int *count) int temporal_num_instants(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return -1; + int result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -2512,7 +2823,10 @@ temporal_num_instants(const Temporal *temp) const TInstant * temporal_start_instant(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; + const TInstant *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -2536,7 +2850,10 @@ temporal_start_instant(const Temporal *temp) const TInstant * temporal_end_instant(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; + const TInstant *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -2562,7 +2879,10 @@ temporal_end_instant(const Temporal *temp) const TInstant * temporal_instant_n(const Temporal *temp, int n) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; + const TInstant *result = NULL; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -2592,7 +2912,10 @@ temporal_instant_n(const Temporal *temp, int n) const TInstant ** temporal_instants(const Temporal *temp, int *count) { - assert(temp); assert(count); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) count)) + return NULL; + const TInstant **result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -2618,7 +2941,10 @@ temporal_instants(const Temporal *temp, int *count) int temporal_num_timestamps(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return -1; + int result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -2638,7 +2964,10 @@ temporal_num_timestamps(const Temporal *temp) TimestampTz temporal_start_timestamp(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return DT_NOEND; + TimestampTz result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -2658,7 +2987,10 @@ temporal_start_timestamp(const Temporal *temp) TimestampTz temporal_end_timestamp(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return DT_NOEND; + TimestampTz result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -2680,7 +3012,10 @@ temporal_end_timestamp(const Temporal *temp) bool temporal_timestamp_n(const Temporal *temp, int n, TimestampTz *result) { - assert(temp); assert(result); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) result)) + return false; + assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) { @@ -2711,7 +3046,10 @@ temporal_timestamp_n(const Temporal *temp, int n, TimestampTz *result) TimestampTz * temporal_timestamps(const Temporal *temp, int *count) { - assert(temp); assert(count); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) count)) + return NULL; + TimestampTz *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -2742,6 +3080,7 @@ bool temporal_bbox_ev_al_eq(const Temporal *temp, Datum value, bool ever) { assert(temp); + /* Bounding box test */ if (tnumber_type(temp->temptype)) { @@ -2788,6 +3127,7 @@ bool temporal_bbox_ev_al_lt_le(const Temporal *temp, Datum value, bool ever) { assert(temp); + if (tnumber_type(temp->temptype)) { TBox box; @@ -2826,10 +3166,13 @@ temporal_ever_eq(const Temporal *temp, Datum value) * @brief Return true if a temporal boolean is ever equal to a boolean. * @sqlop @p ?= */ -bool tbool_ever_eq(const Temporal *temp, bool b) +bool +tbool_ever_eq(const Temporal *temp, bool b) { - assert(temp); - ensure_temporal_has_type(temp, T_TBOOL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TBOOL)) + return false; return temporal_ever_eq(temp, BoolGetDatum(b)); } @@ -2838,10 +3181,13 @@ bool tbool_ever_eq(const Temporal *temp, bool b) * @brief Return true if a temporal integer is ever equal to an integer. * @sqlop @p ?= */ -bool tint_ever_eq(const Temporal *temp, int i) +bool +tint_ever_eq(const Temporal *temp, int i) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TINT)) + return false; return temporal_ever_eq(temp, Int32GetDatum(i)); } @@ -2850,9 +3196,13 @@ bool tint_ever_eq(const Temporal *temp, int i) * @brief Return true if a temporal float is ever equal to a float. * @sqlop @p ?= */ -bool tfloat_ever_eq(const Temporal *temp, double d) +bool +tfloat_ever_eq(const Temporal *temp, double d) { - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return false; return temporal_ever_eq(temp, Float8GetDatum(d)); } @@ -2861,10 +3211,13 @@ bool tfloat_ever_eq(const Temporal *temp, double d) * @brief Return true if a temporal text is ever equal to a text. * @sqlop @p ?= */ -bool ttext_ever_eq(const Temporal *temp, text *txt) +bool +ttext_ever_eq(const Temporal *temp, text *txt) { - assert(temp); - ensure_temporal_has_type(temp, T_TTEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_temporal_has_type(temp, T_TTEXT)) + return false; return temporal_ever_eq(temp, PointerGetDatum(txt)); } #endif /* MEOS */ @@ -2896,8 +3249,10 @@ temporal_always_eq(const Temporal *temp, Datum value) */ bool tbool_always_eq(const Temporal *temp, bool b) { - assert(temp); - ensure_temporal_has_type(temp, T_TBOOL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TBOOL)) + return false; return temporal_always_eq(temp, BoolGetDatum(b)); } @@ -2908,8 +3263,10 @@ bool tbool_always_eq(const Temporal *temp, bool b) */ bool tint_always_eq(const Temporal *temp, int i) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TINT)) + return false; return temporal_always_eq(temp, Int32GetDatum(i)); } @@ -2920,8 +3277,10 @@ bool tint_always_eq(const Temporal *temp, int i) */ bool tfloat_always_eq(const Temporal *temp, double d) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) && + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return false; return temporal_always_eq(temp, Float8GetDatum(d)); } @@ -2932,8 +3291,10 @@ bool tfloat_always_eq(const Temporal *temp, double d) */ bool ttext_always_eq(const Temporal *temp, text *txt) { - assert(temp); - ensure_temporal_has_type(temp, T_TTEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_temporal_has_type(temp, T_TTEXT)) + return false; return temporal_always_eq(temp, PointerGetDatum(txt)); } #endif /* MEOS */ @@ -2965,8 +3326,10 @@ temporal_ever_lt(const Temporal *temp, Datum value) */ bool tint_ever_lt(const Temporal *temp, int i) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TINT)) + return false; return temporal_ever_lt(temp, Int32GetDatum(i)); } @@ -2977,8 +3340,10 @@ bool tint_ever_lt(const Temporal *temp, int i) */ bool tfloat_ever_lt(const Temporal *temp, double d) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return false; return temporal_ever_lt(temp, Float8GetDatum(d)); } @@ -2989,8 +3354,10 @@ bool tfloat_ever_lt(const Temporal *temp, double d) */ bool ttext_ever_lt(const Temporal *temp, text *txt) { - assert(temp); - ensure_temporal_has_type(temp, T_TTEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_temporal_has_type(temp, T_TTEXT)) + return false; return temporal_ever_lt(temp, PointerGetDatum(txt)); } #endif /* MEOS */ @@ -3020,10 +3387,13 @@ temporal_always_lt(const Temporal *temp, Datum value) * @brief Return true if a temporal integer is always less than an integer. * @sqlop @p %< */ -bool tint_always_lt(const Temporal *temp, int i) +bool +tint_always_lt(const Temporal *temp, int i) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TINT)) + return false; return temporal_always_lt(temp, Int32GetDatum(i)); } @@ -3032,10 +3402,13 @@ bool tint_always_lt(const Temporal *temp, int i) * @brief Return true if a temporal float is always less than a float. * @sqlop @p %< */ -bool tfloat_always_lt(const Temporal *temp, double d) +bool +tfloat_always_lt(const Temporal *temp, double d) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return false; return temporal_always_lt(temp, Float8GetDatum(d)); } @@ -3044,10 +3417,13 @@ bool tfloat_always_lt(const Temporal *temp, double d) * @brief Return true if a temporal text is always less than a text. * @sqlop @p %< */ -bool ttext_always_lt(const Temporal *temp, text *txt) +bool +ttext_always_lt(const Temporal *temp, text *txt) { - assert(temp); - ensure_temporal_has_type(temp, T_TTEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_temporal_has_type(temp, T_TTEXT)) + return false; return temporal_always_lt(temp, PointerGetDatum(txt)); } #endif /* MEOS */ @@ -3078,10 +3454,13 @@ temporal_ever_le(const Temporal *temp, Datum value) * @brief Return true if a temporal integer is ever less than or equal to an integer. * @sqlop @p ?<= */ -bool tint_ever_le(const Temporal *temp, int i) +bool +tint_ever_le(const Temporal *temp, int i) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TINT)) + return false; return temporal_ever_le(temp, Int32GetDatum(i)); } @@ -3090,10 +3469,13 @@ bool tint_ever_le(const Temporal *temp, int i) * @brief Return true if a temporal float is ever less than or equal to a float. * @sqlop @p ?<= */ -bool tfloat_ever_le(const Temporal *temp, double d) +bool +tfloat_ever_le(const Temporal *temp, double d) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return false; return temporal_ever_le(temp, Float8GetDatum(d)); } @@ -3102,10 +3484,13 @@ bool tfloat_ever_le(const Temporal *temp, double d) * @brief Return true if a temporal text is ever less than or equal to a text. * @sqlop @p ?<= */ -bool ttext_ever_le(const Temporal *temp, text *txt) +bool +ttext_ever_le(const Temporal *temp, text *txt) { - assert(temp); - ensure_temporal_has_type(temp, T_TTEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_temporal_has_type(temp, T_TTEXT)) + return false; return temporal_ever_le(temp, PointerGetDatum(txt)); } #endif /* MEOS */ @@ -3136,10 +3521,13 @@ temporal_always_le(const Temporal *temp, Datum value) * @brief Return true if a temporal integer is always less than or equal to an integer. * @sqlop @p %<= */ -bool tint_always_le(const Temporal *temp, int i) +bool +tint_always_le(const Temporal *temp, int i) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TINT)) + return false; return temporal_always_le(temp, Int32GetDatum(i)); } @@ -3148,10 +3536,13 @@ bool tint_always_le(const Temporal *temp, int i) * @brief Return true if a temporal float is always less than or equal to a float. * @sqlop @p %<= */ -bool tfloat_always_le(const Temporal *temp, double d) +bool +tfloat_always_le(const Temporal *temp, double d) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return false; return temporal_always_le(temp, Float8GetDatum(d)); } @@ -3160,10 +3551,13 @@ bool tfloat_always_le(const Temporal *temp, double d) * @brief Return true if a temporal text is always less than or equal to a text. * @sqlop @p %<= */ -bool ttext_always_le(const Temporal *temp, text *txt) +bool +ttext_always_le(const Temporal *temp, text *txt) { - assert(temp); - ensure_temporal_has_type(temp, T_TTEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_temporal_has_type(temp, T_TTEXT)) + return false; return temporal_always_le(temp, PointerGetDatum(txt)); } #endif /* MEOS */ @@ -3180,6 +3574,7 @@ bool temporal_bbox_restrict_value(const Temporal *temp, Datum value) { assert(temp); + /* Bounding box test */ if (tnumber_type(temp->temptype)) { @@ -3192,9 +3587,9 @@ temporal_bbox_restrict_value(const Temporal *temp, Datum value) { /* Test that the geometry is not empty */ GSERIALIZED *gs = DatumGetGserializedP(value); - ensure_point_type(gs); - ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)); - ensure_same_dimensionality_tpoint_gs(temp, gs); + assert(gserialized_get_type(gs) == POINTTYPE); + assert(tpoint_srid(temp) == gserialized_get_srid(gs)); + assert(MEOS_FLAGS_GET_Z(temp->flags) == FLAGS_GET_Z(gs->gflags)); if (gserialized_is_empty(gs)) return false; if (temp->subtype != TINSTANT) @@ -3216,8 +3611,8 @@ bool tnumber_bbox_restrict_span(const Temporal *temp, const Span *s) { assert(temp); assert(s); - /* Bounding box test */ assert(tnumber_type(temp->temptype)); + /* Bounding box test */ TBox box1, box2; temporal_set_bbox(temp, &box1); numspan_set_tbox(s, &box2); @@ -3240,6 +3635,16 @@ Temporal * temporal_restrict_value(const Temporal *temp, Datum value, bool atfunc) { assert(temp); + /* Ensure validity of the arguments */ + if (tgeo_type(temp->temptype)) + { + GSERIALIZED *gs = DatumGetGserializedP(value); + if (! ensure_point_type(gs) || + ! ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)) || + ! ensure_same_dimensionality_tpoint_gs(temp, gs)) + return NULL; + } + /* Bounding box test */ interpType interp = MEOS_FLAGS_GET_INTERP(temp->flags); if (! temporal_bbox_restrict_value(temp, value)) @@ -3306,11 +3711,10 @@ Temporal * temporal_restrict_values(const Temporal *temp, const Set *s, bool atfunc) { assert(temp); assert(s); - /* Ensure validity of arguments */ if (tgeo_type(temp->temptype)) { - ensure_same_srid(tpoint_srid(temp), geoset_srid(s)); - ensure_same_spatial_dimensionality(temp->flags, s->flags); + assert(tpoint_srid(temp) == geoset_srid(s)); + assert(same_spatial_dimensionality(temp->flags, s->flags)); } /* Bounding box test */ @@ -3571,7 +3975,6 @@ temporal_restrict_period(const Temporal *temp, const Span *s, bool atfunc) /** * @ingroup libmeos_internal_temporal_restrict * @brief Restrict a temporal value to (the complement of) a period set. - * @sqlfunc atTime, minusTime */ Temporal * temporal_restrict_periodset(const Temporal *temp, const SpanSet *ss, @@ -3584,9 +3987,7 @@ temporal_restrict_periodset(const Temporal *temp, const SpanSet *ss, result = (Temporal *) tinstant_restrict_periodset( (TInstant *) temp, ss, atfunc); else if (temp->subtype == TSEQUENCE) - result = MEOS_FLAGS_GET_DISCRETE(temp->flags) ? - (Temporal *) tdiscseq_restrict_periodset((TSequence *) temp, ss, atfunc) : - (Temporal *) tcontseq_restrict_periodset((TSequence *) temp, ss, atfunc); + result = tsequence_restrict_periodset((TSequence *) temp, ss, atfunc); else /* temp->subtype == TSEQUENCESET */ result = (Temporal *) tsequenceset_restrict_periodset( (TSequenceSet *) temp, ss, atfunc); @@ -3603,8 +4004,11 @@ temporal_restrict_periodset(const Temporal *temp, const SpanSet *ss, Temporal * tnumber_at_tbox(const Temporal *temp, const TBox *box) { - assert(temp); assert(box); - ensure_tnumber_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) box) || + ! ensure_tnumber_type(temp->temptype)) + return NULL; + /* Bounding box test */ TBox box1; temporal_set_bbox(temp, &box1); @@ -3647,8 +4051,11 @@ tnumber_at_tbox(const Temporal *temp, const TBox *box) Temporal * tnumber_minus_tbox(const Temporal *temp, const TBox *box) { - assert(temp); assert(box); - ensure_tnumber_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) box) || + ! ensure_tnumber_type(temp->temptype)) + return NULL; + /* Bounding box test */ TBox box1; temporal_set_bbox(temp, &box1); @@ -3678,9 +4085,12 @@ tnumber_minus_tbox(const Temporal *temp, const TBox *box) Temporal * temporal_insert(const Temporal *temp1, const Temporal *temp2, bool connect) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return NULL; + /* Convert to the same subtype */ - assert(temp1); assert(temp2); - ensure_same_temporal_type(temp1, temp2); Temporal *new1, *new2; temporal_convert_same_subtype(temp1, temp2, &new1, &new2); @@ -3714,8 +4124,11 @@ temporal_insert(const Temporal *temp1, const Temporal *temp2, bool connect) Temporal * temporal_update(const Temporal *temp1, const Temporal *temp2, bool connect) { - assert(temp1); assert(temp2); - ensure_same_temporal_type(temp1, temp2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return NULL; + SpanSet *ps = temporal_time(temp2); Temporal *rest = temporal_restrict_periodset(temp1, ps, REST_MINUS); if (! rest) @@ -3734,7 +4147,10 @@ temporal_update(const Temporal *temp1, const Temporal *temp2, bool connect) Temporal * temporal_delete_timestamp(const Temporal *temp, TimestampTz t, bool connect) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; + Temporal *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -3762,7 +4178,10 @@ temporal_delete_timestamp(const Temporal *temp, TimestampTz t, bool connect) Temporal * temporal_delete_timestampset(const Temporal *temp, const Set *s, bool connect) { - assert(temp); assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) s)) + return NULL; + Temporal *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -3790,7 +4209,10 @@ temporal_delete_timestampset(const Temporal *temp, const Set *s, bool connect) Temporal * temporal_delete_period(const Temporal *temp, const Span *s, bool connect) { - assert(temp); assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) && ! ensure_not_null((void *) s)) + return NULL; + Temporal *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -3819,7 +4241,10 @@ Temporal * temporal_delete_periodset(const Temporal *temp, const SpanSet *ss, bool connect) { - assert(temp); assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) ss)) + return NULL; + Temporal *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -3991,22 +4416,30 @@ TSequenceSet * temporal_stops(const Temporal *temp, double maxdist, const Interval *minduration) { - assert(temp); - if (maxdist < 0) - elog(ERROR, "The maximum distance must be positive: %f", maxdist); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_positive_datum(Float8GetDatum(maxdist), T_FLOAT8)) + return NULL; + /* We cannot call #ensure_valid_duration since the duration may be zero */ Interval intervalzero; memset(&intervalzero, 0, sizeof(Interval)); int cmp = pg_interval_cmp(minduration, &intervalzero); if (cmp < 0) - elog(ERROR, "The duration must be positive"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The duration must be positive"); + return NULL; + } int64 mintunits = interval_units(minduration); TSequenceSet *result = NULL; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT || ! MEOS_FLAGS_GET_LINEAR(temp->flags)) { - elog(ERROR, "Input must be a temporal sequence (set) with linear interpolation"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Input must be a temporal sequence (set) with linear interpolation"); + return NULL; } else if (temp->subtype == TSEQUENCE) result = tsequence_stops((TSequence *) temp, maxdist, mintunits); @@ -4026,8 +4459,10 @@ temporal_stops(const Temporal *temp, double maxdist, double tnumber_integral(const Temporal *temp) { - assert(temp); - ensure_tnumber_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tnumber_type(temp->temptype)) + return -1.0; + double result = 0.0; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT || MEOS_FLAGS_GET_DISCRETE(temp->flags)) @@ -4047,8 +4482,10 @@ tnumber_integral(const Temporal *temp) double tnumber_twavg(const Temporal *temp) { - assert(temp); - ensure_tnumber_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tnumber_type(temp->temptype)) + return DBL_MAX; + double result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -4096,14 +4533,16 @@ temporal_compact(const Temporal *temp) bool temporal_eq(const Temporal *temp1, const Temporal *temp2) { - assert(temp1); assert(temp2); - ensure_same_temporal_type(temp1, temp2); - assert(temptype_subtype(temp1->subtype)); - assert(temptype_subtype(temp2->subtype)); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return false; const TInstant *inst1; const TSequence *seq; const TSequenceSet *ss; + assert(temptype_subtype(temp1->subtype)); + assert(temptype_subtype(temp2->subtype)); /* If both are of the same temporal type use the specific equality */ if (temp1->subtype == temp2->subtype) { @@ -4195,8 +4634,10 @@ temporal_ne(const Temporal *temp1, const Temporal *temp2) int temporal_cmp(const Temporal *temp1, const Temporal *temp2) { - assert(temp1); assert(temp2); - ensure_same_temporal_type(temp1, temp2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return INT_MAX; /* Compare bounding period * We need to compare periods AND bounding boxes since the bounding boxes @@ -4320,6 +4761,10 @@ temporal_gt(const Temporal *temp1, const Temporal *temp2) uint32 temporal_hash(const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return INT_MAX; + uint32 result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) diff --git a/meos/src/general/temporal_aggfuncs.c b/meos/src/general/temporal_aggfuncs.c index a7c337a02d..58ba094a27 100644 --- a/meos/src/general/temporal_aggfuncs.c +++ b/meos/src/general/temporal_aggfuncs.c @@ -181,7 +181,10 @@ tinstant_tagg(TInstant **instants1, int count1, TInstant **instants2, if (tinstant_eq(inst1, inst2)) result[count++] = tinstant_copy(inst1); else - elog(ERROR, "Unable to merge values"); + { + meos_error(ERROR, MEOS_ERR_INTERNAL_ERROR, "Unable to merge values"); + return NULL; + } } i++; j++; @@ -311,7 +314,10 @@ tsequence_tagg_iter(const TSequence *seq1, const TSequence *seq2, if (tinstant_eq(inst1, inst2)) instants[i] = tinstant_copy(inst1); else - elog(ERROR, "Unable to merge values"); + { + meos_error(ERROR, MEOS_ERR_INTERNAL_ERROR, "Unable to merge values"); + return -1; + } } } sequences[nseqs++] = tsequence_make_free(instants, syncseq1->count, diff --git a/meos/src/general/temporal_boxops.c b/meos/src/general/temporal_boxops.c index bfcc2157ff..cac9eaf290 100644 --- a/meos/src/general/temporal_boxops.c +++ b/meos/src/general/temporal_boxops.c @@ -47,6 +47,7 @@ /* C */ #include +#include /* PostgreSQL */ #include /* MEOS */ @@ -73,24 +74,13 @@ bbox_type(meosType bboxtype) return false; } -/** - * @brief Ensure that the type corresponds to a bounding box type - */ -void -ensure_bbox_type(meosType bboxtype) -{ - if (! bbox_type(bboxtype)) - elog(ERROR, "unknown bounding box type: %d", bboxtype); - return; -} - /** * @brief Return the size of a bounding box type */ size_t bbox_get_size(meosType bboxtype) { - ensure_bbox_type(bboxtype); + assert(bbox_type(bboxtype)); if (bboxtype == T_TSTZSPAN) return sizeof(Span); if (bboxtype == T_TBOX) @@ -105,7 +95,7 @@ bbox_get_size(meosType bboxtype) int bbox_max_dims(meosType bboxtype) { - ensure_bbox_type(bboxtype); + assert(bbox_type(bboxtype)); if (bboxtype == T_TSTZSPAN) return 1; if (bboxtype == T_TBOX) @@ -135,8 +125,9 @@ temporal_bbox_eq(const void *box1, const void *box2, meosType temptype) // Look for temp != merge in that file for 2 other cases where // a problem still remains (result != 0) even with the _cmp function return stbox_cmp((STBox *) box1, (STBox *) box2) == 0; - elog(ERROR, "unknown temporal type for bounding box function: %d", temptype); - return false; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown temporal type for bounding box function: %d", temptype); + return false; } /** @@ -155,8 +146,9 @@ temporal_bbox_cmp(const void *box1, const void *box2, meosType temptype) return tbox_cmp((TBox *) box1, (TBox *) box2); if (tspatial_type(temptype)) return stbox_cmp((STBox *) box1, (STBox *) box2); - elog(ERROR, "unknown temporal type for bounding box function: %d", temptype); - return 0; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown temporal type for bounding box function: %d", temptype); + return INT_MAX; } /***************************************************************************** @@ -175,8 +167,9 @@ temporal_bbox_size(meosType temptype) return sizeof(TBox); if (tspatial_type(temptype)) return sizeof(STBox); - elog(ERROR, "unknown temporal type for bounding box function: %d", temptype); - return 0; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown temporal type for bounding box function: %d", temptype); + return SIZE_MAX; /* make compiler quiet */ } /** @@ -213,8 +206,8 @@ tinstant_set_bbox(const TInstant *inst, void *box) tnpointinst_set_stbox(inst, (STBox *) box); #endif else - elog(ERROR, "unknown temporal type for bounding box function: %d", - inst->temptype); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown temporal type for bounding box function: %d", inst->temptype); return; } @@ -309,8 +302,11 @@ tinstarr_compute_bbox(const TInstant **instants, int count, bool lower_inc, tnpointinstarr_set_stbox(instants, count, interp, (STBox *) box); #endif else - elog(ERROR, "unknown temporal type for bounding box function: %d", - temptype); + { + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown temporal type for bounding box function: %d", temptype); + return; + } /* Set the lower_inc and upper_inc bounds of the period at the beginning * of the bounding box */ Span *p = (Span *) box; @@ -355,8 +351,8 @@ tsequence_expand_bbox(TSequence *seq, const TInstant *inst) tnpointseq_expand_stbox(seq, inst); #endif else - elog(ERROR, "unknown temporal type for bounding box function: %d", - seq->temptype); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown temporal type for bounding box function: %d", seq->temptype); return; } @@ -380,8 +376,8 @@ tsequenceset_expand_bbox(TSequenceSet *ss, const TSequence *seq) stbox_expand((STBox *) TSEQUENCE_BBOX_PTR(seq), (STBox *) TSEQUENCE_BBOX_PTR(ss)); else - elog(ERROR, "unknown temporal type for bounding box function: %d", - ss->temptype); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown temporal type for bounding box function: %d", ss->temptype); return; } @@ -433,7 +429,8 @@ tseqarr_compute_bbox(const TSequence **sequences, int count, void *box) else if (tspatial_type(sequences[0]->temptype)) tpointseqarr_set_stbox(sequences, count, (STBox *) box); else - elog(ERROR, "unknown temporal type for bounding box function: %d", + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown temporal type for bounding box function: %d", sequences[0]->temptype); return; } diff --git a/meos/src/general/temporal_compops.c b/meos/src/general/temporal_compops.c index 42424223a2..f70c57225e 100644 --- a/meos/src/general/temporal_compops.c +++ b/meos/src/general/temporal_compops.c @@ -75,11 +75,11 @@ Temporal * tcomp_temporal_temporal(const Temporal *temp1, const Temporal *temp2, Datum (*func)(Datum, Datum, meosType)) { - if (tgeo_type(temp1->temptype)) - { - ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)); - ensure_same_dimensionality(temp1->flags, temp2->flags); - } + if (tgeo_type(temp1->temptype) && + (! ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)) || + ! ensure_same_dimensionality(temp1->flags, temp2->flags))) + return NULL; + LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); lfinfo.func = (varfunc) func; diff --git a/meos/src/general/temporal_compops_meos.c b/meos/src/general/temporal_compops_meos.c index b44c320cdb..c9558cdc59 100644 --- a/meos/src/general/temporal_compops_meos.c +++ b/meos/src/general/temporal_compops_meos.c @@ -34,6 +34,8 @@ #include "general/temporal_compops.h" +/* C */ +#include /* MEOS */ #include "general/temporaltypes.h" #include "general/type_util.h" @@ -50,6 +52,10 @@ Temporal * teq_bool_tbool(bool b, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_BOOL)) + return NULL; return tcomp_temporal_base(temp, BoolGetDatum(b), T_BOOL, &datum2_eq, INVERT); } @@ -62,6 +68,10 @@ teq_bool_tbool(bool b, const Temporal *temp) Temporal * teq_int_tint(int i, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return tcomp_temporal_base(temp, Int32GetDatum(i), T_INT4, &datum2_eq, INVERT); } @@ -74,6 +84,10 @@ teq_int_tint(int i, const Temporal *temp) Temporal * teq_float_tfloat(double d, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return tcomp_temporal_base(temp, Float8GetDatum(d), T_FLOAT8, &datum2_eq, INVERT); } @@ -86,36 +100,14 @@ teq_float_tfloat(double d, const Temporal *temp) Temporal * teq_text_ttext(const text *txt, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_same_temporal_basetype(temp, T_TEXT)) + return NULL; return tcomp_temporal_base(temp, PointerGetDatum(txt), T_TEXT, &datum2_eq, INVERT); } -/** - * @ingroup libmeos_temporal_comp - * @brief Return the temporal equality of a point and a temporal geometric - * point. - * @sqlop @p #= - */ -Temporal * -teq_point_tgeompoint(const GSERIALIZED *gs, const Temporal *temp) -{ - return tcomp_temporal_base(temp, PointerGetDatum(gs), T_GEOMETRY, &datum2_eq, - INVERT); -} - -/** - * @ingroup libmeos_temporal_comp - * @brief Return the temporal equality of a point and a temporal geographic - * point. - * @sqlop @p #= - */ -Temporal * -teq_point_tgeogpoint(const GSERIALIZED *gs, const Temporal *temp) -{ - return tcomp_temporal_base(temp, PointerGetDatum(gs), T_GEOGRAPHY, - &datum2_eq, INVERT); -} - /** * @ingroup libmeos_temporal_comp * @brief Return the temporal equality of a temporal boolean and a boolean. @@ -124,6 +116,10 @@ teq_point_tgeogpoint(const GSERIALIZED *gs, const Temporal *temp) Temporal * teq_tbool_bool(const Temporal *temp, bool b) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_BOOL)) + return NULL; return tcomp_temporal_base(temp, BoolGetDatum(b), T_BOOL, &datum2_eq, INVERT_NO); } @@ -136,6 +132,10 @@ teq_tbool_bool(const Temporal *temp, bool b) Temporal * teq_tint_int(const Temporal *temp, int i) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return tcomp_temporal_base(temp, Int32GetDatum(i), T_INT4, &datum2_eq, INVERT_NO); } @@ -148,6 +148,10 @@ teq_tint_int(const Temporal *temp, int i) Temporal * teq_tfloat_float(const Temporal *temp, double d) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return tcomp_temporal_base(temp, Float8GetDatum(d), T_FLOAT8, &datum2_eq, INVERT_NO); } @@ -160,36 +164,14 @@ teq_tfloat_float(const Temporal *temp, double d) Temporal * teq_ttext_text(const Temporal *temp, const text *txt) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_same_temporal_basetype(temp, T_TEXT)) + return NULL; return tcomp_temporal_base(temp, PointerGetDatum(txt), T_TEXT, &datum2_eq, INVERT_NO); } -/** - * @ingroup libmeos_temporal_comp - * @brief Return the temporal equality of a temporal geometric point and a - * point. - * @sqlop @p #= - */ -Temporal * -teq_tgeompoint_point(const Temporal *temp, const GSERIALIZED *gs) -{ - return tcomp_temporal_base(temp, PointerGetDatum(gs), T_GEOMETRY, &datum2_eq, - INVERT_NO); -} - -/** - * @ingroup libmeos_temporal_comp - * @brief Return the temporal equality of a temporal geographic point and a - * point. - * @sqlop @p #= - */ -Temporal * -teq_tgeogpoint_point(const Temporal *temp, const GSERIALIZED *gs) -{ - return tcomp_temporal_base(temp, PointerGetDatum(gs), T_GEOGRAPHY, &datum2_eq, - INVERT_NO); -} - /** * @ingroup libmeos_temporal_comp * @brief Return the temporal equality of the temporal values. @@ -198,6 +180,10 @@ teq_tgeogpoint_point(const Temporal *temp, const GSERIALIZED *gs) Temporal * teq_temporal_temporal(const Temporal *temp1, const Temporal *temp2) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return NULL; return tcomp_temporal_temporal(temp1, temp2, &datum2_eq); } @@ -213,6 +199,10 @@ teq_temporal_temporal(const Temporal *temp1, const Temporal *temp2) Temporal * tne_bool_tbool(bool b, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_BOOL)) + return NULL; return tcomp_temporal_base(temp, BoolGetDatum(b), T_BOOL, &datum2_ne, INVERT); } @@ -225,6 +215,10 @@ tne_bool_tbool(bool b, const Temporal *temp) Temporal * tne_int_tint(int i, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return tcomp_temporal_base(temp, Int32GetDatum(i), T_INT4, &datum2_ne, INVERT); } @@ -237,6 +231,10 @@ tne_int_tint(int i, const Temporal *temp) Temporal * tne_float_tfloat(double d, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return tcomp_temporal_base(temp, Float8GetDatum(d), T_FLOAT8, &datum2_ne, INVERT); } @@ -249,36 +247,14 @@ tne_float_tfloat(double d, const Temporal *temp) Temporal * tne_text_ttext(const text *txt, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_same_temporal_basetype(temp, T_TEXT)) + return NULL; return tcomp_temporal_base(temp, PointerGetDatum(txt), T_TEXT, &datum2_ne, INVERT); } -/** - * @ingroup libmeos_temporal_comp - * @brief Return the temporal inequality of a point and a temporal geometric - * point. - * @sqlop @p #<> - */ -Temporal * -tne_point_tgeompoint(const GSERIALIZED *gs, const Temporal *temp) -{ - return tcomp_temporal_base(temp, PointerGetDatum(gs), T_GEOMETRY, &datum2_ne, - INVERT); -} - -/** - * @ingroup libmeos_temporal_comp - * @brief Return the temporal inequality of a point and a temporal geographic - * point. - * @sqlop @p #<> - */ -Temporal * -tne_point_tgeogpoint(const GSERIALIZED *gs, const Temporal *temp) -{ - return tcomp_temporal_base(temp, PointerGetDatum(gs), T_GEOGRAPHY, &datum2_ne, - INVERT); -} - /** * @ingroup libmeos_temporal_comp * @brief Return the temporal inequality of a temporal boolean and a boolean. @@ -287,6 +263,10 @@ tne_point_tgeogpoint(const GSERIALIZED *gs, const Temporal *temp) Temporal * tne_tbool_bool(const Temporal *temp, bool b) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_BOOL)) + return NULL; return tcomp_temporal_base(temp, BoolGetDatum(b), T_BOOL, &datum2_ne, INVERT_NO); } @@ -299,6 +279,10 @@ tne_tbool_bool(const Temporal *temp, bool b) Temporal * tne_tint_int(const Temporal *temp, int i) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return tcomp_temporal_base(temp, Int32GetDatum(i), T_INT4, &datum2_ne, INVERT_NO); } @@ -311,6 +295,10 @@ tne_tint_int(const Temporal *temp, int i) Temporal * tne_tfloat_float(const Temporal *temp, double d) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return tcomp_temporal_base(temp, Float8GetDatum(d), T_FLOAT8, &datum2_ne, INVERT_NO); } @@ -323,44 +311,27 @@ tne_tfloat_float(const Temporal *temp, double d) Temporal * tne_ttext_text(const Temporal *temp, const text *txt) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_same_temporal_basetype(temp, T_TEXT)) + return NULL; return tcomp_temporal_base(temp, PointerGetDatum(txt), T_TEXT, &datum2_ne, INVERT_NO); } /** * @ingroup libmeos_temporal_comp - * @brief Return the temporal inequality of a temporal geometric point and a - * point. - * @sqlop @p #<> - */ -Temporal * -tne_tgeompoint_point(const Temporal *temp, const GSERIALIZED *gs) -{ - return tcomp_temporal_base(temp, PointerGetDatum(gs), T_GEOMETRY, &datum2_ne, - INVERT_NO); -} - -/** - * @ingroup libmeos_temporal_comp - * @brief Return the temporal inequality of a temporal geographic point and a - * point. - * @sqlop @p #<> - */ -Temporal * -tne_tgeogpoint_point(const Temporal *temp, const GSERIALIZED *gs) -{ - return tcomp_temporal_base(temp, PointerGetDatum(gs), T_GEOGRAPHY, &datum2_ne, - INVERT_NO); -} - -/** - * @ingroup libmeos_temporal_comp +>>>>>>> Stashed changes * @brief Return the temporal inequality of the temporal values. * @sqlop @p #<> */ Temporal * tne_temporal_temporal(const Temporal *temp1, const Temporal *temp2) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return NULL; return tcomp_temporal_temporal(temp1, temp2, &datum2_ne); } @@ -376,6 +347,10 @@ tne_temporal_temporal(const Temporal *temp1, const Temporal *temp2) Temporal * tlt_int_tint(int i, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return tcomp_temporal_base(temp, Int32GetDatum(i), T_INT4, &datum2_lt, INVERT); } @@ -388,6 +363,10 @@ tlt_int_tint(int i, const Temporal *temp) Temporal * tlt_float_tfloat(double d, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return tcomp_temporal_base(temp, Float8GetDatum(d), T_FLOAT8, &datum2_lt, INVERT); } @@ -400,6 +379,10 @@ tlt_float_tfloat(double d, const Temporal *temp) Temporal * tlt_text_ttext(const text *txt, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_same_temporal_basetype(temp, T_TEXT)) + return NULL; return tcomp_temporal_base(temp, PointerGetDatum(txt), T_TEXT, &datum2_lt, INVERT); } @@ -412,6 +395,10 @@ tlt_text_ttext(const text *txt, const Temporal *temp) Temporal * tlt_tint_int(const Temporal *temp, int i) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return tcomp_temporal_base(temp, Int32GetDatum(i), T_INT4, &datum2_lt, INVERT_NO); } @@ -424,6 +411,10 @@ tlt_tint_int(const Temporal *temp, int i) Temporal * tlt_tfloat_float(const Temporal *temp, double d) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return tcomp_temporal_base(temp, Float8GetDatum(d), T_FLOAT8, &datum2_lt, INVERT_NO); } @@ -436,6 +427,10 @@ tlt_tfloat_float(const Temporal *temp, double d) Temporal * tlt_ttext_text(const Temporal *temp, const text *txt) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_same_temporal_basetype(temp, T_TEXT)) + return NULL; return tcomp_temporal_base(temp, PointerGetDatum(txt), T_TEXT, &datum2_lt, INVERT_NO); } @@ -448,6 +443,10 @@ tlt_ttext_text(const Temporal *temp, const text *txt) Temporal * tlt_temporal_temporal(const Temporal *temp1, const Temporal *temp2) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return NULL; return tcomp_temporal_temporal(temp1, temp2, &datum2_lt); } @@ -464,6 +463,10 @@ tlt_temporal_temporal(const Temporal *temp1, const Temporal *temp2) Temporal * tle_int_tint(int i, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return tcomp_temporal_base(temp, Int32GetDatum(i), T_INT4, &datum2_le, INVERT); } @@ -477,6 +480,10 @@ tle_int_tint(int i, const Temporal *temp) Temporal * tle_float_tfloat(double d, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return tcomp_temporal_base(temp, Float8GetDatum(d), T_FLOAT8, &datum2_le, INVERT); } @@ -490,6 +497,10 @@ tle_float_tfloat(double d, const Temporal *temp) Temporal * tle_text_ttext(const text *txt, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_same_temporal_basetype(temp, T_TEXT)) + return NULL; return tcomp_temporal_base(temp, PointerGetDatum(txt), T_TEXT, &datum2_le, INVERT); } @@ -503,6 +514,10 @@ tle_text_ttext(const text *txt, const Temporal *temp) Temporal * tle_tint_int(const Temporal *temp, int i) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return tcomp_temporal_base(temp, Int32GetDatum(i), T_INT4, &datum2_le, INVERT_NO); } @@ -516,6 +531,10 @@ tle_tint_int(const Temporal *temp, int i) Temporal * tle_tfloat_float(const Temporal *temp, double d) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return tcomp_temporal_base(temp, Float8GetDatum(d), T_FLOAT8, &datum2_le, INVERT_NO); } @@ -529,6 +548,10 @@ tle_tfloat_float(const Temporal *temp, double d) Temporal * tle_ttext_text(const Temporal *temp, const text *txt) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_same_temporal_basetype(temp, T_TEXT)) + return NULL; return tcomp_temporal_base(temp, PointerGetDatum(txt), T_TEXT, &datum2_le, INVERT_NO); } @@ -541,6 +564,10 @@ tle_ttext_text(const Temporal *temp, const text *txt) Temporal * tle_temporal_temporal(const Temporal *temp1, const Temporal *temp2) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return NULL; return tcomp_temporal_temporal(temp1, temp2, &datum2_le); } @@ -556,6 +583,10 @@ tle_temporal_temporal(const Temporal *temp1, const Temporal *temp2) Temporal * tgt_int_tint(int i, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return tcomp_temporal_base(temp, Int32GetDatum(i), T_INT4, &datum2_gt, INVERT); } @@ -568,6 +599,10 @@ tgt_int_tint(int i, const Temporal *temp) Temporal * tgt_float_tfloat(double d, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return tcomp_temporal_base(temp, Float8GetDatum(d), T_FLOAT8, &datum2_gt, INVERT); } @@ -580,6 +615,10 @@ tgt_float_tfloat(double d, const Temporal *temp) Temporal * tgt_text_ttext(const text *txt, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_same_temporal_basetype(temp, T_TEXT)) + return NULL; return tcomp_temporal_base(temp, PointerGetDatum(txt), T_TEXT, &datum2_gt, INVERT); } @@ -592,6 +631,10 @@ tgt_text_ttext(const text *txt, const Temporal *temp) Temporal * tgt_tint_int(const Temporal *temp, int i) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return tcomp_temporal_base(temp, Int32GetDatum(i), T_INT4, &datum2_gt, INVERT_NO); } @@ -604,6 +647,10 @@ tgt_tint_int(const Temporal *temp, int i) Temporal * tgt_tfloat_float(const Temporal *temp, double d) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return tcomp_temporal_base(temp, Float8GetDatum(d), T_FLOAT8, &datum2_gt, INVERT_NO); } @@ -616,6 +663,10 @@ tgt_tfloat_float(const Temporal *temp, double d) Temporal * tgt_ttext_text(const Temporal *temp, const text *txt) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_same_temporal_basetype(temp, T_TEXT)) + return NULL; return tcomp_temporal_base(temp, PointerGetDatum(txt), T_TEXT, &datum2_gt, INVERT_NO); } @@ -628,6 +679,10 @@ tgt_ttext_text(const Temporal *temp, const text *txt) Temporal * tgt_temporal_temporal(const Temporal *temp1, const Temporal *temp2) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return NULL; return tcomp_temporal_temporal(temp1, temp2, &datum2_gt); } @@ -644,6 +699,10 @@ tgt_temporal_temporal(const Temporal *temp1, const Temporal *temp2) Temporal * tge_int_tint(int i, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return tcomp_temporal_base(temp, Int32GetDatum(i), T_INT4, &datum2_ge, INVERT); } @@ -657,6 +716,10 @@ tge_int_tint(int i, const Temporal *temp) Temporal * tge_float_tfloat(double d, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return tcomp_temporal_base(temp, Float8GetDatum(d), T_FLOAT8, &datum2_ge, INVERT); } @@ -670,6 +733,10 @@ tge_float_tfloat(double d, const Temporal *temp) Temporal * tge_text_ttext(const text *txt, const Temporal *temp) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_same_temporal_basetype(temp, T_TEXT)) + return NULL; return tcomp_temporal_base(temp, PointerGetDatum(txt), T_TEXT, &datum2_ge, INVERT); } @@ -683,6 +750,10 @@ tge_text_ttext(const text *txt, const Temporal *temp) Temporal * tge_tint_int(const Temporal *temp, int i) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return tcomp_temporal_base(temp, Int32GetDatum(i), T_INT4, &datum2_ge, INVERT_NO); } @@ -696,6 +767,10 @@ tge_tint_int(const Temporal *temp, int i) Temporal * tge_tfloat_float(const Temporal *temp, double d) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return tcomp_temporal_base(temp, Float8GetDatum(d), T_FLOAT8, &datum2_ge, INVERT_NO); } @@ -709,6 +784,10 @@ tge_tfloat_float(const Temporal *temp, double d) Temporal * tge_ttext_text(const Temporal *temp, const text *txt) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_same_temporal_basetype(temp, T_TEXT)) + return NULL; return tcomp_temporal_base(temp, PointerGetDatum(txt), T_TEXT, &datum2_ge, INVERT_NO); } @@ -721,6 +800,10 @@ tge_ttext_text(const Temporal *temp, const text *txt) Temporal * tge_temporal_temporal(const Temporal *temp1, const Temporal *temp2) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return NULL; return tcomp_temporal_temporal(temp1, temp2, &datum2_ge); } diff --git a/meos/src/general/temporal_meos.c b/meos/src/general/temporal_meos.c index 8392970089..22efbad744 100644 --- a/meos/src/general/temporal_meos.c +++ b/meos/src/general/temporal_meos.c @@ -34,11 +34,10 @@ #include "general/temporal.h" -/* C */ -#include /* MEOS */ #include #include +#include "point/tpoint_spatialfuncs.h" /***************************************************************************** * Restriction Functions @@ -52,8 +51,10 @@ Temporal * tbool_at_value(const Temporal *temp, bool b) { - assert(temp); - ensure_same_temporal_basetype(temp, T_BOOL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_BOOL)) + return NULL; Temporal *result = temporal_restrict_value(temp, BoolGetDatum(b), REST_AT); return result; } @@ -66,8 +67,10 @@ tbool_at_value(const Temporal *temp, bool b) Temporal * tint_at_value(const Temporal *temp, int i) { - assert(temp); - ensure_same_temporal_basetype(temp, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; Temporal *result = temporal_restrict_value(temp, Int32GetDatum(i), REST_AT); return result; } @@ -80,8 +83,10 @@ tint_at_value(const Temporal *temp, int i) Temporal * tfloat_at_value(const Temporal *temp, double d) { - assert(temp); - ensure_same_temporal_basetype(temp, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; Temporal *result = temporal_restrict_value(temp, Float8GetDatum(d), REST_AT); return result; } @@ -94,8 +99,10 @@ tfloat_at_value(const Temporal *temp, double d) Temporal * ttext_at_value(const Temporal *temp, text *txt) { - assert(temp); - ensure_same_temporal_basetype(temp, T_TEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_same_temporal_basetype(temp, T_TEXT)) + return NULL; Temporal *result = temporal_restrict_value(temp, PointerGetDatum(txt), REST_AT); return result; } @@ -108,8 +115,10 @@ ttext_at_value(const Temporal *temp, text *txt) Temporal * tpoint_at_value(const Temporal *temp, GSERIALIZED *gs) { - assert(temp); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_tgeo_type(temp->temptype) || ! ensure_point_type(gs)) + return NULL; Temporal *result = temporal_restrict_value(temp, PointerGetDatum(gs), REST_AT); return result; } @@ -122,8 +131,10 @@ tpoint_at_value(const Temporal *temp, GSERIALIZED *gs) Temporal * tbool_minus_value(const Temporal *temp, bool b) { - assert(temp); - ensure_same_temporal_basetype(temp, T_BOOL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_BOOL)) + return NULL; Temporal *result = temporal_restrict_value(temp, BoolGetDatum(b), REST_MINUS); return result; } @@ -136,8 +147,10 @@ tbool_minus_value(const Temporal *temp, bool b) Temporal * tint_minus_value(const Temporal *temp, int i) { - assert(temp); - ensure_same_temporal_basetype(temp, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; Temporal *result = temporal_restrict_value(temp, Int32GetDatum(i), REST_MINUS); return result; } @@ -150,8 +163,10 @@ tint_minus_value(const Temporal *temp, int i) Temporal * tfloat_minus_value(const Temporal *temp, double d) { - assert(temp); - ensure_same_temporal_basetype(temp, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; Temporal *result = temporal_restrict_value(temp, Float8GetDatum(d), REST_MINUS); return result; } @@ -164,8 +179,10 @@ tfloat_minus_value(const Temporal *temp, double d) Temporal * ttext_minus_value(const Temporal *temp, text *txt) { - assert(temp); - ensure_same_temporal_basetype(temp, T_TEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_same_temporal_basetype(temp, T_TEXT)) + return NULL; Temporal *result = temporal_restrict_value(temp, PointerGetDatum(txt), REST_MINUS); return result; } @@ -178,8 +195,10 @@ ttext_minus_value(const Temporal *temp, text *txt) Temporal * tpoint_minus_value(const Temporal *temp, GSERIALIZED *gs) { - assert(temp); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_tgeo_type(temp->temptype)) + return NULL; Temporal *result = temporal_restrict_value(temp, PointerGetDatum(gs), REST_MINUS); return result; } @@ -194,8 +213,10 @@ tpoint_minus_value(const Temporal *temp, GSERIALIZED *gs) Temporal * temporal_at_values(const Temporal *temp, const Set *s) { - assert(temp); - ensure_same_temporal_basetype(temp, s->basetype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) s) || + ! ensure_same_temporal_basetype(temp, s->basetype)) + return NULL; return temporal_restrict_values(temp, s, REST_AT); } @@ -207,8 +228,10 @@ temporal_at_values(const Temporal *temp, const Set *s) Temporal * temporal_minus_values(const Temporal *temp, const Set *s) { - assert(temp); - ensure_same_temporal_basetype(temp, s->basetype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) s) || + ! ensure_same_temporal_basetype(temp, s->basetype)) + return NULL; return temporal_restrict_values(temp, s, REST_MINUS); } @@ -223,8 +246,11 @@ bool tbool_value_at_timestamp(const Temporal *temp, TimestampTz t, bool strict, bool *value) { - assert(temp); assert(value); - ensure_temporal_has_type(temp, T_TBOOL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) value) || + ! ensure_temporal_has_type(temp, T_TBOOL)) + return false; + Datum res; bool result = temporal_value_at_timestamp(temp, t, strict, &res); *value = DatumGetBool(res); @@ -240,8 +266,11 @@ bool tint_value_at_timestamp(const Temporal *temp, TimestampTz t, bool strict, int *value) { - assert(temp); assert(value); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) value) || + ! ensure_temporal_has_type(temp, T_TINT)) + return false; + Datum res; bool result = temporal_value_at_timestamp(temp, t, strict, &res); *value = DatumGetInt32(res); @@ -257,8 +286,11 @@ bool tfloat_value_at_timestamp(const Temporal *temp, TimestampTz t, bool strict, double *value) { - assert(temp); assert(value); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) value) || + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return false; + Datum res; bool result = temporal_value_at_timestamp(temp, t, strict, &res); *value = DatumGetFloat8(res); @@ -274,8 +306,11 @@ bool ttext_value_at_timestamp(const Temporal *temp, TimestampTz t, bool strict, text **value) { - assert(temp); assert(value); - ensure_temporal_has_type(temp, T_TTEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) value) || + ! ensure_temporal_has_type(temp, T_TTEXT)) + return NULL; + Datum res; bool result = temporal_value_at_timestamp(temp, t, strict, &res); *value = DatumGetTextP(res); @@ -291,8 +326,11 @@ bool tpoint_value_at_timestamp(const Temporal *temp, TimestampTz t, bool strict, GSERIALIZED **value) { - assert(temp); assert(value); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) value) || + ! ensure_tgeo_type(temp->temptype)) + return false; + Datum res; bool result = temporal_value_at_timestamp(temp, t, strict, &res); *value = DatumGetGserializedP(res); @@ -309,7 +347,9 @@ tpoint_value_at_timestamp(const Temporal *temp, TimestampTz t, bool strict, Temporal * temporal_at_min(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; Temporal *result = temporal_restrict_minmax(temp, GET_MIN, REST_AT); return result; } @@ -322,7 +362,9 @@ temporal_at_min(const Temporal *temp) Temporal * temporal_minus_min(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; Temporal *result = temporal_restrict_minmax(temp, GET_MIN, REST_MINUS); return result; } @@ -335,7 +377,9 @@ temporal_minus_min(const Temporal *temp) Temporal * temporal_at_max(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; Temporal *result = temporal_restrict_minmax(temp, GET_MAX, REST_AT); return result; } @@ -348,7 +392,9 @@ temporal_at_max(const Temporal *temp) Temporal * temporal_minus_max(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; Temporal *result = temporal_restrict_minmax(temp, GET_MAX, REST_MINUS); return result; } @@ -363,7 +409,10 @@ temporal_minus_max(const Temporal *temp) Temporal * tnumber_at_span(const Temporal *temp, const Span *s) { - assert(temp); assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) s) || + ! ensure_tnumber_type(temp->temptype)) + return NULL; Temporal *result = tnumber_restrict_span(temp, s, REST_AT); return result; } @@ -376,7 +425,10 @@ tnumber_at_span(const Temporal *temp, const Span *s) Temporal * tnumber_minus_span(const Temporal *temp, const Span *s) { - assert(temp); assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) s) || + ! ensure_tnumber_type(temp->temptype)) + return NULL; Temporal *result = tnumber_restrict_span(temp, s, REST_MINUS); return result; } @@ -389,7 +441,10 @@ tnumber_minus_span(const Temporal *temp, const Span *s) Temporal * tnumber_at_spanset(const Temporal *temp, const SpanSet *ss) { - assert(temp); assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) ss) || + ! ensure_tnumber_type(temp->temptype)) + return NULL; Temporal *result = tnumber_restrict_spanset(temp, ss, REST_AT); return result; } @@ -403,7 +458,10 @@ tnumber_at_spanset(const Temporal *temp, const SpanSet *ss) Temporal * tnumber_minus_spanset(const Temporal *temp, const SpanSet *ss) { - assert(temp); assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) ss) || + ! ensure_tnumber_type(temp->temptype)) + return NULL; Temporal *result = tnumber_restrict_spanset(temp, ss, REST_MINUS); return result; } @@ -418,7 +476,9 @@ tnumber_minus_spanset(const Temporal *temp, const SpanSet *ss) Temporal * temporal_at_timestamp(const Temporal *temp, TimestampTz t) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; Temporal *result = temporal_restrict_timestamp(temp, t, REST_AT); return result; } @@ -431,7 +491,9 @@ temporal_at_timestamp(const Temporal *temp, TimestampTz t) Temporal * temporal_minus_timestamp(const Temporal *temp, TimestampTz t) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; Temporal *result = temporal_restrict_timestamp(temp, t, REST_MINUS); return result; } @@ -444,7 +506,9 @@ temporal_minus_timestamp(const Temporal *temp, TimestampTz t) Temporal * temporal_at_timestampset(const Temporal *temp, const Set *s) { - assert(temp); assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) s)) + return NULL; Temporal *result = temporal_restrict_timestampset(temp, s, REST_AT); return result; } @@ -457,7 +521,9 @@ temporal_at_timestampset(const Temporal *temp, const Set *s) Temporal * temporal_minus_timestampset(const Temporal *temp, const Set *s) { - assert(temp); assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) s)) + return NULL; Temporal *result = temporal_restrict_timestampset(temp, s, REST_MINUS); return result; } @@ -470,7 +536,9 @@ temporal_minus_timestampset(const Temporal *temp, const Set *s) Temporal * temporal_at_period(const Temporal *temp, const Span *s) { - assert(temp); assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) s)) + return NULL; Temporal *result = temporal_restrict_period(temp, s, REST_AT); return result; } @@ -483,7 +551,9 @@ temporal_at_period(const Temporal *temp, const Span *s) Temporal * temporal_minus_period(const Temporal *temp, const Span *s) { - assert(temp); assert(s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) s)) + return NULL; Temporal *result = temporal_restrict_period(temp, s, REST_MINUS); return result; } @@ -496,7 +566,9 @@ temporal_minus_period(const Temporal *temp, const Span *s) Temporal * temporal_at_periodset(const Temporal *temp, const SpanSet *ss) { - assert(temp); assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) ss)) + return NULL; Temporal *result = temporal_restrict_periodset(temp, ss, REST_AT); return result; } @@ -509,7 +581,9 @@ temporal_at_periodset(const Temporal *temp, const SpanSet *ss) Temporal * temporal_minus_periodset(const Temporal *temp, const SpanSet *ss) { - assert(temp); assert(ss); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) ss)) + return NULL; Temporal *result = temporal_restrict_periodset(temp, ss, REST_MINUS); return result; } diff --git a/meos/src/general/temporal_similarity.c b/meos/src/general/temporal_similarity.c index 99949e910e..6cb2ade928 100644 --- a/meos/src/general/temporal_similarity.c +++ b/meos/src/general/temporal_similarity.c @@ -152,7 +152,7 @@ temporal_similarity(const Temporal *temp1, const Temporal *temp2, SimFunc simfunc) { assert(temp1); assert(temp2); - ensure_same_temporal_type(temp1, temp2); + assert(temp1->temptype == temp2->temptype); double result; int count1, count2; const TInstant **instants1 = temporal_instants(temp1, &count1); @@ -175,6 +175,9 @@ temporal_similarity(const Temporal *temp1, const Temporal *temp2, double temporal_frechet_distance(const Temporal *temp1, const Temporal *temp2) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2)) + return DBL_MAX; return temporal_similarity(temp1, temp2, FRECHET); } @@ -187,6 +190,9 @@ temporal_frechet_distance(const Temporal *temp1, const Temporal *temp2) double temporal_dyntimewarp_distance(const Temporal *temp1, const Temporal *temp2) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2)) + return DBL_MAX; return temporal_similarity(temp1, temp2, DYNTIMEWARP); } #endif @@ -225,7 +231,7 @@ matrix_print(double *dist, int count1, int count2) for (j = 0; j < count2; j++) len += sprintf(buf+len, " %2d ", j); sprintf(buf+len, "\n"); /* make Codacy quiet by removing last assignment */ - elog(WARNING, "MATRIX:\n%s", buf); + meos_error(WARNING, 0, "MATRIX:\n%s", buf); return; } @@ -240,7 +246,7 @@ path_print(Match *path, int count) int i, k = 0; for (i = count - 1; i >= 0; i--) len += sprintf(buf+len, "%d: (%2d,%2d)\n", k++, path[i].i, path[i].j); - elog(WARNING, "PATH:\n%s", buf); + meos_error(WARNING, 0, "PATH:\n%s", buf); return; } #endif @@ -393,7 +399,7 @@ temporal_similarity_path(const Temporal *temp1, const Temporal *temp2, int *count, SimFunc simfunc) { assert(temp1); assert(temp2); assert(count); - ensure_same_temporal_type(temp1, temp2); + assert(temp1->temptype == temp2->temptype); int count1, count2; const TInstant **instants1 = temporal_instants(temp1, &count1); const TInstant **instants2 = temporal_instants(temp2, &count2); @@ -418,6 +424,10 @@ temporal_similarity_path(const Temporal *temp1, const Temporal *temp2, Match * temporal_frechet_path(const Temporal *temp1, const Temporal *temp2, int *count) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_not_null((void *) count)) + return NULL; return temporal_similarity_path(temp1, temp2, count, FRECHET); } @@ -432,6 +442,10 @@ Match * temporal_dyntimewarp_path(const Temporal *temp1, const Temporal *temp2, int *count) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_not_null((void *) count)) + return NULL; return temporal_similarity_path(temp1, temp2, count, DYNTIMEWARP); } #endif @@ -497,8 +511,11 @@ tinstarr_hausdorff_distance(const TInstant **instants1, int count1, double temporal_hausdorff_distance(const Temporal *temp1, const Temporal *temp2) { - assert(temp1); assert(temp2); - ensure_same_temporal_type(temp1, temp2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return -1.0; + double result; int count1, count2; const TInstant **instants1 = temporal_instants(temp1, &count1); diff --git a/meos/src/general/temporal_tile.c b/meos/src/general/temporal_tile.c index 1d1fba120c..b5c22e7181 100644 --- a/meos/src/general/temporal_tile.c +++ b/meos/src/general/temporal_tile.c @@ -40,6 +40,7 @@ /* C */ #include #include +#include #include /* PostgreSQL */ #include @@ -151,7 +152,10 @@ span_bucket_state_next(SpanBucketState *state) int int_bucket(int value, int size, int origin) { - assert(size > 0); + /* Ensure validity of the arguments */ + if (! ensure_positive(size)) + return INT_MAX; + if (origin != 0) { /* @@ -164,7 +168,8 @@ int_bucket(int value, int size, int origin) if ((origin > 0 && value < PG_INT32_MIN + origin) || (origin < 0 && value > PG_INT32_MAX + origin)) { - elog(ERROR, "number out of span"); + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, "number out of span"); + return INT_MAX; } value -= origin; } @@ -179,7 +184,8 @@ int_bucket(int value, int size, int origin) */ if (result < PG_INT32_MIN + size) { - elog(ERROR, "number out of span"); + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, "number out of span"); + return INT_MAX; } else result -= size; @@ -198,7 +204,10 @@ int_bucket(int value, int size, int origin) double float_bucket(double value, double size, double origin) { - assert(size > 0.0); + /* Ensure validity of the arguments */ + if (! ensure_positive_datum(Float8GetDatum(size), T_FLOAT8)) + return DBL_MAX; + if (origin != 0) { /* @@ -210,7 +219,10 @@ float_bucket(double value, double size, double origin) origin = fmod(origin, size); if ((origin > 0 && value < -1 * DBL_MAX + origin) || (origin < 0 && value > DBL_MAX + origin)) - elog(ERROR, "number out of span"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, "number out of span"); + return DBL_MAX; + } value -= origin; } double result = floor(value / size) * size; @@ -240,7 +252,10 @@ TimestampTz timestamptz_bucket1(TimestampTz t, int64 size, TimestampTz origin) { if (TIMESTAMP_NOT_FINITE(t)) - elog(ERROR, "timestamp out of span"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, "timestamp out of span"); + return DT_NOEND; + } if (origin != 0) { /* @@ -252,7 +267,11 @@ timestamptz_bucket1(TimestampTz t, int64 size, TimestampTz origin) origin = origin % size; if ((origin > 0 && t < DT_NOBEGIN + origin) || (origin < 0 && t > DT_NOEND + origin)) - elog(ERROR, "timestamp out of span"); + { + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, "timestamp out of span"); + return DT_NOEND; + } + t -= origin; } TimestampTz result = (t / size) * size; @@ -266,7 +285,8 @@ timestamptz_bucket1(TimestampTz t, int64 size, TimestampTz origin) */ if (result < DT_NOBEGIN + size) { - elog(ERROR, "timestamp out of span"); + meos_error(ERROR, MEOS_ERR_VALUE_OUT_OF_RANGE, "timestamp out of span"); + return DT_NOEND; } else result -= size; @@ -285,7 +305,9 @@ timestamptz_bucket1(TimestampTz t, int64 size, TimestampTz origin) TimestampTz timestamptz_bucket(TimestampTz t, const Interval *duration, TimestampTz origin) { - ensure_valid_duration(duration); + /* Ensure validity of the arguments */ + if (! ensure_valid_duration(duration)) + return DT_NOEND; int64 size = interval_units(duration); return timestamptz_bucket1(t, size, origin); } @@ -300,7 +322,10 @@ timestamptz_bucket(TimestampTz t, const Interval *duration, TimestampTz origin) Datum datum_bucket(Datum value, Datum size, Datum origin, meosType basetype) { - ensure_positive_datum(size, basetype); + /* This function is called directly by the MobilityDB APID */ + if (! ensure_positive_datum(size, basetype)) + return 0; + assert(span_basetype(basetype)); if (basetype == T_INT4) return Int32GetDatum(int_bucket(DatumGetInt32(value), @@ -311,7 +336,9 @@ datum_bucket(Datum value, Datum size, Datum origin, meosType basetype) else if(basetype == T_TIMESTAMPTZ) return TimestampTzGetDatum(timestamptz_bucket1(DatumGetTimestampTz(value), DatumGetInt64(size), DatumGetTimestampTz(origin))); - elog(ERROR, "Unknown type for function datum_bucket: %d", basetype); + meos_error(ERROR, MEOS_ERR_INTERNAL_ERROR, + "Unknown type for function datum_bucket: %d", basetype); + return 0; } /***************************************************************************** @@ -351,7 +378,9 @@ span_bucket_list(const Span *s, Datum size, Datum origin, int count) Span * intspan_bucket_list(const Span *s, int size, int origin, int *count) { - assert(s); assert(count); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) count)) + return NULL; *count = ceil((DatumGetInt32(s->upper) - DatumGetInt32(s->lower)) / size); return span_bucket_list(s, Int32GetDatum(size), Int32GetDatum(origin), *count); @@ -368,7 +397,9 @@ intspan_bucket_list(const Span *s, int size, int origin, int *count) Span * floatspan_bucket_list(const Span *s, double size, double origin, int *count) { - assert(s); assert(count); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) count)) + return NULL; *count = ceil((DatumGetFloat8(s->upper) - DatumGetFloat8(s->lower)) / size); return span_bucket_list(s, Float8GetDatum(size), Float8GetDatum(origin), *count); @@ -386,8 +417,11 @@ Span * period_bucket_list(const Span *s, const Interval *duration, TimestampTz origin, int *count) { - assert(s); assert(count); - ensure_valid_duration(duration); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) count) || + ! ensure_valid_duration(duration)) + return NULL; + int64 size = interval_units(duration); *count = ceil((DatumGetTimestampTz(s->upper) - DatumGetTimestampTz(s->lower)) / size); @@ -518,10 +552,14 @@ TBox * tbox_tile_list(const TBox *box, double xsize, const Interval *duration, double xorigin, TimestampTz torigin, int *rows, int *columns) { - assert(box); assert(rows); assert(columns); - // TODO: generalize for intspan - ensure_positive_datum(Float8GetDatum(xsize), box->span.basetype); - ensure_valid_duration(duration); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) rows) || + ! ensure_not_null((void *) columns) || + // TODO: generalize for intspan + ! ensure_positive_datum(Float8GetDatum(xsize), box->span.basetype) || + ! ensure_valid_duration(duration)) + return NULL; + int64 tsize = interval_units(duration); TboxGridState *state = tbox_tile_state_make(box, xsize, duration, xorigin, torigin); @@ -755,7 +793,7 @@ static TSequence ** tsequence_time_split(const TSequence *seq, TimestampTz start, TimestampTz end, int64 tunits, int count, TimestampTz **buckets, int *newcount) { - assert(seq); assert(buckets); assert(newcount); + assert(seq); assert(buckets); ensure_not_null((void *) newcount); TSequence **result = palloc(sizeof(TSequence *) * count); TimestampTz *times = palloc(sizeof(TimestampTz) * count); *newcount = tsequence_time_split_iter(seq, start, end, tunits, count, result, @@ -886,6 +924,7 @@ temporal_time_split1(const Temporal *temp, TimestampTz start, TimestampTz end, int64 tunits, TimestampTz torigin, int count, TimestampTz **buckets, int *newcount) { + assert(temp); assert(buckets); assert(newcount); assert(start < end); assert(count > 0); /* Split the temporal value */ @@ -946,6 +985,7 @@ static TInstant ** tnumberinst_value_split(const TInstant *inst, Datum start_bucket, Datum size, Datum **buckets, int *newcount) { + assert(inst); assert(buckets); assert(newcount); Datum value = tinstant_value(inst); meosType basetype = temptype_basetype(inst->temptype); TInstant **result = palloc(sizeof(TInstant *)); @@ -973,6 +1013,7 @@ static TSequence ** tnumberseq_disc_value_split(const TSequence *seq, Datum start_bucket, Datum size, int count, Datum **buckets, int *newcount) { + assert(seq); assert(buckets); assert(newcount); meosType basetype = temptype_basetype(seq->temptype); TSequence **result; Datum *values, value, bucket_value; @@ -1279,6 +1320,7 @@ static TSequenceSet ** tnumberseq_value_split(const TSequence *seq, Datum start_bucket, Datum size, int count, Datum **buckets, int *newcount) { + assert(seq); assert(buckets); assert(newcount); meosType basetype = temptype_basetype(seq->temptype); interpType interp = MEOS_FLAGS_GET_INTERP(seq->flags); /* Instantaneous sequence */ @@ -1341,6 +1383,7 @@ static TSequenceSet ** tnumberseqset_value_split(const TSequenceSet *ss, Datum start_bucket, Datum size, int count, Datum **buckets, int *newcount) { + assert(ss); assert(buckets); assert(newcount); /* Singleton sequence set */ if (ss->count == 1) return tnumberseq_value_split(TSEQUENCESET_SEQ_N(ss, 0), start_bucket, @@ -1394,7 +1437,7 @@ Temporal ** tnumber_value_split1(const Temporal *temp, Datum start_bucket, Datum size, int count, Datum **buckets, int *newcount) { - assert(temp); assert(newcount); + assert(temp); assert(buckets); assert(newcount); assert(count > 0); /* Split the temporal value */ Temporal **fragments; @@ -1428,10 +1471,10 @@ temporal_value_time_split1(Temporal *temp, Datum size, Interval *duration, meosType basetype = temptype_basetype(temp->temptype); int64 tunits = 0; if (valuesplit) - ensure_positive_datum(size, basetype); + assert(positive_datum(size, basetype)); if (timesplit) { - ensure_valid_duration(duration); + assert(valid_duration(duration)); tunits = interval_units(duration); } @@ -1544,8 +1587,10 @@ temporal_value_time_split1(Temporal *temp, Datum size, Interval *duration, Temporal ** tint_value_split(Temporal *temp, int size, int origin, int *newcount) { - assert(temp); assert(newcount); - ensure_temporal_has_type(temp, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) newcount) || + ! ensure_temporal_has_type(temp, T_TINT)) + return NULL; Datum *value_buckets; return temporal_value_time_split1(temp, Int32GetDatum(size), NULL, Int32GetDatum(origin), 0, true, false, &value_buckets, NULL, newcount); @@ -1563,8 +1608,10 @@ tint_value_split(Temporal *temp, int size, int origin, int *newcount) Temporal ** tfloat_value_split(Temporal *temp, double size, double origin, int *newcount) { - assert(temp); assert(newcount); - ensure_temporal_has_type(temp, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) newcount) || + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return NULL; Datum *value_buckets; return temporal_value_time_split1(temp, Float8GetDatum(size), NULL, Float8GetDatum(origin), 0, true, false, &value_buckets, NULL, newcount); @@ -1583,7 +1630,9 @@ Temporal ** temporal_time_split(Temporal *temp, Interval *duration, TimestampTz torigin, int *newcount) { - assert(temp); assert(newcount); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) newcount)) + return NULL; TimestampTz *time_buckets; return temporal_value_time_split1(temp, Float8GetDatum(0), duration, Float8GetDatum(0), torigin, false, true, NULL, &time_buckets, newcount); @@ -1605,8 +1654,10 @@ Temporal ** tint_value_time_split(Temporal *temp, int size, int vorigin, Interval *duration, TimestampTz torigin, int *newcount) { - assert(temp); assert(newcount); - ensure_temporal_has_type(temp, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) newcount) || + ! ensure_temporal_has_type(temp, T_TINT)) + return NULL; Datum *value_buckets; TimestampTz *time_buckets; return temporal_value_time_split1(temp, Int32GetDatum(size), duration, @@ -1630,8 +1681,10 @@ Temporal ** tfloat_value_time_split(Temporal *temp, double size, double vorigin, Interval *duration, TimestampTz torigin, int *newcount) { - assert(temp); assert(newcount); - ensure_temporal_has_type(temp, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) newcount) || + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return NULL; Datum *value_buckets; TimestampTz *time_buckets; return temporal_value_time_split1(temp, Float8GetDatum(size), duration, diff --git a/meos/src/general/time_aggfuncs.c b/meos/src/general/time_aggfuncs.c index e1b0665230..eae33fb4d5 100644 --- a/meos/src/general/time_aggfuncs.c +++ b/meos/src/general/time_aggfuncs.c @@ -138,13 +138,17 @@ periodset_transform_tcount(const SpanSet *ps) return result; } -void +bool ensure_same_timetype_skiplist(SkipList *state, uint8 subtype) { Temporal *head = (Temporal *) skiplist_headval(state); if (head->subtype != subtype) - elog(ERROR, "Cannot aggregate temporal values of different duration"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Cannot aggregate temporal values of different duration"); + return false; + } + return true; } /*****************************************************************************/ @@ -163,7 +167,8 @@ timestamp_tcount_transfn(SkipList *state, TimestampTz t) } else { - ensure_same_timetype_skiplist(state, TINSTANT); + if (! ensure_same_timetype_skiplist(state, TINSTANT)) + return NULL; skiplist_splice(state, (void **) instants, 1, &datum_sum_int32, CROSSINGS_NO); } @@ -181,12 +186,11 @@ timestampset_tcount_transfn(SkipList *state, const Set *ts) { TInstant **instants = timestampset_transform_tcount(ts); if (! state) - { state = skiplist_make((void **) instants, ts->count); - } else { - ensure_same_timetype_skiplist(state, TINSTANT); + if (! ensure_same_timetype_skiplist(state, TINSTANT)) + return NULL; skiplist_splice(state, (void **) instants, ts->count, &datum_sum_int32, CROSSINGS_NO); } @@ -204,12 +208,11 @@ period_tcount_transfn(SkipList *state, const Span *p) { TSequence *seq = period_transform_tcount(p); if (! state) - { state = skiplist_make((void **) &seq, 1); - } else { - ensure_same_timetype_skiplist(state, TSEQUENCE); + if (! ensure_same_timetype_skiplist(state, TSEQUENCE)) + return NULL; skiplist_splice(state, (void **) &seq, 1, &datum_sum_int32, CROSSINGS_NO); } @@ -233,7 +236,10 @@ periodset_tcount_transfn(SkipList *state, const SpanSet *ps) start++; } else - ensure_same_timetype_skiplist(state, TSEQUENCE); + { + if (! ensure_same_timetype_skiplist(state, TSEQUENCE)) + return NULL; + } for (int i = start; i < ps->count; i++) { skiplist_splice(state, (void **) &sequences[i], 1, &datum_sum_int32, diff --git a/meos/src/general/tinstant.c b/meos/src/general/tinstant.c index c1aad5fab1..2a67195ab0 100644 --- a/meos/src/general/tinstant.c +++ b/meos/src/general/tinstant.c @@ -242,9 +242,8 @@ tgeogpointinst_in(const char *str) char * tinstant_to_string(const TInstant *inst, int maxdd, outfunc value_out) { - /* Ensure validity of the arguments */ assert(inst); - ensure_non_negative(maxdd); + assert(maxdd >= 0); char *t = pg_timestamptz_out(inst->t); meosType basetype = temptype_basetype(inst->temptype); @@ -322,7 +321,7 @@ tinstant_make(Datum value, meosType temptype, TimestampTz t) /* Initialize fixed-size values */ result->temptype = temptype; result->subtype = TINSTANT; - result->t = t; + result->t = t; SET_VARSIZE(result, size); MEOS_FLAGS_SET_BYVAL(result->flags, typbyval); MEOS_FLAGS_SET_CONTINUOUS(result->flags, temptype_continuous(temptype)); @@ -380,28 +379,26 @@ tfloatinst_make(double d, TimestampTz t) TInstant * ttextinst_make(const text *txt, TimestampTz t) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) txt)) + return NULL; return tinstant_make(PointerGetDatum(txt), T_TTEXT, t); } /** * @ingroup libmeos_temporal_constructor - * @brief Construct a temporal instant geometric point from the arguments. + * @brief Construct a temporal instant point from the arguments. * @sqlfunc tgeompoint_inst() */ TInstant * -tgeompointinst_make(const GSERIALIZED *gs, TimestampTz t) -{ - return tinstant_make(PointerGetDatum(gs), T_TGEOMPOINT, t); -} -/** - * @ingroup libmeos_temporal_constructor - * @brief Construct a temporal instant geographic point from the arguments. - * @sqlfunc tgeogpoint_inst(). - */ -TInstant * -tgeogpointinst_make(const GSERIALIZED *gs, TimestampTz t) +tpointinst_make(const GSERIALIZED *gs, TimestampTz t) { - return tinstant_make(PointerGetDatum(gs), T_TGEOGPOINT, t); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs) || gserialized_is_empty(gs)) + return NULL; + meosType temptype = FLAGS_GET_GEODETIC(gs->gflags) ? + T_TGEOGPOINT : T_TGEOMPOINT; + return tinstant_make(PointerGetDatum(gs), temptype, t); } #endif /* MEOS */ @@ -412,6 +409,7 @@ tgeogpointinst_make(const GSERIALIZED *gs, TimestampTz t) TInstant * tinstant_copy(const TInstant *inst) { + assert(inst); TInstant *result = palloc0(VARSIZE(inst)); memcpy(result, inst, VARSIZE(inst)); return result; @@ -543,8 +541,11 @@ tsequence_to_tinstant(const TSequence *seq) { assert(seq); if (seq->count != 1) - elog(ERROR, "Cannot transform input value to a temporal instant"); - + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Cannot transform input value to a temporal instant"); + return NULL; + } return tinstant_copy(TSEQUENCE_INST_N(seq, 0)); } @@ -558,7 +559,11 @@ tsequenceset_to_tinstant(const TSequenceSet *ss) { assert(ss); if (ss->totalcount != 1) - elog(ERROR, "Cannot transform input value to a temporal instant"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Cannot transform input value to a temporal instant"); + return NULL; + } return tinstant_copy(TSEQUENCE_INST_N(TSEQUENCESET_SEQ_N(ss, 0), 0)); } @@ -916,7 +921,8 @@ tinstant_merge_array(const TInstant **instants, int count) assert(count > 1); tinstarr_sort((TInstant **) instants, count); /* Ensure validity of the arguments and compute the bounding box */ - ensure_valid_tinstarr(instants, count, MERGE, DISCRETE); + if (! ensure_valid_tinstarr(instants, count, MERGE, DISCRETE)) + return NULL; const TInstant **newinstants = palloc(sizeof(TInstant *) * count); memcpy(newinstants, instants, sizeof(TInstant *) * count); int newcount = tinstarr_remove_duplicates(newinstants, count); diff --git a/meos/src/general/tnumber_distance.c b/meos/src/general/tnumber_distance.c index f9ebea71e7..714607a191 100644 --- a/meos/src/general/tnumber_distance.c +++ b/meos/src/general/tnumber_distance.c @@ -107,7 +107,10 @@ distance_tnumber_number(const Temporal *temp, Datum value, meosType valuetype, Temporal * distance_tint_int(const Temporal *temp, int i) { - ensure_same_temporal_basetype(temp, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return distance_tnumber_number(temp, Int32GetDatum(i), T_INT4, T_TINT); } @@ -119,7 +122,10 @@ distance_tint_int(const Temporal *temp, int i) Temporal * distance_tfloat_float(const Temporal *temp, double d) { - ensure_same_temporal_basetype(temp, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return distance_tnumber_number(temp, Int32GetDatum(d), T_FLOAT8, T_TFLOAT); } #endif /* MEOS */ @@ -154,9 +160,12 @@ tnumber_min_dist_at_timestamp(const TInstant *start1, const TInstant *end1, Temporal * distance_tnumber_tnumber(const Temporal *temp1, const Temporal *temp2) { - assert(temp1); assert(temp2); - assert(temp1->temptype == temp2->temptype); - assert(tnumber_type(temp1->temptype)); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2) || + ! ensure_tnumber_type(temp1->temptype)) + return NULL; + LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); lfinfo.func = (varfunc) &number_distance; @@ -205,8 +214,10 @@ nad_tnumber_number(const Temporal *temp, Datum value, meosType basetype) int nad_tint_int(const Temporal *temp, int i) { - assert(temp); - ensure_same_temporal_basetype(temp, T_INT4); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return -1; double result = nad_tnumber_number(temp, Int32GetDatum(i), T_INT4); return (int) result; } @@ -220,8 +231,10 @@ nad_tint_int(const Temporal *temp, int i) double nad_tfloat_float(const Temporal *temp, double d) { - assert(temp); - ensure_same_temporal_basetype(temp, T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return -1.0; return nad_tnumber_number(temp, Float8GetDatum(d), T_FLOAT8); } #endif /* MEOS */ @@ -234,10 +247,11 @@ nad_tfloat_float(const Temporal *temp, double d) double nad_tbox_tbox(const TBox *box1, const TBox *box2) { - /* Test the validity of the arguments */ - assert(box1); assert(box2); - ensure_has_X_tbox(box1); ensure_has_X_tbox(box2); - ensure_same_span_type(&box1->span, &box2->span); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_X_tbox(box1) || ! ensure_has_X_tbox(box2) || + ! ensure_same_span_type(&box1->span, &box2->span)) + return -1.0; /* If the boxes do not intersect in the time dimension return infinity */ bool hast = MEOS_FLAGS_GET_T(box1->flags) && MEOS_FLAGS_GET_T(box2->flags); @@ -256,10 +270,12 @@ nad_tbox_tbox(const TBox *box1, const TBox *box2) double nad_tnumber_tbox(const Temporal *temp, const TBox *box) { - /* Test the validity of the arguments */ - assert(temp); assert(box); - ensure_has_X_tbox(box); - ensure_same_temporal_basetype(temp, box->span.basetype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) box) || + ! ensure_has_X_tbox(box) || + ! ensure_same_temporal_basetype(temp, box->span.basetype)) + return -1.0; + bool hast = MEOS_FLAGS_GET_T(box->flags); Span p, inter; if (hast) @@ -317,9 +333,11 @@ nad_tnumber_tnumber(const Temporal *temp1, const Temporal *temp2) int nad_tint_tint(const Temporal *temp1, const Temporal *temp2) { - assert(temp1); assert(temp2); - ensure_same_temporal_type(temp1, temp2); - ensure_tnumber_type(temp1->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2) || + ! ensure_tnumber_type(temp1->temptype)) + return -1; Datum result = nad_tnumber_tnumber(temp1, temp2); return Int32GetDatum(result); } @@ -332,9 +350,11 @@ nad_tint_tint(const Temporal *temp1, const Temporal *temp2) double nad_tfloat_tfloat(const Temporal *temp1, const Temporal *temp2) { - assert(temp1); assert(temp2); - ensure_same_temporal_type(temp1, temp2); - ensure_tnumber_type(temp1->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2) || + ! ensure_tnumber_type(temp1->temptype)) + return -1.0; Datum result = nad_tnumber_tnumber(temp1, temp2); return Float8GetDatum(result); } diff --git a/meos/src/general/tnumber_mathfuncs.c b/meos/src/general/tnumber_mathfuncs.c index a3df54b42e..2084c81689 100644 --- a/meos/src/general/tnumber_mathfuncs.c +++ b/meos/src/general/tnumber_mathfuncs.c @@ -235,13 +235,19 @@ arithop_tnumber_number(const Temporal *temp, Datum value, meosType basetype, if (invert) { if (temporal_ever_eq(temp, Float8GetDatum(0.0))) - elog(ERROR, "Division by zero"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, "Division by zero"); + return NULL; + } } else { double d = datum_double(value, basetype); if (fabs(d) < MEOS_EPSILON) - elog(ERROR, "Division by zero"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, "Division by zero"); + return NULL; + } } } @@ -290,7 +296,10 @@ arithop_tnumber_tnumber(const Temporal *temp1, const Temporal *temp2, if (projtemp2 == NULL) return NULL; if (temporal_ever_eq(projtemp2, Float8GetDatum(0.0))) - elog(ERROR, "Division by zero"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, "Division by zero"); + return NULL; + } } LiftedFunctionInfo lfinfo; @@ -411,6 +420,21 @@ tnumberseq_linear_abs(const TSequence *seq) seq->period.upper_inc, LINEAR, NORMALIZE); } +/** + * @ingroup libmeos_internal_temporal_math + * @brief Get the absolute value of a temporal number + * @sqlfunc abs() + */ +TSequence * +tnumberseq_abs(const TSequence *seq) +{ + assert(seq); + assert(tnumber_type(seq->temptype)); + TSequence *result = MEOS_FLAGS_GET_LINEAR(seq->flags) ? + tnumberseq_linear_abs(seq) : tnumberseq_iter_abs(seq); + return result; +} + /** * @ingroup libmeos_internal_temporal_math * @brief Get the absolute value of a temporal number @@ -439,16 +463,16 @@ tnumberseqset_abs(const TSequenceSet *ss) Temporal * tnumber_abs(const Temporal *temp) { - assert(temp); - ensure_tnumber_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tnumber_type(temp->temptype)) + return NULL; + Temporal *result = NULL; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) result = (Temporal *) tnumberinst_abs((TInstant *) temp); else if (temp->subtype == TSEQUENCE) - result = MEOS_FLAGS_GET_LINEAR(temp->flags) ? - (Temporal *) tnumberseq_linear_abs((TSequence *) temp) : - (Temporal *) tnumberseq_iter_abs((TSequence *) temp); + result = (Temporal *) tnumberseq_abs((TSequence *) temp); else /* temp->subtype == TSEQUENCESET */ result = (Temporal *) tnumberseqset_abs((TSequenceSet *) temp); return result; @@ -548,8 +572,10 @@ tnumberseqset_delta_value(const TSequenceSet *ss) Temporal * tnumber_delta_value(const Temporal *temp) { - assert(temp); - ensure_tnumber_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tnumber_type(temp->temptype)) + return NULL; + Temporal *result = NULL; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -615,6 +641,7 @@ tnumberseq_angular_difference_iter(const TSequence *seq, TInstant **result) TSequence * tnumberseq_angular_difference(const TSequence *seq) { + assert(seq); /* Instantaneous sequence */ if (seq->count == 1) return NULL; @@ -634,6 +661,7 @@ tnumberseq_angular_difference(const TSequence *seq) TSequence * tnumberseqset_angular_difference(const TSequenceSet *ss) { + assert(ss); /* Singleton sequence set */ if (ss->count == 1) return tnumberseq_angular_difference(TSEQUENCESET_SEQ_N(ss, 0)); @@ -659,8 +687,10 @@ tnumberseqset_angular_difference(const TSequenceSet *ss) Temporal * tnumber_angular_difference(const Temporal *temp) { - assert(temp); - ensure_tnumber_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tnumber_type(temp->temptype)) + return NULL; + Temporal *result = NULL; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -685,9 +715,10 @@ Temporal * tfloat_round(const Temporal *temp, int maxdd) { /* Ensure validity of the arguments */ - assert(temp != NULL); - assert(temp->temptype == T_TFLOAT); - ensure_non_negative(maxdd); + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TFLOAT) || + ! ensure_non_negative(maxdd)) + return NULL; /* We only need to fill these parameters for tfunc_temporal */ LiftedFunctionInfo lfinfo; @@ -713,8 +744,11 @@ tfloat_round(const Temporal *temp, int maxdd) Temporal * tfloat_degrees(const Temporal *temp, bool normalize) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return NULL; + /* We only need to fill these parameters for tfunc_temporal */ LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); @@ -738,8 +772,11 @@ tfloat_degrees(const Temporal *temp, bool normalize) Temporal * tfloat_radians(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return NULL; + /* We only need to fill these parameters for tfunc_temporal */ LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); @@ -834,8 +871,11 @@ tfloatseqset_derivative(const TSequenceSet *ss) Temporal * tfloat_derivative(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TFLOAT)) + return NULL; + Temporal *result = NULL; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT || ! MEOS_FLAGS_GET_LINEAR(temp->flags)) diff --git a/meos/src/general/tnumber_mathfuncs_meos.c b/meos/src/general/tnumber_mathfuncs_meos.c index 17d1d09c22..c826b04dd3 100644 --- a/meos/src/general/tnumber_mathfuncs_meos.c +++ b/meos/src/general/tnumber_mathfuncs_meos.c @@ -55,8 +55,10 @@ Temporal * add_int_tint(int i, const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return arithop_tnumber_number(temp, Int32GetDatum(i), T_INT4, ADD, &datum_add, INVERT); } @@ -69,8 +71,10 @@ add_int_tint(int i, const Temporal *temp) Temporal * add_float_tfloat(double d, const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return arithop_tnumber_number(temp, Float8GetDatum(d), T_FLOAT8, ADD, &datum_add, INVERT); } @@ -83,8 +87,10 @@ add_float_tfloat(double d, const Temporal *temp) Temporal * add_tint_int(const Temporal *temp, int i) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return arithop_tnumber_number(temp, Int32GetDatum(i), T_INT4, ADD, &datum_add, INVERT_NO); } @@ -97,8 +103,10 @@ add_tint_int(const Temporal *temp, int i) Temporal * add_tfloat_float(const Temporal *temp, double d) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return arithop_tnumber_number(temp, Float8GetDatum(d), T_FLOAT8, ADD, &datum_add, INVERT_NO); } @@ -109,11 +117,13 @@ add_tfloat_float(const Temporal *temp, double d) * @sqlop @p + */ Temporal * -add_tnumber_tnumber(const Temporal *tnumber1, const Temporal *tnumber2) +add_tnumber_tnumber(const Temporal *temp1, const Temporal *temp2) { - assert(tnumber1); assert(tnumber2); - ensure_same_temporal_type(tnumber1, tnumber2); - return arithop_tnumber_tnumber(tnumber1, tnumber2, ADD, &datum_add, NULL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return NULL; + return arithop_tnumber_tnumber(temp1, temp2, ADD, &datum_add, NULL); } /***************************************************************************** @@ -128,8 +138,10 @@ add_tnumber_tnumber(const Temporal *tnumber1, const Temporal *tnumber2) Temporal * sub_int_tint(int i, const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return arithop_tnumber_number(temp, Int32GetDatum(i), T_INT4, SUB, &datum_sub, INVERT); } @@ -142,8 +154,10 @@ sub_int_tint(int i, const Temporal *temp) Temporal * sub_float_tfloat(double d, const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return arithop_tnumber_number(temp, Float8GetDatum(d), T_FLOAT8, SUB, &datum_sub, INVERT); } @@ -156,8 +170,10 @@ sub_float_tfloat(double d, const Temporal *temp) Temporal * sub_tint_int(const Temporal *temp, int i) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return arithop_tnumber_number(temp, Int32GetDatum(i), T_INT4, SUB, &datum_sub, INVERT_NO); } @@ -170,8 +186,10 @@ sub_tint_int(const Temporal *temp, int i) Temporal * sub_tfloat_float(const Temporal *temp, double d) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return arithop_tnumber_number(temp, Float8GetDatum(d), T_FLOAT8, SUB, &datum_sub, INVERT_NO); } @@ -182,11 +200,13 @@ sub_tfloat_float(const Temporal *temp, double d) * @sqlop @p - */ Temporal * -sub_tnumber_tnumber(const Temporal *tnumber1, const Temporal *tnumber2) +sub_tnumber_tnumber(const Temporal *temp1, const Temporal *temp2) { - assert(tnumber1); assert(tnumber2); - ensure_same_temporal_type(tnumber1, tnumber2); - return arithop_tnumber_tnumber(tnumber1, tnumber2, SUB, &datum_sub, NULL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return NULL; + return arithop_tnumber_tnumber(temp1, temp2, SUB, &datum_sub, NULL); } /***************************************************************************** @@ -201,8 +221,10 @@ sub_tnumber_tnumber(const Temporal *tnumber1, const Temporal *tnumber2) Temporal * mult_int_tint(int i, const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return arithop_tnumber_number(temp, Int32GetDatum(i), T_INT4, MULT, &datum_mult, INVERT); } @@ -215,8 +237,10 @@ mult_int_tint(int i, const Temporal *temp) Temporal * mult_float_tfloat(double d, const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return arithop_tnumber_number(temp, Float8GetDatum(d), T_FLOAT8, MULT, &datum_mult, INVERT); } @@ -229,8 +253,10 @@ mult_float_tfloat(double d, const Temporal *temp) Temporal * mult_tint_int(const Temporal *temp, int i) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return arithop_tnumber_number(temp, Int32GetDatum(i), T_INT4, MULT, &datum_mult, INVERT_NO); } @@ -243,8 +269,10 @@ mult_tint_int(const Temporal *temp, int i) Temporal * mult_tfloat_float(const Temporal *temp, double d) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return arithop_tnumber_number(temp, Float8GetDatum(d), T_FLOAT8, MULT, &datum_mult, INVERT_NO); } @@ -255,11 +283,13 @@ mult_tfloat_float(const Temporal *temp, double d) * @sqlop @p * */ Temporal * -mult_tnumber_tnumber(const Temporal *tnumber1, const Temporal *tnumber2) +mult_tnumber_tnumber(const Temporal *temp1, const Temporal *temp2) { - assert(tnumber1); assert(tnumber2); - ensure_same_temporal_type(tnumber1, tnumber2); - return arithop_tnumber_tnumber(tnumber1, tnumber2, MULT, &datum_mult, + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return NULL; + return arithop_tnumber_tnumber(temp1, temp2, MULT, &datum_mult, &tnumber_mult_tp_at_timestamp); } @@ -275,8 +305,10 @@ mult_tnumber_tnumber(const Temporal *tnumber1, const Temporal *tnumber2) Temporal * div_int_tint(int i, const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return arithop_tnumber_number(temp, Int32GetDatum(i), T_INT4, DIV, &datum_div, INVERT); } @@ -289,8 +321,10 @@ div_int_tint(int i, const Temporal *temp) Temporal * div_float_tfloat(double d, const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return arithop_tnumber_number(temp, Float8GetDatum(d), T_FLOAT8, DIV, &datum_div, INVERT); } @@ -303,8 +337,10 @@ div_float_tfloat(double d, const Temporal *temp) Temporal * div_tint_int(const Temporal *temp, int i) { - assert(temp); - ensure_temporal_has_type(temp, T_TINT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_INT4)) + return NULL; return arithop_tnumber_number(temp, Int32GetDatum(i), T_INT4, DIV, &datum_div, INVERT_NO); } @@ -317,8 +353,10 @@ div_tint_int(const Temporal *temp, int i) Temporal * div_tfloat_float(const Temporal *temp, double d) { - assert(temp); - ensure_temporal_has_type(temp, T_TFLOAT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_same_temporal_basetype(temp, T_FLOAT8)) + return NULL; return arithop_tnumber_number(temp, Float8GetDatum(d), T_FLOAT8, DIV, &datum_div, INVERT_NO); } @@ -329,11 +367,13 @@ div_tfloat_float(const Temporal *temp, double d) * @sqlop @p / */ Temporal * -div_tnumber_tnumber(const Temporal *tnumber1, const Temporal *tnumber2) +div_tnumber_tnumber(const Temporal *temp1, const Temporal *temp2) { - assert(tnumber1); assert(tnumber2); - ensure_same_temporal_type(tnumber1, tnumber2); - return arithop_tnumber_tnumber(tnumber1, tnumber2, DIV, &datum_div, + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return NULL; + return arithop_tnumber_tnumber(temp1, temp2, DIV, &datum_div, &tnumber_div_tp_at_timestamp); } diff --git a/meos/src/general/tsequence.c b/meos/src/general/tsequence.c index 9856c15391..f8ac73b78d 100644 --- a/meos/src/general/tsequence.c +++ b/meos/src/general/tsequence.c @@ -203,8 +203,9 @@ datum_collinear(Datum value1, Datum value2, Datum value3, meosType basetype, return npoint_collinear(DatumGetNpointP(value1), DatumGetNpointP(value2), DatumGetNpointP(value3), ratio); #endif - elog(ERROR, "unknown collinear operation for base type: %d", basetype); - return false; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown collinear operation for base type: %d", basetype); + return false; } /***************************************************************************** @@ -698,9 +699,8 @@ char * tsequence_to_string(const TSequence *seq, int maxdd, bool component, outfunc value_out) { - /* Ensure validity of the arguments */ assert(seq); - ensure_non_negative(maxdd); + assert(maxdd >= 0); char **strings = palloc(sizeof(char *) * seq->count); size_t outlen = 0; @@ -898,24 +898,29 @@ tsequence_make1_exp(const TInstant **instants, int count, int maxcount, * temporal instant. Moreover, ensures that the values are the same * if the timestamps are equal */ -void +bool ensure_increasing_timestamps(const TInstant *inst1, const TInstant *inst2, bool merge) { - if ((merge && inst1->t > inst2->t) || (!merge && inst1->t >= inst2->t)) + if ((merge && inst1->t > inst2->t) || (! merge && inst1->t >= inst2->t)) { char *t1 = pg_timestamptz_out(inst1->t); char *t2 = pg_timestamptz_out(inst2->t); - elog(ERROR, "Timestamps for temporal value must be increasing: %s, %s", t1, t2); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Timestamps for temporal value must be increasing: %s, %s", t1, t2); + return false; } if (merge && inst1->t == inst2->t && ! datum_eq(tinstant_value(inst1), tinstant_value(inst2), temptype_basetype(inst1->temptype))) { char *t1 = pg_timestamptz_out(inst1->t); - elog(ERROR, "The temporal values have different value at their overlapping instant %s", t1); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal values have different value at their overlapping instant %s", + t1); + return false; } - return; + return true; } /** @@ -933,7 +938,8 @@ bbox_expand(const void *box1, void *box2, meosType temptype) else if (tspatial_type(temptype)) stbox_expand((STBox *) box1, (STBox *) box2); else - elog(ERROR, "Undefined temporal type for bounding box operation"); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "Undefined temporal type for bounding box operation"); return; } @@ -950,59 +956,74 @@ bbox_expand(const void *box1, void *box2, meosType temptype) * consecutive instants may be equal * @param[in] interp Interpolation */ -void +bool ensure_valid_tinstarr(const TInstant **instants, int count, bool merge, interpType interp __attribute__((unused))) { for (int i = 0; i < count; i++) { if (instants[i]->subtype != TINSTANT) - elog(ERROR, "Input values must be temporal instants"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "Input values must be temporal instants"); + return false; + } if (i > 0) { - ensure_increasing_timestamps(instants[i - 1], instants[i], merge); - ensure_spatial_validity((Temporal *) instants[i - 1], - (Temporal *) instants[i]); + if (! ensure_increasing_timestamps(instants[i - 1], instants[i], merge) || + ! ensure_spatial_validity((Temporal *) instants[i - 1], + (Temporal *) instants[i])) + return false; #if NPOINT - if (interp != DISCRETE && instants[i]->temptype == T_TNPOINT) - ensure_same_rid_tnpointinst(instants[i - 1], instants[i]); + if (interp != DISCRETE && instants[i]->temptype == T_TNPOINT && + ! ensure_same_rid_tnpointinst(instants[i - 1], instants[i])) + return false; #endif /* NPOINT */ } } - return; + return true; } /** * @brief Ensure the validity of the arguments when creating a temporal sequence */ -void +bool tsequence_make_valid1(const TInstant **instants, int count, bool lower_inc, bool upper_inc, interpType interp) { - assert(instants); - assert(count > 0); + assert(instants); assert(count > 0); /* Test the validity of the instants */ - ensure_valid_interpolation(instants[0]->temptype, interp); + if (! ensure_valid_interpolation(instants[0]->temptype, interp)) + return false; if (count == 1 && (! lower_inc || ! upper_inc)) - elog(ERROR, "Instant sequence must have inclusive bounds"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Instant sequence must have inclusive bounds"); + return false; + } meosType basetype = temptype_basetype(instants[0]->temptype); if (interp == STEP && count > 1 && ! upper_inc && datum_ne(tinstant_value(instants[count - 1]), tinstant_value(instants[count - 2]), basetype)) - elog(ERROR, "Invalid end value for temporal sequence with step interpolation"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Invalid end value for temporal sequence with step interpolation"); + return false; + } + return true; } /** * @brief Ensure the validity of the arguments when creating a temporal sequence */ -static void +static bool tsequence_make_valid(const TInstant **instants, int count, bool lower_inc, bool upper_inc, interpType interp) { - tsequence_make_valid1(instants, count, lower_inc, upper_inc, interp); - ensure_valid_tinstarr(instants, count, MERGE_NO, interp); - return; + if (! tsequence_make_valid1(instants, count, lower_inc, upper_inc, interp) || + ! ensure_valid_tinstarr(instants, count, MERGE_NO, interp)) + return false; + return true; } /** @@ -1020,7 +1041,10 @@ TSequence * tsequence_make_exp(const TInstant **instants, int count, int maxcount, bool lower_inc, bool upper_inc, interpType interp, bool normalize) { - tsequence_make_valid(instants, count, lower_inc, upper_inc, interp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) instants) || ! ensure_positive(count) || + ! tsequence_make_valid(instants, count, lower_inc, upper_inc, interp)) + return NULL; return tsequence_make1_exp(instants, count, maxcount, lower_inc, upper_inc, interp, normalize, NULL); } @@ -1039,6 +1063,9 @@ TSequence * tsequence_make(const TInstant **instants, int count, bool lower_inc, bool upper_inc, interpType interp, bool normalize) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) instants) || ! ensure_positive(count)) + return NULL; return tsequence_make_exp(instants, count, count, lower_inc, upper_inc, interp, normalize); } @@ -1169,6 +1196,9 @@ tsequence_from_base_timestampset(Datum value, meosType temptype, const Set *s) TSequence * tboolseq_from_base_timestampset(bool b, const Set *s) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return NULL; return tsequence_from_base_timestampset(BoolGetDatum(b), T_TBOOL, s); } @@ -1180,6 +1210,9 @@ tboolseq_from_base_timestampset(bool b, const Set *s) TSequence * tintseq_from_base_timestampset(int i, const Set *s) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return NULL; return tsequence_from_base_timestampset(Int32GetDatum(i), T_TINT, s); } @@ -1191,6 +1224,9 @@ tintseq_from_base_timestampset(int i, const Set *s) TSequence * tfloatseq_from_base_timestampset(double d, const Set *s) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s)) + return NULL; return tsequence_from_base_timestampset(Float8GetDatum(d), T_TFLOAT, s); } @@ -1202,6 +1238,9 @@ tfloatseq_from_base_timestampset(double d, const Set *s) TSequence * ttextseq_from_base_timestampset(const text *txt, const Set *s) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) txt)) + return NULL; return tsequence_from_base_timestampset(PointerGetDatum(txt), T_TTEXT, s); } @@ -1211,20 +1250,15 @@ ttextseq_from_base_timestampset(const text *txt, const Set *s) * and a timestamp set. */ TSequence * -tgeompointseq_from_base_timestampset(const GSERIALIZED *gs, const Set *s) +tpointseq_from_base_timestampset(const GSERIALIZED *gs, const Set *s) { - return tsequence_from_base_timestampset(PointerGetDatum(gs), T_TGEOMPOINT, s); -} - -/** - * @ingroup libmeos_temporal_constructor - * @brief Construct a temporal geographic point discrete sequence from a point - * and a timestamp set. - */ -TSequence * -tgeogpointseq_from_base_timestampset(const GSERIALIZED *gs, const Set *s) -{ - return tsequence_from_base_timestampset(PointerGetDatum(gs), T_TGEOGPOINT, s); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs) || gserialized_is_empty(gs) || + ! ensure_not_null((void *) s)) + return NULL; + meosType temptype = FLAGS_GET_GEODETIC(gs->gflags) ? + T_TGEOGPOINT : T_TGEOMPOINT; + return tsequence_from_base_timestampset(PointerGetDatum(gs), temptype, s); } #endif /* MEOS */ @@ -1267,6 +1301,9 @@ tsequence_from_base_period(Datum value, meosType temptype, const Span *s, TSequence * tboolseq_from_base_period(bool b, const Span *s) { + /* Ensure validity of the arguments */ + if ( ! ensure_not_null((void *) s)) + return NULL; return tsequence_from_base_period(BoolGetDatum(b), T_TBOOL, s, STEP); } @@ -1277,6 +1314,9 @@ tboolseq_from_base_period(bool b, const Span *s) TSequence * tintseq_from_base_period(int i, const Span *s) { + /* Ensure validity of the arguments */ + if ( ! ensure_not_null((void *) s)) + return NULL; return tsequence_from_base_period(Int32GetDatum(i), T_TINT, s, STEP); } @@ -1287,6 +1327,9 @@ tintseq_from_base_period(int i, const Span *s) TSequence * tfloatseq_from_base_period(double d, const Span *s, interpType interp) { + /* Ensure validity of the arguments */ + if ( ! ensure_not_null((void *) s)) + return NULL; return tsequence_from_base_period(Float8GetDatum(d), T_TFLOAT, s, interp); } @@ -1297,7 +1340,9 @@ tfloatseq_from_base_period(double d, const Span *s, interpType interp) TSequence * ttextseq_from_base_period(const text *txt, const Span *s) { - assert(txt); + /* Ensure validity of the arguments */ + if ( ! ensure_not_null((void *) txt) || ! ensure_not_null((void *) s)) + return NULL; return tsequence_from_base_period(PointerGetDatum(txt), T_TTEXT, s, STEP); } @@ -1307,26 +1352,16 @@ ttextseq_from_base_period(const text *txt, const Span *s) * period. */ TSequence * -tgeompointseq_from_base_period(const GSERIALIZED *gs, const Span *s, +tpointseq_from_base_period(const GSERIALIZED *gs, const Span *s, interpType interp) { - assert(gs); - return tsequence_from_base_period(PointerGetDatum(gs), T_TGEOMPOINT, s, - interp); -} - -/** - * @ingroup libmeos_temporal_constructor - * @brief Construct a temporal geographic point sequence from a point and a - * period. - */ -TSequence * -tgeogpointseq_from_base_period(const GSERIALIZED *gs, const Span *s, - interpType interp) -{ - assert(gs); - return tsequence_from_base_period(PointerGetDatum(gs), T_TGEOGPOINT, s, - interp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs) || gserialized_is_empty(gs) || + ! ensure_not_null((void *) s)) + return NULL; + meosType temptype = FLAGS_GET_GEODETIC(gs->gflags) ? + T_TGEOGPOINT : T_TGEOMPOINT; + return tsequence_from_base_period(PointerGetDatum(gs), temptype, s, interp); } #endif /* MEOS */ @@ -1374,7 +1409,6 @@ Temporal * tsequence_append_tinstant(TSequence *seq, const TInstant *inst, double maxdist, const Interval *maxt, bool expand) { - /* Ensure validity of the arguments */ assert(seq); assert(inst); assert(seq->temptype == inst->temptype); interpType interp = MEOS_FLAGS_GET_INTERP(seq->flags); @@ -1382,8 +1416,9 @@ tsequence_append_tinstant(TSequence *seq, const TInstant *inst, double maxdist, TInstant *last = (TInstant *) TSEQUENCE_INST_N(seq, seq->count - 1); int16 flags = seq->flags; #if NPOINT - if (last->temptype == T_TNPOINT && interp != DISCRETE) - ensure_same_rid_tnpointinst(inst, last); + if (last->temptype == T_TNPOINT && interp != DISCRETE && + ! ensure_same_rid_tnpointinst(inst, last)) + return NULL; #endif /* We cannot call ensure_increasing_timestamps since we must take into * account inclusive/exclusive bounds */ @@ -1391,8 +1426,9 @@ tsequence_append_tinstant(TSequence *seq, const TInstant *inst, double maxdist, { char *t1 = pg_timestamptz_out(last->t); char *t = pg_timestamptz_out(inst->t); - elog(ERROR, "Timestamps for temporal value must be increasing: %s, %s", - t1, t); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Timestamps for temporal value must be increasing: %s, %s", t1, t); + return NULL; } Datum value1 = tinstant_value(last); @@ -1405,7 +1441,10 @@ tsequence_append_tinstant(TSequence *seq, const TInstant *inst, double maxdist, if (! eqv1v) { char *t1 = pg_timestamptz_out(last->t); - elog(ERROR, "The temporal values have different value at their common timestamp %s", t1); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal values have different value at their common timestamp %s", + t1); + return NULL; } /* Do not add the new instant if sequence is discrete and new instant is * equal to be last one */ @@ -1543,7 +1582,6 @@ Temporal * tsequence_append_tsequence(TSequence *seq1, const TSequence *seq2, bool expand __attribute__((unused))) { - /* Ensure validity of the arguments */ assert(seq1); assert(seq2); assert(seq1->temptype == seq2->temptype); interpType interp1 = MEOS_FLAGS_GET_INTERP(seq1->flags); @@ -1557,8 +1595,9 @@ tsequence_append_tsequence(TSequence *seq1, const TSequence *seq2, { t1 = pg_timestamptz_out(inst1->t); char *t2 = pg_timestamptz_out(inst2->t); - elog(ERROR, "Timestamps for temporal value must be increasing: %s, %s", - t1, t2); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Timestamps for temporal value must be increasing: %s, %s", t1, t2); + return NULL; } else if (inst1->t == inst2->t && seq1->period.upper_inc && seq2->period.lower_inc) @@ -1569,12 +1608,16 @@ tsequence_append_tsequence(TSequence *seq1, const TSequence *seq2, if (! datum_eq(value1, value2, basetype)) { t1 = pg_timestamptz_out(inst1->t); - elog(ERROR, "The temporal values have different value at their common timestamp %s", t1); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal values have different value at their common timestamp %s", + t1); + return NULL; } } #if NPOINT - if (inst1->temptype == T_TNPOINT && interp1 != DISCRETE) - ensure_same_rid_tnpointinst(inst1, inst2); + if (inst1->temptype == T_TNPOINT && interp1 != DISCRETE && + ! ensure_same_rid_tnpointinst(inst1, inst2)) + return NULL; #endif bool removelast, removefirst; @@ -1728,7 +1771,9 @@ tsequence_merge_array1(const TSequence **sequences, int count, char *t2; t1 = pg_timestamptz_out(inst1->t); t2 = pg_timestamptz_out(inst2->t); - elog(ERROR, "The temporal values cannot overlap on time: %s, %s", t1, t2); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal values cannot overlap on time: %s, %s", t1, t2); + return NULL; } else if (inst1->t == inst2->t && seq1->period.upper_inc && seq2->period.lower_inc) @@ -1736,7 +1781,10 @@ tsequence_merge_array1(const TSequence **sequences, int count, if (! datum_eq(tinstant_value(inst1), tinstant_value(inst2), basetype)) { t1 = pg_timestamptz_out(inst1->t); - elog(ERROR, "The temporal values have different value at their common instant %s", t1); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal values have different value at their common instant %s", + t1); + return NULL; } } seq1 = seq2; @@ -1929,7 +1977,11 @@ tcontseq_to_discrete(const TSequence *seq) assert(seq); assert(! MEOS_FLAGS_GET_DISCRETE(seq->flags)); if (seq->count != 1) - elog(ERROR, "Cannot transform input value to a temporal discrete sequence"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Cannot transform input value to a temporal discrete sequence"); + return NULL; + } return tinstant_to_tsequence(TSEQUENCE_INST_N(seq, 0), DISCRETE); } @@ -1950,7 +2002,11 @@ tcontseq_to_step(const TSequence *seq) (seq->count == 2 && ! datum_eq( tinstant_value(TSEQUENCE_INST_N(seq, 0)), tinstant_value(TSEQUENCE_INST_N(seq, 1)), basetype))) - elog(ERROR, "Cannot transform input value to step interpolation"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Cannot transform input value to step interpolation"); + return NULL; + } const TInstant *instants[2]; for (int i = 0; i < seq->count; i++) @@ -2609,7 +2665,8 @@ tsegment_value_at_timestamp(const TInstant *inst1, const TInstant *inst2, return PointerGetDatum(result); } #endif - elog(ERROR, "unknown interpolation function for continuous temporal type: %d", + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown interpolation function for continuous temporal type: %d", inst1->temptype); return 0; /* make compiler quiet */ } @@ -3013,8 +3070,12 @@ tlinearsegm_intersection_value(const TInstant *inst1, const TInstant *inst2, result = tnpointsegm_intersection_value(inst1, inst2, value, t); #endif else - elog(ERROR, "unknown intersection function for continuous temporal type: %d", + { + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown intersection function for continuous temporal type: %d", inst1->temptype); + return NULL; + } if (result && inter != NULL) /* We are sure it is linear interpolation */ @@ -5327,7 +5388,10 @@ tcontseq_insert(const TSequence *seq1, const TSequence *seq2) basetype)) { char *str = pg_timestamptz_out(instants[0]->t); - elog(ERROR, "The temporal values have different value at their common instant %s", str); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal values have different value at their common instant %s", + str); + return NULL; } } sequences[nseqs++] = (TSequence *) seq2; @@ -5349,7 +5413,7 @@ tcontseq_insert(const TSequence *seq1, const TSequence *seq2) } /** - * @ingroup libmeos_temporal_modif + * @ingroup libmeos_internal_temporal_modif * @brief Insert the second temporal value into the first one. */ Temporal * @@ -5357,6 +5421,7 @@ tsequence_insert(const TSequence *seq1, const TSequence *seq2, bool connect) { assert(seq1); assert(seq2); assert(seq1->temptype == seq2->temptype); + if (MEOS_FLAGS_GET_DISCRETE(seq1->flags) || ! connect) return (Temporal *) tsequence_merge(seq1, seq2); else @@ -5417,7 +5482,7 @@ tcontseq_delete_timestamp(const TSequence *seq, TimestampTz t) } /** - * @ingroup libmeos_temporal_modif + * @ingroup libmeos_internal_temporal_modif * @brief Delete a timestamp from a temporal value connecting the instants * before and after the given timestamp (if any). * @sqlfunc deleteTime @@ -5426,6 +5491,7 @@ Temporal * tsequence_delete_timestamp(const TSequence *seq, TimestampTz t, bool connect) { assert(seq); + Temporal *result; if (MEOS_FLAGS_GET_DISCRETE(seq->flags)) result = (Temporal *) tdiscseq_minus_timestamp(seq, t); @@ -5525,7 +5591,7 @@ tcontseq_delete_timestampset(const TSequence *seq, const Set *s) } /** - * @ingroup libmeos_temporal_modif + * @ingroup libmeos_internal_temporal_modif * @brief Delete a timestamp set from a temporal value connecting the instants * before and after the given timestamp set (if any). * @sqlfunc deleteTime @@ -5533,7 +5599,8 @@ tcontseq_delete_timestampset(const TSequence *seq, const Set *s) Temporal * tsequence_delete_timestampset(const TSequence *seq, const Set *s, bool connect) { - assert(seq); + assert(seq); assert(s); + Temporal *result; if (MEOS_FLAGS_GET_DISCRETE(seq->flags)) result = (Temporal *) tdiscseq_restrict_timestampset(seq, s, REST_MINUS); @@ -5591,7 +5658,7 @@ tcontseq_delete_period(const TSequence *seq, const Span *s) } /** - * @ingroup libmeos_temporal_modif + * @ingroup libmeos_internal_temporal_modif * @brief Delete a period from a temporal value connecting the instants * before and after the given period (if any). * @sqlfunc deleteTime @@ -5599,7 +5666,8 @@ tcontseq_delete_period(const TSequence *seq, const Span *s) Temporal * tsequence_delete_period(const TSequence *seq, const Span *s, bool connect) { - assert(seq); + assert(seq); assert(s); + Temporal *result; if (MEOS_FLAGS_GET_DISCRETE(seq->flags)) result = (Temporal *) tdiscseq_restrict_period(seq, s, REST_MINUS); @@ -5666,7 +5734,7 @@ tcontseq_delete_periodset(const TSequence *seq, const SpanSet *ss) } /** - * @ingroup libmeos_temporal_modif + * @ingroup libmeos_internal_temporal_modif * @brief Delete a period set from a temporal value connecting the instants * before and after the given period set (if any). * @sqlfunc deleteTime @@ -5675,7 +5743,8 @@ Temporal * tsequence_delete_periodset(const TSequence *seq, const SpanSet *ss, bool connect) { - assert(seq); + assert(seq); assert(ss); + Temporal *result; if (MEOS_FLAGS_GET_DISCRETE(seq->flags)) result = (Temporal *) tdiscseq_restrict_periodset(seq, ss, REST_MINUS); @@ -5686,6 +5755,21 @@ tsequence_delete_periodset(const TSequence *seq, const SpanSet *ss, return result; } +/*****************************************************************************/ + +/** + * @ingroup libmeos_internal_temporal_restrict + * @brief Restrict a temporal sequence to (the complement of) a period set. + */ +Temporal * +tsequence_restrict_periodset(const TSequence *seq, const SpanSet *ss, + bool atfunc) +{ + Temporal *result = MEOS_FLAGS_GET_DISCRETE(seq->flags) ? + (Temporal *) tdiscseq_restrict_periodset(seq, ss, atfunc) : + (Temporal *) tcontseq_restrict_periodset(seq, ss, atfunc); + return result; +} /***************************************************************************** * Local aggregate functions diff --git a/meos/src/general/tsequenceset.c b/meos/src/general/tsequenceset.c index 4560a81b9b..8d345383dd 100644 --- a/meos/src/general/tsequenceset.c +++ b/meos/src/general/tsequenceset.c @@ -148,20 +148,32 @@ tsequenceset_set_bbox(const TSequenceSet *ss, void *box) * timestamp, and if they are temporal points, have the same srid and the * same dimensionality */ -static void +static bool ensure_valid_tseqarr(const TSequence **sequences, int count) { interpType interp = MEOS_FLAGS_GET_INTERP(sequences[0]->flags); if (interp == DISCRETE) - elog(ERROR, "Input sequences must be continuous"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Input sequences must be continuous"); + return false; + } for (int i = 0; i < count; i++) { if (sequences[i]->subtype != TSEQUENCE) - elog(ERROR, "Input values must be temporal sequences"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "Input values must be temporal sequences"); + return false; + } if (i > 0) { if (MEOS_FLAGS_GET_INTERP(sequences[i]->flags) != interp) - elog(ERROR, "The temporal values must have the same interpolation"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal values must have the same interpolation"); + return false; + } TimestampTz upper1 = DatumGetTimestampTz(sequences[i - 1]->period.upper); TimestampTz lower2 = DatumGetTimestampTz(sequences[i]->period.lower); if ( upper1 > lower2 || @@ -170,13 +182,16 @@ ensure_valid_tseqarr(const TSequence **sequences, int count) { char *t1 = pg_timestamptz_out(upper1); char *t2 = pg_timestamptz_out(lower2); - elog(ERROR, "Timestamps for temporal value must be increasing: %s, %s", t1, t2); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Timestamps for temporal value must be increasing: %s, %s", t1, t2); + return false; } - ensure_spatial_validity((Temporal *) sequences[i - 1], - (Temporal *) sequences[i]); + if (! ensure_spatial_validity((Temporal *) sequences[i - 1], + (Temporal *) sequences[i])) + return false; } } - return; + return true; } #ifdef DEBUG_BUILD @@ -235,9 +250,9 @@ tsequenceset_make_exp(const TSequence **sequences, int count, int maxcount, { assert(count > 0); assert(maxcount >= count); - - /* Test the validity of the sequences and compute the bounding box */ + /* Ensure validity of the arguments */ ensure_valid_tseqarr(sequences, count); + /* Normalize the array of sequences */ TSequence **normseqs = (TSequence **) sequences; int newcount = count; @@ -324,6 +339,9 @@ tsequenceset_make_exp(const TSequence **sequences, int count, int maxcount, TSequenceSet * tsequenceset_make(const TSequence **sequences, int count, bool normalize) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) sequences) || ! ensure_positive(count)) + return NULL; return tsequenceset_make_exp(sequences, count, count, normalize); } @@ -381,12 +399,14 @@ ensure_valid_tinstarr_gaps(const TInstant **instants, int count, bool merge, int k = 0; for (int i = 1; i < count; i++) { - ensure_increasing_timestamps(instants[i - 1], instants[i], merge); - ensure_spatial_validity((Temporal *) instants[i - 1], - (Temporal *) instants[i]); + if (! ensure_increasing_timestamps(instants[i - 1], instants[i], merge) || + ! ensure_spatial_validity((Temporal *) instants[i - 1], + (Temporal *) instants[i])) + return NULL; #if NPOINT - if (instants[i]->temptype == T_TNPOINT) - ensure_same_rid_tnpointinst(instants[i - 1], instants[i]); + if (instants[i]->temptype == T_TNPOINT && + ! ensure_same_rid_tnpointinst(instants[i - 1], instants[i])) + return NULL; #endif /* Determine if there should be a split */ bool split = false; @@ -424,7 +444,8 @@ tsequenceset_make_gaps_valid(const TInstant **instants, int count, Interval *maxt, int *nsplits) { assert(interp != DISCRETE); - tsequence_make_valid1(instants, count, lower_inc, upper_inc, interp); + if (! tsequence_make_valid1(instants, count, lower_inc, upper_inc, interp)) + return NULL; return ensure_valid_tinstarr_gaps(instants, count, MERGE_NO, maxdist, maxt, nsplits); } @@ -446,8 +467,10 @@ TSequenceSet * tsequenceset_make_gaps(const TInstant **instants, int count, interpType interp, Interval *maxt, double maxdist) { - assert(instants); - assert(count > 0); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) instants) || ! ensure_positive(count)) + return NULL; + TSequence *seq; TSequenceSet *result; @@ -463,9 +486,11 @@ tsequenceset_make_gaps(const TInstant **instants, int count, interpType interp, } /* Ensure that the array of instants is valid and determine the splits */ - int nsplits; + int nsplits = 0; int *splits = tsequenceset_make_gaps_valid((const TInstant **) instants, count, true, true, interp, maxdist, maxt, &nsplits); + if (! splits) + return NULL; if (nsplits == 0) { /* There are no gaps */ @@ -586,7 +611,9 @@ tsequenceset_from_base_periodset(Datum value, meosType temptype, TSequenceSet * tboolseqset_from_base_periodset(bool b, const SpanSet *ps) { - assert(ps); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ps)) + return NULL; return tsequenceset_from_base_periodset(BoolGetDatum(b), T_TBOOL, ps, STEP); } @@ -598,7 +625,9 @@ tboolseqset_from_base_periodset(bool b, const SpanSet *ps) TSequenceSet * tintseqset_from_base_periodset(int i, const SpanSet *ps) { - assert(ps); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ps)) + return NULL; return tsequenceset_from_base_periodset(Int32GetDatum(i), T_TINT, ps, STEP); } @@ -609,7 +638,9 @@ tintseqset_from_base_periodset(int i, const SpanSet *ps) TSequenceSet * tfloatseqset_from_base_periodset(double d, const SpanSet *ps, interpType interp) { - assert(ps); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ps)) + return NULL; return tsequenceset_from_base_periodset(Float8GetDatum(d), T_TFLOAT, ps, interp); } @@ -621,7 +652,9 @@ tfloatseqset_from_base_periodset(double d, const SpanSet *ps, interpType interp) TSequenceSet * ttextseqset_from_base_periodset(const text *txt, const SpanSet *ps) { - assert(ps); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) txt) || ! ensure_not_null((void *) ps)) + return NULL; return tsequenceset_from_base_periodset(PointerGetDatum(txt), T_TTEXT, ps, STEP); } @@ -632,26 +665,17 @@ ttextseqset_from_base_periodset(const text *txt, const SpanSet *ps) * period set. */ TSequenceSet * -tgeompointseqset_from_base_periodset(const GSERIALIZED *gs, const SpanSet *ps, - interpType interp) -{ - assert(ps); - return tsequenceset_from_base_periodset(PointerGetDatum(gs), T_TGEOMPOINT, - ps, interp); -} - -/** - * @ingroup libmeos_temporal_constructor - * @brief Construct a temporal geographic point sequence set from a point and a - * period set. - */ -TSequenceSet * -tgeogpointseqset_from_base_periodset(const GSERIALIZED *gs, const SpanSet *ps, +tpointseqset_from_base_periodset(const GSERIALIZED *gs, const SpanSet *ps, interpType interp) { - assert(ps); - return tsequenceset_from_base_periodset(PointerGetDatum(gs), T_TGEOGPOINT, - ps, interp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs) || gserialized_is_empty(gs) || + ! ensure_not_null((void *) ps)) + return NULL; + meosType temptype = FLAGS_GET_GEODETIC(gs->gflags) ? + T_TGEOGPOINT : T_TGEOMPOINT; + return tsequenceset_from_base_periodset(PointerGetDatum(gs), temptype, ps, + interp); } #endif /* MEOS */ @@ -1376,7 +1400,11 @@ tsequenceset_to_tsequence(const TSequenceSet *ss) { assert(ss); if (ss->count != 1) - elog(ERROR, "Cannot transform input value to a temporal sequence"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Cannot transform input value to a temporal sequence"); + return NULL; + } return tsequence_copy(TSEQUENCESET_SEQ_N(ss, 0)); } @@ -1396,7 +1424,11 @@ tsequenceset_to_discrete(const TSequenceSet *ss) { assert(ss); if (ss->count != ss->totalcount) - elog(ERROR, "Cannot transform input value to a temporal discrete sequence"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Cannot transform input value to a temporal discrete sequence"); + return NULL; + } const TInstant **instants = palloc(sizeof(TInstant *) * ss->count); for (int i = 0; i < ss->count; i++) @@ -1433,7 +1465,11 @@ tsequenceset_to_step(const TSequenceSet *ss) (seq->count == 2 && ! datum_eq( tinstant_value(TSEQUENCE_INST_N(seq, 0)), tinstant_value(TSEQUENCE_INST_N(seq, 1)), basetype))) - elog(ERROR, "Cannot transform input value to step interpolation"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Cannot transform input value to step interpolation"); + return NULL; + } } /* Construct the result */ @@ -2284,9 +2320,9 @@ TSequenceSet * tsequenceset_append_tsequence(TSequenceSet *ss, const TSequence *seq, bool expand) { - /* Ensure validity of the arguments */ assert(ss); assert(seq); assert(ss->temptype == seq->temptype); + /* The last sequence below may be modified with expandable structures */ TSequence *last = (TSequence *) TSEQUENCESET_SEQ_N(ss, ss->count - 1); const TInstant *inst1 = TSEQUENCE_INST_N(last, last->count - 1); @@ -2298,8 +2334,9 @@ tsequenceset_append_tsequence(TSequenceSet *ss, const TSequence *seq, { t1 = pg_timestamptz_out(inst1->t); char *t2 = pg_timestamptz_out(inst2->t); - elog(ERROR, "Timestamps for temporal value must be increasing: %s, %s", - t1, t2); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Timestamps for temporal value must be increasing: %s, %s", t1, t2); + return NULL; } else if (inst1->t == inst2->t && ss->period.upper_inc && seq->period.lower_inc) @@ -2310,7 +2347,10 @@ tsequenceset_append_tsequence(TSequenceSet *ss, const TSequence *seq, if (! datum_eq(value1, value2, basetype)) { t1 = pg_timestamptz_out(inst1->t); - elog(ERROR, "The temporal values have different value at their common timestamp %s", t1); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal values have different value at their common timestamp %s", + t1); + return NULL; } } @@ -2773,9 +2813,8 @@ tgeogpointseqset_in(const char *str) char * tsequenceset_to_string(const TSequenceSet *ss, int maxdd, outfunc value_out) { - /* Ensure validity of the arguments */ assert(ss); - ensure_non_negative(maxdd); + assert(maxdd >= 0); char **strings = palloc(sizeof(char *) * ss->count); size_t outlen = 0; @@ -2899,6 +2938,7 @@ tsequenceset_insert(const TSequenceSet *ss1, const TSequenceSet *ss2) /* If seq2 is between the last sequence added and seq1 */ if (cmp1 <= 0 && cmp2 <= 0) { + char *str; /* Verify that the two sequences have the same value at common instants */ const TInstant *inst1, *inst2; if (cmp1 == 0 && sequences[nseqs - 1]->period.upper_inc && @@ -2909,8 +2949,11 @@ tsequenceset_insert(const TSequenceSet *ss1, const TSequenceSet *ss2) inst2 = TSEQUENCE_INST_N(seq2, 0); if (! datum_eq(tinstant_value(inst1), tinstant_value(inst2), basetype)) { - char *str = pg_timestamptz_out(inst1->t); - elog(ERROR, "The temporal values have different value at their common instant %s", str); + str = pg_timestamptz_out(inst1->t); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal values have different value at their common instant %s", + str); + return NULL; } } if (cmp2 == 0 && seq2->period.upper_inc && seq1->period.lower_inc) @@ -2919,8 +2962,11 @@ tsequenceset_insert(const TSequenceSet *ss1, const TSequenceSet *ss2) inst2 = TSEQUENCE_INST_N(seq1, 0); if (! datum_eq(tinstant_value(inst1), tinstant_value(inst2), basetype)) { - char *str = pg_timestamptz_out(inst1->t); - elog(ERROR, "The temporal values have different value at their common instant %s", str); + str = pg_timestamptz_out(inst1->t); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal values have different value at their common instant %s", + str); + return NULL; } } /* Fill the gap between the last sequence added and seq2 */ diff --git a/meos/src/general/ttext_textfuncs.c b/meos/src/general/ttext_textfuncs.c index ba1bab1be5..488c574538 100644 --- a/meos/src/general/ttext_textfuncs.c +++ b/meos/src/general/ttext_textfuncs.c @@ -246,8 +246,10 @@ datum_upper(Datum value) Temporal * textfunc_ttext(const Temporal *temp, Datum (*func)(Datum value)) { + /* Ensure validity of the arguments */ assert(temp); assert(func); assert(temp->temptype == T_TTEXT); + /* We only need to fill these parameters for tfunc_temporal */ LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); @@ -266,8 +268,10 @@ Temporal * textfunc_ttext_text(const Temporal *temp, Datum value, datum_func2 func, bool invert) { + /* Ensure validity of the arguments */ assert(temp); assert(temp->temptype == T_TTEXT); + LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); lfinfo.func = (varfunc) func; @@ -288,9 +292,11 @@ Temporal * textfunc_ttext_ttext(const Temporal *temp1, const Temporal *temp2, datum_func2 func) { + /* Ensure validity of the arguments */ assert(temp1); assert(temp2); assert(temp1->temptype == temp2->temptype); assert(temp1->temptype == T_TTEXT); + LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); lfinfo.func = (varfunc) func; diff --git a/meos/src/general/ttext_textfuncs_meos.c b/meos/src/general/ttext_textfuncs_meos.c index e24c1ca0aa..d41036b60f 100644 --- a/meos/src/general/ttext_textfuncs_meos.c +++ b/meos/src/general/ttext_textfuncs_meos.c @@ -51,8 +51,11 @@ Temporal * textcat_text_ttext(const text *txt, const Temporal *temp) { - assert(temp); assert(txt); - ensure_temporal_has_type(temp, T_TTEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_same_temporal_basetype(temp, T_TEXT)) + return NULL; + Temporal *result = textfunc_ttext_text(temp, PointerGetDatum(txt), &datum_textcat, INVERT); return result; @@ -66,8 +69,11 @@ textcat_text_ttext(const text *txt, const Temporal *temp) Temporal * textcat_ttext_text(const Temporal *temp, const text *txt) { - assert(temp); assert(txt); - ensure_temporal_has_type(temp, T_TTEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) txt) || + ! ensure_same_temporal_basetype(temp, T_TEXT)) + return NULL; + Temporal *result = textfunc_ttext_text(temp, PointerGetDatum(txt), &datum_textcat, INVERT_NO); return result; @@ -79,11 +85,14 @@ textcat_ttext_text(const Temporal *temp, const text *txt) * @sqlop @p || */ Temporal * -textcat_ttext_ttext(const Temporal *ttext1, const Temporal *ttext2) +textcat_ttext_ttext(const Temporal *temp1, const Temporal *temp2) { - assert(ttext1); assert(ttext2); - ensure_same_temporal_type(ttext1, ttext2); - Temporal *result = textfunc_ttext_ttext(ttext1, ttext2, &datum_textcat); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_same_temporal_type(temp1, temp2)) + return NULL; + + Temporal *result = textfunc_ttext_ttext(temp1, temp2, &datum_textcat); return result; } @@ -97,8 +106,11 @@ textcat_ttext_ttext(const Temporal *ttext1, const Temporal *ttext2) Temporal * ttext_upper(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TTEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TTEXT)) + return NULL; + Temporal *result = textfunc_ttext(temp, &datum_upper); return result; } @@ -111,8 +123,11 @@ ttext_upper(const Temporal *temp) Temporal * ttext_lower(const Temporal *temp) { - assert(temp); - ensure_temporal_has_type(temp, T_TTEXT); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_temporal_has_type(temp, T_TTEXT)) + return NULL; + Temporal *result = textfunc_ttext(temp, &datum_lower); return result; } diff --git a/meos/src/general/type_in.c b/meos/src/general/type_in.c index 1f6c69a1c4..4736f172e7 100644 --- a/meos/src/general/type_in.c +++ b/meos/src/general/type_in.c @@ -103,7 +103,7 @@ findMemberByName(json_object *poObj, const char *pszName) { if (json_object_get_object(poTmp)->head == NULL) { - elog(ERROR, "Invalid MFJSON string"); + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, "Invalid MFJSON string"); return NULL; } for (it.entry = json_object_get_object(poTmp)->head; @@ -128,13 +128,24 @@ static Datum parse_mfjson_coord(json_object *poObj, int srid, bool geodetic) { if (json_type_array != json_object_get_type(poObj)) - elog(ERROR, "Invalid value of the 'coordinates' array in MFJSON string"); - + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid value of the 'coordinates' array in MFJSON string"); + return 0; + } int numcoord = (int) json_object_array_length(poObj); if (numcoord < 2) - elog(ERROR, "Too few elements in 'coordinates' values in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Too few elements in 'coordinates' values in MFJSON string"); + return 0; + } if (numcoord > 3) - elog(ERROR, "Too many elements in 'coordinates' values in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Too many elements in 'coordinates' values in MFJSON string"); + return 0; + } double x, y; json_object *poObjCoord = NULL; @@ -176,14 +187,24 @@ parse_mfjson_values(json_object *mfjson, meosType temptype, int *count) json_object *jvalues = NULL; jvalues = findMemberByName(mfjsonTmp, "values"); if (jvalues == NULL) - elog(ERROR, "Unable to find 'values' in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Unable to find 'values' in MFJSON string"); + return NULL; + } if (json_object_get_type(jvalues) != json_type_array) - elog(ERROR, "Invalid 'values' array in MFJSON string"); - + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid 'values' array in MFJSON string"); + return NULL; + } int numvalues = (int) json_object_array_length(jvalues); if (numvalues < 1) - elog(ERROR, "Invalid value of 'values' array in MFJSON string"); - + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid value of 'values' array in MFJSON string"); + return NULL; + } Datum *values = palloc(sizeof(Datum) * numvalues); for (int i = 0; i < numvalues; ++i) { @@ -193,12 +214,20 @@ parse_mfjson_values(json_object *mfjson, meosType temptype, int *count) { case T_TBOOL: if (json_object_get_type(jvalue) != json_type_boolean) - elog(ERROR, "Invalid boolean value in 'values' array in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid boolean value in 'values' array in MFJSON string"); + return NULL; + } values[i] = BoolGetDatum(json_object_get_boolean(jvalue)); break; case T_TINT: if (json_object_get_type(jvalue) != json_type_int) - elog(ERROR, "Invalid integer value in 'values' array in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid integer value in 'values' array in MFJSON string"); + return NULL; + } values[i] = Int32GetDatum(json_object_get_int(jvalue)); break; case T_TFLOAT: @@ -206,11 +235,17 @@ parse_mfjson_values(json_object *mfjson, meosType temptype, int *count) break; case T_TTEXT: if (json_object_get_type(jvalue) != json_type_string) - elog(ERROR, "Invalid string value in 'values' array in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid string value in 'values' array in MFJSON string"); + return NULL; + } values[i] = PointerGetDatum(cstring2text(json_object_get_string(jvalue))); break; default: /* Error! */ - elog(ERROR, "Unknown temporal type: %d", temptype); + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Unknown temporal type in MFJSON string: %d", temptype); + return NULL; } } *count = numvalues; @@ -231,13 +266,25 @@ parse_mfjson_points(json_object *mfjson, int srid, bool geodetic, json_object *coordinates = NULL; coordinates = findMemberByName(mfjsonTmp, "coordinates"); if (coordinates == NULL) - elog(ERROR, "Unable to find 'coordinates' in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Unable to find 'coordinates' in MFJSON string"); + return NULL; + } if (json_object_get_type(coordinates) != json_type_array) - elog(ERROR, "Invalid 'coordinates' array in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid 'coordinates' array in MFJSON string"); + return NULL; + } int numpoints = (int) json_object_array_length(coordinates); if (numpoints < 1) - elog(ERROR, "Invalid value of 'coordinates' array in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid value of 'coordinates' array in MFJSON string"); + return NULL; + } Datum *values = palloc(sizeof(Datum) * numpoints); for (int i = 0; i < numpoints; ++i) @@ -258,13 +305,25 @@ parse_mfjson_datetimes(json_object *mfjson, int *count) json_object *datetimes = NULL; datetimes = findMemberByName(mfjson, "datetimes"); if (datetimes == NULL) - elog(ERROR, "Unable to find 'datetimes' in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Unable to find 'datetimes' in MFJSON string"); + return NULL; + } if (json_object_get_type(datetimes) != json_type_array) - elog(ERROR, "Invalid 'datetimes' array in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid 'datetimes' array in MFJSON string"); + return NULL; + } int numdates = (int) json_object_array_length(datetimes); if (numdates < 1) - elog(ERROR, "Invalid value of 'datetimes' array in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid value of 'datetimes' array in MFJSON string"); + return NULL; + } TimestampTz *times = palloc(sizeof(TimestampTz) * numdates); for (int i = 0; i < numdates; i++) @@ -306,18 +365,30 @@ tinstant_from_mfjson(json_object *mfjson, bool isgeo, int srid, /* Get values */ json_object *values = findMemberByName(mfjson, "values"); if (values == NULL) - elog(ERROR, "Unable to find 'values' in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Unable to find 'values' in MFJSON string"); + return NULL; + } json_object *val = json_object_array_get_idx(values, 0); switch (temptype) { case T_TBOOL: if (json_object_get_type(val) != json_type_boolean) - elog(ERROR, "Invalid boolean value in 'values' array in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid boolean value in 'values' array in MFJSON string"); + return NULL; + } value = BoolGetDatum(json_object_get_boolean(val)); break; case T_TINT: if (json_object_get_type(val) != json_type_int) - elog(ERROR, "Invalid integer value in 'values' array in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid integer value in 'values' array in MFJSON string"); + return NULL; + } value = Int32GetDatum(json_object_get_int(val)); break; case T_TFLOAT: @@ -325,11 +396,17 @@ tinstant_from_mfjson(json_object *mfjson, bool isgeo, int srid, break; case T_TTEXT: if (json_object_get_type(val) != json_type_string) - elog(ERROR, "Invalid string value in 'values' array in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid string value in 'values' array in MFJSON string"); + return NULL; + } value = PointerGetDatum(cstring2text(json_object_get_string(val))); break; default: /* Error! */ - elog(ERROR, "Unknown temporal type: %d", temptype); + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Unknown temporal type in MFJSON string: %d", temptype); + return NULL; } } else @@ -337,7 +414,11 @@ tinstant_from_mfjson(json_object *mfjson, bool isgeo, int srid, /* Get coordinates */ json_object *coordinates = findMemberByName(mfjson, "coordinates"); if (coordinates == NULL) - elog(ERROR, "Unable to find 'coordinates' in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Unable to find 'coordinates' in MFJSON string"); + return NULL; + } json_object *coords = json_object_array_get_idx(coordinates, 0); value = parse_mfjson_coord(coords, srid, geodetic); } @@ -355,7 +436,8 @@ tinstant_from_mfjson(json_object *mfjson, bool isgeo, int srid, const char *strdatetimes = json_object_get_string(datevalue); if (strdatetimes == NULL) { - elog(ERROR, "Invalid 'datetimes' value in MFJSON string"); + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid 'datetimes' value in MFJSON string"); return NULL; /* make Codacy quiet */ } strcpy(str, strdatetimes); @@ -456,7 +538,7 @@ tinstarr_from_mfjson(json_object *mfjson, bool isgeo, int srid, bool geodetic = (temptype == T_TGEOGPOINT); bool byvalue = basetype_byvalue(temptype_basetype(temptype)); /* Get coordinates and datetimes */ - int numvalues, numdates; + int numvalues = 0, numdates = 0; Datum *values; if (! isgeo) values = parse_mfjson_values(mfjson, temptype, &numvalues); @@ -464,8 +546,12 @@ tinstarr_from_mfjson(json_object *mfjson, bool isgeo, int srid, values = parse_mfjson_points(mfjson, srid, geodetic, &numvalues); TimestampTz *times = parse_mfjson_datetimes(mfjson, &numdates); if (numvalues != numdates) - elog(ERROR, "Distinct number of elements in '%s' and 'datetimes' arrays", + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Distinct number of elements in '%s' and 'datetimes' arrays", ! isgeo ? "values" : "coordinates"); + return NULL; + } /* Construct the array of temporal instant points */ TInstant **result = palloc(sizeof(TInstant *) * numvalues); @@ -492,7 +578,7 @@ tsequence_from_mfjson(json_object *mfjson, bool isgeo, int srid, { assert(mfjson); /* Get the array of temporal instant points */ - int count; + int count = 0; TInstant **instants = tinstarr_from_mfjson(mfjson, isgeo, srid, temptype, &count); @@ -500,14 +586,22 @@ tsequence_from_mfjson(json_object *mfjson, bool isgeo, int srid, json_object *lowerinc = NULL; lowerinc = findMemberByName(mfjson, "lower_inc"); if (lowerinc == NULL) - elog(ERROR, "Unable to find 'lower_inc' in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Unable to find 'lower_inc' in MFJSON string"); + return NULL; + } bool lower_inc = (bool) json_object_get_boolean(lowerinc); /* Get upper bound flag */ json_object *upperinc = NULL; upperinc = findMemberByName(mfjson, "upper_inc"); if (upperinc == NULL) - elog(ERROR, "Unable to find 'upper_inc' in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Unable to find 'upper_inc' in MFJSON string"); + return NULL; + } bool upper_inc = (bool) json_object_get_boolean(upperinc); /* Construct the temporal point */ @@ -606,10 +700,18 @@ tsequenceset_from_mfjson(json_object *mfjson, bool isgeo, int srid, * a sequence and a sequence set we look for the "sequences" member and * then call this function */ if (json_object_get_type(seqs) != json_type_array) - elog(ERROR, "Invalid 'sequences' array in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid 'sequences' array in MFJSON string"); + return NULL; + } int numseqs = (int) json_object_array_length(seqs); if (numseqs < 1) - elog(ERROR, "Invalid value of 'sequences' array in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid value of 'sequences' array in MFJSON string"); + return NULL; + } /* Construct the temporal point */ TSequence **sequences = palloc(sizeof(TSequence *) * numseqs); @@ -701,13 +803,18 @@ tgeogpointseqset_from_mfjson(json_object *mfjson, int srid, interpType interp) /*****************************************************************************/ -static void +static bool ensure_temptype_mfjson(const char *typestr) { if (strcmp(typestr, "MovingBoolean") != 0 && strcmp(typestr, "MovingInteger") != 0 && strcmp(typestr, "MovingFloat") != 0 && strcmp(typestr, "MovingText") != 0 && strcmp(typestr, "MovingGeomPoint") != 0 && strcmp(typestr, "MovingGeogPoint") != 0 ) - elog(ERROR, "Invalid 'type' value in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid 'type' value in MFJSON string"); + return false; + } + return true; } /** @@ -717,7 +824,10 @@ ensure_temptype_mfjson(const char *typestr) Temporal * temporal_from_mfjson(const char *mfjson) { - assert(mfjson); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) mfjson)) + return NULL; + char *srs = NULL; int srid = 0; Temporal *result = NULL; @@ -738,7 +848,9 @@ temporal_from_mfjson(const char *mfjson) json_tokener_error_desc(jstok->err), jstok->char_offset); json_tokener_free(jstok); json_object_put(poObj); - elog(ERROR, "Error while processing MFJSON string"); + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Error while processing MFJSON string"); + return NULL; } json_tokener_free(jstok); @@ -747,14 +859,17 @@ temporal_from_mfjson(const char *mfjson) */ poObjType = findMemberByName(poObj, "type"); if (poObjType == NULL) - elog(ERROR, "Unable to find 'type' in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Unable to find 'type' in MFJSON string"); + return NULL; + } - /* - * Determine type of temporal type - */ + /* Determine the type of temporal type */ const char *typestr = json_object_get_string(poObjType); meosType temptype; - ensure_temptype_mfjson(typestr); + if (! ensure_temptype_mfjson(typestr)) + return NULL; if (strcmp(typestr, "MovingBoolean") == 0) temptype = T_TBOOL; else if (strcmp(typestr, "MovingInteger") == 0) @@ -773,7 +888,11 @@ temporal_from_mfjson(const char *mfjson) */ poObjInterp = findMemberByName(poObj, "interpolation"); if (poObjInterp == NULL) - elog(ERROR, "Unable to find 'interpolation' in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Unable to find 'interpolation' in MFJSON string"); + return NULL; + } bool isgeo = tgeo_type(temptype); if (isgeo) @@ -834,9 +953,12 @@ temporal_from_mfjson(const char *mfjson) temptype, interp); } else - elog(ERROR, "Invalid 'interpolation' value in MFJSON string"); + { + meos_error(ERROR, MEOS_ERR_MFJSON_INPUT, + "Invalid 'interpolation' value in MFJSON string"); + return NULL; + } } - return result; } @@ -853,7 +975,11 @@ static inline void wkb_parse_state_check(wkb_parse_state *s, size_t next) { if ((s->pos + next) > (s->wkb + s->wkb_size)) - elog(ERROR, "WKB structure does not match expected size!"); + { + meos_error(ERROR, MEOS_ERR_WKB_INPUT, + "WKB structure does not match expected size!"); + return; + } } /** @@ -1086,7 +1212,8 @@ basevalue_from_wkb_state(wkb_parse_state *s) return PointerGetDatum(npoint_from_wkb_state(s)); #endif /* NPOINT */ default: /* Error! */ - elog(ERROR, "Unknown base type: %d", s->basetype); + meos_error(ERROR, MEOS_ERR_WKB_INPUT, + "Unknown base type IN WKB string: %d", s->basetype); return 0; /* make compiler quiet */ } } @@ -1397,7 +1524,8 @@ temporal_flags_from_wkb_state(wkb_parse_state *s, uint8_t wkb_flags) s->subtype = TSEQUENCESET; break; default: /* Error! */ - elog(ERROR, "Unknown WKB flags: %d", wkb_flags); + meos_error(ERROR, MEOS_ERR_WKB_INPUT, + "Unknown WKB flags: %d", wkb_flags); break; } return; @@ -1544,8 +1672,11 @@ datum_from_wkb(const uint8_t *wkb, size_t size, meosType type) /* Fail when handed incorrect starting byte */ char wkb_little_endian = byte_from_wkb_state(&s); if (wkb_little_endian != 1 && wkb_little_endian != 0) - elog(ERROR, "Invalid endian flag value encountered."); - + { + meos_error(ERROR, MEOS_ERR_WKB_INPUT, + "Invalid endian flag value in WKB string."); + return 0; + } /* Check the endianness of our input */ s.swap_bytes = false; /* Machine arch is big endian, request is for little */ @@ -1574,7 +1705,8 @@ datum_from_wkb(const uint8_t *wkb, size_t size, meosType type) if (temporal_type(type)) return PointerGetDatum(temporal_from_wkb_state(&s)); /* Error! */ - elog(ERROR, "Unknown WKB type: %d", type); + meos_error(ERROR, MEOS_ERR_WKB_INPUT, + "Unknown type in WKB string: %d", type); return 0; } @@ -1603,7 +1735,9 @@ datum_from_hexwkb(const char *hexwkb, size_t size, meosType type) Set * set_from_wkb(const uint8_t *wkb, size_t size) { - assert(wkb); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) wkb)) + return NULL; /* We pass ANY set type, the actual type is read from the byte string */ return DatumGetSetP(datum_from_wkb(wkb, size, T_INTSET)); } @@ -1617,7 +1751,9 @@ set_from_wkb(const uint8_t *wkb, size_t size) Set * set_from_hexwkb(const char *hexwkb) { - assert(hexwkb); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) hexwkb)) + return NULL; size_t size = strlen(hexwkb); /* We pass ANY set type, the actual type is read from the byte string */ return DatumGetSetP(datum_from_hexwkb(hexwkb, size, T_INTSET)); @@ -1634,7 +1770,9 @@ set_from_hexwkb(const char *hexwkb) Span * span_from_wkb(const uint8_t *wkb, size_t size) { - assert(wkb); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) wkb)) + return NULL; /* We pass ANY span type, the actual type is read from the byte string */ return DatumGetSpanP(datum_from_wkb(wkb, size, T_INTSPAN)); } @@ -1647,7 +1785,9 @@ span_from_wkb(const uint8_t *wkb, size_t size) Span * span_from_hexwkb(const char *hexwkb) { - assert(hexwkb); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) hexwkb)) + return NULL; size_t size = strlen(hexwkb); /* We pass ANY span type, the actual type is read from the byte string */ return DatumGetSpanP(datum_from_hexwkb(hexwkb, size, T_INTSPAN)); @@ -1664,7 +1804,9 @@ span_from_hexwkb(const char *hexwkb) SpanSet * spanset_from_wkb(const uint8_t *wkb, size_t size) { - assert(wkb); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) wkb)) + return NULL; /* We pass ANY span set type, the actual type is read from the byte string */ return DatumGetSpanSetP(datum_from_wkb(wkb, size, T_INTSPANSET)); } @@ -1677,7 +1819,9 @@ spanset_from_wkb(const uint8_t *wkb, size_t size) SpanSet * spanset_from_hexwkb(const char *hexwkb) { - assert(hexwkb); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) hexwkb)) + return NULL; size_t size = strlen(hexwkb); /* We pass ANY span set type, the actual type is read from the byte string */ return DatumGetSpanSetP(datum_from_hexwkb(hexwkb, size, T_INTSPANSET)); @@ -1694,7 +1838,9 @@ spanset_from_hexwkb(const char *hexwkb) TBox * tbox_from_wkb(const uint8_t *wkb, size_t size) { - assert(wkb); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) wkb)) + return NULL; return DatumGetTboxP(datum_from_wkb(wkb, size, T_TBOX)); } @@ -1706,7 +1852,9 @@ tbox_from_wkb(const uint8_t *wkb, size_t size) TBox * tbox_from_hexwkb(const char *hexwkb) { - assert(hexwkb); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) hexwkb)) + return NULL; size_t size = strlen(hexwkb); return DatumGetTboxP(datum_from_hexwkb(hexwkb, size, T_TBOX)); } @@ -1722,7 +1870,9 @@ tbox_from_hexwkb(const char *hexwkb) STBox * stbox_from_wkb(const uint8_t *wkb, size_t size) { - assert(wkb); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) wkb)) + return NULL; return DatumGetSTboxP(datum_from_wkb(wkb, size, T_STBOX)); } @@ -1735,7 +1885,9 @@ stbox_from_wkb(const uint8_t *wkb, size_t size) STBox * stbox_from_hexwkb(const char *hexwkb) { - assert(hexwkb); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) hexwkb)) + return NULL; size_t size = strlen(hexwkb); return DatumGetSTboxP(datum_from_hexwkb(hexwkb, size, T_STBOX)); } @@ -1752,7 +1904,9 @@ stbox_from_hexwkb(const char *hexwkb) Temporal * temporal_from_wkb(const uint8_t *wkb, size_t size) { - assert(wkb); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) wkb)) + return NULL; /* We pass ANY temporal type, the actual type is read from the byte string */ return DatumGetTemporalP(datum_from_wkb(wkb, size, T_TINT)); } @@ -1766,7 +1920,9 @@ temporal_from_wkb(const uint8_t *wkb, size_t size) Temporal * temporal_from_hexwkb(const char *hexwkb) { - assert(hexwkb); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) hexwkb)) + return NULL; size_t size = strlen(hexwkb); /* We pass ANY temporal type, the actual type is read from the byte string */ return DatumGetTemporalP(datum_from_hexwkb(hexwkb, size, T_TINT)); diff --git a/meos/src/general/type_out.c b/meos/src/general/type_out.c index a2d5b9a2d8..c20c978618 100644 --- a/meos/src/general/type_out.c +++ b/meos/src/general/type_out.c @@ -35,6 +35,7 @@ /* C */ #include #include +#include /* PostgreSQL */ #include #if POSTGRESQL_VERSION_NUMBER >= 160000 @@ -413,7 +414,8 @@ bbox_mfjson_size(meosType temptype, bool hasz, int precision) size = stbox_mfjson_size(hasz, precision); break; default: /* Error! */ - elog(ERROR, "Unknown temporal type: %d", temptype); + meos_error(ERROR, MEOS_ERR_MFJSON_OUTPUT, + "Unknown temporal type in MFJSON output: %d", temptype); return 0; /* make compiler quiet */ } return size; @@ -439,7 +441,8 @@ bbox_mfjson_buf(meosType temptype, char *output, const bboxunion *bbox, case T_TGEOGPOINT: return stbox_mfjson_buf(output, (STBox *) bbox, hasz, precision); default: /* Error! */ - elog(ERROR, "Unknown temporal type: %d", temptype); + meos_error(ERROR, MEOS_ERR_MFJSON_OUTPUT, + "Unknown temporal type in MFJSON output: %d", temptype); return 0; /* make compiler quiet */ } } @@ -474,7 +477,8 @@ temptype_mfjson_size(meosType temptype) size = sizeof("{'type':'MovingGeogPoint',"); break; default: /* Error! */ - elog(ERROR, "Unknown temporal type: %d", temptype); + meos_error(ERROR, MEOS_ERR_MFJSON_OUTPUT, + "Unknown temporal type in MFJSON output: %d", temptype); size = 0; /* make compiler quiet */ break; } @@ -510,7 +514,8 @@ temptype_mfjson_buf(char *output, meosType temptype) ptr += sprintf(ptr, "{\"type\":\"MovingGeogPoint\","); break; default: /* Error! */ - elog(ERROR, "Unknown temporal type: %d", temptype); + meos_error(ERROR, MEOS_ERR_MFJSON_OUTPUT, + "Unknown temporal type in MFJSON output: %d", temptype); break; } return (ptr - output); @@ -980,7 +985,10 @@ char * temporal_as_mfjson(const Temporal *temp, bool with_bbox, int flags, int precision, char *srs) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; + char *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -1011,10 +1019,9 @@ temporal_as_mfjson(const Temporal *temp, bool with_bbox, int flags, char ** temporalarr_out(const Temporal **temparr, int count, int maxdd) { - /* Ensure validity of the arguments */ assert(temparr); assert(count > 0); - ensure_non_negative(maxdd); + assert(maxdd >=0); char **result = palloc(sizeof(text *) * count); for (int i = 0; i < count; i++) @@ -1071,7 +1078,8 @@ basetype_to_wkb_size(Datum value, meosType basetype, int16 flags) return MEOS_WKB_INT8_SIZE + MEOS_WKB_DOUBLE_SIZE; #endif /* NPOINT */ default: /* Error! */ - elog(ERROR, "Unknown temporal base type: %d", basetype); + meos_error(ERROR, MEOS_ERR_MFJSON_OUTPUT, + "Unknown temporal base type in MFJSON output: %d", basetype); return 0; /* make compiler quiet */ } } @@ -1392,8 +1400,9 @@ datum_to_wkb_size(Datum value, meosType type, uint8_t variant) if (temporal_type(type)) return temporal_to_wkb_size((Temporal *) DatumGetPointer(value), variant); /* Error! */ - elog(ERROR, "Unknown WKB type: %d", type); - return 0; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_WKB_OUTPUT, + "Unknown type in WKB output: %d", type); + return SIZE_MAX; } /***************************************************************************** @@ -1482,8 +1491,11 @@ static uint8_t * bool_to_wkb_buf(bool b, uint8_t *buf, uint8_t variant) { if (sizeof(bool) != MEOS_WKB_BYTE_SIZE) - elog(ERROR, "Machine bool size is not %d bytes!", MEOS_WKB_BYTE_SIZE); - + { + meos_error(ERROR, MEOS_ERR_WKB_OUTPUT, + "Machine bool size is not %d bytes!", MEOS_WKB_BYTE_SIZE); + return NULL; + } char *bptr = (char *)(&b); return bytes_to_wkb_buf(bptr, MEOS_WKB_BYTE_SIZE, buf, variant); } @@ -1495,8 +1507,11 @@ static uint8_t * uint8_to_wkb_buf(const uint8_t i, uint8_t *buf, uint8_t variant) { if (sizeof(int8) != MEOS_WKB_BYTE_SIZE) - elog(ERROR, "Machine int8 size is not %d bytes!", MEOS_WKB_BYTE_SIZE); - + { + meos_error(ERROR, MEOS_ERR_WKB_OUTPUT, + "Machine int8 size is not %d bytes!", MEOS_WKB_BYTE_SIZE); + return NULL; + } char *iptr = (char *)(&i); return bytes_to_wkb_buf(iptr, MEOS_WKB_BYTE_SIZE, buf, variant); } @@ -1508,8 +1523,11 @@ static uint8_t * int16_to_wkb_buf(const int16 i, uint8_t *buf, uint8_t variant) { if (sizeof(int16) != MEOS_WKB_INT2_SIZE) - elog(ERROR, "Machine int16 size is not %d bytes!", MEOS_WKB_INT2_SIZE); - + { + meos_error(ERROR, MEOS_ERR_WKB_OUTPUT, + "Machine int16 size is not %d bytes!", MEOS_WKB_INT2_SIZE); + return NULL; + } char *iptr = (char *)(&i); return bytes_to_wkb_buf(iptr, MEOS_WKB_INT2_SIZE, buf, variant); } @@ -1521,8 +1539,11 @@ uint8_t * int32_to_wkb_buf(const int i, uint8_t *buf, uint8_t variant) { if (sizeof(int) != MEOS_WKB_INT4_SIZE) - elog(ERROR, "Machine int32 size is not %d bytes!", MEOS_WKB_INT4_SIZE); - + { + meos_error(ERROR, MEOS_ERR_WKB_OUTPUT, + "Machine int32 size is not %d bytes!", MEOS_WKB_INT4_SIZE); + return NULL; + } char *iptr = (char *)(&i); return bytes_to_wkb_buf(iptr, MEOS_WKB_INT4_SIZE, buf, variant); } @@ -1534,8 +1555,11 @@ uint8_t * int64_to_wkb_buf(const int64 i, uint8_t *buf, uint8_t variant) { if (sizeof(int64) != MEOS_WKB_INT8_SIZE) - elog(ERROR, "Machine int64 size is not %d bytes!", MEOS_WKB_INT8_SIZE); - + { + meos_error(ERROR, MEOS_ERR_WKB_OUTPUT, + "Machine int64 size is not %d bytes!", MEOS_WKB_INT8_SIZE); + return NULL; + } char *iptr = (char *)(&i); return bytes_to_wkb_buf(iptr, MEOS_WKB_INT8_SIZE, buf, variant); } @@ -1547,8 +1571,11 @@ uint8_t* double_to_wkb_buf(const double d, uint8_t *buf, uint8_t variant) { if (sizeof(double) != MEOS_WKB_DOUBLE_SIZE) - elog(ERROR, "Machine double size is not %d bytes!", MEOS_WKB_DOUBLE_SIZE); - + { + meos_error(ERROR, MEOS_ERR_WKB_OUTPUT, + "Machine double size is not %d bytes!", MEOS_WKB_DOUBLE_SIZE); + return NULL; + } char *dptr = (char *)(&d); return bytes_to_wkb_buf(dptr, MEOS_WKB_DOUBLE_SIZE, buf, variant); } @@ -1561,9 +1588,11 @@ uint8_t * timestamp_to_wkb_buf(const TimestampTz t, uint8_t *buf, uint8_t variant) { if (sizeof(TimestampTz) != MEOS_WKB_TIMESTAMP_SIZE) - elog(ERROR, "Machine timestamp size is not %d bytes!", - MEOS_WKB_TIMESTAMP_SIZE); - + { + meos_error(ERROR, MEOS_ERR_WKB_OUTPUT, + "Machine timestamp size is not %d bytes!", MEOS_WKB_TIMESTAMP_SIZE); + return NULL; + } char *tptr = (char *)(&t); return bytes_to_wkb_buf(tptr, MEOS_WKB_TIMESTAMP_SIZE, buf, variant); } @@ -1661,8 +1690,8 @@ basevalue_to_wkb_buf(Datum value, meosType basetype, int16 flags, uint8_t *buf, break; #endif /* NPOINT */ default: /* Error! */ - elog(ERROR, "unknown basetype for function basevalue_to_wkb_buf: %d", - basetype); + meos_error(ERROR, MEOS_ERR_WKB_OUTPUT, + "unknown basetype in WKB output: %d", basetype); } return buf; } @@ -2176,7 +2205,8 @@ datum_to_wkb_buf(Datum value, meosType type, uint8_t *buf, uint8_t variant) buf = temporal_to_wkb_buf((Temporal *) DatumGetPointer(value), buf, variant); else /* Error! */ - elog(ERROR, "Unknown WKB type: %d", type); + meos_error(ERROR, MEOS_ERR_WKB_OUTPUT, + "Unknown type in WKB output: %d", type); return buf; } @@ -2209,7 +2239,8 @@ datum_as_wkb(Datum value, meosType type, uint8_t variant, size_t *size_out) buf_size = datum_to_wkb_size(value, type, variant); if (buf_size == 0) { - elog(ERROR, "Error calculating output WKB buffer size."); + meos_error(ERROR, MEOS_ERR_WKB_OUTPUT, + "Error calculating output WKB buffer size."); return NULL; } @@ -2231,8 +2262,8 @@ datum_as_wkb(Datum value, meosType type, uint8_t variant, size_t *size_out) buf = palloc(buf_size); if (buf == NULL) { - elog(ERROR, "Unable to allocate " UINT64_FORMAT - " bytes for WKB output buffer.", buf_size); + meos_error(ERROR, MEOS_ERR_WKB_OUTPUT, "Unable to allocate " + UINT64_FORMAT " bytes for WKB output buffer.", buf_size); return NULL; } @@ -2252,7 +2283,8 @@ datum_as_wkb(Datum value, meosType type, uint8_t variant, size_t *size_out) /* The buffer pointer should now land at the end of the allocated buffer space. Let's check. */ if (buf_size != (size_t) (buf - wkb_out)) { - elog(ERROR, "Output WKB is not the same size as the allocated buffer."); + meos_error(ERROR, MEOS_ERR_WKB_OUTPUT, + "Output WKB is not the same size as the allocated buffer."); pfree(wkb_out); return NULL; } @@ -2288,7 +2320,9 @@ datum_as_hexwkb(Datum value, meosType type, uint8_t variant, size_t *size) uint8_t * span_as_wkb(const Span *s, uint8_t variant, size_t *size_out) { - assert(s); assert(size_out); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) size_out)) + return NULL; uint8_t *result = datum_as_wkb(PointerGetDatum(s), s->spantype, variant, size_out); return result; @@ -2303,7 +2337,9 @@ span_as_wkb(const Span *s, uint8_t variant, size_t *size_out) char * span_as_hexwkb(const Span *s, uint8_t variant, size_t *size_out) { - assert(s); assert(size_out); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) size_out)) + return NULL; char *result = (char *) datum_as_wkb(PointerGetDatum(s), s->spantype, variant | (uint8_t) WKB_HEX, size_out); return result; @@ -2320,7 +2356,9 @@ span_as_hexwkb(const Span *s, uint8_t variant, size_t *size_out) uint8_t * set_as_wkb(const Set *s, uint8_t variant, size_t *size_out) { - assert(s); assert(size_out); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) size_out)) + return NULL; uint8_t *result = datum_as_wkb(PointerGetDatum(s), s->settype, variant, size_out); return result; @@ -2335,7 +2373,9 @@ set_as_wkb(const Set *s, uint8_t variant, size_t *size_out) char * set_as_hexwkb(const Set *s, uint8_t variant, size_t *size_out) { - assert(s); assert(size_out); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) s) || ! ensure_not_null((void *) size_out)) + return NULL; char *result = (char *) datum_as_wkb(PointerGetDatum(s), s->settype, variant | (uint8_t) WKB_HEX, size_out); return result; @@ -2352,7 +2392,9 @@ set_as_hexwkb(const Set *s, uint8_t variant, size_t *size_out) uint8_t * spanset_as_wkb(const SpanSet *ss, uint8_t variant, size_t *size_out) { - assert(ss); assert(size_out); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) size_out)) + return NULL; uint8_t *result = datum_as_wkb(PointerGetDatum(ss), ss->spansettype, variant, size_out); return result; @@ -2367,7 +2409,9 @@ spanset_as_wkb(const SpanSet *ss, uint8_t variant, size_t *size_out) char * spanset_as_hexwkb(const SpanSet *ss, uint8_t variant, size_t *size_out) { - assert(ss); assert(size_out); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) ss) || ! ensure_not_null((void *) size_out)) + return NULL; char *result = (char *) datum_as_wkb(PointerGetDatum(ss), ss->spansettype, variant | (uint8_t) WKB_HEX, size_out); return result; @@ -2384,7 +2428,9 @@ spanset_as_hexwkb(const SpanSet *ss, uint8_t variant, size_t *size_out) uint8_t * tbox_as_wkb(const TBox *box, uint8_t variant, size_t *size_out) { - assert(box); assert(size_out); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) size_out)) + return NULL; uint8_t *result = datum_as_wkb(PointerGetDatum(box), T_TBOX, variant, size_out); return result; @@ -2399,7 +2445,9 @@ tbox_as_wkb(const TBox *box, uint8_t variant, size_t *size_out) char * tbox_as_hexwkb(const TBox *box, uint8_t variant, size_t *size_out) { - assert(box); assert(size_out); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) size_out)) + return NULL; char *result = (char *) datum_as_wkb(PointerGetDatum(box), T_TBOX, variant | (uint8_t) WKB_HEX, size_out); return result; @@ -2416,7 +2464,9 @@ tbox_as_hexwkb(const TBox *box, uint8_t variant, size_t *size_out) uint8_t * stbox_as_wkb(const STBox *box, uint8_t variant, size_t *size_out) { - assert(box); assert(size_out); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) size_out)) + return NULL; uint8_t *result = datum_as_wkb(PointerGetDatum(box), T_STBOX, variant, size_out); return result; @@ -2431,7 +2481,9 @@ stbox_as_wkb(const STBox *box, uint8_t variant, size_t *size_out) char * stbox_as_hexwkb(const STBox *box, uint8_t variant, size_t *size_out) { - assert(box); assert(size_out); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) size_out)) + return NULL; char *result = (char *) datum_as_wkb(PointerGetDatum(box), T_STBOX, variant | (uint8_t) WKB_HEX, size_out); return result; @@ -2448,7 +2500,9 @@ stbox_as_hexwkb(const STBox *box, uint8_t variant, size_t *size_out) uint8_t * temporal_as_wkb(const Temporal *temp, uint8_t variant, size_t *size_out) { - assert(temp); assert(size_out); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) size_out)) + return NULL; uint8_t *result = datum_as_wkb(PointerGetDatum(temp), temp->temptype, variant, size_out); return result; @@ -2463,7 +2517,9 @@ temporal_as_wkb(const Temporal *temp, uint8_t variant, size_t *size_out) char * temporal_as_hexwkb(const Temporal *temp, uint8_t variant, size_t *size_out) { - assert(temp); assert(size_out); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) size_out)) + return NULL; char *result = (char *) datum_as_wkb(PointerGetDatum(temp), temp->temptype, variant | (uint8_t) WKB_HEX, size_out); return result; diff --git a/meos/src/general/type_parser.c b/meos/src/general/type_parser.c index ac4510fe08..a130839ee4 100644 --- a/meos/src/general/type_parser.c +++ b/meos/src/general/type_parser.c @@ -30,7 +30,7 @@ /** * @file * @brief Functions for parsing base, set, span, tbox, and temporal types - * @note Many functions make two passes for parsing, the first one to obtain + * @note Many functions make two passes for parsing, the first one to obtain * the number of elements in order to do memory allocation with `palloc`, the * second one to create the type. This is the only approach we can see at the * moment which is both correct and simple. @@ -38,6 +38,9 @@ #include "general/type_parser.h" +/* C */ +#include +#include /* MEOS */ #include #include @@ -47,28 +50,29 @@ /*****************************************************************************/ /** - * @brief Input a white space from the buffer + * @brief Ensure there is no more input excepted white spaces */ -void -p_whitespace(const char **str) +bool +ensure_end_input(const char **str, const char *type) { - while (**str == ' ' || **str == '\n' || **str == '\r' || **str == '\t') - *str += 1; - return; + p_whitespace(str); + if (**str != 0) + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Could not parse %s value: Extraneous characters at the end", type); + return false; + } + return true; } /** - * @brief Ensure there is no more input excepted white spaces + * @brief Input a white space from the buffer */ void -ensure_end_input(const char **str, bool end, const char *type) +p_whitespace(const char **str) { - if (end) - { - p_whitespace(str); - if (**str != 0) - elog(ERROR, "Could not parse %s value", type); - } + while (**str == ' ' || **str == '\n' || **str == '\r' || **str == '\t') + *str += 1; return; } @@ -87,6 +91,21 @@ p_obrace(const char **str) return false; } +/** + * @brief Ensure to input an opening brace from the buffer + */ +bool +ensure_obrace(const char **str, const char *type) +{ + if (! p_obrace(str)) + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Could not parse %s value: Missing opening brace", type); + return false; + } + return true; +} + /** * @brief Input a closing brace from the buffer */ @@ -102,6 +121,21 @@ p_cbrace(const char **str) return false; } +/** + * @brief Ensure to input a closing brace from the buffer + */ +bool +ensure_cbrace(const char **str, const char *type) +{ + if (! p_cbrace(str)) + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Could not parse %s value: Missing closing brace", type); + return false; + } + return true; +} + /** * @brief Input an opening bracket from the buffer */ @@ -150,11 +184,16 @@ p_oparen(const char **str) /** * @brief Ensure to input an opening parenthesis from the buffer */ -void +bool ensure_oparen(const char **str, const char *type) { if (!p_oparen(str)) - elog(ERROR, "Could not parse %s: Missing opening parenthesis", type); + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Could not parse %s: Missing opening parenthesis", type); + return false; + } + return true; } /** @@ -175,11 +214,16 @@ p_cparen(const char **str) /** * @brief Ensure to input a closing parenthesis from the buffer */ -void +bool ensure_cparen(const char **str, const char *type) { if (!p_cparen(str)) - elog(ERROR, "Could not parse %s: Missing closing parenthesis", type); + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Could not parse %s: Missing closing parenthesis", type); + return false; + } + return true; } /** @@ -197,19 +241,22 @@ p_comma(const char **str) return false; } +/*****************************************************************************/ + /** * @brief Input a double from the buffer - * - * @param[in,out] str Pointer to the current position of the input buffer */ - double double_parse(const char **str) { char *nextstr = (char *) *str; double result = strtod(*str, &nextstr); if (*str == nextstr) - elog(ERROR, "Invalid input syntax for type double"); + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Invalid input syntax for type double"); + return DBL_MAX; + } *str = nextstr; return result; } @@ -237,8 +284,11 @@ temporal_basetype_parse(const char **str, meosType basetype) delim++; } if ((*str)[delim] == '\0') - elog(ERROR, "Could not parse element value"); - + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Could not parse element value"); + return 0; + } char *str1 = palloc(sizeof(char) * (delim + 1)); strncpy(str1, *str, delim); str1[delim] = '\0'; @@ -260,7 +310,8 @@ tbox_parse(const char **str) bool hasx = false, hast = false; Span span; Span period; - + const char *type_str = "temporal box"; + p_whitespace(str); /* By default the span type is float span */ meosType spantype = T_FLOATSPAN; @@ -281,8 +332,11 @@ tbox_parse(const char **str) p_whitespace(str); } else - elog(ERROR, "Could not parse temporal box"); - + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Could not parse temporal box"); + return NULL; + } /* Determine whether the box has X and/or T dimensions */ if (pg_strncasecmp(*str, "XT", 2) == 0) { @@ -303,10 +357,14 @@ tbox_parse(const char **str) p_whitespace(str); } else - elog(ERROR, "Could not parse temporal box: Missing dimension information"); - + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Could not parse temporal box: Missing dimension information"); + return NULL; + } /* Parse opening parenthesis */ - ensure_oparen(str, "temporal box"); + if (! ensure_oparen(str, type_str)) + return NULL; if (hasx) { @@ -324,10 +382,10 @@ tbox_parse(const char **str) /* Parse closing parenthesis */ p_whitespace(str); - ensure_cparen(str, "temporal box"); - - /* Ensure there is no more input */ - ensure_end_input(str, true, "temporal box"); + if (! ensure_cparen(str, type_str) || + /* Ensure there is no more input */ + ! ensure_end_input(str, type_str)) + return NULL; return tbox_make(hasx ? &span: NULL, hast ? &period : NULL); } @@ -394,16 +452,17 @@ elem_parse(const char **str, meosType basetype) } /** - * @brief Parse a timestamp set value from the buffer. + * @brief Parse a set value from the buffer. */ Set * set_parse(const char **str, meosType settype) { - if (!p_obrace(str)) - elog(ERROR, "Could not parse set: Missing open brace"); + const char *type_str = "set"; + if (! ensure_obrace(str, type_str)) + return NULL; + meosType basetype = settype_basetype(settype); /* First parsing */ - meosType basetype = settype_basetype(settype); const char *bak = *str; elem_parse(str, basetype); int count = 1; @@ -412,9 +471,11 @@ set_parse(const char **str, meosType settype) count++; elem_parse(str, basetype); } - if (!p_cbrace(str)) - elog(ERROR, "Could not parse set: Missing closing brace"); + if (! ensure_cbrace(str, type_str) || + ! ensure_end_input(str, type_str)) + return NULL; + /* Second parsing */ *str = bak; Datum *values = palloc(sizeof(Datum) * count); for (int i = 0; i < count; i++) @@ -427,7 +488,7 @@ set_parse(const char **str, meosType settype) } /** - * @brief Parse a element value from the buffer + * @brief Parse a bound value from the buffer */ Datum bound_parse(const char **str, meosType basetype) @@ -458,8 +519,11 @@ span_parse(const char **str, meosType spantype, bool end, Span *span) else if (p_oparen(str)) lower_inc = false; else - elog(ERROR, "Could not parse span: Missing opening bracket/parenthesis"); - + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Could not parse span: Missing opening bracket/parenthesis"); + return; + } meosType basetype = spantype_basetype(spantype); /* The next two instructions will throw an exception if they fail */ Datum lower = bound_parse(str, basetype); @@ -471,10 +535,14 @@ span_parse(const char **str, meosType spantype, bool end, Span *span) else if (p_cparen(str)) upper_inc = false; else - elog(ERROR, "Could not parse span: Missing closing bracket/parenthesis"); - + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Could not parse span: Missing closing bracket/parenthesis"); + return; + } /* Ensure there is no more input */ - ensure_end_input(str, end, "span"); + if (end && ! ensure_end_input(str, "span")) + return; if (! span) return; @@ -488,10 +556,11 @@ span_parse(const char **str, meosType spantype, bool end, Span *span) SpanSet * spanset_parse(const char **str, meosType spansettype) { - if (! p_obrace(str)) - elog(ERROR, "Could not parse span set: Missing open brace"); - + const char *type_str = "span set"; + if (! ensure_obrace(str, type_str)) + return NULL; meosType spantype = spansettype_spantype(spansettype); + /* First parsing */ const char *bak = *str; span_parse(str, spantype, false, NULL); @@ -501,8 +570,8 @@ spanset_parse(const char **str, meosType spansettype) count++; span_parse(str, spantype, false, NULL); } - if (! p_cbrace(str)) - elog(ERROR, "Could not parse span set: Missing closing brace"); + if (! ensure_cbrace(str, type_str) || ! ensure_end_input(str, type_str)) + return NULL; /* Second parsing */ *str = bak; @@ -537,8 +606,7 @@ tinstant_parse(const char **str, meosType temptype, bool end, bool make) Datum elem = temporal_basetype_parse(str, basetype); TimestampTz t = timestamp_parse(str); /* Ensure there is no more input */ - ensure_end_input(str, end, "temporal"); - if (! make) + if ((end && ! ensure_end_input(str, "temporal")) || ! make) return NULL; return tinstant_make(elem, temptype, t); } @@ -551,6 +619,7 @@ tinstant_parse(const char **str, meosType temptype, bool end, bool make) TSequence * tdiscseq_parse(const char **str, meosType temptype) { + const char *type_str = "temporal"; p_whitespace(str); /* We are sure to find an opening brace because that was the condition * to call this function in the dispatch function temporal_parse */ @@ -565,10 +634,8 @@ tdiscseq_parse(const char **str, meosType temptype) count++; tinstant_parse(str, temptype, false, false); } - if (!p_cbrace(str)) - elog(ERROR, "Could not parse temporal value: Missing closing brace"); - /* Ensure there is no more input */ - ensure_end_input(str, true, "temporal"); + if (! ensure_cbrace(str, type_str) || ! ensure_end_input(str, type_str)) + return NULL; /* Second parsing */ *str = bak; @@ -619,10 +686,13 @@ tcontseq_parse(const char **str, meosType temptype, interpType interp, bool end, else if (p_cparen(str)) upper_inc = false; else - elog(ERROR, "Could not parse temporal value: Missing closing bracket/parenthesis"); + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Could not parse temporal value: Missing closing bracket/parenthesis"); + return NULL; + } /* Ensure there is no more input */ - ensure_end_input(str, end, "temporal"); - if (! make) + if ((end && ! ensure_end_input(str, "temporal")) || ! make) return NULL; /* Second parsing */ @@ -648,6 +718,7 @@ tcontseq_parse(const char **str, meosType temptype, interpType interp, bool end, TSequenceSet * tsequenceset_parse(const char **str, meosType temptype, interpType interp) { + const char *type_str = "temporal"; p_whitespace(str); /* We are sure to find an opening brace because that was the condition * to call this function in the dispatch function temporal_parse */ @@ -662,10 +733,8 @@ tsequenceset_parse(const char **str, meosType temptype, interpType interp) count++; tcontseq_parse(str, temptype, interp, false, false); } - if (!p_cbrace(str)) - elog(ERROR, "Could not parse temporal value: Missing closing brace"); - /* Ensure there is no more input */ - ensure_end_input(str, true, "temporal"); + if (! ensure_cbrace(str, type_str) || ! ensure_end_input(str, type_str)) + return NULL; /* Second parsing */ *str = bak; diff --git a/meos/src/general/type_util.c b/meos/src/general/type_util.c index 5ed112ea71..7cb3691151 100644 --- a/meos/src/general/type_util.c +++ b/meos/src/general/type_util.c @@ -36,6 +36,7 @@ /* C */ #include +#include /* PostgreSQL */ #include #include @@ -105,8 +106,9 @@ datum_cmp(Datum l, Datum r, meosType type) if (type == T_NPOINT) return npoint_cmp(DatumGetNpointP(l), DatumGetNpointP(r)); #endif - elog(ERROR, "unknown compare function for base type: %d", type); - return 0; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown compare function for base type: %d", type); + return INT_MAX; } /** @@ -141,8 +143,9 @@ datum_eq(Datum l, Datum r, meosType type) if (type == T_NPOINT) return npoint_eq(DatumGetNpointP(l), DatumGetNpointP(r)); #endif - elog(ERROR, "unknown datum_eq2 function for base type: %d", type); - return false; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown datum_eq2 function for base type: %d", type); + return false; } /** @@ -265,7 +268,8 @@ datum_add(Datum l, Datum r, meosType type) else if (type == T_FLOAT8) result = Float8GetDatum(DatumGetFloat8(l) + DatumGetFloat8(r)); else - elog(ERROR, "unknown add function for base type: %d", type); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown add function for base type: %d", type); return result; } @@ -283,7 +287,8 @@ datum_sub(Datum l, Datum r, meosType type) else if (type == T_FLOAT8) result = Float8GetDatum(DatumGetFloat8(l) - DatumGetFloat8(r)); else - elog(ERROR, "unknown sub function for base type: %d", type); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown sub function for base type: %d", type); return result; } @@ -301,7 +306,8 @@ datum_mult(Datum l, Datum r, meosType type) else if (type == T_FLOAT8) result = Float8GetDatum(DatumGetFloat8(l) * DatumGetFloat8(r)); else - elog(ERROR, "unknown mul function for base type: %d", type); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown mul function for base type: %d", type); return result; } @@ -311,7 +317,7 @@ datum_mult(Datum l, Datum r, meosType type) Datum datum_div(Datum l, Datum r, meosType type) { - Datum result; + Datum result = 0; if (type == T_INT4) result = Int32GetDatum(DatumGetInt32(l) / DatumGetInt32(r)); else if (type == T_INT8) @@ -319,7 +325,8 @@ datum_div(Datum l, Datum r, meosType type) else if (type == T_FLOAT8) result = Float8GetDatum(DatumGetFloat8(l) / DatumGetFloat8(r)); else - elog(ERROR, "unknown mul function for base type: %d", type); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown mul function for base type: %d", type); return result; } @@ -353,8 +360,9 @@ datum_hash(Datum d, meosType type) else if (type == T_NPOINT) return npoint_hash(DatumGetNpointP(d)); #endif - elog(ERROR, "unknown hash function for base type: %d", type); - return (uint32) 0; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown hash function for base type: %d", type); + return INT_MAX; } /** @@ -384,8 +392,9 @@ datum_hash_extended(Datum d, meosType type, uint64 seed) else if (type == T_NPOINT) return npoint_hash_extended(DatumGetNpointP(d), seed); #endif - elog(ERROR, "unknown extended hash function for base type: %d", type); - return (uint64) 0; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "unknown extended hash function for base type: %d", type); + return INT_MAX; } /***************************************************************************** @@ -615,6 +624,10 @@ bstring2bytea(const uint8_t *wkb, size_t size) text * cstring2text(const char *cstring) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) cstring)) + return NULL; + size_t len = strlen(cstring); text *result = palloc(len + VARHDRSZ); SET_VARSIZE(result, len + VARHDRSZ); @@ -631,6 +644,10 @@ cstring2text(const char *cstring) char * text2cstring(const text *textptr) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) textptr)) + return NULL; + size_t size = VARSIZE_ANY_EXHDR(textptr); char *str = palloc(size + 1); memcpy(str, VARDATA(textptr), size); @@ -906,8 +923,9 @@ basetype_in(const char *str, meosType basetype, bool end __attribute__((unused)) return PointerGetDatum(npoint_parse(&str, end)); #endif default: /* Error! */ - elog(ERROR, "Unknown base type: %d", basetype); - return Int32GetDatum(0); /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "Unknown base type: %d", basetype); + return Int32GetDatum(0); } } @@ -917,9 +935,8 @@ basetype_in(const char *str, meosType basetype, bool end __attribute__((unused)) char * basetype_out(Datum value, meosType basetype, int maxdd) { - /* Ensure validity of the arguments */ assert(meos_basetype(basetype)); - ensure_non_negative(maxdd); + assert(maxdd >= 0); switch (basetype) { @@ -950,16 +967,16 @@ basetype_out(Datum value, meosType basetype, int maxdd) return double4_out(DatumGetDouble4P(value), maxdd); #endif case T_GEOMETRY: - return gserialized_out(DatumGetGserializedP(value)); case T_GEOGRAPHY: - return gserialized_geog_out(DatumGetGserializedP(value)); + return gserialized_out(DatumGetGserializedP(value)); #if NPOINT case T_NPOINT: return npoint_out(DatumGetNpointP(value), maxdd); #endif default: /* Error! */ - elog(ERROR, "Unknown base type: %d", basetype); - return NULL; /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "Unknown base type: %d", basetype); + return NULL; } } diff --git a/meos/src/npoint/tnpoint.c b/meos/src/npoint/tnpoint.c index 118515a4ce..fa3245229a 100644 --- a/meos/src/npoint/tnpoint.c +++ b/meos/src/npoint/tnpoint.c @@ -36,6 +36,7 @@ /* C */ #include +#include /* MEOS */ #include #include @@ -105,12 +106,11 @@ tnpointcontseq_tgeompointcontseq(const TSequence *seq) inst = TSEQUENCE_INST_N(seq, i); np = DatumGetNpointP(tinstant_value(inst)); POINTARRAY *opa = lwline_interpolate_points(lwline, np->pos, 0); - LWGEOM *lwpoint; assert(opa->npoints <= 1); - lwpoint = lwpoint_as_lwgeom(lwpoint_construct(srid, NULL, opa)); + LWGEOM *lwpoint = lwpoint_as_lwgeom(lwpoint_construct(srid, NULL, opa)); Datum point = PointerGetDatum(geo_serialize(lwpoint)); instants[i] = tinstant_make(point, T_TGEOMPOINT, inst->t); - lwpoint_free((LWPOINT *) lwpoint); + lwgeom_free(lwpoint); pfree(DatumGetPointer(point)); } @@ -224,7 +224,9 @@ tgeompoint_tnpoint(const Temporal *temp) { int32_t srid_tpoint = tpoint_srid(temp); int32_t srid_ways = get_srid_ways(); - ensure_same_srid(srid_tpoint, srid_ways); + if (! ensure_same_srid(srid_tpoint, srid_ways)) + return NULL; + Temporal *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -402,8 +404,11 @@ int64 tnpoint_route(const Temporal *temp) { if ( temp->subtype != TINSTANT && MEOS_FLAGS_GET_DISCRETE(temp->flags) ) - elog(ERROR, "Input must be a temporal instant or a temporal sequence with continuous interpolation"); - + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Input must be a temporal instant or a temporal sequence with continuous interpolation"); + return INT_MAX; + } const TInstant *inst = (temp->subtype == TINSTANT) ? (const TInstant *) temp : TSEQUENCE_INST_N((const TSequence *) temp, 0); Npoint *np = DatumGetNpointP(tinstant_value(inst)); diff --git a/meos/src/npoint/tnpoint_distance.c b/meos/src/npoint/tnpoint_distance.c index de9f7604ec..86ff7c3f71 100644 --- a/meos/src/npoint/tnpoint_distance.c +++ b/meos/src/npoint/tnpoint_distance.c @@ -73,13 +73,15 @@ npoint_distance(Datum np1, Datum np2) * network point */ Temporal * -distance_tnpoint_geo(const Temporal *temp, const GSERIALIZED *geo) +distance_tnpoint_geo(const Temporal *temp, const GSERIALIZED *gs) { - if (gserialized_is_empty(geo)) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + gserialized_is_empty(gs) || ! ensure_point_type(gs)) return NULL; - ensure_point_type(geo); + Temporal *tempgeom = tnpoint_tgeompoint(temp); - Temporal *result = distance_tpoint_geo((const Temporal *) tempgeom, geo); + Temporal *result = distance_tpoint_geo((const Temporal *) tempgeom, gs); pfree(tempgeom); return result; } @@ -127,12 +129,12 @@ distance_tnpoint_tnpoint(const Temporal *temp1, const Temporal *temp2) * and the geometry */ TInstant * -nai_tnpoint_geo(const Temporal *temp, const GSERIALIZED *geo) +nai_tnpoint_geo(const Temporal *temp, const GSERIALIZED *gs) { - if (gserialized_is_empty(geo)) + if (gserialized_is_empty(gs)) return NULL; Temporal *tempgeom = tnpoint_tgeompoint(temp); - TInstant *resultgeom = nai_tpoint_geo(tempgeom, geo); + TInstant *resultgeom = nai_tpoint_geo(tempgeom, gs); /* We do not call the function tgeompointinst_tnpointinst to avoid * roundoff errors. The closest point may be at an exclusive bound. */ Datum value; @@ -191,13 +193,13 @@ nai_tnpoint_tnpoint(const Temporal *temp1, const Temporal *temp2) * and the geometry */ double -nad_tnpoint_geo(const Temporal *temp, const GSERIALIZED *geo) +nad_tnpoint_geo(const Temporal *temp, const GSERIALIZED *gs) { - if (gserialized_is_empty(geo)) + if (gserialized_is_empty(gs)) return -1; GSERIALIZED *traj = tnpoint_geom(temp); double result = DatumGetFloat8(geom_distance2d(PointerGetDatum(traj), - PointerGetDatum(geo))); + PointerGetDatum(gs))); pfree(traj); return result; } @@ -241,13 +243,13 @@ nad_tnpoint_tnpoint(const Temporal *temp1, const Temporal *temp2) * geometry and the temporal network point */ bool -shortestline_tnpoint_geo(const Temporal *temp, const GSERIALIZED *geo, +shortestline_tnpoint_geo(const Temporal *temp, const GSERIALIZED *gs, GSERIALIZED **result) { - if (gserialized_is_empty(geo)) + if (gserialized_is_empty(gs)) return false; GSERIALIZED *traj = tnpoint_geom(temp); - *result = gserialized_shortestline2d(traj, geo); + *result = gserialized_shortestline2d(traj, gs); pfree(traj); return true; } diff --git a/meos/src/npoint/tnpoint_parser.c b/meos/src/npoint/tnpoint_parser.c index f321ddb6ec..7d2e57a8f8 100644 --- a/meos/src/npoint/tnpoint_parser.c +++ b/meos/src/npoint/tnpoint_parser.c @@ -49,17 +49,21 @@ Npoint * npoint_parse(const char **str, bool end) { + const char *type_str = "network point"; p_whitespace(str); - if (pg_strncasecmp(*str, "NPOINT", 6) != 0) - elog(ERROR, "Could not parse network point"); + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Could not parse network point"); + return NULL; + } *str += 6; p_whitespace(str); - + /* Parse opening parenthesis */ - if (! p_oparen(str)) - elog(ERROR, "Could not parse network point: Missing opening parenthesis"); + if (! ensure_oparen(str, type_str)) + return NULL; /* Parse rid */ p_whitespace(str); @@ -68,15 +72,17 @@ npoint_parse(const char **str, bool end) p_whitespace(str); double pos = DatumGetFloat8(elem_parse(str, T_FLOAT8)); if (pos < 0 || pos > 1) - elog(ERROR, "The relative position must be a real number between 0 and 1"); + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "The relative position must be a real number between 0 and 1"); + return NULL; + } /* Parse closing parenthesis */ p_whitespace(str); - if (! p_cparen(str)) - elog(ERROR, "Could not parse network point: Missing closing parenthesis"); - - /* Ensure there is no more input */ - ensure_end_input(str, end, "network point"); + if (! ensure_cparen(str, type_str) || + (end && ! ensure_end_input(str, type_str))) + return NULL; return npoint_make(rid, pos); } @@ -87,17 +93,22 @@ npoint_parse(const char **str, bool end) Nsegment * nsegment_parse(const char **str) { + const char *type_str = "network segment"; p_whitespace(str); if (pg_strncasecmp(*str, "NSEGMENT", 8) != 0) - elog(ERROR, "Could not parse network segment"); + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Could not parse network segment"); + return NULL; + } *str += 8; p_whitespace(str); /* Parse opening parenthesis */ - if (! p_oparen(str)) - elog(ERROR, "Could not parse network point: Missing opening parenthesis"); + if (! ensure_oparen(str, type_str)) + return NULL; /* Parse rid */ p_whitespace(str); @@ -106,20 +117,25 @@ nsegment_parse(const char **str) p_whitespace(str); double pos1 = DatumGetFloat8(elem_parse(str, T_FLOAT8)); if (pos1 < 0 || pos1 > 1) - elog(ERROR, "The relative position must be a real number between 0 and 1"); + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "The relative position must be a real number between 0 and 1"); + return NULL; + } p_comma(str); p_whitespace(str); double pos2 = DatumGetFloat8(elem_parse(str, T_FLOAT8)); if (pos2 < 0 || pos2 > 1) - elog(ERROR, "The relative position must be a real number between 0 and 1"); + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "The relative position must be a real number between 0 and 1"); + return NULL; + } /* Parse closing parenthesis */ p_whitespace(str); - if (! p_cparen(str)) - elog(ERROR, "Could not parse network point: Missing closing parenthesis"); - - /* Ensure there is no more input */ - ensure_end_input(str, true, "network segment"); + if (! ensure_cparen(str, type_str) || ! ensure_end_input(str, type_str)) + return NULL; return nsegment_make(rid, pos1, pos2); } diff --git a/meos/src/npoint/tnpoint_spatialfuncs.c b/meos/src/npoint/tnpoint_spatialfuncs.c index f6635e0234..5b48436d4b 100644 --- a/meos/src/npoint/tnpoint_spatialfuncs.c +++ b/meos/src/npoint/tnpoint_spatialfuncs.c @@ -57,13 +57,16 @@ /** * @brief Ensure that a temporal network point and a STBox have the same SRID */ -void +bool ensure_same_srid_tnpoint_stbox(const Temporal *temp, const STBox *box) { - if (MEOS_FLAGS_GET_X(box->flags) && - tnpoint_srid(temp) != box->srid) - elog(ERROR, "The temporal network point and the box must be in the same SRID"); - return; + if (MEOS_FLAGS_GET_X(box->flags) && tnpoint_srid(temp) != box->srid) + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal network point and the box must be in the same SRID"); + return false; + } + return true; } #endif /* not used */ @@ -71,12 +74,16 @@ ensure_same_srid_tnpoint_stbox(const Temporal *temp, const STBox *box) * @brief Ensure that two temporal network point instants have the same route * identifier */ -void +bool ensure_same_rid_tnpointinst(const TInstant *inst1, const TInstant *inst2) { if (tnpointinst_route(inst1) != tnpointinst_route(inst2)) - elog(ERROR, "All network points composing a temporal sequence must have same route identifier"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "All network points composing a temporal sequence must have same route identifier"); + return false; + } + return true; } /***************************************************************************** @@ -768,21 +775,26 @@ tnpoint_azimuth(const Temporal *temp) * @brief Restrict a temporal network point to (the complement of) a geometry */ Temporal * -tnpoint_restrict_geom_time(const Temporal *temp, const GSERIALIZED *geo, +tnpoint_restrict_geom_time(const Temporal *temp, const GSERIALIZED *gs, const Span *zspan, const Span *period, bool atfunc) { - ensure_same_srid(tnpoint_srid(temp), gserialized_get_srid(geo)); - if (gserialized_is_empty(geo)) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_same_srid(tnpoint_srid(temp), gserialized_get_srid(gs))) + return NULL; + + if (gserialized_is_empty(gs)) { Temporal *result = atfunc ? NULL : temporal_copy(temp); if (atfunc) return NULL; return result; } - ensure_has_not_Z_gs(geo); + if (! ensure_has_not_Z_gs(gs)) + return NULL; Temporal *tempgeom = tnpoint_tgeompoint(temp); - Temporal *resultgeom = tpoint_restrict_geom_time(tempgeom, geo, zspan, + Temporal *resultgeom = tpoint_restrict_geom_time(tempgeom, gs, zspan, period, atfunc); Temporal *result = NULL; if (resultgeom != NULL) diff --git a/meos/src/npoint/tnpoint_spatialrels.c b/meos/src/npoint/tnpoint_spatialrels.c index fa9f82f9f3..a6c3d1629e 100644 --- a/meos/src/npoint/tnpoint_spatialrels.c +++ b/meos/src/npoint/tnpoint_spatialrels.c @@ -41,6 +41,8 @@ #include "npoint/tnpoint_spatialrels.h" +/* C */ +#include /* MEOS */ #include #include "general/lifting.h" @@ -95,7 +97,8 @@ int espatialrel_tnpoint_tnpoint(const Temporal *temp1, const Temporal *temp2, Datum (*func)(Datum, Datum)) { - ensure_same_srid(tnpoint_srid(temp1), tnpoint_srid(temp2)); + assert(tnpoint_srid(temp1) == tnpoint_srid(temp2)); + Temporal *sync1, *sync2; /* Return NULL if the temporal points do not intersect in time */ if (! intersection_temporal_temporal(temp1, temp2, SYNCHRONIZE_NOCROSS, @@ -179,7 +182,10 @@ int edwithin_tnpoint_tnpoint(const Temporal *temp1, const Temporal *temp2, double dist) { - ensure_same_srid(tnpoint_srid(temp1), tnpoint_srid(temp2)); + /* Ensure validity of the arguments */ + if (! ensure_same_srid(tnpoint_srid(temp1), tnpoint_srid(temp2))) + return -1; + Temporal *sync1, *sync2; /* Return -1 if the temporal points do not intersect in time */ if (! intersection_temporal_temporal(temp1, temp2, SYNCHRONIZE_NOCROSS, diff --git a/meos/src/npoint/tnpoint_static.c b/meos/src/npoint/tnpoint_static.c index a5f2f7309c..68e00a99ea 100644 --- a/meos/src/npoint/tnpoint_static.c +++ b/meos/src/npoint/tnpoint_static.c @@ -80,13 +80,19 @@ get_srid_ways() SPITupleTable *tuptable = SPI_tuptable; Datum value = SPI_getbinval(tuptable->vals[0], tuptable->tupdesc, 1, &isNull); if (isNull) - elog(ERROR, "Cannot determine SRID of the ways table"); - + { + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "Cannot determine SRID of the ways table"); + return SRID_INVALID; + } srid_ways = DatumGetInt32(value); } else - elog(ERROR, "Cannot determine SRID of the ways table"); - + { + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "Cannot determine SRID of the ways table"); + return SRID_INVALID; + } SPI_finish(); return srid_ways; } @@ -104,17 +110,17 @@ npointarr_geom(Npoint **points, int count) LWGEOM **geoms = palloc(sizeof(LWGEOM *) * count); for (int i = 0; i < count; i++) { - GSERIALIZED *line = route_geom(points[i]->rid); - int32_t srid = gserialized_get_srid(line); - LWGEOM *lwline = lwgeom_from_gserialized(line); - geoms[i] = lwgeom_line_interpolate_point(lwline, points[i]->pos, srid, 0); - pfree(line); pfree(lwline); + GSERIALIZED *gsline = route_geom(points[i]->rid); + int32_t srid = gserialized_get_srid(gsline); + LWGEOM *line = lwgeom_from_gserialized(gsline); + geoms[i] = lwgeom_line_interpolate_point(line, points[i]->pos, srid, 0); + pfree(gsline); pfree(line); } int newcount; LWGEOM **newgeoms = lwpointarr_remove_duplicates(geoms, count, &newcount); - LWGEOM *lwgeom = lwpointarr_make_trajectory(newgeoms, newcount, STEP); - GSERIALIZED *result = geo_serialize(lwgeom); - pfree(newgeoms); pfree(lwgeom); + LWGEOM *geom = lwpointarr_make_trajectory(newgeoms, newcount, STEP); + GSERIALIZED *result = geo_serialize(geom); + pfree(newgeoms); pfree(geom); pfree_array((void **) geoms, count); return result; } @@ -251,8 +257,8 @@ char * npoint_out(const Npoint *np, int maxdd) { /* Ensure validity of the arguments */ - assert(np != NULL); - ensure_non_negative(maxdd); + if (! ensure_not_null((void *) np) || ! ensure_non_negative(maxdd)) + return NULL; char *result = palloc(MAXNPOINTLEN); char *rid = int8_out(np->rid); @@ -280,8 +286,8 @@ char * nsegment_out(const Nsegment *ns, int maxdd) { /* Ensure validity of the arguments */ - assert(ns != NULL); - ensure_non_negative(maxdd); + if (! ensure_not_null((void *) ns) || ! ensure_non_negative(maxdd)) + return NULL; char *result = palloc(MAXNPOINTLEN); char *rid = int8_out(ns->rid); @@ -315,10 +321,17 @@ void npoint_set(int64 rid, double pos, Npoint *np) { if (!route_exists(rid)) - elog(ERROR, "There is no route with gid value %ld in table ways", rid); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "There is no route with gid value %ld in table ways", rid); + return; + } if (pos < 0 || pos > 1) - elog(ERROR, "The relative position must be a real number between 0 and 1"); - + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The relative position must be a real number between 0 and 1"); + return; + } /* Note: zero-fill is required here, just as in heap tuples */ memset(np, 0, sizeof(Npoint)); /* Fill in the network point */ @@ -345,10 +358,17 @@ void nsegment_set(int64 rid, double pos1, double pos2, Nsegment *ns) { if (! route_exists(rid)) - elog(ERROR, "There is no route with gid value %ld in table ways", rid); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "There is no route with gid value %ld in table ways", rid); + return; + } if (pos1 < 0 || pos1 > 1 || pos2 < 0 || pos2 > 1) - elog(ERROR, "The relative position of a network segment must be a real number between 0 and 1"); - + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The relative position of a network segment must be a real number between 0 and 1"); + return; + } ns->rid = rid; ns->pos1 = Min(pos1, pos2); ns->pos2 = Max(pos1, pos2); @@ -466,8 +486,11 @@ route_length(int64 rid) SPI_finish(); if (isNull) - elog(ERROR, "Cannot get the length for route %ld", rid); - + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Cannot get the length for route %ld", rid); + return 0; + } return result; } @@ -500,9 +523,14 @@ route_geom(int64 rid) SPI_finish(); if (isNull) - elog(ERROR, "Cannot get the geometry for route %ld", rid); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Cannot get the geometry for route %ld", rid); - ensure_non_empty(result); + if (! ensure_non_empty(result)) + { + pfree(result); + return NULL; + } return result; } @@ -531,7 +559,8 @@ rid_from_geom(Datum geom) } SPI_finish(); if (isNull) - elog(ERROR, "Cannot get route identifier from geometry point"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Cannot get route identifier from geometry point"); return result; } @@ -555,12 +584,14 @@ npoint_geom(const Npoint *np) Npoint * geom_npoint(const GSERIALIZED *gs) { - /* Ensure validity of operation */ - ensure_non_empty(gs); - ensure_point_type(gs); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs) || ! ensure_non_empty(gs) || + ! ensure_point_type(gs)) + return NULL; int32_t srid_geom = gserialized_get_srid(gs); int32_t srid_ways = get_srid_ways(); - ensure_same_srid(srid_geom, srid_ways); + if (srid_ways == SRID_INVALID || ! ensure_same_srid(srid_geom, srid_ways)) + return NULL; char *geomstr = ewkt_out(PointerGetDatum(gs), 0, OUT_DEFAULT_DECIMAL_DIGITS); char sql[512]; @@ -616,11 +647,13 @@ nsegment_geom(const Nsegment *ns) Nsegment * geom_nsegment(const GSERIALIZED *gs) { - /* Ensure validity of operation */ - ensure_non_empty(gs); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs) || ! ensure_non_empty(gs)) + return NULL; int geomtype = gserialized_get_type(gs); if (geomtype != POINTTYPE && geomtype != LINETYPE) - elog(ERROR, "Only point or line geometries accepted"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Only point or line geometries accepted"); Npoint **points; Npoint *np; diff --git a/meos/src/npoint/tnpoint_tempspatialrels.c b/meos/src/npoint/tnpoint_tempspatialrels.c index ddfb629fa9..9e29291b1c 100644 --- a/meos/src/npoint/tnpoint_tempspatialrels.c +++ b/meos/src/npoint/tnpoint_tempspatialrels.c @@ -56,14 +56,17 @@ Temporal * tinterrel_tnpoint_npoint(const Temporal *temp, const Npoint *np, bool tinter, bool restr, bool atvalue) { - ensure_same_srid(tnpoint_srid(temp), npoint_srid(np)); + /* Ensure validity of the arguments */ + if (! ensure_same_srid(tnpoint_srid(temp), npoint_srid(np))) + return NULL; + Temporal *tempgeom = tnpoint_tgeompoint(temp); - GSERIALIZED *geo = npoint_geom(np); + GSERIALIZED *gs = npoint_geom(np); /* Result depends on whether we are computing tintersects or tdisjoint */ - Temporal *result = tinterrel_tpoint_geo(tempgeom, geo, tinter, restr, + Temporal *result = tinterrel_tpoint_geo(tempgeom, gs, tinter, restr, atvalue); pfree(tempgeom); - pfree(geo); + pfree(gs); return result; } @@ -72,15 +75,18 @@ tinterrel_tnpoint_npoint(const Temporal *temp, const Npoint *np, bool tinter, * temporal network point and the geometry */ Temporal * -tinterrel_tnpoint_geo(const Temporal *temp, const GSERIALIZED *geo, bool tinter, +tinterrel_tnpoint_geo(const Temporal *temp, const GSERIALIZED *gs, bool tinter, bool restr, bool atvalue) { - if (gserialized_is_empty(geo)) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + gserialized_is_empty(gs) || + ! ensure_same_srid(tnpoint_srid(temp), gserialized_get_srid(gs))) return NULL; - ensure_same_srid(tnpoint_srid(temp), gserialized_get_srid(geo)); + Temporal *tempgeom = tnpoint_tgeompoint(temp); /* Result depends on whether we are computing tintersects or tdisjoint */ - Temporal *result = tinterrel_tpoint_geo(tempgeom, geo, tinter, restr, + Temporal *result = tinterrel_tpoint_geo(tempgeom, gs, tinter, restr, atvalue); pfree(tempgeom); return result; @@ -93,13 +99,13 @@ tinterrel_tnpoint_geo(const Temporal *temp, const GSERIALIZED *geo, bool tinter, * the temporal network point */ Temporal * -tcontains_geo_tnpoint(GSERIALIZED *geo, Temporal *temp, bool restr, +tcontains_geo_tnpoint(GSERIALIZED *gs, Temporal *temp, bool restr, bool atvalue) { - if (gserialized_is_empty(geo)) + if (gserialized_is_empty(gs)) return NULL; Temporal *tempgeom = tnpoint_tgeompoint(temp); - Temporal *result = tcontains_geo_tpoint(geo, tempgeom, restr, atvalue); + Temporal *result = tcontains_geo_tpoint(gs, tempgeom, restr, atvalue); pfree(tempgeom); return result; } @@ -109,15 +115,17 @@ tcontains_geo_tnpoint(GSERIALIZED *geo, Temporal *temp, bool restr, * point and the geometry */ Temporal * -ttouches_tnpoint_geo(const Temporal *temp, const GSERIALIZED *geo, bool restr, +ttouches_tnpoint_geo(const Temporal *temp, const GSERIALIZED *gs, bool restr, bool atvalue) { - if (gserialized_is_empty(geo)) + /* Ensure validity of the arguments */ + if (gserialized_is_empty(gs) || + ! ensure_same_srid(tnpoint_srid(temp), gserialized_get_srid(gs))) return NULL; - ensure_same_srid(tnpoint_srid(temp), gserialized_get_srid(geo)); + Temporal *tempgeom = tnpoint_tgeompoint(temp); /* Result depends on whether we are computing tintersects or tdisjoint */ - Temporal *result = ttouches_tpoint_geo(tempgeom, geo, restr, atvalue); + Temporal *result = ttouches_tpoint_geo(tempgeom, gs, restr, atvalue); pfree(tempgeom); return result; } @@ -127,10 +135,10 @@ ttouches_tnpoint_geo(const Temporal *temp, const GSERIALIZED *geo, bool restr, * point and the geometry */ Temporal * -ttouches_geo_tnpoint(const GSERIALIZED *geo, const Temporal *temp, bool restr, +ttouches_geo_tnpoint(const GSERIALIZED *gs, const Temporal *temp, bool restr, bool atvalue) { - return ttouches_tnpoint_geo(temp, geo, restr, atvalue); + return ttouches_tnpoint_geo(temp, gs, restr, atvalue); } /** @@ -141,13 +149,16 @@ Temporal * ttouches_tnpoint_npoint(const Temporal *temp, const Npoint *np, bool restr, bool atvalue) { - ensure_same_srid(tnpoint_srid(temp), npoint_srid(np)); + /* Ensure validity of the arguments */ + if (! ensure_same_srid(tnpoint_srid(temp), npoint_srid(np))) + return NULL; + Temporal *tempgeom = tnpoint_tgeompoint(temp); - GSERIALIZED *geo = npoint_geom(np); + GSERIALIZED *gs = npoint_geom(np); /* Result depends on whether we are computing tintersects or tdisjoint */ - Temporal *result = ttouches_tpoint_geo(tempgeom, geo, restr, atvalue); + Temporal *result = ttouches_tpoint_geo(tempgeom, gs, restr, atvalue); pfree(tempgeom); - pfree(geo); + pfree(gs); return result; } @@ -167,13 +178,13 @@ ttouches_npoint_tnpoint(const Npoint *np, const Temporal *temp, bool restr, * temporal network point are within the given distance */ Temporal * -tdwithin_tnpoint_geo(Temporal *temp, GSERIALIZED *geo, double dist, bool restr, +tdwithin_tnpoint_geo(Temporal *temp, GSERIALIZED *gs, double dist, bool restr, bool atvalue) { - if (gserialized_is_empty(geo)) + if (gserialized_is_empty(gs)) return NULL; Temporal *tempgeom = tnpoint_tgeompoint(temp); - Temporal *result = tdwithin_tpoint_geo(tempgeom, geo, dist, restr, atvalue); + Temporal *result = tdwithin_tpoint_geo(tempgeom, gs, dist, restr, atvalue); pfree(tempgeom); return result; } @@ -183,10 +194,10 @@ tdwithin_tnpoint_geo(Temporal *temp, GSERIALIZED *geo, double dist, bool restr, * temporal network point are within the given distance */ Temporal * -tdwithin_geo_tnpoint(GSERIALIZED *geo, Temporal *temp, double dist, bool restr, +tdwithin_geo_tnpoint(GSERIALIZED *gs, Temporal *temp, double dist, bool restr, bool atvalue) { - return tdwithin_tnpoint_geo(temp, geo, dist, restr, atvalue); + return tdwithin_tnpoint_geo(temp, gs, dist, restr, atvalue); } /** diff --git a/meos/src/point/CMakeLists.txt b/meos/src/point/CMakeLists.txt index 3b04beb37f..75973c5720 100644 --- a/meos/src/point/CMakeLists.txt +++ b/meos/src/point/CMakeLists.txt @@ -16,6 +16,3 @@ add_library(point OBJECT tpoint_tile.c ) -add_library(point_meos OBJECT - tpoint_meos.c -) diff --git a/meos/src/point/geography_functions.c b/meos/src/point/geography_functions.c index ff1f9e95df..a26b824342 100644 --- a/meos/src/point/geography_functions.c +++ b/meos/src/point/geography_functions.c @@ -107,14 +107,14 @@ geography_tree_shortestline(const GSERIALIZED* g1, const GSERIALIZED* g2, * second input geography in 2D */ GSERIALIZED * -geography_shortestline_internal(const GSERIALIZED *g1, const GSERIALIZED *g2, +geography_shortestline_internal(const GSERIALIZED *gs1, const GSERIALIZED *gs2, bool use_spheroid) { SPHEROID s; - ensure_same_srid(gserialized_get_srid(g1), gserialized_get_srid(g2)); + assert(gserialized_get_srid(gs1) == gserialized_get_srid(gs2)); /* Return NULL on empty arguments. */ - if ( gserialized_is_empty(g1) || gserialized_is_empty(g2) ) + if ( gserialized_is_empty(gs1) || gserialized_is_empty(gs2) ) return NULL; /* Initialize spheroid */ @@ -127,7 +127,7 @@ geography_shortestline_internal(const GSERIALIZED *g1, const GSERIALIZED *g2, if ( ! use_spheroid ) s.a = s.b = s.radius; - LWGEOM *line = geography_tree_shortestline(g1, g2, FP_TOLERANCE, &s); + LWGEOM *line = geography_tree_shortestline(gs1, gs2, FP_TOLERANCE, &s); #if ! MEOS GSERIALIZED *result = geography_serialize(line); diff --git a/meos/src/point/pgis_call.c b/meos/src/point/pgis_call.c index d4d6c4b9d9..86352f6379 100644 --- a/meos/src/point/pgis_call.c +++ b/meos/src/point/pgis_call.c @@ -72,7 +72,7 @@ void srid_check_latlong(int32_t srid); #endif GSERIALIZED * -gserialized_geography_from_lwgeom(LWGEOM *lwgeom, int32 geog_typmod); +gserialized_geography_from_lwgeom(LWGEOM *geom, int32 geog_typmod); /***************************************************************************** * Functions adapted from lwgeom_box.c @@ -427,21 +427,21 @@ lwgeom_boundary(LWGEOM *lwgeom) * @note PostGIS function: boundary(PG_FUNCTION_ARGS) */ GSERIALIZED * -gserialized_boundary(const GSERIALIZED *geom1) +gserialized_boundary(const GSERIALIZED *gs) { /* Empty.Boundary() == Empty, but of other dimension, so can't shortcut */ - LWGEOM *lwgeom = lwgeom_from_gserialized(geom1); - LWGEOM *lwresult = lwgeom_boundary(lwgeom); + LWGEOM *geom = lwgeom_from_gserialized(gs); + LWGEOM *lwresult = lwgeom_boundary(geom); if (! lwresult) { - lwgeom_free(lwgeom); + lwgeom_free(geom); return NULL; } GSERIALIZED *result = geo_serialize(lwresult); - lwgeom_free(lwgeom); + lwgeom_free(geom); lwgeom_free(lwresult); return result; @@ -452,19 +452,20 @@ gserialized_boundary(const GSERIALIZED *geom1) * @note PostGIS function: LWGEOM_shortestline2d(PG_FUNCTION_ARGS) */ GSERIALIZED * -gserialized_shortestline2d(const GSERIALIZED *geom1, const GSERIALIZED *geom2) +gserialized_shortestline2d(const GSERIALIZED *gs1, const GSERIALIZED *gs2) { - ensure_same_srid(gserialized_get_srid(geom1), gserialized_get_srid(geom2)); - LWGEOM *lwgeom1 = lwgeom_from_gserialized(geom1); - LWGEOM *lwgeom2 = lwgeom_from_gserialized(geom2); - LWGEOM *theline = lwgeom_closest_line(lwgeom1, lwgeom2); - if (lwgeom_is_empty(theline)) + assert(gserialized_get_srid(gs1) == gserialized_get_srid(gs2)); + + LWGEOM *geom1 = lwgeom_from_gserialized(gs1); + LWGEOM *geom2 = lwgeom_from_gserialized(gs2); + LWGEOM *line = lwgeom_closest_line(geom1, geom2); + if (lwgeom_is_empty(line)) return NULL; - GSERIALIZED *result = geo_serialize(theline); - lwgeom_free(theline); - lwgeom_free(lwgeom1); - lwgeom_free(lwgeom2); + GSERIALIZED *result = geo_serialize(line); + lwgeom_free(line); + lwgeom_free(geom1); + lwgeom_free(geom2); return result; } @@ -473,19 +474,20 @@ gserialized_shortestline2d(const GSERIALIZED *geom1, const GSERIALIZED *geom2) * @note PostGIS function: LWGEOM_shortestline3d(PG_FUNCTION_ARGS) */ GSERIALIZED * -gserialized_shortestline3d(const GSERIALIZED *geom1, const GSERIALIZED *geom2) +gserialized_shortestline3d(const GSERIALIZED *gs1, const GSERIALIZED *gs2) { - ensure_same_srid(gserialized_get_srid(geom1), gserialized_get_srid(geom2)); - LWGEOM *lwgeom1 = lwgeom_from_gserialized(geom1); - LWGEOM *lwgeom2 = lwgeom_from_gserialized(geom2); - LWGEOM *theline = lwgeom_closest_line_3d(lwgeom1, lwgeom2); - if (lwgeom_is_empty(theline)) + assert(gserialized_get_srid(gs1) == gserialized_get_srid(gs2)); + + LWGEOM *geom1 = lwgeom_from_gserialized(gs1); + LWGEOM *geom2 = lwgeom_from_gserialized(gs2); + LWGEOM *line = lwgeom_closest_line_3d(geom1, geom2); + if (lwgeom_is_empty(line)) return NULL; - GSERIALIZED *result = geo_serialize(theline); - lwgeom_free(theline); - lwgeom_free(lwgeom1); - lwgeom_free(lwgeom2); + GSERIALIZED *result = geo_serialize(line); + lwgeom_free(line); + lwgeom_free(geom1); + lwgeom_free(geom2); return result; } @@ -494,14 +496,15 @@ gserialized_shortestline3d(const GSERIALIZED *geom1, const GSERIALIZED *geom2) * @note PostGIS function: ST_Distance(PG_FUNCTION_ARGS) */ double -gserialized_distance(const GSERIALIZED *geom1, const GSERIALIZED *geom2) +gserialized_distance(const GSERIALIZED *gs1, const GSERIALIZED *gs2) { - ensure_same_srid(gserialized_get_srid(geom1), gserialized_get_srid(geom2)); - LWGEOM *lwgeom1 = lwgeom_from_gserialized(geom1); - LWGEOM *lwgeom2 = lwgeom_from_gserialized(geom2); - double mindist = lwgeom_mindistance2d(lwgeom1, lwgeom2); - lwgeom_free(lwgeom1); - lwgeom_free(lwgeom2); + assert(gserialized_get_srid(gs1) == gserialized_get_srid(gs2)); + + LWGEOM *geom1 = lwgeom_from_gserialized(gs1); + LWGEOM *geom2 = lwgeom_from_gserialized(gs2); + double mindist = lwgeom_mindistance2d(geom1, geom2); + lwgeom_free(geom1); + lwgeom_free(geom2); /* if called with empty geometries the ingoing mindistance is untouched, * and makes us return NULL */ if (mindist < FLT_MAX) @@ -514,14 +517,15 @@ gserialized_distance(const GSERIALIZED *geom1, const GSERIALIZED *geom2) * @note PostGIS function: ST_3DDistance(PG_FUNCTION_ARGS) */ double -gserialized_3Ddistance(const GSERIALIZED *geom1, const GSERIALIZED *geom2) +gserialized_3Ddistance(const GSERIALIZED *gs1, const GSERIALIZED *gs2) { - ensure_same_srid(gserialized_get_srid(geom1), gserialized_get_srid(geom2)); - LWGEOM *lwgeom1 = lwgeom_from_gserialized(geom1); - LWGEOM *lwgeom2 = lwgeom_from_gserialized(geom2); - double mindist = lwgeom_mindistance3d(lwgeom1, lwgeom2); - lwgeom_free(lwgeom1); - lwgeom_free(lwgeom2); + assert(gserialized_get_srid(gs1) == gserialized_get_srid(gs2)); + + LWGEOM *geom1 = lwgeom_from_gserialized(gs1); + LWGEOM *geom2 = lwgeom_from_gserialized(gs2); + double mindist = lwgeom_mindistance3d(geom1, geom2); + lwgeom_free(geom1); + lwgeom_free(geom2); /* if called with empty geometries the ingoing mindistance is untouched, * and makes us return NULL */ if (mindist < FLT_MAX) @@ -534,15 +538,16 @@ gserialized_3Ddistance(const GSERIALIZED *geom1, const GSERIALIZED *geom2) * @note PostGIS function: ST_3DIntersects(PG_FUNCTION_ARGS) */ bool -gserialized_3Dintersects(const GSERIALIZED *geom1, const GSERIALIZED *geom2) +gserialized_3Dintersects(const GSERIALIZED *gs1, const GSERIALIZED *gs2) { - ensure_same_srid(gserialized_get_srid(geom1), gserialized_get_srid(geom2)); - LWGEOM *lwgeom1 = lwgeom_from_gserialized(geom1); - LWGEOM *lwgeom2 = lwgeom_from_gserialized(geom2); - double mindist = lwgeom_mindistance3d_tolerance(lwgeom1, lwgeom2, 0.0); + assert(gserialized_get_srid(gs1) == gserialized_get_srid(gs2)); + + LWGEOM *geom1 = lwgeom_from_gserialized(gs1); + LWGEOM *geom2 = lwgeom_from_gserialized(gs2); + double mindist = lwgeom_mindistance3d_tolerance(geom1, geom2, 0.0); /* empty geometries cases should be right handled since return from underlying functions should be FLT_MAX which causes false as answer */ - return (0.0 == mindist); + return (mindist == 0.0); } /** @@ -550,19 +555,17 @@ gserialized_3Dintersects(const GSERIALIZED *geom1, const GSERIALIZED *geom2) * @note PostGIS function: LWGEOM_dwithin(PG_FUNCTION_ARGS) */ bool -gserialized_dwithin(const GSERIALIZED *geom1, const GSERIALIZED *geom2, +gserialized_dwithin(const GSERIALIZED *gs1, const GSERIALIZED *gs2, double tolerance) { - if (tolerance < 0) - elog(ERROR, "Tolerance cannot be less than zero\n"); - ensure_same_srid(gserialized_get_srid(geom1), gserialized_get_srid(geom2)); - - if (gserialized_is_empty(geom1) || gserialized_is_empty(geom2)) + if (! ensure_positive_datum(Float8GetDatum(tolerance), T_FLOAT8) || + ! ensure_same_srid(gserialized_get_srid(gs1), gserialized_get_srid(gs2)) || + gserialized_is_empty(gs1) || gserialized_is_empty(gs2)) return false; - LWGEOM *lwgeom1 = lwgeom_from_gserialized(geom1); - LWGEOM *lwgeom2 = lwgeom_from_gserialized(geom2); - double mindist = lwgeom_mindistance2d_tolerance(lwgeom1, lwgeom2, tolerance); + LWGEOM *geom1 = lwgeom_from_gserialized(gs1); + LWGEOM *geom2 = lwgeom_from_gserialized(gs2); + double mindist = lwgeom_mindistance2d_tolerance(geom1, geom2, tolerance); /*empty geometries cases should be right handled since return from underlying functions should be FLT_MAX which causes false as answer*/ return (tolerance >= mindist); @@ -573,18 +576,16 @@ gserialized_dwithin(const GSERIALIZED *geom1, const GSERIALIZED *geom2, * @note PostGIS function: LWGEOM_dwithin3d(PG_FUNCTION_ARGS) */ bool -gserialized_dwithin3d(const GSERIALIZED *geom1, const GSERIALIZED *geom2, +gserialized_dwithin3d(const GSERIALIZED *gs1, const GSERIALIZED *gs2, double tolerance) { - if (tolerance < 0) - elog(ERROR, "Tolerance cannot be less than zero\n"); - ensure_same_srid(gserialized_get_srid(geom1), gserialized_get_srid(geom2)); - - LWGEOM *lwgeom1 = lwgeom_from_gserialized(geom1); - LWGEOM *lwgeom2 = lwgeom_from_gserialized(geom2); - - double mindist = lwgeom_mindistance3d_tolerance(lwgeom1, lwgeom2, tolerance); + if (! ensure_positive_datum(Float8GetDatum(tolerance), T_FLOAT8) || + ! ensure_same_srid(gserialized_get_srid(gs1), gserialized_get_srid(gs2))) + return false; + LWGEOM *geom1 = lwgeom_from_gserialized(gs1); + LWGEOM *geom2 = lwgeom_from_gserialized(gs2); + double mindist = lwgeom_mindistance3d_tolerance(geom1, geom2, tolerance); /*empty geometries cases should be right handled since return from underlying functions should be FLT_MAX which causes false as answer*/ return (tolerance >= mindist); @@ -595,11 +596,11 @@ gserialized_dwithin3d(const GSERIALIZED *geom1, const GSERIALIZED *geom2, * @note PostGIS function: LWGEOM_reverse(PG_FUNCTION_ARGS) */ GSERIALIZED * -gserialized_reverse(const GSERIALIZED *geom) +gserialized_reverse(const GSERIALIZED *gs) { - LWGEOM *lwgeom = lwgeom_from_gserialized(geom); - lwgeom_reverse_in_place(lwgeom); - GSERIALIZED *result = geo_serialize(lwgeom); + LWGEOM *geom = lwgeom_from_gserialized(gs); + lwgeom_reverse_in_place(geom); + GSERIALIZED *result = geo_serialize(geom); return result; } @@ -609,45 +610,49 @@ gserialized_reverse(const GSERIALIZED *geom) * @return NULL on exception (same point). Return radians otherwise. */ bool -gserialized_azimuth(GSERIALIZED *geom1, GSERIALIZED *geom2, double *result) +gserialized_azimuth(GSERIALIZED *gs1, GSERIALIZED *gs2, double *result) { - LWPOINT *lwpoint; + LWPOINT *point; POINT2D p1, p2; int32_t srid; /* Extract first point */ - lwpoint = lwgeom_as_lwpoint(lwgeom_from_gserialized(geom1)); - if (!lwpoint) + point = lwgeom_as_lwpoint(lwgeom_from_gserialized(gs1)); + if (! point) { - elog(ERROR, "Argument must be POINT geometries"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Arguments must be point geometries"); return false; } - srid = lwpoint->srid; - if (!getPoint2d_p(lwpoint->point, 0, &p1)) + srid = point->srid; + if (!getPoint2d_p(point->point, 0, &p1)) { - elog(ERROR, "Error extracting point"); + meos_error(ERROR, MEOS_ERR_INTERNAL_ERROR, "Error extracting point"); return false; } - lwpoint_free(lwpoint); + lwpoint_free(point); /* Extract second point */ - lwpoint = lwgeom_as_lwpoint(lwgeom_from_gserialized(geom2)); - if (!lwpoint) + point = lwgeom_as_lwpoint(lwgeom_from_gserialized(gs2)); + if (! point) { - elog(ERROR, "Argument must be POINT geometries"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Arguments must be point geometries"); return false; } - if (lwpoint->srid != srid) + if (point->srid != srid) { - elog(ERROR, "Operation on mixed SRID geometries"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Operation on mixed SRID geometries"); return false; } - if (!getPoint2d_p(lwpoint->point, 0, &p2)) + if (! getPoint2d_p(point->point, 0, &p2)) { - elog(ERROR, "Error extracting point"); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "Error extracting point"); return false; } - lwpoint_free(lwpoint); + lwpoint_free(point); /* Standard return value for equality case */ if ((p1.x == p2.x) && (p1.y == p2.y)) @@ -656,10 +661,8 @@ gserialized_azimuth(GSERIALIZED *geom1, GSERIALIZED *geom2, double *result) } /* Compute azimuth */ - if (!azimuth_pt_pt(&p1, &p2, result)) - { + if (! azimuth_pt_pt(&p1, &p2, result)) return false; - } return true; } @@ -669,16 +672,16 @@ gserialized_azimuth(GSERIALIZED *geom1, GSERIALIZED *geom2, double *result) *****************************************************************************/ static char -gserialized_is_point(const GSERIALIZED* g) +gserialized_is_point(const GSERIALIZED* gs) { - int type = gserialized_get_type(g); + int type = gserialized_get_type(gs); return (type == POINTTYPE || type == MULTIPOINTTYPE); } static char -gserialized_is_poly(const GSERIALIZED* g) +gserialized_is_poly(const GSERIALIZED* gs) { - int type = gserialized_get_type(g); + int type = gserialized_get_type(gs); return (type == POLYGONTYPE || type == MULTIPOLYGONTYPE); } @@ -689,11 +692,11 @@ gserialized_is_poly(const GSERIALIZED* g) * the cache */ static int -meos_point_in_polygon(const GSERIALIZED *geom1, const GSERIALIZED *geom2, +meos_point_in_polygon(const GSERIALIZED *gs1, const GSERIALIZED *gs2, bool inter) { - const GSERIALIZED *gpoly = gserialized_is_poly(geom1) ? geom1 : geom2; - const GSERIALIZED *gpoint = gserialized_is_point(geom1) ? geom1 : geom2; + const GSERIALIZED *gpoly = gserialized_is_poly(gs1) ? gs1 : gs2; + const GSERIALIZED *gpoint = gserialized_is_point(gs1) ? gs1 : gs2; LWGEOM *poly = lwgeom_from_gserialized(gpoly); int32 polytype = lwgeom_get_type(poly); @@ -740,19 +743,19 @@ meos_point_in_polygon(const GSERIALIZED *geom1, const GSERIALIZED *geom2, } GEOSGeometry * -POSTGIS2GEOS(const GSERIALIZED *pglwgeom) +POSTGIS2GEOS(const GSERIALIZED *gs) { - GEOSGeometry *ret; - LWGEOM *lwgeom = lwgeom_from_gserialized(pglwgeom); + GEOSGeometry *result; + LWGEOM *lwgeom = lwgeom_from_gserialized(gs); if ( ! lwgeom ) { - elog(ERROR, "POSTGIS2GEOS: unable to deserialize input"); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "POSTGIS2GEOS: unable to deserialize input"); return NULL; } - ret = LWGEOM2GEOS(lwgeom, 0); + result = LWGEOM2GEOS(lwgeom, 0); lwgeom_free(lwgeom); - - return ret; + return result; } GSERIALIZED * @@ -764,7 +767,8 @@ GEOS2POSTGIS(GEOSGeom geom, char want3d) lwgeom = GEOS2LWGEOM(geom, want3d); if ( ! lwgeom ) { - elog(ERROR, "GEOS2LWGEOM returned NULL"); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "GEOS2LWGEOM returned NULL"); return NULL; } @@ -781,28 +785,35 @@ GEOS2POSTGIS(GEOSGeom geom, char want3d) * call the GEOS function passed as argument */ static char -meos_call_geos2(const GSERIALIZED *geom1, const GSERIALIZED *geom2, - char (*func)(const GEOSGeometry *g1, const GEOSGeometry *g2)) +meos_call_geos2(const GSERIALIZED *gs1, const GSERIALIZED *gs2, + char (*func)(const GEOSGeometry *geos1, const GEOSGeometry *geos2)) { initGEOS(lwnotice, lwgeom_geos_error); - GEOSGeometry *g1 = POSTGIS2GEOS(geom1); - if (!g1) - elog(ERROR, "First argument geometry could not be converted to GEOS"); - GEOSGeometry *g2 = POSTGIS2GEOS(geom2); - if (!g2) + GEOSGeometry *geos1 = POSTGIS2GEOS(gs1); + if (! geos1) + { + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "First argument geometry could not be converted to GEOS"); + return 2; + } + GEOSGeometry *geos2 = POSTGIS2GEOS(gs2); + if (! geos2) { - GEOSGeom_destroy(g1); - elog(ERROR, "Second argument geometry could not be converted to GEOS"); + GEOSGeom_destroy(geos1); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "Second argument geometry could not be converted to GEOS"); + return 2; } - char result = func(g1, g2); + char result = func(geos1, geos2); - GEOSGeom_destroy(g1); - GEOSGeom_destroy(g2); + GEOSGeom_destroy(geos1); + GEOSGeom_destroy(geos2); if (result == 2) - elog(ERROR, "GEOS returned error"); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "GEOS returned error"); return result; } @@ -810,28 +821,28 @@ meos_call_geos2(const GSERIALIZED *geom1, const GSERIALIZED *geom2, /** * @brief Return true if the geometries intersect or the first contains * the other, where the function called depend on the third argument - * @param[in] geom1,geom2 Geometries + * @param[in] gs1,gs2 Geometries * @param[in] rel Spatial relationship * @note PostGIS functions: ST_Intersects(PG_FUNCTION_ARGS), * contains(PG_FUNCTION_ARGS), touches(PG_FUNCTION_ARGS) */ bool -gserialized_spatialrel(const GSERIALIZED *geom1, const GSERIALIZED *geom2, +gserialized_spatialrel(const GSERIALIZED *gs1, const GSERIALIZED *gs2, spatialRel rel) { - ensure_same_srid(gserialized_get_srid(geom1), gserialized_get_srid(geom2)); + assert(gserialized_get_srid(gs1) == gserialized_get_srid(gs2)); /* A.Intersects(Empty) == FALSE */ - if ( gserialized_is_empty(geom1) || gserialized_is_empty(geom2) ) + if ( gserialized_is_empty(gs1) || gserialized_is_empty(gs2) ) return false; /* - * short-circuit 1: if geom2 bounding box does not overlap - * geom1 bounding box we can return FALSE. + * short-circuit 1: if gs2 bounding box does not overlap + * gs1 bounding box we can return FALSE. */ GBOX box1, box2; - if (gserialized_get_gbox_p(geom1, &box1) && - gserialized_get_gbox_p(geom2, &box2)) + if (gserialized_get_gbox_p(gs1, &box1) && + gserialized_get_gbox_p(gs2, &box2)) { if (gbox_overlaps_2d(&box1, &box2) == LW_FALSE) return false; @@ -842,10 +853,10 @@ gserialized_spatialrel(const GSERIALIZED *geom1, const GSERIALIZED *geom2, * call the point_outside_polygon function. */ if ((rel == INTERSECTS || rel == CONTAINS) && ( - (gserialized_is_point(geom1) && gserialized_is_poly(geom2)) || - (gserialized_is_poly(geom1) && gserialized_is_point(geom2)))) + (gserialized_is_point(gs1) && gserialized_is_poly(gs2)) || + (gserialized_is_poly(gs1) && gserialized_is_point(gs2)))) { - int pip_result = meos_point_in_polygon(geom1, geom2, rel == INTERSECTS); + int pip_result = meos_point_in_polygon(gs1, gs2, rel == INTERSECTS); return (rel == INTERSECTS) ? (pip_result != -1) : /* not outside */ (pip_result == 1); /* inside */ @@ -856,11 +867,11 @@ gserialized_spatialrel(const GSERIALIZED *geom1, const GSERIALIZED *geom2, switch (rel) { case INTERSECTS: - return (bool) meos_call_geos2(geom1, geom2, &GEOSIntersects); + return (bool) meos_call_geos2(gs1, gs2, &GEOSIntersects); case CONTAINS: - return (bool) meos_call_geos2(geom1, geom2, &GEOSContains); + return (bool) meos_call_geos2(gs1, gs2, &GEOSContains); case TOUCHES: - return (bool) meos_call_geos2(geom1, geom2, &GEOSTouches); + return (bool) meos_call_geos2(gs1, gs2, &GEOSTouches); default: /* keep compiler quiet */ return false; @@ -872,23 +883,29 @@ gserialized_spatialrel(const GSERIALIZED *geom1, const GSERIALIZED *geom2, * @note PostGIS function: relate_pattern(PG_FUNCTION_ARGS) */ bool -gserialized_relate_pattern(const GSERIALIZED *geom1, const GSERIALIZED *geom2, +gserialized_relate_pattern(const GSERIALIZED *gs1, const GSERIALIZED *gs2, char *patt) { - ensure_same_srid(gserialized_get_srid(geom1), gserialized_get_srid(geom2)); + assert(gserialized_get_srid(gs1) == gserialized_get_srid(gs2)); /* TODO handle empty */ initGEOS(lwnotice, lwgeom_geos_error); - GEOSGeometry *g1 = POSTGIS2GEOS(geom1); - if (!g1) - elog(ERROR, "First argument geometry could not be converted to GEOS"); - GEOSGeometry *g2 = POSTGIS2GEOS(geom2); - if (!g2) + GEOSGeometry *geos1 = POSTGIS2GEOS(gs1); + if (!geos1) + { + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "First argument geometry could not be converted to GEOS"); + return false; + } + GEOSGeometry *geos2 = POSTGIS2GEOS(gs2); + if (!geos2) { - GEOSGeom_destroy(g1); - elog(ERROR, "Second argument geometry could not be converted to GEOS"); + GEOSGeom_destroy(geos1); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "Second argument geometry could not be converted to GEOS"); + return false; } /* @@ -900,12 +917,13 @@ gserialized_relate_pattern(const GSERIALIZED *geom1, const GSERIALIZED *geom2, if ( patt[i] == 'f' ) patt[i] = 'F'; } - char result = GEOSRelatePattern(g1, g2, patt); - GEOSGeom_destroy(g1); - GEOSGeom_destroy(g2); + char result = GEOSRelatePattern(geos1, geos2, patt); + GEOSGeom_destroy(geos1); + GEOSGeom_destroy(geos2); if (result == 2) - elog(ERROR, "GEOSRelatePattern returned error"); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "GEOSRelatePattern returned error"); return (bool) result; } @@ -916,17 +934,17 @@ gserialized_relate_pattern(const GSERIALIZED *geom1, const GSERIALIZED *geom2, * @note With respect to the original function we do not use the prec argument */ GSERIALIZED * -gserialized_intersection(const GSERIALIZED *geom1, const GSERIALIZED *geom2) +gserialized_intersection(const GSERIALIZED *gs1, const GSERIALIZED *gs2) { GSERIALIZED *result; - LWGEOM *lwgeom1, *lwgeom2, *lwresult; + LWGEOM *geom1, *geom2, *lwresult; double prec = -1; - lwgeom1 = lwgeom_from_gserialized(geom1); - lwgeom2 = lwgeom_from_gserialized(geom2); - lwresult = lwgeom_intersection_prec(lwgeom1, lwgeom2, prec); + geom1 = lwgeom_from_gserialized(gs1); + geom2 = lwgeom_from_gserialized(gs2); + lwresult = lwgeom_intersection_prec(geom1, geom2, prec); result = geo_serialize(lwresult); - lwgeom_free(lwgeom1); - lwgeom_free(lwgeom2); + lwgeom_free(geom1); + lwgeom_free(geom2); lwgeom_free(lwresult); return result; } @@ -952,7 +970,7 @@ gserialized_array_union(GSERIALIZED **gsarr, int nelems) int curgeom = 0; uint8_t empty_type = 0; int32_t srid = SRID_UNKNOWN; - GSERIALIZED *gser_out = NULL; + GSERIALIZED *result = NULL; GEOSGeometry *g = NULL; GEOSGeometry *g_union = NULL; @@ -969,7 +987,7 @@ gserialized_array_union(GSERIALIZED **gsarr, int nelems) { /* Check for SRID mismatch in array elements */ if (gotsrid) - ensure_same_srid(gserialized_get_srid(gsarr[i]), srid); + assert(gserialized_get_srid(gsarr[i]) == srid); else { /* Initialize SRID/dimensions info */ @@ -991,7 +1009,11 @@ gserialized_array_union(GSERIALIZED **gsarr, int nelems) /* Uh oh! Exception thrown at construction... */ if (! g) - elog(ERROR, "One of the geometries in the set could not be converted to GEOS"); + { + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "One of the geometries in the set could not be converted to GEOS"); + return NULL; + } geoms[curgeom++] = g; } @@ -1005,15 +1027,22 @@ gserialized_array_union(GSERIALIZED **gsarr, int nelems) { g = GEOSGeom_createCollection(GEOS_GEOMETRYCOLLECTION, geoms, curgeom); if (! g) - elog(ERROR, "Could not create GEOS COLLECTION from geometry array"); + { + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "Could not create GEOS COLLECTION from geometry array"); + return NULL; + } g_union = GEOSUnaryUnion(g); GEOSGeom_destroy(g); if (! g_union) - elog(ERROR, "GEOSUnaryUnion"); + { + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, "GEOSUnaryUnion"); + return NULL; + } GEOSSetSRID(g_union, srid); - gser_out = GEOS2POSTGIS(g_union, is3d); + result = GEOS2POSTGIS(g_union, is3d); GEOSGeom_destroy(g_union); } /* No real geometries in our array, any empties? */ @@ -1028,11 +1057,11 @@ gserialized_array_union(GSERIALIZED **gsarr, int nelems) return NULL; } - if (! gser_out) + if (! result) /* Union returned a NULL geometry */ return NULL; - return gser_out; + return result; } /** @@ -1041,40 +1070,49 @@ gserialized_array_union(GSERIALIZED **gsarr, int nelems) * @note With respect to the original function we do not use the prec argument */ GSERIALIZED * -gserialized_convex_hull(const GSERIALIZED *geom) +gserialized_convex_hull(const GSERIALIZED *gs) { /* Empty.ConvexHull() == Empty */ - if ( gserialized_is_empty(geom) ) - return gserialized_copy(geom); + if ( gserialized_is_empty(gs) ) + return gserialized_copy(gs); - int32_t srid = gserialized_get_srid(geom); + int32_t srid = gserialized_get_srid(gs); initGEOS(lwnotice, lwgeom_geos_error); - GEOSGeometry *g1 = POSTGIS2GEOS(geom); - if (!g1) - elog(ERROR, "First argument geometry could not be converted to GEOS"); + GEOSGeometry *geos1 = POSTGIS2GEOS(gs); + if (!geos1) + { + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "First argument geometry could not be converted to GEOS"); + return NULL; + } - GEOSGeometry *g3 = GEOSConvexHull(g1); - GEOSGeom_destroy(g1); + GEOSGeometry *geos2 = GEOSConvexHull(geos1); + GEOSGeom_destroy(geos1); - if (!g3) - elog(ERROR,"GEOS convexhull() threw an error !"); + if (! geos2) + { + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "GEOS convexhull() threw an error !"); + return NULL; + } - GEOSSetSRID(g3, srid); + GEOSSetSRID(geos2, srid); - LWGEOM *lwout = GEOS2LWGEOM(g3, (uint8_t) gserialized_has_z(geom)); - GEOSGeom_destroy(g3); + LWGEOM *lwout = GEOS2LWGEOM(geos2, (uint8_t) gserialized_has_z(gs)); + GEOSGeom_destroy(geos2); if (!lwout) { - elog(ERROR, "convexhull() failed to convert GEOS geometry to LWGEOM"); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "convexhull() failed to convert GEOS geometry to LWGEOM"); return NULL; /* never get here */ } /* Copy input bbox if any */ GBOX bbox; - if ( gserialized_get_gbox_p(geom, &bbox) ) + if ( gserialized_get_gbox_p(gs, &bbox) ) { /* Force the box to have the same dimensionality as the lwgeom */ bbox.flags = lwout->flags; @@ -1086,7 +1124,8 @@ gserialized_convex_hull(const GSERIALIZED *geom) if (!result) { - elog(ERROR,"GEOS convexhull() threw an error !"); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "GEOS convexhull() threw an error !"); return NULL; /* never get here */ } @@ -1102,21 +1141,21 @@ gserialized_convex_hull(const GSERIALIZED *geom) * @note PostGIS function: geography_length(PG_FUNCTION_ARGS) */ double -gserialized_geog_length(GSERIALIZED *g, bool use_spheroid) +gserialized_geog_length(GSERIALIZED *gs, bool use_spheroid) { /* EMPTY things have no length */ - int32 geo_type = gserialized_get_type(g); - if (gserialized_is_empty(g) || geo_type == POLYGONTYPE || + int32 geo_type = gserialized_get_type(gs); + if (gserialized_is_empty(gs) || geo_type == POLYGONTYPE || geo_type == MULTIPOLYGONTYPE) return 0.0; /* Get our geometry object loaded into memory. */ - LWGEOM *lwgeom = lwgeom_from_gserialized(g); + LWGEOM *geom = lwgeom_from_gserialized(gs); /* Initialize spheroid */ /* We currently cannot use the following statement since PROJ4 API is not * available directly to MobilityDB. */ - // spheroid_init_from_srid(gserialized_get_srid(g), &s); + // spheroid_init_from_srid(gserialized_get_srid(gs), &s); SPHEROID s; spheroid_init(&s, WGS84_MAJOR_AXIS, WGS84_MINOR_AXIS); @@ -1125,16 +1164,17 @@ gserialized_geog_length(GSERIALIZED *g, bool use_spheroid) s.a = s.b = s.radius; /* Calculate the length */ - double length = lwgeom_length_spheroid(lwgeom, &s); + double length = lwgeom_length_spheroid(geom, &s); /* Something went wrong... */ if ( length < 0.0 ) { - elog(ERROR, "lwgeom_length_spheroid returned length < 0.0"); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "lwgeom_length_spheroid returned length < 0.0"); } /* Clean up */ - lwgeom_free(lwgeom); + lwgeom_free(geom); return length; } @@ -1145,18 +1185,19 @@ gserialized_geog_length(GSERIALIZED *g, bool use_spheroid) * where we use the WGS84 spheroid */ bool -gserialized_geog_dwithin(GSERIALIZED *g1, GSERIALIZED *g2, double tolerance, +gserialized_geog_dwithin(GSERIALIZED *gs1, GSERIALIZED *gs2, double tolerance, bool use_spheroid) { - ensure_same_srid(gserialized_get_srid(g1), gserialized_get_srid(g2)); + assert(gserialized_get_srid(gs1) == gserialized_get_srid(gs2)); + /* Return FALSE on empty arguments. */ - if (gserialized_is_empty(g1) || gserialized_is_empty(g2)) + if (gserialized_is_empty(gs1) || gserialized_is_empty(gs2)) return false; /* Initialize spheroid */ /* We currently cannot use the following statement since PROJ4 API is not * available directly to MobilityDB. */ - // spheroid_init_from_srid(gserialized_get_srid(g1), &s); + // spheroid_init_from_srid(gserialized_get_srid(gs1), &s); SPHEROID s; spheroid_init(&s, WGS84_MAJOR_AXIS, WGS84_MINOR_AXIS); @@ -1164,8 +1205,8 @@ gserialized_geog_dwithin(GSERIALIZED *g1, GSERIALIZED *g2, double tolerance, if ( ! use_spheroid ) s.a = s.b = s.radius; - LWGEOM *lwgeom1 = lwgeom_from_gserialized(g1); - LWGEOM *lwgeom2 = lwgeom_from_gserialized(g2); + LWGEOM *lwgeom1 = lwgeom_from_gserialized(gs1); + LWGEOM *lwgeom2 = lwgeom_from_gserialized(gs2); double distance = lwgeom_distance_spheroid(lwgeom1, lwgeom2, &s, tolerance); /* Clean up */ @@ -1175,7 +1216,8 @@ gserialized_geog_dwithin(GSERIALIZED *g1, GSERIALIZED *g2, double tolerance, /* Something went wrong... should already be eloged, return FALSE */ if ( distance < 0.0 ) { - elog(ERROR, "lwgeom_distance_spheroid returned negative!"); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "lwgeom_distance_spheroid returned negative!"); return false; } @@ -1193,11 +1235,12 @@ gserialized_geog_dwithin(GSERIALIZED *g1, GSERIALIZED *g2, double tolerance, * @note Errors return -1 to replace return NULL */ double -gserialized_geog_distance(const GSERIALIZED *g1, const GSERIALIZED *g2) +gserialized_geog_distance(const GSERIALIZED *gs1, const GSERIALIZED *gs2) { - ensure_same_srid(gserialized_get_srid(g1), gserialized_get_srid(g1)); + assert(gserialized_get_srid(gs1) == gserialized_get_srid(gs1)); + /* Return NULL on empty arguments. */ - if (gserialized_is_empty(g1) || gserialized_is_empty(g2) ) + if (gserialized_is_empty(gs1) || gserialized_is_empty(gs2) ) return -1; double tolerance = PGIS_FP_TOLERANCE; @@ -1214,8 +1257,8 @@ gserialized_geog_distance(const GSERIALIZED *g1, const GSERIALIZED *g2) if ( ! use_spheroid ) s.a = s.b = s.radius; - LWGEOM *lwgeom1 = lwgeom_from_gserialized(g1); - LWGEOM *lwgeom2 = lwgeom_from_gserialized(g2); + LWGEOM *lwgeom1 = lwgeom_from_gserialized(gs1); + LWGEOM *lwgeom2 = lwgeom_from_gserialized(gs2); /* Make sure we have boxes attached */ lwgeom_add_bbox_deep(lwgeom1, NULL); @@ -1229,7 +1272,8 @@ gserialized_geog_distance(const GSERIALIZED *g1, const GSERIALIZED *g2) /* Something went wrong, negative return... should already be eloged, return NULL */ if ( distance < 0.0 ) - elog(ERROR, "gserialized_geog_distance returned distance < 0.0"); + meos_error(ERROR, MEOS_ERR_INTERNAL_TYPE_ERROR, + "gserialized_geog_distance returned distance < 0.0"); return distance; } @@ -1244,19 +1288,19 @@ gserialized_geog_distance(const GSERIALIZED *g1, const GSERIALIZED *g2) * @note Function from gserialized_typmod.c */ GSERIALIZED * -postgis_valid_typmod(GSERIALIZED *gser, int32_t typmod) +postgis_valid_typmod(GSERIALIZED *gs, int32_t typmod) { - int32 geom_srid = gserialized_get_srid(gser); - int32 geom_type = gserialized_get_type(gser); - int32 geom_z = gserialized_has_z(gser); - int32 geom_m = gserialized_has_m(gser); + int32 geom_srid = gserialized_get_srid(gs); + int32 geom_type = gserialized_get_type(gs); + int32 geom_z = gserialized_has_z(gs); + int32 geom_m = gserialized_has_m(gs); int32 typmod_srid = TYPMOD_GET_SRID(typmod); int32 typmod_type = TYPMOD_GET_TYPE(typmod); int32 typmod_z = TYPMOD_GET_Z(typmod); int32 typmod_m = TYPMOD_GET_M(typmod); /* No typmod (-1) => no preferences */ - if (typmod < 0) return gser; + if (typmod < 0) return gs; /* * #3031: If a user is handing us a MULTIPOINT EMPTY but trying to fit it into @@ -1268,27 +1312,29 @@ postgis_valid_typmod(GSERIALIZED *gser, int32_t typmod) * point EMPTY, rather than throwing an error. */ if ( typmod_type == POINTTYPE && geom_type == MULTIPOINTTYPE && - gserialized_is_empty(gser) ) + gserialized_is_empty(gs) ) { LWPOINT *empty_point = lwpoint_construct_empty(geom_srid, geom_z, geom_m); geom_type = POINTTYPE; - pfree(gser); + pfree(gs); /* MEOS: use internal geo_serialize that copes with both geom and geog */ - gser = geo_serialize(lwpoint_as_lwgeom(empty_point)); + gs = geo_serialize(lwpoint_as_lwgeom(empty_point)); } /* Typmod has a preference for SRID, but geometry does not? Harmonize the geometry SRID. */ if ( typmod_srid > 0 && geom_srid == 0 ) { - gserialized_set_srid(gser, typmod_srid); + gserialized_set_srid(gs, typmod_srid); geom_srid = typmod_srid; } /* Typmod has a preference for SRID? Geometry SRID had better match. */ if ( typmod_srid > 0 && typmod_srid != geom_srid ) { - elog(ERROR, "Geometry SRID (%d) does not match column SRID (%d)", + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Geometry SRID (%d) does not match column SRID (%d)", geom_srid, typmod_srid); + return NULL; } /* Typmod has a preference for geometry type. */ @@ -1300,35 +1346,45 @@ postgis_valid_typmod(GSERIALIZED *gser, int32_t typmod) /* Other types must be strictly equal. */ (typmod_type != geom_type)) ) { - elog(ERROR, "Geometry type (%s) does not match column type (%s)", + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Geometry type (%s) does not match column type (%s)", lwtype_name(geom_type), lwtype_name(typmod_type)); + return NULL; } /* Mismatched Z dimensionality. */ if ( typmod_z && ! geom_z ) { - elog(ERROR, "Column has Z dimension but geometry does not"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Column has Z dimension but geometry does not"); + return NULL; } /* Mismatched Z dimensionality (other way). */ if ( geom_z && ! typmod_z ) { - elog(ERROR, "Geometry has Z dimension but column does not"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Geometry has Z dimension but column does not"); + return NULL; } /* Mismatched M dimensionality. */ if ( typmod_m && ! geom_m ) { - elog(ERROR, "Column has M dimension but geometry does not"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Column has M dimension but geometry does not"); + return NULL; } /* Mismatched M dimensionality (other way). */ if ( geom_m && ! typmod_m ) { - elog(ERROR, "Geometry has M dimension but column does not"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Geometry has M dimension but column does not"); + return NULL; } - return gser; + return gs; } /** @@ -1347,6 +1403,10 @@ postgis_valid_typmod(GSERIALIZED *gser, int32_t typmod) GSERIALIZED * pgis_geometry_in(char *input, int32 geom_typmod) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) input)) + return NULL; + char *str = input; LWGEOM_PARSER_RESULT lwg_parser_result; LWGEOM *lwgeom; @@ -1357,7 +1417,8 @@ pgis_geometry_in(char *input, int32 geom_typmod) /* Empty string. */ if ( str[0] == '\0' ) { - elog(ERROR, "parse error - invalid geometry"); + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, "parse error - invalid geometry"); + return NULL; } /* Starts with "SRID=" */ @@ -1447,10 +1508,16 @@ pgis_geometry_in(char *input, int32 geom_typmod) * @note PostGIS function: LWGEOM_out(PG_FUNCTION_ARGS) */ char * -gserialized_out(const GSERIALIZED *geom) +gserialized_out(const GSERIALIZED *gs) { - LWGEOM *lwgeom = lwgeom_from_gserialized(geom); - return lwgeom_to_hexwkb_buffer(lwgeom, WKB_EXTENDED); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs)) + return NULL; + + LWGEOM *geom = lwgeom_from_gserialized(gs); + char *result = lwgeom_to_hexwkb_buffer(geom, WKB_EXTENDED); + lwgeom_free(geom); + return result; } #if MEOS @@ -1461,6 +1528,10 @@ gserialized_out(const GSERIALIZED *geom) static GSERIALIZED * gserialized_from_text(char *wkt, int srid, bool geography) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) wkt)) + return NULL; + LWGEOM_PARSER_RESULT lwg_parser_result; GSERIALIZED *geo_result = NULL; LWGEOM *lwgeom; @@ -1472,7 +1543,8 @@ gserialized_from_text(char *wkt, int srid, bool geography) if ( lwgeom->srid != SRID_UNKNOWN ) { - elog(WARNING, "OGC WKT expected, EWKT provided - use GeomFromEWKT() for this"); + meos_error(WARNING, MEOS_ERR_TEXT_INPUT, + "OGC WKT expected, EWKT provided - use GeomFromEWKT() for this"); } /* read user-requested SRID if any */ @@ -1492,7 +1564,7 @@ gserialized_from_text(char *wkt, int srid, bool geography) /** * @ingroup libmeos_pgis_types * @brief Return a geometry from its WKT representation (and optionally a SRID) - * @note This is a a stricter version of pgis_geometry_in, where we refuse to + * @note This is a a stricter version of #pgis_geometry_in, where we refuse to * accept (HEX)WKB or EWKT. * @note PostGIS function: LWGEOM_from_text(PG_FUNCTION_ARGS) */ @@ -1505,8 +1577,8 @@ geometry_from_text(char *wkt, int srid) /** * @ingroup libmeos_pgis_types * @brief Return a geometry from its WKT representation (and optionally a SRID) - * @note This is a a stricter version of gegraphy_in, where we refuse to accept - * (HEX)WKB or EWKT. + * @note This is a a stricter version of #pgis_geography_in, where we refuse to + * accept (HEX)WKB or EWKT. * @note PostGIS function: geography_from_text(PG_FUNCTION_ARGS) */ GSERIALIZED * @@ -1518,35 +1590,43 @@ geography_from_text(char *wkt, int srid) /** * @ingroup libmeos_pgis_types * @brief Return the WKT representation (and optionally a SRID) of a geometry - * @note This is a a stricter version of pgis_geometry_in, where we refuse to + * @note This is a a stricter version of #pgis_geometry_in, where we refuse to * accept (HEX)WKB or EWKT. * @note PostGIS function: LWGEOM_asText(PG_FUNCTION_ARGS) */ char * -gserialized_as_text(const GSERIALIZED *geom, int precision) +gserialized_as_text(const GSERIALIZED *gs, int precision) { - LWGEOM *lwgeom = lwgeom_from_gserialized(geom); - return lwgeom_to_wkt(lwgeom, WKT_ISO, precision, NULL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs)) + return NULL; + + LWGEOM *geom = lwgeom_from_gserialized(gs); + return lwgeom_to_wkt(geom, WKT_ISO, precision, NULL); } /** * @ingroup libmeos_pgis_types * @brief Return the EWKT representation (and optionally a SRID) of a geometry - * @note This is a a stricter version of pgis_geometry_in, where we refuse to + * @note This is a a stricter version of #pgis_geometry_in, where we refuse to * accept (HEX)WKB or EWKT. * @note PostGIS function: LWGEOM_asEWKT(PG_FUNCTION_ARGS) */ char * -gserialized_as_ewkt(const GSERIALIZED *geom, int precision) +gserialized_as_ewkt(const GSERIALIZED *gs, int precision) { - LWGEOM *lwgeom = lwgeom_from_gserialized(geom); - return lwgeom_to_wkt(lwgeom, WKT_EXTENDED, precision, NULL); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs)) + return NULL; + + LWGEOM *geom = lwgeom_from_gserialized(gs); + return lwgeom_to_wkt(geom, WKT_EXTENDED, precision, NULL); } /** * @ingroup libmeos_pgis_types * @brief Return a geometry from its WKT representation - * @note This is a a stricter version of pgis_geometry_in, where we refuse to + * @note This is a a stricter version of #pgis_geometry_in, where we refuse to * accept (HEX)WKB or EWKT. * @note PostGIS function: LWGEOM_from_text(PG_FUNCTION_ARGS) */ @@ -1559,7 +1639,7 @@ geometry_from_hexewkb(const char *wkt) /** * @ingroup libmeos_pgis_types * @brief Return a geography from its WKT representation - * @note This is a a stricter version of pgis_geography_in, where we refuse to + * @note This is a a stricter version of #pgis_geography_in, where we refuse to * accept (HEX)WKB or EWKT. * @note PostGIS function: LWGEOM_from_text(PG_FUNCTION_ARGS) */ @@ -1572,11 +1652,15 @@ geography_from_hexewkb(const char *wkt) /** * @ingroup libmeos_pgis_types * @brief Return the WKB representation of a geometry in hex-encoded ASCII. - * @note PostGIS function: AsHEXEWKB(geom, string) + * @note PostGIS function: AsHEXEWKB(gs, string) */ char * -gserialized_as_hexewkb(const GSERIALIZED *geom, const char *type) +gserialized_as_hexewkb(const GSERIALIZED *gs, const char *type) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs)) + return NULL; + uint8_t variant = 0; /* If user specified endianness, respect it */ if (type != NULL) @@ -1587,8 +1671,8 @@ gserialized_as_hexewkb(const GSERIALIZED *geom, const char *type) variant = variant | WKB_NDR; } /* Create WKB hex string */ - LWGEOM *lwgeom = lwgeom_from_gserialized(geom); - lwvarlena_t *hexwkb = lwgeom_to_hexwkb_varlena(lwgeom, variant | WKB_EXTENDED); + LWGEOM *geom = lwgeom_from_gserialized(gs); + lwvarlena_t *hexwkb = lwgeom_to_hexwkb_varlena(geom, variant | WKB_EXTENDED); char *result = strdup(VARDATA(hexwkb)); pfree(hexwkb); return result; @@ -1604,21 +1688,28 @@ gserialized_as_hexewkb(const GSERIALIZED *geom, const char *type) GSERIALIZED * gserialized_from_ewkb(const bytea *bytea_wkb, int32 srid) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) bytea_wkb)) + return NULL; + uint8_t *wkb = (uint8_t *) VARDATA(bytea_wkb); - LWGEOM *lwgeom = lwgeom_from_wkb(wkb, VARSIZE_ANY_EXHDR(bytea_wkb), + LWGEOM *geom = lwgeom_from_wkb(wkb, VARSIZE_ANY_EXHDR(bytea_wkb), LW_PARSER_CHECK_ALL); - if (!lwgeom) - elog(ERROR, "Unable to parse WKB"); + if (!geom) + { + meos_error(ERROR, MEOS_ERR_WKB_INPUT, "Unable to parse WKB string"); + return NULL; + } if (srid > 0) - lwgeom_set_srid(lwgeom, srid); + lwgeom_set_srid(geom, srid); - if (lwgeom_needs_bbox(lwgeom)) - lwgeom_add_bbox(lwgeom); + if (lwgeom_needs_bbox(geom)) + lwgeom_add_bbox(geom); - GSERIALIZED *geom = geo_serialize(lwgeom); - lwgeom_free(lwgeom); - return geom; + GSERIALIZED *result = geo_serialize(geom); + lwgeom_free(geom); + return result; } /** @@ -1627,8 +1718,12 @@ gserialized_from_ewkb(const bytea *bytea_wkb, int32 srid) * @note PostGIS function: WKBFromLWGEOM(lwgeom) --> wkb */ bytea * -gserialized_as_ewkb(const GSERIALIZED *geom, char *type) +gserialized_as_ewkb(const GSERIALIZED *gs, char *type) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs)) + return NULL; + uint8_t variant = 0; /* If user specified endianness, respect it */ @@ -1641,11 +1736,11 @@ gserialized_as_ewkb(const GSERIALIZED *geom, char *type) } /* Create WKB hex string */ - LWGEOM *lwgeom = lwgeom_from_gserialized(geom); - lwvarlena_t *wkb = lwgeom_to_wkb_varlena(lwgeom, variant | WKB_EXTENDED); + LWGEOM *geom = lwgeom_from_gserialized(gs); + lwvarlena_t *wkb = lwgeom_to_wkb_varlena(geom, variant | WKB_EXTENDED); bytea *result = palloc(wkb->size - LWVARHDRSZ); memcpy(result, wkb->data, wkb->size - LWVARHDRSZ); - pfree(lwgeom); pfree(wkb); + pfree(geom); pfree(wkb); return result; } @@ -1657,16 +1752,19 @@ gserialized_as_ewkb(const GSERIALIZED *geom, char *type) GSERIALIZED * gserialized_from_geojson(const char *geojson) { - GSERIALIZED *geom; - LWGEOM *lwgeom; + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) geojson)) + return NULL; + char *srs = NULL; int32_t srid = WGS84_SRID; - lwgeom = lwgeom_from_geojson(geojson, &srs); - if (!lwgeom) + LWGEOM *geom = lwgeom_from_geojson(geojson, &srs); + if (!geom) { /* Shouldn't get here */ - elog(ERROR, "lwgeom_from_geojson returned NULL"); + meos_error(ERROR, MEOS_ERR_GEOJSON_INPUT, + "lwgeom_from_geojson returned NULL"); return NULL; } @@ -1676,11 +1774,11 @@ gserialized_from_geojson(const char *geojson) // lwfree(srs); // } - lwgeom_set_srid(lwgeom, srid); - geom = geo_serialize(lwgeom); - lwgeom_free(lwgeom); + lwgeom_set_srid(geom, srid); + GSERIALIZED *result = geo_serialize(geom); + lwgeom_free(geom); - return geom; + return result; } /** @@ -1689,10 +1787,13 @@ gserialized_from_geojson(const char *geojson) * @note PostGIS function: LWGEOM_asGeoJson(PG_FUNCTION_ARGS) */ char * -gserialized_as_geojson(const GSERIALIZED *geom, int option, int precision, +gserialized_as_geojson(const GSERIALIZED *gs, int option, int precision, char *srs) { - LWGEOM *lwgeom; + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs)) + return NULL; + // int precision = OUT_DEFAULT_DECIMAL_DIGITS; int output_bbox = LW_FALSE; // int output_long_crs = LW_FALSE; @@ -1700,7 +1801,7 @@ gserialized_as_geojson(const GSERIALIZED *geom, int option, int precision, // int output_guess_short_srid = LW_FALSE; // const char *srs = NULL; - // int32_t srid = gserialized_get_srid(geom); + // int32_t srid = gserialized_get_srid(gs); /* Retrieve output option * 0 = without option @@ -1723,14 +1824,16 @@ gserialized_as_geojson(const GSERIALIZED *geom, int option, int precision, // if (!srs) // { - // elog(ERROR, "SRID %i unknown in spatial_ref_sys table", srid); + // meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + // "SRID %i unknown in spatial_ref_sys table", srid); // return NULL; // } // } - lwgeom = lwgeom_from_gserialized(geom); - lwvarlena_t *txt = lwgeom_to_geojson(lwgeom, srs, precision, output_bbox); + LWGEOM *geom = lwgeom_from_gserialized(gs); + lwvarlena_t *txt = lwgeom_to_geojson(geom, srs, precision, output_bbox); char *result = pstrdup(VARDATA(txt)); + lwgeom_free(geom); pfree(txt); return result; } @@ -1743,12 +1846,16 @@ gserialized_as_geojson(const GSERIALIZED *geom, int option, int precision, * `gserialized_same` in file `gserialized_gist_nd.c` */ bool -pgis_gserialized_same(const GSERIALIZED *geom1, const GSERIALIZED *geom2) +pgis_gserialized_same(const GSERIALIZED *gs1, const GSERIALIZED *gs2) { - LWGEOM *lwgeom1 = lwgeom_from_gserialized(geom1); - LWGEOM *lwgeom2 = lwgeom_from_gserialized(geom2); - char result = lwgeom_same(lwgeom1, lwgeom2); - pfree(lwgeom1); pfree(lwgeom2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs1) || ! ensure_not_null((void *) gs2)) + return false; + + LWGEOM *geom1 = lwgeom_from_gserialized(gs1); + LWGEOM *geom2 = lwgeom_from_gserialized(gs2); + char result = lwgeom_same(geom1, geom2); + pfree(geom1); pfree(geom2); return (result == LW_TRUE); } @@ -1768,7 +1875,8 @@ geography_valid_type(uint8_t type) type == MULTIPOINTTYPE || type == MULTILINETYPE || type == MULTIPOLYGONTYPE || type == COLLECTIONTYPE) ) { - elog(ERROR, "Geography type does not support %s", lwtype_name(type)); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "Geography type does not support %s", lwtype_name(type)); } } @@ -1787,7 +1895,7 @@ gserialized_geography_from_lwgeom(LWGEOM *lwgeom, int32 geog_typmod) lwgeom_nudge_geodetic(lwgeom); if ( lwgeom_force_geodetic(lwgeom) == LW_TRUE ) { - elog(NOTICE, + meos_error(NOTICE, MEOS_ERR_TEXT_INPUT, "Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY"); } @@ -1809,12 +1917,17 @@ gserialized_geography_from_lwgeom(LWGEOM *lwgeom, int32 geog_typmod) } /** + * @ingroup libmeos_pgis_types * @brief Get a geography from in string * @note PostGIS function: geography_in(PG_FUNCTION_ARGS) */ GSERIALIZED * pgis_geography_in(char *str, int32 geog_typmod) { + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; + LWGEOM_PARSER_RESULT lwg_parser_result; LWGEOM *lwgeom = NULL; GSERIALIZED *g_ser = NULL; @@ -1823,7 +1936,11 @@ pgis_geography_in(char *str, int32 geog_typmod) /* Empty string. */ if ( str[0] == '\0' ) - elog(ERROR, "parse error - invalid geometry"); + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "parse error - invalid geography"); + return NULL; + } /* WKB? Let's find out. */ if ( str[0] == '0' ) @@ -1833,7 +1950,11 @@ pgis_geography_in(char *str, int32 geog_typmod) lwgeom = lwgeom_from_hexwkb(str, LW_PARSER_CHECK_NONE); /* Error out if something went sideways */ if ( ! lwgeom ) - elog(ERROR, "parse error - invalid geometry"); + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "parse error - invalid geometry"); + return NULL; + } } /* WKT then. */ else @@ -1858,17 +1979,6 @@ pgis_geography_in(char *str, int32 geog_typmod) return g_ser; } -/** - * @brief Output a geography in string format - * @note PostGIS function: geography_out(PG_FUNCTION_ARGS) - */ -char * -gserialized_geog_out(GSERIALIZED *g) -{ - LWGEOM *lwgeom = lwgeom_from_gserialized(g); - return lwgeom_to_hexwkb_buffer(lwgeom, WKB_EXTENDED); -} - #if MEOS /* ** geography_from_binary(*char) returns *GSERIALIZED @@ -1876,20 +1986,26 @@ gserialized_geog_out(GSERIALIZED *g) GSERIALIZED * pgis_geography_from_binary(const char *wkb_bytea) { - GSERIALIZED *gser = NULL; + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) wkb_bytea)) + return NULL; + size_t wkb_size = VARSIZE(wkb_bytea); uint8_t *wkb = (uint8_t *) VARDATA(wkb_bytea); - LWGEOM *lwgeom = lwgeom_from_wkb(wkb, wkb_size, LW_PARSER_CHECK_NONE); + LWGEOM *geom = lwgeom_from_wkb(wkb, wkb_size, LW_PARSER_CHECK_NONE); - if ( ! lwgeom ) - elog(ERROR, "Unable to parse WKB"); + if ( ! geom ) + { + meos_error(ERROR, MEOS_ERR_WKB_INPUT, "Unable to parse WKB string"); + return NULL; + } /* Error on any SRID != default */ // srid_check_latlong(lwgeom->srid); - gser = gserialized_geography_from_lwgeom(lwgeom, -1); - lwgeom_free(lwgeom); - return gser; + GSERIALIZED *result = gserialized_geography_from_lwgeom(geom, -1); + lwgeom_free(geom); + return result; } #endif /* MEOS */ @@ -1920,7 +2036,7 @@ gserialized_geog_from_geom(GSERIALIZED *geom) lwgeom_nudge_geodetic(lwgeom); if ( lwgeom_force_geodetic(lwgeom) == LW_TRUE ) { - elog(NOTICE, + meos_error(NOTICE, MEOS_ERR_TEXT_INPUT, "Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY" ); } @@ -1987,22 +2103,30 @@ lwgeom_line_interpolate_point(LWGEOM *lwgeom, double fraction, int32_t srid, * @note PostGIS function: LWGEOM_line_interpolate_point(PG_FUNCTION_ARGS) */ GSERIALIZED * -gserialized_line_interpolate_point(GSERIALIZED *gser, double distance_fraction, +gserialized_line_interpolate_point(GSERIALIZED *gs, double distance_fraction, char repeat) { GSERIALIZED *result; - int32_t srid = gserialized_get_srid(gser); + int32_t srid = gserialized_get_srid(gs); LWLINE* lwline; LWGEOM* lwresult; POINTARRAY* opa; if (distance_fraction < 0 || distance_fraction > 1) - elog(ERROR,"line_interpolate_point: 2nd arg isn't within [0,1]"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Second argument is not within [0,1]"); + return NULL; + } - if ( gserialized_get_type(gser) != LINETYPE ) - elog(ERROR,"line_interpolate_point: 1st arg isn't a line"); + if ( gserialized_get_type(gs) != LINETYPE ) + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "First argument is not a line"); + return NULL; + } - lwline = lwgeom_as_lwline(lwgeom_from_gserialized(gser)); + lwline = lwgeom_as_lwline(lwgeom_from_gserialized(gs)); opa = lwline_interpolate_points(lwline, distance_fraction, repeat); lwgeom_free(lwline_as_lwgeom(lwline)); @@ -2032,19 +2156,22 @@ gserialized_line_substring(GSERIALIZED *geom, double from, double to) if ( from < 0 || from > 1 ) { - elog(ERROR,"line_interpolate_point: 2nd arg isn't within [0,1]"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Second argument is not within [0,1]"); return NULL; } if ( to < 0 || to > 1 ) { - elog(ERROR,"line_interpolate_point: 3rd arg isn't within [0,1]"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Third argument is not within [0,1]"); return NULL; } if ( from > to ) { - elog(ERROR, "2nd arg must be smaller then 3rd arg"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Second argument must be smaller then the third one"); return NULL; } @@ -2150,7 +2277,8 @@ gserialized_line_substring(GSERIALIZED *geom, double from, double to) } else { - elog(ERROR, "line_substring: 1st arg isn't a line"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "First argument is not a line"); return NULL; } @@ -2164,7 +2292,7 @@ gserialized_line_substring(GSERIALIZED *geom, double from, double to) *****************************************************************************/ double -gserialized_line_locate_point(GSERIALIZED *geom1, GSERIALIZED *geom2) +gserialized_line_locate_point(GSERIALIZED *gs1, GSERIALIZED *gs2) { LWLINE *lwline; LWPOINT *lwpoint; @@ -2172,19 +2300,23 @@ gserialized_line_locate_point(GSERIALIZED *geom1, GSERIALIZED *geom2) POINT4D p, p_proj; double ret; - if ( gserialized_get_type(geom1) != LINETYPE ) + if ( gserialized_get_type(gs1) != LINETYPE ) { - elog(ERROR,"line_locate_point: 1st arg isn't a line"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "First argument is not a line"); + return -1.0; } - if ( gserialized_get_type(geom2) != POINTTYPE ) + if ( gserialized_get_type(gs2) != POINTTYPE ) { - elog(ERROR,"line_locate_point: 2st arg isn't a point"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Second argument is not a point"); + return -1.0; } - ensure_same_srid(gserialized_get_srid(geom1), gserialized_get_srid(geom2)); + assert(gserialized_get_srid(gs1) == gserialized_get_srid(gs2)); - lwline = lwgeom_as_lwline(lwgeom_from_gserialized(geom1)); - lwpoint = lwgeom_as_lwpoint(lwgeom_from_gserialized(geom2)); + lwline = lwgeom_as_lwline(lwgeom_from_gserialized(gs1)); + lwpoint = lwgeom_as_lwpoint(lwgeom_from_gserialized(gs2)); pa = lwline->points; lwpoint_getPoint4d_p(lwpoint, &p); @@ -2204,18 +2336,18 @@ gserialized_line_locate_point(GSERIALIZED *geom1, GSERIALIZED *geom2) * there is no LINESTRING(..) in GEOMETRY or INTEGER is out of bounds. */ GSERIALIZED * -gserialized_pointn_linestring(const GSERIALIZED *geom, int where) +gserialized_pointn_linestring(const GSERIALIZED *gs, int where) { - LWGEOM *lwgeom = lwgeom_from_gserialized(geom); - LWPOINT *lwpoint = NULL; - int type = lwgeom->type; + LWGEOM *geom = lwgeom_from_gserialized(gs); + LWPOINT *point = NULL; + int type = geom->type; /* If index is negative, count backward */ if( where < 1 ) { int count = -1; if ( type == LINETYPE || type == CIRCSTRINGTYPE || type == COMPOUNDTYPE ) - count = lwgeom_count_vertices(lwgeom); + count = lwgeom_count_vertices(geom); if(count >0) { /* only work if we found the total point number */ @@ -2229,19 +2361,19 @@ gserialized_pointn_linestring(const GSERIALIZED *geom, int where) if ( type == LINETYPE || type == CIRCSTRINGTYPE ) { /* OGC index starts at one, so we substract first. */ - lwpoint = lwline_get_lwpoint((LWLINE*)lwgeom, where - 1); + point = lwline_get_lwpoint((LWLINE*) geom, where - 1); } else if ( type == COMPOUNDTYPE ) { - lwpoint = lwcompound_get_lwpoint((LWCOMPOUND*)lwgeom, where - 1); + point = lwcompound_get_lwpoint((LWCOMPOUND*) geom, where - 1); } - lwgeom_free(lwgeom); + lwgeom_free(geom); - if ( ! lwpoint ) + if ( ! point ) return NULL; - return geo_serialize(lwpoint_as_lwgeom(lwpoint)); + return geo_serialize(lwpoint_as_lwgeom(point)); } /** @@ -2249,20 +2381,24 @@ gserialized_pointn_linestring(const GSERIALIZED *geom, int where) * linestring, or NULL if it is not a linestring */ int -gserialized_numpoints_linestring(const GSERIALIZED *geom) +gserialized_numpoints_linestring(const GSERIALIZED *gs) { - LWGEOM *lwgeom = lwgeom_from_gserialized(geom); + LWGEOM *geom = lwgeom_from_gserialized(gs); int count = -1; - int type = lwgeom->type; + int type = geom->type; if ( type == LINETYPE || type == CIRCSTRINGTYPE || type == COMPOUNDTYPE ) - count = lwgeom_count_vertices(lwgeom); + count = lwgeom_count_vertices(geom); - lwgeom_free(lwgeom); + lwgeom_free(geom); /* OGC says this functions is only valid on LINESTRING */ if ( count < 0 ) - elog(ERROR, "Error in computing number of points of a linestring"); + { + meos_error(ERROR, MEOS_ERR_INTERNAL_ERROR, + "Error in computing number of points of a linestring"); + return -1; + } return count; } diff --git a/meos/src/point/stbox.c b/meos/src/point/stbox.c index ec18aae997..7b73e30991 100644 --- a/meos/src/point/stbox.c +++ b/meos/src/point/stbox.c @@ -36,6 +36,7 @@ /* C */ #include +#include /* PostGIS */ #include /* MEOS */ @@ -97,23 +98,31 @@ stbox_expand(const STBox *box1, STBox *box2) /** * @brief Ensure that the temporal value has XY dimension */ -void +bool ensure_has_X_stbox(const STBox *box) { if (! MEOS_FLAGS_GET_X(box->flags)) - elog(ERROR, "The box must have space dimension"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The box must have space dimension"); + return false; + } + return true; } /** * @brief Ensure that the temporal value has T dimension */ -void +bool ensure_has_T_stbox(const STBox *box) { if (! MEOS_FLAGS_GET_T(box->flags)) - elog(ERROR, "The box must have time dimension"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The box must have time dimension"); + return false; + } + return true; } @@ -156,8 +165,8 @@ char * stbox_out(const STBox *box, int maxdd) { /* Ensure validity of the arguments */ - assert(box); - ensure_non_negative(maxdd); + if (! ensure_not_null((void *) box) || ! ensure_non_negative(maxdd)) + return NULL; static size_t size = MAXSTBOXLEN + 1; char *xmin = NULL, *xmax = NULL, *ymin = NULL, *ymax = NULL, *zmin = NULL, @@ -301,7 +310,9 @@ stbox_set(bool hasx, bool hasz, bool geodetic, int32 srid, double xmin, STBox * stbox_copy(const STBox *box) { - assert(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box)) + return NULL; STBox *result = palloc(sizeof(STBox)); memcpy(result, box, sizeof(STBox)); return result; @@ -317,7 +328,10 @@ stbox_copy(const STBox *box) STBox * geo_timestamp_to_stbox(const GSERIALIZED *gs, TimestampTz t) { - assert(gs); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs)) + return NULL; + if (gserialized_is_empty(gs)) return NULL; STBox *result = palloc(sizeof(STBox)); @@ -336,7 +350,10 @@ geo_timestamp_to_stbox(const GSERIALIZED *gs, TimestampTz t) STBox * geo_period_to_stbox(const GSERIALIZED *gs, const Span *p) { - assert(gs); assert(p); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs) || ! ensure_not_null((void *) p)) + return NULL; + if (gserialized_is_empty(gs)) return NULL; STBox *result = palloc(sizeof(STBox)); @@ -359,7 +376,7 @@ void stbox_set_gbox(const STBox *box, GBOX *gbox) { assert(box); assert(gbox); - ensure_has_X_stbox(box); + assert(MEOS_FLAGS_GET_X(box->flags)); /* Note: zero-fill is required here, just as in heap tuples */ memset(gbox, 0, sizeof(GBOX)); /* Initialize existing dimensions */ @@ -387,7 +404,7 @@ void stbox_set_box3d(const STBox *box, BOX3D *box3d) { assert(box); assert(box3d); - ensure_has_X_stbox(box); + assert(MEOS_FLAGS_GET_X(box->flags)); /* Note: zero-fill is required here, just as in heap tuples */ memset(box3d, 0, sizeof(BOX3D)); /* Initialize existing dimensions */ @@ -413,8 +430,10 @@ stbox_set_box3d(const STBox *box, BOX3D *box3d) GSERIALIZED * stbox_to_geo(const STBox *box) { - assert(box); - ensure_has_X_stbox(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_has_X_stbox(box)) + return NULL; + LWGEOM *geo; GSERIALIZED *result; BOX3D box3d; @@ -472,7 +491,10 @@ stbox_to_geo(const STBox *box) Span * stbox_to_period(const STBox *box) { - assert(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box)) + return NULL; + if (! MEOS_FLAGS_GET_T(box->flags)) return NULL; return span_copy(&box->period); @@ -542,15 +564,15 @@ geo_set_stbox(const GSERIALIZED *gs, STBox *box) } /* General case for arbitrary geometry/geography */ - LWGEOM *lwgeom = lwgeom_from_gserialized(gs); + LWGEOM *geom = lwgeom_from_gserialized(gs); GBOX gbox; memset(&gbox, 0, sizeof(GBOX)); /* We are sure that the geometry/geography is not empty * We cannot use `lwgeom_calculate_gbox` since for geography it calculates * a geodetic box where the coordinates are expressed in the unit sphere */ - lwgeom_calculate_gbox_cartesian(lwgeom, &gbox); - lwgeom_free(lwgeom); + lwgeom_calculate_gbox_cartesian(geom, &gbox); + lwgeom_free(geom); box->xmin = gbox.xmin; box->xmax = gbox.xmax; box->ymin = gbox.ymin; @@ -573,7 +595,10 @@ geo_set_stbox(const GSERIALIZED *gs, STBox *box) STBox * geo_to_stbox(const GSERIALIZED *gs) { - assert(gs); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs)) + return NULL; + STBox *result = palloc(sizeof(STBox)); geo_set_stbox(gs, result); return result; @@ -743,7 +768,9 @@ periodset_to_stbox(const SpanSet *ss) bool stbox_hasx(const STBox *box) { - assert(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box)) + return false; bool result = MEOS_FLAGS_GET_X(box->flags); return result; } @@ -756,7 +783,9 @@ stbox_hasx(const STBox *box) bool stbox_hasz(const STBox *box) { - assert(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box)) + return false; bool result = MEOS_FLAGS_GET_Z(box->flags); return result; } @@ -769,7 +798,9 @@ stbox_hasz(const STBox *box) bool stbox_hast(const STBox *box) { - assert(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box)) + return false; bool result = MEOS_FLAGS_GET_T(box->flags); return result; } @@ -782,7 +813,9 @@ stbox_hast(const STBox *box) bool stbox_isgeodetic(const STBox *box) { - assert(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box)) + return false; bool result = MEOS_FLAGS_GET_GEODETIC(box->flags); return result; } @@ -797,7 +830,10 @@ stbox_isgeodetic(const STBox *box) bool stbox_xmin(const STBox *box, double *result) { - assert(box); assert(result); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_X(box->flags)) return false; *result = box->xmin; @@ -814,7 +850,10 @@ stbox_xmin(const STBox *box, double *result) bool stbox_xmax(const STBox *box, double *result) { - assert(box); assert(result); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_X(box->flags)) return false; *result = box->xmax; @@ -831,7 +870,10 @@ stbox_xmax(const STBox *box, double *result) bool stbox_ymin(const STBox *box, double *result) { - assert(box); assert(result); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_X(box->flags)) return false; *result = box->ymin; @@ -848,7 +890,10 @@ stbox_ymin(const STBox *box, double *result) bool stbox_ymax(const STBox *box, double *result) { - assert(box); assert(result); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_X(box->flags)) return false; *result = box->ymax; @@ -865,7 +910,10 @@ stbox_ymax(const STBox *box, double *result) bool stbox_zmin(const STBox *box, double *result) { - assert(box); assert(result); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_Z(box->flags)) return false; *result = box->zmin; @@ -882,7 +930,10 @@ stbox_zmin(const STBox *box, double *result) bool stbox_zmax(const STBox *box, double *result) { - assert(box); assert(result); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_Z(box->flags)) return false; *result = box->zmax; @@ -899,7 +950,10 @@ stbox_zmax(const STBox *box, double *result) bool stbox_tmin(const STBox *box, TimestampTz *result) { - assert(box); assert(result); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_T(box->flags)) return false; *result = DatumGetTimestampTz(box->period.lower); @@ -917,10 +971,13 @@ stbox_tmin(const STBox *box, TimestampTz *result) bool stbox_tmin_inc(const STBox *box, bool *result) { - assert(box); assert(result); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_T(box->flags)) return false; - *result = DatumGetBool(box->period.lower_inc); + *result = box->period.lower_inc; return true; } @@ -934,7 +991,10 @@ stbox_tmin_inc(const STBox *box, bool *result) bool stbox_tmax(const STBox *box, TimestampTz *result) { - assert(box); assert(result); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_T(box->flags)) return false; *result = DatumGetTimestampTz(box->period.upper); @@ -952,10 +1012,13 @@ stbox_tmax(const STBox *box, TimestampTz *result) bool stbox_tmax_inc(const STBox *box, bool *result) { - assert(box); assert(result); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) result)) + return false; + if (! MEOS_FLAGS_GET_T(box->flags)) return false; - *result = DatumGetBool(box->period.upper_inc); + *result = box->period.upper_inc; return true; } @@ -971,7 +1034,9 @@ stbox_tmax_inc(const STBox *box, bool *result) int32 stbox_srid(const STBox *box) { - assert(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box)) + return SRID_INVALID; return box->srid; } @@ -983,7 +1048,9 @@ stbox_srid(const STBox *box) STBox * stbox_set_srid(const STBox *box, int32 srid) { - assert(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box)) + return NULL; STBox *result = stbox_copy(box); result->srid = srid; return result; @@ -994,7 +1061,7 @@ stbox_set_srid(const STBox *box, int32 srid) *****************************************************************************/ /** - * @ingroup libmeos_temporal_box_transf + * @ingroup libmeos_box_transf * @brief Return a copy of the spatiotemporal box keeping only the space * dimension * @sqlfunc getSpace() @@ -1002,8 +1069,10 @@ stbox_set_srid(const STBox *box, int32 srid) STBox * stbox_get_space(const STBox *box) { - assert(box); - ensure_has_X_stbox(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_has_X_stbox(box)) + return NULL; + STBox *result = palloc(sizeof(STBox)); stbox_set(true, MEOS_FLAGS_GET_Z(box->flags), MEOS_FLAGS_GET_GEODETIC(box->flags), box->srid, box->xmin, box->xmax, @@ -1020,8 +1089,10 @@ stbox_get_space(const STBox *box) STBox * stbox_expand_space(const STBox *box, double d) { - assert(box); - ensure_has_X_stbox(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_has_X_stbox(box)) + return NULL; + STBox *result = stbox_copy(box); result->xmin -= d; result->ymin -= d; @@ -1044,8 +1115,11 @@ stbox_expand_space(const STBox *box, double d) STBox * stbox_expand_time(const STBox *box, const Interval *interval) { - assert(box); assert(interval); - ensure_has_T_stbox(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) interval) || + ! ensure_has_T_stbox(box)) + return NULL; + STBox *result = stbox_copy(box); TimestampTz tmin = pg_timestamp_mi_interval(DatumGetTimestampTz( box->period.lower), interval); @@ -1057,15 +1131,16 @@ stbox_expand_time(const STBox *box, const Interval *interval) } /** + * @ingroup libmeos_box_transf * @brief Sets the precision of the coordinates of the spatiotemporal box. */ STBox * stbox_round(const STBox *box, int maxdd) { /* Ensure validity of the arguments */ - assert(box); - ensure_has_X_stbox(box); - ensure_non_negative(maxdd); + if (! ensure_not_null((void *) box) || ! ensure_has_X_stbox(box) || + ! ensure_non_negative(maxdd)) + return NULL; STBox *result = stbox_copy(box); Datum size = Int32GetDatum(maxdd); @@ -1110,18 +1185,19 @@ stbox_stbox_flags(const STBox *box1, const STBox *box2, bool *hasx, * @param[in] box1,box2 Input boxes * @param[out] hasx,hasz,hast,geodetic Boolean variables */ -static void +static bool topo_stbox_stbox_init(const STBox *box1, const STBox *box2, bool *hasx, bool *hasz, bool *hast, bool *geodetic) { - ensure_common_dimension(box1->flags, box2->flags); - if (MEOS_FLAGS_GET_X(box1->flags) && MEOS_FLAGS_GET_X(box2->flags)) - { - ensure_same_geodetic(box1->flags, box2->flags); - ensure_same_srid(stbox_srid(box1), stbox_srid(box2)); - } + /* Ensure validity of the arguments */ + if (! ensure_common_dimension(box1->flags, box2->flags)) + return false; + if (MEOS_FLAGS_GET_X(box1->flags) && MEOS_FLAGS_GET_X(box2->flags) && + (! ensure_same_geodetic(box1->flags, box2->flags) || + ! ensure_same_srid(stbox_srid(box1), stbox_srid(box2)))) + return false; stbox_stbox_flags(box1, box2, hasx, hasz, hast, geodetic); - return; + return true; } /** @@ -1132,9 +1208,12 @@ topo_stbox_stbox_init(const STBox *box1, const STBox *box2, bool *hasx, bool contains_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); bool hasx, hasz, hast, geodetic; - topo_stbox_stbox_init(box1, box2, &hasx, &hasz, &hast, &geodetic); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! topo_stbox_stbox_init(box1, box2, &hasx, &hasz, &hast, &geodetic)) + return false; + if (hasx && (box2->xmin < box1->xmin || box2->xmax > box1->xmax || box2->ymin < box1->ymin || box2->ymax > box1->ymax)) return false; @@ -1167,9 +1246,12 @@ contained_stbox_stbox(const STBox *box1, const STBox *box2) bool overlaps_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); bool hasx, hasz, hast, geodetic; - topo_stbox_stbox_init(box1, box2, &hasx, &hasz, &hast, &geodetic); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! topo_stbox_stbox_init(box1, box2, &hasx, &hasz, &hast, &geodetic)) + return false; + if (hasx && (box1->xmax < box2->xmin || box1->xmin > box2->xmax || box1->ymax < box2->ymin || box1->ymin > box2->ymax)) return false; @@ -1191,9 +1273,12 @@ overlaps_stbox_stbox(const STBox *box1, const STBox *box2) bool same_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); bool hasx, hasz, hast, geodetic; - topo_stbox_stbox_init(box1, box2, &hasx, &hasz, &hast, &geodetic); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! topo_stbox_stbox_init(box1, box2, &hasx, &hasz, &hast, &geodetic)) + return false; + if (hasx && (box1->xmin != box2->xmin || box1->xmax != box2->xmax || box1->ymin != box2->ymin || box1->ymax != box2->ymax)) return false; @@ -1213,9 +1298,12 @@ same_stbox_stbox(const STBox *box1, const STBox *box2) bool adjacent_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); bool hasx, hasz, hast, geodetic; - topo_stbox_stbox_init(box1, box2, &hasx, &hasz, &hast, &geodetic); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! topo_stbox_stbox_init(box1, box2, &hasx, &hasz, &hast, &geodetic)) + return false; + STBox inter; if (! inter_stbox_stbox(box1, box2, &inter)) return false; @@ -1252,12 +1340,14 @@ adjacent_stbox_stbox(const STBox *box1, const STBox *box2) * @brief Verify the conditions for a position operator * @param[in] box1,box2 Input boxes */ -static void +static bool pos_stbox_stbox_test(const STBox *box1, const STBox *box2) { - ensure_same_geodetic(box1->flags, box2->flags); - ensure_same_srid(stbox_srid(box1), stbox_srid(box2)); - return; + /* Ensure validity of the arguments */ + if (! ensure_same_geodetic(box1->flags, box2->flags) || + ! ensure_same_srid(stbox_srid(box1), stbox_srid(box2))) + return false; + return true; } /** @@ -1269,10 +1359,11 @@ pos_stbox_stbox_test(const STBox *box1, const STBox *box2) bool left_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - ensure_has_X_stbox(box1); - ensure_has_X_stbox(box2); - pos_stbox_stbox_test(box1, box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_X_stbox(box1) || ! ensure_has_X_stbox(box2) || + ! pos_stbox_stbox_test(box1, box2)) + return false; return (box1->xmax < box2->xmin); } @@ -1285,10 +1376,11 @@ left_stbox_stbox(const STBox *box1, const STBox *box2) bool overleft_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - ensure_has_X_stbox(box1); - ensure_has_X_stbox(box2); - pos_stbox_stbox_test(box1, box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_X_stbox(box1) || ! ensure_has_X_stbox(box2) || + ! pos_stbox_stbox_test(box1, box2)) + return false; return (box1->xmax <= box2->xmax); } @@ -1301,10 +1393,11 @@ overleft_stbox_stbox(const STBox *box1, const STBox *box2) bool right_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - ensure_has_X_stbox(box1); - ensure_has_X_stbox(box2); - pos_stbox_stbox_test(box1, box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_X_stbox(box1) || ! ensure_has_X_stbox(box2) || + ! pos_stbox_stbox_test(box1, box2)) + return false; return (box1->xmin > box2->xmax); } @@ -1317,10 +1410,11 @@ right_stbox_stbox(const STBox *box1, const STBox *box2) bool overright_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - ensure_has_X_stbox(box1); - ensure_has_X_stbox(box2); - pos_stbox_stbox_test(box1, box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_X_stbox(box1) || ! ensure_has_X_stbox(box2) || + ! pos_stbox_stbox_test(box1, box2)) + return false; return (box1->xmin >= box2->xmin); } @@ -1333,10 +1427,11 @@ overright_stbox_stbox(const STBox *box1, const STBox *box2) bool below_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - ensure_has_X_stbox(box1); - ensure_has_X_stbox(box2); - pos_stbox_stbox_test(box1, box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_X_stbox(box1) || ! ensure_has_X_stbox(box2) || + ! pos_stbox_stbox_test(box1, box2)) + return false; return (box1->ymax < box2->ymin); } @@ -1349,10 +1444,11 @@ below_stbox_stbox(const STBox *box1, const STBox *box2) bool overbelow_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - ensure_has_X_stbox(box1); - ensure_has_X_stbox(box2); - pos_stbox_stbox_test(box1, box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_X_stbox(box1) || ! ensure_has_X_stbox(box2) || + ! pos_stbox_stbox_test(box1, box2)) + return false; return (box1->ymax <= box2->ymax); } @@ -1365,10 +1461,11 @@ overbelow_stbox_stbox(const STBox *box1, const STBox *box2) bool above_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - ensure_has_X_stbox(box1); - ensure_has_X_stbox(box2); - pos_stbox_stbox_test(box1, box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_X_stbox(box1) || ! ensure_has_X_stbox(box2) || + ! pos_stbox_stbox_test(box1, box2)) + return false; return (box1->ymin > box2->ymax); } @@ -1381,10 +1478,11 @@ above_stbox_stbox(const STBox *box1, const STBox *box2) bool overabove_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - ensure_has_X_stbox(box1); - ensure_has_X_stbox(box2); - pos_stbox_stbox_test(box1, box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_X_stbox(box1) || ! ensure_has_X_stbox(box2) || + ! pos_stbox_stbox_test(box1, box2)) + return false; return (box1->ymin >= box2->ymin); } @@ -1397,10 +1495,11 @@ overabove_stbox_stbox(const STBox *box1, const STBox *box2) bool front_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - ensure_has_Z(box1->flags); - ensure_has_Z(box2->flags); - pos_stbox_stbox_test(box1, box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_Z(box1->flags) || ! ensure_has_Z(box2->flags) || + ! pos_stbox_stbox_test(box1, box2)) + return false; return (box1->zmax < box2->zmin); } @@ -1413,10 +1512,11 @@ front_stbox_stbox(const STBox *box1, const STBox *box2) bool overfront_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - ensure_has_Z(box1->flags); - ensure_has_Z(box2->flags); - pos_stbox_stbox_test(box1, box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_Z(box1->flags) || ! ensure_has_Z(box2->flags) || + ! pos_stbox_stbox_test(box1, box2)) + return false; return (box1->zmax <= box2->zmax); } @@ -1429,10 +1529,11 @@ overfront_stbox_stbox(const STBox *box1, const STBox *box2) bool back_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - ensure_has_Z(box1->flags); - ensure_has_Z(box2->flags); - pos_stbox_stbox_test(box1, box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_Z(box1->flags) || ! ensure_has_Z(box2->flags) || + ! pos_stbox_stbox_test(box1, box2)) + return false; return (box1->zmin > box2->zmax); } @@ -1445,10 +1546,11 @@ back_stbox_stbox(const STBox *box1, const STBox *box2) bool overback_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - ensure_has_Z(box1->flags); - ensure_has_Z(box2->flags); - pos_stbox_stbox_test(box1, box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_Z(box1->flags) || ! ensure_has_Z(box2->flags) || + ! pos_stbox_stbox_test(box1, box2)) + return false; return (box1->zmin >= box2->zmin); } @@ -1461,11 +1563,11 @@ overback_stbox_stbox(const STBox *box1, const STBox *box2) bool before_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - ensure_has_T_stbox(box1); - ensure_has_T_stbox(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_T_stbox(box1) || ! ensure_has_T_stbox(box2)) + return false; return left_span_span(&box1->period, &box2->period); - } /** @@ -1477,9 +1579,10 @@ before_stbox_stbox(const STBox *box1, const STBox *box2) bool overbefore_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - ensure_has_T_stbox(box1); - ensure_has_T_stbox(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_T_stbox(box1) || ! ensure_has_T_stbox(box2)) + return false; return overleft_span_span(&box1->period, &box2->period); } @@ -1492,9 +1595,10 @@ overbefore_stbox_stbox(const STBox *box1, const STBox *box2) bool after_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - ensure_has_T_stbox(box1); - ensure_has_T_stbox(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_T_stbox(box1) || ! ensure_has_T_stbox(box2)) + return false; return right_span_span(&box1->period, &box2->period); } @@ -1507,9 +1611,10 @@ after_stbox_stbox(const STBox *box1, const STBox *box2) bool overafter_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - ensure_has_T_stbox(box1); - ensure_has_T_stbox(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_T_stbox(box1) || ! ensure_has_T_stbox(box2)) + return false; return overright_span_span(&box1->period, &box2->period); } @@ -1525,14 +1630,20 @@ overafter_stbox_stbox(const STBox *box1, const STBox *box2) STBox * union_stbox_stbox(const STBox *box1, const STBox *box2, bool strict) { - assert(box1); assert(box2); - ensure_same_geodetic(box1->flags, box2->flags); - ensure_same_dimensionality(box1->flags, box2->flags); - ensure_same_srid(stbox_srid(box1), stbox_srid(box2)); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_same_geodetic(box1->flags, box2->flags) || + ! ensure_same_dimensionality(box1->flags, box2->flags) || + ! ensure_same_srid(stbox_srid(box1), stbox_srid(box2))) + return NULL; /* If the strict parameter is true, we need to ensure that the boxes * intersect, otherwise their union cannot be represented by a box */ if (strict && ! overlaps_stbox_stbox(box1, box2)) - elog(ERROR, "Result of box union would not be contiguous"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Result of box union would not be contiguous"); + return NULL; + } STBox *result = stbox_copy(box1); stbox_expand(box2, result); @@ -1565,8 +1676,9 @@ inter_stbox_stbox(const STBox *box1, const STBox *box2, STBox *result) if (hasx) { - ensure_same_geodetic(box1->flags, box2->flags); - ensure_same_srid(stbox_srid(box1), stbox_srid(box2)); + assert(MEOS_FLAGS_GET_GEODETIC(box1->flags) == + MEOS_FLAGS_GET_GEODETIC(box2->flags)); + assert(stbox_srid(box1) == stbox_srid(box2)); } double xmin = 0, xmax = 0, ymin = 0, ymax = 0, zmin = 0, zmax = 0; Span period; @@ -1599,10 +1711,13 @@ inter_stbox_stbox(const STBox *box1, const STBox *box2, STBox *result) STBox * intersection_stbox_stbox(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - ensure_same_geodetic(box1->flags, box2->flags); - // ensure_same_dimensionality(box1->flags, box2->flags); - ensure_same_srid(stbox_srid(box1), stbox_srid(box2)); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_same_geodetic(box1->flags, box2->flags) || + // ! ensure_same_dimensionality(box1->flags, box2->flags) || + ! ensure_same_srid(stbox_srid(box1), stbox_srid(box2))) + return NULL; + STBox *result = palloc(sizeof(STBox)); if (! inter_stbox_stbox(box1, box2, result)) { @@ -1633,8 +1748,11 @@ intersection_stbox_stbox(const STBox *box1, const STBox *box2) STBox * stbox_quad_split(const STBox *box, int *count) { - assert(box); assert(count); - ensure_has_X_stbox(box); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) count) || + ! ensure_has_X_stbox(box)) + return NULL; + bool hasz = MEOS_FLAGS_GET_Z(box->flags); bool hast = MEOS_FLAGS_GET_T(box->flags); bool geodetic = MEOS_FLAGS_GET_GEODETIC(box->flags); @@ -1700,8 +1818,11 @@ stbox_quad_split(const STBox *box, int *count) bool stbox_eq(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); - if (box1->flags != box2->flags || + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2)) + return false; + + if (box1->flags != box2->flags || box1->xmin != box2->xmin || box1->ymin != box2->ymin || box1->zmin != box2->zmin || box1->xmax != box2->xmax || box1->ymax != box2->ymax || box1->zmax != box2->zmax || @@ -1731,7 +1852,10 @@ stbox_ne(const STBox *box1, const STBox *box2) int stbox_cmp(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2)) + return INT_MAX; + /* Compare the SRID */ if (box1->srid < box2->srid) return -1; @@ -1799,7 +1923,6 @@ stbox_cmp(const STBox *box1, const STBox *box2) bool stbox_lt(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); int cmp = stbox_cmp(box1, box2); return cmp < 0; } @@ -1813,7 +1936,6 @@ stbox_lt(const STBox *box1, const STBox *box2) bool stbox_le(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); int cmp = stbox_cmp(box1, box2); return cmp <= 0; } @@ -1827,7 +1949,6 @@ stbox_le(const STBox *box1, const STBox *box2) bool stbox_ge(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); int cmp = stbox_cmp(box1, box2); return cmp >= 0; } @@ -1840,7 +1961,6 @@ stbox_ge(const STBox *box1, const STBox *box2) bool stbox_gt(const STBox *box1, const STBox *box2) { - assert(box1); assert(box2); int cmp = stbox_cmp(box1, box2); return cmp > 0; } diff --git a/meos/src/point/tpoint.c b/meos/src/point/tpoint.c index 62d9b6e46a..59be67fbfd 100644 --- a/meos/src/point/tpoint.c +++ b/meos/src/point/tpoint.c @@ -79,7 +79,9 @@ gserialized_copy(const GSERIALIZED *g) STBox * tpoint_to_stbox(const Temporal *temp) { - assert(temp); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; STBox *result = palloc(sizeof(STBox)); temporal_set_bbox(temp, result); return result; @@ -98,9 +100,10 @@ tpoint_to_stbox(const Temporal *temp) STBox * geo_expand_space(const GSERIALIZED *gs, double d) { - assert(gs); - if (gserialized_is_empty(gs)) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs) || gserialized_is_empty(gs)) return NULL; + STBox box; geo_set_stbox(gs, &box); STBox *result = stbox_expand_space(&box, d); @@ -116,9 +119,12 @@ geo_expand_space(const GSERIALIZED *gs, double d) STBox * tpoint_expand_space(const Temporal *temp, double d) { - assert(temp); - /* This function is also called for tnpoint */ - assert(tspatial_type(temp->temptype)); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + /* This function is also called for tnpoint */ + ! ensure_tspatial_type(temp->temptype)) + return NULL; + STBox box; temporal_set_bbox(temp, &box); STBox *result = stbox_expand_space(&box, d); @@ -133,19 +139,94 @@ tpoint_expand_space(const Temporal *temp, double d) * @brief Return the temporal comparison of a temporal point and a point */ Temporal * -tcomp_tpoint_point(const Temporal *temp, const GSERIALIZED *gs, +tcomp_tpoint_point_int(const Temporal *temp, const GSERIALIZED *gs, Datum (*func)(Datum, Datum, meosType), bool invert) { assert(temp); assert(gs); assert(func); if (gserialized_is_empty(gs)) return NULL; - ensure_point_type(gs); - ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)); - ensure_same_dimensionality_tpoint_gs(temp, gs); + assert(gserialized_get_type(gs) == POINTTYPE); + assert(tpoint_srid(temp) == gserialized_get_srid(gs)); + assert(same_dimensionality_tpoint_gs(temp, gs)); + meosType basetype = temptype_basetype(temp->temptype); Temporal *result = tcomp_temporal_base(temp, PointerGetDatum(gs), basetype, func, invert); return result; } +#if MEOS +/** + * @ingroup libmeos_temporal_comp + * @brief Return the temporal equality of a point and a temporal point + * @sqlop @p #= + */ +Temporal * +teq_point_tpoint(const GSERIALIZED *gs, const Temporal *temp) +{ + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp)) + return NULL; + + meosType geotype = FLAGS_GET_GEODETIC(gs->gflags) ? T_GEOGRAPHY : T_GEOMETRY; + if (! ensure_same_temporal_basetype(temp, geotype)) + return NULL; + return tcomp_tpoint_point_int(temp, gs, &datum2_eq, INVERT); +} + +/** + * @ingroup libmeos_temporal_comp + * @brief Return the temporal equality of a temporal point and a point + * @sqlop @p #= + */ +Temporal * +teq_tpoint_point(const Temporal *temp, const GSERIALIZED *gs) +{ + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs)) + return NULL; + + meosType geotype = FLAGS_GET_GEODETIC(gs->gflags) ? T_GEOGRAPHY : T_GEOMETRY; + if (! ensure_same_temporal_basetype(temp, geotype)) + return NULL; + return tcomp_tpoint_point_int(temp, gs, &datum2_eq, INVERT_NO); +} + +/** + * @ingroup libmeos_temporal_comp + * @brief Return the temporal difference of a point and a temporal point + * @sqlop @p #<> + */ +Temporal * +tne_point_tpoint(const GSERIALIZED *gs, const Temporal *temp) +{ + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs)) + return NULL; + + meosType geotype = FLAGS_GET_GEODETIC(gs->gflags) ? T_GEOGRAPHY : T_GEOMETRY; + if (! ensure_same_temporal_basetype(temp, geotype)) + return NULL; + return tcomp_tpoint_point_int(temp, gs, &datum2_ne, INVERT); +} + +/** + * @ingroup libmeos_temporal_comp + * @brief Return the temporal difference of the temporal point and a point + * @sqlop @p #<> + */ +Temporal * +tne_tpoint_point(const Temporal *temp, const GSERIALIZED *gs) +{ + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs)) + return NULL; + + meosType geotype = FLAGS_GET_GEODETIC(gs->gflags) ? T_GEOGRAPHY : T_GEOMETRY; + if (! ensure_same_temporal_basetype(temp, geotype)) + return NULL; + return tcomp_tpoint_point_int(temp, gs, &datum2_ne, INVERT_NO); +} +#endif /* MEOS */ + /*****************************************************************************/ diff --git a/meos/src/point/tpoint_aggfuncs.c b/meos/src/point/tpoint_aggfuncs.c index bc19b75046..8cf24ee51f 100644 --- a/meos/src/point/tpoint_aggfuncs.c +++ b/meos/src/point/tpoint_aggfuncs.c @@ -62,9 +62,11 @@ geoaggstate_check(const SkipList *state, int32_t srid, bool hasz) return; struct GeoAggregateState *extra = state->extra; if (extra && extra->srid != srid) - elog(ERROR, "Geometries must have the same SRID for temporal aggregation"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Geometries must have the same SRID for temporal aggregation"); if (extra && extra->hasz != hasz) - elog(ERROR, "Geometries must have the same dimensionality for temporal aggregation"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Geometries must have the same dimensionality for temporal aggregation"); return; } @@ -263,9 +265,11 @@ tpoint_extent_transfn(STBox *box, const Temporal *temp) } /* Both box and temporal are not null */ - ensure_same_srid(tpoint_srid(temp), stbox_srid(box)); - ensure_same_dimensionality(temp->flags, box->flags); - ensure_same_geodetic(temp->flags, box->flags); + if (! ensure_same_srid(tpoint_srid(temp), stbox_srid(box)) || + ! ensure_same_dimensionality(temp->flags, box->flags) || + ! ensure_same_geodetic(temp->flags, box->flags)) + return NULL; + temporal_set_bbox(temp, result); stbox_expand(box, result); return result; diff --git a/meos/src/point/tpoint_analytics.c b/meos/src/point/tpoint_analytics.c index 0cfda7fb45..b9d287eeab 100644 --- a/meos/src/point/tpoint_analytics.c +++ b/meos/src/point/tpoint_analytics.c @@ -495,12 +495,16 @@ bool tpoint_to_geo_meas(const Temporal *tpoint, const Temporal *meas, bool segmentize, GSERIALIZED **result) { - assert(tpoint); assert(result); - assert(tgeo_type(tpoint->temptype)); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) tpoint) || ! ensure_not_null((void *) result) || + ! ensure_tgeo_type(tpoint->temptype)) + return false; + Temporal *sync1, *sync2; if (meas) { - ensure_tnumber_type(meas->temptype); + if (! ensure_tnumber_type(meas->temptype)) + return false; /* Return false if the temporal values do not intersect in time * The operation is synchronization without adding crossings */ if (! intersection_temporal_temporal(tpoint, meas, SYNCHRONIZE_NOCROSS, @@ -585,10 +589,10 @@ trajpoint_to_tpointinst(LWPOINT *lwpoint) * coordinates encode the timestamps in Unix epoch into a temporal instant point. */ static TInstant * -geo_to_tpointinst(const LWGEOM *lwgeom) +geo_to_tpointinst(const LWGEOM *geom) { /* Geometry is a POINT */ - return trajpoint_to_tpointinst((LWPOINT *) lwgeom); + return trajpoint_to_tpointinst((LWPOINT *) geom); } /** @@ -597,28 +601,28 @@ geo_to_tpointinst(const LWGEOM *lwgeom) * function lwgeom_is_trajectory causes discrepancies with regression tests * due to the error message that varies across PostGIS versions. */ -static void -ensure_valid_trajectory(const LWGEOM *lwgeom, bool hasz, bool discrete) +static bool +ensure_valid_trajectory(const LWGEOM *geom, bool hasz, bool discrete) { - assert(lwgeom->type != MULTIPOINTTYPE || lwgeom->type != MULTILINETYPE); - LWCOLLECTION *lwcoll = NULL; - LWLINE *lwline = NULL; + assert(geom->type != MULTIPOINTTYPE || geom->type != MULTILINETYPE); + LWCOLLECTION *coll = NULL; + LWLINE *line = NULL; uint32_t npoints; if (discrete) { - lwcoll = lwgeom_as_lwcollection(lwgeom); - npoints = lwcoll->ngeoms; + coll = lwgeom_as_lwcollection(geom); + npoints = coll->ngeoms; } else { - lwline = lwgeom_as_lwline(lwgeom); - npoints = lwline->points->npoints; + line = lwgeom_as_lwline(geom); + npoints = line->points->npoints; } double m1 = -1 * DBL_MAX, m2; for (uint32_t i = 0; i < npoints; i++) { const POINTARRAY *pa = discrete ? - ((LWPOINT *) lwcoll->geoms[i])->point : lwline->points; + ((LWPOINT *) coll->geoms[i])->point : line->points; uint32_t where = discrete ? 0 : i; if (hasz) { @@ -632,11 +636,13 @@ ensure_valid_trajectory(const LWGEOM *lwgeom, bool hasz, bool discrete) } if (m1 >= m2) { - elog(ERROR, "Trajectory must be valid"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Trajectory must be valid"); + return false; } m1 = m2; } - return; + return true; } /** @@ -645,16 +651,17 @@ ensure_valid_trajectory(const LWGEOM *lwgeom, bool hasz, bool discrete) * sequence point. */ static TSequence * -geo_to_tpointseq_disc(const LWGEOM *lwgeom, bool hasz) +geo_to_tpointseq_disc(const LWGEOM *geom, bool hasz) { /* Verify that the trajectory is valid */ - ensure_valid_trajectory(lwgeom, hasz, true); + if (! ensure_valid_trajectory(geom, hasz, true)) + return NULL; /* Geometry is a MULTIPOINT */ - LWCOLLECTION *lwcoll = lwgeom_as_lwcollection(lwgeom); - uint32_t npoints = lwcoll->ngeoms; + LWCOLLECTION *coll = lwgeom_as_lwcollection(geom); + uint32_t npoints = coll->ngeoms; TInstant **instants = palloc(sizeof(TInstant *) * npoints); for (uint32_t i = 0; i < npoints; i++) - instants[i] = trajpoint_to_tpointinst((LWPOINT *) lwcoll->geoms[i]); + instants[i] = trajpoint_to_tpointinst((LWPOINT *) coll->geoms[i]); return tsequence_make_free(instants, npoints, true, true, DISCRETE, NORMALIZE); } @@ -667,12 +674,13 @@ geo_to_tpointseq_disc(const LWGEOM *lwgeom, bool hasz) * PostGIS and thus sequences obtained will be either discrete or linear. */ static TSequence * -geo_to_tpointseq_linear(const LWGEOM *lwgeom, bool hasz, bool geodetic) +geo_to_tpointseq_linear(const LWGEOM *geom, bool hasz, bool geodetic) { /* Verify that the trajectory is valid */ - ensure_valid_trajectory(lwgeom, hasz, false); + if (! ensure_valid_trajectory(geom, hasz, false)) + return NULL; /* Geometry is a LINESTRING */ - LWLINE *lwline = lwgeom_as_lwline(lwgeom); + LWLINE *lwline = lwgeom_as_lwline(geom); uint32_t npoints = lwline->points->npoints; TInstant **instants = palloc(sizeof(TInstant *) * npoints); for (uint32_t i = 0; i < npoints; i++) @@ -700,57 +708,59 @@ geo_to_tpointseq_linear(const LWGEOM *lwgeom, bool hasz, bool geodetic) * the sequence set. */ static TSequenceSet * -geo_to_tpointseqset(const LWGEOM *lwgeom, bool hasz, bool geodetic) +geo_to_tpointseqset(const LWGEOM *geom, bool hasz, bool geodetic) { /* Geometry is a MULTILINESTRING or a COLLECTION composed of (MULTI)POINT and * (MULTI)LINESTRING */ - LWCOLLECTION *lwcoll = lwgeom_as_lwcollection(lwgeom); - int ngeoms = lwcoll->ngeoms; + LWCOLLECTION *coll = lwgeom_as_lwcollection(geom); + int ngeoms = coll->ngeoms; int totalgeoms = 0; for (int i = 0; i < ngeoms; i++) { - LWGEOM *lwgeom1 = lwcoll->geoms[i]; - if (lwgeom1->type != POINTTYPE && lwgeom1->type != MULTIPOINTTYPE && - lwgeom1->type != LINETYPE && lwgeom1->type != MULTILINETYPE) + LWGEOM *geom1 = coll->geoms[i]; + if (geom1->type != POINTTYPE && geom1->type != MULTIPOINTTYPE && + geom1->type != LINETYPE && geom1->type != MULTILINETYPE) { - elog(ERROR, "Component geometry/geography must be of type (Multi)Point(Z)M or (Multi)Linestring(Z)M"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "Component geometry/geography must be of type (Multi)Point(Z)M or (Multi)Linestring(Z)M"); + return NULL; } - if (lwgeom1->type == POINTTYPE || lwgeom1->type == LINETYPE) + if (geom1->type == POINTTYPE || geom1->type == LINETYPE) totalgeoms++; - else /* lwgeom1->type == MULTIPOINTTYPE || lwgeom1->type == MULTILINETYPE */ - totalgeoms += lwgeom_as_lwcollection(lwgeom1)->ngeoms; + else /* geom1->type == MULTIPOINTTYPE || geom1->type == MULTILINETYPE */ + totalgeoms += lwgeom_as_lwcollection(geom1)->ngeoms; } TSequence **sequences = palloc(sizeof(TSequence *) * totalgeoms); int nseqs = 0; for (int i = 0; i < ngeoms; i++) { - LWGEOM *lwgeom1 = lwcoll->geoms[i]; - if (lwgeom1->type == POINTTYPE) + LWGEOM *geom1 = coll->geoms[i]; + if (geom1->type == POINTTYPE) { - TInstant *inst1 = geo_to_tpointinst(lwgeom1); + TInstant *inst1 = geo_to_tpointinst(geom1); /* The resulting sequence assumes linear interpolation */ sequences[nseqs++] = tinstant_to_tsequence(inst1, LINEAR); pfree(inst1); } - else if (lwgeom1->type == LINETYPE) - sequences[nseqs++] = geo_to_tpointseq_linear(lwgeom1, hasz, geodetic); - else /* lwgeom1->type == MULTIPOINTTYPE || lwgeom1->type == MULTILINETYPE */ + else if (geom1->type == LINETYPE) + sequences[nseqs++] = geo_to_tpointseq_linear(geom1, hasz, geodetic); + else /* geom1->type == MULTIPOINTTYPE || geom1->type == MULTILINETYPE */ { - LWCOLLECTION *lwcoll1 = lwgeom_as_lwcollection(lwgeom1); - int ngeoms1 = lwcoll1->ngeoms; + LWCOLLECTION *coll1 = lwgeom_as_lwcollection(geom1); + int ngeoms1 = coll1->ngeoms; for (int j = 0; j < ngeoms1; j++) { - LWGEOM *lwgeom2 = lwcoll1->geoms[j]; - if (lwgeom2->type == POINTTYPE) + LWGEOM *geom2 = coll1->geoms[j]; + if (geom2->type == POINTTYPE) { - TInstant *inst2 = geo_to_tpointinst(lwgeom2); + TInstant *inst2 = geo_to_tpointinst(geom2); /* The resulting sequence assumes linear interpolation */ sequences[nseqs++] = tinstant_to_tsequence(inst2, LINEAR); pfree(inst2); } - else /* lwgeom2->type == LINETYPE */ - sequences[nseqs++] = geo_to_tpointseq_linear(lwgeom2, hasz, geodetic); + else /* geom2->type == LINETYPE */ + sequences[nseqs++] = geo_to_tpointseq_linear(geom2, hasz, geodetic); } } } @@ -768,26 +778,29 @@ geo_to_tpointseqset(const LWGEOM *lwgeom, bool hasz, bool geodetic) * @sqlop @p :: */ Temporal * -geo_to_tpoint(const GSERIALIZED *geo) +geo_to_tpoint(const GSERIALIZED *gs) { - assert(geo); - ensure_non_empty(geo); - ensure_has_M_gs(geo); - bool hasz = (bool) FLAGS_GET_Z(geo->gflags); - bool geodetic = (bool) FLAGS_GET_GEODETIC(geo->gflags); - LWGEOM *lwgeom = lwgeom_from_gserialized(geo); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs) || ! ensure_non_empty(gs) || + ! ensure_has_M_gs(gs)) + return NULL; + + bool hasz = (bool) FLAGS_GET_Z(gs->gflags); + bool geodetic = (bool) FLAGS_GET_GEODETIC(gs->gflags); + LWGEOM *geom = lwgeom_from_gserialized(gs); Temporal *result = NULL; /* Make compiler quiet */ - if (lwgeom->type == POINTTYPE) - result = (Temporal *) geo_to_tpointinst(lwgeom); - else if (lwgeom->type == MULTIPOINTTYPE) - result = (Temporal *) geo_to_tpointseq_disc(lwgeom, hasz); - else if (lwgeom->type == LINETYPE) - result = (Temporal *) geo_to_tpointseq_linear(lwgeom, hasz, geodetic); - else if (lwgeom->type == MULTILINETYPE || lwgeom->type == COLLECTIONTYPE) - result = (Temporal *) geo_to_tpointseqset(lwgeom, hasz, geodetic); + if (geom->type == POINTTYPE) + result = (Temporal *) geo_to_tpointinst(geom); + else if (geom->type == MULTIPOINTTYPE) + result = (Temporal *) geo_to_tpointseq_disc(geom, hasz); + else if (geom->type == LINETYPE) + result = (Temporal *) geo_to_tpointseq_linear(geom, hasz, geodetic); + else if (geom->type == MULTILINETYPE || geom->type == COLLECTIONTYPE) + result = (Temporal *) geo_to_tpointseqset(geom, hasz, geodetic); else - elog(ERROR, "Invalid geometry type for trajectory"); - lwgeom_free(lwgeom); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_TYPE, + "Invalid geometry type for trajectory"); + lwgeom_free(geom); return result; } @@ -872,9 +885,12 @@ tsequenceset_simplify_min_dist(const TSequenceSet *ss, double dist) Temporal * temporal_simplify_min_dist(const Temporal *temp, double dist) { - assert(temp); - assert(tnumber_type(temp->temptype) || tgeo_type(temp->temptype)); - ensure_positive_datum(Float8GetDatum(dist), T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_tnumber_tgeo_type(temp->temptype) || + ! ensure_positive_datum(Float8GetDatum(dist), T_FLOAT8)) + return NULL; + Temporal *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT || ! MEOS_FLAGS_GET_LINEAR(temp->flags)) @@ -967,9 +983,12 @@ tsequenceset_simplify_min_tdelta(const TSequenceSet *ss, const Interval *mint) Temporal * temporal_simplify_min_tdelta(const Temporal *temp, const Interval *mint) { - assert(temp); assert(mint); - assert(tnumber_type(temp->temptype) || tgeo_type(temp->temptype)); - ensure_valid_duration(mint); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) mint) || + ! ensure_tnumber_tgeo_type(temp->temptype) || + ! ensure_valid_duration(mint)) + return NULL; + Temporal *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT || ! MEOS_FLAGS_GET_LINEAR(temp->flags)) @@ -1300,8 +1319,11 @@ tsequenceset_simplify_max_dist(const TSequenceSet *ss, double dist, Temporal * temporal_simplify_max_dist(const Temporal *temp, double dist, bool syncdist) { - assert(temp); - assert(tnumber_type(temp->temptype) || tgeo_type(temp->temptype)); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_tnumber_tgeo_type(temp->temptype)) + return NULL; + Temporal *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT || ! MEOS_FLAGS_GET_LINEAR(temp->flags)) @@ -1448,8 +1470,11 @@ tsequenceset_simplify_dp(const TSequenceSet *ss, double dist, bool syncdist, Temporal * temporal_simplify_dp(const Temporal *temp, double dist, bool syncdist) { - assert(temp); - assert(tnumber_type(temp->temptype) || tgeo_type(temp->temptype)); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || + ! ensure_tnumber_tgeo_type(temp->temptype)) + return NULL; + Temporal *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT || ! MEOS_FLAGS_GET_LINEAR(temp->flags)) @@ -1962,9 +1987,9 @@ static GSERIALIZED * tpointseq_decouple(const TSequence *seq, int64 **timesarr, int *count) { int64 *times = palloc(sizeof(int64) * seq->count); - LWGEOM *lwgeom = tpointseq_decouple_iter(seq, times); - GSERIALIZED *result = geo_serialize(lwgeom); - pfree(lwgeom); + LWGEOM *geom = tpointseq_decouple_iter(seq, times); + GSERIALIZED *result = geo_serialize(geom); + pfree(geom); *timesarr = times; *count = seq->count; return result; @@ -2042,16 +2067,27 @@ tpoint_decouple(const Temporal *temp, int64 **timesarr, int *count) */ bool tpoint_AsMVTGeom(const Temporal *temp, const STBox *bounds, int32_t extent, - int32_t buffer, bool clip_geom, GSERIALIZED **geom, int64 **timesarr, + int32_t buffer, bool clip_geom, GSERIALIZED **gsarr, int64 **timesarr, int *count) { - assert(temp); assert(bounds); assert(geom); assert(timesarr); assert(count); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) bounds) || + ! ensure_not_null((void *) gsarr) || ! ensure_not_null((void *) timesarr) || + ! ensure_not_null((void *) count) || ! ensure_tgeo_type(temp->temptype)) + return false; if (bounds->xmax - bounds->xmin <= 0 || bounds->ymax - bounds->ymin <= 0) - elog(ERROR, "%s: Geometric bounds are too small", __func__); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "%s: Geometric bounds are too small", __func__); + return false; + } if (extent <= 0) - elog(ERROR, "%s: Extent must be greater than 0", __func__); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "%s: Extent must be greater than 0", __func__); + return false; + } /* Contrary to what is done in PostGIS we do not use the following filter * to enable the visualization of temporal points with instant subtype. @@ -2078,7 +2114,7 @@ tpoint_AsMVTGeom(const Temporal *temp, const STBox *bounds, int32_t extent, return false; /* Decouple the geometry and the timestamps */ - *geom = tpoint_decouple(temp1, timesarr, count); + *gsarr = tpoint_decouple(temp1, timesarr, count); pfree(temp1); return true; diff --git a/meos/src/point/tpoint_boxops.c b/meos/src/point/tpoint_boxops.c index 85bd564d08..3b547c746b 100644 --- a/meos/src/point/tpoint_boxops.c +++ b/meos/src/point/tpoint_boxops.c @@ -236,14 +236,17 @@ tpointseqset_stboxes(const TSequenceSet *ss, int *count) /** * @ingroup libmeos_temporal_spatial_accessor - * @brief Return an array of spatiotemporal boxes from a temporal point + * @brief Return an array of spatiotemporal boxes from the segments of a + * temporal point * @sqlfunc stboxes() */ STBox * tpoint_stboxes(const Temporal *temp, int *count) { - assert(temp); assert(count); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) count) || + ! ensure_tgeo_type(temp->temptype)) + return NULL; STBox *result = NULL; assert(temptype_subtype(temp->subtype)); diff --git a/meos/src/point/tpoint_distance.c b/meos/src/point/tpoint_distance.c index a353675b26..cf2cce667a 100644 --- a/meos/src/point/tpoint_distance.c +++ b/meos/src/point/tpoint_distance.c @@ -113,25 +113,25 @@ tinstant_distance(const TInstant *inst1, const TInstant *inst2, * from measures.c */ static double -lw_distance_fraction(const LWGEOM *lw1, const LWGEOM *lw2, int mode, +lw_distance_fraction(const LWGEOM *geom1, const LWGEOM *geom2, int mode, double *fraction) { double result; - if (FLAGS_GET_GEODETIC(lw1->flags)) + if (FLAGS_GET_GEODETIC(geom1->flags)) { double min_dist = FLT_MAX; double max_dist = FLT_MAX; GEOGRAPHIC_POINT closest1, closest2; GEOGRAPHIC_EDGE e; - CIRC_NODE *circ_tree1 = lwgeom_calculate_circ_tree(lw1); - CIRC_NODE *circ_tree2 = lwgeom_calculate_circ_tree(lw2); + CIRC_NODE *circ_tree1 = lwgeom_calculate_circ_tree(geom1); + CIRC_NODE *circ_tree2 = lwgeom_calculate_circ_tree(geom2); circ_tree_distance_tree_internal(circ_tree1, circ_tree2, FP_TOLERANCE, &min_dist, &max_dist, &closest1, &closest2); result = sphere_distance(&closest1, &closest2); if (fraction != NULL) { - assert(lw1->type == LINETYPE); - LWLINE *lwline = lwgeom_as_lwline(lw1); + assert(geom1->type == LINETYPE); + LWLINE *lwline = lwgeom_as_lwline(geom1); /* Initialize edge */ POINT4D a, b; GEOGRAPHIC_POINT proj; @@ -149,18 +149,18 @@ lw_distance_fraction(const LWGEOM *lw1, const LWGEOM *lw2, int mode, } else { - if (FLAGS_GET_Z(lw1->flags)) + if (FLAGS_GET_Z(geom1->flags)) { DISTPTS3D dl; dl.mode = mode; dl.distance= FLT_MAX; dl.tolerance = 0; - lw_dist3d_recursive(lw1, lw2, &dl); + lw_dist3d_recursive(geom1, geom2, &dl); result = dl.distance; if (fraction != NULL) { - assert(lw1->type == LINETYPE); - LWLINE *lwline = lwgeom_as_lwline(lw1); + assert(geom1->type == LINETYPE); + LWLINE *lwline = lwgeom_as_lwline(geom1); POINT3DZ a, b, closest; getPoint3dz_p(lwline->points, 0, &a); getPoint3dz_p(lwline->points, 1, &b); @@ -173,12 +173,12 @@ lw_distance_fraction(const LWGEOM *lw1, const LWGEOM *lw2, int mode, dl.mode = mode; dl.distance= FLT_MAX; dl.tolerance = 0; - lw_dist2d_recursive(lw1, lw2, &dl); + lw_dist2d_recursive(geom1, geom2, &dl); result = dl.distance; if (fraction != NULL) { - assert(lw1->type == LINETYPE); - LWLINE *lwline = lwgeom_as_lwline(lw1); + assert(geom1->type == LINETYPE); + LWLINE *lwline = lwgeom_as_lwline(geom1); POINT2D a, b, closest; getPoint2d_p(lwline->points, 0, &a); getPoint2d_p(lwline->points, 1, &b); @@ -374,6 +374,8 @@ tgeogpoint_min_dist_at_timestamp(const TInstant *start1, const TInstant *end1, geog2cart(&(e2.end), &B2); double fraction; // TODO: The next computation should be done on geodetic coordinates + // The value found by the linear approximation below could be the starting + // point for an iterative method such as gradient descent or Newton's method bool found = point3d_min_dist((const POINT3DZ *) &A1, (const POINT3DZ *) &A2, (const POINT3DZ *) &B1, (const POINT3DZ *) &B2, &fraction); if (! found) @@ -393,7 +395,11 @@ tgeogpoint_min_dist_at_timestamp(const TInstant *start1, const TInstant *end1, res = sphere_project(&(e2.start), dist2 * fraction, dir2, &close2); if (res == LW_FAILURE) return false; - *mindist = Float8GetDatum(sphere_distance(&close1, &close2)); + double dist = sphere_distance(&close1, &close2); + /* Ensure robustness */ + if (fabs(dist) < FP_TOLERANCE) + dist = 0.0; + *mindist = Float8GetDatum(dist); } /* Compute the timestamp of intersection */ @@ -433,15 +439,15 @@ tpoint_min_dist_at_timestamp(const TInstant *start1, const TInstant *end1, * @sqlop @p <-> */ Temporal * -distance_tpoint_geo(const Temporal *temp, const GSERIALIZED *geo) +distance_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs) { - assert(temp); assert(geo); - if (gserialized_is_empty(geo)) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + gserialized_is_empty(gs) || + ! ensure_tgeo_type(temp->temptype) || ! ensure_point_type(gs) || + ! ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)) || + ! ensure_same_dimensionality_tpoint_gs(temp, gs)) return NULL; - ensure_tgeo_type(temp->temptype); - ensure_point_type(geo); - ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(geo)); - ensure_same_dimensionality_tpoint_gs(temp, geo); LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); @@ -455,7 +461,7 @@ distance_tpoint_geo(const Temporal *temp, const GSERIALIZED *geo) lfinfo.tpfunc_base = lfinfo.reslinear ? &tpoint_geo_min_dist_at_timestamp : NULL; lfinfo.tpfunc = NULL; - Temporal *result = tfunc_temporal_base(temp, PointerGetDatum(geo), &lfinfo); + Temporal *result = tfunc_temporal_base(temp, PointerGetDatum(gs), &lfinfo); return result; } @@ -467,11 +473,13 @@ distance_tpoint_geo(const Temporal *temp, const GSERIALIZED *geo) Temporal * distance_tpoint_tpoint(const Temporal *temp1, const Temporal *temp2) { - assert(temp1); assert(temp2); - ensure_tgeo_type(temp1->temptype); - ensure_same_temporal_type(temp1, temp2); - ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)); - ensure_same_dimensionality(temp1->flags, temp2->flags); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_tgeo_type(temp1->temptype) || + ! ensure_same_temporal_type(temp1, temp2) || + ! ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)) || + ! ensure_same_dimensionality(temp1->flags, temp2->flags)) + return NULL; LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); @@ -505,7 +513,7 @@ distance_tpoint_tpoint(const Temporal *temp1, const Temporal *temp2) * @result Minimum distance */ static double -NAI_tpointseq_discstep_geo_iter(const TSequence *seq, const LWGEOM *geo, +nai_tpointseq_discstep_geo_iter(const TSequence *seq, const LWGEOM *geo, double mindist, const TInstant **result) { for (int i = 0; i < seq->count; i++) @@ -532,10 +540,10 @@ NAI_tpointseq_discstep_geo_iter(const TSequence *seq, const LWGEOM *geo, * @param[in] geo Geometry/geography */ static TInstant * -NAI_tpointseq_discstep_geo(const TSequence *seq, const LWGEOM *geo) +nai_tpointseq_discstep_geo(const TSequence *seq, const LWGEOM *geo) { const TInstant *inst = NULL; /* make compiler quiet */ - NAI_tpointseq_discstep_geo_iter(seq, geo, DBL_MAX, &inst); + nai_tpointseq_discstep_geo_iter(seq, geo, DBL_MAX, &inst); return tinstant_copy(inst); } @@ -546,14 +554,14 @@ NAI_tpointseq_discstep_geo(const TSequence *seq, const LWGEOM *geo) * @param[in] geo Geometry/geography */ static TInstant * -NAI_tpointseqset_step_geo(const TSequenceSet *ss, const LWGEOM *geo) +nai_tpointseqset_step_geo(const TSequenceSet *ss, const LWGEOM *geo) { const TInstant *inst = NULL; /* make compiler quiet */ double mindist = DBL_MAX; for (int i = 0; i < ss->count; i++) { const TSequence *seq = TSEQUENCESET_SEQ_N(ss, i); - mindist = NAI_tpointseq_discstep_geo_iter(seq, geo, mindist, &inst); + mindist = nai_tpointseq_discstep_geo_iter(seq, geo, mindist, &inst); } assert(inst != NULL); return tinstant_copy(inst); @@ -571,7 +579,7 @@ NAI_tpointseqset_step_geo(const TSequenceSet *ss, const LWGEOM *geo) * @result Distance */ static double -NAI_tpointsegm_linear_geo1(const TInstant *inst1, const TInstant *inst2, +nai_tpointsegm_linear_geo1(const TInstant *inst1, const TInstant *inst2, const LWGEOM *geo, TimestampTz *t) { Datum value1 = tinstant_value(inst1); @@ -617,7 +625,7 @@ NAI_tpointsegm_linear_geo1(const TInstant *inst1, const TInstant *inst2, * @param[out] t Timestamp */ static double -NAI_tpointseq_linear_geo_iter(const TSequence *seq, const LWGEOM *geo, +nai_tpointseq_linear_geo_iter(const TSequence *seq, const LWGEOM *geo, double mindist, TimestampTz *t) { double dist; @@ -644,7 +652,7 @@ NAI_tpointseq_linear_geo_iter(const TSequence *seq, const LWGEOM *geo, for (int i = 0; i < seq->count - 1; i++) { const TInstant *inst2 = TSEQUENCE_INST_N(seq, i + 1); - dist = NAI_tpointsegm_linear_geo1(inst1, inst2, geo, &t1); + dist = nai_tpointsegm_linear_geo1(inst1, inst2, geo, &t1); if (dist < mindist) { mindist = dist; @@ -663,10 +671,10 @@ NAI_tpointseq_linear_geo_iter(const TSequence *seq, const LWGEOM *geo, * point with linear interpolation and a geometry (iterator function) */ static TInstant * -NAI_tpointseq_linear_geo(const TSequence *seq, const LWGEOM *geo) +nai_tpointseq_linear_geo(const TSequence *seq, const LWGEOM *geo) { TimestampTz t; - NAI_tpointseq_linear_geo_iter(seq, geo, DBL_MAX, &t); + nai_tpointseq_linear_geo_iter(seq, geo, DBL_MAX, &t); /* The closest point may be at an exclusive bound */ Datum value; tsequence_value_at_timestamp(seq, t, false, &value); @@ -680,7 +688,7 @@ NAI_tpointseq_linear_geo(const TSequence *seq, const LWGEOM *geo) * point with linear interpolation and a geometry */ static TInstant * -NAI_tpointseqset_linear_geo(const TSequenceSet *ss, const LWGEOM *geo) +nai_tpointseqset_linear_geo(const TSequenceSet *ss, const LWGEOM *geo) { TimestampTz t = 0; /* make compiler quiet */ double mindist = DBL_MAX; @@ -688,7 +696,7 @@ NAI_tpointseqset_linear_geo(const TSequenceSet *ss, const LWGEOM *geo) { const TSequence *seq = TSEQUENCESET_SEQ_N(ss, i); TimestampTz t1; - double dist = NAI_tpointseq_linear_geo_iter(seq, geo, mindist, &t1); + double dist = nai_tpointseq_linear_geo_iter(seq, geo, mindist, &t1); if (dist < mindist) { mindist = dist; @@ -716,12 +724,12 @@ NAI_tpointseqset_linear_geo(const TSequenceSet *ss, const LWGEOM *geo) TInstant * nai_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs) { - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); - if (gserialized_is_empty(gs)) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_tgeo_type(temp->temptype) || gserialized_is_empty(gs) || + ! ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)) || + ! ensure_same_dimensionality_tpoint_gs(temp, gs)) return NULL; - ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)); - ensure_same_dimensionality_tpoint_gs(temp, gs); LWGEOM *geo = lwgeom_from_gserialized(gs); TInstant *result; @@ -730,12 +738,12 @@ nai_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs) result = tinstant_copy((TInstant *) temp); else if (temp->subtype == TSEQUENCE) result = MEOS_FLAGS_GET_LINEAR(temp->flags) ? - NAI_tpointseq_linear_geo((TSequence *) temp, geo) : - NAI_tpointseq_discstep_geo((TSequence *) temp, geo); + nai_tpointseq_linear_geo((TSequence *) temp, geo) : + nai_tpointseq_discstep_geo((TSequence *) temp, geo); else /* temp->subtype == TSEQUENCESET */ result = MEOS_FLAGS_GET_LINEAR(temp->flags) ? - NAI_tpointseqset_linear_geo((TSequenceSet *) temp, geo) : - NAI_tpointseqset_step_geo((TSequenceSet *) temp, geo); + nai_tpointseqset_linear_geo((TSequenceSet *) temp, geo) : + nai_tpointseqset_step_geo((TSequenceSet *) temp, geo); lwgeom_free(geo); return result; } @@ -748,11 +756,14 @@ nai_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs) TInstant * nai_tpoint_tpoint(const Temporal *temp1, const Temporal *temp2) { - assert(temp1); assert(temp2); - ensure_tgeo_type(temp1->temptype); - ensure_same_temporal_type(temp1, temp2); - ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)); - ensure_same_dimensionality(temp1->flags, temp2->flags); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_tgeo_type(temp1->temptype) || + ! ensure_same_temporal_type(temp1, temp2) || + ! ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)) || + ! ensure_same_dimensionality(temp1->flags, temp2->flags)) + return NULL; + TInstant *result = NULL; Temporal *dist = distance_tpoint_tpoint(temp1, temp2); if (dist != NULL) @@ -780,12 +791,13 @@ nai_tpoint_tpoint(const Temporal *temp1, const Temporal *temp2) double nad_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs) { - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); - if (gserialized_is_empty(gs)) - return -1; - ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)); - ensure_same_dimensionality_tpoint_gs(temp, gs); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_tgeo_type(temp->temptype) || gserialized_is_empty(gs) || + ! ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)) || + ! ensure_same_dimensionality_tpoint_gs(temp, gs)) + return -1.0; + datum_func2 func = distance_fn(temp->flags); Datum traj = PointerGetDatum(tpoint_trajectory(temp)); double result = DatumGetFloat8(func(traj, PointerGetDatum(gs))); @@ -802,11 +814,12 @@ nad_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs) double nad_stbox_geo(const STBox *box, const GSERIALIZED *gs) { - assert(box); assert(gs); - if (gserialized_is_empty(gs)) - return -1; - ensure_same_srid_stbox_gs(box, gs); - ensure_same_spatial_dimensionality_stbox_gs(box, gs); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box) || ! ensure_not_null((void *) gs) || + gserialized_is_empty(gs) || ! ensure_same_srid_stbox_gs(box, gs) || + ! ensure_same_spatial_dimensionality_stbox_gs(box, gs)) + return -1.0; + datum_func2 func = distance_fn(box->flags); Datum geo = PointerGetDatum(stbox_to_geo(box)); double result = DatumGetFloat8(func(geo, PointerGetDatum(gs))); @@ -823,12 +836,13 @@ nad_stbox_geo(const STBox *box, const GSERIALIZED *gs) double nad_stbox_stbox(const STBox *box1, const STBox *box2) { - /* Test the validity of the arguments */ - assert(box1); assert(box2); - ensure_has_X_stbox(box1); ensure_has_X_stbox(box2); - ensure_same_geodetic(box1->flags, box2->flags); - ensure_same_spatial_dimensionality(box1->flags, box2->flags); - ensure_same_srid(stbox_srid(box1), stbox_srid(box2)); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) box1) || ! ensure_not_null((void *) box2) || + ! ensure_has_X_stbox(box1) || ! ensure_has_X_stbox(box2) || + ! ensure_same_geodetic(box1->flags, box2->flags) || + ! ensure_same_spatial_dimensionality(box1->flags, box2->flags) || + ! ensure_same_srid(stbox_srid(box1), stbox_srid(box2))) + return -1.0; /* If the boxes do not intersect in the time dimension return infinity */ bool hast = MEOS_FLAGS_GET_T(box1->flags) && MEOS_FLAGS_GET_T(box2->flags); @@ -859,13 +873,14 @@ nad_stbox_stbox(const STBox *box1, const STBox *box2) double nad_tpoint_stbox(const Temporal *temp, const STBox *box) { - /* Test the validity of the arguments */ - assert(temp); assert(box); - ensure_tgeo_type(temp->temptype); - ensure_has_X_stbox(box); - ensure_same_geodetic(temp->flags, box->flags); - ensure_same_spatial_dimensionality_temp_box(temp->flags, box->flags); - ensure_same_srid(tpoint_srid(temp), stbox_srid(box)); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) box) || + ! ensure_tgeo_type(temp->temptype) || ! ensure_has_X_stbox(box) || + ! ensure_same_geodetic(temp->flags, box->flags) || + ! ensure_same_spatial_dimensionality_temp_box(temp->flags, box->flags) || + ! ensure_same_srid(tpoint_srid(temp), stbox_srid(box))) + return -1.0; + /* Project the temporal point to the timespan of the box */ bool hast = MEOS_FLAGS_GET_T(box->flags); Span p, inter; @@ -902,14 +917,17 @@ nad_tpoint_stbox(const Temporal *temp, const STBox *box) double nad_tpoint_tpoint(const Temporal *temp1, const Temporal *temp2) { - assert(temp1); assert(temp2); - ensure_tgeo_type(temp1->temptype); - ensure_same_temporal_type(temp1, temp2); - ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)); - ensure_same_dimensionality(temp1->flags, temp2->flags); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_tgeo_type(temp1->temptype) || + ! ensure_same_temporal_type(temp1, temp2) || + ! ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)) || + ! ensure_same_dimensionality(temp1->flags, temp2->flags)) + return -1.0; + Temporal *dist = distance_tpoint_tpoint(temp1, temp2); if (dist == NULL) - return -1; + return -1.0; double result = DatumGetFloat8(temporal_min_value(dist)); pfree(dist); @@ -930,15 +948,18 @@ bool shortestline_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs, GSERIALIZED **result) { - assert(temp); assert(gs); assert(result); - ensure_tgeo_type(temp->temptype); - if (gserialized_is_empty(gs)) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_not_null((void *) result) || ! ensure_tgeo_type(temp->temptype) || + gserialized_is_empty(gs) || + ! ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs))) return false; - ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)); + bool geodetic = MEOS_FLAGS_GET_GEODETIC(temp->flags); - if (geodetic) - ensure_has_not_Z_gs(gs); - ensure_same_dimensionality_tpoint_gs(temp, gs); + if (geodetic && ! ensure_has_not_Z_gs(gs)) + return false; + if (! ensure_same_dimensionality_tpoint_gs(temp, gs)) + return false; GSERIALIZED *traj = tpoint_trajectory(temp); if (geodetic) /* Notice that geography_shortestline_internal is a MobilityDB function */ @@ -963,11 +984,14 @@ bool shortestline_tpoint_tpoint(const Temporal *temp1, const Temporal *temp2, GSERIALIZED **result) { - assert(temp1); assert(temp2); assert(result); - ensure_tgeo_type(temp1->temptype); - ensure_same_temporal_type(temp1, temp2); - ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)); - ensure_same_dimensionality(temp1->flags, temp2->flags); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_not_null((void *) result) || + ! ensure_tgeo_type(temp1->temptype) || + ! ensure_same_temporal_type(temp1, temp2) || + ! ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)) || + ! ensure_same_dimensionality(temp1->flags, temp2->flags)) + return false; Temporal *dist = distance_tpoint_tpoint(temp1, temp2); if (dist == NULL) diff --git a/meos/src/point/tpoint_meos.c b/meos/src/point/tpoint_meos.c deleted file mode 100644 index 7393ee0e08..0000000000 --- a/meos/src/point/tpoint_meos.c +++ /dev/null @@ -1,106 +0,0 @@ -/***************************************************************************** - * - * This MobilityDB code is provided under The PostgreSQL License. - * Copyright (c) 2016-2023, Université libre de Bruxelles and MobilityDB - * contributors - * - * MobilityDB includes portions of PostGIS version 3 source code released - * under the GNU General Public License (GPLv2 or later). - * Copyright (c) 2001-2023, PostGIS contributors - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without a written - * agreement is hereby granted, provided that the above copyright notice and - * this paragraph and the following two paragraphs appear in all copies. - * - * IN NO EVENT SHALL UNIVERSITE LIBRE DE BRUXELLES BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING - * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, - * EVEN IF UNIVERSITE LIBRE DE BRUXELLES HAS BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * UNIVERSITE LIBRE DE BRUXELLES SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON - * AN "AS IS" BASIS, AND UNIVERSITE LIBRE DE BRUXELLES HAS NO OBLIGATIONS TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - *****************************************************************************/ - -/** - * @file - * @brief General functions for temporal points. - */ - -#include "point/tpoint.h" - -/* C */ -#include -/* MEOS */ -#include "general/lifting.h" -#include "general/meos_catalog.h" -#include "general/temporaltypes.h" -#include "general/temporal_compops.h" -#include "general/type_util.h" -#include "point/stbox.h" -#include "point/tpoint_parser.h" -#include "point/tpoint_boxops.h" -#include "point/tpoint_spatialfuncs.h" - -/***************************************************************************** - * Temporal comparisons - *****************************************************************************/ - -/** - * @ingroup libmeos_temporal_comp - * @brief Return the temporal equality of a point and a temporal point - * @sqlop @p #= - */ -Temporal * -teq_geo_tpoint(const GSERIALIZED *gs, const Temporal *temp) -{ - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); - return tcomp_tpoint_point(temp, gs, &datum2_eq, INVERT); -} - -/** - * @ingroup libmeos_temporal_comp - * @brief Return the temporal equality of a temporal point and a point - * @sqlop @p #= - */ -Temporal * -teq_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs) -{ - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); - return tcomp_tpoint_point(temp, gs, &datum2_eq, INVERT_NO); -} - -/** - * @ingroup libmeos_temporal_comp - * @brief Return the temporal difference of a point and a temporal point - * @sqlop @p #<> - */ -Temporal * -tne_geo_tpoint(const GSERIALIZED *gs, const Temporal *temp) -{ - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); - return tcomp_tpoint_point(temp, gs, &datum2_ne, INVERT); -} - -/** - * @ingroup libmeos_temporal_comp - * @brief Return the temporal difference of the temporal point and a point - * @sqlop @p #<> - */ -Temporal * -tne_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs) -{ - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); - return tcomp_tpoint_point(temp, gs, &datum2_ne, INVERT_NO); -} - -/*****************************************************************************/ diff --git a/meos/src/point/tpoint_out.c b/meos/src/point/tpoint_out.c index 55a73f8a8a..6381a6b405 100644 --- a/meos/src/point/tpoint_out.c +++ b/meos/src/point/tpoint_out.c @@ -98,9 +98,9 @@ char * tpoint_as_text(const Temporal *temp, int maxdd) { /* Ensure validity of the arguments */ - assert(temp); - ensure_tgeo_type(temp->temptype); - ensure_non_negative(maxdd); + if (! ensure_not_null((void *) temp) || ! ensure_tgeo_type(temp->temptype) || + ! ensure_non_negative(maxdd)) + return NULL; char *result; assert(temptype_subtype(temp->subtype)); @@ -123,8 +123,8 @@ char * tpoint_as_ewkt(const Temporal *temp, int maxdd) { /* Ensure validity of the arguments */ - assert(temp); - ensure_non_negative(maxdd); + if (! ensure_not_null((void *) temp) || ! ensure_non_negative(maxdd)) + return NULL; int srid = tpoint_srid(temp); char str1[20]; @@ -157,10 +157,9 @@ tpoint_as_ewkt(const Temporal *temp, int maxdd) char ** geoarr_as_text(const Datum *geoarr, int count, int maxdd, bool extended) { - /* Ensure validity of the arguments */ assert(geoarr); assert(count > 0); - ensure_non_negative(maxdd); + assert(maxdd >= 0); char **result = palloc(sizeof(char *) * count); for (int i = 0; i < count; i++) @@ -180,10 +179,9 @@ char ** tpointarr_as_text(const Temporal **temparr, int count, int maxdd, bool extended) { - /* Ensure validity of the arguments */ assert(temparr); assert(count > 0); - ensure_non_negative(maxdd); + assert(maxdd >= 0); char **result = palloc(sizeof(text *) * count); for (int i = 0; i < count; i++) diff --git a/meos/src/point/tpoint_parser.c b/meos/src/point/tpoint_parser.c index b98b6e3774..e18ff91d08 100644 --- a/meos/src/point/tpoint_parser.c +++ b/meos/src/point/tpoint_parser.c @@ -56,6 +56,7 @@ stbox_parse(const char **str) bool hasx = false, hasz = false, hast = false, geodetic = false; int srid = 0; bool hassrid = false; + const char *type_str = "spatiotemporal box"; /* Determine whether the box has an SRID */ p_whitespace(str); @@ -91,7 +92,11 @@ stbox_parse(const char **str) srid = 4326; } else - elog(ERROR, "Could not parse spatiotemporal box"); + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Could not parse spatiotemporal box"); + return NULL; + } /* Determine whether the box has X, Z, and/or T dimensions */ if (pg_strncasecmp(*str, "ZT", 2) == 0) @@ -120,24 +125,31 @@ stbox_parse(const char **str) hast = true; } else - elog(ERROR, "Could not parse spatiotemporal box: Missing dimension information"); + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Could not parse spatiotemporal box: Missing dimension information"); + return NULL; + } /* Parse external opening parenthesis (if both space and time dimensions) */ if (hast) { p_whitespace(str); - ensure_oparen(str, "spatiotemporal box"); + if (! ensure_oparen(str, type_str)) + return NULL; } if (hasx) { /* Parse enclosing opening parenthesis */ p_whitespace(str); - ensure_oparen(str, "spatiotemporal box"); + if (! ensure_oparen(str, type_str)) + return NULL; /* Parse lower bounds */ p_whitespace(str); - ensure_oparen(str, "spatiotemporal box"); + if (! ensure_oparen(str, type_str)) + return NULL; /* xmin */ xmin = double_parse(str); /* ymin */ @@ -154,7 +166,8 @@ stbox_parse(const char **str) zmin = double_parse(str); } p_whitespace(str); - ensure_cparen(str, "spatiotemporal box"); + if (! ensure_cparen(str, type_str)) + return NULL; /* Parse optional comma */ p_whitespace(str); @@ -162,7 +175,8 @@ stbox_parse(const char **str) /* Parse upper bounds */ p_whitespace(str); - ensure_oparen(str, "spatiotemporal box"); + if (! ensure_oparen(str, type_str)) + return NULL; /* xmax */ xmax = double_parse(str); /* ymax */ @@ -179,11 +193,13 @@ stbox_parse(const char **str) zmax = double_parse(str); } p_whitespace(str); - ensure_cparen(str, "spatiotemporal box"); + if (! ensure_cparen(str, type_str)) + return NULL; /* Parse enclosing closing parenthesis */ p_whitespace(str); - ensure_cparen(str, "spatiotemporal box"); + if (! ensure_cparen(str, type_str)) + return NULL; if (hast) { @@ -204,11 +220,13 @@ stbox_parse(const char **str) if (hast) { p_whitespace(str); - ensure_cparen(str, "spatiotemporal box"); + if (! ensure_cparen(str, type_str)) + return NULL; } /* Ensure there is no more input */ - ensure_end_input(str, true, "spatiotemporal box"); + if (! ensure_end_input(str, type_str)) + return NULL; return stbox_make(hasx, hasz, geodetic, srid, xmin, xmax, ymin, ymax, zmin, zmax, hast ? &period : NULL); @@ -234,9 +252,12 @@ tpointinst_parse(const char **str, meosType temptype, bool end, bool make, /* The next instruction will throw an exception if it fails */ Datum geo = temporal_basetype_parse(str, basetype); GSERIALIZED *gs = DatumGetGserializedP(geo); - ensure_point_type(gs); - ensure_non_empty(gs); - ensure_has_not_M_gs(gs); + if (! ensure_point_type(gs) || ! ensure_non_empty(gs) || + ! ensure_has_not_M_gs(gs)) + { + pfree(gs); + return NULL; + } /* If one of the SRID of the temporal point and of the geometry * is SRID_UNKNOWN and the other not, copy the SRID */ int geo_srid = gserialized_get_srid(gs); @@ -247,13 +268,21 @@ tpointinst_parse(const char **str, meosType temptype, bool end, bool make, /* If the SRID of the temporal point and of the geometry do not match */ else if (*tpoint_srid != SRID_UNKNOWN && geo_srid != SRID_UNKNOWN && *tpoint_srid != geo_srid) - elog(ERROR, "Geometry SRID (%d) does not match temporal type SRID (%d)", + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Geometry SRID (%d) does not match temporal type SRID (%d)", geo_srid, *tpoint_srid); + pfree(gs); + return NULL; + } /* The next instruction will throw an exception if it fails */ TimestampTz t = timestamp_parse(str); - ensure_end_input(str, end, "temporal point"); - TInstant *result = make ? - tinstant_make(PointerGetDatum(gs), temptype, t) : NULL; + if ((end && ! ensure_end_input(str, "temporal point")) || ! make) + { + pfree(gs); + return NULL; + } + TInstant *result = tinstant_make(PointerGetDatum(gs), temptype, t); pfree(gs); return result; } @@ -267,6 +296,7 @@ tpointinst_parse(const char **str, meosType temptype, bool end, bool make, TSequence * tpointseq_disc_parse(const char **str, meosType temptype, int *tpoint_srid) { + const char *type_str = "temporal point"; p_whitespace(str); /* We are sure to find an opening brace because that was the condition * to call this function in the dispatch function tpoint_parse */ @@ -281,9 +311,8 @@ tpointseq_disc_parse(const char **str, meosType temptype, int *tpoint_srid) count++; tpointinst_parse(str, temptype, false, false, tpoint_srid); } - if (!p_cbrace(str)) - elog(ERROR, "Could not parse temporal point value: Missing closing brace"); - ensure_end_input(str, true, "temporal point"); + if (! ensure_cbrace(str, type_str) || ! ensure_end_input(str, type_str)) + return NULL; /* Second parsing */ *str = bak; @@ -335,10 +364,13 @@ tpointseq_cont_parse(const char **str, meosType temptype, interpType interp, else if (p_cparen(str)) upper_inc = false; else - elog(ERROR, "Could not parse temporal point value: Missing closing bracket/parenthesis"); + { + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "Could not parse temporal point value: Missing closing bracket/parenthesis"); + return NULL; + } /* Ensure there is no more input */ - ensure_end_input(str, end, "temporal point"); - if (! make) + if ((end && ! ensure_end_input(str, "temporal point")) || ! make) return NULL; /* Second parsing */ @@ -351,8 +383,8 @@ tpointseq_cont_parse(const char **str, meosType temptype, interpType interp, } p_cbracket(str); p_cparen(str); - return tsequence_make_free(instants, count, lower_inc, upper_inc, - interp, NORMALIZE); + return tsequence_make_free(instants, count, lower_inc, upper_inc, interp, + NORMALIZE); } /** @@ -366,6 +398,7 @@ TSequenceSet * tpointseqset_parse(const char **str, meosType temptype, interpType interp, int *tpoint_srid) { + const char *type_str = "temporal point"; p_whitespace(str); /* We are sure to find an opening brace because that was the condition * to call this function in the dispatch function tpoint_parse */ @@ -380,9 +413,8 @@ tpointseqset_parse(const char **str, meosType temptype, interpType interp, count++; tpointseq_cont_parse(str, temptype, interp, false, false, tpoint_srid); } - if (!p_cbrace(str)) - elog(ERROR, "Could not parse temporal point value: Missing closing brace"); - ensure_end_input(str, true, "temporal point"); + if (! ensure_cbrace(str, type_str) || ! ensure_end_input(str, type_str)) + return NULL; /* Second parsing */ *str = bak; @@ -489,7 +521,9 @@ tpoint_parse(const char **str, meosType temptype) Temporal * tgeompoint_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return tpoint_parse(&str, T_TGEOMPOINT); } /** @@ -500,7 +534,9 @@ tgeompoint_in(const char *str) Temporal * tgeogpoint_in(const char *str) { - assert(str); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) str)) + return NULL; return tpoint_parse(&str, T_TGEOGPOINT); } #endif /* MEOS */ diff --git a/meos/src/point/tpoint_restrfuncs.c b/meos/src/point/tpoint_restrfuncs.c index d54720f469..7d0c884295 100644 --- a/meos/src/point/tpoint_restrfuncs.c +++ b/meos/src/point/tpoint_restrfuncs.c @@ -77,9 +77,11 @@ point_force2d(Datum point, Datum srid) static Temporal * tpoint_force2d(const Temporal *temp) { - assert(temp); - assert(tgeo_type(temp->temptype)); - assert(MEOS_FLAGS_GET_Z(temp->flags)); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tgeo_type(temp->temptype) || + ! ensure_has_Z(temp->flags)) + return NULL; + /* We only need to fill these parameters for tfunc_temporal */ LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); @@ -514,8 +516,10 @@ tpointseqset_is_simple(const TSequenceSet *ss) bool tpoint_is_simple(const Temporal *temp) { - assert(temp); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tgeo_type(temp->temptype)) + return false; + bool result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -715,8 +719,11 @@ tpointseqset_make_simple(const TSequenceSet *ss, int *count) Temporal ** tpoint_make_simple(const Temporal *temp, int *count) { - assert(temp); assert(count); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) count) || + ! ensure_tgeo_type(temp->temptype)) + return NULL; + Temporal **result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -779,10 +786,11 @@ point_get_z(Datum point) Temporal * tpoint_get_coord(const Temporal *temp, int coord) { - assert(temp); - assert(tgeo_type(temp->temptype)); - if (coord == 2) - ensure_has_Z(temp->flags); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tgeo_type(temp->temptype) || + (coord == 2 && ! ensure_has_Z(temp->flags))) + return NULL; + /* We only need to fill these parameters for tfunc_temporal */ LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); @@ -875,7 +883,7 @@ TSequence * tpointseq_disc_restrict_geom_time(const TSequence *seq, const GSERIALIZED *gs, const Span *zspan, const Span *period, bool atfunc) { - assert(seq); assert(gs); + assert(seq); ensure_not_null((void *) gs); assert(tgeo_type(seq->temptype)); assert(MEOS_FLAGS_GET_INTERP(seq->flags) == DISCRETE); assert(seq->count > 1); @@ -913,7 +921,7 @@ TSequenceSet * tpointseq_step_restrict_geom_time(const TSequence *seq, const GSERIALIZED *gs, const Span *zspan, const Span *period, bool atfunc) { - assert(seq); assert(gs); + assert(seq); ensure_not_null((void *) gs); assert(tgeo_type(seq->temptype)); assert(MEOS_FLAGS_GET_INTERP(seq->flags) == STEP); assert(seq->count > 1); @@ -1091,7 +1099,8 @@ tpointseq_timestamp_at_value(const TSequence *seq, Datum value, inst1 = inst2; } /* We should never arrive here */ - elog(ERROR, "The value has not been found due to roundoff errors"); + meos_error(ERROR, MEOS_ERR_TEXT_INPUT, + "The value has not been found due to roundoff errors"); return false; } @@ -1128,27 +1137,27 @@ tpointseq_interperiods(const TSequence *seq, GSERIALIZED *gsinter, int *count) } /* General case */ - LWGEOM *lwgeom_inter = lwgeom_from_gserialized(gsinter); - int type = lwgeom_inter->type; + LWGEOM *geom_inter = lwgeom_from_gserialized(gsinter); + int type = geom_inter->type; int ninter; - LWPOINT *lwpoint_inter = NULL; /* make compiler quiet */ - LWLINE *lwline_inter = NULL; /* make compiler quiet */ + LWPOINT *point_inter = NULL; /* make compiler quiet */ + LWLINE *line_inter = NULL; /* make compiler quiet */ LWCOLLECTION *coll = NULL; /* make compiler quiet */ if (type == POINTTYPE) { ninter = 1; - lwpoint_inter = lwgeom_as_lwpoint(lwgeom_inter); + point_inter = lwgeom_as_lwpoint(geom_inter); } else if (type == LINETYPE) { ninter = 1; - lwline_inter = lwgeom_as_lwline(lwgeom_inter); + line_inter = lwgeom_as_lwline(geom_inter); } else /* It is a collection of type MULTIPOINTTYPE, MULTILINETYPE, or * COLLECTIONTYPE */ { - coll = lwgeom_as_lwcollection(lwgeom_inter); + coll = lwgeom_as_lwcollection(geom_inter); ninter = coll->ngeoms; } Span *periods = palloc(sizeof(Span) * ninter); @@ -1160,9 +1169,9 @@ tpointseq_interperiods(const TSequence *seq, GSERIALIZED *gsinter, int *count) /* Find the i-th intersection */ LWGEOM *subgeom = coll->geoms[i]; if (subgeom->type == POINTTYPE) - lwpoint_inter = lwgeom_as_lwpoint(subgeom); + point_inter = lwgeom_as_lwpoint(subgeom); else /* type == LINETYPE */ - lwline_inter = lwgeom_as_lwline(subgeom); + line_inter = lwgeom_as_lwline(subgeom); type = subgeom->type; } TimestampTz t1, t2; @@ -1170,7 +1179,7 @@ tpointseq_interperiods(const TSequence *seq, GSERIALIZED *gsinter, int *count) /* Each intersection is either a point or a linestring */ if (type == POINTTYPE) { - gspoint = geo_serialize((LWGEOM *) lwpoint_inter); + gspoint = geo_serialize((LWGEOM *) point_inter); tpointseq_timestamp_at_value(seq, PointerGetDatum(gspoint), &t1); pfree(gspoint); /* If the intersection is not at an exclusive bound */ @@ -1181,13 +1190,13 @@ tpointseq_interperiods(const TSequence *seq, GSERIALIZED *gsinter, int *count) else { /* Get the fraction of the start point of the intersecting line */ - LWPOINT *lwpoint = lwline_get_lwpoint(lwline_inter, 0); - gspoint = geo_serialize((LWGEOM *) lwpoint); + LWPOINT *point = lwline_get_lwpoint(line_inter, 0); + gspoint = geo_serialize((LWGEOM *) point); tpointseq_timestamp_at_value(seq, PointerGetDatum(gspoint), &t1); pfree(gspoint); /* Get the fraction of the end point of the intersecting line */ - lwpoint = lwline_get_lwpoint(lwline_inter, lwline_inter->points->npoints - 1); - gspoint = geo_serialize((LWGEOM *) lwpoint); + point = lwline_get_lwpoint(line_inter, line_inter->points->npoints - 1); + gspoint = geo_serialize((LWGEOM *) point); tpointseq_timestamp_at_value(seq, PointerGetDatum(gspoint), &t2); pfree(gspoint); /* If t1 == t2 and the intersection is not at an exclusive bound */ @@ -1208,7 +1217,7 @@ tpointseq_interperiods(const TSequence *seq, GSERIALIZED *gsinter, int *count) } } } - lwgeom_free(lwgeom_inter); + lwgeom_free(geom_inter); if (npers == 0) { @@ -1374,7 +1383,7 @@ TSequenceSet * tpointseq_linear_restrict_geom_time(const TSequence *seq, const GSERIALIZED *gs, const Span *zspan, const Span *period, bool atfunc) { - assert(seq); assert(gs); + assert(seq); ensure_not_null((void *) gs); assert(tgeo_type(seq->temptype)); assert(MEOS_FLAGS_GET_LINEAR(seq->flags)); assert(seq->count > 1); @@ -1557,11 +1566,11 @@ Temporal * tpoint_restrict_geom_time(const Temporal *temp, const GSERIALIZED *gs, const Span *zspan, const Span *period, bool atfunc) { - /* Parameter test */ assert(temp); assert(gs); assert(tgeo_type(temp->temptype)); if (gserialized_is_empty(gs)) return atfunc ? NULL : temporal_copy(temp); + /* Ensure validity of the arguments */ ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)); ensure_has_not_Z_gs(gs); if (zspan) @@ -1611,8 +1620,10 @@ Temporal * tpoint_at_geom_time(const Temporal *temp, const GSERIALIZED *gs, const Span *zspan, const Span *period) { - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_tgeo_type(temp->temptype)) + return NULL; return tpoint_restrict_geom_time(temp, gs, zspan, period, REST_AT); } @@ -1625,8 +1636,10 @@ Temporal * tpoint_minus_geom_time(const Temporal *temp, const GSERIALIZED *gs, const Span *zspan, const Span *period) { - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_tgeo_type(temp->temptype)) + return NULL; return tpoint_restrict_geom_time(temp, gs, zspan, period, REST_MINUS); } #endif /* MEOS */ @@ -2443,14 +2456,19 @@ tpoint_restrict_stbox(const Temporal *temp, const STBox *box, bool border_inc, bool hasx = MEOS_FLAGS_GET_X(box->flags); bool hast = MEOS_FLAGS_GET_T(box->flags); assert(hasx || hast); + /* Ensure validity of the arguments */ + if (! ensure_same_geodetic(temp->flags, box->flags) || + ! ensure_same_srid(tpoint_srid(temp), stbox_srid(box))) + return NULL; /* Short-circuit restriction to only T dimension */ if (hast && ! hasx) return temporal_restrict_period(temp, &box->period, atfunc); /* Parameter test */ - ensure_same_srid(tpoint_srid(temp), stbox_srid(box)); - ensure_same_geodetic(temp->flags, box->flags); + assert(tpoint_srid(temp) == stbox_srid(box)); + assert(MEOS_FLAGS_GET_GEODETIC(temp->flags) == + MEOS_FLAGS_GET_GEODETIC(box->flags)); /* Bounding box test */ STBox box1; @@ -2482,8 +2500,10 @@ tpoint_restrict_stbox(const Temporal *temp, const STBox *box, bool border_inc, Temporal * tpoint_at_stbox(const Temporal *temp, const STBox *box, bool border_inc) { - assert(temp); assert(box); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) box) || + ! ensure_tgeo_type(temp->temptype)) + return NULL; Temporal *result = tpoint_restrict_stbox(temp, box, border_inc, REST_AT); return result; } @@ -2496,8 +2516,10 @@ tpoint_at_stbox(const Temporal *temp, const STBox *box, bool border_inc) Temporal * tpoint_minus_stbox(const Temporal *temp, const STBox *box, bool border_inc) { - assert(temp); assert(box); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) box) || + ! ensure_tgeo_type(temp->temptype)) + return NULL; Temporal *result = tpoint_restrict_stbox(temp, box, border_inc, REST_MINUS); return result; } diff --git a/meos/src/point/tpoint_spatialfuncs.c b/meos/src/point/tpoint_spatialfuncs.c index 55347ae1d6..d70113c92a 100644 --- a/meos/src/point/tpoint_spatialfuncs.c +++ b/meos/src/point/tpoint_spatialfuncs.c @@ -324,230 +324,325 @@ geom_intersection2d(Datum geom1, Datum geom2) * @brief Ensure that the spatial constraints required for operating on two * temporal geometries are satisfied */ -void +bool ensure_spatial_validity(const Temporal *temp1, const Temporal *temp2) { - if (tgeo_type(temp1->temptype)) - { - ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)); - ensure_same_dimensionality(temp1->flags, temp2->flags); - } - return; + if (tgeo_type(temp1->temptype) && + (! ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)) || + ! ensure_same_dimensionality(temp1->flags, temp2->flags))) + return false; + return true; } /** * @brief Ensure that the spatiotemporal argument has planar coordinates */ -void +bool ensure_not_geodetic(int16 flags) { if (MEOS_FLAGS_GET_GEODETIC(flags)) - elog(ERROR, "Only planar coordinates supported"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Only planar coordinates supported"); + return false; + } + return true; } /** * @brief Ensure that the spatiotemporal argument have the same type of * coordinates, either planar or geodetic */ -void +bool ensure_same_geodetic(int16 flags1, int16 flags2) { if (MEOS_FLAGS_GET_X(flags1) && MEOS_FLAGS_GET_X(flags2) && MEOS_FLAGS_GET_GEODETIC(flags1) != MEOS_FLAGS_GET_GEODETIC(flags2)) - elog(ERROR, "Operation on mixed planar and geodetic coordinates"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Operation on mixed planar and geodetic coordinates"); + return false; + } + return true; } /** * @brief Ensure that the two spatial "objects" have the same SRID */ -void +bool ensure_same_srid(int32_t srid1, int32_t srid2) { if (srid1 != srid2) - elog(ERROR, "Operation on mixed SRID"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Operation on mixed SRID"); + return false; + } + return true; } /** * @brief Ensure that a temporal point and a geometry/geography have the same * SRID */ -void +bool ensure_same_srid_stbox_gs(const STBox *box, const GSERIALIZED *gs) { if (box->srid != gserialized_get_srid(gs)) - elog(ERROR, "Operation on mixed SRID"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Operation on mixed SRID"); + return false; + } + return true; } /** * @brief Ensure that two temporal points have the same dimensionality as given * by their flags */ -void +bool ensure_same_dimensionality(int16 flags1, int16 flags2) { if (MEOS_FLAGS_GET_X(flags1) != MEOS_FLAGS_GET_X(flags2) || - MEOS_FLAGS_GET_Z(flags1) != MEOS_FLAGS_GET_Z(flags2) || - MEOS_FLAGS_GET_T(flags1) != MEOS_FLAGS_GET_T(flags2)) - elog(ERROR, "The arguments must be of the same dimensionality"); - return; + MEOS_FLAGS_GET_Z(flags1) != MEOS_FLAGS_GET_Z(flags2) || + MEOS_FLAGS_GET_T(flags1) != MEOS_FLAGS_GET_T(flags2)) + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The arguments must be of the same dimensionality"); + return false; + } + return true; +} + +/** + * @brief Return true if the two temporal points have the same spatial + * dimensionality as given by their flags + */ +bool +same_spatial_dimensionality(int16 flags1, int16 flags2) +{ + if (MEOS_FLAGS_GET_X(flags1) != MEOS_FLAGS_GET_X(flags2) || + MEOS_FLAGS_GET_Z(flags1) != MEOS_FLAGS_GET_Z(flags2)) + return false; + return true; } /** * @brief Ensure that two temporal points have the same spatial dimensionality * as given by their flags */ -void +bool ensure_same_spatial_dimensionality(int16 flags1, int16 flags2) { - if (MEOS_FLAGS_GET_X(flags1) != MEOS_FLAGS_GET_X(flags2) || - MEOS_FLAGS_GET_Z(flags1) != MEOS_FLAGS_GET_Z(flags2)) - elog(ERROR, "Operation on mixed 2D/3D dimensions"); - return; + if (! same_spatial_dimensionality(flags1, flags2)) + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Operation on mixed 2D/3D dimensions"); + return false; + } + return true; } /** * @brief Ensure that a temporal point and a spatiotemporal box have the same * spatial dimensionality as given by their flags */ -void +bool ensure_same_spatial_dimensionality_temp_box(int16 flags1, int16 flags2) { if (MEOS_FLAGS_GET_X(flags1) != MEOS_FLAGS_GET_X(flags2) || /* Geodetic boxes are always in 3D */ (! MEOS_FLAGS_GET_GEODETIC(flags2) && MEOS_FLAGS_GET_Z(flags1) != MEOS_FLAGS_GET_Z(flags2))) - elog(ERROR, "Operation on mixed 2D/3D dimensions"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Operation on mixed 2D/3D dimensions"); + return false; + } + return true; } /** * @brief Ensure that two geometries/geographies have the same dimensionality */ -void +bool ensure_same_dimensionality_gs(const GSERIALIZED *gs1, const GSERIALIZED *gs2) { if (FLAGS_GET_Z(gs1->gflags) != FLAGS_GET_Z(gs2->gflags)) - elog(ERROR, "Operation on mixed 2D/3D dimensions"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Operation on mixed 2D/3D dimensions"); + return false; + } + return true; +} + +/** + * @brief Return true if a temporal point and a geometry/geography have the + * same dimensionality + */ +bool +same_dimensionality_tpoint_gs(const Temporal *temp, const GSERIALIZED *gs) +{ + if (MEOS_FLAGS_GET_Z(temp->flags) != FLAGS_GET_Z(gs->gflags)) + return false; + return true; } /** * @brief Ensure that a temporal point and a geometry/geography have the same * dimensionality */ -void +bool ensure_same_dimensionality_tpoint_gs(const Temporal *temp, const GSERIALIZED *gs) { - if (MEOS_FLAGS_GET_Z(temp->flags) != FLAGS_GET_Z(gs->gflags)) - elog(ERROR, "Operation on mixed 2D/3D dimensions"); - return; + if (! same_dimensionality_tpoint_gs(temp, gs)) + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Operation on mixed 2D/3D dimensions"); + return false; + } + return true; } /** * @brief Ensure that the spatiotemporal boxes have the same spatial * dimensionality */ -void +bool ensure_same_spatial_dimensionality_stbox_gs(const STBox *box, const GSERIALIZED *gs) { if (! MEOS_FLAGS_GET_X(box->flags) || /* Geodetic boxes are always in 3D */ (! MEOS_FLAGS_GET_GEODETIC(box->flags) && MEOS_FLAGS_GET_Z(box->flags) != FLAGS_GET_Z(gs->gflags))) - elog(ERROR, "The spatiotemporal box and the geometry must be of the same dimensionality"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The spatiotemporal box and the geometry must be of the same dimensionality"); + return false; + } + return true; } /** * @brief Ensure that a temporal point has Z dimension */ -void +bool ensure_has_Z(int16 flags) { if (! MEOS_FLAGS_GET_Z(flags)) - elog(ERROR, "The temporal point must have Z dimension"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal point must have Z dimension"); + return false; + } + return true; } /** * @brief Ensure that a temporal point has not Z dimension */ -void +bool ensure_has_not_Z(int16 flags) { if (MEOS_FLAGS_GET_Z(flags)) - elog(ERROR, "The temporal point cannot have Z dimension"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The temporal point cannot have Z dimension"); + return false; + } + return true; } /** * @brief Ensure that the geometry/geography has not Z dimension */ -void +bool ensure_has_Z_gs(const GSERIALIZED *gs) { if (! FLAGS_GET_Z(gs->gflags)) - elog(ERROR, "The geometry must have Z dimension"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The geometry must have Z dimension"); + return false; + } + return true; } /** * @brief Ensure that the geometry/geography has not Z dimension */ -void +bool ensure_has_not_Z_gs(const GSERIALIZED *gs) { if (FLAGS_GET_Z(gs->gflags)) - elog(ERROR, "The geometry cannot have Z dimension"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "The geometry cannot have Z dimension"); + return false; + } + return true; } /** * @brief Ensure that the geometry/geography has M dimension */ -void +bool ensure_has_M_gs(const GSERIALIZED *gs) { if (! FLAGS_GET_M(gs->gflags)) - elog(ERROR, "Only geometries with M dimension accepted"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Only geometries with M dimension accepted"); + return false; + } + return true; } /** * @brief Ensure that the geometry/geography has not M dimension */ -void +bool ensure_has_not_M_gs(const GSERIALIZED *gs) { if (FLAGS_GET_M(gs->gflags)) - elog(ERROR, "Only geometries without M dimension accepted"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Only geometries without M dimension accepted"); + return false; + } + return true; } /** * @brief Ensure that the geometry/geography is a point */ -void +bool ensure_point_type(const GSERIALIZED *gs) { if (gserialized_get_type(gs) != POINTTYPE) - elog(ERROR, "Only point geometries accepted"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Only point geometries accepted"); + return false; + } + return true; } /** * @brief Ensure that the geometry/geography is not empty */ -void +bool ensure_non_empty(const GSERIALIZED *gs) { if (gserialized_is_empty(gs)) - elog(ERROR, "Only non-empty geometries accepted"); - return; + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Only non-empty geometries accepted"); + return false; + } + return true; } /***************************************************************************** @@ -752,17 +847,20 @@ tpointseqset_ever_eq(const TSequenceSet *ss, Datum value) * @see tpointseqset_ever_eq */ bool -tpoint_ever_eq(const Temporal *temp, Datum value) +tpoint_ever_eq(const Temporal *temp, const GSERIALIZED *gs) { - assert(temp); - ensure_tgeo_type(temp->temptype); - GSERIALIZED *gs = DatumGetGserializedP(value); - if (gserialized_is_empty(gs)) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_tgeo_type(temp->temptype) || gserialized_is_empty(gs)) + return false; + meosType geotype = FLAGS_GET_GEODETIC(gs->gflags) ? T_GEOGRAPHY : T_GEOMETRY; + if (! ensure_same_temporal_basetype(temp, geotype) || + ! ensure_point_type(gs) || + ! ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)) || + ! ensure_same_dimensionality_tpoint_gs(temp, gs)) return false; - ensure_point_type(gs); - ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)); - ensure_same_dimensionality_tpoint_gs(temp, gs); + Datum value = PointerGetDatum(gs); bool result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -774,33 +872,6 @@ tpoint_ever_eq(const Temporal *temp, Datum value) return result; } -#if MEOS -/** - * @ingroup libmeos_temporal_ever - * @brief Return true if a temporal geometric point is ever equal to a point. - * @sqlop @p ?= - */ -bool tgeompoint_ever_eq(const Temporal *temp, GSERIALIZED *gs) -{ - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); - return tpoint_ever_eq(temp, PointerGetDatum(gs)); - -} - -/** - * @ingroup libmeos_temporal_ever - * @brief Return true if a temporal geographic point is ever equal to a point. - * @sqlop @p ?= - */ -bool tgeogpoint_ever_eq(const Temporal *temp, GSERIALIZED *gs) -{ - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); - return tpoint_ever_eq(temp, PointerGetDatum(gs)); -} -#endif /* MEOS */ - /*****************************************************************************/ /** @@ -866,17 +937,20 @@ tpointseqset_always_eq(const TSequenceSet *ss, Datum value) * @sqlop @p %= */ bool -tpoint_always_eq(const Temporal *temp, Datum value) +tpoint_always_eq(const Temporal *temp, const GSERIALIZED *gs) { - assert(temp); - assert(tgeo_type(temp->temptype)); - GSERIALIZED *gs = DatumGetGserializedP(value); - if (gserialized_is_empty(gs)) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_tgeo_type(temp->temptype) || gserialized_is_empty(gs)) + return false; + meosType geotype = FLAGS_GET_GEODETIC(gs->gflags) ? T_GEOGRAPHY : T_GEOMETRY; + if (! ensure_same_temporal_basetype(temp, geotype) || + ! ensure_point_type(gs) || + ! ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)) || + ! ensure_same_dimensionality_tpoint_gs(temp, gs)) return false; - ensure_point_type(gs); - ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)); - ensure_same_dimensionality_tpoint_gs(temp, gs); + Datum value = PointerGetDatum(gs); bool result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -888,32 +962,6 @@ tpoint_always_eq(const Temporal *temp, Datum value) return result; } -#if MEOS -/** - * @ingroup libmeos_temporal_ever - * @brief Return true if a temporal geometric point is always equal to a point. - * @sqlop @p %= - */ -bool tgeompoint_always_eq(const Temporal *temp, GSERIALIZED *gs) -{ - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); - return tpoint_always_eq(temp, PointerGetDatum(gs)); -} - -/** - * @ingroup libmeos_temporal_ever - * @brief Return true if a temporal geographic point is always equal to a point. - * @sqlop @p %= - */ -bool tgeogpoint_always_eq(const Temporal *temp, GSERIALIZED *gs) -{ - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); - return tpoint_always_eq(temp, PointerGetDatum(gs)); -} -#endif /* MEOS */ - /***************************************************************************** * Functions derived from PostGIS to increase floating-point precision *****************************************************************************/ @@ -1125,11 +1173,11 @@ GSERIALIZED * gspoint_make(double x, double y, double z, bool hasz, bool geodetic, int32 srid) { - LWPOINT *lwpoint = hasz ? + LWPOINT *point = hasz ? lwpoint_make3dz(srid, x, y, z) : lwpoint_make2d(srid, x, y); - FLAGS_SET_GEODETIC(lwpoint->flags, geodetic); - GSERIALIZED *result = geo_serialize((LWGEOM *) lwpoint); - lwpoint_free(lwpoint); + FLAGS_SET_GEODETIC(point->flags, geodetic); + GSERIALIZED *result = geo_serialize((LWGEOM *) point); + lwpoint_free(point); return result; } @@ -1539,23 +1587,23 @@ lwpointarr_remove_duplicates(LWGEOM **points, int count, int *newcount) * @note The function does not remove duplicate points, that is, repeated * points in a multipoint or consecutive equal points in a line string. This * should be done in the calling function. - * @param[in] lwpoints Array of points + * @param[in] points Array of points * @param[in] count Number of elements in the input array * @param[in] interp Interpolation */ LWGEOM * -lwpointarr_make_trajectory(LWGEOM **lwpoints, int count, interpType interp) +lwpointarr_make_trajectory(LWGEOM **points, int count, interpType interp) { if (count == 1) - return lwpoint_as_lwgeom(lwpoint_clone(lwgeom_as_lwpoint(lwpoints[0]))); + return lwpoint_as_lwgeom(lwpoint_clone(lwgeom_as_lwpoint(points[0]))); LWGEOM *result = (interp == LINEAR) ? - (LWGEOM *) lwline_from_lwgeom_array(lwpoints[0]->srid, (uint32_t) count, - lwpoints) : - (LWGEOM *) lwcollection_construct(MULTIPOINTTYPE, lwpoints[0]->srid, - NULL, (uint32_t) count, lwpoints); - FLAGS_SET_Z(result->flags, FLAGS_GET_Z(lwpoints[0]->flags)); - FLAGS_SET_GEODETIC(result->flags, FLAGS_GET_GEODETIC(lwpoints[0]->flags)); + (LWGEOM *) lwline_from_lwgeom_array(points[0]->srid, (uint32_t) count, + points) : + (LWGEOM *) lwcollection_construct(MULTIPOINTTYPE, points[0]->srid, + NULL, (uint32_t) count, points); + FLAGS_SET_Z(result->flags, FLAGS_GET_Z(points[0]->flags)); + FLAGS_SET_GEODETIC(result->flags, FLAGS_GET_GEODETIC(points[0]->flags)); return result; } @@ -1629,10 +1677,10 @@ tpointseq_cont_trajectory(const TSequence *seq) { value = tinstant_value(TSEQUENCE_INST_N(seq, i)); gs = DatumGetGserializedP(value); - LWPOINT *lwpoint = lwgeom_as_lwpoint(lwgeom_from_gserialized(gs)); + LWPOINT *point = lwgeom_as_lwpoint(lwgeom_from_gserialized(gs)); /* Remove two consecutive points if they are equal */ - if (! lwpoint_same(lwpoint, (LWPOINT *) points[npoints - 1])) - points[npoints++] = (LWGEOM *) lwpoint; + if (! lwpoint_same(point, (LWPOINT *) points[npoints - 1])) + points[npoints++] = (LWGEOM *) point; } interpType interp = MEOS_FLAGS_GET_INTERP(seq->flags); LWGEOM *lwresult = lwpointarr_make_trajectory(points, npoints, interp); @@ -1667,7 +1715,7 @@ tpointseq_trajectory(const TSequence *seq) GSERIALIZED *result = MEOS_FLAGS_GET_DISCRETE(seq->flags) ? tpointseq_disc_trajectory(seq) : tpointseq_cont_trajectory(seq); - return result; + return result; } /** @@ -1762,22 +1810,22 @@ tpointseqset_trajectory(const TSequenceSet *ss) GSERIALIZED *gs = DatumGetGserializedP(value); /* npoints is the current number of points so far, k is the number of * additional points from the current sequence */ - LWGEOM *lwpoint1 = lwgeom_from_gserialized(gs); - points[npoints] = lwpoint1; + LWGEOM *point1 = lwgeom_from_gserialized(gs); + points[npoints] = point1; int k = 1; for (int j = 1; j < seq->count; j++) { value = tinstant_value(TSEQUENCE_INST_N(seq, j)); gs = DatumGetGserializedP(value); /* Do not add the point if it is equal to the previous ones */ - LWGEOM *lwpoint2 = lwgeom_from_gserialized(gs); - if (! lwpoint_same((LWPOINT *) lwpoint1, (LWPOINT *) lwpoint2)) + LWGEOM *point2 = lwgeom_from_gserialized(gs); + if (! lwpoint_same((LWPOINT *) point1, (LWPOINT *) point2)) { - points[npoints + k++] = lwpoint2; - lwpoint1 = lwpoint2; + points[npoints + k++] = point2; + point1 = point2; } else - lwgeom_free(lwpoint2); + lwgeom_free(point2); } if (linear && k > 1) { @@ -1809,8 +1857,10 @@ tpointseqset_trajectory(const TSequenceSet *ss) GSERIALIZED * tpoint_trajectory(const Temporal *temp) { - assert(temp); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tgeo_type(temp->temptype)) + return NULL; + GSERIALIZED *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -1878,8 +1928,10 @@ tpointseqset_srid(const TSequenceSet *ss) int tpoint_srid(const Temporal *temp) { - assert(temp); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tgeo_type(temp->temptype)) + return SRID_INVALID; + int result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -1977,8 +2029,10 @@ tpointseqset_set_srid(const TSequenceSet *ss, int32 srid) Temporal * tpoint_set_srid(const Temporal *temp, int32 srid) { - assert(temp); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tgeo_type(temp->temptype)) + return NULL; + Temporal *result; if (temp->subtype == TINSTANT) result = (Temporal *) tpointinst_set_srid((TInstant *) temp, srid); @@ -2031,24 +2085,24 @@ tgeompointinst_tgeogpointinst(const TInstant *inst, bool oper) assert(inst); assert(tgeo_type(inst->temptype)); GSERIALIZED *gs = DatumGetGserializedP(tinstant_value(inst)); - LWGEOM *lwgeom = lwgeom_from_gserialized(gs); + LWGEOM *geom = lwgeom_from_gserialized(gs); /* Short circuit functions gserialized_geog_from_geom and gserialized_geom_from_geog since we know it is a point */ - if ((int) lwgeom->srid <= 0) - lwgeom->srid = SRID_DEFAULT; + if ((int) geom->srid <= 0) + geom->srid = SRID_DEFAULT; if (oper == GEOM_TO_GEOG) { /* We cannot test the following without access to PROJ */ - // srid_check_latlong(lwgeom->srid); + // srid_check_latlong(geom->srid); /* Coerce the coordinate values into [-180 -90, 180 90] for GEOGRAPHY */ - pt_force_geodetic((LWPOINT *) lwgeom); - lwgeom_set_geodetic(lwgeom, true); + pt_force_geodetic((LWPOINT *) geom); + lwgeom_set_geodetic(geom, true); } else { - lwgeom_set_geodetic(lwgeom, false); + lwgeom_set_geodetic(geom, false); } - GSERIALIZED *newgs = geo_serialize(lwgeom); + GSERIALIZED *newgs = geo_serialize(geom); TInstant *result = tinstant_make(PointerGetDatum(newgs), (oper == GEOM_TO_GEOG) ? T_TGEOGPOINT : T_TGEOMPOINT, inst->t); pfree(newgs); @@ -2114,8 +2168,10 @@ tgeompointseqset_tgeogpointseqset(const TSequenceSet *ss, bool oper) Temporal * tgeompoint_tgeogpoint(const Temporal *temp, bool oper) { - assert(temp); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tgeo_type(temp->temptype)) + return NULL; + Temporal *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -2167,10 +2223,10 @@ datum_round_point(GSERIALIZED *gs, Datum size) assert(gserialized_get_type(gs) == POINTTYPE); bool hasz = (bool) FLAGS_GET_Z(gs->gflags); bool hasm = (bool) FLAGS_GET_M(gs->gflags); - LWPOINT *lwpoint = lwgeom_as_lwpoint(lwgeom_from_gserialized(gs)); - round_point(lwpoint->point, 0, size, hasz, hasm); - GSERIALIZED *result = geo_serialize((LWGEOM *) lwpoint); - pfree(lwpoint); + LWPOINT *point = lwgeom_as_lwpoint(lwgeom_from_gserialized(gs)); + round_point(point->point, 0, size, hasz, hasm); + GSERIALIZED *result = geo_serialize((LWGEOM *) point); + pfree(point); return PointerGetDatum(result); } @@ -2178,11 +2234,11 @@ datum_round_point(GSERIALIZED *gs, Datum size) * @brief Set the precision of the coordinates to the number of decimal places */ static void -round_linestring(LWLINE *lwline, Datum size, bool hasz, bool hasm) +round_linestring(LWLINE *line, Datum size, bool hasz, bool hasm) { - int npoints = lwline->points->npoints; + int npoints = line->points->npoints; for (int i = 0; i < npoints; i++) - round_point(lwline->points, i, size, hasz, hasm); + round_point(line->points, i, size, hasz, hasm); return; } @@ -2195,10 +2251,10 @@ datum_round_linestring(GSERIALIZED *gs, Datum size) assert(gserialized_get_type(gs) == LINETYPE); bool hasz = (bool) FLAGS_GET_Z(gs->gflags); bool hasm = (bool) FLAGS_GET_M(gs->gflags); - LWLINE *lwline = lwgeom_as_lwline(lwgeom_from_gserialized(gs)); - round_linestring(lwline, size, hasz, hasm); - GSERIALIZED *result = geo_serialize((LWGEOM *) lwline); - lwfree(lwline); + LWLINE *line = lwgeom_as_lwline(lwgeom_from_gserialized(gs)); + round_linestring(line, size, hasz, hasm); + GSERIALIZED *result = geo_serialize((LWGEOM *) line); + lwfree(line); return PointerGetDatum(result); } @@ -2206,11 +2262,11 @@ datum_round_linestring(GSERIALIZED *gs, Datum size) * @brief Set the precision of the coordinates to the number of decimal places */ static void -round_triangle(LWTRIANGLE *lwtriangle, Datum size, bool hasz, bool hasm) +round_triangle(LWTRIANGLE *triangle, Datum size, bool hasz, bool hasm) { - int npoints = lwtriangle->points->npoints; + int npoints = triangle->points->npoints; for (int i = 0; i < npoints; i++) - round_point(lwtriangle->points, i, size, hasz, hasm); + round_point(triangle->points, i, size, hasz, hasm); return; } @@ -2223,10 +2279,10 @@ datum_round_triangle(GSERIALIZED *gs, Datum size) assert(gserialized_get_type(gs) == TRIANGLETYPE); bool hasz = (bool) FLAGS_GET_Z(gs->gflags); bool hasm = (bool) FLAGS_GET_M(gs->gflags); - LWTRIANGLE *lwtriangle = lwgeom_as_lwtriangle(lwgeom_from_gserialized(gs)); - round_triangle(lwtriangle, size, hasz, hasm); - GSERIALIZED *result = geo_serialize((LWGEOM *) lwtriangle); - lwfree(lwtriangle); + LWTRIANGLE *triangle = lwgeom_as_lwtriangle(lwgeom_from_gserialized(gs)); + round_triangle(triangle, size, hasz, hasm); + GSERIALIZED *result = geo_serialize((LWGEOM *) triangle); + lwfree(triangle); return PointerGetDatum(result); } @@ -2234,12 +2290,12 @@ datum_round_triangle(GSERIALIZED *gs, Datum size) * @brief Set the precision of the coordinates to the number of decimal places */ static void -round_circularstring(LWCIRCSTRING *lwcircstring, Datum size, bool hasz, +round_circularstring(LWCIRCSTRING *circstring, Datum size, bool hasz, bool hasm) { - int npoints = lwcircstring->points->npoints; + int npoints = circstring->points->npoints; for (int i = 0; i < npoints; i++) - round_point(lwcircstring->points, i, size, hasz, hasm); + round_point(circstring->points, i, size, hasz, hasm); return; } @@ -2252,10 +2308,10 @@ datum_round_circularstring(GSERIALIZED *gs, Datum size) assert(gserialized_get_type(gs) == CIRCSTRINGTYPE); bool hasz = (bool) FLAGS_GET_Z(gs->gflags); bool hasm = (bool) FLAGS_GET_M(gs->gflags); - LWCIRCSTRING *lwcircstring = lwgeom_as_lwcircstring(lwgeom_from_gserialized(gs)); - round_circularstring(lwcircstring, size, hasz, hasm); - GSERIALIZED *result = geo_serialize((LWGEOM *) lwcircstring); - lwfree(lwcircstring); + LWCIRCSTRING *circstring = lwgeom_as_lwcircstring(lwgeom_from_gserialized(gs)); + round_circularstring(circstring, size, hasz, hasm); + GSERIALIZED *result = geo_serialize((LWGEOM *) circstring); + lwfree(circstring); return PointerGetDatum(result); } @@ -2263,12 +2319,12 @@ datum_round_circularstring(GSERIALIZED *gs, Datum size) * @brief Set the precision of the coordinates to the number of decimal places */ static void -round_polygon(LWPOLY *lwpoly, Datum size, bool hasz, bool hasm) +round_polygon(LWPOLY *poly, Datum size, bool hasz, bool hasm) { - int nrings = lwpoly->nrings; + int nrings = poly->nrings; for (int i = 0; i < nrings; i++) { - POINTARRAY *points = lwpoly->rings[i]; + POINTARRAY *points = poly->rings[i]; int npoints = points->npoints; for (int j = 0; j < npoints; j++) round_point(points, j, size, hasz, hasm); @@ -2285,10 +2341,10 @@ datum_round_polygon(GSERIALIZED *gs, Datum size) assert(gserialized_get_type(gs) == POLYGONTYPE); bool hasz = (bool) FLAGS_GET_Z(gs->gflags); bool hasm = (bool) FLAGS_GET_M(gs->gflags); - LWPOLY *lwpoly = lwgeom_as_lwpoly(lwgeom_from_gserialized(gs)); - round_polygon(lwpoly, size, hasz, hasm); - GSERIALIZED *result = geo_serialize((LWGEOM *) lwpoly); - lwfree(lwpoly); + LWPOLY *poly = lwgeom_as_lwpoly(lwgeom_from_gserialized(gs)); + round_polygon(poly, size, hasz, hasm); + GSERIALIZED *result = geo_serialize((LWGEOM *) poly); + lwfree(poly); return PointerGetDatum(result); } @@ -2296,13 +2352,13 @@ datum_round_polygon(GSERIALIZED *gs, Datum size) * @brief Set the precision of the coordinates to the number of decimal places */ static void -round_multipoint(LWMPOINT *lwmpoint, Datum size, bool hasz, bool hasm) +round_multipoint(LWMPOINT *mpoint, Datum size, bool hasz, bool hasm) { - int ngeoms = lwmpoint->ngeoms; + int ngeoms = mpoint->ngeoms; for (int i = 0; i < ngeoms; i++) { - LWPOINT *lwpoint = lwmpoint->geoms[i]; - round_point(lwpoint->point, 0, size, hasz, hasm); + LWPOINT *point = mpoint->geoms[i]; + round_point(point->point, 0, size, hasz, hasm); } return; } @@ -2316,10 +2372,10 @@ datum_round_multipoint(GSERIALIZED *gs, Datum size) assert(gserialized_get_type(gs) == MULTIPOINTTYPE); bool hasz = (bool) FLAGS_GET_Z(gs->gflags); bool hasm = (bool) FLAGS_GET_M(gs->gflags); - LWMPOINT *lwmpoint = lwgeom_as_lwmpoint(lwgeom_from_gserialized(gs)); - round_multipoint(lwmpoint, size, hasz, hasm); - GSERIALIZED *result = geo_serialize((LWGEOM *) lwmpoint); - lwfree(lwmpoint); + LWMPOINT *mpoint = lwgeom_as_lwmpoint(lwgeom_from_gserialized(gs)); + round_multipoint(mpoint, size, hasz, hasm); + GSERIALIZED *result = geo_serialize((LWGEOM *) mpoint); + lwfree(mpoint); return PointerGetDatum(result); } @@ -2327,15 +2383,15 @@ datum_round_multipoint(GSERIALIZED *gs, Datum size) * @brief Set the precision of the coordinates to the number of decimal places */ static void -round_multilinestring(LWMLINE *lwmline, Datum size, bool hasz, bool hasm) +round_multilinestring(LWMLINE *mline, Datum size, bool hasz, bool hasm) { - int ngeoms = lwmline->ngeoms; + int ngeoms = mline->ngeoms; for (int i = 0; i < ngeoms; i++) { - LWLINE *lwline = lwmline->geoms[i]; - int npoints = lwline->points->npoints; + LWLINE *line = mline->geoms[i]; + int npoints = line->points->npoints; for (int j = 0; j < npoints; j++) - round_point(lwline->points, j, size, hasz, hasm); + round_point(line->points, j, size, hasz, hasm); } return; } @@ -2349,10 +2405,10 @@ datum_round_multilinestring(GSERIALIZED *gs, Datum size) assert(gserialized_get_type(gs) == MULTILINETYPE); bool hasz = (bool) FLAGS_GET_Z(gs->gflags); bool hasm = (bool) FLAGS_GET_M(gs->gflags); - LWMLINE *lwmline = lwgeom_as_lwmline(lwgeom_from_gserialized(gs)); - round_multilinestring(lwmline, size, hasz, hasm); - GSERIALIZED *result = geo_serialize((LWGEOM *) lwmline); - lwfree(lwmline); + LWMLINE *mline = lwgeom_as_lwmline(lwgeom_from_gserialized(gs)); + round_multilinestring(mline, size, hasz, hasm); + GSERIALIZED *result = geo_serialize((LWGEOM *) mline); + lwfree(mline); return PointerGetDatum(result); } @@ -2360,13 +2416,13 @@ datum_round_multilinestring(GSERIALIZED *gs, Datum size) * @brief Set the precision of the coordinates to the number of decimal places */ static void -round_multipolygon(LWMPOLY *lwmpoly, Datum size, bool hasz, bool hasm) +round_multipolygon(LWMPOLY *mpoly, Datum size, bool hasz, bool hasm) { - int ngeoms = lwmpoly->ngeoms; + int ngeoms = mpoly->ngeoms; for (int i = 0; i < ngeoms; i++) { - LWPOLY *lwpoly = lwmpoly->geoms[i]; - round_polygon(lwpoly, size, hasz, hasm); + LWPOLY *poly = mpoly->geoms[i]; + round_polygon(poly, size, hasz, hasm); } return; } @@ -2380,10 +2436,10 @@ datum_round_multipolygon(GSERIALIZED *gs, Datum size) assert(gserialized_get_type(gs) == MULTIPOLYGONTYPE); bool hasz = (bool) FLAGS_GET_Z(gs->gflags); bool hasm = (bool) FLAGS_GET_M(gs->gflags); - LWMPOLY *lwmpoly = lwgeom_as_lwmpoly(lwgeom_from_gserialized(gs)); - round_multipolygon(lwmpoly, size, hasz, hasm); - GSERIALIZED *result = geo_serialize((LWGEOM *) lwmpoly); - lwfree(lwmpoly); + LWMPOLY *mpoly = lwgeom_as_lwmpoly(lwgeom_from_gserialized(gs)); + round_multipolygon(mpoly, size, hasz, hasm); + GSERIALIZED *result = geo_serialize((LWGEOM *) mpoly); + lwfree(mpoly); return PointerGetDatum(result); } @@ -2394,34 +2450,38 @@ static Datum datum_round_geometrycollection(GSERIALIZED *gs, Datum size) { assert(gserialized_get_type(gs) == COLLECTIONTYPE); - LWCOLLECTION *lwcol = lwgeom_as_lwcollection(lwgeom_from_gserialized(gs)); - int ngeoms = lwcol->ngeoms; + LWCOLLECTION *coll = lwgeom_as_lwcollection(lwgeom_from_gserialized(gs)); + int ngeoms = coll->ngeoms; bool hasz = (bool) FLAGS_GET_Z(gs->gflags); bool hasm = (bool) FLAGS_GET_M(gs->gflags); for (int i = 0; i < ngeoms; i++) { - LWGEOM *lwgeom = lwcol->geoms[i]; - if (lwgeom->type == POINTTYPE) - round_point((lwgeom_as_lwpoint(lwgeom))->point, 0, size, hasz, hasm); - else if (lwgeom->type == LINETYPE) - round_linestring(lwgeom_as_lwline(lwgeom), size, hasz, hasm); - else if (lwgeom->type == TRIANGLETYPE) - round_triangle(lwgeom_as_lwtriangle(lwgeom), size, hasz, hasm); - else if (lwgeom->type == CIRCSTRINGTYPE) - round_circularstring(lwgeom_as_lwcircstring(lwgeom), size, hasz, hasm); - else if (lwgeom->type == POLYGONTYPE) - round_polygon(lwgeom_as_lwpoly(lwgeom), size, hasz, hasm); - else if (lwgeom->type == MULTIPOINTTYPE) - round_multipoint(lwgeom_as_lwmpoint(lwgeom), size, hasz, hasm); - else if (lwgeom->type == MULTILINETYPE) - round_multilinestring(lwgeom_as_lwmline(lwgeom), size, hasz, hasm); - else if (lwgeom->type == MULTIPOLYGONTYPE) - round_multipolygon(lwgeom_as_lwmpoly(lwgeom), size, hasz, hasm); + LWGEOM *geom = coll->geoms[i]; + if (geom->type == POINTTYPE) + round_point((lwgeom_as_lwpoint(geom))->point, 0, size, hasz, hasm); + else if (geom->type == LINETYPE) + round_linestring(lwgeom_as_lwline(geom), size, hasz, hasm); + else if (geom->type == TRIANGLETYPE) + round_triangle(lwgeom_as_lwtriangle(geom), size, hasz, hasm); + else if (geom->type == CIRCSTRINGTYPE) + round_circularstring(lwgeom_as_lwcircstring(geom), size, hasz, hasm); + else if (geom->type == POLYGONTYPE) + round_polygon(lwgeom_as_lwpoly(geom), size, hasz, hasm); + else if (geom->type == MULTIPOINTTYPE) + round_multipoint(lwgeom_as_lwmpoint(geom), size, hasz, hasm); + else if (geom->type == MULTILINETYPE) + round_multilinestring(lwgeom_as_lwmline(geom), size, hasz, hasm); + else if (geom->type == MULTIPOLYGONTYPE) + round_multipolygon(lwgeom_as_lwmpoly(geom), size, hasz, hasm); else - elog(ERROR, "Unsupported geometry type"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Unsupported geometry type"); + return PointerGetDatum(NULL); + } } - GSERIALIZED *result = geo_serialize((LWGEOM *) lwcol); - lwfree(lwcol); + GSERIALIZED *result = geo_serialize((LWGEOM *) coll); + lwfree(coll); return PointerGetDatum(result); } @@ -2455,12 +2515,13 @@ datum_round_geo(Datum value, Datum size) return datum_round_multipolygon(gs, size); if (type == COLLECTIONTYPE) return datum_round_geometrycollection(gs, size); - elog(ERROR, "Unsupported geometry type"); - return Float8GetDatum(0); /* make compiler quiet */ + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Unsupported geometry type"); + return Float8GetDatum(0); } /** - * @ingroup mobilitydb_temporal_spatial_transf + * @ingroup meos_temporal_spatial_transf * @brief Set the precision of the coordinates of a temporal point to a * number of decimal places. * @sqlfunc round() @@ -2469,9 +2530,9 @@ Temporal * tpoint_round(const Temporal *temp, int maxdd) { /* Ensure validity of the arguments */ - assert(temp != NULL); - assert(temp->temptype == T_TGEOMPOINT || temp->temptype == T_TGEOGPOINT); - ensure_non_negative(maxdd); + if (! ensure_not_null((void *) temp) || ! ensure_tgeo_type(temp->temptype) || + ! ensure_non_negative(maxdd)) + return NULL; /* We only need to fill these parameters for tfunc_temporal */ LiftedFunctionInfo lfinfo; @@ -2589,8 +2650,10 @@ tpointseqset_length(const TSequenceSet *ss) double tpoint_length(const Temporal *temp) { - assert(temp); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tgeo_type(temp->temptype)) + return -1.0; + double result = 0.0; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT || ! MEOS_FLAGS_GET_LINEAR(temp->flags)) @@ -2681,8 +2744,10 @@ tpointseqset_cumulative_length(const TSequenceSet *ss) Temporal * tpoint_cumulative_length(const Temporal *temp) { - assert(temp); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tgeo_type(temp->temptype)) + return NULL; + Temporal *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT || ! MEOS_FLAGS_GET_LINEAR(temp->flags)) @@ -2704,8 +2769,10 @@ tpoint_cumulative_length(const Temporal *temp) GSERIALIZED * tpoint_convex_hull(const Temporal *temp) { - assert(temp); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tgeo_type(temp->temptype)) + return NULL; + GSERIALIZED *traj = tpoint_trajectory(temp); GSERIALIZED *result = gserialized_convex_hull(traj); pfree(traj); @@ -2790,8 +2857,10 @@ tpointseqset_speed(const TSequenceSet *ss) Temporal * tpoint_speed(const Temporal *temp) { - assert(temp); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tgeo_type(temp->temptype)) + return NULL; + Temporal *result = NULL; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT || ! MEOS_FLAGS_GET_LINEAR(temp->flags)) @@ -2911,8 +2980,10 @@ tpointseqset_twcentroid(const TSequenceSet *ss) GSERIALIZED * tpoint_twcentroid(const Temporal *temp) { - assert(temp); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tgeo_type(temp->temptype)) + return NULL; + GSERIALIZED *result; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -2949,13 +3020,13 @@ geog_azimuth(Datum geog1, Datum geog2) { const GSERIALIZED *g1 = DatumGetGserializedP(geog1); const GSERIALIZED *g2 = DatumGetGserializedP(geog2); - const LWGEOM *lwgeom1 = lwgeom_from_gserialized(g1); - const LWGEOM *lwgeom2 = lwgeom_from_gserialized(g2); + const LWGEOM *geom1 = lwgeom_from_gserialized(g1); + const LWGEOM *geom2 = lwgeom_from_gserialized(g2); SPHEROID s; spheroid_init(&s, WGS84_MAJOR_AXIS, WGS84_MINOR_AXIS); - double result = lwgeom_azumith_spheroid(lwgeom_as_lwpoint(lwgeom1), - lwgeom_as_lwpoint(lwgeom2), &s); + double result = lwgeom_azumith_spheroid(lwgeom_as_lwpoint(geom1), + lwgeom_as_lwpoint(geom2), &s); return Float8GetDatum(result); } @@ -3037,8 +3108,11 @@ tpointseqset_direction(const TSequenceSet *ss, double *result) bool tpoint_direction(const Temporal *temp, double *result) { - assert(temp); assert(result); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) result) || + ! ensure_tgeo_type(temp->temptype)) + return false; + bool found = false; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT) @@ -3168,8 +3242,10 @@ tpointseqset_azimuth(const TSequenceSet *ss) Temporal * tpoint_azimuth(const Temporal *temp) { - assert(temp); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tgeo_type(temp->temptype)) + return NULL; + Temporal *result = NULL; assert(temptype_subtype(temp->subtype)); if (temp->subtype == TINSTANT || ! MEOS_FLAGS_GET_LINEAR(temp->flags)) @@ -3189,8 +3265,10 @@ tpoint_azimuth(const Temporal *temp) Temporal * tpoint_angular_difference(const Temporal *temp) { - assert(temp); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_tgeo_type(temp->temptype)) + return NULL; + Temporal *tazimuth = tpoint_azimuth(temp); Temporal *result = NULL; if (tazimuth) @@ -3434,18 +3512,21 @@ tpointsegm_min_bearing_at_timestamp(const TInstant *start1, * @sqlfunc bearing() */ bool -bearing_point_point(const GSERIALIZED *geo1, const GSERIALIZED *geo2, +bearing_point_point(const GSERIALIZED *gs1, const GSERIALIZED *gs2, double *result) { - assert(geo1); assert(geo2); - ensure_point_type(geo1); ensure_point_type(geo2); - ensure_same_srid(gserialized_get_srid(geo1), gserialized_get_srid(geo2)); - ensure_same_dimensionality_gs(geo1, geo2); - if (gserialized_is_empty(geo1) || gserialized_is_empty(geo2)) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) gs1) || ! ensure_not_null((void *) gs2) || + ! ensure_point_type(gs1) || ! ensure_point_type(gs2) || + ! ensure_same_srid(gserialized_get_srid(gs1), gserialized_get_srid(gs2)) || + ! ensure_same_dimensionality_gs(gs1, gs2)) + return false; + + if (gserialized_is_empty(gs1) || gserialized_is_empty(gs2)) return false; - *result = FLAGS_GET_GEODETIC(geo1->gflags) ? - DatumGetFloat8(geog_bearing(PointerGetDatum(geo1), PointerGetDatum(geo2))) : - DatumGetFloat8(geom_bearing(PointerGetDatum(geo1), PointerGetDatum(geo2))); + *result = FLAGS_GET_GEODETIC(gs1->gflags) ? + DatumGetFloat8(geog_bearing(PointerGetDatum(gs1), PointerGetDatum(gs2))) : + DatumGetFloat8(geom_bearing(PointerGetDatum(gs1), PointerGetDatum(gs2))); return true; } @@ -3458,13 +3539,13 @@ bearing_point_point(const GSERIALIZED *geo1, const GSERIALIZED *geo2, Temporal * bearing_tpoint_point(const Temporal *temp, const GSERIALIZED *gs, bool invert) { - assert(temp); assert(gs); - if (gserialized_is_empty(gs)) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + gserialized_is_empty(gs) || + ! ensure_tgeo_type(temp->temptype) || ! ensure_point_type(gs) || + ! ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)) || + ! ensure_same_dimensionality_tpoint_gs(temp, gs)) return NULL; - ensure_tgeo_type(temp->temptype); - ensure_point_type(gs); - ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)); - ensure_same_dimensionality_tpoint_gs(temp, gs); LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); @@ -3490,11 +3571,14 @@ bearing_tpoint_point(const Temporal *temp, const GSERIALIZED *gs, bool invert) Temporal * bearing_tpoint_tpoint(const Temporal *temp1, const Temporal *temp2) { - assert(temp1); assert(temp2); - ensure_tgeo_type(temp1->temptype); - ensure_same_temporal_type(temp1, temp2); - ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)); - ensure_same_dimensionality(temp1->flags, temp2->flags); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_tgeo_type(temp1->temptype) || + ! ensure_same_temporal_type(temp1, temp2) || + ! ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)) || + ! ensure_same_dimensionality(temp1->flags, temp2->flags) ) + return NULL; + datum_func2 func = get_bearing_fn(temp1->flags); LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); @@ -3607,7 +3691,9 @@ mrr_distance_geos(GEOSGeometry *geom, bool geodetic) GEOSGeom_destroy(pt2); break; default: - elog(ERROR, "Invalid geometry type for Minimum Rotated Rectangle"); + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Invalid geometry type for Minimum Rotated Rectangle"); + return -1; } } return result; @@ -3633,7 +3719,11 @@ multipoint_make(const TSequence *seq, int start, int end) tinstant_value(TSEQUENCE_INST_N(seq, start + i)))); #endif else - elog(ERROR, "Sequence must have a spatial base type"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Sequence must have a spatial base type"); + return NULL; + } const POINT2D *pt = GSERIALIZED_POINT2D_P(gs); geoms[i] = GEOSGeom_createPointFromXY(pt->x, pt->y); } @@ -3656,7 +3746,11 @@ multipoint_add_inst_free(GEOSGeometry *geom, const TInstant *inst) gs = npoint_geom(DatumGetNpointP(tinstant_value(inst))); #endif else - elog(ERROR, "Instant must have a spatial base type"); + { + meos_error(ERROR, MEOS_ERR_INVALID_ARG_VALUE, + "Instant must have a spatial base type"); + return NULL; + } const POINT2D *pt = GSERIALIZED_POINT2D_P(gs); GEOSGeometry *geom1 = GEOSGeom_createPointFromXY(pt->x, pt->y); GEOSGeometry *result = GEOSUnion(geom, geom1); diff --git a/meos/src/point/tpoint_spatialrels.c b/meos/src/point/tpoint_spatialrels.c index f18a08f1ab..f806b74be9 100644 --- a/meos/src/point/tpoint_spatialrels.c +++ b/meos/src/point/tpoint_spatialrels.c @@ -263,11 +263,17 @@ get_dwithin_fn_gs(int16 flags1, uint8_t flags2) * @param[in] numparam Number of parameters of the functions * @param[in] invert True if the arguments should be inverted */ -bool +static int espatialrel_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs, Datum param, Datum (*func)(Datum, ...), int numparam, bool invert) { - ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_tgeo_type(temp->temptype) || gserialized_is_empty(gs) || + ! ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs))) + return -1; + + assert(tpoint_srid(temp) == gserialized_get_srid(gs)); assert(numparam == 2 || numparam == 3); Datum geo = PointerGetDatum(gs); Datum traj = PointerGetDatum(tpoint_trajectory(temp)); @@ -277,7 +283,7 @@ espatialrel_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs, Datum param, else /* numparam == 3 */ result = invert ? func(geo, traj, param) : func(traj, geo, param); pfree(DatumGetPointer(traj)); - return DatumGetBool(result); + return result ? 1 : 0; } /*****************************************************************************/ @@ -292,9 +298,14 @@ int espatialrel_tpoint_tpoint(const Temporal *temp1, const Temporal *temp2, Datum (*func)(Datum, Datum)) { - assert(temp1); assert(temp2); - ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)); - ensure_same_dimensionality(temp1->flags, temp2->flags); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_tgeo_type(temp1->temptype) || + ! ensure_tgeo_type(temp2->temptype) || + ! ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)) || + ! ensure_same_dimensionality(temp1->flags, temp2->flags)) + return -1; + /* Fill the lifted structure */ LiftedFunctionInfo lfinfo; memset(&lfinfo, 0, sizeof(LiftedFunctionInfo)); @@ -334,12 +345,12 @@ espatialrel_tpoint_tpoint(const Temporal *temp1, const Temporal *temp2, int econtains_geo_tpoint(const GSERIALIZED *gs, const Temporal *temp) { - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); - if (gserialized_is_empty(gs)) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_tgeo_type(temp->temptype) || gserialized_is_empty(gs) || + ! ensure_has_not_Z_gs(gs) || ! ensure_has_not_Z(temp->flags) || + ! ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs))) return -1; - ensure_has_not_Z_gs(gs); - ensure_has_not_Z(temp->flags); GSERIALIZED *traj = tpoint_trajectory(temp); bool result = gserialized_relate_pattern(gs, traj, "T********"); return result ? 1 : 0; @@ -414,11 +425,12 @@ edisjoint_tpointseqset_geo(const TSequenceSet *ss, Datum geo, int edisjoint_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs) { - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); - if (gserialized_is_empty(gs)) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_tgeo_type(temp->temptype) || gserialized_is_empty(gs) || + ! ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs))) return -1; - ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)); + varfunc func = (varfunc) get_disjoint_fn_gs(temp->flags, gs->gflags); bool result; assert(temptype_subtype(temp->subtype)); @@ -438,15 +450,12 @@ edisjoint_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs) /** * @ingroup libmeos_temporal_spatial_rel * @brief Return 1 if the temporal points are ever disjoint, 0 if not, and - * -1 if the temporal points do not intersect in time + * -1 on error or if the temporal points do not intersect in time * @sqlfunc disjoint() */ int edisjoint_tpoint_tpoint(const Temporal *temp1, const Temporal *temp2) { - assert(temp1); assert(temp2); - ensure_tgeo_type(temp1->temptype); - ensure_tgeo_type(temp2->temptype); if (MEOS_FLAGS_GET_GEODETIC(temp1->flags)) return espatialrel_tpoint_tpoint(temp1, temp2, &datum2_point_nsame); else @@ -461,35 +470,28 @@ edisjoint_tpoint_tpoint(const Temporal *temp1, const Temporal *temp2) /** * @ingroup libmeos_temporal_spatial_rel * @brief Return 1 if a geometry and a temporal point ever intersect, - * 0 if not, and -1 if the geometry is empty. + * 0 if not, and -1 on error or if the geometry is empty. * @sqlfunc intersects() */ int eintersects_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs) { - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); - if (gserialized_is_empty(gs)) - return -1; datum_func2 func = get_intersects_fn_gs(temp->flags, gs->gflags); - bool result = espatialrel_tpoint_geo(temp, gs, (Datum) NULL, (varfunc) func, + int result = espatialrel_tpoint_geo(temp, gs, (Datum) NULL, (varfunc) func, 2, INVERT_NO); - return result ? 1 : 0; + return result; } #if MEOS /** * @ingroup libmeos_temporal_spatial_rel * @brief Return 1 if the temporal points ever intersect, 0 if not, and - * -1 if the temporal points do not intersect in time + * -1 on error or if the temporal points do not intersect in time * @sqlfunc intersects() */ int eintersects_tpoint_tpoint(const Temporal *temp1, const Temporal *temp2) { - assert(temp1); assert(temp2); - ensure_tgeo_type(temp1->temptype); - ensure_tgeo_type(temp2->temptype); if (MEOS_FLAGS_GET_GEODETIC(temp1->flags)) return espatialrel_tpoint_tpoint(temp1, temp2, &datum2_point_same); else @@ -506,17 +508,18 @@ eintersects_tpoint_tpoint(const Temporal *temp1, const Temporal *temp2) /** * @ingroup libmeos_temporal_spatial_rel * @brief Return 1 if a temporal point and a geometry ever touch, 0 if not, and - * -1 if the geometry is empty + * -1 on error or if the geometry is empty * @sqlfunc touches() */ int etouches_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs) { - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); - if (gserialized_is_empty(gs)) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_tgeo_type(temp->temptype) || gserialized_is_empty(gs) || + ! ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs))) return -1; - ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)); + /* There is no need to do a bounding box test since this is done in * the SQL function definition */ varfunc func = (MEOS_FLAGS_GET_Z(temp->flags) && FLAGS_GET_Z(gs->gflags)) ? @@ -550,20 +553,16 @@ etouches_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs) /** * @ingroup libmeos_temporal_spatial_rel * @brief Return 1 if a geometry and a temporal point are ever within the - * given distance, 0 if not, -1 if a geometry is empty + * given distance, 0 if not, -1 on error or if a geometry is empty * @sqlfunc dwithin() */ int edwithin_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs, double dist) { - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); - if (gserialized_is_empty(gs)) - return -1; datum_func3 func = get_dwithin_fn_gs(temp->flags, gs->gflags); - bool result = espatialrel_tpoint_geo(temp, gs, Float8GetDatum(dist), + int result = espatialrel_tpoint_geo(temp, gs, Float8GetDatum(dist), (varfunc) func, 3, INVERT_NO); - return result ? 1 : 0; + return result; } /*****************************************************************************/ @@ -730,16 +729,19 @@ edwithin_tpoint_tpoint1(const Temporal *sync1, const Temporal *sync2, /** * @ingroup libmeos_temporal_spatial_rel * @brief Return 1 if the temporal points are ever within the given distance, - * 0 if not, -1 if the temporal points do not intersect on time + * 0 if not, -1 on error or if the temporal points do not intersect on time * @sqlfunc dwithin() */ int edwithin_tpoint_tpoint(const Temporal *temp1, const Temporal *temp2, double dist) { - assert(temp1); assert(temp2); - ensure_tgeo_type(temp1->temptype); - ensure_tgeo_type(temp2->temptype); - ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_tgeo_type(temp1->temptype) || + ! ensure_tgeo_type(temp2->temptype) || + ! ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2))) + return -1; + Temporal *sync1, *sync2; /* Return NULL if the temporal points do not intersect in time * The operation is synchronization without adding crossings */ diff --git a/meos/src/point/tpoint_tempspatialrels.c b/meos/src/point/tpoint_tempspatialrels.c index 1f431911c4..c097fa587e 100644 --- a/meos/src/point/tpoint_tempspatialrels.c +++ b/meos/src/point/tpoint_tempspatialrels.c @@ -423,8 +423,10 @@ Temporal * tinterrel_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs, bool tinter, bool restr, bool atvalue) { + assert(temp); assert(gs); if (gserialized_is_empty(gs)) return NULL; + /* Ensure validity of the arguments */ ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)); ensure_has_not_Z(temp->flags); ensure_has_not_Z_gs(gs); @@ -484,8 +486,10 @@ Temporal * tdisjoint_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs, bool restr, bool atvalue) { - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_tgeo_type(temp->temptype)) + return NULL; return tinterrel_tpoint_geo(temp, gs, TDISJOINT, restr, atvalue); } @@ -499,8 +503,10 @@ Temporal * tintersects_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs, bool restr, bool atvalue) { - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_tgeo_type(temp->temptype)) + return NULL; return tinterrel_tpoint_geo(temp, gs, TINTERSECTS, restr, atvalue); } #endif /* MEOS */ @@ -1090,8 +1096,11 @@ Temporal * tcontains_geo_tpoint(const GSERIALIZED *gs, const Temporal *temp, bool restr, bool atvalue) { - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_tgeo_type(temp->temptype)) + return NULL; + if (gserialized_is_empty(gs)) return NULL; Temporal *inter = tinterrel_tpoint_geo(temp, gs, TINTERSECTS, restr, @@ -1135,12 +1144,13 @@ Temporal * ttouches_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs, bool restr, bool atvalue) { - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); - if (gserialized_is_empty(gs)) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_tgeo_type(temp->temptype) || gserialized_is_empty(gs) || + ! ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)) || + ! ensure_has_not_Z(temp->flags) || ! ensure_has_not_Z_gs(gs)) return NULL; - ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)); - ensure_has_not_Z(temp->flags); ensure_has_not_Z_gs(gs); + GSERIALIZED *gsbound = gserialized_boundary(gs); Temporal *result; if (! gserialized_is_empty(gsbound)) @@ -1175,12 +1185,13 @@ Temporal * tdwithin_tpoint_geo(const Temporal *temp, const GSERIALIZED *gs, double dist, bool restr, bool atvalue) { - assert(temp); assert(gs); - ensure_tgeo_type(temp->temptype); - if (gserialized_is_empty(gs)) + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp) || ! ensure_not_null((void *) gs) || + ! ensure_tgeo_type(temp->temptype) || gserialized_is_empty(gs) || + ! ensure_point_type(gs) || + ! ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs))) return NULL; - ensure_point_type(gs); - ensure_same_srid(tpoint_srid(temp), gserialized_get_srid(gs)); + datum_func3 func = /* 3D only if both arguments are 3D */ MEOS_FLAGS_GET_Z(temp->flags) && FLAGS_GET_Z(gs->gflags) ? @@ -1311,10 +1322,13 @@ Temporal * tdwithin_tpoint_tpoint(const Temporal *temp1, const Temporal *temp2, double dist, bool restr, bool atvalue) { - assert(temp1); assert(temp2); - ensure_tgeo_type(temp1->temptype); - ensure_tgeo_type(temp2->temptype); - ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2)); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) temp1) || ! ensure_not_null((void *) temp2) || + ! ensure_tgeo_type(temp1->temptype) || + ! ensure_tgeo_type(temp2->temptype) || + ! ensure_same_srid(tpoint_srid(temp1), tpoint_srid(temp2))) + return NULL; + Temporal *sync1, *sync2; /* Return false if the temporal points do not intersect in time * The operation is synchronization without adding crossings */ diff --git a/meos/src/point/tpoint_tile.c b/meos/src/point/tpoint_tile.c index 869bef0dd1..5a949a6e9c 100644 --- a/meos/src/point/tpoint_tile.c +++ b/meos/src/point/tpoint_tile.c @@ -570,31 +570,36 @@ stbox_tile_list(const STBox *bounds, double xsize, double ysize, double zsize, const Interval *duration, GSERIALIZED *sorigin, TimestampTz torigin, int **no_cells) { - /* Get input parameters */ - ensure_has_X_stbox(bounds); - ensure_not_geodetic(bounds->flags); - ensure_positive_datum(Float8GetDatum(xsize), T_FLOAT8); - ensure_positive_datum(Float8GetDatum(ysize), T_FLOAT8); - if (MEOS_FLAGS_GET_Z(bounds->flags)) - ensure_positive_datum(Float8GetDatum(zsize), T_FLOAT8); + /* Ensure validity of the arguments */ + if (! ensure_not_null((void *) bounds) || + ! ensure_not_null((void *) no_cells) || ! ensure_has_X_stbox(bounds) || + ! ensure_not_geodetic(bounds->flags) || + ! ensure_positive_datum(Float8GetDatum(xsize), T_FLOAT8) || + ! ensure_positive_datum(Float8GetDatum(ysize), T_FLOAT8) || + (MEOS_FLAGS_GET_Z(bounds->flags) && + ! ensure_positive_datum(Float8GetDatum(zsize), T_FLOAT8))) + return NULL; + int64 tunits = 0; /* make compiler quiet */ /* If time arguments are given */ if (duration) { - ensure_has_T_stbox(bounds); - ensure_valid_duration(duration); + if (! ensure_has_T_stbox(bounds) || ! ensure_valid_duration(duration) ) + return NULL; tunits = interval_units(duration); } - ensure_non_empty(sorigin); - ensure_point_type(sorigin); /* Since we pass by default Point(0 0 0) as origin independently of the input * STBox, we test the same spatial dimensionality only for STBox Z */ - if (MEOS_FLAGS_GET_Z(bounds->flags)) - ensure_same_spatial_dimensionality_stbox_gs(bounds, sorigin); + if (! ensure_not_null((void *) bounds) || + ! ensure_non_empty(sorigin) || ! ensure_point_type(sorigin) || + (MEOS_FLAGS_GET_Z(bounds->flags) && + ! ensure_same_spatial_dimensionality_stbox_gs(bounds, sorigin))) + return NULL; int32 srid = bounds->srid; int32 gs_srid = gserialized_get_srid(sorigin); - if (gs_srid != SRID_UNKNOWN) - ensure_same_srid(srid, gs_srid); + if (gs_srid != SRID_UNKNOWN && ! ensure_same_srid(srid, gs_srid)) + return NULL; + POINT3DZ pt; memset(&pt, 0, sizeof(POINT3DZ)); if (FLAGS_GET_Z(sorigin->gflags)) diff --git a/mobilitydb/pg_include/pg_general/doxygen_mobilitydb_api.h b/mobilitydb/pg_include/pg_general/doxygen_mobilitydb_api.h index 3f1b7b2f14..83b570d01f 100644 --- a/mobilitydb/pg_include/pg_general/doxygen_mobilitydb_api.h +++ b/mobilitydb/pg_include/pg_general/doxygen_mobilitydb_api.h @@ -219,6 +219,10 @@ * @ingroup mobilitydb_temporal_spatial * @brief Spatial relationship functions for temporal point types. * + * @defgroup mobilitydb_temporal_spatial_route Route functions + * @ingroup mobilitydb_temporal_spatial + * @brief Route functions for temporal network point types. + * * @defgroup mobilitydb_temporal_time Time functions * @ingroup mobilitydb_temporal * @brief Time functions for temporal types. diff --git a/mobilitydb/pg_include/pg_general/temporal.h b/mobilitydb/pg_include/pg_general/temporal.h index c6849e7d7b..d8f28602ec 100644 --- a/mobilitydb/pg_include/pg_general/temporal.h +++ b/mobilitydb/pg_include/pg_general/temporal.h @@ -197,7 +197,6 @@ extern void store_fcinfo(FunctionCallInfo fcinfo); /* Typmod functions */ -extern const char *tempsubtype_name(int16 subtype); extern bool tempsubtype_from_string(const char *str, int16 *subtype); /* Send/receive functions */ @@ -207,7 +206,7 @@ extern void temporal_write(const Temporal *temp, StringInfo buf); /* Parameter tests */ -extern void ensure_non_empty_array(ArrayType *array); +extern bool ensure_non_empty_array(ArrayType *array); /*****************************************************************************/ diff --git a/mobilitydb/sql/general/002_set_ops.in.sql b/mobilitydb/sql/general/002_set_ops.in.sql index ab33c64302..feac27cc5d 100644 --- a/mobilitydb/sql/general/002_set_ops.in.sql +++ b/mobilitydb/sql/general/002_set_ops.in.sql @@ -1344,23 +1344,6 @@ CREATE FUNCTION set_distance(floatset, floatset) AS 'MODULE_PATHNAME', 'Distance_set_set' LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; -CREATE FUNCTION set_distance(text, text) - RETURNS text - AS 'MODULE_PATHNAME', 'Distance_value_value' - LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; -CREATE FUNCTION set_distance(text, textset) - RETURNS text - AS 'MODULE_PATHNAME', 'Distance_value_set' - LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; -CREATE FUNCTION set_distance(textset, text) - RETURNS text - AS 'MODULE_PATHNAME', 'Distance_set_value' - LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; -CREATE FUNCTION set_distance(textset, textset) - RETURNS text - AS 'MODULE_PATHNAME', 'Distance_set_set' - LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE; - CREATE FUNCTION set_distance(timestamptz, timestamptz) RETURNS float AS 'MODULE_PATHNAME', 'Distance_value_value' diff --git a/mobilitydb/src/general/meos_catalog.c b/mobilitydb/src/general/meos_catalog.c index ba15967002..88988dc275 100644 --- a/mobilitydb/src/general/meos_catalog.c +++ b/mobilitydb/src/general/meos_catalog.c @@ -308,7 +308,8 @@ type_oid(meosType type) populate_operoid_cache(); Oid result = _type_oids[type]; if (! result) - elog(ERROR, "Unknown MEOS type; %d", type); + ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("Unknown MEOS type; %d", type))); return result; } @@ -374,8 +375,8 @@ oper_oid(meosOper oper, meosType lt, meosType rt) populate_operoid_cache(); Oid result = _oper_oid[oper][lt][rt]; if (! result) - elog(ERROR, "Unknown MEOS operator: %d, ltype; %d, rtype; %d", - oper, lt, rt); + ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), + errmsg("Unknown MEOS operator: %d, ltype; %d, rtype; %d", oper, lt, rt))); return _oper_oid[oper][lt][rt]; } diff --git a/mobilitydb/src/general/span_ops.c b/mobilitydb/src/general/span_ops.c index 54e266d7c2..c6460985d5 100644 --- a/mobilitydb/src/general/span_ops.c +++ b/mobilitydb/src/general/span_ops.c @@ -613,10 +613,8 @@ Distance_value_value(PG_FUNCTION_ARGS) { Datum d1 = PG_GETARG_DATUM(0); Datum d2 = PG_GETARG_DATUM(1); - meosType basetype1 = oid_type(get_fn_expr_argtype(fcinfo->flinfo, 0)); - meosType basetype2 = oid_type(get_fn_expr_argtype(fcinfo->flinfo, 1)); - assert(basetype1 == basetype2); - double result = distance_value_value(d1, d2, basetype1); + meosType basetype = oid_type(get_fn_expr_argtype(fcinfo->flinfo, 0)); + double result = distance_value_value(d1, d2, basetype); PG_RETURN_FLOAT8(result); } diff --git a/mobilitydb/src/general/temporal.c b/mobilitydb/src/general/temporal.c index b1154b2ce7..de78cc9c11 100644 --- a/mobilitydb/src/general/temporal.c +++ b/mobilitydb/src/general/temporal.c @@ -152,31 +152,22 @@ store_fcinfo(FunctionCallInfo fcinfo) * @brief Ensure that the array is not empty * @note Used for the constructor functions */ -void +bool ensure_non_empty_array(ArrayType *array) { if (ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array)) == 0) + { ereport(ERROR, (errcode(ERRCODE_ARRAY_ELEMENT_ERROR), errmsg("The input array cannot be empty"))); - return; + return false; + } + return true; } /***************************************************************************** * Typmod functions *****************************************************************************/ -/** - * @brief Array storing the string representation of the concrete subtypes of - * temporal types - */ -static char *tempsubtypeName[] = -{ - "AnyDuration", - "Instant", - "Sequence", - "SequenceSet" -}; - /** * @brief Array storing the mapping between the string representation of the * subtypes of temporal types and the corresponding enum value @@ -189,16 +180,6 @@ struct tempsubtype_struct tempsubtype_struct_array[] = {"SEQUENCESET", TSEQUENCESET}, }; -/** - * @brief Return the string representation of the subtype of the temporal type - * corresponding to the enum value - */ -const char * -tempsubtype_name(int16 subtype) -{ - return tempsubtypeName[subtype]; -} - /** * @brief Return the enum value corresponding to the string representation * of the concrete subtype of a temporal type. @@ -984,7 +965,7 @@ PG_FUNCTION_INFO_V1(Tinstant_get_value); Datum Tinstant_get_value(PG_FUNCTION_ARGS) { - TInstant *inst = PG_GETARG_TINSTANT_P(0); + TInstant *inst = PG_GETARG_TINSTANT_P(0); if (inst->subtype != TINSTANT) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("The temporal value must be of subtype instant"))); diff --git a/mobilitydb/src/npoint/tnpoint.c b/mobilitydb/src/npoint/tnpoint.c index 57ebcf167f..1a142b4e17 100644 --- a/mobilitydb/src/npoint/tnpoint.c +++ b/mobilitydb/src/npoint/tnpoint.c @@ -168,8 +168,8 @@ PGDLLEXPORT Datum Tnpoint_round(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Tnpoint_round); /** * @ingroup mobilitydb_temporal_transf - * @brief Set the precision of the fraction of the temporal network point to the - * number of decimal places. + * @brief Set the precision of the fraction of the temporal network point to + * the number of decimal places. * @sqlfunc round() */ Datum @@ -186,7 +186,7 @@ PGDLLEXPORT Datum Npointset_round(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Npointset_round); /** * @ingroup mobilitydb_temporal_spatial_transf - * @brief Sets the precision of the coordinates of the geometry set + * @brief Set the precision of the coordinates of the geometry set * @sqlfunc round() */ Datum diff --git a/mobilitydb/src/npoint/tnpoint_routeops.c b/mobilitydb/src/npoint/tnpoint_routeops.c index 66b6dbdad5..ad32681de7 100644 --- a/mobilitydb/src/npoint/tnpoint_routeops.c +++ b/mobilitydb/src/npoint/tnpoint_routeops.c @@ -357,8 +357,8 @@ routeop_tnpoint_tnpoint_ext(FunctionCallInfo fcinfo, PGDLLEXPORT Datum Overlaps_rid_bigintset_tnpoint(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Overlaps_rid_bigintset_tnpoint); /** - * @ingroup mobilitydb_tnpoint_routes - * @brief Return true if the routes and the routes of + * @ingroup mobilitydb_temporal_spatial_route + * @brief Return true if the routes in the set and the routes of * the temporal network point overlap * @sqlfunc overlaps_rid() * @sqlop @p @@ @@ -374,9 +374,9 @@ Overlaps_rid_bigintset_tnpoint(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Overlaps_rid_tnpoint_bigintset(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Overlaps_rid_tnpoint_bigintset); /** - * @ingroup mobilitydb_tnpoint_routes + * @ingroup mobilitydb_temporal_spatial_route * @brief Return true if the routes of the temporal network point and - * the routes overlap + * the routes in the set overlap * @sqlfunc overlaps_rid() * @sqlop @p @@ */ @@ -389,8 +389,8 @@ Overlaps_rid_tnpoint_bigintset(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Overlaps_rid_tnpoint_tnpoint(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Overlaps_rid_tnpoint_tnpoint); /** - * @ingroup mobilitydb_tnpoint_routes - * @brief Return true if the route identifiers of the temporal network points + * @ingroup mobilitydb_temporal_spatial_route + * @brief Return true if the routes of the temporal network points * overlap * @sqlfunc overlaps_rid() * @sqlop @p @@ @@ -408,8 +408,8 @@ Overlaps_rid_tnpoint_tnpoint(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Contains_rid_bigintset_tnpoint(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Contains_rid_bigintset_tnpoint); /** - * @ingroup mobilitydb_tnpoint_routes - * @brief Return true if big integer set contains the one of the temporal + * @ingroup mobilitydb_temporal_spatial_route + * @brief Return true if routes in the set contain the routes of the temporal * network point * @sqlfunc contains_rid() * @sqlop @p \@? @@ -425,9 +425,9 @@ Contains_rid_bigintset_tnpoint(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Contains_rid_tnpoint_bigint(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Contains_rid_tnpoint_bigint); /** - * @ingroup mobilitydb_tnpoint_routes + * @ingroup mobilitydb_temporal_spatial_route * @brief Return true if the routes of the temporal network point - * contain the one of the route + * contain the routes in the set * @sqlfunc contains_rid() * @sqlop @p \@? */ @@ -440,9 +440,9 @@ Contains_rid_tnpoint_bigint(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Contains_rid_tnpoint_bigintset(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Contains_rid_tnpoint_bigintset); /** - * @ingroup mobilitydb_tnpoint_routes + * @ingroup mobilitydb_temporal_spatial_route * @brief Return true if the routes of the temporal network point - * contain the routes + * contain the routes in the set * @sqlfunc contains_rid() * @sqlop @p \@? */ @@ -455,9 +455,9 @@ Contains_rid_tnpoint_bigintset(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Contains_rid_tnpoint_npoint(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Contains_rid_tnpoint_npoint); /** - * @ingroup mobilitydb_tnpoint_routes + * @ingroup mobilitydb_temporal_spatial_route * @brief Return true if the routes of the temporal network point - * contain the one of the network point + * contain the route of the network point * @sqlfunc contains_rid() * @sqlop @p \@? */ @@ -470,9 +470,9 @@ Contains_rid_tnpoint_npoint(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Contains_rid_tnpoint_tnpoint(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Contains_rid_tnpoint_tnpoint); /** - * @ingroup mobilitydb_tnpoint_routes + * @ingroup mobilitydb_temporal_spatial_route * @brief Return true if the routes of the first temporal network point - * contain the one of the second temporal network point + * contain the routes of the second temporal network point * @sqlfunc contains_rid() * @sqlop @p \@? */ @@ -489,9 +489,9 @@ Contains_rid_tnpoint_tnpoint(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Contained_rid_bigint_tnpoint(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Contained_rid_bigint_tnpoint); /** - * @ingroup mobilitydb_tnpoint_routes - * @brief Return true if the routes is contained in the one of the - * temporal network point + * @ingroup mobilitydb_temporal_spatial_route + * @brief Return true if the route is contained in the routes of the temporal + * network point * @sqlfunc contained_rid() * @sqlop @p ?@ */ @@ -504,9 +504,9 @@ Contained_rid_bigint_tnpoint(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Contained_rid_bigintset_tnpoint(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Contained_rid_bigintset_tnpoint); /** - * @ingroup mobilitydb_tnpoint_routes - * @brief Return true if the routes is contained in the one of the - * temporal network point + * @ingroup mobilitydb_temporal_spatial_route + * @brief Return true if the routes in the set are contained in the routes of + * the temporal network point * @sqlfunc contained_rid() * @sqlop @p ?@ */ @@ -519,9 +519,9 @@ Contained_rid_bigintset_tnpoint(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Contained_rid_npoint_tnpoint(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Contained_rid_npoint_tnpoint); /** - * @ingroup mobilitydb_tnpoint_routes - * @brief Return true if the routes of the network point is contained in - * the one of the temporal network point + * @ingroup mobilitydb_temporal_spatial_route + * @brief Return true if the route of the network point is contained in + * the routes of the temporal network point * @sqlfunc contained_rid() * @sqlop @p ?@ */ @@ -536,9 +536,9 @@ Contained_rid_npoint_tnpoint(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Contained_rid_tnpoint_bigintset(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Contained_rid_tnpoint_bigintset); /** - * @ingroup mobilitydb_tnpoint_routes - * @brief Return true if the routes of the temporal network point is - * contained in the routes + * @ingroup mobilitydb_temporal_spatial_route + * @brief Return true if the routes of the temporal network point are + * contained in the routes fo the set * @sqlfunc contained_rid() * @sqlop @p ?@ */ @@ -551,9 +551,9 @@ Contained_rid_tnpoint_bigintset(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Contained_rid_tnpoint_tnpoint(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Contained_rid_tnpoint_tnpoint); /** - * @ingroup mobilitydb_tnpoint_routes + * @ingroup mobilitydb_temporal_spatial_route * @brief Return true if the routes of the first temporal network point - * is contained in the one of the second temporal network point + * are contained in the routes of the second temporal network point * @sqlfunc contained_rid() * @sqlop @p ?@ */ @@ -570,9 +570,9 @@ Contained_rid_tnpoint_tnpoint(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Same_rid_bigint_tnpoint(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Same_rid_bigint_tnpoint); /** - * @ingroup mobilitydb_tnpoint_routes - * @brief Return true if the route identifiers of the route and the temporal - * network point are equal + * @ingroup mobilitydb_temporal_spatial_route + * @brief Return true if the route and the routes of the temporal network point + * are equal * @sqlfunc same_rid() * @sqlop @p @= */ @@ -585,9 +585,9 @@ Same_rid_bigint_tnpoint(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Same_rid_bigintset_tnpoint(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Same_rid_bigintset_tnpoint); /** - * @ingroup mobilitydb_tnpoint_routes - * @brief Return true if the routes and the routes of the - * temporal network point are equal + * @ingroup mobilitydb_temporal_spatial_route + * @brief Return true if the routes of the set and the routes of the temporal + * network point are equal * @sqlfunc same_rid() * @sqlop @p @= */ @@ -600,8 +600,8 @@ Same_rid_bigintset_tnpoint(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Same_rid_npoint_tnpoint(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Same_rid_npoint_tnpoint); /** - * @ingroup mobilitydb_tnpoint_routes - * @brief Return true if the route identifiers of the network point and the + * @ingroup mobilitydb_temporal_spatial_route + * @brief Return true if the route of the network point and the routes of the * temporal network point are equal * @sqlfunc same_rid() * @sqlop @p @= @@ -617,9 +617,9 @@ Same_rid_npoint_tnpoint(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Same_rid_tnpoint_bigint(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Same_rid_tnpoint_bigint); /** - * @ingroup mobilitydb_tnpoint_routes - * @brief Return true if the route identifiers of the temporal network point and - * the big integer are equal + * @ingroup mobilitydb_temporal_spatial_route + * @brief Return true if the routes of the temporal network point and the route + * are equal * @sqlfunc same_rid() * @sqlop @p @= */ @@ -632,9 +632,9 @@ Same_rid_tnpoint_bigint(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Same_rid_tnpoint_bigintset(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Same_rid_tnpoint_bigintset); /** - * @ingroup mobilitydb_tnpoint_routes - * @brief Return true if the route identifiers of the temporal network point and - * the big integer set are equal + * @ingroup mobilitydb_temporal_spatial_route + * @brief Return true if the routes of the temporal network point and the + * routes of the set are equal * @sqlfunc same_rid() * @sqlop @p @= */ @@ -647,9 +647,9 @@ Same_rid_tnpoint_bigintset(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Same_rid_tnpoint_npoint(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Same_rid_tnpoint_npoint); /** - * @ingroup mobilitydb_tnpoint_routes - * @brief Return true if the route identifiers of the temporal network point and - * the network point are equal + * @ingroup mobilitydb_temporal_spatial_route + * @brief Return true if the routes of the temporal network point and the route + * of the network point are equal * @sqlfunc same_rid() * @sqlop @p @= */ @@ -662,9 +662,8 @@ Same_rid_tnpoint_npoint(PG_FUNCTION_ARGS) PGDLLEXPORT Datum Same_rid_tnpoint_tnpoint(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(Same_rid_tnpoint_tnpoint); /** - * @ingroup mobilitydb_tnpoint_routes - * @brief Return true if the route identifiers of the temporal network points - * are equal + * @ingroup mobilitydb_temporal_spatial_route + * @brief Return true if the routes of the temporal network points are equal * @sqlfunc same_rid() * @sqlop @p @= */ diff --git a/mobilitydb/src/point/stbox.c b/mobilitydb/src/point/stbox.c index 438574a5e5..16e70ca141 100644 --- a/mobilitydb/src/point/stbox.c +++ b/mobilitydb/src/point/stbox.c @@ -790,7 +790,9 @@ Stbox_set_srid(PG_FUNCTION_ARGS) static STBox * stbox_transform(const STBox *box, int32 srid) { + /* Ensure validity of the arguments */ ensure_has_X_stbox(box); + STBox *result = stbox_copy(box); result->srid = DatumGetInt32(srid); bool hasz = MEOS_FLAGS_GET_Z(box->flags); diff --git a/mobilitydb/src/point/tpoint.c b/mobilitydb/src/point/tpoint.c index 84372bad75..e6790f0d47 100644 --- a/mobilitydb/src/point/tpoint.c +++ b/mobilitydb/src/point/tpoint.c @@ -508,7 +508,7 @@ tcomp_geo_tpoint_ext(FunctionCallInfo fcinfo, { GSERIALIZED *gs = PG_GETARG_GSERIALIZED_P(0); Temporal *temp = PG_GETARG_TEMPORAL_P(1); - Temporal *result = tcomp_tpoint_point(temp, gs, func, true); + Temporal *result = tcomp_tpoint_point_int(temp, gs, func, true); PG_FREE_IF_COPY(gs, 0); PG_FREE_IF_COPY(temp, 1); if (! result) @@ -525,7 +525,7 @@ tcomp_tpoint_point_ext(FunctionCallInfo fcinfo, { Temporal *temp = PG_GETARG_TEMPORAL_P(0); GSERIALIZED *gs = PG_GETARG_GSERIALIZED_P(1); - Temporal *result = tcomp_tpoint_point(temp, gs, func, false); + Temporal *result = tcomp_tpoint_point_int(temp, gs, func, false); PG_FREE_IF_COPY(temp, 0); PG_FREE_IF_COPY(gs, 1); if (! result) diff --git a/mobilitydb/src/point/tpoint_spatialfuncs.c b/mobilitydb/src/point/tpoint_spatialfuncs.c index 4b00ebe663..a2c75b7f8e 100644 --- a/mobilitydb/src/point/tpoint_spatialfuncs.c +++ b/mobilitydb/src/point/tpoint_spatialfuncs.c @@ -62,17 +62,16 @@ /** * @brief Generic function for the temporal ever/always comparison operators - * * @param[in] fcinfo Catalog information about the external function * @param[in] func Specific function for the ever/always comparison */ static Datum tpoint_ev_al_comp_ext(FunctionCallInfo fcinfo, - bool (*func)(const Temporal *, Datum)) + bool (*func)(const Temporal *, const GSERIALIZED *)) { Temporal *temp = PG_GETARG_TEMPORAL_P(0); GSERIALIZED *gs = PG_GETARG_GSERIALIZED_P(1); - bool result = func(temp, PointerGetDatum(gs)); + bool result = func(temp, gs); PG_FREE_IF_COPY(temp, 0); PG_FREE_IF_COPY(gs, 1); PG_RETURN_BOOL(result); @@ -289,12 +288,12 @@ tpointseqset_transform(const TSequenceSet *ss, int srid) } } /* Last parameter set to STEP to force the function to return multipoint */ - LWGEOM *lwgeom = lwpointarr_make_trajectory(points, ss->totalcount, STEP); - Datum multipoint = PointerGetDatum(geo_serialize(lwgeom)); - lwgeom_free(lwgeom); + LWGEOM *geom = lwpointarr_make_trajectory(points, ss->totalcount, STEP); + Datum multipoint = PointerGetDatum(geo_serialize(geom)); + lwgeom_free(geom); Datum transf = datum_transform(multipoint, srid); GSERIALIZED *gs = (GSERIALIZED *) PG_DETOAST_DATUM(transf); - LWMPOINT *lwmpoint = lwgeom_as_lwmpoint(lwgeom_from_gserialized(gs)); + LWMPOINT *mpoint = lwgeom_as_lwmpoint(lwgeom_from_gserialized(gs)); TSequence **sequences = palloc(sizeof(TSequence *) * ss->count); TInstant **instants = palloc(sizeof(TInstant *) * maxcount); interpType interp = MEOS_FLAGS_GET_INTERP(ss->flags); @@ -305,7 +304,7 @@ tpointseqset_transform(const TSequenceSet *ss, int srid) for (int j = 0; j < seq->count; j++) { GSERIALIZED *point = geo_serialize((LWGEOM *) - (lwmpoint->geoms[npoints++])); + (mpoint->geoms[npoints++])); const TInstant *inst = TSEQUENCE_INST_N(seq, j); instants[j] = tinstant_make(PointerGetDatum(point), inst->temptype, inst->t); @@ -321,7 +320,7 @@ tpointseqset_transform(const TSequenceSet *ss, int srid) pfree(instants); PG_FREE_IF_COPY_P(gs, DatumGetPointer(transf)); pfree(DatumGetPointer(transf)); pfree(DatumGetPointer(multipoint)); - lwmpoint_free(lwmpoint); + lwmpoint_free(mpoint); return result; } diff --git a/mobilitydb/test/general/expected/001_set.test.out b/mobilitydb/test/general/expected/001_set.test.out index 6ec79b7723..5192df0654 100644 --- a/mobilitydb/test/general/expected/001_set.test.out +++ b/mobilitydb/test/general/expected/001_set.test.out @@ -1,10 +1,10 @@ /* Errors */ SELECT tstzset '2000-01-01, 2000-01-02'; -ERROR: Could not parse set: Missing open brace +ERROR: Could not parse set value: Missing opening brace LINE 2: SELECT tstzset '2000-01-01, 2000-01-02'; ^ SELECT tstzset '{2000-01-01, 2000-01-02'; -ERROR: Could not parse set: Missing closing brace +ERROR: Could not parse set value: Missing closing brace LINE 1: SELECT tstzset '{2000-01-01, 2000-01-02'; ^ SELECT set(ARRAY [timestamptz '2000-01-01', '2000-01-02', '2000-01-03']); diff --git a/mobilitydb/test/general/expected/003_span.test.out b/mobilitydb/test/general/expected/003_span.test.out index ea5fd18216..d5f0725023 100644 --- a/mobilitydb/test/general/expected/003_span.test.out +++ b/mobilitydb/test/general/expected/003_span.test.out @@ -1,14 +1,14 @@ /* Errors */ SELECT intspan '[1,2] xxx'; -ERROR: Could not parse span value +ERROR: Could not parse span value: Extraneous characters at the end LINE 2: SELECT intspan '[1,2] xxx'; ^ SELECT floatspan '[1,2] xxx'; -ERROR: Could not parse span value +ERROR: Could not parse span value: Extraneous characters at the end LINE 1: SELECT floatspan '[1,2] xxx'; ^ SELECT tstzspan '[2000-01-01,2000-01-02] xxx'; -ERROR: Could not parse span value +ERROR: Could not parse span value: Extraneous characters at the end LINE 1: SELECT tstzspan '[2000-01-01,2000-01-02] xxx'; ^ SELECT tstzspan '2000-01-01, 2000-01-02'; diff --git a/mobilitydb/test/general/expected/007_spanset.test.out b/mobilitydb/test/general/expected/007_spanset.test.out index 508db3e906..6eb3b6bc4e 100644 --- a/mobilitydb/test/general/expected/007_spanset.test.out +++ b/mobilitydb/test/general/expected/007_spanset.test.out @@ -24,11 +24,11 @@ SELECT tstzspanset '{[2000-01-01, 2000-01-02), [2000-01-02, 2000-01-03), [2000-0 /* Errors */ SELECT tstzspanset '2000-01-01, 2000-01-02'; -ERROR: Could not parse span set: Missing open brace +ERROR: Could not parse span set value: Missing opening brace LINE 2: SELECT tstzspanset '2000-01-01, 2000-01-02'; ^ SELECT tstzspanset '{[2000-01-01, 2000-01-02]'; -ERROR: Could not parse span set: Missing closing brace +ERROR: Could not parse span set value: Missing closing brace LINE 1: SELECT tstzspanset '{[2000-01-01, 2000-01-02]'; ^ SELECT spanset(ARRAY [intspan '[1,2)','[3,4)','[5,6)']); diff --git a/mobilitydb/test/general/expected/022_temporal.test.out b/mobilitydb/test/general/expected/022_temporal.test.out index df998ccf22..c3a978fe3e 100644 --- a/mobilitydb/test/general/expected/022_temporal.test.out +++ b/mobilitydb/test/general/expected/022_temporal.test.out @@ -76,7 +76,7 @@ ERROR: Could not parse element value LINE 1: SELECT tfloat '25'; ^ SELECT tfloat '2@2012-01-01 08:00:00,'; -ERROR: Could not parse temporal value +ERROR: Could not parse temporal value: Extraneous characters at the end LINE 1: SELECT tfloat '2@2012-01-01 08:00:00,'; ^ SELECT tbool ' { true@2001-01-01 08:00:00 , false@2001-01-01 08:05:00 , true@2001-01-01 08:06:00 } '; @@ -149,7 +149,7 @@ ERROR: Could not parse temporal value: Missing closing brace LINE 1: SELECT tint '{1@2001-01-01, 2@2001-01-02, 3@2001-01-03'; ^ SELECT tint '{1@2001-01-01, 2@2001-01-02, 3@2001-01-03},'; -ERROR: Could not parse temporal value +ERROR: Could not parse temporal value: Extraneous characters at the end LINE 1: SELECT tint '{1@2001-01-01, 2@2001-01-02, 3@2001-01-03},'; ^ SELECT tbool ' [ true@2001-01-01 08:00:00 , false@2001-01-01 08:05:00 , true@2001-01-01 08:06:00 ] '; @@ -230,7 +230,7 @@ ERROR: Could not parse temporal value: Missing closing bracket/parenthesis LINE 1: SELECT tbool '[true@2001-01-01, true@2001-01-02'; ^ SELECT tbool '[true@2001-01-01, true@2001-01-02],'; -ERROR: Could not parse temporal value +ERROR: Could not parse temporal value: Extraneous characters at the end LINE 1: SELECT tbool '[true@2001-01-01, true@2001-01-02],'; ^ SELECT tbool ' { [ true@2001-01-01 08:00:00 , false@2001-01-01 08:05:00 , true@2001-01-01 08:06:00 ], @@ -325,7 +325,7 @@ ERROR: Could not parse temporal value: Missing closing brace LINE 1: SELECT tfloat_seqset(tfloat '{[1@2000-01-01, 2@2000-01-03], ... ^ SELECT tfloat_seqset(tfloat '{[1@2000-01-01, 2@2000-01-03], [2@2000-01-02, 1@2000-01-04]},'); -ERROR: Could not parse temporal value +ERROR: Could not parse temporal value: Extraneous characters at the end LINE 1: SELECT tfloat_seqset(tfloat '{[1@2000-01-01, 2@2000-01-03], ... ^ SELECT format_type(oid, -1) FROM (SELECT oid FROM pg_type WHERE typname = 'tfloat') t; @@ -1997,7 +1997,7 @@ ERROR: Timestamps for temporal value must be increasing: Sun Jan 02 00:00:00 20 SELECT appendInstant(tfloat '[1@2000-01-01, 1@2000-01-02]', '2@2000-01-02'); ERROR: The temporal values have different value at their common timestamp Sun Jan 02 00:00:00 2000 PST SELECT appendInstant(tint '[1@2000-01-01, 2@2000-01-02, 1@2000-01-03]', tint '[1@2000-01-04, 1@2000-01-05]'); -ERROR: The second argument must be of instant subtype +ERROR: The temporal value must be of subtype Instant SELECT appendInstant(tfloat '{[1@2000-01-01, 1@2000-01-02]}', '2@2000-01-02'); ERROR: The temporal values have different value at their common timestamp Sun Jan 02 00:00:00 2000 PST SELECT appendInstant(tfloat '[1@2000-01-01, 2@2000-01-03]', '1@2000-01-02'); @@ -2020,7 +2020,7 @@ ERROR: Timestamps for temporal value must be increasing: Mon Jan 03 00:00:00 20 SELECT appendSequence(tfloat '[1@2000-01-01, 2@2000-01-02]', tfloat '[1@2000-01-02]'); ERROR: The temporal values have different value at their common timestamp Sun Jan 02 00:00:00 2000 PST SELECT appendSequence(tfloat '{[1@2000-01-01, 1@2000-01-02)}', tfloat '2@2000-01-02'); -ERROR: The second argument must be of sequence subtype +ERROR: The temporal value must be of subtype Sequence SELECT appendSequence(tfloat '{1@2000-01-01, 2@2000-01-02}', tfloat '[2@2000-01-01]'); ERROR: The temporal values must have the same interpolation SELECT appendSequence(tfloat '{[1@2000-01-01, 1@2000-01-03]}', tfloat '[2@2000-01-02]'); diff --git a/mobilitydb/test/general/expected/022_temporal_tbl.test.out b/mobilitydb/test/general/expected/022_temporal_tbl.test.out index 69b5c7b6bb..5da7e61e9b 100644 --- a/mobilitydb/test/general/expected/022_temporal_tbl.test.out +++ b/mobilitydb/test/general/expected/022_temporal_tbl.test.out @@ -1675,7 +1675,7 @@ SELECT MAX(numInstants(stops(seq, 50.0, '5 min'))) FROM tbl_tfloat_seq; SELECT MAX(numInstants(stops(inst, 50.0))) FROM tbl_tfloat_inst; ERROR: Input must be a temporal sequence (set) with linear interpolation SELECT MAX(numInstants(stops(seq, -50.0))) FROM tbl_tfloat_seq; -ERROR: The maximum distance must be positive: -50.000000 +ERROR: The value must be strictly positive: -50.000000 SELECT COUNT(*) FROM tbl_tbool WHERE temp ?= startValue(temp); count ------- diff --git a/mobilitydb/test/npoint/expected/081_tnpoint_static.test.out b/mobilitydb/test/npoint/expected/081_tnpoint_static.test.out index a79a012d10..288084f2db 100644 --- a/mobilitydb/test/npoint/expected/081_tnpoint_static.test.out +++ b/mobilitydb/test/npoint/expected/081_tnpoint_static.test.out @@ -36,7 +36,7 @@ ERROR: The relative position must be a real number between 0 and 1 LINE 1: SELECT npoint 'npoint(1,1.5)'; ^ SELECT npoint 'npoint(1,0.5)xxx'; -ERROR: Could not parse network point value +ERROR: Could not parse network point value: Extraneous characters at the end LINE 1: SELECT npoint 'npoint(1,0.5)xxx'; ^ SELECT nsegment 'nsegment(1,0.5,0.7)'; @@ -53,7 +53,7 @@ SELECT nsegment ' nsegment ( 1 , 0.5 , 0.7 ) '; /* Errors */ SELECT nsegment 'Nsegment 1, 1.1)'; -ERROR: Could not parse network point: Missing opening parenthesis +ERROR: Could not parse network segment: Missing opening parenthesis LINE 2: SELECT nsegment 'Nsegment 1, 1.1)'; ^ SELECT nsegment(1, 1.1); @@ -63,7 +63,7 @@ ERROR: Could not parse network segment LINE 1: SELECT nsegment 'segment(1,0.5,0.7)'; ^ SELECT nsegment 'nsegment(1,0.5,0.7'; -ERROR: Could not parse network point: Missing closing parenthesis +ERROR: Could not parse network segment: Missing closing parenthesis LINE 1: SELECT nsegment 'nsegment(1,0.5,0.7'; ^ SELECT nsegment 'nsegment(1 0.5 0.7)'; @@ -79,7 +79,7 @@ ERROR: The relative position must be a real number between 0 and 1 LINE 1: SELECT nsegment 'nsegment(1,1.5,0.7)'; ^ SELECT nsegment 'nsegment(1,0.5,0.7)xxx'; -ERROR: Could not parse network segment value +ERROR: Could not parse network segment value: Extraneous characters at the end LINE 1: SELECT nsegment 'nsegment(1,0.5,0.7)xxx'; ^ SELECT nsegment 'NSegment(1, 1, 1.5)'; diff --git a/mobilitydb/test/point/expected/051_stbox.test.out b/mobilitydb/test/point/expected/051_stbox.test.out index 6ee7d29f00..b8d092c12a 100644 --- a/mobilitydb/test/point/expected/051_stbox.test.out +++ b/mobilitydb/test/point/expected/051_stbox.test.out @@ -158,7 +158,7 @@ ERROR: Span lower bound must be less than or equal to span upper bound LINE 1: SELECT stbox 'SRID=4326;GEODSTBOX ZT(((5,6,7),(1,2,3)),[2001... ^ SELECT stbox 'STBOX ZT(((5,6,7),(1,2,3)),[2001-01-04,2001-01-08])xxxx'; -ERROR: Could not parse spatiotemporal box value +ERROR: Could not parse spatiotemporal box value: Extraneous characters at the end LINE 1: SELECT stbox 'STBOX ZT(((5,6,7),(1,2,3)),[2001-01-04,2001-01... ^ COPY tbl_stbox3d TO '/tmp/tbl_stbox3d' (FORMAT BINARY); diff --git a/mobilitydb/test/point/expected/052_tpoint.test.out b/mobilitydb/test/point/expected/052_tpoint.test.out index 175d71d586..347d2b40e1 100644 --- a/mobilitydb/test/point/expected/052_tpoint.test.out +++ b/mobilitydb/test/point/expected/052_tpoint.test.out @@ -42,11 +42,11 @@ ERROR: Only non-empty geometries accepted LINE 1: SELECT tgeogpoint 'Point empty@2012-01-01 08:00:00'; ^ SELECT tgeompoint 'Point(1 1)@2000-01-01 00:00:00+01 ,'; -ERROR: Could not parse temporal point value +ERROR: Could not parse temporal point value: Extraneous characters at the end LINE 1: SELECT tgeompoint 'Point(1 1)@2000-01-01 00:00:00+01 ,'; ^ SELECT tgeogpoint 'Point(1 1)@2000-01-01 00:00:00+01 ,'; -ERROR: Could not parse temporal point value +ERROR: Could not parse temporal point value: Extraneous characters at the end LINE 1: SELECT tgeogpoint 'Point(1 1)@2000-01-01 00:00:00+01 ,'; ^ SELECT tgeogpoint 'Point M(1 1 1)@2000-01-01 00:00:00+01'; @@ -103,11 +103,11 @@ ERROR: Could not parse temporal point value: Missing closing brace LINE 1: SELECT tgeogpoint '{Point(1 1)@2001-01-01 08:00:00,Point(2 2... ^ SELECT tgeogpoint '{Point(1 1)@2001-01-01 08:00:00,Point(2 2)@2001-01-01 08:05:00,Point(3 3)@2001-01-01 08:06:00} xxx'; -ERROR: Could not parse temporal point value +ERROR: Could not parse temporal point value: Extraneous characters at the end LINE 1: SELECT tgeogpoint '{Point(1 1)@2001-01-01 08:00:00,Point(2 2... ^ SELECT tgeogpoint '{Point(1 1)@2001-01-01 08:00:00,Point(2 2)@2001-01-01 08:05:00,Point(3 3)@2001-01-01 08:06:00} xxx'; -ERROR: Could not parse temporal point value +ERROR: Could not parse temporal point value: Extraneous characters at the end LINE 1: SELECT tgeogpoint '{Point(1 1)@2001-01-01 08:00:00,Point(2 2... ^ SELECT asText(tgeompoint ' [ Point(1 1)@2001-01-01 08:00:00 , Point(2 2)@2001-01-01 08:05:00 , Point(3 3)@2001-01-01 08:06:00 ] '); @@ -166,11 +166,11 @@ ERROR: Could not parse temporal point value: Missing closing bracket/parenthesi LINE 1: SELECT tgeogpoint '[Point(1 1)@2001-01-01 08:00:00,Point(2 2... ^ SELECT tgeompoint '[Point(1 1)@2001-01-01 08:00:00,Point(2 2)@2001-01-01 08:05:00,Point(3 3)@2001-01-01 08:06:00] xxx'; -ERROR: Could not parse temporal point value +ERROR: Could not parse temporal point value: Extraneous characters at the end LINE 1: SELECT tgeompoint '[Point(1 1)@2001-01-01 08:00:00,Point(2 2... ^ SELECT tgeogpoint '[Point(1 1)@2001-01-01 08:00:00,Point(2 2)@2001-01-01 08:05:00,Point(3 3)@2001-01-01 08:06:00] xxx'; -ERROR: Could not parse temporal point value +ERROR: Could not parse temporal point value: Extraneous characters at the end LINE 1: SELECT tgeogpoint '[Point(1 1)@2001-01-01 08:00:00,Point(2 2... ^ SELECT asText(tgeompoint ' { [ Point(1 1)@2001-01-01 08:00:00 , Point(2 2)@2001-01-01 08:05:00 , Point(3 3)@2001-01-01 08:06:00 ], @@ -229,11 +229,11 @@ ERROR: Could not parse temporal point value: Missing closing brace LINE 1: SELECT tgeogpoint '{[Point(1 1)@2001-01-01 08:00:00],[Point(... ^ SELECT tgeompoint '{[Point(1 1)@2001-01-01 08:00:00],[Point(2 2)@2001-01-01 08:05:00,Point(3 3)@2001-01-01 08:06:00]} xxx'; -ERROR: Could not parse temporal point value +ERROR: Could not parse temporal point value: Extraneous characters at the end LINE 1: SELECT tgeompoint '{[Point(1 1)@2001-01-01 08:00:00],[Point(... ^ SELECT tgeogpoint '{[Point(1 1)@2001-01-01 08:00:00],[Point(2 2)@2001-01-01 08:05:00,Point(3 3)@2001-01-01 08:06:00]} xxx'; -ERROR: Could not parse temporal point value +ERROR: Could not parse temporal point value: Extraneous characters at the end LINE 1: SELECT tgeogpoint '{[Point(1 1)@2001-01-01 08:00:00],[Point(... ^ SELECT asEWKT(tgeompoint 'SRID=4326;[Point(0 1)@2000-01-01, Point(0 1)@2000-01-02]'); diff --git a/mobilitydb/test/point/expected/064_tpoint_distance.test.out b/mobilitydb/test/point/expected/064_tpoint_distance.test.out index ec3b5d49e9..339c40e187 100644 --- a/mobilitydb/test/point/expected/064_tpoint_distance.test.out +++ b/mobilitydb/test/point/expected/064_tpoint_distance.test.out @@ -141,97 +141,97 @@ SELECT round(geometry 'Point Z empty' <-> tgeompoint '{[Point(2 2 2)@2000-01-01, (1 row) -SELECT round(geography 'Point(1 1)' <-> tgeogpoint 'Point(2.5 2.5)@2000-01-01', 6); - round --------------------------------------------- - 235298.120089@Sat Jan 01 00:00:00 2000 PST +SELECT round(geography 'Point(-90 0)' <-> tgeogpoint 'Point(0 -90)@2000-01-01', 6); + round +---------------------------------------------- + 10001965.729313@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(geography 'Point(1 1)' <-> tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}', 6); - round -------------------------------------------------------------------------------------------------------------------------------------- - {235298.120089@Sat Jan 01 00:00:00 2000 PST, 78442.466039@Sun Jan 02 00:00:00 2000 PST, 235298.120089@Mon Jan 03 00:00:00 2000 PST} +SELECT round(geography 'Point(-90 0)' <-> tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}', 6); + round +------------------------------------------------------------------------------------------------------------------------------ + {20003931.458625@Sat Jan 01 00:00:00 2000 PST, 0@Sun Jan 02 00:00:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST} (1 row) -SELECT round(geography 'Point(1 1)' <-> tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]', 6); - round -------------------------------------------------------------------------------------------------------------------------------------- - [235298.120089@Sat Jan 01 00:00:00 2000 PST, 78442.466039@Sun Jan 02 00:00:00 2000 PST, 235298.120089@Mon Jan 03 00:00:00 2000 PST] +SELECT round(geography 'Point(-90 0)' <-> tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]', 6); + round +------------------------------------------------------------------------------------------------------------------------------ + [20003931.458625@Sat Jan 01 00:00:00 2000 PST, 0@Sun Jan 02 00:00:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST] (1 row) -SELECT round(geography 'Point(1 1)' <-> tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', 6); - round ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {[235298.120089@Sat Jan 01 00:00:00 2000 PST, 78442.466039@Sun Jan 02 00:00:00 2000 PST, 235298.120089@Mon Jan 03 00:00:00 2000 PST], [392095.189447@Tue Jan 04 00:00:00 2000 PST, 392095.189447@Wed Jan 05 00:00:00 2000 PST]} +SELECT round(geography 'Point(-90 0)' <-> tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', 6); + round +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + {[20003931.458625@Sat Jan 01 00:00:00 2000 PST, 0@Sun Jan 02 00:00:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST], [10001965.729313@Tue Jan 04 00:00:00 2000 PST, 10001965.729313@Wed Jan 05 00:00:00 2000 PST]} (1 row) -SELECT round(geography 'Point empty' <-> tgeogpoint 'Point(2.5 2.5)@2000-01-01', 6); +SELECT round(geography 'Point empty' <-> tgeogpoint 'Point(0 -90)@2000-01-01', 6); round ------- (1 row) -SELECT round(geography 'Point empty' <-> tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}', 6); +SELECT round(geography 'Point empty' <-> tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}', 6); round ------- (1 row) -SELECT round(geography 'Point empty' <-> tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]', 6); +SELECT round(geography 'Point empty' <-> tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]', 6); round ------- (1 row) -SELECT round(geography 'Point empty' <-> tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', 6); +SELECT round(geography 'Point empty' <-> tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', 6); round ------- (1 row) -SELECT round(geography 'Point(1 1 1)' <-> tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01', 6); - round --------------------------------------------- - 235298.120089@Sat Jan 01 00:00:00 2000 PST +SELECT round(geography 'Point(-90 0 100)' <-> tgeogpoint 'Point(0 -90 100)@2000-01-01', 6); + round +---------------------------------------------- + 10001965.729313@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(geography 'Point(1 1 1)' <-> tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}', 6); - round -------------------------------------------------------------------------------------------------------------------------------------- - {235298.120089@Sat Jan 01 00:00:00 2000 PST, 78442.466039@Sun Jan 02 00:00:00 2000 PST, 235298.120089@Mon Jan 03 00:00:00 2000 PST} +SELECT round(geography 'Point(-90 0 100)' <-> tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}', 6); + round +------------------------------------------------------------------------------------------------------------------------------ + {20003931.458625@Sat Jan 01 00:00:00 2000 PST, 0@Sun Jan 02 00:00:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST} (1 row) -SELECT round(geography 'Point(1 1 1)' <-> tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]', 6); - round -------------------------------------------------------------------------------------------------------------------------------------- - [235298.120089@Sat Jan 01 00:00:00 2000 PST, 78442.466039@Sun Jan 02 00:00:00 2000 PST, 235298.120089@Mon Jan 03 00:00:00 2000 PST] +SELECT round(geography 'Point(-90 0 100)' <-> tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]', 6); + round +------------------------------------------------------------------------------------------------------------------------------ + [20003931.458625@Sat Jan 01 00:00:00 2000 PST, 0@Sun Jan 02 00:00:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST] (1 row) -SELECT round(geography 'Point(1 1 1)' <-> tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', 6); - round ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {[235298.120089@Sat Jan 01 00:00:00 2000 PST, 78442.466039@Sun Jan 02 00:00:00 2000 PST, 235298.120089@Mon Jan 03 00:00:00 2000 PST], [392095.189447@Tue Jan 04 00:00:00 2000 PST, 392095.189447@Wed Jan 05 00:00:00 2000 PST]} +SELECT round(geography 'Point(-90 0 100)' <-> tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', 6); + round +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + {[20003931.458625@Sat Jan 01 00:00:00 2000 PST, 0@Sun Jan 02 00:00:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST], [10001965.729313@Tue Jan 04 00:00:00 2000 PST, 10001965.729313@Wed Jan 05 00:00:00 2000 PST]} (1 row) -SELECT round(geography 'Point Z empty' <-> tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01', 6); +SELECT round(geography 'Point Z empty' <-> tgeogpoint 'Point(0 -90 100)@2000-01-01', 6); round ------- (1 row) -SELECT round(geography 'Point Z empty' <-> tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}', 6); +SELECT round(geography 'Point Z empty' <-> tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}', 6); round ------- (1 row) -SELECT round(geography 'Point Z empty' <-> tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]', 6); +SELECT round(geography 'Point Z empty' <-> tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]', 6); round ------- (1 row) -SELECT round(geography 'Point Z empty' <-> tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', 6); +SELECT round(geography 'Point Z empty' <-> tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', 6); round ------- @@ -333,97 +333,97 @@ SELECT round(tgeompoint '{[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Poi (1 row) -SELECT round(tgeogpoint 'Point(1.5 1.5)@2000-01-01' <-> geography 'Point(1 1)', 6); - round -------------------------------------------- - 78442.466039@Sat Jan 01 00:00:00 2000 PST +SELECT round(tgeogpoint 'Point(-90 0)@2000-01-01' <-> geography 'Point(-90 0)', 6); + round +-------------------------------- + 0@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' <-> geography 'Point(1 1)', 6); - round ------------------------------------------------------------------------------------------------------------------------------------- - {78442.466039@Sat Jan 01 00:00:00 2000 PST, 235298.120089@Sun Jan 02 00:00:00 2000 PST, 78442.466039@Mon Jan 03 00:00:00 2000 PST} +SELECT round(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' <-> geography 'Point(-90 0)', 6); + round +---------------------------------------------------------------------------------------------------------------- + {0@Sat Jan 01 00:00:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 0@Mon Jan 03 00:00:00 2000 PST} (1 row) -SELECT round(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' <-> geography 'Point(1 1)', 6); - round ------------------------------------------------------------------------------------------------------------------------------------- - [78442.466039@Sat Jan 01 00:00:00 2000 PST, 235298.120089@Sun Jan 02 00:00:00 2000 PST, 78442.466039@Mon Jan 03 00:00:00 2000 PST] +SELECT round(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' <-> geography 'Point(-90 0)', 6); + round +---------------------------------------------------------------------------------------------------------------- + [0@Sat Jan 01 00:00:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 0@Mon Jan 03 00:00:00 2000 PST] (1 row) -SELECT round(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' <-> geography 'Point(1 1)', 6); - round --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {[78442.466039@Sat Jan 01 00:00:00 2000 PST, 235298.120089@Sun Jan 02 00:00:00 2000 PST, 78442.466039@Mon Jan 03 00:00:00 2000 PST], [392095.189447@Tue Jan 04 00:00:00 2000 PST, 392095.189447@Wed Jan 05 00:00:00 2000 PST]} +SELECT round(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' <-> geography 'Point(-90 0)', 6); + round +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {[0@Sat Jan 01 00:00:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 0@Mon Jan 03 00:00:00 2000 PST], [10001965.729313@Tue Jan 04 00:00:00 2000 PST, 10001965.729313@Wed Jan 05 00:00:00 2000 PST]} (1 row) -SELECT round(tgeogpoint 'Point(1.5 1.5)@2000-01-01' <-> geography 'Point empty', 6); +SELECT round(tgeogpoint 'Point(-90 0)@2000-01-01' <-> geography 'Point empty', 6); round ------- (1 row) -SELECT round(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' <-> geography 'Point empty', 6); +SELECT round(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' <-> geography 'Point empty', 6); round ------- (1 row) -SELECT round(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' <-> geography 'Point empty', 6); +SELECT round(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' <-> geography 'Point empty', 6); round ------- (1 row) -SELECT round(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' <-> geography 'Point empty', 6); +SELECT round(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' <-> geography 'Point empty', 6); round ------- (1 row) -SELECT round(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' <-> geography 'Point(1 1 1)', 6); - round -------------------------------------------- - 78442.466039@Sat Jan 01 00:00:00 2000 PST +SELECT round(tgeogpoint 'Point(-90 0 100)@2000-01-01' <-> geography 'Point(-90 0 100)', 6); + round +-------------------------------- + 0@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' <-> geography 'Point(1 1 1)', 6); - round ------------------------------------------------------------------------------------------------------------------------------------- - {78442.466039@Sat Jan 01 00:00:00 2000 PST, 235298.120089@Sun Jan 02 00:00:00 2000 PST, 78442.466039@Mon Jan 03 00:00:00 2000 PST} +SELECT round(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' <-> geography 'Point(-90 0 100)', 6); + round +---------------------------------------------------------------------------------------------------------------- + {0@Sat Jan 01 00:00:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 0@Mon Jan 03 00:00:00 2000 PST} (1 row) -SELECT round(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' <-> geography 'Point(1 1 1)', 6); - round ------------------------------------------------------------------------------------------------------------------------------------- - [78442.466039@Sat Jan 01 00:00:00 2000 PST, 235298.120089@Sun Jan 02 00:00:00 2000 PST, 78442.466039@Mon Jan 03 00:00:00 2000 PST] +SELECT round(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' <-> geography 'Point(-90 0 100)', 6); + round +---------------------------------------------------------------------------------------------------------------- + [0@Sat Jan 01 00:00:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 0@Mon Jan 03 00:00:00 2000 PST] (1 row) -SELECT round(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' <-> geography 'Point(1 1 1)', 6); - round --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {[78442.466039@Sat Jan 01 00:00:00 2000 PST, 235298.120089@Sun Jan 02 00:00:00 2000 PST, 78442.466039@Mon Jan 03 00:00:00 2000 PST], [392095.189447@Tue Jan 04 00:00:00 2000 PST, 392095.189447@Wed Jan 05 00:00:00 2000 PST]} +SELECT round(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' <-> geography 'Point(-90 0 100)', 6); + round +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {[0@Sat Jan 01 00:00:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 0@Mon Jan 03 00:00:00 2000 PST], [10001965.729313@Tue Jan 04 00:00:00 2000 PST, 10001965.729313@Wed Jan 05 00:00:00 2000 PST]} (1 row) -SELECT round(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' <-> geography 'Point Z empty', 6); +SELECT round(tgeogpoint 'Point(-90 0 100)@2000-01-01' <-> geography 'Point Z empty', 6); round ------- (1 row) -SELECT round(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' <-> geography 'Point Z empty', 6); +SELECT round(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' <-> geography 'Point Z empty', 6); round ------- (1 row) -SELECT round(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' <-> geography 'Point Z empty', 6); +SELECT round(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' <-> geography 'Point Z empty', 6); round ------- (1 row) -SELECT round(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' <-> geography 'Point Z empty', 6); +SELECT round(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' <-> geography 'Point Z empty', 6); round ------- @@ -627,196 +627,196 @@ SELECT round(tgeompoint 'Interp=Step;[Point(1 1)@2000-01-01, Point(2 2)@2000-01- Interp=Step;[1.414214@Sat Jan 01 00:00:00 2000 PST, 1.414214@Sun Jan 02 00:00:00 2000 PST] (1 row) -SELECT round(tgeogpoint 'Point(1.5 1.5)@2000-01-01' <-> tgeogpoint 'Point(2.5 2.5)@2000-01-01', 6); - round --------------------------------------------- - 156855.662657@Sat Jan 01 00:00:00 2000 PST +SELECT round(tgeogpoint 'Point(-90 0)@2000-01-01' <-> tgeogpoint 'Point(0 -90)@2000-01-01', 6); + round +---------------------------------------------- + 10001965.729313@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' <-> tgeogpoint 'Point(2.5 2.5)@2000-01-01', 6); - round --------------------------------------------- - 156855.662657@Sat Jan 01 00:00:00 2000 PST +SELECT round(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' <-> tgeogpoint 'Point(0 -90)@2000-01-01', 6); + round +---------------------------------------------- + 10001965.729313@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' <-> tgeogpoint 'Point(2.5 2.5)@2000-01-01', 6); - round --------------------------------------------- - 156855.662657@Sat Jan 01 00:00:00 2000 PST +SELECT round(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' <-> tgeogpoint 'Point(0 -90)@2000-01-01', 6); + round +---------------------------------------------- + 10001965.729313@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' <-> tgeogpoint 'Point(2.5 2.5)@2000-01-01', 6); - round --------------------------------------------- - 156855.662657@Sat Jan 01 00:00:00 2000 PST +SELECT round(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' <-> tgeogpoint 'Point(0 -90)@2000-01-01', 6); + round +---------------------------------------------- + 10001965.729313@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(tgeogpoint 'Point(1.5 1.5)@2000-01-01' <-> tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}', 6); - round --------------------------------------------- - 156855.662657@Sat Jan 01 00:00:00 2000 PST +SELECT round(tgeogpoint 'Point(-90 0)@2000-01-01' <-> tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}', 6); + round +---------------------------------------------- + 20003931.458625@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' <-> tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}', 6); - round --------------------------------------------------------------------------------------------------------------------------------------- - {156855.662657@Sat Jan 01 00:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST} +SELECT round(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' <-> tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}', 6); + round +-------------------------------------------------------------------------------------------------------------------------------------------- + {20003931.458625@Sat Jan 01 00:00:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST} (1 row) -SELECT round(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' <-> tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}', 6); - round --------------------------------------------------------------------------------------------------------------------------------------- - {156855.662657@Sat Jan 01 00:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST} +SELECT round(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' <-> tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}', 6); + round +-------------------------------------------------------------------------------------------------------------------------------------------- + {20003931.458625@Sat Jan 01 00:00:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST} (1 row) -SELECT round(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' <-> tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}', 6); - round --------------------------------------------------------------------------------------------------------------------------------------- - {156855.662657@Sat Jan 01 00:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST} +SELECT round(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' <-> tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}', 6); + round +-------------------------------------------------------------------------------------------------------------------------------------------- + {20003931.458625@Sat Jan 01 00:00:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST} (1 row) -SELECT round(tgeogpoint 'Point(1.5 1.5)@2000-01-01' <-> tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]', 6); - round --------------------------------------------- - 156855.662657@Sat Jan 01 00:00:00 2000 PST +SELECT round(tgeogpoint 'Point(-90 0)@2000-01-01' <-> tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]', 6); + round +---------------------------------------------- + 20003931.458625@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' <-> tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]', 6); - round --------------------------------------------------------------------------------------------------------------------------------------- - {156855.662657@Sat Jan 01 00:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST} +SELECT round(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' <-> tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]', 6); + round +-------------------------------------------------------------------------------------------------------------------------------------------- + {20003931.458625@Sat Jan 01 00:00:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST} (1 row) -SELECT round(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' <-> tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]', 6); - round ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - [156855.662657@Sat Jan 01 00:00:00 2000 PST, 0@Sat Jan 01 12:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 0@Sun Jan 02 12:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST] +SELECT round(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' <-> tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]', 6); + round +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + [20003931.458625@Sat Jan 01 00:00:00 2000 PST, 0.314159@Sat Jan 01 14:24:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 0.314159@Sun Jan 02 09:36:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST] (1 row) -SELECT round(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' <-> tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]', 6); - round --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {[156855.662657@Sat Jan 01 00:00:00 2000 PST, 0@Sat Jan 01 12:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 0@Sun Jan 02 12:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST]} +SELECT round(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' <-> tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]', 6); + round +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {[20003931.458625@Sat Jan 01 00:00:00 2000 PST, 0.314159@Sat Jan 01 14:24:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 0.314159@Sun Jan 02 09:36:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST]} (1 row) -SELECT round(tgeogpoint 'Point(1.5 1.5)@2000-01-01' <-> tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', 6); - round --------------------------------------------- - 156855.662657@Sat Jan 01 00:00:00 2000 PST +SELECT round(tgeogpoint 'Point(-90 0)@2000-01-01' <-> tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', 6); + round +---------------------------------------------- + 20003931.458625@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' <-> tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', 6); - round --------------------------------------------------------------------------------------------------------------------------------------- - {156855.662657@Sat Jan 01 00:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST} +SELECT round(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' <-> tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', 6); + round +-------------------------------------------------------------------------------------------------------------------------------------------- + {20003931.458625@Sat Jan 01 00:00:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST} (1 row) -SELECT round(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' <-> tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', 6); - round --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {[156855.662657@Sat Jan 01 00:00:00 2000 PST, 0@Sat Jan 01 12:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 0@Sun Jan 02 12:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST]} +SELECT round(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' <-> tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', 6); + round +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {[20003931.458625@Sat Jan 01 00:00:00 2000 PST, 0.314159@Sat Jan 01 14:24:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 0.314159@Sun Jan 02 09:36:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST]} (1 row) -SELECT round(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' <-> tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', 6); - round --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {[156855.662657@Sat Jan 01 00:00:00 2000 PST, 0@Sat Jan 01 12:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 0@Sun Jan 02 12:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST], [0@Tue Jan 04 00:00:00 2000 PST, 0@Wed Jan 05 00:00:00 2000 PST]} +SELECT round(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' <-> tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', 6); + round +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {[20003931.458625@Sat Jan 01 00:00:00 2000 PST, 0.314159@Sat Jan 01 14:24:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 0.314159@Sun Jan 02 09:36:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST], [0@Tue Jan 04 00:00:00 2000 PST, 0@Wed Jan 05 00:00:00 2000 PST]} (1 row) -SELECT round(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' <-> tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01', 6); - round --------------------------------------------- - 156855.662657@Sat Jan 01 00:00:00 2000 PST +SELECT round(tgeogpoint 'Point(-90 0 100)@2000-01-01' <-> tgeogpoint 'Point(0 -90 100)@2000-01-01', 6); + round +---------------------------------------------- + 10001965.729313@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' <-> tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01', 6); - round --------------------------------------------- - 156855.662657@Sat Jan 01 00:00:00 2000 PST +SELECT round(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' <-> tgeogpoint 'Point(0 -90 100)@2000-01-01', 6); + round +---------------------------------------------- + 10001965.729313@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' <-> tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01', 6); - round --------------------------------------------- - 156855.662657@Sat Jan 01 00:00:00 2000 PST +SELECT round(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' <-> tgeogpoint 'Point(0 -90 100)@2000-01-01', 6); + round +---------------------------------------------- + 10001965.729313@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' <-> tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01', 6); - round --------------------------------------------- - 156855.662657@Sat Jan 01 00:00:00 2000 PST +SELECT round(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' <-> tgeogpoint 'Point(0 -90 100)@2000-01-01', 6); + round +---------------------------------------------- + 10001965.729313@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' <-> tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}', 6); - round --------------------------------------------- - 156855.662657@Sat Jan 01 00:00:00 2000 PST +SELECT round(tgeogpoint 'Point(-90 0 100)@2000-01-01' <-> tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}', 6); + round +---------------------------------------------- + 20003931.458625@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' <-> tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}', 6); - round --------------------------------------------------------------------------------------------------------------------------------------- - {156855.662657@Sat Jan 01 00:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST} +SELECT round(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' <-> tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}', 6); + round +-------------------------------------------------------------------------------------------------------------------------------------------- + {20003931.458625@Sat Jan 01 00:00:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST} (1 row) -SELECT round(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' <-> tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}', 6); - round --------------------------------------------------------------------------------------------------------------------------------------- - {156855.662657@Sat Jan 01 00:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST} +SELECT round(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' <-> tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}', 6); + round +-------------------------------------------------------------------------------------------------------------------------------------------- + {20003931.458625@Sat Jan 01 00:00:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST} (1 row) -SELECT round(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' <-> tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}', 6); - round --------------------------------------------------------------------------------------------------------------------------------------- - {156855.662657@Sat Jan 01 00:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST} +SELECT round(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' <-> tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}', 6); + round +-------------------------------------------------------------------------------------------------------------------------------------------- + {20003931.458625@Sat Jan 01 00:00:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST} (1 row) -SELECT round(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' <-> tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]', 6); - round --------------------------------------------- - 156855.662657@Sat Jan 01 00:00:00 2000 PST +SELECT round(tgeogpoint 'Point(-90 0 100)@2000-01-01' <-> tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]', 6); + round +---------------------------------------------- + 20003931.458625@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' <-> tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]', 6); - round --------------------------------------------------------------------------------------------------------------------------------------- - {156855.662657@Sat Jan 01 00:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST} +SELECT round(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' <-> tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]', 6); + round +-------------------------------------------------------------------------------------------------------------------------------------------- + {20003931.458625@Sat Jan 01 00:00:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST} (1 row) -SELECT round(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' <-> tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]', 6); - round ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - [156855.662657@Sat Jan 01 00:00:00 2000 PST, 0@Sat Jan 01 12:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 0@Sun Jan 02 12:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST] +SELECT round(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' <-> tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]', 6); + round +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + [20003931.458625@Sat Jan 01 00:00:00 2000 PST, 0.314159@Sat Jan 01 14:24:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 0.314159@Sun Jan 02 09:36:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST] (1 row) -SELECT round(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' <-> tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]', 6); - round --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {[156855.662657@Sat Jan 01 00:00:00 2000 PST, 0@Sat Jan 01 12:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 0@Sun Jan 02 12:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST]} +SELECT round(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' <-> tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]', 6); + round +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {[20003931.458625@Sat Jan 01 00:00:00 2000 PST, 0.314159@Sat Jan 01 14:24:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 0.314159@Sun Jan 02 09:36:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST]} (1 row) -SELECT round(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' <-> tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', 6); - round --------------------------------------------- - 156855.662657@Sat Jan 01 00:00:00 2000 PST +SELECT round(tgeogpoint 'Point(-90 0 100)@2000-01-01' <-> tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', 6); + round +---------------------------------------------- + 20003931.458625@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT round(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' <-> tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', 6); - round --------------------------------------------------------------------------------------------------------------------------------------- - {156855.662657@Sat Jan 01 00:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST} +SELECT round(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' <-> tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', 6); + round +-------------------------------------------------------------------------------------------------------------------------------------------- + {20003931.458625@Sat Jan 01 00:00:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST} (1 row) -SELECT round(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' <-> tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', 6); - round --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {[156855.662657@Sat Jan 01 00:00:00 2000 PST, 0@Sat Jan 01 12:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 0@Sun Jan 02 12:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST]} +SELECT round(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' <-> tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', 6); + round +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {[20003931.458625@Sat Jan 01 00:00:00 2000 PST, 0.314159@Sat Jan 01 14:24:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 0.314159@Sun Jan 02 09:36:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST]} (1 row) -SELECT round(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' <-> tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', 6); - round --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - {[156855.662657@Sat Jan 01 00:00:00 2000 PST, 0@Sat Jan 01 12:00:00 2000 PST, 156855.662657@Sun Jan 02 00:00:00 2000 PST, 0@Sun Jan 02 12:00:00 2000 PST, 156855.662657@Mon Jan 03 00:00:00 2000 PST], [0@Tue Jan 04 00:00:00 2000 PST, 0@Wed Jan 05 00:00:00 2000 PST]} +SELECT round(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' <-> tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', 6); + round +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {[20003931.458625@Sat Jan 01 00:00:00 2000 PST, 0.314159@Sat Jan 01 14:24:00 2000 PST, 10018754.171395@Sun Jan 02 00:00:00 2000 PST, 0.314159@Sun Jan 02 09:36:00 2000 PST, 20003931.458625@Mon Jan 03 00:00:00 2000 PST], [0@Tue Jan 04 00:00:00 2000 PST, 0@Wed Jan 05 00:00:00 2000 PST]} (1 row) SELECT asText(NearestApproachInstant(tgeompoint 'Point(1 1)@2000-01-01', geometry 'Linestring(0 0,3 3)')); @@ -897,73 +897,73 @@ SELECT asText(NearestApproachInstant(tgeompoint '[Point(1 1)@2000-01-01, Point(1 POINT(1 1)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5)@2000-01-01', geography 'Linestring(0 0,3 3)'),6)); - astext ---------------------------------------------- - POINT(1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0)@2000-01-01', geography 'Linestring(90 0,0 90)'),6)); + astext +------------------------------------------- + POINT(-90 0)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', geography 'Linestring(0 0,3 3)'),6)); - astext ---------------------------------------------- - POINT(2.5 2.5)@Sun Jan 02 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', geography 'Linestring(90 0,0 90)'),6)); + astext +------------------------------------------- + POINT(-90 0)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', geography 'Linestring(0 0,3 3)'),6)); - astext ---------------------------------------------- - POINT(2.5 2.5)@Sun Jan 02 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', geography 'Linestring(90 0,0 90)'),6)); + astext +------------------------------------------- + POINT(-90 0)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', geography 'Linestring(0 0,3 3)'),6)); - astext ---------------------------------------------- - POINT(2.5 2.5)@Sun Jan 02 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', geography 'Linestring(90 0,0 90)'),6)); + astext +------------------------------------------- + POINT(-90 0)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(NearestApproachInstant(tgeogpoint 'Interp=Step;[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', geography 'Linestring(0 0,3 3)')); - astext ---------------------------------------------- - POINT(2.5 2.5)@Sun Jan 02 00:00:00 2000 PST +SELECT asText(NearestApproachInstant(tgeogpoint 'Interp=Step;[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', geography 'Linestring(90 0,0 90)')); + astext +------------------------------------------- + POINT(-90 0)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(NearestApproachInstant(tgeogpoint 'Interp=Step;{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', geography 'Linestring(0 0,3 3)')); - astext ---------------------------------------------- - POINT(2.5 2.5)@Sun Jan 02 00:00:00 2000 PST +SELECT asText(NearestApproachInstant(tgeogpoint 'Interp=Step;{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', geography 'Linestring(90 0,0 90)')); + astext +------------------------------------------- + POINT(90 90)@Tue Jan 04 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5)@2000-01-01', geography 'Linestring empty'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0)@2000-01-01', geography 'Linestring empty'),6)); astext -------- (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', geography 'Linestring empty'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', geography 'Linestring empty'),6)); astext -------- (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', geography 'Linestring empty'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', geography 'Linestring empty'),6)); astext -------- (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', geography 'Linestring empty'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', geography 'Linestring empty'),6)); astext -------- (1 row) -SELECT asText(NearestApproachInstant(tgeogpoint 'Interp=Step;[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', geography 'Linestring empty')); +SELECT asText(NearestApproachInstant(tgeogpoint 'Interp=Step;[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', geography 'Linestring empty')); astext -------- (1 row) -SELECT asText(NearestApproachInstant(tgeogpoint 'Interp=Step;{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', geography 'Linestring empty')); +SELECT asText(NearestApproachInstant(tgeogpoint 'Interp=Step;{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', geography 'Linestring empty')); astext -------- @@ -1017,49 +1017,49 @@ SELECT asText(NearestApproachInstant(geometry 'Linestring empty', tgeompoint '{[ (1 row) -SELECT asText(NearestApproachInstant(geography 'Linestring(0 0,3 3)', tgeogpoint 'Point(1.5 1.5)@2000-01-01')); - astext ---------------------------------------------- - POINT(1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(NearestApproachInstant(geography 'Linestring(90 0,0 90)', tgeogpoint 'Point(-90 0)@2000-01-01')); + astext +------------------------------------------- + POINT(-90 0)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(NearestApproachInstant(geography 'Linestring(0 0,3 3)', tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}')); - astext ---------------------------------------------- - POINT(2.5 2.5)@Sun Jan 02 00:00:00 2000 PST +SELECT asText(NearestApproachInstant(geography 'Linestring(90 0,0 90)', tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}')); + astext +------------------------------------------- + POINT(-90 0)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(NearestApproachInstant(geography 'Linestring(0 0,3 3)', tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]')); - astext ---------------------------------------------- - POINT(2.5 2.5)@Sun Jan 02 00:00:00 2000 PST +SELECT asText(NearestApproachInstant(geography 'Linestring(90 0,0 90)', tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]')); + astext +------------------------------------------- + POINT(-90 0)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(NearestApproachInstant(geography 'Linestring(0 0,3 3)', tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')); - astext ---------------------------------------------- - POINT(2.5 2.5)@Sun Jan 02 00:00:00 2000 PST +SELECT asText(NearestApproachInstant(geography 'Linestring(90 0,0 90)', tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')); + astext +------------------------------------------- + POINT(-90 0)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(NearestApproachInstant(geography 'Linestring empty', tgeogpoint 'Point(1.5 1.5)@2000-01-01')); +SELECT asText(NearestApproachInstant(geography 'Linestring empty', tgeogpoint 'Point(-90 0)@2000-01-01')); astext -------- (1 row) -SELECT asText(NearestApproachInstant(geography 'Linestring empty', tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}')); +SELECT asText(NearestApproachInstant(geography 'Linestring empty', tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}')); astext -------- (1 row) -SELECT asText(NearestApproachInstant(geography 'Linestring empty', tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]')); +SELECT asText(NearestApproachInstant(geography 'Linestring empty', tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]')); astext -------- (1 row) -SELECT asText(NearestApproachInstant(geography 'Linestring empty', tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')); +SELECT asText(NearestApproachInstant(geography 'Linestring empty', tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')); astext -------- @@ -1269,196 +1269,196 @@ SELECT asText(NearestApproachInstant(tgeompoint '{[Point(1 1 1)@2000-01-01, Poin POINT Z (1.5 1.5 1.5)@Sat Jan 01 12:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint 'Point(2.5 2.5)@2000-01-01'),6)); - astext ---------------------------------------------- - POINT(1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint 'Point(0 -90)@2000-01-01'),6)); + astext +------------------------------------------- + POINT(-90 0)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint 'Point(2.5 2.5)@2000-01-01'),6)); - astext ---------------------------------------------- - POINT(1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint 'Point(0 -90)@2000-01-01'),6)); + astext +------------------------------------------- + POINT(-90 0)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint 'Point(2.5 2.5)@2000-01-01'),6)); - astext ---------------------------------------------- - POINT(1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint 'Point(0 -90)@2000-01-01'),6)); + astext +------------------------------------------- + POINT(-90 0)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint 'Point(2.5 2.5)@2000-01-01'),6)); - astext ---------------------------------------------- - POINT(1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint 'Point(0 -90)@2000-01-01'),6)); + astext +------------------------------------------- + POINT(-90 0)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}'),6)); - astext ---------------------------------------------- - POINT(1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}'),6)); + astext +------------------------------------------- + POINT(-90 0)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}'),6)); - astext ---------------------------------------------- - POINT(1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}'),6)); + astext +----------------------------------------- + POINT(0 0)@Sun Jan 02 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}'),6)); - astext ---------------------------------------------- - POINT(1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}'),6)); + astext +----------------------------------------- + POINT(0 0)@Sun Jan 02 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}'),6)); - astext ---------------------------------------------- - POINT(1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}'),6)); + astext +----------------------------------------- + POINT(0 0)@Sun Jan 02 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]'),6)); - astext ---------------------------------------------- - POINT(1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]'),6)); + astext +------------------------------------------- + POINT(-90 0)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]'),6)); - astext ---------------------------------------------- - POINT(1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]'),6)); + astext +----------------------------------------- + POINT(0 0)@Sun Jan 02 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]'),6)); - astext -------------------------------------------------------- - POINT(1.999848 2.000076)@Sat Jan 01 12:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-03]', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]'),6)); + astext +--------------------------------------------------------- + POINT(-54.157111 0)@Sat Jan 01 19:06:58.346516 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]'),6)); - astext -------------------------------------------------------- - POINT(1.999848 2.000076)@Sat Jan 01 12:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]'),6)); + astext +--------------------------------------------------------- + POINT(-54.157111 0)@Sat Jan 01 19:06:58.346516 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'),6)); - astext ---------------------------------------------- - POINT(1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}'),6)); + astext +------------------------------------------- + POINT(-90 0)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'),6)); - astext ---------------------------------------------- - POINT(1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}'),6)); + astext +----------------------------------------- + POINT(0 0)@Sun Jan 02 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'),6)); - astext -------------------------------------------------------- - POINT(1.999848 2.000076)@Sat Jan 01 12:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-03]', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}'),6)); + astext +--------------------------------------------------------- + POINT(-54.157111 0)@Sat Jan 01 19:06:58.346516 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'),6)); - astext ---------------------------------------------- - POINT(3.5 3.5)@Tue Jan 04 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}'),6)); + astext +------------------------------------------- + POINT(90 90)@Tue Jan 04 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01'),6)); - astext ----------------------------------------------------- - POINT Z (1.5 1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint 'Point(0 -90 100)@2000-01-01'),6)); + astext +-------------------------------------------------- + POINT Z (-90 0 100)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01'),6)); - astext ----------------------------------------------------- - POINT Z (1.5 1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint 'Point(0 -90 100)@2000-01-01'),6)); + astext +-------------------------------------------------- + POINT Z (-90 0 100)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01'),6)); - astext ----------------------------------------------------- - POINT Z (1.5 1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint 'Point(0 -90 100)@2000-01-01'),6)); + astext +-------------------------------------------------- + POINT Z (-90 0 100)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01'),6)); - astext ----------------------------------------------------- - POINT Z (1.5 1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint 'Point(0 -90 100)@2000-01-01'),6)); + astext +-------------------------------------------------- + POINT Z (-90 0 100)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}'),6)); - astext ----------------------------------------------------- - POINT Z (1.5 1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}'),6)); + astext +-------------------------------------------------- + POINT Z (-90 0 100)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}'),6)); - astext ----------------------------------------------------- - POINT Z (1.5 1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}'),6)); + astext +------------------------------------------------ + POINT Z (0 0 100)@Sun Jan 02 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}'),6)); - astext ----------------------------------------------------- - POINT Z (1.5 1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}'),6)); + astext +------------------------------------------------ + POINT Z (0 0 100)@Sun Jan 02 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}'),6)); - astext ----------------------------------------------------- - POINT Z (1.5 1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}'),6)); + astext +------------------------------------------------ + POINT Z (0 0 100)@Sun Jan 02 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'),6)); - astext ----------------------------------------------------- - POINT Z (1.5 1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]'),6)); + astext +-------------------------------------------------- + POINT Z (-90 0 100)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'),6)); - astext ----------------------------------------------------- - POINT Z (1.5 1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]'),6)); + astext +------------------------------------------------ + POINT Z (0 0 100)@Sun Jan 02 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'),6)); - astext ------------------------------------------------------------- - POINT Z (1.999848 2.000076 2)@Sat Jan 01 12:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-03]', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]'),6)); + astext +---------------------------------------------------------------- + POINT Z (-54.157111 0 100)@Sat Jan 01 19:06:58.346516 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'),6)); - astext ------------------------------------------------------------- - POINT Z (1.999848 2.000076 2)@Sat Jan 01 12:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]'),6)); + astext +---------------------------------------------------------------- + POINT Z (-54.157111 0 100)@Sat Jan 01 19:06:58.346516 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}'),6)); - astext ----------------------------------------------------- - POINT Z (1.5 1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}'),6)); + astext +-------------------------------------------------- + POINT Z (-90 0 100)@Sat Jan 01 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}'),6)); - astext ----------------------------------------------------- - POINT Z (1.5 1.5 1.5)@Sat Jan 01 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}'),6)); + astext +------------------------------------------------ + POINT Z (0 0 100)@Sun Jan 02 00:00:00 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}'),6)); - astext ------------------------------------------------------------- - POINT Z (1.999848 2.000076 2)@Sat Jan 01 12:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-03]', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}'),6)); + astext +---------------------------------------------------------------- + POINT Z (-54.157111 0 100)@Sat Jan 01 19:06:58.346516 2000 PST (1 row) -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}'),6)); - astext ----------------------------------------------------- - POINT Z (3.5 3.5 3.5)@Tue Jan 04 00:00:00 2000 PST +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}'),6)); + astext +-------------------------------------------------- + POINT Z (90 90 100)@Tue Jan 04 00:00:00 2000 PST (1 row) /* Errors */ @@ -1618,97 +1618,97 @@ SELECT round(NearestApproachDistance(tgeompoint 'Interp=Step;{[Point(1 1 1)@2000 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5)@2000-01-01', geography 'Linestring(0 0,3 3)')::numeric, 6); - round ------------- - 121.017803 +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0)@2000-01-01', geography 'Linestring(90 0,0 90)')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', geography 'Linestring(0 0,3 3)')::numeric, 6); - round ------------ - 82.147884 +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', geography 'Linestring(90 0,0 90)')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', geography 'Linestring(0 0,3 3)')::numeric, 6); - round ------------ - 82.147884 +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', geography 'Linestring(90 0,0 90)')::numeric, 6); + round +---------- + 0.000000 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', geography 'Linestring(0 0,3 3)')::numeric, 6); - round ------------ - 82.147884 +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', geography 'Linestring(90 0,0 90)')::numeric, 6); + round +---------- + 0.000000 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5)@2000-01-01', geography 'Linestring empty')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0)@2000-01-01', geography 'Linestring empty')::numeric, 6); round ------- (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', geography 'Linestring empty')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', geography 'Linestring empty')::numeric, 6); round ------- (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', geography 'Linestring empty')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', geography 'Linestring empty')::numeric, 6); round ------- (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', geography 'Linestring empty')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', geography 'Linestring empty')::numeric, 6); round ------- (1 row) -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', geography 'Linestring(0 0 0,3 3 3)')::numeric, 6); - round ------------- - 121.017803 +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0 100)@2000-01-01', geography 'Linestring(90 0 0,0 90 100)')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', geography 'Linestring(0 0 0,3 3 3)')::numeric, 6); - round ------------ - 82.147884 +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', geography 'Linestring(90 0 0,0 90 100)')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', geography 'Linestring(0 0 0,3 3 3)')::numeric, 6); - round ------------ - 82.147884 +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', geography 'Linestring(90 0 0,0 90 100)')::numeric, 6); + round +---------- + 0.000000 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', geography 'Linestring(0 0 0,3 3 3)')::numeric, 6); - round ------------ - 82.147884 +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', geography 'Linestring(90 0 0,0 90 100)')::numeric, 6); + round +---------- + 0.000000 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', geography 'Linestring Z empty')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0 100)@2000-01-01', geography 'Linestring Z empty')::numeric, 6); round ------- (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', geography 'Linestring Z empty')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', geography 'Linestring Z empty')::numeric, 6); round ------- (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', geography 'Linestring Z empty')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', geography 'Linestring Z empty')::numeric, 6); round ------- (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', geography 'Linestring Z empty')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', geography 'Linestring Z empty')::numeric, 6); round ------- @@ -1810,97 +1810,97 @@ SELECT round(NearestApproachDistance(geometry 'Linestring Z empty', tgeompoint ' (1 row) -SELECT round(NearestApproachDistance(geography 'Linestring(0 0,3 3)', tgeogpoint 'Point(1.5 1.5)@2000-01-01')::numeric, 6); - round ------------- - 121.017803 +SELECT round(NearestApproachDistance(geography 'Linestring(90 0,0 90)', tgeogpoint 'Point(-90 0)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round(NearestApproachDistance(geography 'Linestring(0 0,3 3)', tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}')::numeric, 6); - round ------------ - 82.147884 +SELECT round(NearestApproachDistance(geography 'Linestring(90 0,0 90)', tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round(NearestApproachDistance(geography 'Linestring(0 0,3 3)', tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]')::numeric, 6); - round ------------ - 82.147884 +SELECT round(NearestApproachDistance(geography 'Linestring(90 0,0 90)', tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]')::numeric, 6); + round +---------- + 0.000000 (1 row) -SELECT round(NearestApproachDistance(geography 'Linestring(0 0,3 3)', tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); - round ------------ - 82.147884 +SELECT round(NearestApproachDistance(geography 'Linestring(90 0,0 90)', tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); + round +---------- + 0.000000 (1 row) -SELECT round(NearestApproachDistance(geography 'Linestring empty', tgeogpoint 'Point(1.5 1.5)@2000-01-01')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring empty', tgeogpoint 'Point(-90 0)@2000-01-01')::numeric, 6); round ------- (1 row) -SELECT round(NearestApproachDistance(geography 'Linestring empty', tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring empty', tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}')::numeric, 6); round ------- (1 row) -SELECT round(NearestApproachDistance(geography 'Linestring empty', tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring empty', tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]')::numeric, 6); round ------- (1 row) -SELECT round(NearestApproachDistance(geography 'Linestring empty', tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring empty', tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); round ------- (1 row) -SELECT round(NearestApproachDistance(geography 'Linestring(0 0 0,3 3 3)', tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01')::numeric, 6); - round ------------- - 121.017803 +SELECT round(NearestApproachDistance(geography 'Linestring(90 0 0,0 90 100)', tgeogpoint 'Point(-90 0 100)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round(NearestApproachDistance(geography 'Linestring(0 0 0,3 3 3)', tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}')::numeric, 6); - round ------------ - 82.147884 +SELECT round(NearestApproachDistance(geography 'Linestring(90 0 0,0 90 100)', tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round(NearestApproachDistance(geography 'Linestring(0 0 0,3 3 3)', tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]')::numeric, 6); - round ------------ - 82.147884 +SELECT round(NearestApproachDistance(geography 'Linestring(90 0 0,0 90 100)', tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]')::numeric, 6); + round +---------- + 0.000000 (1 row) -SELECT round(NearestApproachDistance(geography 'Linestring(0 0 0,3 3 3)', tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); - round ------------ - 82.147884 +SELECT round(NearestApproachDistance(geography 'Linestring(90 0 0,0 90 100)', tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); + round +---------- + 0.000000 (1 row) -SELECT round(NearestApproachDistance(geography 'Linestring Z empty', tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring Z empty', tgeogpoint 'Point(-90 0 100)@2000-01-01')::numeric, 6); round ------- (1 row) -SELECT round(NearestApproachDistance(geography 'Linestring Z empty', tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring Z empty', tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}')::numeric, 6); round ------- (1 row) -SELECT round(NearestApproachDistance(geography 'Linestring Z empty', tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring Z empty', tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]')::numeric, 6); round ------- (1 row) -SELECT round(NearestApproachDistance(geography 'Linestring Z empty', tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring Z empty', tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); round ------- @@ -2098,191 +2098,193 @@ SELECT round(NearestApproachDistance(tgeompoint '{[Point(1 1 1)@2000-01-01, Poin 0.000000 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint 'Point(2.5 2.5)@2000-01-01')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint 'Point(0 -90)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint 'Point(2.5 2.5)@2000-01-01')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint 'Point(0 -90)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint 'Point(2.5 2.5)@2000-01-01')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint 'Point(0 -90)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint 'Point(2.5 2.5)@2000-01-01')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint 'Point(0 -90)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')::numeric, 6); + round +----------------- + 20003931.458625 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')::numeric, 6); + round +----------------- + 20003931.458625 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')::numeric, 6); round ---------- - 0.000000 + 0.314159 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')::numeric, 6); round ---------- - 0.000000 + 0.314159 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); + round +----------------- + 20003931.458625 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); round ---------- - 0.000000 + 0.314159 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); round ---------- 0.000000 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint 'Point(0 -90 100)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint 'Point(0 -90 100)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint 'Point(0 -90 100)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint 'Point(0 -90 100)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')::numeric, 6); + round +----------------- + 20003931.458625 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')::numeric, 6); + round +----------------- + 20003931.458625 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'::numeric, 6)); -ERROR: cannot cast type tgeogpoint to numeric -LINE 1: ...5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'::numeric,... - ^ -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')::numeric, 6); round ---------- - 0.000000 + 0.314159 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')::numeric, 6); + round +---------- + 0.314159 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); + round +----------------- + 20003931.458625 +(1 row) + +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); round ---------- - 0.000000 + 0.314159 (1 row) -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); round ---------- 0.000000 @@ -2490,97 +2492,97 @@ SELECT round((tgeompoint '{[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Po (1 row) -SELECT round((tgeogpoint 'Point(1.5 1.5)@2000-01-01' |=| geography 'Linestring(0 0,3 3)')::numeric, 6); - round ------------- - 121.017803 +SELECT round((tgeogpoint 'Point(-90 0)@2000-01-01' |=| geography 'Linestring(90 0,0 90)')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round((tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' |=| geography 'Linestring(0 0,3 3)')::numeric, 6); - round ------------ - 82.147884 +SELECT round((tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' |=| geography 'Linestring(90 0,0 90)')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round((tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' |=| geography 'Linestring(0 0,3 3)')::numeric, 6); - round ------------ - 82.147884 +SELECT round((tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' |=| geography 'Linestring(90 0,0 90)')::numeric, 6); + round +---------- + 0.000000 (1 row) -SELECT round((tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' |=| geography 'Linestring(0 0,3 3)')::numeric, 6); - round ------------ - 82.147884 +SELECT round((tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' |=| geography 'Linestring(90 0,0 90)')::numeric, 6); + round +---------- + 0.000000 (1 row) -SELECT round((tgeogpoint 'Point(1.5 1.5)@2000-01-01' |=| geography 'Linestring empty')::numeric, 6); +SELECT round((tgeogpoint 'Point(-90 0)@2000-01-01' |=| geography 'Linestring empty')::numeric, 6); round ------- (1 row) -SELECT round((tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' |=| geography 'Linestring empty')::numeric, 6); +SELECT round((tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' |=| geography 'Linestring empty')::numeric, 6); round ------- (1 row) -SELECT round((tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' |=| geography 'Linestring empty')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' |=| geography 'Linestring empty')::numeric, 6); round ------- (1 row) -SELECT round((tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' |=| geography 'Linestring empty')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' |=| geography 'Linestring empty')::numeric, 6); round ------- (1 row) -SELECT round((tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' |=| geography 'Linestring(0 0 0,3 3 3)')::numeric, 6); - round ------------- - 121.017803 +SELECT round((tgeogpoint 'Point(-90 0 100)@2000-01-01' |=| geography 'Linestring(90 0 0,0 90 100)')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round((tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' |=| geography 'Linestring(0 0 0,3 3 3)')::numeric, 6); - round ------------ - 82.147884 +SELECT round((tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' |=| geography 'Linestring(90 0 0,0 90 100)')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round((tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' |=| geography 'Linestring(0 0 0,3 3 3)')::numeric, 6); - round ------------ - 82.147884 +SELECT round((tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' |=| geography 'Linestring(90 0 0,0 90 100)')::numeric, 6); + round +---------- + 0.000000 (1 row) -SELECT round((tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' |=| geography 'Linestring(0 0 0,3 3 3)')::numeric, 6); - round ------------ - 82.147884 +SELECT round((tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' |=| geography 'Linestring(90 0 0,0 90 100)')::numeric, 6); + round +---------- + 0.000000 (1 row) -SELECT round((tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' |=| geography 'Linestring Z empty')::numeric, 6); +SELECT round((tgeogpoint 'Point(-90 0 100)@2000-01-01' |=| geography 'Linestring Z empty')::numeric, 6); round ------- (1 row) -SELECT round((tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' |=| geography 'Linestring Z empty')::numeric, 6); +SELECT round((tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' |=| geography 'Linestring Z empty')::numeric, 6); round ------- (1 row) -SELECT round((tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' |=| geography 'Linestring Z empty')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' |=| geography 'Linestring Z empty')::numeric, 6); round ------- (1 row) -SELECT round((tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' |=| geography 'Linestring Z empty')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' |=| geography 'Linestring Z empty')::numeric, 6); round ------- @@ -2682,97 +2684,97 @@ SELECT round((geometry 'Linestring Z empty' |=| tgeompoint '{[Point(1 1 1)@2000- (1 row) -SELECT round((geography 'Linestring(0 0,3 3)' |=| tgeogpoint 'Point(1.5 1.5)@2000-01-01')::numeric, 6); - round ------------- - 121.017803 +SELECT round((geography 'Linestring(90 0,0 90)' |=| tgeogpoint 'Point(-90 0)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round((geography 'Linestring(0 0,3 3)' |=| tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}')::numeric, 6); - round ------------ - 82.147884 +SELECT round((geography 'Linestring(90 0,0 90)' |=| tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round((geography 'Linestring(0 0,3 3)' |=| tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]')::numeric, 6); - round ------------ - 82.147884 +SELECT round((geography 'Linestring(90 0,0 90)' |=| tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]')::numeric, 6); + round +---------- + 0.000000 (1 row) -SELECT round((geography 'Linestring(0 0,3 3)' |=| tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); - round ------------ - 82.147884 +SELECT round((geography 'Linestring(90 0,0 90)' |=| tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); + round +---------- + 0.000000 (1 row) -SELECT round((geography 'Linestring empty' |=| tgeogpoint 'Point(1.5 1.5)@2000-01-01')::numeric, 6); +SELECT round((geography 'Linestring empty' |=| tgeogpoint 'Point(-90 0)@2000-01-01')::numeric, 6); round ------- (1 row) -SELECT round((geography 'Linestring empty' |=| tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}')::numeric, 6); +SELECT round((geography 'Linestring empty' |=| tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}')::numeric, 6); round ------- (1 row) -SELECT round((geography 'Linestring empty' |=| tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]')::numeric, 6); +SELECT round((geography 'Linestring empty' |=| tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]')::numeric, 6); round ------- (1 row) -SELECT round((geography 'Linestring empty' |=| tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round((geography 'Linestring empty' |=| tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); round ------- (1 row) -SELECT round((geography 'Linestring(0 0 0,3 3 3)' |=| tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01')::numeric, 6); - round ------------- - 121.017803 +SELECT round((geography 'Linestring(90 0 0,0 90 100)' |=| tgeogpoint 'Point(-90 0 100)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round((geography 'Linestring(0 0 0,3 3 3)' |=| tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}')::numeric, 6); - round ------------ - 82.147884 +SELECT round((geography 'Linestring(90 0 0,0 90 100)' |=| tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round((geography 'Linestring(0 0 0,3 3 3)' |=| tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]')::numeric, 6); - round ------------ - 82.147884 +SELECT round((geography 'Linestring(90 0 0,0 90 100)' |=| tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]')::numeric, 6); + round +---------- + 0.000000 (1 row) -SELECT round((geography 'Linestring(0 0 0,3 3 3)' |=| tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); - round ------------ - 82.147884 +SELECT round((geography 'Linestring(90 0 0,0 90 100)' |=| tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); + round +---------- + 0.000000 (1 row) -SELECT round((geography 'Linestring Z empty' |=| tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01')::numeric, 6); +SELECT round((geography 'Linestring Z empty' |=| tgeogpoint 'Point(-90 0 100)@2000-01-01')::numeric, 6); round ------- (1 row) -SELECT round((geography 'Linestring Z empty' |=| tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}')::numeric, 6); +SELECT round((geography 'Linestring Z empty' |=| tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}')::numeric, 6); round ------- (1 row) -SELECT round((geography 'Linestring Z empty' |=| tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]')::numeric, 6); +SELECT round((geography 'Linestring Z empty' |=| tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]')::numeric, 6); round ------- (1 row) -SELECT round((geography 'Linestring Z empty' |=| tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round((geography 'Linestring Z empty' |=| tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); round ------- @@ -2970,193 +2972,193 @@ SELECT round((tgeompoint '{[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Po 0.000000 (1 row) -SELECT round((tgeogpoint 'Point(1.5 1.5)@2000-01-01' |=| tgeogpoint 'Point(2.5 2.5)@2000-01-01')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint 'Point(-90 0)@2000-01-01' |=| tgeogpoint 'Point(0 -90)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round((tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' |=| tgeogpoint 'Point(2.5 2.5)@2000-01-01')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' |=| tgeogpoint 'Point(0 -90)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round((tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' |=| tgeogpoint 'Point(2.5 2.5)@2000-01-01')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' |=| tgeogpoint 'Point(0 -90)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round((tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' |=| tgeogpoint 'Point(2.5 2.5)@2000-01-01')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' |=| tgeogpoint 'Point(0 -90)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round((tgeogpoint 'Point(1.5 1.5)@2000-01-01' |=| tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint 'Point(-90 0)@2000-01-01' |=| tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')::numeric, 6); + round +----------------- + 20003931.458625 (1 row) -SELECT round((tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' |=| tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' |=| tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round((tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' |=| tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' |=| tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round((tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' |=| tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' |=| tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round((tgeogpoint 'Point(1.5 1.5)@2000-01-01' |=| tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint 'Point(-90 0)@2000-01-01' |=| tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')::numeric, 6); + round +----------------- + 20003931.458625 (1 row) -SELECT round((tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' |=| tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' |=| tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round((tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' |=| tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' |=| tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')::numeric, 6); round ---------- - 0.000000 + 0.314159 (1 row) -SELECT round((tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' |=| tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' |=| tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')::numeric, 6); round ---------- - 0.000000 + 0.314159 (1 row) -SELECT round((tgeogpoint 'Point(1.5 1.5)@2000-01-01' |=| tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint 'Point(-90 0)@2000-01-01' |=| tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); + round +----------------- + 20003931.458625 (1 row) -SELECT round((tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' |=| tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' |=| tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round((tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' |=| tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' |=| tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); round ---------- - 0.000000 + 0.314159 (1 row) -SELECT round((tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' |=| tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' |=| tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); round ---------- 0.000000 (1 row) -SELECT round((tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' |=| tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint 'Point(-90 0 100)@2000-01-01' |=| tgeogpoint 'Point(0 -90 100)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round((tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' |=| tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' |=| tgeogpoint 'Point(0 -90 100)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round((tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' |=| tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' |=| tgeogpoint 'Point(0 -90 100)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round((tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' |=| tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' |=| tgeogpoint 'Point(0 -90 100)@2000-01-01')::numeric, 6); + round +----------------- + 10001965.729313 (1 row) -SELECT round((tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' |=| tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint 'Point(-90 0 100)@2000-01-01' |=| tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')::numeric, 6); + round +----------------- + 20003931.458625 (1 row) -SELECT round((tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' |=| tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' |=| tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round((tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' |=| tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' |=| tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round((tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' |=| tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' |=| tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round((tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' |=| tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint 'Point(-90 0 100)@2000-01-01' |=| tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')::numeric, 6); + round +----------------- + 20003931.458625 (1 row) -SELECT round((tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' |=| tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' |=| tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round((tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' |=| tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' |=| tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')::numeric, 6); round ---------- - 0.000000 + 0.314159 (1 row) -SELECT round((tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' |=| tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' |=| tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')::numeric, 6); round ---------- - 0.000000 + 0.314159 (1 row) -SELECT round((tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' |=| tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint 'Point(-90 0 100)@2000-01-01' |=| tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); + round +----------------- + 20003931.458625 (1 row) -SELECT round((tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' |=| tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); - round ---------------- - 156855.662657 +SELECT round((tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' |=| tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); + round +----------------- + 10018754.171395 (1 row) -SELECT round((tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' |=| tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' |=| tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); round ---------- - 0.000000 + 0.314159 (1 row) -SELECT round((tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' |=| tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' |=| tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); round ---------- 0.000000 @@ -3271,49 +3273,49 @@ SELECT ST_AsTexT(shortestLine(tgeompoint '{[Point(1 1 1)@2000-01-01, Point(2 2 2 (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5)@2000-01-01', geography 'Linestring(0 0,3 3)'), 1); - st_astext ------------------------------ - LINESTRING(1.5 1.5,1.5 1.5) +SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(-90 0)@2000-01-01', geography 'Linestring(90 0,0 90)'), 1); + st_astext +------------------------ + LINESTRING(-90 0,0 90) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', geography 'Linestring(0 0,3 3)'), 1); - st_astext ------------------------------ - LINESTRING(2.5 2.5,2.5 2.5) +SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', geography 'Linestring(90 0,0 90)'), 1); + st_astext +---------------------- + LINESTRING(0 0,90 0) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', geography 'Linestring(0 0,3 3)'), 1); - st_astext ------------------------------ - LINESTRING(2.5 2.5,2.5 2.5) +SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', geography 'Linestring(90 0,0 90)'), 1); + st_astext +------------------------- + LINESTRING(-90 0,-90 0) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', geography 'Linestring(0 0,3 3)'), 1); - st_astext ------------------------------ - LINESTRING(2.5 2.5,2.5 2.5) +SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', geography 'Linestring(90 0,0 90)'), 1); + st_astext +------------------------- + LINESTRING(-90 0,-90 0) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5)@2000-01-01', geography 'Linestring empty')); +SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(-90 0)@2000-01-01', geography 'Linestring empty')); st_astext ----------- (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', geography 'Linestring empty')); +SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', geography 'Linestring empty')); st_astext ----------- (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', geography 'Linestring empty')); +SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', geography 'Linestring empty')); st_astext ----------- (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', geography 'Linestring empty')); +SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', geography 'Linestring empty')); st_astext ----------- @@ -3415,49 +3417,49 @@ SELECT ST_AsTexT(shortestLine(geometry 'Linestring Z empty', tgeompoint '{[Point (1 row) -SELECT ST_AsTexT(shortestLine(geography 'Linestring(0 0,3 3)', tgeogpoint 'Point(1.5 1.5)@2000-01-01'), 1); - st_astext ------------------------------ - LINESTRING(1.5 1.5,1.5 1.5) +SELECT ST_AsTexT(shortestLine(geography 'Linestring(90 0,0 90)', tgeogpoint 'Point(-90 0)@2000-01-01'), 1); + st_astext +------------------------ + LINESTRING(-90 0,0 90) (1 row) -SELECT ST_AsTexT(shortestLine(geography 'Linestring(0 0,3 3)', tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}'), 1); - st_astext ------------------------------ - LINESTRING(2.5 2.5,2.5 2.5) +SELECT ST_AsTexT(shortestLine(geography 'Linestring(90 0,0 90)', tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}'), 1); + st_astext +---------------------- + LINESTRING(0 0,90 0) (1 row) -SELECT ST_AsTexT(shortestLine(geography 'Linestring(0 0,3 3)', tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]'), 1); - st_astext ------------------------------ - LINESTRING(2.5 2.5,2.5 2.5) +SELECT ST_AsTexT(shortestLine(geography 'Linestring(90 0,0 90)', tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]'), 1); + st_astext +------------------------- + LINESTRING(-90 0,-90 0) (1 row) -SELECT ST_AsTexT(shortestLine(geography 'Linestring(0 0,3 3)', tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'), 1); - st_astext ------------------------------ - LINESTRING(2.5 2.5,2.5 2.5) +SELECT ST_AsTexT(shortestLine(geography 'Linestring(90 0,0 90)', tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}'), 1); + st_astext +------------------------- + LINESTRING(-90 0,-90 0) (1 row) -SELECT ST_AsTexT(shortestLine(geography 'Linestring empty', tgeogpoint 'Point(1.5 1.5)@2000-01-01'), 1); +SELECT ST_AsTexT(shortestLine(geography 'Linestring empty', tgeogpoint 'Point(-90 0)@2000-01-01'), 1); st_astext ----------- (1 row) -SELECT ST_AsTexT(shortestLine(geography 'Linestring empty', tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}'), 1); +SELECT ST_AsTexT(shortestLine(geography 'Linestring empty', tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}'), 1); st_astext ----------- (1 row) -SELECT ST_AsTexT(shortestLine(geography 'Linestring empty', tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]'), 1); +SELECT ST_AsTexT(shortestLine(geography 'Linestring empty', tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]'), 1); st_astext ----------- (1 row) -SELECT ST_AsTexT(shortestLine(geography 'Linestring empty', tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'), 1); +SELECT ST_AsTexT(shortestLine(geography 'Linestring empty', tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}'), 1); st_astext ----------- @@ -3655,196 +3657,196 @@ SELECT ST_AsTexT(shortestLine(tgeompoint '{[Point(1 1 1)@2000-01-01, Point(2 2 2 LINESTRING Z (1.5 1.5 1.5,1.5 1.5 1.5) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint 'Point(2.5 2.5)@2000-01-01'), 6); - st_astext ------------------------------ - LINESTRING(1.5 1.5,2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint 'Point(0 -90)@2000-01-01')), 6); + st_astext +------------------------- + LINESTRING(-90 0,0 -90) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint 'Point(2.5 2.5)@2000-01-01'), 6); - st_astext ------------------------------ - LINESTRING(1.5 1.5,2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint 'Point(0 -90)@2000-01-01')), 6); + st_astext +------------------------- + LINESTRING(-90 0,0 -90) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint 'Point(2.5 2.5)@2000-01-01'), 6); - st_astext ------------------------------ - LINESTRING(1.5 1.5,2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint 'Point(0 -90)@2000-01-01')), 6); + st_astext +------------------------- + LINESTRING(-90 0,0 -90) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint 'Point(2.5 2.5)@2000-01-01'), 6); - st_astext ------------------------------ - LINESTRING(1.5 1.5,2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint 'Point(0 -90)@2000-01-01')), 6); + st_astext +------------------------- + LINESTRING(-90 0,0 -90) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}'), 6); - st_astext ------------------------------ - LINESTRING(1.5 1.5,2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')), 6); + st_astext +------------------------ + LINESTRING(-90 0,90 0) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}'), 6); - st_astext ------------------------------ - LINESTRING(1.5 1.5,2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')), 6); + st_astext +----------------------- + LINESTRING(0 0,-90 0) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}'), 6); - st_astext ------------------------------ - LINESTRING(1.5 1.5,2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')), 6); + st_astext +----------------------- + LINESTRING(0 0,-90 0) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}'), 6); - st_astext ------------------------------ - LINESTRING(1.5 1.5,2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')), 6); + st_astext +----------------------- + LINESTRING(0 0,-90 0) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]'), 6); - st_astext ------------------------------ - LINESTRING(1.5 1.5,2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')), 6); + st_astext +------------------------ + LINESTRING(-90 0,90 0) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]'), 6); - st_astext ------------------------------ - LINESTRING(1.5 1.5,2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')), 6); + st_astext +----------------------- + LINESTRING(0 0,-90 0) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]'), 6); - st_astext -------------------------------------------------- - LINESTRING(1.999848 2.000076,1.999848 2.000076) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')), 6); + st_astext +------------------------- + LINESTRING(-36 0,-18 0) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]'), 6); - st_astext -------------------------------------------------- - LINESTRING(1.999848 2.000076,1.999848 2.000076) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')), 6); + st_astext +------------------------- + LINESTRING(-36 0,-18 0) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'), 6); - st_astext ------------------------------ - LINESTRING(1.5 1.5,2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')), 6); + st_astext +------------------------ + LINESTRING(-90 0,90 0) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'), 6); - st_astext ------------------------------ - LINESTRING(1.5 1.5,2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')), 6); + st_astext +----------------------- + LINESTRING(0 0,-90 0) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'), 6); - st_astext -------------------------------------------------- - LINESTRING(1.999848 2.000076,1.999848 2.000076) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')), 6); + st_astext +------------------------- + LINESTRING(-36 0,-18 0) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'), 6); - st_astext ------------------------------ - LINESTRING(3.5 3.5,3.5 3.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')), 6); + st_astext +------------------------- + LINESTRING(90 90,90 90) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01'), 6); - st_astext ----------------------------------------- - LINESTRING Z (1.5 1.5 1.5,2.5 2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint 'Point(0 -90 100)@2000-01-01')), 6); + st_astext +------------------------------------ + LINESTRING Z (-90 0 100,0 -90 100) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01'), 6); - st_astext ----------------------------------------- - LINESTRING Z (1.5 1.5 1.5,2.5 2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint 'Point(0 -90 100)@2000-01-01')), 6); + st_astext +------------------------------------ + LINESTRING Z (-90 0 100,0 -90 100) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01'), 6); - st_astext ----------------------------------------- - LINESTRING Z (1.5 1.5 1.5,2.5 2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint 'Point(0 -90 100)@2000-01-01')), 6); + st_astext +------------------------------------ + LINESTRING Z (-90 0 100,0 -90 100) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01'), 6); - st_astext ----------------------------------------- - LINESTRING Z (1.5 1.5 1.5,2.5 2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint 'Point(0 -90 100)@2000-01-01')), 6); + st_astext +------------------------------------ + LINESTRING Z (-90 0 100,0 -90 100) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}'), 6); - st_astext ----------------------------------------- - LINESTRING Z (1.5 1.5 1.5,2.5 2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')), 6); + st_astext +----------------------------------- + LINESTRING Z (-90 0 100,90 0 100) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}'), 6); - st_astext ----------------------------------------- - LINESTRING Z (1.5 1.5 1.5,2.5 2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')), 6); + st_astext +---------------------------------- + LINESTRING Z (0 0 100,-90 0 100) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}'), 6); - st_astext ----------------------------------------- - LINESTRING Z (1.5 1.5 1.5,2.5 2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')), 6); + st_astext +---------------------------------- + LINESTRING Z (0 0 100,-90 0 100) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}'), 6); - st_astext ----------------------------------------- - LINESTRING Z (1.5 1.5 1.5,2.5 2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')), 6); + st_astext +---------------------------------- + LINESTRING Z (0 0 100,-90 0 100) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'), 6); - st_astext ----------------------------------------- - LINESTRING Z (1.5 1.5 1.5,2.5 2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')), 6); + st_astext +----------------------------------- + LINESTRING Z (-90 0 100,90 0 100) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'), 6); - st_astext ----------------------------------------- - LINESTRING Z (1.5 1.5 1.5,2.5 2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')), 6); + st_astext +---------------------------------- + LINESTRING Z (0 0 100,-90 0 100) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'), 6); - st_astext --------------------------------------------------------- - LINESTRING Z (1.999848 2.000076 2,1.999848 2.000076 2) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')), 6); + st_astext +------------------------------------ + LINESTRING Z (-36 0 100,-18 0 100) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'), 6); - st_astext --------------------------------------------------------- - LINESTRING Z (1.999848 2.000076 2,1.999848 2.000076 2) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')), 6); + st_astext +------------------------------------ + LINESTRING Z (-36 0 100,-18 0 100) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}'), 6); - st_astext ----------------------------------------- - LINESTRING Z (1.5 1.5 1.5,2.5 2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')), 6); + st_astext +----------------------------------- + LINESTRING Z (-90 0 100,90 0 100) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}'), 6); - st_astext ----------------------------------------- - LINESTRING Z (1.5 1.5 1.5,2.5 2.5 2.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')), 6); + st_astext +---------------------------------- + LINESTRING Z (0 0 100,-90 0 100) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}'), 6); - st_astext --------------------------------------------------------- - LINESTRING Z (1.999848 2.000076 2,1.999848 2.000076 2) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')), 6); + st_astext +------------------------------------ + LINESTRING Z (-36 0 100,-18 0 100) (1 row) -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}'), 6); - st_astext ----------------------------------------- - LINESTRING Z (3.5 3.5 3.5,3.5 3.5 3.5) +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')), 6); + st_astext +------------------------------------ + LINESTRING Z (90 90 100,90 90 100) (1 row) SELECT ST_AsTexT(shortestLine(tgeompoint '{[Point(1 1)@2000-01-01, Point(1 1)@2000-01-02], (Point(2 2)@2000-01-04, Point(1 1)@2000-01-05]}', tgeompoint '{[Point(3 3)@2000-01-01, Point(3 3)@2000-01-02], (Point(2 2)@2000-01-04, Point(3 3)@2000-01-05]}')); @@ -3914,7 +3916,7 @@ SELECT shortestLine(tgeompoint 'Point(1 1)@2000-01-01', tgeompoint 'SRID=5676;Po ERROR: Operation on mixed SRID SELECT shortestLine(tgeompoint 'Point(1 1)@2000-01-01', tgeompoint 'Point(1 1 1)@2000-01-01'); ERROR: The arguments must be of the same dimensionality -SELECT shortestLine(geography 'Linestring(0 0 0,3 3 3)', tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01'); +SELECT shortestLine(geography 'Linestring(90 0 0,0 90 100)', tgeogpoint 'Point(-90 0 100)@2000-01-01'); ERROR: The geometry cannot have Z dimension -SELECT shortestLine(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', geography 'Linestring(0 0 0,3 3 3)'); +SELECT shortestLine(tgeogpoint 'Point(-90 0 100)@2000-01-01', geography 'Linestring(90 0 0,0 90 100)'); ERROR: The geometry cannot have Z dimension diff --git a/mobilitydb/test/point/expected/072_tpoint_tempspatialrels.test.out b/mobilitydb/test/point/expected/072_tpoint_tempspatialrels.test.out index 66c5999c23..5e06b4c6bb 100644 --- a/mobilitydb/test/point/expected/072_tpoint_tempspatialrels.test.out +++ b/mobilitydb/test/point/expected/072_tpoint_tempspatialrels.test.out @@ -1659,8 +1659,6 @@ ERROR: Only point geometries accepted SELECT tdwithin(tgeompoint 'Point(1 1)@2000-01-01', geometry 'Linestring(1 1,2 2)', 2); ERROR: Only point geometries accepted SELECT tdwithin(tgeompoint 'Point(1 1)@2000-01-01', geometry 'Point(0 0)', -1); -ERROR: Tolerance cannot be less than zero - +ERROR: The value must be strictly positive: -1.000000 SELECT tdwithin(tgeompoint 'Point(1 1 1)@2000-01-01', geometry 'Point(0 0 0)', -1); -ERROR: Tolerance cannot be less than zero - +ERROR: The value must be strictly positive: -1.000000 diff --git a/mobilitydb/test/point/queries/064_tpoint_distance.test.sql b/mobilitydb/test/point/queries/064_tpoint_distance.test.sql index 1970235722..1e5db34b58 100644 --- a/mobilitydb/test/point/queries/064_tpoint_distance.test.sql +++ b/mobilitydb/test/point/queries/064_tpoint_distance.test.sql @@ -66,25 +66,25 @@ SELECT round(geometry 'Point Z empty' <-> tgeompoint '{Point(2 2 2)@2000-01-01, SELECT round(geometry 'Point Z empty' <-> tgeompoint '[Point(2 2 2)@2000-01-01, Point(1 1 1)@2000-01-02, Point(2 2 2)@2000-01-03]', 6); SELECT round(geometry 'Point Z empty' <-> tgeompoint '{[Point(2 2 2)@2000-01-01, Point(1 1 1)@2000-01-02, Point(2 2 2)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}', 6); -SELECT round(geography 'Point(1 1)' <-> tgeogpoint 'Point(2.5 2.5)@2000-01-01', 6); -SELECT round(geography 'Point(1 1)' <-> tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}', 6); -SELECT round(geography 'Point(1 1)' <-> tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]', 6); -SELECT round(geography 'Point(1 1)' <-> tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', 6); - -SELECT round(geography 'Point empty' <-> tgeogpoint 'Point(2.5 2.5)@2000-01-01', 6); -SELECT round(geography 'Point empty' <-> tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}', 6); -SELECT round(geography 'Point empty' <-> tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]', 6); -SELECT round(geography 'Point empty' <-> tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', 6); - -SELECT round(geography 'Point(1 1 1)' <-> tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01', 6); -SELECT round(geography 'Point(1 1 1)' <-> tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}', 6); -SELECT round(geography 'Point(1 1 1)' <-> tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]', 6); -SELECT round(geography 'Point(1 1 1)' <-> tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', 6); - -SELECT round(geography 'Point Z empty' <-> tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01', 6); -SELECT round(geography 'Point Z empty' <-> tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}', 6); -SELECT round(geography 'Point Z empty' <-> tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]', 6); -SELECT round(geography 'Point Z empty' <-> tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', 6); +SELECT round(geography 'Point(-90 0)' <-> tgeogpoint 'Point(0 -90)@2000-01-01', 6); +SELECT round(geography 'Point(-90 0)' <-> tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}', 6); +SELECT round(geography 'Point(-90 0)' <-> tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]', 6); +SELECT round(geography 'Point(-90 0)' <-> tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', 6); + +SELECT round(geography 'Point empty' <-> tgeogpoint 'Point(0 -90)@2000-01-01', 6); +SELECT round(geography 'Point empty' <-> tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}', 6); +SELECT round(geography 'Point empty' <-> tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]', 6); +SELECT round(geography 'Point empty' <-> tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', 6); + +SELECT round(geography 'Point(-90 0 100)' <-> tgeogpoint 'Point(0 -90 100)@2000-01-01', 6); +SELECT round(geography 'Point(-90 0 100)' <-> tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}', 6); +SELECT round(geography 'Point(-90 0 100)' <-> tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]', 6); +SELECT round(geography 'Point(-90 0 100)' <-> tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', 6); + +SELECT round(geography 'Point Z empty' <-> tgeogpoint 'Point(0 -90 100)@2000-01-01', 6); +SELECT round(geography 'Point Z empty' <-> tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}', 6); +SELECT round(geography 'Point Z empty' <-> tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]', 6); +SELECT round(geography 'Point Z empty' <-> tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', 6); SELECT round(tgeompoint 'Point(1 1)@2000-01-01' <-> geometry 'Point(1 1)', 6); SELECT round(tgeompoint '{Point(1 1)@2000-01-01, Point(2 2)@2000-01-02, Point(1 1)@2000-01-03}' <-> geometry 'Point(1 1)', 6); @@ -106,25 +106,25 @@ SELECT round(tgeompoint '{Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Poin SELECT round(tgeompoint '[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03]' <-> geometry 'Point Z empty', 6); SELECT round(tgeompoint '{[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}' <-> geometry 'Point Z empty', 6); -SELECT round(tgeogpoint 'Point(1.5 1.5)@2000-01-01' <-> geography 'Point(1 1)', 6); -SELECT round(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' <-> geography 'Point(1 1)', 6); -SELECT round(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' <-> geography 'Point(1 1)', 6); -SELECT round(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' <-> geography 'Point(1 1)', 6); +SELECT round(tgeogpoint 'Point(-90 0)@2000-01-01' <-> geography 'Point(-90 0)', 6); +SELECT round(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' <-> geography 'Point(-90 0)', 6); +SELECT round(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' <-> geography 'Point(-90 0)', 6); +SELECT round(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' <-> geography 'Point(-90 0)', 6); -SELECT round(tgeogpoint 'Point(1.5 1.5)@2000-01-01' <-> geography 'Point empty', 6); -SELECT round(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' <-> geography 'Point empty', 6); -SELECT round(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' <-> geography 'Point empty', 6); -SELECT round(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' <-> geography 'Point empty', 6); +SELECT round(tgeogpoint 'Point(-90 0)@2000-01-01' <-> geography 'Point empty', 6); +SELECT round(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' <-> geography 'Point empty', 6); +SELECT round(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' <-> geography 'Point empty', 6); +SELECT round(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' <-> geography 'Point empty', 6); -SELECT round(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' <-> geography 'Point(1 1 1)', 6); -SELECT round(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' <-> geography 'Point(1 1 1)', 6); -SELECT round(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' <-> geography 'Point(1 1 1)', 6); -SELECT round(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' <-> geography 'Point(1 1 1)', 6); +SELECT round(tgeogpoint 'Point(-90 0 100)@2000-01-01' <-> geography 'Point(-90 0 100)', 6); +SELECT round(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' <-> geography 'Point(-90 0 100)', 6); +SELECT round(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' <-> geography 'Point(-90 0 100)', 6); +SELECT round(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' <-> geography 'Point(-90 0 100)', 6); -SELECT round(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' <-> geography 'Point Z empty', 6); -SELECT round(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' <-> geography 'Point Z empty', 6); -SELECT round(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' <-> geography 'Point Z empty', 6); -SELECT round(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' <-> geography 'Point Z empty', 6); +SELECT round(tgeogpoint 'Point(-90 0 100)@2000-01-01' <-> geography 'Point Z empty', 6); +SELECT round(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' <-> geography 'Point Z empty', 6); +SELECT round(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' <-> geography 'Point Z empty', 6); +SELECT round(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' <-> geography 'Point Z empty', 6); SELECT round(tgeompoint 'Point(1 1)@2000-01-01' <-> tgeompoint 'Point(2 2)@2000-01-01', 6); SELECT round(tgeompoint '{Point(1 1)@2000-01-01, Point(2 2)@2000-01-02, Point(1 1)@2000-01-03}' <-> tgeompoint 'Point(2 2)@2000-01-01', 6); @@ -162,39 +162,39 @@ SELECT round(tgeompoint '{[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Poi SELECT round(tgeompoint 'Interp=Step;[Point(1 1)@2000-01-01, Point(2 2)@2000-01-02]' <-> tgeompoint 'Interp=Step;[Point(2 2)@2000-01-01, Point(1 1)@2000-01-02]', 6); -SELECT round(tgeogpoint 'Point(1.5 1.5)@2000-01-01' <-> tgeogpoint 'Point(2.5 2.5)@2000-01-01', 6); -SELECT round(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' <-> tgeogpoint 'Point(2.5 2.5)@2000-01-01', 6); -SELECT round(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' <-> tgeogpoint 'Point(2.5 2.5)@2000-01-01', 6); -SELECT round(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' <-> tgeogpoint 'Point(2.5 2.5)@2000-01-01', 6); -SELECT round(tgeogpoint 'Point(1.5 1.5)@2000-01-01' <-> tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}', 6); -SELECT round(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' <-> tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}', 6); -SELECT round(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' <-> tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}', 6); -SELECT round(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' <-> tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}', 6); -SELECT round(tgeogpoint 'Point(1.5 1.5)@2000-01-01' <-> tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]', 6); -SELECT round(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' <-> tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]', 6); -SELECT round(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' <-> tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]', 6); -SELECT round(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' <-> tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]', 6); -SELECT round(tgeogpoint 'Point(1.5 1.5)@2000-01-01' <-> tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', 6); -SELECT round(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' <-> tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', 6); -SELECT round(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' <-> tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', 6); -SELECT round(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' <-> tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', 6); - -SELECT round(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' <-> tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01', 6); -SELECT round(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' <-> tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01', 6); -SELECT round(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' <-> tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01', 6); -SELECT round(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' <-> tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01', 6); -SELECT round(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' <-> tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}', 6); -SELECT round(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' <-> tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}', 6); -SELECT round(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' <-> tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}', 6); -SELECT round(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' <-> tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}', 6); -SELECT round(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' <-> tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]', 6); -SELECT round(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' <-> tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]', 6); -SELECT round(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' <-> tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]', 6); -SELECT round(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' <-> tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]', 6); -SELECT round(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' <-> tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', 6); -SELECT round(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' <-> tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', 6); -SELECT round(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' <-> tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', 6); -SELECT round(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' <-> tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', 6); +SELECT round(tgeogpoint 'Point(-90 0)@2000-01-01' <-> tgeogpoint 'Point(0 -90)@2000-01-01', 6); +SELECT round(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' <-> tgeogpoint 'Point(0 -90)@2000-01-01', 6); +SELECT round(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' <-> tgeogpoint 'Point(0 -90)@2000-01-01', 6); +SELECT round(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' <-> tgeogpoint 'Point(0 -90)@2000-01-01', 6); +SELECT round(tgeogpoint 'Point(-90 0)@2000-01-01' <-> tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}', 6); +SELECT round(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' <-> tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}', 6); +SELECT round(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' <-> tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}', 6); +SELECT round(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' <-> tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}', 6); +SELECT round(tgeogpoint 'Point(-90 0)@2000-01-01' <-> tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]', 6); +SELECT round(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' <-> tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]', 6); +SELECT round(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' <-> tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]', 6); +SELECT round(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' <-> tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]', 6); +SELECT round(tgeogpoint 'Point(-90 0)@2000-01-01' <-> tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', 6); +SELECT round(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' <-> tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', 6); +SELECT round(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' <-> tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', 6); +SELECT round(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' <-> tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', 6); + +SELECT round(tgeogpoint 'Point(-90 0 100)@2000-01-01' <-> tgeogpoint 'Point(0 -90 100)@2000-01-01', 6); +SELECT round(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' <-> tgeogpoint 'Point(0 -90 100)@2000-01-01', 6); +SELECT round(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' <-> tgeogpoint 'Point(0 -90 100)@2000-01-01', 6); +SELECT round(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' <-> tgeogpoint 'Point(0 -90 100)@2000-01-01', 6); +SELECT round(tgeogpoint 'Point(-90 0 100)@2000-01-01' <-> tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}', 6); +SELECT round(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' <-> tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}', 6); +SELECT round(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' <-> tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}', 6); +SELECT round(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' <-> tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}', 6); +SELECT round(tgeogpoint 'Point(-90 0 100)@2000-01-01' <-> tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]', 6); +SELECT round(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' <-> tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]', 6); +SELECT round(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' <-> tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]', 6); +SELECT round(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' <-> tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]', 6); +SELECT round(tgeogpoint 'Point(-90 0 100)@2000-01-01' <-> tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', 6); +SELECT round(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' <-> tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', 6); +SELECT round(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' <-> tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', 6); +SELECT round(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' <-> tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', 6); ------------------------------------------------------------------------------- @@ -213,18 +213,18 @@ SELECT asText(NearestApproachInstant(tgeompoint 'Interp=Step;{[Point(1 1)@2000-0 SELECT asText(NearestApproachInstant(tgeompoint '[Point(1 1)@2000-01-01, Point(1 1)@2000-01-02]', geometry 'Linestring(1 1,3 3)')); -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5)@2000-01-01', geography 'Linestring(0 0,3 3)'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', geography 'Linestring(0 0,3 3)'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', geography 'Linestring(0 0,3 3)'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', geography 'Linestring(0 0,3 3)'),6)); -SELECT asText(NearestApproachInstant(tgeogpoint 'Interp=Step;[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', geography 'Linestring(0 0,3 3)')); -SELECT asText(NearestApproachInstant(tgeogpoint 'Interp=Step;{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', geography 'Linestring(0 0,3 3)')); -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5)@2000-01-01', geography 'Linestring empty'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', geography 'Linestring empty'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', geography 'Linestring empty'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', geography 'Linestring empty'),6)); -SELECT asText(NearestApproachInstant(tgeogpoint 'Interp=Step;[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', geography 'Linestring empty')); -SELECT asText(NearestApproachInstant(tgeogpoint 'Interp=Step;{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', geography 'Linestring empty')); +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0)@2000-01-01', geography 'Linestring(90 0,0 90)'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', geography 'Linestring(90 0,0 90)'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', geography 'Linestring(90 0,0 90)'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', geography 'Linestring(90 0,0 90)'),6)); +SELECT asText(NearestApproachInstant(tgeogpoint 'Interp=Step;[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', geography 'Linestring(90 0,0 90)')); +SELECT asText(NearestApproachInstant(tgeogpoint 'Interp=Step;{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', geography 'Linestring(90 0,0 90)')); +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0)@2000-01-01', geography 'Linestring empty'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', geography 'Linestring empty'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', geography 'Linestring empty'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', geography 'Linestring empty'),6)); +SELECT asText(NearestApproachInstant(tgeogpoint 'Interp=Step;[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', geography 'Linestring empty')); +SELECT asText(NearestApproachInstant(tgeogpoint 'Interp=Step;{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', geography 'Linestring empty')); SELECT asText(NearestApproachInstant(geometry 'Linestring(0 0,3 3)', tgeompoint 'Point(1 1)@2000-01-01')); SELECT asText(NearestApproachInstant(geometry 'Linestring(0 0,3 3)', tgeompoint '{Point(1 1)@2000-01-01, Point(2 2)@2000-01-02, Point(1 1)@2000-01-03}')); @@ -236,15 +236,15 @@ SELECT asText(NearestApproachInstant(geometry 'Linestring empty', tgeompoint '{P SELECT asText(NearestApproachInstant(geometry 'Linestring empty', tgeompoint '[Point(1 1)@2000-01-01, Point(2 2)@2000-01-02, Point(1 1)@2000-01-03]')); SELECT asText(NearestApproachInstant(geometry 'Linestring empty', tgeompoint '{[Point(1 1)@2000-01-01, Point(2 2)@2000-01-02, Point(1 1)@2000-01-03],[Point(3 3)@2000-01-04, Point(3 3)@2000-01-05]}')); -SELECT asText(NearestApproachInstant(geography 'Linestring(0 0,3 3)', tgeogpoint 'Point(1.5 1.5)@2000-01-01')); -SELECT asText(NearestApproachInstant(geography 'Linestring(0 0,3 3)', tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}')); -SELECT asText(NearestApproachInstant(geography 'Linestring(0 0,3 3)', tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]')); -SELECT asText(NearestApproachInstant(geography 'Linestring(0 0,3 3)', tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')); +SELECT asText(NearestApproachInstant(geography 'Linestring(90 0,0 90)', tgeogpoint 'Point(-90 0)@2000-01-01')); +SELECT asText(NearestApproachInstant(geography 'Linestring(90 0,0 90)', tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}')); +SELECT asText(NearestApproachInstant(geography 'Linestring(90 0,0 90)', tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]')); +SELECT asText(NearestApproachInstant(geography 'Linestring(90 0,0 90)', tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')); -SELECT asText(NearestApproachInstant(geography 'Linestring empty', tgeogpoint 'Point(1.5 1.5)@2000-01-01')); -SELECT asText(NearestApproachInstant(geography 'Linestring empty', tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}')); -SELECT asText(NearestApproachInstant(geography 'Linestring empty', tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]')); -SELECT asText(NearestApproachInstant(geography 'Linestring empty', tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')); +SELECT asText(NearestApproachInstant(geography 'Linestring empty', tgeogpoint 'Point(-90 0)@2000-01-01')); +SELECT asText(NearestApproachInstant(geography 'Linestring empty', tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}')); +SELECT asText(NearestApproachInstant(geography 'Linestring empty', tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]')); +SELECT asText(NearestApproachInstant(geography 'Linestring empty', tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')); SELECT asText(NearestApproachInstant(tgeompoint 'Point(1 1)@2000-01-01', tgeompoint 'Point(2 2)@2000-01-01')); SELECT asText(NearestApproachInstant(tgeompoint '{Point(1 1)@2000-01-01, Point(2 2)@2000-01-02, Point(1 1)@2000-01-03}', tgeompoint 'Point(2 2)@2000-01-01')); @@ -283,39 +283,39 @@ SELECT asText(NearestApproachInstant(tgeompoint '{Point(1 1 1)@2000-01-01, Point SELECT asText(NearestApproachInstant(tgeompoint '[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03]', tgeompoint '{[Point(2 2 2)@2000-01-01, Point(1 1 1)@2000-01-02, Point(2 2 2)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}')); SELECT asText(NearestApproachInstant(tgeompoint '{[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}', tgeompoint '{[Point(2 2 2)@2000-01-01, Point(1 1 1)@2000-01-02, Point(2 2 2)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}')); -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint 'Point(2.5 2.5)@2000-01-01'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint 'Point(2.5 2.5)@2000-01-01'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint 'Point(2.5 2.5)@2000-01-01'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint 'Point(2.5 2.5)@2000-01-01'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'),6)); - -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}'),6)); -SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint 'Point(0 -90)@2000-01-01'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint 'Point(0 -90)@2000-01-01'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint 'Point(0 -90)@2000-01-01'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint 'Point(0 -90)@2000-01-01'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-03]', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-03]', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}'),6)); + +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint 'Point(0 -90 100)@2000-01-01'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint 'Point(0 -90 100)@2000-01-01'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint 'Point(0 -90 100)@2000-01-01'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint 'Point(0 -90 100)@2000-01-01'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-03]', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-03]', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}'),6)); +SELECT asText(round(NearestApproachInstant(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}'),6)); /* Errors */ SELECT NearestApproachInstant(tgeompoint 'Point(1 1)@2000-01-01', geometry 'SRID=5676;Linestring(1 1,2 2)'); @@ -355,25 +355,25 @@ SELECT round(NearestApproachDistance(tgeompoint '{[Point(1 1 1)@2000-01-01, Poin SELECT round(NearestApproachDistance(tgeompoint 'Interp=Step;[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03]', geometry 'Linestring Z empty')::numeric, 6); SELECT round(NearestApproachDistance(tgeompoint 'Interp=Step;{[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}', geometry 'Linestring Z empty')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5)@2000-01-01', geography 'Linestring(0 0,3 3)')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', geography 'Linestring(0 0,3 3)')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', geography 'Linestring(0 0,3 3)')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', geography 'Linestring(0 0,3 3)')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0)@2000-01-01', geography 'Linestring(90 0,0 90)')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', geography 'Linestring(90 0,0 90)')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', geography 'Linestring(90 0,0 90)')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', geography 'Linestring(90 0,0 90)')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5)@2000-01-01', geography 'Linestring empty')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', geography 'Linestring empty')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', geography 'Linestring empty')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', geography 'Linestring empty')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0)@2000-01-01', geography 'Linestring empty')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', geography 'Linestring empty')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', geography 'Linestring empty')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', geography 'Linestring empty')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', geography 'Linestring(0 0 0,3 3 3)')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', geography 'Linestring(0 0 0,3 3 3)')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', geography 'Linestring(0 0 0,3 3 3)')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', geography 'Linestring(0 0 0,3 3 3)')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0 100)@2000-01-01', geography 'Linestring(90 0 0,0 90 100)')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', geography 'Linestring(90 0 0,0 90 100)')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', geography 'Linestring(90 0 0,0 90 100)')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', geography 'Linestring(90 0 0,0 90 100)')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', geography 'Linestring Z empty')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', geography 'Linestring Z empty')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', geography 'Linestring Z empty')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', geography 'Linestring Z empty')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0 100)@2000-01-01', geography 'Linestring Z empty')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', geography 'Linestring Z empty')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', geography 'Linestring Z empty')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', geography 'Linestring Z empty')::numeric, 6); SELECT round(NearestApproachDistance(geometry 'Linestring(0 0,3 3)', tgeompoint 'Point(1 1)@2000-01-01')::numeric, 6); SELECT round(NearestApproachDistance(geometry 'Linestring(0 0,3 3)', tgeompoint '{Point(1 1)@2000-01-01, Point(2 2)@2000-01-02, Point(1 1)@2000-01-03}')::numeric, 6); @@ -395,25 +395,25 @@ SELECT round(NearestApproachDistance(geometry 'Linestring Z empty', tgeompoint ' SELECT round(NearestApproachDistance(geometry 'Linestring Z empty', tgeompoint '[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03]')::numeric, 6); SELECT round(NearestApproachDistance(geometry 'Linestring Z empty', tgeompoint '{[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}')::numeric, 6); -SELECT round(NearestApproachDistance(geography 'Linestring(0 0,3 3)', tgeogpoint 'Point(1.5 1.5)@2000-01-01')::numeric, 6); -SELECT round(NearestApproachDistance(geography 'Linestring(0 0,3 3)', tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}')::numeric, 6); -SELECT round(NearestApproachDistance(geography 'Linestring(0 0,3 3)', tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]')::numeric, 6); -SELECT round(NearestApproachDistance(geography 'Linestring(0 0,3 3)', tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring(90 0,0 90)', tgeogpoint 'Point(-90 0)@2000-01-01')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring(90 0,0 90)', tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring(90 0,0 90)', tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring(90 0,0 90)', tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); -SELECT round(NearestApproachDistance(geography 'Linestring empty', tgeogpoint 'Point(1.5 1.5)@2000-01-01')::numeric, 6); -SELECT round(NearestApproachDistance(geography 'Linestring empty', tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}')::numeric, 6); -SELECT round(NearestApproachDistance(geography 'Linestring empty', tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]')::numeric, 6); -SELECT round(NearestApproachDistance(geography 'Linestring empty', tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring empty', tgeogpoint 'Point(-90 0)@2000-01-01')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring empty', tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring empty', tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring empty', tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); -SELECT round(NearestApproachDistance(geography 'Linestring(0 0 0,3 3 3)', tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01')::numeric, 6); -SELECT round(NearestApproachDistance(geography 'Linestring(0 0 0,3 3 3)', tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}')::numeric, 6); -SELECT round(NearestApproachDistance(geography 'Linestring(0 0 0,3 3 3)', tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]')::numeric, 6); -SELECT round(NearestApproachDistance(geography 'Linestring(0 0 0,3 3 3)', tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring(90 0 0,0 90 100)', tgeogpoint 'Point(-90 0 100)@2000-01-01')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring(90 0 0,0 90 100)', tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring(90 0 0,0 90 100)', tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring(90 0 0,0 90 100)', tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); -SELECT round(NearestApproachDistance(geography 'Linestring Z empty', tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01')::numeric, 6); -SELECT round(NearestApproachDistance(geography 'Linestring Z empty', tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}')::numeric, 6); -SELECT round(NearestApproachDistance(geography 'Linestring Z empty', tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]')::numeric, 6); -SELECT round(NearestApproachDistance(geography 'Linestring Z empty', tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring Z empty', tgeogpoint 'Point(-90 0 100)@2000-01-01')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring Z empty', tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring Z empty', tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]')::numeric, 6); +SELECT round(NearestApproachDistance(geography 'Linestring Z empty', tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); SELECT round(NearestApproachDistance(tgeompoint 'Point(1 1)@2000-01-01', tgeompoint 'Point(2 2)@2000-01-01')::numeric, 6); SELECT round(NearestApproachDistance(tgeompoint '{Point(1 1)@2000-01-01, Point(2 2)@2000-01-02, Point(1 1)@2000-01-03}', tgeompoint 'Point(2 2)@2000-01-01')::numeric, 6); @@ -449,39 +449,39 @@ SELECT round(NearestApproachDistance(tgeompoint '{Point(1 1 1)@2000-01-01, Point SELECT round(NearestApproachDistance(tgeompoint '[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03]', tgeompoint '{[Point(2 2 2)@2000-01-01, Point(1 1 1)@2000-01-02, Point(2 2 2)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}')::numeric, 6); SELECT round(NearestApproachDistance(tgeompoint '{[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}', tgeompoint '{[Point(2 2 2)@2000-01-01, Point(1 1 1)@2000-01-02, Point(2 2 2)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint 'Point(2.5 2.5)@2000-01-01')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint 'Point(2.5 2.5)@2000-01-01')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint 'Point(2.5 2.5)@2000-01-01')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint 'Point(2.5 2.5)@2000-01-01')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); - -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'::numeric, 6)); -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); -SELECT round(NearestApproachDistance(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint 'Point(0 -90)@2000-01-01')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint 'Point(0 -90)@2000-01-01')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint 'Point(0 -90)@2000-01-01')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint 'Point(0 -90)@2000-01-01')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); + +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint 'Point(0 -90 100)@2000-01-01')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint 'Point(0 -90 100)@2000-01-01')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint 'Point(0 -90 100)@2000-01-01')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint 'Point(0 -90 100)@2000-01-01')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); +SELECT round(NearestApproachDistance(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); SELECT round((stbox 'STBOX XT(((0,0),(1,1)),[2000-01-01,2000-01-02])' |=| stbox 'STBOX XT(((2,2),(2,3)),[2000-01-01,2000-01-02])')::numeric, 6); SELECT round((stbox 'STBOX XT(((0,0),(1,1)),[2000-01-01,2000-01-02])' |=| stbox 'STBOX XT(((2,2),(3,3)),[2000-01-03,2000-01-04])')::numeric, 6); @@ -533,25 +533,25 @@ SELECT round((tgeompoint '{Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Poi SELECT round((tgeompoint '[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03]' |=| geometry 'Linestring Z empty')::numeric, 6); SELECT round((tgeompoint '{[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}' |=| geometry 'Linestring Z empty')::numeric, 6); -SELECT round((tgeogpoint 'Point(1.5 1.5)@2000-01-01' |=| geography 'Linestring(0 0,3 3)')::numeric, 6); -SELECT round((tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' |=| geography 'Linestring(0 0,3 3)')::numeric, 6); -SELECT round((tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' |=| geography 'Linestring(0 0,3 3)')::numeric, 6); -SELECT round((tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' |=| geography 'Linestring(0 0,3 3)')::numeric, 6); +SELECT round((tgeogpoint 'Point(-90 0)@2000-01-01' |=| geography 'Linestring(90 0,0 90)')::numeric, 6); +SELECT round((tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' |=| geography 'Linestring(90 0,0 90)')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' |=| geography 'Linestring(90 0,0 90)')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' |=| geography 'Linestring(90 0,0 90)')::numeric, 6); -SELECT round((tgeogpoint 'Point(1.5 1.5)@2000-01-01' |=| geography 'Linestring empty')::numeric, 6); -SELECT round((tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' |=| geography 'Linestring empty')::numeric, 6); -SELECT round((tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' |=| geography 'Linestring empty')::numeric, 6); -SELECT round((tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' |=| geography 'Linestring empty')::numeric, 6); +SELECT round((tgeogpoint 'Point(-90 0)@2000-01-01' |=| geography 'Linestring empty')::numeric, 6); +SELECT round((tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' |=| geography 'Linestring empty')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' |=| geography 'Linestring empty')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' |=| geography 'Linestring empty')::numeric, 6); -SELECT round((tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' |=| geography 'Linestring(0 0 0,3 3 3)')::numeric, 6); -SELECT round((tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' |=| geography 'Linestring(0 0 0,3 3 3)')::numeric, 6); -SELECT round((tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' |=| geography 'Linestring(0 0 0,3 3 3)')::numeric, 6); -SELECT round((tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' |=| geography 'Linestring(0 0 0,3 3 3)')::numeric, 6); +SELECT round((tgeogpoint 'Point(-90 0 100)@2000-01-01' |=| geography 'Linestring(90 0 0,0 90 100)')::numeric, 6); +SELECT round((tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' |=| geography 'Linestring(90 0 0,0 90 100)')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' |=| geography 'Linestring(90 0 0,0 90 100)')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' |=| geography 'Linestring(90 0 0,0 90 100)')::numeric, 6); -SELECT round((tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' |=| geography 'Linestring Z empty')::numeric, 6); -SELECT round((tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' |=| geography 'Linestring Z empty')::numeric, 6); -SELECT round((tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' |=| geography 'Linestring Z empty')::numeric, 6); -SELECT round((tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' |=| geography 'Linestring Z empty')::numeric, 6); +SELECT round((tgeogpoint 'Point(-90 0 100)@2000-01-01' |=| geography 'Linestring Z empty')::numeric, 6); +SELECT round((tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' |=| geography 'Linestring Z empty')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' |=| geography 'Linestring Z empty')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' |=| geography 'Linestring Z empty')::numeric, 6); SELECT round((geometry 'Linestring(0 0,3 3)' |=| tgeompoint 'Point(1 1)@2000-01-01')::numeric, 6); SELECT round((geometry 'Linestring(0 0,3 3)' |=| tgeompoint '{Point(1 1)@2000-01-01, Point(2 2)@2000-01-02, Point(1 1)@2000-01-03}')::numeric, 6); @@ -573,25 +573,25 @@ SELECT round((geometry 'Linestring Z empty' |=| tgeompoint '{Point(1 1 1)@2000-0 SELECT round((geometry 'Linestring Z empty' |=| tgeompoint '[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03]')::numeric, 6); SELECT round((geometry 'Linestring Z empty' |=| tgeompoint '{[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}')::numeric, 6); -SELECT round((geography 'Linestring(0 0,3 3)' |=| tgeogpoint 'Point(1.5 1.5)@2000-01-01')::numeric, 6); -SELECT round((geography 'Linestring(0 0,3 3)' |=| tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}')::numeric, 6); -SELECT round((geography 'Linestring(0 0,3 3)' |=| tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]')::numeric, 6); -SELECT round((geography 'Linestring(0 0,3 3)' |=| tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round((geography 'Linestring(90 0,0 90)' |=| tgeogpoint 'Point(-90 0)@2000-01-01')::numeric, 6); +SELECT round((geography 'Linestring(90 0,0 90)' |=| tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}')::numeric, 6); +SELECT round((geography 'Linestring(90 0,0 90)' |=| tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]')::numeric, 6); +SELECT round((geography 'Linestring(90 0,0 90)' |=| tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); -SELECT round((geography 'Linestring empty' |=| tgeogpoint 'Point(1.5 1.5)@2000-01-01')::numeric, 6); -SELECT round((geography 'Linestring empty' |=| tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}')::numeric, 6); -SELECT round((geography 'Linestring empty' |=| tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]')::numeric, 6); -SELECT round((geography 'Linestring empty' |=| tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round((geography 'Linestring empty' |=| tgeogpoint 'Point(-90 0)@2000-01-01')::numeric, 6); +SELECT round((geography 'Linestring empty' |=| tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}')::numeric, 6); +SELECT round((geography 'Linestring empty' |=| tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]')::numeric, 6); +SELECT round((geography 'Linestring empty' |=| tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); -SELECT round((geography 'Linestring(0 0 0,3 3 3)' |=| tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01')::numeric, 6); -SELECT round((geography 'Linestring(0 0 0,3 3 3)' |=| tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}')::numeric, 6); -SELECT round((geography 'Linestring(0 0 0,3 3 3)' |=| tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]')::numeric, 6); -SELECT round((geography 'Linestring(0 0 0,3 3 3)' |=| tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round((geography 'Linestring(90 0 0,0 90 100)' |=| tgeogpoint 'Point(-90 0 100)@2000-01-01')::numeric, 6); +SELECT round((geography 'Linestring(90 0 0,0 90 100)' |=| tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}')::numeric, 6); +SELECT round((geography 'Linestring(90 0 0,0 90 100)' |=| tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]')::numeric, 6); +SELECT round((geography 'Linestring(90 0 0,0 90 100)' |=| tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); -SELECT round((geography 'Linestring Z empty' |=| tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01')::numeric, 6); -SELECT round((geography 'Linestring Z empty' |=| tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}')::numeric, 6); -SELECT round((geography 'Linestring Z empty' |=| tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]')::numeric, 6); -SELECT round((geography 'Linestring Z empty' |=| tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round((geography 'Linestring Z empty' |=| tgeogpoint 'Point(-90 0 100)@2000-01-01')::numeric, 6); +SELECT round((geography 'Linestring Z empty' |=| tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}')::numeric, 6); +SELECT round((geography 'Linestring Z empty' |=| tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]')::numeric, 6); +SELECT round((geography 'Linestring Z empty' |=| tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); SELECT round((tgeompoint 'Point(1 1)@2000-01-01' |=| tgeompoint 'Point(2 2)@2000-01-01')::numeric, 6); SELECT round((tgeompoint '{Point(1 1)@2000-01-01, Point(2 2)@2000-01-02, Point(1 1)@2000-01-03}' |=| tgeompoint 'Point(2 2)@2000-01-01')::numeric, 6); @@ -627,39 +627,39 @@ SELECT round((tgeompoint '{Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Poi SELECT round((tgeompoint '[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03]' |=| tgeompoint '{[Point(2 2 2)@2000-01-01, Point(1 1 1)@2000-01-02, Point(2 2 2)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}')::numeric, 6); SELECT round((tgeompoint '{[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}' |=| tgeompoint '{[Point(2 2 2)@2000-01-01, Point(1 1 1)@2000-01-02, Point(2 2 2)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}')::numeric, 6); -SELECT round((tgeogpoint 'Point(1.5 1.5)@2000-01-01' |=| tgeogpoint 'Point(2.5 2.5)@2000-01-01')::numeric, 6); -SELECT round((tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' |=| tgeogpoint 'Point(2.5 2.5)@2000-01-01')::numeric, 6); -SELECT round((tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' |=| tgeogpoint 'Point(2.5 2.5)@2000-01-01')::numeric, 6); -SELECT round((tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' |=| tgeogpoint 'Point(2.5 2.5)@2000-01-01')::numeric, 6); -SELECT round((tgeogpoint 'Point(1.5 1.5)@2000-01-01' |=| tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}')::numeric, 6); -SELECT round((tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' |=| tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}')::numeric, 6); -SELECT round((tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' |=| tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}')::numeric, 6); -SELECT round((tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' |=| tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}')::numeric, 6); -SELECT round((tgeogpoint 'Point(1.5 1.5)@2000-01-01' |=| tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]')::numeric, 6); -SELECT round((tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' |=| tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]')::numeric, 6); -SELECT round((tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' |=| tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]')::numeric, 6); -SELECT round((tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' |=| tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]')::numeric, 6); -SELECT round((tgeogpoint 'Point(1.5 1.5)@2000-01-01' |=| tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); -SELECT round((tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}' |=| tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); -SELECT round((tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]' |=| tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); -SELECT round((tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}' |=| tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}')::numeric, 6); - -SELECT round((tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' |=| tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01')::numeric, 6); -SELECT round((tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' |=| tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01')::numeric, 6); -SELECT round((tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' |=| tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01')::numeric, 6); -SELECT round((tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' |=| tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01')::numeric, 6); -SELECT round((tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' |=| tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}')::numeric, 6); -SELECT round((tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' |=| tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}')::numeric, 6); -SELECT round((tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' |=| tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}')::numeric, 6); -SELECT round((tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' |=| tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}')::numeric, 6); -SELECT round((tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' |=| tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]')::numeric, 6); -SELECT round((tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' |=| tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]')::numeric, 6); -SELECT round((tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' |=| tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]')::numeric, 6); -SELECT round((tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' |=| tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]')::numeric, 6); -SELECT round((tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01' |=| tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); -SELECT round((tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}' |=| tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); -SELECT round((tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]' |=| tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); -SELECT round((tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}' |=| tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}')::numeric, 6); +SELECT round((tgeogpoint 'Point(-90 0)@2000-01-01' |=| tgeogpoint 'Point(0 -90)@2000-01-01')::numeric, 6); +SELECT round((tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' |=| tgeogpoint 'Point(0 -90)@2000-01-01')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' |=| tgeogpoint 'Point(0 -90)@2000-01-01')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' |=| tgeogpoint 'Point(0 -90)@2000-01-01')::numeric, 6); +SELECT round((tgeogpoint 'Point(-90 0)@2000-01-01' |=| tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')::numeric, 6); +SELECT round((tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' |=| tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' |=| tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' |=| tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')::numeric, 6); +SELECT round((tgeogpoint 'Point(-90 0)@2000-01-01' |=| tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')::numeric, 6); +SELECT round((tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' |=| tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' |=| tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' |=| tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')::numeric, 6); +SELECT round((tgeogpoint 'Point(-90 0)@2000-01-01' |=| tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); +SELECT round((tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}' |=| tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]' |=| tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}' |=| tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')::numeric, 6); + +SELECT round((tgeogpoint 'Point(-90 0 100)@2000-01-01' |=| tgeogpoint 'Point(0 -90 100)@2000-01-01')::numeric, 6); +SELECT round((tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' |=| tgeogpoint 'Point(0 -90 100)@2000-01-01')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' |=| tgeogpoint 'Point(0 -90 100)@2000-01-01')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' |=| tgeogpoint 'Point(0 -90 100)@2000-01-01')::numeric, 6); +SELECT round((tgeogpoint 'Point(-90 0 100)@2000-01-01' |=| tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')::numeric, 6); +SELECT round((tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' |=| tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' |=| tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' |=| tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')::numeric, 6); +SELECT round((tgeogpoint 'Point(-90 0 100)@2000-01-01' |=| tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')::numeric, 6); +SELECT round((tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' |=| tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' |=| tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' |=| tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')::numeric, 6); +SELECT round((tgeogpoint 'Point(-90 0 100)@2000-01-01' |=| tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); +SELECT round((tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}' |=| tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); +SELECT round((tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]' |=| tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); +SELECT round((tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}' |=| tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')::numeric, 6); /* Errors */ SELECT NearestApproachDistance(tgeompoint 'Point(1 1)@2000-01-01', geometry 'SRID=5676;Linestring(1 1,2 2)'); @@ -691,15 +691,15 @@ SELECT ST_AsTexT(shortestLine(tgeompoint '{Point(1 1 1)@2000-01-01, Point(2 2 2) SELECT ST_AsTexT(shortestLine(tgeompoint '[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03]', geometry 'Linestring Z empty')); SELECT ST_AsTexT(shortestLine(tgeompoint '{[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}', geometry 'Linestring Z empty')); -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5)@2000-01-01', geography 'Linestring(0 0,3 3)'), 1); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', geography 'Linestring(0 0,3 3)'), 1); -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', geography 'Linestring(0 0,3 3)'), 1); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', geography 'Linestring(0 0,3 3)'), 1); +SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(-90 0)@2000-01-01', geography 'Linestring(90 0,0 90)'), 1); +SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', geography 'Linestring(90 0,0 90)'), 1); +SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', geography 'Linestring(90 0,0 90)'), 1); +SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', geography 'Linestring(90 0,0 90)'), 1); -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5)@2000-01-01', geography 'Linestring empty')); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', geography 'Linestring empty')); -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', geography 'Linestring empty')); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', geography 'Linestring empty')); +SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(-90 0)@2000-01-01', geography 'Linestring empty')); +SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', geography 'Linestring empty')); +SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', geography 'Linestring empty')); +SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', geography 'Linestring empty')); SELECT ST_AsTexT(shortestLine(geometry 'Linestring(0 0,3 3)', tgeompoint 'Point(1 1)@2000-01-01')); SELECT ST_AsTexT(shortestLine(geometry 'Linestring(0 0,3 3)', tgeompoint '{Point(1 1)@2000-01-01, Point(2 2)@2000-01-02, Point(1 1)@2000-01-03}')); @@ -721,15 +721,15 @@ SELECT ST_AsTexT(shortestLine(geometry 'Linestring Z empty', tgeompoint '{Point( SELECT ST_AsTexT(shortestLine(geometry 'Linestring Z empty', tgeompoint '[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03]')); SELECT ST_AsTexT(shortestLine(geometry 'Linestring Z empty', tgeompoint '{[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}')); -SELECT ST_AsTexT(shortestLine(geography 'Linestring(0 0,3 3)', tgeogpoint 'Point(1.5 1.5)@2000-01-01'), 1); -SELECT ST_AsTexT(shortestLine(geography 'Linestring(0 0,3 3)', tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}'), 1); -SELECT ST_AsTexT(shortestLine(geography 'Linestring(0 0,3 3)', tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]'), 1); -SELECT ST_AsTexT(shortestLine(geography 'Linestring(0 0,3 3)', tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'), 1); +SELECT ST_AsTexT(shortestLine(geography 'Linestring(90 0,0 90)', tgeogpoint 'Point(-90 0)@2000-01-01'), 1); +SELECT ST_AsTexT(shortestLine(geography 'Linestring(90 0,0 90)', tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}'), 1); +SELECT ST_AsTexT(shortestLine(geography 'Linestring(90 0,0 90)', tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]'), 1); +SELECT ST_AsTexT(shortestLine(geography 'Linestring(90 0,0 90)', tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}'), 1); -SELECT ST_AsTexT(shortestLine(geography 'Linestring empty', tgeogpoint 'Point(1.5 1.5)@2000-01-01'), 1); -SELECT ST_AsTexT(shortestLine(geography 'Linestring empty', tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}'), 1); -SELECT ST_AsTexT(shortestLine(geography 'Linestring empty', tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]'), 1); -SELECT ST_AsTexT(shortestLine(geography 'Linestring empty', tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'), 1); +SELECT ST_AsTexT(shortestLine(geography 'Linestring empty', tgeogpoint 'Point(-90 0)@2000-01-01'), 1); +SELECT ST_AsTexT(shortestLine(geography 'Linestring empty', tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}'), 1); +SELECT ST_AsTexT(shortestLine(geography 'Linestring empty', tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]'), 1); +SELECT ST_AsTexT(shortestLine(geography 'Linestring empty', tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}'), 1); SELECT ST_AsTexT(shortestLine(tgeompoint 'Point(1 1)@2000-01-01', tgeompoint 'Point(2 2)@2000-01-01')); SELECT ST_AsTexT(shortestLine(tgeompoint '{Point(1 1)@2000-01-01, Point(2 2)@2000-01-02, Point(1 1)@2000-01-03}', tgeompoint 'Point(2 2)@2000-01-01')); @@ -765,39 +765,39 @@ SELECT ST_AsTexT(shortestLine(tgeompoint '{Point(1 1 1)@2000-01-01, Point(2 2 2) SELECT ST_AsTexT(shortestLine(tgeompoint '[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03]', tgeompoint '{[Point(2 2 2)@2000-01-01, Point(1 1 1)@2000-01-02, Point(2 2 2)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}')); SELECT ST_AsTexT(shortestLine(tgeompoint '{[Point(1 1 1)@2000-01-01, Point(2 2 2)@2000-01-02, Point(1 1 1)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}', tgeompoint '{[Point(2 2 2)@2000-01-01, Point(1 1 1)@2000-01-02, Point(2 2 2)@2000-01-03],[Point(3 3 3)@2000-01-04, Point(3 3 3)@2000-01-05]}')); -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint 'Point(2.5 2.5)@2000-01-01'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint 'Point(2.5 2.5)@2000-01-01'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint 'Point(2.5 2.5)@2000-01-01'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint 'Point(2.5 2.5)@2000-01-01'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '{Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03}'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03]'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5)@2000-01-01', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03}', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03]', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5)@2000-01-01, Point(2.5 2.5)@2000-01-02, Point(1.5 1.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}', tgeogpoint '{[Point(2.5 2.5)@2000-01-01, Point(1.5 1.5)@2000-01-02, Point(2.5 2.5)@2000-01-03],[Point(3.5 3.5)@2000-01-04, Point(3.5 3.5)@2000-01-05]}'), 6); - -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint 'Point(2.5 2.5 2.5)@2000-01-01'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '{Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03}'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03]'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03}', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03]', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}'), 6); -SELECT ST_AsTexT(shortestLine(tgeogpoint '{[Point(1.5 1.5 1.5)@2000-01-01, Point(2.5 2.5 2.5)@2000-01-02, Point(1.5 1.5 1.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}', tgeogpoint '{[Point(2.5 2.5 2.5)@2000-01-01, Point(1.5 1.5 1.5)@2000-01-02, Point(2.5 2.5 2.5)@2000-01-03],[Point(3.5 3.5 3.5)@2000-01-04, Point(3.5 3.5 3.5)@2000-01-05]}'), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint 'Point(0 -90)@2000-01-01')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint 'Point(0 -90)@2000-01-01')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint 'Point(0 -90)@2000-01-01')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint 'Point(0 -90)@2000-01-01')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '{Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03}')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03]')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint 'Point(-90 0)@2000-01-01', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03}', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03]', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{[Point(-90 0)@2000-01-01, Point(0 0)@2000-01-02, Point(-90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}', tgeogpoint '{[Point(90 0)@2000-01-01, Point(-90 0)@2000-01-02, Point(90 0)@2000-01-03],[Point(90 90)@2000-01-04, Point(90 90)@2000-01-05]}')), 6); + +SELECT ST_AsTexT(round(shortestLine(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint 'Point(0 -90 100)@2000-01-01')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint 'Point(0 -90 100)@2000-01-01')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint 'Point(0 -90 100)@2000-01-01')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint 'Point(0 -90 100)@2000-01-01')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '{Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03}')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03]')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint 'Point(-90 0 100)@2000-01-01', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03}', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03]', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')), 6); +SELECT ST_AsTexT(round(shortestLine(tgeogpoint '{[Point(-90 0 100)@2000-01-01, Point(0 0 100)@2000-01-02, Point(-90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}', tgeogpoint '{[Point(90 0 100)@2000-01-01, Point(-90 0 100)@2000-01-02, Point(90 0 100)@2000-01-03],[Point(90 90 100)@2000-01-04, Point(90 90 100)@2000-01-05]}')), 6); SELECT ST_AsTexT(shortestLine(tgeompoint '{[Point(1 1)@2000-01-01, Point(1 1)@2000-01-02], (Point(2 2)@2000-01-04, Point(1 1)@2000-01-05]}', tgeompoint '{[Point(3 3)@2000-01-01, Point(3 3)@2000-01-02], (Point(2 2)@2000-01-04, Point(3 3)@2000-01-05]}')); SELECT ST_AsText(shortestLine(tgeompoint 'Interp=Step;[Point(0 0)@2000-01-01, Point(2 0)@2000-01-02]','[Point(1 1)@2000-01-01,Point(1 1)@2000-01-02]')); @@ -816,7 +816,7 @@ SELECT shortestLine(geometry 'SRID=5676;Linestring(1 1,2 2)', tgeompoint 'Point( SELECT shortestLine(geometry 'Linestring(1 1 1,2 2 2)', tgeompoint 'Point(1 1)@2000-01-01'); SELECT shortestLine(tgeompoint 'Point(1 1)@2000-01-01', tgeompoint 'SRID=5676;Point(1 1)@2000-01-01'); SELECT shortestLine(tgeompoint 'Point(1 1)@2000-01-01', tgeompoint 'Point(1 1 1)@2000-01-01'); -SELECT shortestLine(geography 'Linestring(0 0 0,3 3 3)', tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01'); -SELECT shortestLine(tgeogpoint 'Point(1.5 1.5 1.5)@2000-01-01', geography 'Linestring(0 0 0,3 3 3)'); +SELECT shortestLine(geography 'Linestring(90 0 0,0 90 100)', tgeogpoint 'Point(-90 0 100)@2000-01-01'); +SELECT shortestLine(tgeogpoint 'Point(-90 0 100)@2000-01-01', geography 'Linestring(90 0 0,0 90 100)'); --------------------------------------------------------