From git at osgeo.org Tue Mar 3 17:51:15 2026 From: git at osgeo.org (git at osgeo.org) Date: Tue, 3 Mar 2026 17:51:15 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-349-g3490b7ff1 Message-ID: <20260304015115.95FD4169728@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 3490b7ff1cb2ea50504425d13e9d9e144f598098 (commit) from c21b6cede2e4fdb96233f322d44d5bac256036c8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 3490b7ff1cb2ea50504425d13e9d9e144f598098 Author: Teramoto Ikuhiro Date: Wed Mar 4 00:26:02 2026 +0000 Translated PostGIS Manual using Weblate (Japanese) Currently translated at 99.7% (5879 of 5893 strings) Translation: postgis/PostGIS Manual Translate-URL: https://weblate.osgeo.org/projects/postgis/postgis-manual/ja/ diff --git a/doc/po/ja/postgis-manual.po b/doc/po/ja/postgis-manual.po index a1b0a4376..1f5486de5 100644 --- a/doc/po/ja/postgis-manual.po +++ b/doc/po/ja/postgis-manual.po @@ -10,7 +10,7 @@ msgstr "" "Project-Id-Version: postgis 3.5\n" "Report-Msgid-Bugs-To: https://bugs.kde.org\n" "POT-Creation-Date: 2025-11-13 16:23+0000\n" -"PO-Revision-Date: 2026-02-27 07:51+0000\n" +"PO-Revision-Date: 2026-03-04 01:51+0000\n" "Last-Translator: Teramoto Ikuhiro \n" "Language-Team: Japanese \n" @@ -21061,7 +21061,7 @@ msgstr "" "?????????? (??????)" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "If a table oid is provided, this function tries to " "determine the srid, dimension, and geometry type of all geometry columns in " @@ -21071,9 +21071,9 @@ msgid "" msgstr "" "?????oid??????????????????" "???????????????SRID?????????????????????" -"???????????????? ?????????" -"geometry_columns?????????????????????????" -"??????????????????????" +"???????????????? ?????????geometry_columns?????" +"??????????????????????????????????????" +"????" #. Tag: para #, no-c-format @@ -21089,7 +21089,7 @@ msgstr "" "varname>????????????????????????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "The parameterless variant is a simple wrapper for the parameterized variant " "that first truncates and repopulates the geometry_columns table for every " @@ -21100,11 +21100,11 @@ msgid "" "returns the number of rows inserted into the geometry_columns table." msgstr "" -"???????????geometry_columns??????????" -"??????????????????????????????????????" -"??????????????????????????????????????" -"???????????????geometry_columns??????" -"???????????????????????geometry_columnsgeometry_columns?????" +"????????????????????????geometry_columns???????????????" #. Tag: para @@ -31634,15 +31634,15 @@ msgstr "" "???????)????????X?Y (?????)??????????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "Return record format: geom , val double precision, x " "integer, y integers." msgstr "" -"???????????????geom???????????val????" -"x????y???" +"?????????????geom (?)?val (??????????)" +"?x (???)?y (???)???" #. Tag: para #, no-c-format @@ -35592,14 +35592,14 @@ msgstr "" "args?????????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "The text[] argument to the userfunction is " "required, regardless of whether you choose to pass any arguments to your " "user function for processing or not." msgstr "" -"userfunction??text[]???????????" -"??????????????????????????????????" +"text[]????????? userfunction????" +"???????????????????????" #. Tag: para #, no-c-format @@ -35713,14 +35713,14 @@ msgstr "" "userargs?????????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "The text[] argument to the tworastuserfunc " "is required, regardless of whether you choose to pass any arguments to your " "user function for processing or not." msgstr "" -"tworastuserfunc??text[]??????????" -"???????????????????????????????????" +"text[]????????? tworastuserfunc??" +"?????????????????????????" #. Tag: para #, no-c-format @@ -48279,7 +48279,7 @@ msgstr "" "??????????????????????????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "If SET ENABLE_SEQSCAN TO OFF; helps your query to run " "faster, your Postgres is likely not tuned for your hardware. If you find the " @@ -48292,11 +48292,11 @@ msgid "" msgstr "" "SET ENABLE_SEQSCAN TO OFF;????????????????" "PostgreSQL???????????????????????????????" -"??????????????????????????????????" -"postgresql.conf????RANDOM_PAGE_COST??????" -"???????SET RANDOM_PAGE_COST TO 1.1;????" -"?RANDOM_PAGE_COST????????4.0???1.1 (SSD???)" -"???2.0 (???????????)????????????????????" +"??????????????????????????????????" +"RANDOM_PAGE_COST (postgresql.conf??????)????" +"????????????SET RANDOM_PAGE_COST TO 1.1;???" +"??RANDOM_PAGE_COST????????4.0???1.1 (SSD??" +"?)???2.0 (???????????)????????????????????" "?????????????????????????" #. Tag: para ----------------------------------------------------------------------- Summary of changes: doc/po/ja/postgis-manual.po | 54 ++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 27 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Wed Mar 4 03:51:26 2026 From: git at osgeo.org (git at osgeo.org) Date: Wed, 4 Mar 2026 03:51:26 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-350-gf0af9121d Message-ID: <20260304115127.62BAE16DC3A@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via f0af9121d32fc84d7fc4bcb4db79f26e7abfd74c (commit) from 3490b7ff1cb2ea50504425d13e9d9e144f598098 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f0af9121d32fc84d7fc4bcb4db79f26e7abfd74c Author: Teramoto Ikuhiro Date: Wed Mar 4 09:58:43 2026 +0000 Translated PostGIS Manual using Weblate (Japanese) Currently translated at 99.7% (5879 of 5893 strings) Translation: postgis/PostGIS Manual Translate-URL: https://weblate.osgeo.org/projects/postgis/postgis-manual/ja/ diff --git a/doc/po/ja/postgis-manual.po b/doc/po/ja/postgis-manual.po index 1f5486de5..c44a91f76 100644 --- a/doc/po/ja/postgis-manual.po +++ b/doc/po/ja/postgis-manual.po @@ -10,7 +10,7 @@ msgstr "" "Project-Id-Version: postgis 3.5\n" "Report-Msgid-Bugs-To: https://bugs.kde.org\n" "POT-Creation-Date: 2025-11-13 16:23+0000\n" -"PO-Revision-Date: 2026-03-04 01:51+0000\n" +"PO-Revision-Date: 2026-03-04 11:51+0000\n" "Last-Translator: Teramoto Ikuhiro \n" "Language-Team: Japanese \n" @@ -7597,9 +7597,9 @@ msgid "" msgstr "" "GML3????TopoGeometry?GML????????nsprefix_in?" "?????????????gml??????????????" -"?????nsprefix????????????? (??????15)?options (?" -"?????1)???????????????????????ST_AsGML?????" -"?????" +"?????nsprefix????????????? (??????15)?options " +"(??????1)?????????????????????????ST_AsGML??" +"????????" #. Tag: para #, no-c-format @@ -7614,9 +7614,9 @@ msgid "" "be created automatically by adding a unique constraint to the fields. " "Example:" msgstr "" -"visitedTable???????????????????????" -"??????????????????????????????????????" -"?? (xlink:xref)??????????? ???????" +"visitedTable??????????????????????" +"??????????????????????????????????????" +"????? (xlink:xref)??????????? ???????" "?'element_type'?'element_id'???????????????????????" "??????????????????????????????????????" "????? element_type?element_id??" @@ -7629,8 +7629,8 @@ msgid "" "The idprefix parameter, if given, will be prepended to " "Edge and Node tag identifiers." msgstr "" -"idprefix????????????????Edge??????" -"Node?????????????" +"idprefix??????????????????Edge?????" +"?Node?????????????" #. Tag: para #, no-c-format @@ -7638,7 +7638,7 @@ msgid "" "The gmlver parameter, if given, will be passed to the " "underlying ST_AsGML. Defaults to 3." msgstr "" -"gmlver???????????????????????" +"gmlver?????????????????????????" "ST_AsGML?????????????3???" #. Tag: para @@ -7684,9 +7684,9 @@ msgid "" "\"serial\" and an \"edge_id\" of type integer; the code will query the table " "for \"edge_id\" so it is recommended to add an index on that field." msgstr "" -"??????????????????\"serial\"??\"arc_id\"????????" -"\"edge_id\"????????????????????????\"edge_id\"???" -"?????????????????????????????????" +"??????????????????\"serial\"??\"arc_id\"???????" +"?\"edge_id\"????????????????????????\"edge_id\"??" +"???????????????????????????????????" #. Tag: para #, no-c-format @@ -10045,10 +10045,11 @@ msgid "" "integration and alignment with GEOS releases, alignment of PostGIS with " "PostgreSQL releases, loader/dumper, and Shapefile GUI loader." msgstr "" -"PostGIS???????????????????????????????????" -"?????????????????? (2??,?3???n???????????" -"????????)???????????GEOS??????GEOS?????????" -"PostgreSQL?????????????/????????????GUI????" +"PostGIS????????????????????????????????" +"????????????????????? (2??,?3???n????????" +"?????????????)???????????GEOS??????GEOS????" +"?????PostgreSQL?????????????/????????????GUI" +"????" #. Tag: term #, no-c-format @@ -10266,8 +10267,8 @@ msgid "" "The original developer/Co-founder of PostGIS. Dave wrote the server side " "objects, index bindings, and many of the server side analytical functions." msgstr "" -"PostGIS?????????/?????????????????????????" -"??????????????????????????" +"PostGIS?????????/?????????????????????????" +"???????????????????????????" #. Tag: term #, no-c-format @@ -11632,10 +11633,11 @@ msgid "" "PostGIS includes support for GiST-based R-Tree spatial indexes, and " "functions for analysis and processing of GIS objects." msgstr "" -"PostGIS????????RDB???PostgreSQL?????GIS (????????)??????????" -"?????????PostGIS??GiST????R???????????????GIS?" -"????????????????????????" +"PostGIS????????RDB???PostgreSQL?????GIS (????????)" +"???????????????????PostGIS??GiST????R???" +"?????????????GIS????????????????????????" +"?" #. Tag: para #, no-c-format @@ -11835,7 +11837,7 @@ msgstr "&list_3d_functions;" msgid "" "The functions given below are PostGIS functions that do not throw away the Z-" "Index." -msgstr "????????Z????????????PostGIS?????" +msgstr "????????Z?????????????PostGIS?????" #. Tag: title #, no-c-format @@ -12856,8 +12858,8 @@ msgid "" "Index is 1-based as for OGC specs since version 0.8.0. Previous versions " "implemented this as 0-based instead." msgstr "" -"OGC?????0.8.0?????????1???????????????????0" -"???????????" +"OGC?????0.8.0??????????1???????????????????" +"0???????????" #. Tag: para #, no-c-format @@ -13568,7 +13570,7 @@ msgstr "" #. Tag: para #, no-c-format msgid "Index is 1-based." -msgstr "??????1??????" +msgstr "???????1??????" #. Tag: para #, no-c-format @@ -16331,10 +16333,10 @@ msgid "" "narrower gaps will also be returned as invalid." msgstr "" "??????????????????????????????????????" -"?? (????????)??????????????????????????" -"?????????????????????????tolerance?????0????????????????????????????" -"??????????????????" +"?? (????????)???????????????????????????" +"????????????????????????tolerance???????0??????????????????????????" +"????????????????????" #. Tag: para #, no-c-format @@ -16552,7 +16554,8 @@ msgid "" "parameter to false." msgstr "" "?????????????? (???????????????)????????" -"???simplifyBoundary?????FALSE???????" +"???simplifyBoundary???????FALSE??????" +"?" #. Tag: para #, no-c-format @@ -18110,10 +18113,10 @@ msgid "" "useful in triggers when trying to maintain relationship of joints when one " "vertex moves." msgstr "" -"?????????N??????????????????????????0??" -"????????????????????????????-1?????????" -"??????????????????????????????????????" -"????????????????" +"?????????N???????????????????????????0?" +"?????????????????????????????-1????????" +"??????????????????????????????????????" +"?????????????????" #. Tag: para #, no-c-format @@ -19615,8 +19618,8 @@ msgid "" "Creates a geometry instance from a Well-Known Binary geometry representation " "(WKB) and optional SRID." msgstr "" -"Well-Knwon Binary??????? (WKB)????????SRID??????????" -"??????????" +"Well-Knwon Binary??????? (WKB)??????????SRID??" +"??????????????????" #. Tag: para #, no-c-format @@ -21104,8 +21107,8 @@ msgstr "" "?????????????????????????????????????" "??????????????????????????????????????" "????????????????geometry_columns?????" -"????????????????????????geometry_columns???????????????" +"??????????????????????????" +"geometry_columns???????????????" #. Tag: para #, no-c-format @@ -32306,8 +32309,8 @@ msgid "" "be separated by white space. Accepts inputs in GDAL or ESRI format. Default " "is GDAL." msgstr "" -"????6??????????????????????????GDAL???ESRI?" -"??????????????????GDAL???" +"????6????????????????????????????GDAL???" +"ESRI???????????????????GDAL???" #. Tag: para #, no-c-format @@ -32316,8 +32319,9 @@ msgid "" "in 'GDAL' or 'ESRI' format. Default is GDAL. If 6 coordinates are not " "provided will return null." msgstr "" -"????6??????????????'GDAL'???'ESRI'???????????" -"????????GDAL???6????????????????NULL??????" +"????6????????????????'GDAL'???'ESRI'?????????" +"??????????GDAL???6??????????????????NULL???" +"???" #. Tag: para #, no-c-format @@ -32418,8 +32422,8 @@ msgid "" "Sets the georeference X and Y skew (or rotation parameter). If only one is " "passed in, sets X and Y to the same value." msgstr "" -"????????? (??????)?X??Y??????????????????" -"??X??Y?????????????" +"????????? (????????)?X??Y????????????????" +"????X??Y?????????????" #. Tag: para #, no-c-format @@ -32429,10 +32433,10 @@ msgid "" "href=\"http://en.wikipedia.org/wiki/World_file\">World File for more " "details." msgstr "" -"????????? (??????)?X??Y??????????????????" -"??X??Y????????????????????World File (???WikiPedia)???" -"????" +"????????? (????????)?X??Y????????????????" +"????X??Y????????????????????World File (?" +"??WikiPedia)???????" #. Tag: para #, no-c-format @@ -32704,9 +32708,9 @@ msgid "" "spelling), Bilinear, Cubic, CubicSpline or Lanczos resampling algorithm. " "Default is NearestNeighbor." msgstr "" -"??? (??????)????????????????????????????" -"?????????????????????? ('NearestNeighbor' (????" -"?))?????? ('Bilinear')?3??? ('Cubic')?3???????? " +"??? (????????)???????????????????????" +"??????????????????????????? ('NearestNeighbor' (?" +"????))?????? ('Bilinear')?3??? ('Cubic')?3???????? " "('CubicSpline')???????? ('Lanczos')?????????????????" "???" @@ -32719,9 +32723,9 @@ msgid "" "default is NearestNeighbor which is the fastest but results in the worst " "interpolation." msgstr "" -"???? (??????)???????????????????????????" -"??????????????????????? ('NearestNeighbor' (????" -"?))?????? ('Bilinear')?3??? ('Cubic')?3???????? " +"???? (????????)???????????????????????" +"??????????????????????????? ('NearestNeighbor' (?" +"????))?????? ('Bilinear')?3??? ('Cubic')?3???????? " "('CubicSpline')???????? ('Lanczos')?????????????????" "???????????????????" @@ -32837,7 +32841,7 @@ msgid "" "Use if you need more control over the " "grid parameters." msgstr "" -"??????????????????????????????" #. Tag: para @@ -33895,10 +33899,10 @@ msgid "" msgstr "" "options JPEG????????GDAL????????????" "? (?create_options???????)?" -"JPEG????????? PROGRESSIVE?'ON'???'OFF'??" -"QUALITY?0??100???? (??????75)????????" -"?? GDAL Raster " -"format options???????" +"JPEG??????????? PROGRESSIVE?'ON'???'OFF'?" +"?QUALITY?0??100???? (??????75)???????" +"??? GDAL " +"Raster format options???????" #. Tag: title #, no-c-format @@ -33980,11 +33984,11 @@ msgid "" msgstr "" "options PNG????????GDAL????????????? " "(?create_options???????)?PNG?" -"????????ZLEVEL (???????????????????6)???" -"ARRAY['ZLEVEL=9']?????????????????????????????" -"???????????PNG????????????????GDAL Raster format options???????" +"??????????ZLEVEL (???????????????????6)???" +"ARRAY['ZLEVEL=9']??????????????????????????????" +"??????????PNG????????????????GDAL Raster format " +"options???????" #. Tag: para #, no-c-format @@ -39994,8 +39998,8 @@ msgid "" "This function call includes a bounding box comparison that makes use of any " "indexes that are available on the geometries." msgstr "" -"??????????????????????????????????????" -"??????????????????????" +"????????????????????????????????????" +"?????????????????????????" #. Tag: para #, no-c-format @@ -42159,8 +42163,8 @@ msgid "" "If using more than one transformation, it is useful to have a functional " "index on the commonly used transformations to take advantage of index usage." msgstr "" -"??????????????????????????????????????" -"?????????????????" +"??????????????????????????????????????" +"???????????????????" #. Tag: para #, no-c-format @@ -42187,9 +42191,9 @@ msgid "" "that leaves out null geometries which will both conserve space and make your " "index smaller and more efficient." msgstr "" -"??????????????????????????????????????" -"?????????????????????????????????????" -"NULL???????????????????????????" +"??????????????????????????????????????" +"??????????????????????????????????????" +"?NULL????????????????????????????" #. Tag: para #, no-c-format @@ -42763,7 +42767,7 @@ msgstr "" msgid "" "Enhanced: 2.0.0 additional parameters for specifying the origin of rotation " "were added." -msgstr "Enhanced: 2.0.0 ??????????????????????" +msgstr "Enhanced: 2.0.0 ????????????????????????" #. Tag: para #, no-c-format @@ -43052,13 +43056,13 @@ msgid "" "automatic conversion of a function argument to a type supported by the " "function." msgstr "" -"????????????????????????????????????????????????" -"?????????????PostgreSQL????????????????????" -"???????????????????????????????????????????????????????????" -"??????????????????????????" +"????????????????????????????????????????" +"?????????????????????PostgreSQL????????????" +"?????????????????????????????????????" +"?????????????????????" +"????????????????????????????????????" #. Tag: para #, no-c-format @@ -45325,8 +45329,8 @@ msgid "" "indexes, and spatial operators to use them. See and for details." msgstr "" -"???????????????????PostGIS????????????????" -"????????????????????????" #. Tag: title @@ -46753,7 +46757,7 @@ msgstr "" #. Tag: title #, no-c-format msgid "User-Defined Spatial Reference Systems" -msgstr "??????????" +msgstr "???????????" #. Tag: para #, no-c-format @@ -47192,10 +47196,10 @@ msgid "" "for one-off non-scripted loading or if you are new to PostGIS. It can also " "be configured as a plugin to PgAdminIII." msgstr "" -"???????????????????shp2pgsql-gui??" -"??????????????????????????????????????" -"?????????1????????????PostGIS?????????????" -"??????????PgAdminIII?????????????????" +"????????????????????shp2pgsql-gui?" +"????????????????????????????????????" +"????????????1????????????PostGIS??????????" +"?????????????PgAdminIII?????????????????" #. Tag: term #, no-c-format @@ -47612,7 +47616,7 @@ msgstr "????????????????????" #. Tag: para #, no-c-format msgid "The username to use when connecting to the database." -msgstr "??????????????????" +msgstr "???????????????????" #. Tag: para #, no-c-format @@ -49246,8 +49250,9 @@ msgid "" "will be created in the default schema of the database or user you are " "connecting with." msgstr "" -"??????????????????????????????????????" -"???????????????????????????????????" +"?????????????????????????????????" +"??????????????????????????????????????" +"???" #. Tag: para #, no-c-format @@ -49376,7 +49381,7 @@ msgid "" "index, separate with comma (,). If unspecified, all bands of raster will be " "extracted." msgstr "" -"?????????????????? (1???)?1?????????????" +"??????????????????? (1???)?1?????????????" "?????(,)?????????????????????????????" #. Tag: para @@ -49466,7 +49471,7 @@ msgstr "PostgreSQL?????????????" #. Tag: para #, no-c-format msgid "Create a GiST index on the raster column." -msgstr "???????GiST????????????" +msgstr "???????GiST?????????????" #. Tag: para #, no-c-format @@ -49492,8 +49497,8 @@ msgid "" "also used." msgstr "" "?????????????????????????-X????????????" -"??????? (??????)????????????????????????" -"???????" +"???????? (??????)???????????????????????" +"????????" #. Tag: para #, no-c-format @@ -49501,8 +49506,8 @@ msgid "" "Specify the tablespace for the table's new index. This applies to the " "primary key and the spatial index if the -I flag is used." msgstr "" -"??????????????????????????????????????-" -"I?????????????????????????????" +"??????????????????????????????????????" +"?-I??????????????????????????????" #. Tag: para #, no-c-format @@ -49602,8 +49607,8 @@ msgid "" "Once you are done populating your table initially, you'll want to create a " "spatial index on the raster column with something like:" msgstr "" -"??????????????????????????????????????" -"??????:" +"??????????????????????????????????????" +"???????:" #. Tag: para #, no-c-format @@ -49622,8 +49627,8 @@ msgid "" "those and replace with convex hull based index." msgstr "" "2.0???? PostGIS ????????????????????????????" -"??????????????????????????????????????" -"??????????????????????????" +"??????????????????????????????????" +"?????????????????????????????????" #. Tag: para #, no-c-format @@ -49989,8 +49994,8 @@ msgid "" "spatial_index A boolean that is true if raster column has " "a spatial index." msgstr "" -"spatial_index ??????????????????????" -"????" +"spatial_index ??????????????????????" +"?????" #. Tag: title #, no-c-format @@ -50230,11 +50235,11 @@ msgid "" "specified projection using , and then " "outputs the results as a png using ." msgstr "" -"?????????? ????WGS84?????????????????????" -"??????? ???????????????" -"?????????????????????" -"?????????PNG????????????" -"????????????????????" +"?????????? ????WGS84????????????????????" +"???????? ??????????????" +"?????????????????????" +"???????????PNG??????????" +"??????????????????????" #. Tag: para #, no-c-format ----------------------------------------------------------------------- Summary of changes: doc/po/ja/postgis-manual.po | 221 ++++++++++++++++++++++---------------------- 1 file changed, 113 insertions(+), 108 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Wed Mar 4 12:02:01 2026 From: git at osgeo.org (git at osgeo.org) Date: Wed, 4 Mar 2026 12:02:01 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-351-gab39a258b Message-ID: <20260304200202.02A8C16F5DD@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via ab39a258bf1f6ec872452b313564d34ea5805a4c (commit) from f0af9121d32fc84d7fc4bcb4db79f26e7abfd74c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ab39a258bf1f6ec872452b313564d34ea5805a4c Author: Darafei Praliaskouski Date: Wed Mar 4 23:57:21 2026 +0400 fuzzers: centralize OSS-Fuzz build flow in PostGIS Move OSS-Fuzz project logic into PostGIS-owned scripts so oss-fuzz keeps only thin wrappers. Highlights: - add fuzzers/build_oss_fuzz.sh as the single OSS-Fuzz entrypoint - add fuzzers/install_oss_fuzz_build_deps.sh for builder image apt dependencies - make build_google_oss_fuzzers.sh use portable link flags (pkg-config/geos-config) - fold runtime .so packaging/RPATH setup into build_google_oss_fuzzers.sh - prefer provided CXX over pg_config --cc for Wagyu/FlatGeobuf checks - rename fuzzers/README.TXT to README.md and refresh docs/issue links - document the change in NEWS diff --git a/NEWS b/NEWS index eac939a70..6ed876e0c 100644 --- a/NEWS +++ b/NEWS @@ -41,6 +41,10 @@ This version requires GEOS 3.10 or higher - #5593, Docs: render manual images with GraphicsMagick without temporary files, enabling parallel builds, keeping ImageMagick fallbacks working, and documenting the generator workflow for contributors (Darafei Praliaskouski) + - [fuzzers] Centralize OSS-Fuzz build/dependency logic in PostGIS scripts, + prefer requested CXX over pg_config --cc for internal C++ checks, and + make fuzzer linking/runtime dependency packaging portable + (Darafei Praliaskouski) - GH-848, CG_AlphaShape now returns a MultiPolygon (Jean Felder) PostGIS 3.6.0 @@ -3061,5 +3065,3 @@ PostGIS 0.1 - truely_inside() - rtree index support functions - gist index support functions - - diff --git a/configure.ac b/configure.ac index 6a01d656f..d5fb6cc1b 100644 --- a/configure.ac +++ b/configure.ac @@ -1774,7 +1774,7 @@ if test "x$HAVE_PROTOBUF" = "xyes"; then AC_SUBST([WAGYU_LIB]) dnl ============================================================ - dnl We force to use the same compiler as Postgresql + dnl Prefer user/toolchain CXX, falling back to PostgreSQL compiler when needed. dnl ============================================================ CXX_SAVE="$CXX" CC_SAVE="$CC" @@ -1784,7 +1784,13 @@ if test "x$HAVE_PROTOBUF" = "xyes"; then LDFLAGS_SAVE="$LDFLAGS" LIBS_SAVE="$LIBS" - WAGYU_CXX=`"$PG_CONFIG" --cc` + dnl Prefer the requested C++ toolchain when provided (for example by OSS-Fuzz), + dnl and only fall back to PostgreSQL's compiler when CXX is unset. + if test "x$CXX_SAVE" != "x"; then + WAGYU_CXX="$CXX_SAVE" + else + WAGYU_CXX=`"$PG_CONFIG" --cc` + fi CPPFLAGS="-x c++" CFLAGS="" LDFLAGS="" @@ -1847,7 +1853,7 @@ FLATGEOBUF_LIB=libflatgeobuf.la AC_SUBST([FLATGEOBUF_LIB]) dnl ============================================================ -dnl We force to use the same compiler as Postgresql +dnl Prefer user/toolchain CXX, falling back to PostgreSQL compiler when needed. dnl ============================================================ CXX_SAVE="$CXX" CC_SAVE="$CC" @@ -1857,7 +1863,11 @@ CPPFLAGS_SAVE="$CPPFLAGS" LDFLAGS_SAVE="$LDFLAGS" LIBS_SAVE="$LIBS" -FLATGEOBUF_CXX=`"$PG_CONFIG" --cc` +if test "x$CXX_SAVE" != "x"; then + FLATGEOBUF_CXX="$CXX_SAVE" +else + FLATGEOBUF_CXX=`"$PG_CONFIG" --cc` +fi CPPFLAGS="-x c++" CFLAGS="" LDFLAGS="" diff --git a/fuzzers/README.TXT b/fuzzers/README.TXT deleted file mode 100644 index df858ea2d..000000000 --- a/fuzzers/README.TXT +++ /dev/null @@ -1,38 +0,0 @@ -This directory contains fuzzer main functions and scripts for the -Google OSS Fuzz project: https://github.com/google/oss-fuzz/ - -The main build scripts are in: -https://github.com/google/oss-fuzz/tree/master/projects/postgis -and call scripts in this directory. - -The list of issues is in: -https://bugs.chromium.org/p/oss-fuzz/issues/list?q=postgis - -- Simulate the build of (dummy) fuzzers like OSS Fuzz does: - $ make dummyfuzzers - They are created in /tmp/*_fuzzer as well as with the - /tmp/*_fuzzer_seed_corpus.zip files - - Run one: - $ /tmp/wkt_import_fuzzer a_file_name - -- Run locally OSS Fuzz: - $ git clone --depth=1 https://github.com/google/oss-fuzz.git - $ cd oss-fuzz - $ python infra/helper.py build_image postgis - - Build fuzzers with the address sanitizer (could use undefined, etc...) - $ python infra/helper.py build_fuzzers --sanitizer address postgis - - Test a particular fuzzer (replace wkt_import_fuzzer by other fuzzers - like the ones generated in /tmp by "make dummyfuzzers") - $ python infra/helper.py run_fuzzer postgis wkt_import_fuzzer - - -How to deal with issues reported in https://bugs.chromium.org/p/oss-fuzz/issues/list?q=postgis ? - - 1. Leave a comment in (chromium database) bug entry to indicate that you work on it - 2. Work - 3. Commit a bug fix with log including "Credit to OSS-Fuzz" and a link to the bugs.chromium.org ticket - 4. Add in the bugs.chromium.org ticket a link to the Trac changeset implementing the fix. - 5. Check chromium closed the bug (after one or two days typically) diff --git a/fuzzers/README.md b/fuzzers/README.md new file mode 100644 index 000000000..0c167e4f3 --- /dev/null +++ b/fuzzers/README.md @@ -0,0 +1,64 @@ +# PostGIS Fuzzers + +This directory contains fuzzer entry points and helper scripts for the +[Google OSS-Fuzz project](https://github.com/google/oss-fuzz/). + +## OSS-Fuzz Build Entrypoint + +The main OSS-Fuzz build orchestration lives in: + +- `./fuzzers/build_oss_fuzz.sh` + +The wrapper in +[`oss-fuzz/projects/postgis`](https://github.com/google/oss-fuzz/tree/master/projects/postgis) +should call this script. + +## OSS-Fuzz Image Dependencies + +The package list for the OSS-Fuzz builder image lives in: + +- `./fuzzers/install_oss_fuzz_build_deps.sh` + +The `oss-fuzz` project `Dockerfile` should call this script during image build. + +## Issues + +- [PostGIS OSS-Fuzz issue list](https://issues.oss-fuzz.com/issues?q=postgis) + +## Local Workflow + +### Simulate Dummy Fuzzer Build + +```bash +make dummyfuzzers +``` + +Artifacts are created in `/tmp`: + +- `/tmp/*_fuzzer` +- `/tmp/*_fuzzer_seed_corpus.zip` +- Runtime shared libraries in `/tmp/lib` (when available) + +Run one fuzzer locally: + +```bash +/tmp/wkt_import_fuzzer a_file_name +``` + +### Run OSS-Fuzz Locally + +```bash +git clone --depth=1 https://github.com/google/oss-fuzz.git +cd oss-fuzz +python infra/helper.py build_image postgis +python infra/helper.py build_fuzzers --sanitizer address postgis +python infra/helper.py run_fuzzer postgis wkt_import_fuzzer +``` + +## Handling Reported OSS-Fuzz Issues + +1. Leave a comment in the bug entry to indicate that you are working on it. +2. Implement the fix. +3. Commit with a message including `Credit to OSS-Fuzz` and a link to the OSS-Fuzz ticket. +4. Add a link to the implementing changeset/commit in the OSS-Fuzz ticket. +5. Verify OSS-Fuzz closes the bug (usually within a day or two). diff --git a/fuzzers/build_google_oss_fuzzers.sh b/fuzzers/build_google_oss_fuzzers.sh index cca450323..4f1435c24 100755 --- a/fuzzers/build_google_oss_fuzzers.sh +++ b/fuzzers/build_google_oss_fuzzers.sh @@ -18,6 +18,11 @@ if [ "$CXX" == "" ]; then fi SRC_DIR=$(dirname $0)/.. +JSON_C_LIBS=$(pkg-config --libs json-c) +GEOS_LIBS=$(geos-config --clibs) +PROJ_XML2_LIBS=$(pkg-config --libs proj libxml-2.0) +POSTGIS_FUZZER_LIBS="$JSON_C_LIBS $GEOS_LIBS $PROJ_XML2_LIBS" +POSTGIS_PACKAGE_RUNTIME_LIBS="${POSTGIS_PACKAGE_RUNTIME_LIBS:-1}" build_fuzzer() { @@ -28,7 +33,37 @@ build_fuzzer() echo "Building fuzzer $fuzzerName" $CXX $CXXFLAGS -std=c++11 -I$SRC_DIR/liblwgeom \ $sourceFilename $* -o $OUT/$fuzzerName \ - -lFuzzingEngine -lstdc++ $SRC_DIR/liblwgeom/.libs/liblwgeom.a /usr/lib/x86_64-linux-gnu/libjson-c.a + -lFuzzingEngine -lstdc++ $SRC_DIR/liblwgeom/.libs/liblwgeom.a $POSTGIS_FUZZER_LIBS +} + +package_runtime_libs() +{ + mkdir -p "$OUT/lib" + + for fuzzer in "$OUT"/*_fuzzer; do + [ -f "$fuzzer" ] || continue + + if command -v patchelf >/dev/null 2>&1; then + patchelf --set-rpath '$ORIGIN/lib' "$fuzzer" + fi + + while read -r lib; do + [ -f "$lib" ] || continue + + base="$(basename "$lib")" + case "$base" in + libc.so.*|libm.so.*|libdl.so.*|libpthread.so.*|librt.so.*|libgcc_s.so.*|ld-linux*.so.*|linux-vdso.so.*|libresolv.so.*) + continue + ;; + esac + + cp -n "$lib" "$OUT/lib/" || true + done < <(ldd "$fuzzer" | awk '/=> \// {print $3}') + done + + if command -v patchelf >/dev/null 2>&1; then + patchelf --set-rpath '$ORIGIN' "$OUT"/lib/*.so* 2>/dev/null || true + fi } fuzzerFiles=$(dirname $0)/*.cpp @@ -38,3 +73,7 @@ for F in $fuzzerFiles; do done cp $(dirname $0)/*.dict $(dirname $0)/*.options $(dirname $0)/*.zip $OUT/ + +if [ "$POSTGIS_PACKAGE_RUNTIME_LIBS" != "0" ]; then + package_runtime_libs +fi diff --git a/fuzzers/build_oss_fuzz.sh b/fuzzers/build_oss_fuzz.sh new file mode 100755 index 000000000..5b65ddcda --- /dev/null +++ b/fuzzers/build_oss_fuzz.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +set -e + +if [ "$CC" == "" ]; then + echo "CC env var not defined" + exit 1 +fi + +if [ "$CXX" == "" ]; then + echo "CXX env var not defined" + exit 1 +fi + +if [ "$OUT" == "" ]; then + echo "OUT env var not defined" + exit 1 +fi + +FUZZERS_DIR=$(cd "$(dirname "$0")" && pwd) +SRC_DIR=$(dirname "$FUZZERS_DIR") +mkdir -p "$OUT" + +if [ "$SRC" == "" ]; then + export SRC="$SRC_DIR" +fi + +export CXXFLAGS="$CXXFLAGS -std=c++11" +POSTGIS_OSS_FUZZ_CONFIGURE_FLAGS=( + --enable-static + --without-raster + --without-protobuf + --enable-debug +) + +cd "$SRC_DIR" +./autogen.sh +./configure CC="$CC" CXX="$CXX" "${POSTGIS_OSS_FUZZ_CONFIGURE_FLAGS[@]}" +cd liblwgeom +make clean -s +make -j"$(nproc)" -s +cd .. + +bash ./fuzzers/build_google_oss_fuzzers.sh +bash ./fuzzers/build_seed_corpus.sh diff --git a/fuzzers/install_oss_fuzz_build_deps.sh b/fuzzers/install_oss_fuzz_build_deps.sh new file mode 100755 index 000000000..992d20369 --- /dev/null +++ b/fuzzers/install_oss_fuzz_build_deps.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -e + +if ! command -v apt-get >/dev/null 2>&1; then + echo "apt-get not found" + exit 1 +fi + +if [ "$(id -u)" -ne 0 ]; then + echo "This script must run as root inside the OSS-Fuzz builder image" + exit 1 +fi + +export DEBIAN_FRONTEND="${DEBIAN_FRONTEND:-noninteractive}" + +apt-get update +apt-get install -y --no-install-recommends \ + make autoconf automake libtool g++ postgresql-server-dev-all \ + libgeos-dev libproj-dev libxml2-dev pkg-config libjson-c-dev \ + libc++-dev libc++abi-dev patchelf + +rm -rf /var/lib/apt/lists/* ----------------------------------------------------------------------- Summary of changes: NEWS | 6 ++-- configure.ac | 18 +++++++--- fuzzers/README.TXT | 38 -------------------- fuzzers/README.md | 64 ++++++++++++++++++++++++++++++++++ fuzzers/build_google_oss_fuzzers.sh | 41 +++++++++++++++++++++- fuzzers/build_oss_fuzz.sh | 45 ++++++++++++++++++++++++ fuzzers/install_oss_fuzz_build_deps.sh | 23 ++++++++++++ 7 files changed, 190 insertions(+), 45 deletions(-) delete mode 100644 fuzzers/README.TXT create mode 100644 fuzzers/README.md create mode 100755 fuzzers/build_oss_fuzz.sh create mode 100755 fuzzers/install_oss_fuzz_build_deps.sh hooks/post-receive -- PostGIS From git at osgeo.org Wed Mar 4 17:51:22 2026 From: git at osgeo.org (git at osgeo.org) Date: Wed, 4 Mar 2026 17:51:22 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-352-g13cacae51 Message-ID: <20260305015123.1C6C818881B@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 13cacae51bf7d39ecb714543bbde04d54c1366ac (commit) from ab39a258bf1f6ec872452b313564d34ea5805a4c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 13cacae51bf7d39ecb714543bbde04d54c1366ac Author: Teramoto Ikuhiro Date: Thu Mar 5 00:04:19 2026 +0000 Translated PostGIS Manual using Weblate (Japanese) Currently translated at 99.8% (5886 of 5893 strings) Translation: postgis/PostGIS Manual Translate-URL: https://weblate.osgeo.org/projects/postgis/postgis-manual/ja/ diff --git a/doc/po/ja/postgis-manual.po b/doc/po/ja/postgis-manual.po index c44a91f76..b512408b0 100644 --- a/doc/po/ja/postgis-manual.po +++ b/doc/po/ja/postgis-manual.po @@ -10,7 +10,7 @@ msgstr "" "Project-Id-Version: postgis 3.5\n" "Report-Msgid-Bugs-To: https://bugs.kde.org\n" "POT-Creation-Date: 2025-11-13 16:23+0000\n" -"PO-Revision-Date: 2026-03-04 11:51+0000\n" +"PO-Revision-Date: 2026-03-05 01:51+0000\n" "Last-Translator: Teramoto Ikuhiro \n" "Language-Team: Japanese \n" @@ -1715,49 +1715,49 @@ msgid "(token number 0): Unparsed building identifiers and types." msgstr "(?????? 0): ??????????????????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "(token number 14): The BOX " "in BOX 3B" msgstr "" -"(?????? 14): BOX 3B?? BOX???????" +"(?????? 14): BOX???" +"????????????BOX 3B????????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "(token number 15): The 3B in " "BOX 3B" msgstr "" -"(?????? 15): BOX 3B??3B???????" +"(?????? 15): 3B????" +"???????????BOX 3B????????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "(token number 8): The RR in " "RR 7" msgstr "" -"(?????? 8): RR 7??" -"RR???????" +"(?????? 8): RR????" +"???????????RR 7????????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "(token number 16): The APT " "in APT 3B" msgstr "" -"(?????? 16): APT 3B??APT???????" +"(?????? 16): APT???" +"????????????APT 3B????????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "(token number 17): The 3B in " "APT 3B" msgstr "" -"(??????17): APT 3B??3B???????" +"(??????17): 3B????" +"???????????APT 3B????????" #. Tag: para #, no-c-format @@ -2037,7 +2037,7 @@ msgid "Variant 1: Takes an address as a single line." msgstr "1?????: ??????????????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "Variant 2: Takes an address as 2 parts. A micro " "consisting of standard first line of postal address e.g. house_num " @@ -2045,9 +2045,9 @@ msgid "" "address e.g city, state postal_code country." msgstr "" "2?????: ???????????????micro?" -"house_num street???????????????1?????" -"macro??city, state postal_code country???????" -"????????2?????" +"house_num street???????????????1?????macro?" +"?city, state postal_code country???????????????2" +"?????" #. Tag: para #, no-c-format @@ -9753,15 +9753,15 @@ msgstr "" "???????????????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "After the states you desire have been loaded, make sure to run the: " "SELECT install_missing_indexes(); as " "described in ." msgstr "" -"?????????????????" -"??????SELECT install_missing_indexes();??????????????" +"???????????????SELECT install_missing_indexes" +"();???????????????????????" #. Tag: para #, no-c-format ----------------------------------------------------------------------- Summary of changes: doc/po/ja/postgis-manual.po | 48 ++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 24 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Mar 5 01:38:16 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 5 Mar 2026 01:38:16 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-353-g032bbd623 Message-ID: <20260305093816.3928618A20B@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 032bbd6237c705c4c5a3bc53a5e366f62e6d88ab (commit) from 13cacae51bf7d39ecb714543bbde04d54c1366ac (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 032bbd6237c705c4c5a3bc53a5e366f62e6d88ab Author: Darafei Praliaskouski Date: Thu Mar 5 13:37:40 2026 +0400 CI: fix latest builds and improve regression failure logging diff --git a/.cirrus.yml b/.cirrus.yml index a7dcf094f..bb9728ac8 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -50,7 +50,29 @@ task: ccache -s test_script: - | - gmake ${MAKEJOBS} check RUNTESTFLAGS="-v --extension --dumprestore" || { service postgresql onestop; exit 1; } + show_regression_diffs() { + local tmpdir="${PGIS_REG_TMPDIR:-/tmp/pgis_reg}" + local found=0 + for f in "${tmpdir}"/*_diff; do + [ -f "${f}" ] || continue + if [ "${found}" -eq 0 ]; then + echo "---- BEGIN REGRESSION DIFFS (${tmpdir}) ----" + fi + found=1 + echo "---- ${f} ----" + cat "${f}" + done + if [ "${found}" -eq 0 ]; then + echo "No regression diff files found in ${tmpdir}" + else + echo "---- END REGRESSION DIFFS ----" + fi + } + gmake ${MAKEJOBS} check RUNTESTFLAGS="-v --extension --dumprestore" || { + show_regression_diffs + service postgresql onestop + exit 1 + } service postgresql onestop freebsd_instance: cpu: ${NCPU} @@ -85,6 +107,25 @@ task: test_script: - | + show_regression_diffs() { + local tmpdir="${PGIS_REG_TMPDIR:-/tmp/pgis_reg}" + local found=0 + for f in "${tmpdir}"/*_diff; do + [ -f "${f}" ] || continue + if [ "${found}" -eq 0 ]; then + echo "---- BEGIN REGRESSION DIFFS (${tmpdir}) ----" + fi + found=1 + echo "---- ${f} ----" + cat "${f}" + done + if [ "${found}" -eq 0 ]; then + echo "No regression diff files found in ${tmpdir}" + else + echo "---- END REGRESSION DIFFS ----" + fi + } + export PGCONFIG="${HOMEBREW_PREFIX}/opt/postgresql@${PG}/bin/pg_config" export CFLAGS="-I${HOMEBREW_PREFIX}/opt/gettext/include \ -I${HOMEBREW_PREFIX}/opt/postgresql@${PG}/include \ @@ -105,7 +146,11 @@ task: brew services start postgresql@${PG} make -j$(sysctl -n hw.logicalcpu) || { brew services stop postgresql@${PG}; exit 1; } - make -j$(sysctl -n hw.logicalcpu) check || { brew services stop postgresql@${PG}; exit 1; } + make -j$(sysctl -n hw.logicalcpu) check || { + show_regression_diffs + brew services stop postgresql@${PG} + exit 1 + } brew services stop postgresql@${PG} macos_cache: diff --git a/raster/rt_pg/rtpg_geometry.c b/raster/rt_pg/rtpg_geometry.c index a4059a8bc..5bfd62ad9 100644 --- a/raster/rt_pg/rtpg_geometry.c +++ b/raster/rt_pg/rtpg_geometry.c @@ -1572,9 +1572,8 @@ Datum RASTER_asRaster(PG_FUNCTION_ARGS) srs = NULL; /* determine number of bands */ - /* MIN macro is from GDAL's cpl_port.h */ - num_bands = MIN(pixtypes_len, values_len); - num_bands = MIN(num_bands, nodatavals_len); + num_bands = Min(pixtypes_len, values_len); + num_bands = Min(num_bands, nodatavals_len); POSTGIS_RT_DEBUGF(3, "RASTER_asRaster: pixtypes_len = %d", pixtypes_len); POSTGIS_RT_DEBUGF(3, "RASTER_asRaster: values_len = %d", values_len); POSTGIS_RT_DEBUGF(3, "RASTER_asRaster: nodatavals_len = %d", nodatavals_len); ----------------------------------------------------------------------- Summary of changes: .cirrus.yml | 49 ++++++++++++++++++++++++++++++++++++++++++-- raster/rt_pg/rtpg_geometry.c | 5 ++--- 2 files changed, 49 insertions(+), 5 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Mar 5 07:50:52 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 5 Mar 2026 07:50:52 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-354-g163620225 Message-ID: <20260305155052.C83A018E187@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 1636202258b8e3aa41784b57191400c7d4509f08 (commit) from 032bbd6237c705c4c5a3bc53a5e366f62e6d88ab (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1636202258b8e3aa41784b57191400c7d4509f08 Author: Darafei Praliaskouski Date: Thu Mar 5 19:21:40 2026 +0400 CI: stabilize topology error locations and fix FreeBSD raster make race diff --git a/liblwgeom/topo/lwgeom_topo.c b/liblwgeom/topo/lwgeom_topo.c index ae60d2132..ba42f592c 100644 --- a/liblwgeom/topo/lwgeom_topo.c +++ b/liblwgeom/topo/lwgeom_topo.c @@ -37,17 +37,29 @@ #include +static bool +_lwt_describe_point(const LWPOINT *pt, char *buf, size_t bufsize) +{ + POINT2D p; + + if (!pt || !pt->point || !pt->point->npoints) + return false; + + getPoint2d_p(pt->point, 0, &p); + snprintf(buf, bufsize, " at POINT(%.15g %.15g)", p.x, p.y); + return true; +} + /* - * Report a human readable location along with topology errors so callers can - * narrow down robustness issues such as #5886/#5889 without further tracing. - * Using a point-on-surface keeps the message compact while remaining - * representative for any dimensionality of the offending intersection. + * Report a deterministic GEOS-derived location for topology errors. + * Normalize the intersection geometry so PointOnSurface is stable + * across operand-order and platform differences. */ static bool _lwt_describe_intersection_point(const GEOSGeometry *g1, const GEOSGeometry *g2, char *buf, size_t bufsize) { unsigned int n = 0; - POINT2D pt; + POINT2D p; GEOSGeometry *isect; GEOSGeometry *surface_pt; const GEOSCoordSequence *seq; @@ -56,6 +68,12 @@ _lwt_describe_intersection_point(const GEOSGeometry *g1, const GEOSGeometry *g2, if (!isect) return false; + if (GEOSNormalize(isect) != 0) + { + GEOSGeom_destroy(isect); + return false; + } + surface_pt = GEOSPointOnSurface(isect); GEOSGeom_destroy(isect); if (!surface_pt) @@ -74,26 +92,13 @@ _lwt_describe_intersection_point(const GEOSGeometry *g1, const GEOSGeometry *g2, return false; } - if (!GEOSCoordSeq_getX(seq, 0, &pt.x) || !GEOSCoordSeq_getY(seq, 0, &pt.y)) + if (!GEOSCoordSeq_getX(seq, 0, &p.x) || !GEOSCoordSeq_getY(seq, 0, &p.y)) { GEOSGeom_destroy(surface_pt); return false; } GEOSGeom_destroy(surface_pt); - snprintf(buf, bufsize, " at POINT(%.15g %.15g)", pt.x, pt.y); - return true; -} - -static bool -_lwt_describe_point(const LWPOINT *pt, char *buf, size_t bufsize) -{ - POINT2D p; - - if (!pt || !pt->point || !pt->point->npoints) - return false; - - getPoint2d_p(pt->point, 0, &p); snprintf(buf, bufsize, " at POINT(%.15g %.15g)", p.x, p.y); return true; } @@ -796,9 +801,10 @@ _lwt_CheckEdgeCrossing( LWT_TOPOLOGY* topo, match = GEOSRelatePatternMatch(relate, "1FFF*FFF2"); if ( match ) { char locinfo[128] = ""; - const char *locsuffix = match == 2 ? "" - : _lwt_describe_intersection_point(edgegg, eegg, locinfo, sizeof(locinfo)) ? locinfo - : ""; + const char *locsuffix = match == 2 ? "" + : _lwt_describe_intersection_point(edgegg, eegg, locinfo, sizeof(locinfo)) + ? locinfo + : ""; GEOSGeom_destroy(eegg); GEOSGeom_destroy(edgegg); _lwt_release_edges(edges, num_edges); @@ -817,9 +823,10 @@ _lwt_CheckEdgeCrossing( LWT_TOPOLOGY* topo, match = GEOSRelatePatternMatch(relate, "1********"); if ( match ) { char locinfo[128] = ""; - const char *locsuffix = match == 2 ? "" - : _lwt_describe_intersection_point(edgegg, eegg, locinfo, sizeof(locinfo)) ? locinfo - : ""; + const char *locsuffix = match == 2 ? "" + : _lwt_describe_intersection_point(edgegg, eegg, locinfo, sizeof(locinfo)) + ? locinfo + : ""; GEOSGeom_destroy(eegg); GEOSGeom_destroy(edgegg); _lwt_release_edges(edges, num_edges); @@ -838,9 +845,10 @@ _lwt_CheckEdgeCrossing( LWT_TOPOLOGY* topo, match = GEOSRelatePatternMatch(relate, "T********"); if ( match ) { char locinfo[128] = ""; - const char *locsuffix = match == 2 ? "" - : _lwt_describe_intersection_point(edgegg, eegg, locinfo, sizeof(locinfo)) ? locinfo - : ""; + const char *locsuffix = match == 2 ? "" + : _lwt_describe_intersection_point(edgegg, eegg, locinfo, sizeof(locinfo)) + ? locinfo + : ""; GEOSGeom_destroy(eegg); GEOSGeom_destroy(edgegg); _lwt_release_edges(edges, num_edges); @@ -860,9 +868,10 @@ _lwt_CheckEdgeCrossing( LWT_TOPOLOGY* topo, match = GEOSRelatePatternMatch(relate, "*T*******"); if ( match ) { char locinfo[128] = ""; - const char *locsuffix = match == 2 ? "" - : _lwt_describe_intersection_point(edgegg, eegg, locinfo, sizeof(locinfo)) ? locinfo - : ""; + const char *locsuffix = match == 2 ? "" + : _lwt_describe_intersection_point(edgegg, eegg, locinfo, sizeof(locinfo)) + ? locinfo + : ""; GEOSGeom_destroy(eegg); GEOSGeom_destroy(edgegg); _lwt_release_edges(edges, num_edges); @@ -883,9 +892,10 @@ _lwt_CheckEdgeCrossing( LWT_TOPOLOGY* topo, match = GEOSRelatePatternMatch(relate, "***T*****"); if ( match ) { char locinfo[128] = ""; - const char *locsuffix = match == 2 ? "" - : _lwt_describe_intersection_point(edgegg, eegg, locinfo, sizeof(locinfo)) ? locinfo - : ""; + const char *locsuffix = match == 2 ? "" + : _lwt_describe_intersection_point(edgegg, eegg, locinfo, sizeof(locinfo)) + ? locinfo + : ""; GEOSGeom_destroy(eegg); GEOSGeom_destroy(edgegg); _lwt_release_edges(edges, num_edges); diff --git a/topology/test/regress/st_addedgemodface_expected b/topology/test/regress/st_addedgemodface_expected index d55e6ce19..29aef17ce 100644 --- a/topology/test/regress/st_addedgemodface_expected +++ b/topology/test/regress/st_addedgemodface_expected @@ -8,7 +8,7 @@ ERROR: SQL/MM Spatial exception - curve not simple ERROR: Invalid edge (no two distinct vertices exist) ERROR: Invalid edge (no two distinct vertices exist) ERROR: SQL/MM Spatial exception - coincident edge 8 at POINT(35 22) -ERROR: SQL/MM Spatial exception - geometry crosses edge 5 at POINT(48.0714285714286 41.9285714285714) +ERROR: SQL/MM Spatial exception - geometry crosses edge 5 at POINT(57 33) ERROR: SQL/MM Spatial exception - geometry crosses edge 4 at POINT(45 32) ERROR: Spatial exception - geometry intersects edge 4 at POINT(36 38) L1 diff --git a/topology/test/regress/st_addedgenewfaces_expected b/topology/test/regress/st_addedgenewfaces_expected index bb2a7a572..df23f1044 100644 --- a/topology/test/regress/st_addedgenewfaces_expected +++ b/topology/test/regress/st_addedgenewfaces_expected @@ -8,7 +8,7 @@ ERROR: SQL/MM Spatial exception - curve not simple ERROR: Invalid edge (no two distinct vertices exist) ERROR: Invalid edge (no two distinct vertices exist) ERROR: SQL/MM Spatial exception - coincident edge 8 at POINT(35 22) -ERROR: SQL/MM Spatial exception - geometry crosses edge 5 at POINT(48.0714285714286 41.9285714285714) +ERROR: SQL/MM Spatial exception - geometry crosses edge 5 at POINT(57 33) ERROR: SQL/MM Spatial exception - geometry crosses edge 4 at POINT(45 32) ERROR: Spatial exception - geometry intersects edge 4 at POINT(36 38) L1 diff --git a/utils/Makefile.in b/utils/Makefile.in index 329bbd3b1..090bbedfd 100644 --- a/utils/Makefile.in +++ b/utils/Makefile.in @@ -68,7 +68,7 @@ $(top_builddir)/sfcgal/uninstall_sfcgal.sql: $(top_builddir)/raster/rt_pg/uninstall_rtpostgis.sql: $(MAKE) -C ../raster/rt_pg uninstall_rtpostgis.sql -$(top_builddir)/raster/rt_pg/rtpostgis_upgrade.sql: +$(top_builddir)/raster/rt_pg/rtpostgis_upgrade.sql: $(top_builddir)/raster/rt_pg/uninstall_rtpostgis.sql $(MAKE) -C ../raster/rt_pg rtpostgis_upgrade.sql $(top_builddir)/topology/topology_upgrade.sql: ----------------------------------------------------------------------- Summary of changes: liblwgeom/topo/lwgeom_topo.c | 78 +++++++++++++---------- topology/test/regress/st_addedgemodface_expected | 2 +- topology/test/regress/st_addedgenewfaces_expected | 2 +- utils/Makefile.in | 2 +- 4 files changed, 47 insertions(+), 37 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Mar 5 09:34:45 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 5 Mar 2026 09:34:45 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-355-g04b9a7cb3 Message-ID: <20260305173445.EC76018E698@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 04b9a7cb3a17edde9291944ad0d0e1ab1398d568 (commit) from 1636202258b8e3aa41784b57191400c7d4509f08 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 04b9a7cb3a17edde9291944ad0d0e1ab1398d568 Author: Darafei Praliaskouski Date: Thu Mar 5 21:33:14 2026 +0400 Fix legacy symbol bindings for mingw clang CI diff --git a/postgis/legacy.sql.in b/postgis/legacy.sql.in index 9c90a154a..d67a7f00f 100644 --- a/postgis/legacy.sql.in +++ b/postgis/legacy.sql.in @@ -96,8 +96,8 @@ CREATE OR REPLACE FUNCTION SE_M(geometry) -- PostGIS equivalent function: locate_between_measures(geometry, float8, float8) CREATE OR REPLACE FUNCTION SE_LocateBetween(geometry, float8, float8) RETURNS geometry - AS 'MODULE_PATHNAME', 'LWGEOM_locate_between_m' - LANGUAGE 'c' IMMUTABLE STRICT; + AS $$ SELECT ST_LocateBetween($1, $2, $3, 0.0) $$ + LANGUAGE 'sql' IMMUTABLE STRICT; -- PostGIS equivalent function: locate_along_measure(geometry, float8) CREATE OR REPLACE FUNCTION SE_LocateAlong(geometry, float8) @@ -1248,8 +1248,8 @@ CREATE OR REPLACE FUNCTION LinestringFromWKB(bytea) -- Deprecation in 1.2.3 CREATE OR REPLACE FUNCTION locate_between_measures(geometry, float8, float8) RETURNS geometry - AS 'MODULE_PATHNAME', 'LWGEOM_locate_between_m' - LANGUAGE 'c' IMMUTABLE STRICT; + AS $$ SELECT ST_LocateBetween($1, $2, $3, 0.0) $$ + LANGUAGE 'sql' IMMUTABLE STRICT; -- Deprecation in 1.2.3 CREATE OR REPLACE FUNCTION M(geometry) diff --git a/postgis/lwgeom_geos.c b/postgis/lwgeom_geos.c index 989faabf7..9b1ef3e0f 100644 --- a/postgis/lwgeom_geos.c +++ b/postgis/lwgeom_geos.c @@ -741,17 +741,6 @@ Datum ST_Union(PG_FUNCTION_ARGS) PG_RETURN_POINTER(result); } -/* This is retained for backward ABI compatibility - * with PostGIS < 3.1.0 */ -PG_FUNCTION_INFO_V1(symdifference); -Datum symdifference(PG_FUNCTION_ARGS) -{ - PG_RETURN_DATUM(DirectFunctionCall2( - ST_SymDifference, - PG_GETARG_DATUM(0), PG_GETARG_DATUM(1) - )); -} - /** * @example symdifference {@link #symdifference} - SELECT ST_SymDifference( * 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))', diff --git a/postgis/postgis_legacy.c b/postgis/postgis_legacy.c index 5a250c716..0856c5ba0 100644 --- a/postgis/postgis_legacy.c +++ b/postgis/postgis_legacy.c @@ -101,6 +101,7 @@ POSTGIS_DEPRECATE("3.1.0", postgis_sfcgal_noop) POSTGIS_DEPRECATE("3.1.0", LWGEOM_locate_between_m) POSTGIS_DEPRECATE("3.1.0", postgis_svn_version) +POSTGIS_DEPRECATE("3.1.0", symdifference) POSTGIS_DEPRECATE("3.3.0", pgis_geometry_union_finalfn) /**START: Removal of transactin lock feature **/ ----------------------------------------------------------------------- Summary of changes: postgis/legacy.sql.in | 8 ++++---- postgis/lwgeom_geos.c | 11 ----------- postgis/postgis_legacy.c | 1 + 3 files changed, 5 insertions(+), 15 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Mar 5 10:19:42 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 5 Mar 2026 10:19:42 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-356-g8a31ce8c6 Message-ID: <20260305181943.147C518E92D@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 8a31ce8c686766caacde19e8fa5977ed49a4068e (commit) from 04b9a7cb3a17edde9291944ad0d0e1ab1398d568 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8a31ce8c686766caacde19e8fa5977ed49a4068e Author: Darafei Praliaskouski Date: Thu Mar 5 22:18:25 2026 +0400 Fix mingw clang redeclaration errors in gserialized_estimate diff --git a/postgis/gserialized_estimate.c b/postgis/gserialized_estimate.c index 7f5e6d89c..15791f382 100644 --- a/postgis/gserialized_estimate.c +++ b/postgis/gserialized_estimate.c @@ -124,12 +124,9 @@ dimensionality cases. (2D geometry) &&& (3D column), etc. /************************************************************************/ - /* Prototypes */ -Datum gserialized_gist_joinsel(PG_FUNCTION_ARGS); Datum gserialized_gist_joinsel_2d(PG_FUNCTION_ARGS); Datum gserialized_gist_joinsel_nd(PG_FUNCTION_ARGS); -Datum gserialized_gist_sel(PG_FUNCTION_ARGS); Datum gserialized_gist_sel_2d(PG_FUNCTION_ARGS); Datum gserialized_gist_sel_nd(PG_FUNCTION_ARGS); Datum gserialized_analyze_nd(PG_FUNCTION_ARGS); @@ -1087,36 +1084,6 @@ estimate_join_selectivity(const ND_STATS *s1, const ND_STATS *s2) return selectivity; } -/** -* For (geometry &&& geometry) and (geography && geography) -* we call into the N-D mode. -*/ -PG_FUNCTION_INFO_V1(gserialized_gist_joinsel_nd); -Datum gserialized_gist_joinsel_nd(PG_FUNCTION_ARGS) -{ - PG_RETURN_DATUM(DirectFunctionCall5( - gserialized_gist_joinsel, - PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), - PG_GETARG_DATUM(2), PG_GETARG_DATUM(3), - Int32GetDatum(0) /* ND mode */ - )); -} - -/** -* For (geometry && geometry) -* we call into the 2-D mode. -*/ -PG_FUNCTION_INFO_V1(gserialized_gist_joinsel_2d); -Datum gserialized_gist_joinsel_2d(PG_FUNCTION_ARGS) -{ - PG_RETURN_DATUM(DirectFunctionCall5( - gserialized_gist_joinsel, - PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), - PG_GETARG_DATUM(2), PG_GETARG_DATUM(3), - Int32GetDatum(2) /* 2D mode */ - )); -} - double gserialized_joinsel_internal(PlannerInfo *root, List *args, JoinType jointype, int mode) { @@ -1201,6 +1168,40 @@ Datum gserialized_gist_joinsel(PG_FUNCTION_ARGS) PG_RETURN_FLOAT8(gserialized_joinsel_internal(root, args, jointype, mode)); } +/** + * For (geometry &&& geometry) and (geography && geography) + * we call into the N-D mode. + */ +PG_FUNCTION_INFO_V1(gserialized_gist_joinsel_nd); +Datum +gserialized_gist_joinsel_nd(PG_FUNCTION_ARGS) +{ + PG_RETURN_DATUM(DirectFunctionCall5(gserialized_gist_joinsel, + PG_GETARG_DATUM(0), + PG_GETARG_DATUM(1), + PG_GETARG_DATUM(2), + PG_GETARG_DATUM(3), + Int32GetDatum(0) /* ND mode */ + )); +} + +/** + * For (geometry && geometry) + * we call into the 2-D mode. + */ +PG_FUNCTION_INFO_V1(gserialized_gist_joinsel_2d); +Datum +gserialized_gist_joinsel_2d(PG_FUNCTION_ARGS) +{ + PG_RETURN_DATUM(DirectFunctionCall5(gserialized_gist_joinsel, + PG_GETARG_DATUM(0), + PG_GETARG_DATUM(1), + PG_GETARG_DATUM(2), + PG_GETARG_DATUM(3), + Int32GetDatum(2) /* 2D mode */ + )); +} + /** * The gserialized_analyze_nd sets this function as a * callback on the stats object when called by the ANALYZE @@ -2017,37 +2018,6 @@ Datum _postgis_gserialized_joinsel(PG_FUNCTION_ARGS) PG_RETURN_FLOAT8(selectivity); } -/** -* For (geometry && geometry) -* we call into the 2-D mode. -*/ -PG_FUNCTION_INFO_V1(gserialized_gist_sel_2d); -Datum gserialized_gist_sel_2d(PG_FUNCTION_ARGS) -{ - PG_RETURN_DATUM(DirectFunctionCall5( - gserialized_gist_sel, - PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), - PG_GETARG_DATUM(2), PG_GETARG_DATUM(3), - Int32GetDatum(2) /* 2-D mode */ - )); -} - -/** -* For (geometry &&& geometry) and (geography && geography) -* we call into the N-D mode. -*/ -PG_FUNCTION_INFO_V1(gserialized_gist_sel_nd); -Datum gserialized_gist_sel_nd(PG_FUNCTION_ARGS) -{ - PG_RETURN_DATUM(DirectFunctionCall5( - gserialized_gist_sel, - PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), - PG_GETARG_DATUM(2), PG_GETARG_DATUM(3), - Int32GetDatum(0) /* N-D mode */ - )); -} - - /** * This function should return an estimation of the number of * rows returned by a query involving an overlap check @@ -2132,6 +2102,40 @@ Datum gserialized_gist_sel(PG_FUNCTION_ARGS) PG_RETURN_FLOAT8(selectivity); } +/** + * For (geometry && geometry) + * we call into the 2-D mode. + */ +PG_FUNCTION_INFO_V1(gserialized_gist_sel_2d); +Datum +gserialized_gist_sel_2d(PG_FUNCTION_ARGS) +{ + PG_RETURN_DATUM(DirectFunctionCall5(gserialized_gist_sel, + PG_GETARG_DATUM(0), + PG_GETARG_DATUM(1), + PG_GETARG_DATUM(2), + PG_GETARG_DATUM(3), + Int32GetDatum(2) /* 2-D mode */ + )); +} + +/** + * For (geometry &&& geometry) and (geography && geography) + * we call into the N-D mode. + */ +PG_FUNCTION_INFO_V1(gserialized_gist_sel_nd); +Datum +gserialized_gist_sel_nd(PG_FUNCTION_ARGS) +{ + PG_RETURN_DATUM(DirectFunctionCall5(gserialized_gist_sel, + PG_GETARG_DATUM(0), + PG_GETARG_DATUM(1), + PG_GETARG_DATUM(2), + PG_GETARG_DATUM(3), + Int32GetDatum(0) /* N-D mode */ + )); +} + /************************************************************************/ ----------------------------------------------------------------------- Summary of changes: postgis/gserialized_estimate.c | 132 +++++++++++++++++++++-------------------- 1 file changed, 68 insertions(+), 64 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Mar 5 10:49:29 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 5 Mar 2026 10:49:29 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-358-g7dfe8b69c Message-ID: <20260305184929.540F218F4B5@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 7dfe8b69cde8c683251c9e104d71f3d42e3d5552 (commit) via bd152a4bccf1c134b11b0e60c1a50e071b911a6c (commit) from 8a31ce8c686766caacde19e8fa5977ed49a4068e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7dfe8b69cde8c683251c9e104d71f3d42e3d5552 Author: Darafei Praliaskouski Date: Thu Mar 5 22:49:08 2026 +0400 Stabilize Windows CI checks for spelling and CUnit diff --git a/.codespellrc b/.codespellrc index daf57c70c..016dfb022 100644 --- a/.codespellrc +++ b/.codespellrc @@ -1,3 +1,3 @@ [codespell] -skip = *.sql,*.po,spatial_ref_sys.sql,./deps,./extras/tiger_geocoder/tables/lookup_tables_2011.sql,./extras/tiger_geocoder/pagc_normalize/pagc_tables.sql,./extensions/address_standardizer,./configure*,./macros/*.m4,./autom4te.cache,./build-aux,./libtool,./extensions/postgis_tiger_geocoder/*.in,.git,build* +skip = *.po,spatial_ref_sys.sql,./deps,./extensions/address_standardizer,./configure*,./autom4te.cache,./build-aux,./libtool,.git,build* ignore-words = .codespell.ignore diff --git a/.github/workflows/msys.yml b/.github/workflows/msys.yml index 4b6321dcc..358775b51 100644 --- a/.github/workflows/msys.yml +++ b/.github/workflows/msys.yml @@ -40,6 +40,7 @@ jobs: gdal:p sfcgal:p json-c:p + cunit:p gettext:p libxml2:p postgresql:p diff --git a/extensions/address_standardizer/std_pg_hash.c b/extensions/address_standardizer/std_pg_hash.c index 63f490415..4717f4ded 100644 --- a/extensions/address_standardizer/std_pg_hash.c +++ b/extensions/address_standardizer/std_pg_hash.c @@ -369,8 +369,7 @@ AddToStdPortalCache(StdPortalCache *STDCache, char *lextab, char *gaztab, char * DBG("STDCache->NextSlot=%d", STDCache->NextSlot); } - -/* pubilc api */ +/* public api */ StdCache GetStdCache(FunctionCallInfo fcinfo) { return (StdCache) GetStdPortalCache(fcinfo); diff --git a/loader/cunit/Makefile.in b/loader/cunit/Makefile.in index ab9e8d791..e5ee4df2f 100644 --- a/loader/cunit/Makefile.in +++ b/loader/cunit/Makefile.in @@ -20,7 +20,8 @@ CFLAGS=@CFLAGS@ SHELL = @SHELL@ LIBTOOL = @LIBTOOL@ -CUNIT_LDFLAGS=@CUNIT_LDFLAGS@ @GEOS_LDFLAGS@ +CUNIT_LDFLAGS=@CUNIT_LDFLAGS@ +GEOS_LDFLAGS=@GEOS_LDFLAGS@ CUNIT_CPPFLAGS = \ -I$(srcdir)/.. \ -I$(top_builddir)/liblwgeom \ commit bd152a4bccf1c134b11b0e60c1a50e071b911a6c Author: Darafei Praliaskouski Date: Thu Mar 5 22:21:28 2026 +0400 Fix codespell typo in shp2pgsql header comment diff --git a/loader/shp2pgsql-core.h b/loader/shp2pgsql-core.h index 905f92253..748d4773a 100644 --- a/loader/shp2pgsql-core.h +++ b/loader/shp2pgsql-core.h @@ -192,7 +192,7 @@ typedef struct shp_loader_state /* Pointer to an array of PostgreSQL field types */ char **pgfieldtypes; - /* String containing colume name list in the form "col1, col2, col3 ... , colN" */ + /* String containing column name list in the form "col1, col2, col3 ... , colN" */ char *col_names; /* String containing the PostGIS geometry type, e.g. POINT, POLYGON etc. */ ----------------------------------------------------------------------- Summary of changes: .codespellrc | 2 +- .github/workflows/msys.yml | 1 + extensions/address_standardizer/std_pg_hash.c | 3 +-- loader/cunit/Makefile.in | 3 ++- loader/shp2pgsql-core.h | 2 +- 5 files changed, 6 insertions(+), 5 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Mar 5 11:39:04 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 5 Mar 2026 11:39:04 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-359-geabe42d06 Message-ID: <20260305193904.C9A3318FBCD@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via eabe42d06e572fedfd6684c1be542e41097e5bc2 (commit) from 7dfe8b69cde8c683251c9e104d71f3d42e3d5552 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit eabe42d06e572fedfd6684c1be542e41097e5bc2 Author: Darafei Praliaskouski Date: Thu Mar 5 23:37:21 2026 +0400 msys: use Windows tmpdir and print regression diffs diff --git a/.github/workflows/msys.yml b/.github/workflows/msys.yml index 358775b51..4ae3f6abc 100644 --- a/.github/workflows/msys.yml +++ b/.github/workflows/msys.yml @@ -54,4 +54,14 @@ jobs: MSYSTEM= ./autogen.sh MSYSTEM= ./configure --with-pgconfig=/${{ matrix.sys }}/bin/pg_config --without-protobuf MSYSTEM= make - MSYSTEM= make check + MSYSTEM= PGIS_REG_TMPDIR=D:/a/_tmp/pgis_reg make check || { + status=$? + echo "::group::Regression diffs" + for f in /d/a/_tmp/pgis_reg/test_*_diff; do + [ -f "$f" ] || continue + echo "===== $f =====" + sed -n '1,400p' "$f" + done + echo "::endgroup::" + exit "$status" + } ----------------------------------------------------------------------- Summary of changes: .github/workflows/msys.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) hooks/post-receive -- PostGIS From git at osgeo.org Fri Mar 6 01:08:41 2026 From: git at osgeo.org (git at osgeo.org) Date: Fri, 6 Mar 2026 01:08:41 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-360-g8b07652d0 Message-ID: <20260306090842.5D428191823@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 8b07652d087b33fc347ee243b7af998fa58ab4a3 (commit) from eabe42d06e572fedfd6684c1be542e41097e5bc2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8b07652d087b33fc347ee243b7af998fa58ab4a3 Author: Darafei Praliaskouski Date: Fri Mar 6 00:00:02 2026 +0400 regress: stabilize topology output across architectures Break tied topology edge, node, and edge-end selections deterministically so regressions no longer depend on platform-specific ordering. Refresh alphashape_components expected output to match current SFCGAL behavior. diff --git a/liblwgeom/topo/lwgeom_topo.c b/liblwgeom/topo/lwgeom_topo.c index ba42f592c..054c2b21c 100644 --- a/liblwgeom/topo/lwgeom_topo.c +++ b/liblwgeom/topo/lwgeom_topo.c @@ -5193,22 +5193,48 @@ _lwt_minTolerance( LWGEOM *g ) #define _LWT_MINTOLERANCE( topo, geom ) ( \ topo->precision ? topo->precision : _lwt_minTolerance(geom) ) -typedef struct scored_pointer_t { - void *ptr; - double score; -} scored_pointer; +typedef struct scored_node_t { + LWT_ISO_NODE *node; + double score; +} scored_node; static int -compare_scored_pointer(const void *si1, const void *si2) +compare_scored_node(const void *si1, const void *si2) { - double a = ((scored_pointer *)si1)->score; - double b = ((scored_pointer *)si2)->score; - if ( a < b ) - return -1; - else if ( a > b ) - return 1; - else - return 0; + const scored_node *a = si1; + const scored_node *b = si2; + if (a->score < b->score) + return -1; + else if (a->score > b->score) + return 1; + else if (a->node->node_id < b->node->node_id) + return -1; + else if (a->node->node_id > b->node->node_id) + return 1; + else + return 0; +} + +typedef struct scored_edge_t { + LWT_ISO_EDGE *edge; + double score; +} scored_edge; + +static int +compare_scored_edge(const void *si1, const void *si2) +{ + const scored_edge *a = si1; + const scored_edge *b = si2; + if (a->score < b->score) + return -1; + else if (a->score > b->score) + return 1; + else if (a->edge->edge_id < b->edge->edge_id) + return -1; + else if (a->edge->edge_id > b->edge->edge_id) + return 1; + else + return 0; } /* Return identifier of an equal edge, 0 if none or -1 on error @@ -6646,7 +6672,7 @@ static LWT_ELEMID _lwt_SplitAllEdgesToNewNode(LWT_TOPOLOGY* topo, LWT_ISO_EDGE *edges, uint64_t num, LWPOINT *point, double tol, int *moved) { uint64_t i, j; - scored_pointer *sorted = lwalloc(sizeof(scored_pointer)*num); + scored_edge *sorted = lwalloc(sizeof(scored_edge) * num); LWT_ISO_EDGE *edges2 = NULL; LWT_ISO_NODE node; node.node_id = 0; /* unneeded, but hushes a compiler warning */ @@ -6663,7 +6689,7 @@ _lwt_SplitAllEdgesToNewNode(LWT_TOPOLOGY* topo, LWT_ISO_EDGE *edges, uint64_t nu dist = lwgeom_mindistance2d(lwline_as_lwgeom(edges[i].geom), lwpoint_as_lwgeom(point)); LWDEBUGF(1, "Edge %" LWTFMT_ELEMID " distance: %.15g", e->edge_id, dist); if ( dist >= tol ) continue; - sorted[j].ptr = e; + sorted[j].edge = e; sorted[j++].score = dist; } if ( ! j ) @@ -6673,18 +6699,18 @@ _lwt_SplitAllEdgesToNewNode(LWT_TOPOLOGY* topo, LWT_ISO_EDGE *edges, uint64_t nu } num = j; - qsort(sorted, num, sizeof(scored_pointer), compare_scored_pointer); + qsort(sorted, num, sizeof(scored_edge), compare_scored_edge); edges2 = lwalloc(sizeof(LWT_ISO_EDGE)*num); for (j=0, i=0; igeom); + edges2[j++] = *sorted[i].edge; + // lwline_free(sorted[i].edge->geom); } } num = j; @@ -6890,7 +6916,7 @@ _lwt_AddPoint(LWT_TOPOLOGY* topo, LWPOINT* point, double tol, int LWT_ISO_NODE *nodes, *nodes2; LWT_ISO_EDGE *edges; LWGEOM *pt = lwpoint_as_lwgeom(point); - scored_pointer *sorted; + scored_node *sorted; int flds; LWT_ELEMID id = 0; @@ -6921,20 +6947,20 @@ _lwt_AddPoint(LWT_TOPOLOGY* topo, LWPOINT* point, double tol, int /* Order by distance if there are more than a single return */ if ( num > 1 ) {{ - sorted = lwalloc(sizeof(scored_pointer)*num); - for (i=0; inode_id, sorted[i].score); - } - qsort(sorted, num, sizeof(scored_pointer), compare_scored_pointer); - nodes2 = lwalloc(sizeof(LWT_ISO_NODE)*num); - for (i=0; inode_id, sorted[i].score); + } + qsort(sorted, num, sizeof(scored_node), compare_scored_node); + nodes2 = lwalloc(sizeof(LWT_ISO_NODE) * num); + for (i = 0; i < num; ++i) + { + nodes2[i] = *sorted[i].node; + } lwfree(sorted); lwfree(nodes); nodes = nodes2; diff --git a/liblwgeom/topo/lwt_edgeend_star.c b/liblwgeom/topo/lwt_edgeend_star.c index 600e7b6da..a9a0e7acb 100644 --- a/liblwgeom/topo/lwt_edgeend_star.c +++ b/liblwgeom/topo/lwt_edgeend_star.c @@ -135,6 +135,14 @@ lwt_edgeEnd_compare(const void *i1, const void *i2) ret = -1; else if ( ee1->azimuth > ee2->azimuth ) ret = 1; + else if (ee1->edge->edge_id < ee2->edge->edge_id) + ret = -1; + else if (ee1->edge->edge_id > ee2->edge->edge_id) + ret = 1; + else if (ee1->outgoing < ee2->outgoing) + ret = -1; + else if (ee1->outgoing > ee2->outgoing) + ret = 1; else ret = 0; diff --git a/regress/run_test.pl b/regress/run_test.pl index bf7386bbe..40fcce21e 100755 --- a/regress/run_test.pl +++ b/regress/run_test.pl @@ -524,7 +524,6 @@ print " GDAL: $gdalver\n" if $gdalver; # allow hook scripts to perform arbitrary reports via output of INFO strings system("grep INFO $REGRESS_LOG | sed 's/INFO://'"); - ################################################################## # Run the tests ################################################################## diff --git a/sfcgal/regress/alphashape_components_expected b/sfcgal/regress/alphashape_components_expected index a30a4ad59..022ef1221 100644 --- a/sfcgal/regress/alphashape_components_expected +++ b/sfcgal/regress/alphashape_components_expected @@ -1,2 +1,2 @@ -CG_Optimalalphashape_2components|MULTIPOLYGON(((8.3 11.8,6.2 12.1,4.1 11.9,2.6 11.2,1.1 10.1,0.3 8.2,0.1 6.1,0.4 4,1.2 2.3,2.5 1,4.2 0.3,6 0,8.1 0.1,10.1 0.2,9.2 2.4,7.8 2.2,6 2.3,3.6 6.2,7.6 9.8,9.1 9.9,10.2 11.1,8.3 11.8)),((55.6 12.1,55.8 15,54.3 15.2,52.9 10.6,52.7 7.3,52.8 4.1,46.9 2.8,43.3 7.1,43.1 10.4,43.1 15.3,41.9 15.6,40.5 15.2,40.2 12.3,40.4 9,39.8 6.2,40.1 3.1,40.3 0.4,42.1 0.3,44.2 0.2,49.8 -0.2,52.6 0.1,55.4 0.5,55.7 3.3,55.5 6,55.9 9.2,55.6 12.1))) -CG_OptimalAlphaShape_hole_2components|MULTIPOLYGON(((5.5 8.5,5 9,4.5 9.5,4 10,3 10,2 10,1 10,0.5 10,0.23 10,0.03 9.82,0 9,0 8,0 7,0 6,0 5,0 4,0 3,0 2,0 1,0 0,0.5 0,1 0,2 0,3 0,4 0,5 0,5.5 0.5,6 1,6 2,5.8 2.5,5.5 3,5 3.5,4.5 4,4 4.5,5 5,5.5 5.5,6 6,6 7,6 8,5.5 8.5),(0.5 2,0.5 3,1 4,2 4,3 4,4 4,4.5 3.5,5 3,5.1 2.5,5.5 2,5.5 1,5 0.5,4 0.5,3 0.5,2 0.5,1 0.5,0.5 1,0.5 2),(0.5 7,0.5 8,0.5 9,1 9.5,2 9.5,3 9.5,4 9.5,4.5 9,5 8.5,5.5 8,5.5 7,5.5 6.5,5.5 6,5 5.5,4 5.5,3 5.5,2 5.5,1 5.5,0.5 6,0.5 7)),((17.5 8.5,17 9,16.5 9.5,16 10,15 10,14 10,13 10,12.5 10,12 10,12 9,12 8,12 7,12 6,12 5,12 4,12 3,12 2,12 1,12 0,12.5 0,13 1,13 2,13 3,13 4,13 5,14 5,15 5,16 5,17 5,17.5 5.5,18 6,18 7,18 7.3,18 8,17.5 8.5),(12.5 7,12.5 8,12.5 9,13 9.5,14 9.5,15 9.5,16 9.5,16.5 9,17 8.5,17.5 8,17.5 7.4,17.5 7,17.5 6.5,17.5 6,17 5.5,16 5.5,15 5.5,14 5.5,13 5.5,12.5 6,12.5 7))) +CG_Optimalalphashape_2components|POLYGON((0.1 6.1,0.3 8.2,1.1 10.1,2.6 11.2,4.1 11.9,6.2 12.1,8.3 11.8,10.2 11.1,9.1 9.9,7.6 9.8,3.6 6.2,6 2.3,7.8 2.2,9.2 2.4,10.1 0.2,8.1 0.1,6 0,4.2 0.3,2.5 1,1.2 2.3,0.4 4,55.6 12.1,55.9 9.2,55.5 6,55.7 3.3,55.4 0.5,52.6 0.1,49.8 -0.2,44.2 0.2,42.1 0.3,40.3 0.4,40.1 3.1,39.8 6.2,40.4 9,40.2 12.3,40.5 15.2,41.9 15.6,43.1 15.3,43.1 10.4,43.3 7.1,46.9 2.8,52.8 4.1,52.7 7.3,52.9 10.6,54.3 15.2,55.8 15,0.1 6.1)) +CG_OptimalAlphaShape_hole_2components|POLYGON((0 0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0 8,0 9,0.03 9.82,0.23 10,0.5 10,1 10,2 10,3 10,4 10,4.5 9.5,5 9,5.5 8.5,6 8,6 7,6 6,5.5 5.5,5 5,4 4.5,4.5 4,5 3.5,5.5 3,5.8 2.5,6 2,6 1,5.5 0.5,5 0,4 0,3 0,2 0,1 0,0.5 0,12 0,12 1,12 2,12 3,12 4,12 5,12 6,12 7,12 8,12 9,12 10,12.5 10,13 10,14 10,15 10,16 10,16.5 9.5,17 9,17.5 8.5,18 8,18 7.3,18 7,18 6,17.5 5.5,17 5,16 5,15 5,14 5,13 5,13 4,13 3,13 2,13 1,12.5 0,0 0),(0.5 1,0.5 2,0.5 3,1 4,2 4,3 4,4 4,4.5 3.5,5 3,5.1 2.5,5.5 2,5.5 1,5 0.5,4 0.5,3 0.5,2 0.5,1 0.5,0.5 6,0.5 7,0.5 8,0.5 9,1 9.5,2 9.5,3 9.5,4 9.5,4.5 9,5 8.5,5.5 8,5.5 7,5.5 6.5,5.5 6,5 5.5,4 5.5,3 5.5,2 5.5,1 5.5,0.5 1),(12.5 6,12.5 7,12.5 8,12.5 9,13 9.5,14 9.5,15 9.5,16 9.5,16.5 9,17 8.5,17.5 8,17.5 7.4,17.5 7,17.5 6.5,17.5 6,17 5.5,16 5.5,15 5.5,14 5.5,13 5.5,12.5 6)) diff --git a/topology/postgis_topology.c b/topology/postgis_topology.c index f6bd71a5c..7707ece2b 100644 --- a/topology/postgis_topology.c +++ b/topology/postgis_topology.c @@ -3048,7 +3048,11 @@ cb_getClosestEdge( const LWT_BE_TOPOLOGY* topo, const LWPOINT* pt, uint64_t *num appendStringInfoString(sql, "SELECT "); addEdgeFields(sql, fields, 0); - appendStringInfo(sql, " FROM \"%s\".edge_data ORDER BY geom <-> $1 ASC LIMIT 1", topo->name); + appendStringInfo(sql, + " FROM \"%s\".edge_data" + " ORDER BY geom <-> $1 ASC, edge_id ASC" + " LIMIT 1", + topo->name); POSTGIS_DEBUGF(1, "cb_getClosestEdge query: %s", sql->data); ----------------------------------------------------------------------- Summary of changes: liblwgeom/topo/lwgeom_topo.c | 94 +++++++++++++++++---------- liblwgeom/topo/lwt_edgeend_star.c | 8 +++ regress/run_test.pl | 1 - sfcgal/regress/alphashape_components_expected | 4 +- topology/postgis_topology.c | 6 +- 5 files changed, 75 insertions(+), 38 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Fri Mar 6 01:18:58 2026 From: git at osgeo.org (git at osgeo.org) Date: Fri, 6 Mar 2026 01:18:58 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-361-g99af6dc68 Message-ID: <20260306091859.076EC191B36@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 99af6dc68c1085547e6cc8158178de20f982191c (commit) from 8b07652d087b33fc347ee243b7af998fa58ab4a3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 99af6dc68c1085547e6cc8158178de20f982191c Author: Darafei Praliaskouski Date: Fri Mar 6 13:16:51 2026 +0400 regress: stabilize parser locations in core SQL tests diff --git a/regress/core/bestsrid.sql b/regress/core/bestsrid.sql index 2437a4d02..4745e808f 100644 --- a/regress/core/bestsrid.sql +++ b/regress/core/bestsrid.sql @@ -26,6 +26,6 @@ select 'world', _ST_BestSRID(ST_Point(-160, -40), ST_Point(160, 40)); -- infinite coords SELECT _ST_BestSRID(ST_Point('-infinity', 'infinity')); -SELECT '#5347', ST_Intersection('0102000020E610000005000000000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F'::geography, - '0101000020E6100000000000000000F07F000000000000F07F'::geography); - +-- Keep this statement on one line so parser notice locations stay stable +-- across LF and CRLF platforms. +SELECT '#5347', ST_Intersection('0102000020E610000005000000000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F000000000000F07F'::geography, '0101000020E6100000000000000000F07F000000000000F07F'::geography); diff --git a/regress/core/bestsrid_expected b/regress/core/bestsrid_expected index 3947d96ec..ecc32b2a9 100644 --- a/regress/core/bestsrid_expected +++ b/regress/core/bestsrid_expected @@ -128,5 +128,5 @@ world|999000 NOTICE: Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY ERROR: Error in geography_bestsrid calling with infinite coordinate geographies NOTICE: Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY at character 33 -NOTICE: Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY at character 257 +NOTICE: Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY at character 234 ERROR: Error in geography_bestsrid calling with infinite coordinate geographies diff --git a/regress/core/dumpsegments.sql b/regress/core/dumpsegments.sql index 8dd838912..566adb095 100644 --- a/regress/core/dumpsegments.sql +++ b/regress/core/dumpsegments.sql @@ -98,15 +98,13 @@ FROM st_dumpsegments( ))' ); +-- Keep this statement on one line so parser notice locations stay stable +-- across LF and CRLF platforms. -- Check dumping a degenerate (even number of points) circular string -SELECT 'dumpsegments15', path, st_astext(geom) -FROM st_dumpsegments( -'010800000006000000000000000000f03f000000000000f03f0000000000000040000000000000004000000000000008400000000000000840000000000000104000000000000010400000000000001440000000000000144000000000000018400000000000001840' -); +SELECT 'dumpsegments15', path, st_astext(geom) FROM st_dumpsegments('010800000006000000000000000000f03f000000000000f03f0000000000000040000000000000004000000000000008400000000000000840000000000000104000000000000010400000000000001440000000000000144000000000000018400000000000001840'); +-- Keep this statement on one line so parser notice locations stay stable +-- across LF and CRLF platforms. -- Check dumping a compound that contains a degenerate circular -- string -SELECT 'dumpsegments16', path, st_astext(geom) -FROM st_dumpsegments( -'010900000002000000010200000007000000000000000000f03f000000000000f03f00000000000000400000000000000040000000000000084000000000000008400000000000001040000000000000104000000000000014400000000000001440000000000000184000000000000018400000000000001c400000000000001c400108000000060000000000000000001c400000000000001c400000000000001840000000000000184000000000000014400000000000001440000000000000104000000000000010400000000000000840000000000000084000000000000000400000000000000040' -); +SELECT 'dumpsegments16', path, st_astext(geom) FROM st_dumpsegments('010900000002000000010200000007000000000000000000f03f000000000000f03f00000000000000400000000000000040000000000000084000000000000008400000000000001040000000000000104000000000000014400000000000001440000000000000184000000000000018400000000000001c400000000000001c400108000000060000000000000000001c400000000000001c400000000000001840000000000000184000000000000014400000000000001440000000000000104000000000000010400000000000000840000000000000084000000000000000400000000000000040'); diff --git a/regress/core/dumpsegments_expected b/regress/core/dumpsegments_expected index d08b9a948..6bc404677 100644 --- a/regress/core/dumpsegments_expected +++ b/regress/core/dumpsegments_expected @@ -70,10 +70,10 @@ dumpsegments14|{1,1,1,6}|LINESTRING(6 6,7 7) dumpsegments14|{1,1,2,1}|CIRCULARSTRING(7 7,6 6,5 5) dumpsegments14|{1,1,2,2}|CIRCULARSTRING(5 5,4 4,3 3) dumpsegments14|{1,1,2,3}|CIRCULARSTRING(3 3,2 2,1 1) -NOTICE: lwcircstring_construct: invalid point count 6 at character 70 +NOTICE: lwcircstring_construct: invalid point count 6 at character 69 dumpsegments15|{1}|CIRCULARSTRING(1 1,2 2,3 3) dumpsegments15|{2}|CIRCULARSTRING(3 3,4 4,5 5) -NOTICE: lwcircstring_construct: invalid point count 6 at character 70 +NOTICE: lwcircstring_construct: invalid point count 6 at character 69 dumpsegments16|{1,1}|LINESTRING(1 1,2 2) dumpsegments16|{1,2}|LINESTRING(2 2,3 3) dumpsegments16|{1,3}|LINESTRING(3 3,4 4) ----------------------------------------------------------------------- Summary of changes: regress/core/bestsrid.sql | 6 +++--- regress/core/bestsrid_expected | 2 +- regress/core/dumpsegments.sql | 14 ++++++-------- regress/core/dumpsegments_expected | 4 ++-- 4 files changed, 12 insertions(+), 14 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Fri Mar 6 01:56:18 2026 From: git at osgeo.org (git at osgeo.org) Date: Fri, 6 Mar 2026 01:56:18 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-362-g532c6ade2 Message-ID: <20260306095618.65CE4192328@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 532c6ade24ff41013541c56a995e401a4de14dbd (commit) from 99af6dc68c1085547e6cc8158178de20f982191c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 532c6ade24ff41013541c56a995e401a4de14dbd Author: Darafei Praliaskouski Date: Fri Mar 6 13:54:16 2026 +0400 sfcgal/tests: normalize alpha shape component output diff --git a/sfcgal/regress/alphashape_components.sql b/sfcgal/regress/alphashape_components.sql index 38e896ffd..3dcfa350c 100644 --- a/sfcgal/regress/alphashape_components.sql +++ b/sfcgal/regress/alphashape_components.sql @@ -1,4 +1,6 @@ +-- Normalize POLYGON vs MULTIPOLYGON output so this SFCGAL 2.3+ regression +-- checks the stable shape result rather than a raw return-type difference. SELECT 'CG_Optimalalphashape_2components', - ST_AsText(CG_OptimalAlphaShape('MULTIPOINT((10.1 0.2),(8.1 0.1),(6.0 0.0),(4.2 0.3),(2.5 1.0),(1.2 2.3),(0.4 4.0),(0.1 6.1),(0.3 8.2),(1.1 10.1),(2.6 11.2),(4.1 11.9),(6.2 12.1),(8.3 11.8),(10.2 11.1),(9.1 9.9),(7.6 9.8),(6.1 9.9),(4.8 9.2),(3.8 8.0),(3.6 6.2),(3.7 4.1),(4.6 2.9),(6.0 2.3),(7.8 2.2),(9.2 2.4),(40.3 0.4),(40.1 3.1),(39.8 6.2),(40.4 9.0),(40.2 12.3),(40.5 15.2),(41.9 15.6),(43.1 15.3),(54.3 15.2),(55.8 15.0),(55.6 12.1),(55.9 9.2),(55.5 6.0),(55.7 3.3),(55.4 0.5),(52.6 0.1),(49.8 -0.2),(46.9 2.8),(44.2 0.2),(42.1 0.3),(43.0 3.8),(43.3 7.1),(43.1 10.4),(52.9 10.6),(52.7 7.3),(52.8 4.1))', allow_holes => false, nb_components => 2)); + ST_AsText(ST_Normalize(ST_Multi(CG_OptimalAlphaShape('MULTIPOINT((10.1 0.2),(8.1 0.1),(6.0 0.0),(4.2 0.3),(2.5 1.0),(1.2 2.3),(0.4 4.0),(0.1 6.1),(0.3 8.2),(1.1 10.1),(2.6 11.2),(4.1 11.9),(6.2 12.1),(8.3 11.8),(10.2 11.1),(9.1 9.9),(7.6 9.8),(6.1 9.9),(4.8 9.2),(3.8 8.0),(3.6 6.2),(3.7 4.1),(4.6 2.9),(6.0 2.3),(7.8 2.2),(9.2 2.4),(40.3 0.4),(40.1 3.1),(39.8 6.2),(40.4 9.0),(40.2 12.3),(40.5 15.2),(41.9 15.6),(43.1 15.3),(54.3 15.2),(55.8 15.0),(55.6 12.1),(55.9 9.2),(55.5 6.0),(55.7 3.3),(55.4 0.5),(52.6 0.1),(49.8 -0.2),(46.9 2.8),(44.2 0.2),(42.1 0.3),(43.0 3.8),(43.3 7.1),(43.1 10.4),(52.9 10.6),(52.7 7.3),(52.8 4.1))', allow_holes => false, nb_components => 2)))); SELECT 'CG_OptimalAlphaShape_hole_2components', - ST_AsText(CG_OptimalAlphaShape('MULTIPOINT((0 0),(0 1),(0 2),(0 3),(0 4),(0 5),(0 6),(0 7),(0 8),(0 9),(1 10),(2 10),(3 10),(4 10),(4.5 9.5),(5 9),(5.5 8.5),(6 8),(6 7),(6 6),(5.5 5.5),(5 5),(4 5),(3 5),(2 5),(1 5),(1 4),(2 4),(3 4),(4 4),(4.5 3.5),(5 3),(6 2),(6 1),(5.5 0.5),(5 0),(4 0),(3 0),(2 0),(1 0),(0.5 0),(0.5 1),(0.5 2),(0.5 3),(0.5 4),(0.5 5),(0.5 6),(0.5 7),(0.5 8),(0.5 9),(0.5 10),(1 9.5),(2 9.5),(3 9.5),(4 9.5),(4.5 9),(5 8.5),(5.5 8),(5.5 7),(5.5 6),(5.5 6.5),(5 5.5),(4 5.5),(3 5.5),(2 5.5),(1 5.5),(1.5 4.5),(2.5 4.5),(3.5 4.5),(4 4.5),(4.5 4),(5 3.5),(5.5 3),(5.5 2),(5.5 1),(5 0.5),(4 0.5),(3 0.5),(2 0.5),(1 0.5),(12 0),(12 1),(12 2),(12 3),(12 4),(12 5),(12 6),(12 7),(12 8),(12 9),(12 10),(13 10),(14 10),(15 10),(16 10),(16.5 9.5),(17 9),(17.5 8.5),(18 8),(18 7),(18 6),(17.5 5.5),(17 5),(16 5),(15 5),(14 5),(13 5),(12.5 0),(12.5 1),(12.5 2),(12.5 3),(12.5 4),(12.5 5),(12.5 6),(12.5 7),(12.5 8),(12.5 9),(12.5 10),(13 9.5),(14 9.5),(15 9.5),(16 9.5),(16.5 9),(17 8.5),(17.5 8),(17.5 7),(17.5 6),(17.5 6.5),(17 5.5),(16 5.5),(15 5.5),(14 5.5),(13 5.5),(13 1),(13 2),(13 3),(13 4),(17.5 7.4),(18 7.3),(5.1 2.5),(5.8 2.5),(0.03 9.82),(0.23 10))', allow_holes => true, nb_components => 2)); + ST_AsText(ST_Normalize(ST_Multi(CG_OptimalAlphaShape('MULTIPOINT((0 0),(0 1),(0 2),(0 3),(0 4),(0 5),(0 6),(0 7),(0 8),(0 9),(1 10),(2 10),(3 10),(4 10),(4.5 9.5),(5 9),(5.5 8.5),(6 8),(6 7),(6 6),(5.5 5.5),(5 5),(4 5),(3 5),(2 5),(1 5),(1 4),(2 4),(3 4),(4 4),(4.5 3.5),(5 3),(6 2),(6 1),(5.5 0.5),(5 0),(4 0),(3 0),(2 0),(1 0),(0.5 0),(0.5 1),(0.5 2),(0.5 3),(0.5 4),(0.5 5),(0.5 6),(0.5 7),(0.5 8),(0.5 9),(0.5 10),(1 9.5),(2 9.5),(3 9.5),(4 9.5),(4.5 9),(5 8.5),(5.5 8),(5.5 7),(5.5 6),(5.5 6.5),(5 5.5),(4 5.5),(3 5.5),(2 5.5),(1 5.5),(1.5 4.5),(2.5 4.5),(3.5 4.5),(4 4.5),(4.5 4),(5 3.5),(5.5 3),(5.5 2),(5.5 1),(5 0.5),(4 0.5),(3 0.5),(2 0.5),(1 0.5),(12 0),(12 1),(12 2),(12 3),(12 4),(12 5),(12 6),(12 7),(12 8),(12 9),(12 10),(13 10),(14 10),(15 10),(16 10),(16.5 9.5),(17 9),(17.5 8.5),(18 8),(18 7),(18 6),(17.5 5.5),(17 5),(16 5),(15 5),(14 5),(13 5),(12.5 0),(12.5 1),(12.5 2),(12.5 3),(12.5 4),(12.5 5),(12.5 6),(12.5 7),(12.5 8),(12.5 9),(12.5 10),(13 9.5),(14 9.5),(15 9.5) ,(16 9.5),(16.5 9),(17 8.5),(17.5 8),(17.5 7),(17.5 6),(17.5 6.5),(17 5.5),(16 5.5),(15 5.5),(14 5.5),(13 5.5),(13 1),(13 2),(13 3),(13 4),(17.5 7.4),(18 7.3),(5.1 2.5),(5.8 2.5),(0.03 9.82),(0.23 10))', allow_holes => true, nb_components => 2)))); diff --git a/sfcgal/regress/alphashape_components_expected b/sfcgal/regress/alphashape_components_expected index 022ef1221..00efc058f 100644 --- a/sfcgal/regress/alphashape_components_expected +++ b/sfcgal/regress/alphashape_components_expected @@ -1,2 +1,2 @@ -CG_Optimalalphashape_2components|POLYGON((0.1 6.1,0.3 8.2,1.1 10.1,2.6 11.2,4.1 11.9,6.2 12.1,8.3 11.8,10.2 11.1,9.1 9.9,7.6 9.8,3.6 6.2,6 2.3,7.8 2.2,9.2 2.4,10.1 0.2,8.1 0.1,6 0,4.2 0.3,2.5 1,1.2 2.3,0.4 4,55.6 12.1,55.9 9.2,55.5 6,55.7 3.3,55.4 0.5,52.6 0.1,49.8 -0.2,44.2 0.2,42.1 0.3,40.3 0.4,40.1 3.1,39.8 6.2,40.4 9,40.2 12.3,40.5 15.2,41.9 15.6,43.1 15.3,43.1 10.4,43.3 7.1,46.9 2.8,52.8 4.1,52.7 7.3,52.9 10.6,54.3 15.2,55.8 15,0.1 6.1)) -CG_OptimalAlphaShape_hole_2components|POLYGON((0 0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0 8,0 9,0.03 9.82,0.23 10,0.5 10,1 10,2 10,3 10,4 10,4.5 9.5,5 9,5.5 8.5,6 8,6 7,6 6,5.5 5.5,5 5,4 4.5,4.5 4,5 3.5,5.5 3,5.8 2.5,6 2,6 1,5.5 0.5,5 0,4 0,3 0,2 0,1 0,0.5 0,12 0,12 1,12 2,12 3,12 4,12 5,12 6,12 7,12 8,12 9,12 10,12.5 10,13 10,14 10,15 10,16 10,16.5 9.5,17 9,17.5 8.5,18 8,18 7.3,18 7,18 6,17.5 5.5,17 5,16 5,15 5,14 5,13 5,13 4,13 3,13 2,13 1,12.5 0,0 0),(0.5 1,0.5 2,0.5 3,1 4,2 4,3 4,4 4,4.5 3.5,5 3,5.1 2.5,5.5 2,5.5 1,5 0.5,4 0.5,3 0.5,2 0.5,1 0.5,0.5 6,0.5 7,0.5 8,0.5 9,1 9.5,2 9.5,3 9.5,4 9.5,4.5 9,5 8.5,5.5 8,5.5 7,5.5 6.5,5.5 6,5 5.5,4 5.5,3 5.5,2 5.5,1 5.5,0.5 1),(12.5 6,12.5 7,12.5 8,12.5 9,13 9.5,14 9.5,15 9.5,16 9.5,16.5 9,17 8.5,17.5 8,17.5 7.4,17.5 7,17.5 6.5,17.5 6,17 5.5,16 5.5,15 5.5,14 5.5,13 5.5,12.5 6)) +CG_Optimalalphashape_2components|MULTIPOLYGON(((39.8 6.2,40.4 9,40.2 12.3,40.5 15.2,41.9 15.6,43.1 15.3,43.1 10.4,43.3 7.1,46.9 2.8,52.8 4.1,52.7 7.3,52.9 10.6,54.3 15.2,55.8 15,55.6 12.1,55.9 9.2,55.5 6,55.7 3.3,55.4 0.5,52.6 0.1,49.8 -0.2,44.2 0.2,42.1 0.3,40.3 0.4,40.1 3.1,39.8 6.2)),((0.1 6.1,0.3 8.2,1.1 10.1,2.6 11.2,4.1 11.9,6.2 12.1,8.3 11.8,10.2 11.1,9.1 9.9,7.6 9.8,3.6 6.2,6 2.3,7.8 2.2,9.2 2.4,10.1 0.2,8.1 0.1,6 0,4.2 0.3,2.5 1,1.2 2.3,0.4 4,0.1 6.1))) +CG_OptimalAlphaShape_hole_2components|MULTIPOLYGON(((0 0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0 8,0 9,0.03 9.82,0.23 10,0.5 10,1 10,2 10,3 10,4 10,4.5 9.5,5 9,5.5 8.5,6 8,6 7,6 6,5.5 5.5,5 5,4 4.5,4.5 4,5 3.5,5.5 3,5.8 2.5,6 2,6 1,5.5 0.5,5 0,4 0,3 0,2 0,1 0,0.5 0,0 0),(0.5 6,1 5.5,2 5.5,3 5.5,4 5.5,5 5.5,5.5 6,5.5 6.5,5.5 7,5.5 8,5 8.5,4.5 9,4 9.5,3 9.5,2 9.5,1 9.5,0.5 9,0.5 8,0.5 7,0.5 6),(0.5 1,1 0.5,2 0.5,3 0.5,4 0.5,5 0.5,5.5 1,5.5 2,5.1 2.5,5 3,4.5 3.5,4 4,3 4,2 4,1 4,0.5 3,0.5 2,0.5 1)),((12 0,12 1,12 2,12 3,12 4,12 5,12 6,12 7,12 8,12 9,12 10,12.5 10,13 10,14 10,15 10,16 10,16.5 9.5,17 9,17.5 8.5,18 8,18 7.3,18 7,18 6,17.5 5.5,17 5,16 5,15 5,14 5,13 5,13 4,13 3,13 2,13 1,12.5 0,12 0),(12.5 6,13 5.5,14 5.5,15 5.5,16 5.5,17 5.5,17.5 6,17.5 6.5,17.5 7,17.5 7.4,17.5 8,17 8.5,16.5 9,16 9.5,15 9.5,14 9.5,13 9.5,12.5 9,12.5 8,12.5 7,12.5 6))) ----------------------------------------------------------------------- Summary of changes: sfcgal/regress/alphashape_components.sql | 6 ++++-- sfcgal/regress/alphashape_components_expected | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Fri Mar 6 02:52:11 2026 From: git at osgeo.org (git at osgeo.org) Date: Fri, 6 Mar 2026 02:52:11 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-363-ge48c072d0 Message-ID: <20260306105212.3BD15191CC8@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via e48c072d066590721b0c100818c2e484c7f0395d (commit) from 532c6ade24ff41013541c56a995e401a4de14dbd (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e48c072d066590721b0c100818c2e484c7f0395d Author: Darafei Praliaskouski Date: Fri Mar 6 14:50:44 2026 +0400 ci/debbie: bump dist jobs to PostgreSQL 14 diff --git a/ci/debbie/postgis_make_dist.sh b/ci/debbie/postgis_make_dist.sh index 33d880dc1..f3d75311a 100644 --- a/ci/debbie/postgis_make_dist.sh +++ b/ci/debbie/postgis_make_dist.sh @@ -2,7 +2,7 @@ set -e ## begin variables passed in by jenkins -export PG_VER=13 +export PG_VER=14 # export PGPORT=8442 export OS_BUILD=64 # export POSTGIS_MAJOR_VERSION=2 diff --git a/ci/debbie/postgis_release_docs.sh b/ci/debbie/postgis_release_docs.sh index 82c67cca7..7807c7074 100644 --- a/ci/debbie/postgis_release_docs.sh +++ b/ci/debbie/postgis_release_docs.sh @@ -2,7 +2,7 @@ set -e -export PG_VER=13 +export PG_VER=14 # export PGPORT=8442 export OS_BUILD=64 #this is passed in via postgis_make_dist.sh via jenkins diff --git a/doc/developer.md b/doc/developer.md index 6b56c610b..eb3a69c47 100644 --- a/doc/developer.md +++ b/doc/developer.md @@ -374,7 +374,9 @@ while keeping the CI account unprivileged. * Edit doc/postgis.xml and change entity `min_postgres_version` to new minimum version +* Update any CI scripts that hard-code a PostgreSQL major for packaging or docs jobs, + notably `ci/debbie/postgis_make_dist.sh` and `ci/debbie/postgis_release_docs.sh` + * Add to NEWS Breaking Changes section, your removal of said versions - ----------------------------------------------------------------------- Summary of changes: ci/debbie/postgis_make_dist.sh | 2 +- ci/debbie/postgis_release_docs.sh | 2 +- doc/developer.md | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Fri Mar 6 04:47:50 2026 From: git at osgeo.org (git at osgeo.org) Date: Fri, 6 Mar 2026 04:47:50 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-364-g2cbc46f29 Message-ID: <20260306124750.5CEC01962AD@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 2cbc46f2915e694ec329407503574004c16311b9 (commit) from e48c072d066590721b0c100818c2e484c7f0395d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2cbc46f2915e694ec329407503574004c16311b9 Author: Darafei Praliaskouski Date: Fri Mar 6 16:46:56 2026 +0400 topology: avoid uninitialized edge id in edge split diff --git a/liblwgeom/topo/lwgeom_topo.c b/liblwgeom/topo/lwgeom_topo.c index 054c2b21c..07e7ba7cd 100644 --- a/liblwgeom/topo/lwgeom_topo.c +++ b/liblwgeom/topo/lwgeom_topo.c @@ -6138,7 +6138,10 @@ _lwt_SnapEdgeToExistingNode( newEdge.geom = lwgeom_as_lwline(splitC->geoms[1]); newEdge.end_node = edge->end_node; newEdge.start_node = node->node_id; - newEdge.next_right = -updatedEdge.edge_id; // to be assigned later, if needed + /* Seed the split pair with mutual linkage; nodeStar may replace these + * with the actual neighboring edges below. + */ + newEdge.next_right = -edge->edge_id; if ( edge->next_left == -edge->edge_id ) { newEdge.next_left = -newEdge.edge_id; } else { @@ -6151,7 +6154,7 @@ _lwt_SnapEdgeToExistingNode( updatedEdge.edge_id = edge->edge_id; updatedEdge.geom = lwgeom_as_lwline(splitC->geoms[0]); updatedEdge.end_node = node->node_id; - updatedEdge.next_left = newEdge.edge_id; // to be re-assigned later, if needed + updatedEdge.next_left = newEdge.edge_id; LWT_EDGEEND_STAR *nodeStar = lwt_edgeEndStar_init( node->node_id ); ----------------------------------------------------------------------- Summary of changes: liblwgeom/topo/lwgeom_topo.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Fri Mar 6 08:15:30 2026 From: git at osgeo.org (git at osgeo.org) Date: Fri, 6 Mar 2026 08:15:30 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-366-g67d1d0640 Message-ID: <20260306161531.459C8197302@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 67d1d0640e2e01d1fff997372bf357250fecc90d (commit) via 17f698631baf0c3b4c63ec474fed51d9518a0e1a (commit) from 2cbc46f2915e694ec329407503574004c16311b9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 67d1d0640e2e01d1fff997372bf357250fecc90d Author: Darafei Praliaskouski Date: Fri Mar 6 20:14:52 2026 +0400 doc: fix comment SQL escaping and spell checks diff --git a/.codespellrc b/.codespellrc index 016dfb022..964a27237 100644 --- a/.codespellrc +++ b/.codespellrc @@ -1,3 +1,4 @@ [codespell] -skip = *.po,spatial_ref_sys.sql,./deps,./extensions/address_standardizer,./configure*,./autom4te.cache,./build-aux,./libtool,.git,build* +# utils/check_spelling.sh builds a deterministic list of tracked files plus +# generated comment SQL. ignore-words = .codespell.ignore diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index 302aa40a1..617153b0b 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -21,9 +21,12 @@ jobs: - name: 'Install codespell' run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends libxml2-utils docbook-xml docbook-xsl docbook-xsl-ns xsltproc sudo pip install codespell - name: 'Build & Test' run: | codespell --version - codespell -I ".codespell.ignore" + make -C doc comments + ./utils/check_spelling.sh diff --git a/GNUmakefile.in b/GNUmakefile.in index 1e0c2fb92..e468eed66 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -307,7 +307,7 @@ endif check-spell: ifneq (@CODESPELL@,) - cd $(top_srcdir) && @CODESPELL@ + cd $(top_srcdir) && ./utils/check_spelling.sh @CODESPELL@ else @echo "SKIP: spell checking disabled" endif diff --git a/doc/po/zh_Hans/postgis-manual.po b/doc/po/zh_Hans/postgis-manual.po index d319ec99a..f571d2fcc 100644 --- a/doc/po/zh_Hans/postgis-manual.po +++ b/doc/po/zh_Hans/postgis-manual.po @@ -4346,7 +4346,7 @@ msgid "" "topogeometries created before the upgrade. This function fixes this " "corruption in affected tables." msgstr "" -"? PostGIS topology ?? <3.6.0 ??? >3.6.0+ ??topogeometry " +"? PostGIS topology ?? <3.6.0 ??? >3.6.0+ ??topogeometry " "?????????????????? topogeometry " "????????????????????????????" diff --git a/doc/xsl/postgis_comments.sql.xsl b/doc/xsl/postgis_comments.sql.xsl index 3e5333d2a..3e27ba993 100644 --- a/doc/xsl/postgis_comments.sql.xsl +++ b/doc/xsl/postgis_comments.sql.xsl @@ -22,6 +22,7 @@ ' + '' @@ -32,7 +33,7 @@ - + diff --git a/doc/xsl/raster_comments.sql.xsl b/doc/xsl/raster_comments.sql.xsl index d9dd68970..450904c7d 100644 --- a/doc/xsl/raster_comments.sql.xsl +++ b/doc/xsl/raster_comments.sql.xsl @@ -24,6 +24,7 @@ ' + '' @@ -34,7 +35,7 @@ - + @@ -61,7 +63,7 @@ COMMENT ON - + COMMENT ON TYPE IS 'postgis raster type: '; diff --git a/doc/xsl/sfcgal_comments.sql.xsl b/doc/xsl/sfcgal_comments.sql.xsl index 6eb857037..116da9a30 100644 --- a/doc/xsl/sfcgal_comments.sql.xsl +++ b/doc/xsl/sfcgal_comments.sql.xsl @@ -23,6 +23,7 @@ ' + '' @@ -33,7 +34,7 @@ - + @@ -33,7 +34,7 @@ - + @@ -33,7 +34,7 @@ - + diff --git a/utils/check_spelling.sh b/utils/check_spelling.sh new file mode 100755 index 000000000..5537675ed --- /dev/null +++ b/utils/check_spelling.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +set -eu + +CODESPELL=${1:-codespell} + +ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) +cd "$ROOT" + +tmpfiles=$(mktemp) +trap 'rm -f "$tmpfiles"' EXIT HUP INT TERM + +# Keep the check deterministic by starting from tracked files and excluding +# vendor data, generated trees, and authoritative datasets that are not prose. +git ls-files -z -- . \ + ':(exclude)deps' \ + ':(exclude)extensions/address_standardizer' \ + ':(exclude)doc/html' \ + ':(exclude)doc/po' \ + ':(exclude)doc/postgis-out.xml' \ + ':(exclude)doc/postgis-nospecial.xml' \ + ':(exclude)aclocal.m4' \ + ':(exclude)configure' \ + ':(exclude)macros/libtool.m4' \ + ':(exclude)spatial_ref_sys.sql' \ + ':(exclude)extensions/postgis/sql/spatial_ref_sys.sql' \ + ':(glob,exclude)extensions/postgis/sql/postgis--*.sql' \ + ':(glob,exclude)**/*.po' \ + > "$tmpfiles" + +# The comment SQL files are generated from the docs and shipped in release +# artifacts, so include them when they exist. +for generated in doc/postgis_comments.sql \ + doc/raster_comments.sql \ + doc/sfcgal_comments.sql \ + doc/tiger_geocoder_comments.sql \ + doc/topology_comments.sql +do + if [ -f "$generated" ]; then + printf '%s\0' "$generated" >> "$tmpfiles" + fi +done + +xargs -0 "$CODESPELL" --config .codespellrc < "$tmpfiles" commit 17f698631baf0c3b4c63ec474fed51d9518a0e1a Author: Darafei Praliaskouski Date: Fri Mar 6 19:45:36 2026 +0400 geos: use fixed-width flags in signedness-sensitive paths diff --git a/liblwgeom/cunit/cu_geos_cluster.c b/liblwgeom/cunit/cu_geos_cluster.c index 78d8c35c9..20129f14b 100644 --- a/liblwgeom/cunit/cu_geos_cluster.c +++ b/liblwgeom/cunit/cu_geos_cluster.c @@ -22,7 +22,7 @@ static void assert_all_results_found(LWGEOM** results, size_t num_outputs, LWGEO { size_t i, j; - char found_equal = 0; + uint8_t found_equal = 0; for (i = 0; i < num_outputs; i++) { for (j = 0; j < num_expected_outputs; j++) @@ -271,7 +271,7 @@ static void do_dbscan_test(struct dbscan_test_info test) LWGEOM** geoms = WKTARRAY2LWGEOM(test.wkt_inputs, test.num_geoms); UNIONFIND* uf = UF_create(test.num_geoms); uint32_t* ids; - char* in_a_cluster; + uint8_t *in_a_cluster; uint32_t i; union_dbscan(geoms, test.num_geoms, uf, test.eps, test.min_points, &in_a_cluster); diff --git a/liblwgeom/cunit/cu_unionfind.c b/liblwgeom/cunit/cu_unionfind.c index 223129866..fb00dc5c1 100644 --- a/liblwgeom/cunit/cu_unionfind.c +++ b/liblwgeom/cunit/cu_unionfind.c @@ -66,7 +66,7 @@ static void test_unionfind_ordered_by_cluster(void) uint32_t* ids_by_cluster = UF_ordered_by_cluster(&uf); - char encountered_cluster[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t encountered_cluster[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint32_t i; for (i = 0; i < uf.N; i++) @@ -147,7 +147,7 @@ static void test_unionfind_collapse_cluster_ids(void) lwfree(collapsed_ids); - char is_in_cluster[] = { 0, 1, 1, 1, 0, 1, 0, 0, 0, 0 }; + uint8_t is_in_cluster[] = {0, 1, 1, 1, 0, 1, 0, 0, 0, 0}; uint32_t expected_collapsed_ids2[] = { 8, 0, 0, 0, 7, 0, 8, 7, 8, 7 }; collapsed_ids = UF_get_collapsed_cluster_ids(uf, is_in_cluster); diff --git a/liblwgeom/lwgeom_geos.c b/liblwgeom/lwgeom_geos.c index e3fb18625..b42f1eb69 100644 --- a/liblwgeom/lwgeom_geos.c +++ b/liblwgeom/lwgeom_geos.c @@ -1776,7 +1776,7 @@ lwgeom_voronoi_diagram(const LWGEOM* g, const GBOX* env, double tolerance, int o { uint32_t num_points = lwgeom_count_vertices(g); LWGEOM* lwgeom_result; - char is_3d = LW_FALSE; + uint8_t is_3d = LW_FALSE; int32_t srid = lwgeom_get_srid(g); GEOSCoordSequence* coords; GEOSGeometry* geos_geom; diff --git a/liblwgeom/lwgeom_geos.h b/liblwgeom/lwgeom_geos.h index 2d80819fb..f444cb6e5 100644 --- a/liblwgeom/lwgeom_geos.h +++ b/liblwgeom/lwgeom_geos.h @@ -46,7 +46,12 @@ int cluster_intersecting(GEOSGeometry **geoms, uint32_t num_geoms, GEOSGeometry int union_intersecting_pairs(GEOSGeometry** geoms, uint32_t num_geoms, UNIONFIND* uf); int union_related_pairs(GEOSGeometry** geoms, uint32_t num_geoms, const char* im, UNIONFIND* uf); int cluster_within_distance(LWGEOM **geoms, uint32_t num_geoms, double tolerance, LWGEOM ***clusterGeoms, uint32_t *num_clusters); -int union_dbscan(LWGEOM **geoms, uint32_t num_geoms, UNIONFIND *uf, double eps, uint32_t min_points, char **is_in_cluster_ret); +int union_dbscan(LWGEOM **geoms, + uint32_t num_geoms, + UNIONFIND *uf, + double eps, + uint32_t min_points, + uint8_t **is_in_cluster_ret); POINTARRAY* ptarray_from_GEOSCoordSeq(const GEOSCoordSequence* cs, uint8_t want3d); diff --git a/liblwgeom/lwgeom_geos_cluster.c b/liblwgeom/lwgeom_geos_cluster.c index 318d3558e..64ca68f5f 100644 --- a/liblwgeom/lwgeom_geos_cluster.c +++ b/liblwgeom/lwgeom_geos_cluster.c @@ -48,9 +48,14 @@ struct STRTree uint32_t num_geoms; }; -static struct STRTree make_strtree(void** geoms, uint32_t num_geoms, char is_lwgeom); +static struct STRTree make_strtree(void **geoms, uint32_t num_geoms, uint8_t is_lwgeom); static void destroy_strtree(struct STRTree * tree); -static int combine_geometries(UNIONFIND* uf, void** geoms, uint32_t num_geoms, void*** clustersGeoms, uint32_t* num_clusters, char is_lwgeom); +static int combine_geometries(UNIONFIND *uf, + void **geoms, + uint32_t num_geoms, + void ***clustersGeoms, + uint32_t *num_clusters, + uint8_t is_lwgeom); /* Make a minimal GEOSGeometry* whose Envelope covers the same 2D extent as * the supplied GBOX. This is faster and uses less memory than building a @@ -77,7 +82,7 @@ geos_envelope_surrogate(const LWGEOM* g) /** Make a GEOSSTRtree that stores a pointer to a variable containing * the array index of the input geoms */ static struct STRTree -make_strtree(void** geoms, uint32_t num_geoms, char is_lwgeom) +make_strtree(void **geoms, uint32_t num_geoms, uint8_t is_lwgeom) { struct STRTree tree; tree.envelopes = 0; @@ -385,7 +390,7 @@ dbscan_update_context(GEOSSTRtree* tree, struct QueryContext* cxt, LWGEOM** geom * Applicable to DBSCAN with minpoints > 1. */ static void -union_if_available(UNIONFIND* uf, uint32_t p, uint32_t q, char* is_in_core, char* in_a_cluster) +union_if_available(UNIONFIND *uf, uint32_t p, uint32_t q, uint8_t *is_in_core, uint8_t *in_a_cluster) { if (in_a_cluster[q]) { @@ -411,7 +416,7 @@ union_if_available(UNIONFIND* uf, uint32_t p, uint32_t q, char* is_in_core, char * to avoid some distance computations altogether. */ static int -union_dbscan_minpoints_1(LWGEOM** geoms, uint32_t num_geoms, UNIONFIND* uf, double eps, char** in_a_cluster_ret) +union_dbscan_minpoints_1(LWGEOM **geoms, uint32_t num_geoms, UNIONFIND *uf, double eps, uint8_t **in_a_cluster_ret) { uint32_t p, i; struct STRTree tree; @@ -425,7 +430,7 @@ union_dbscan_minpoints_1(LWGEOM** geoms, uint32_t num_geoms, UNIONFIND* uf, doub if (in_a_cluster_ret) { - char* in_a_cluster = lwalloc(num_geoms * sizeof(char)); + uint8_t *in_a_cluster = lwalloc(num_geoms * sizeof(uint8_t)); for (i = 0; i < num_geoms; i++) in_a_cluster[i] = LW_TRUE; *in_a_cluster_ret = in_a_cluster; @@ -481,7 +486,12 @@ union_dbscan_minpoints_1(LWGEOM** geoms, uint32_t num_geoms, UNIONFIND* uf, doub } static int -union_dbscan_general(LWGEOM** geoms, uint32_t num_geoms, UNIONFIND* uf, double eps, uint32_t min_points, char** in_a_cluster_ret) +union_dbscan_general(LWGEOM **geoms, + uint32_t num_geoms, + UNIONFIND *uf, + double eps, + uint32_t min_points, + uint8_t **in_a_cluster_ret) { uint32_t p, i; struct STRTree tree; @@ -493,11 +503,11 @@ union_dbscan_general(LWGEOM** geoms, uint32_t num_geoms, UNIONFIND* uf, double e }; int success = LW_SUCCESS; uint32_t* neighbors; - char* in_a_cluster; - char* is_in_core; + uint8_t *in_a_cluster; + uint8_t *is_in_core; - in_a_cluster = lwalloc(num_geoms * sizeof(char)); - memset(in_a_cluster, 0, num_geoms * sizeof(char)); + in_a_cluster = lwalloc(num_geoms * sizeof(uint8_t)); + memset(in_a_cluster, 0, num_geoms * sizeof(uint8_t)); if (in_a_cluster_ret) *in_a_cluster_ret = in_a_cluster; @@ -517,8 +527,8 @@ union_dbscan_general(LWGEOM** geoms, uint32_t num_geoms, UNIONFIND* uf, double e return LW_FAILURE; } - is_in_core = lwalloc(num_geoms * sizeof(char)); - memset(is_in_core, 0, num_geoms * sizeof(char)); + is_in_core = lwalloc(num_geoms * sizeof(uint8_t)); + memset(is_in_core, 0, num_geoms * sizeof(uint8_t)); neighbors = lwalloc(min_points * sizeof(uint32_t)); for (p = 0; p < num_geoms; p++) @@ -619,7 +629,13 @@ union_dbscan_general(LWGEOM** geoms, uint32_t num_geoms, UNIONFIND* uf, double e return success; } -int union_dbscan(LWGEOM** geoms, uint32_t num_geoms, UNIONFIND* uf, double eps, uint32_t min_points, char** in_a_cluster_ret) +int +union_dbscan(LWGEOM **geoms, + uint32_t num_geoms, + UNIONFIND *uf, + double eps, + uint32_t min_points, + uint8_t **in_a_cluster_ret) { if (min_points <= 1) return union_dbscan_minpoints_1(geoms, num_geoms, uf, eps, in_a_cluster_ret); @@ -651,7 +667,12 @@ cluster_within_distance(LWGEOM** geoms, uint32_t num_geoms, double tolerance, LW * GeometryCollections. Supplied geometry array may be of either LWGEOM* or GEOSGeometry*; is_lwgeom is used to * identify which. Caller is responsible for freeing input geometry array but not the items contained within it. */ static int -combine_geometries(UNIONFIND* uf, void** geoms, uint32_t num_geoms, void*** clusterGeoms, uint32_t* num_clusters, char is_lwgeom) +combine_geometries(UNIONFIND *uf, + void **geoms, + uint32_t num_geoms, + void ***clusterGeoms, + uint32_t *num_clusters, + uint8_t is_lwgeom) { size_t i, j, k; diff --git a/liblwgeom/lwunionfind.c b/liblwgeom/lwunionfind.c index 854a9e807..9ca47a1c3 100644 --- a/liblwgeom/lwunionfind.c +++ b/liblwgeom/lwunionfind.c @@ -142,13 +142,13 @@ UF_ordered_by_cluster(UNIONFIND* uf) return ordered_ids; } -uint32_t* -UF_get_collapsed_cluster_ids(UNIONFIND* uf, const char* is_in_cluster) +uint32_t * +UF_get_collapsed_cluster_ids(UNIONFIND *uf, const uint8_t *is_in_cluster) { uint32_t* ordered_components = UF_ordered_by_cluster(uf); uint32_t* new_ids = lwalloc(uf->N * sizeof(uint32_t)); uint32_t last_old_id, current_new_id, i; - char encountered_cluster = LW_FALSE; + uint8_t encountered_cluster = LW_FALSE; current_new_id = 0; last_old_id = 0; for (i = 0; i < uf->N; i++) diff --git a/liblwgeom/lwunionfind.h b/liblwgeom/lwunionfind.h index 75e0ae788..8964a3671 100644 --- a/liblwgeom/lwunionfind.h +++ b/liblwgeom/lwunionfind.h @@ -57,5 +57,4 @@ uint32_t* UF_ordered_by_cluster(UNIONFIND* uf); * If is_in_cluster array is provided, it will be used to skip any indexes * that are not in a cluster. * */ -uint32_t* UF_get_collapsed_cluster_ids(UNIONFIND* uf, const char* is_in_cluster); - +uint32_t *UF_get_collapsed_cluster_ids(UNIONFIND *uf, const uint8_t *is_in_cluster); diff --git a/postgis/lwgeom_geos.c b/postgis/lwgeom_geos.c index 9b1ef3e0f..e93db0af7 100644 --- a/postgis/lwgeom_geos.c +++ b/postgis/lwgeom_geos.c @@ -1551,7 +1551,7 @@ Datum isvalid(PG_FUNCTION_ARGS) { GSERIALIZED *geom1; LWGEOM *lwgeom; - char result; + int8_t result; GEOSGeom g1; geom1 = PG_GETARG_GSERIALIZED_P(0); @@ -1628,7 +1628,7 @@ Datum isvaliddetail(PG_FUNCTION_ARGS) char *reason = NULL; GEOSGeometry *geos_location = NULL; LWGEOM *location = NULL; - char valid = 0; + int8_t valid = 0; HeapTupleHeader result; TupleDesc tupdesc; HeapTuple tuple; @@ -1706,7 +1706,7 @@ Datum issimple(PG_FUNCTION_ARGS) { GSERIALIZED *geom; LWGEOM *lwgeom_in; - int result; + int8_t result; POSTGIS_DEBUG(2, "issimple called"); @@ -1732,7 +1732,7 @@ Datum isring(PG_FUNCTION_ARGS) { GSERIALIZED *geom; GEOSGeometry *g1; - int result; + int8_t result; geom = PG_GETARG_GSERIALIZED_P(0); @@ -1762,7 +1762,7 @@ Datum isring(PG_FUNCTION_ARGS) } GSERIALIZED * -GEOS2POSTGIS(GEOSGeom geom, char want3d) +GEOS2POSTGIS(GEOSGeom geom, uint8_t want3d) { LWGEOM *lwgeom; GSERIALIZED *result; @@ -2662,7 +2662,7 @@ Datum LWGEOM_dfullywithin(PG_FUNCTION_ARGS) double radius = PG_GETARG_FLOAT8(2); GEOSGeometry *buffer1 = NULL; GEOSGeometry *geos1 = NULL, *geos2 = NULL; - char contained; + int8_t contained; if (radius < 0.0) { diff --git a/postgis/lwgeom_geos.h b/postgis/lwgeom_geos.h index 07707c459..1fdc58e83 100644 --- a/postgis/lwgeom_geos.h +++ b/postgis/lwgeom_geos.h @@ -34,7 +34,7 @@ ** Public prototypes for GEOS utility functions. */ -GSERIALIZED *GEOS2POSTGIS(GEOSGeom geom, char want3d); +GSERIALIZED *GEOS2POSTGIS(GEOSGeom geom, uint8_t want3d); GEOSGeometry *POSTGIS2GEOS(const GSERIALIZED *g); GEOSGeometry** ARRAY2GEOS(ArrayType* array, uint32_t nelems, int* is3d, int* srid); LWGEOM** ARRAY2LWGEOM(ArrayType* array, uint32_t nelems, int* is3d, int* srid); diff --git a/postgis/lwgeom_geos_predicates.c b/postgis/lwgeom_geos_predicates.c index 1219117f8..87d34a694 100644 --- a/postgis/lwgeom_geos_predicates.c +++ b/postgis/lwgeom_geos_predicates.c @@ -65,8 +65,8 @@ Datum ST_Equals(PG_FUNCTION_ARGS); /* * Utility to quickly check for polygonal geometries */ -static inline char -is_poly(const GSERIALIZED* g) +static inline uint8_t +is_poly(const GSERIALIZED *g) { int type = gserialized_get_type(g); return type == POLYGONTYPE || type == MULTIPOLYGONTYPE; @@ -75,8 +75,8 @@ is_poly(const GSERIALIZED* g) /* * Utility to quickly check for point geometries */ -static inline char -is_point(const GSERIALIZED* g) +static inline uint8_t +is_point(const GSERIALIZED *g) { int type = gserialized_get_type(g); return type == POINTTYPE || type == MULTIPOINTTYPE; @@ -95,7 +95,7 @@ Datum ST_Intersects(PG_FUNCTION_ARGS) SHARED_GSERIALIZED *shared_geom2 = ToastCacheGetGeometry(fcinfo, 1); const GSERIALIZED *geom1 = shared_gserialized_get(shared_geom1); const GSERIALIZED *geom2 = shared_gserialized_get(shared_geom2); - int result; + int8_t result; GBOX box1, box2; PrepGeomCache *prep_cache; @@ -174,7 +174,7 @@ Datum ST_Equals(PG_FUNCTION_ARGS) SHARED_GSERIALIZED *shared_geom2 = ToastCacheGetGeometry(fcinfo, 1); const GSERIALIZED *geom1 = shared_gserialized_get(shared_geom1); const GSERIALIZED *geom2 = shared_gserialized_get(shared_geom2); - char result; + int8_t result; GBOX box1, box2; GEOSGeometry *g1, *g2; @@ -233,7 +233,7 @@ Datum touches(PG_FUNCTION_ARGS) SHARED_GSERIALIZED *shared_geom2 = ToastCacheGetGeometry(fcinfo, 1); const GSERIALIZED *geom1 = shared_gserialized_get(shared_geom1); const GSERIALIZED *geom2 = shared_gserialized_get(shared_geom2); - char result; + int8_t result; GBOX box1, box2; PrepGeomCache *prep_cache; @@ -297,7 +297,7 @@ Datum disjoint(PG_FUNCTION_ARGS) SHARED_GSERIALIZED *shared_geom2 = ToastCacheGetGeometry(fcinfo, 1); const GSERIALIZED *geom1 = shared_gserialized_get(shared_geom1); const GSERIALIZED *geom2 = shared_gserialized_get(shared_geom2); - char result; + int8_t result; GBOX box1, box2; PrepGeomCache *prep_cache; @@ -365,7 +365,7 @@ Datum overlaps(PG_FUNCTION_ARGS) SHARED_GSERIALIZED *shared_geom2 = ToastCacheGetGeometry(fcinfo, 1); const GSERIALIZED *geom1 = shared_gserialized_get(shared_geom1); const GSERIALIZED *geom2 = shared_gserialized_get(shared_geom2); - char result; + int8_t result; GBOX box1, box2; PrepGeomCache *prep_cache; @@ -432,7 +432,7 @@ Datum crosses(PG_FUNCTION_ARGS) SHARED_GSERIALIZED *shared_geom2 = ToastCacheGetGeometry(fcinfo, 1); const GSERIALIZED *geom1 = shared_gserialized_get(shared_geom1); const GSERIALIZED *geom2 = shared_gserialized_get(shared_geom2); - int result; + int8_t result; GBOX box1, box2; PrepGeomCache *prep_cache; @@ -500,7 +500,7 @@ Datum contains(PG_FUNCTION_ARGS) SHARED_GSERIALIZED *shared_geom2 = ToastCacheGetGeometry(fcinfo, 1); const GSERIALIZED *geom1 = shared_gserialized_get(shared_geom1); const GSERIALIZED *geom2 = shared_gserialized_get(shared_geom2); - int result; + int8_t result; GEOSGeometry *g1, *g2; GBOX box1, box2; PrepGeomCache *prep_cache; @@ -581,7 +581,7 @@ Datum within(PG_FUNCTION_ARGS) SHARED_GSERIALIZED *shared_geom2 = ToastCacheGetGeometry(fcinfo, 1); const GSERIALIZED *geom1 = shared_gserialized_get(shared_geom1); const GSERIALIZED *geom2 = shared_gserialized_get(shared_geom2); - int result; + int8_t result; GEOSGeometry *g1, *g2; GBOX box1, box2; PrepGeomCache *prep_cache; @@ -661,7 +661,7 @@ Datum containsproperly(PG_FUNCTION_ARGS) SHARED_GSERIALIZED *shared_geom2 = ToastCacheGetGeometry(fcinfo, 1); const GSERIALIZED *geom1 = shared_gserialized_get(shared_geom1); const GSERIALIZED *geom2 = shared_gserialized_get(shared_geom2); - char result; + int8_t result; GBOX box1, box2; PrepGeomCache *prep_cache; @@ -726,7 +726,7 @@ Datum covers(PG_FUNCTION_ARGS) SHARED_GSERIALIZED *shared_geom2 = ToastCacheGetGeometry(fcinfo, 1); const GSERIALIZED *geom1 = shared_gserialized_get(shared_geom1); const GSERIALIZED *geom2 = shared_gserialized_get(shared_geom2); - int result; + int8_t result; GBOX box1, box2; PrepGeomCache *prep_cache; @@ -810,7 +810,7 @@ Datum coveredby(PG_FUNCTION_ARGS) SHARED_GSERIALIZED *shared_geom2 = ToastCacheGetGeometry(fcinfo, 1); const GSERIALIZED *geom1 = shared_gserialized_get(shared_geom1); const GSERIALIZED *geom2 = shared_gserialized_get(shared_geom2); - int result; + int8_t result; GBOX box1, box2; PrepGeomCache *prep_cache; @@ -909,7 +909,7 @@ Datum relate_pattern(PG_FUNCTION_ARGS) text *imPtr = DatumGetTextP(DirectFunctionCall2(text_left, PG_GETARG_DATUM(2), Int32GetDatum(9))); char *im = text_to_cstring(imPtr); - char result; + int8_t result; uint32_t i; #if POSTGIS_GEOS_VERSION >= 31300 PrepGeomCache *prep_cache; @@ -1045,7 +1045,7 @@ Datum LWGEOM_dwithin(PG_FUNCTION_ARGS) const GSERIALIZED *geom2 = shared_gserialized_get(shared_geom2); PrepGeomCache *prep_cache = NULL; const size_t small_threshold = 1024; - char is_dwithin = -1; + int8_t is_dwithin = -1; /* * Only enter the GEOS/PreparedGeometry code line if one of the @@ -1103,5 +1103,3 @@ Datum LWGEOM_dwithin(PG_FUNCTION_ARGS) PG_RETURN_BOOL(is_dwithin); } - - diff --git a/postgis/lwgeom_window.c b/postgis/lwgeom_window.c index 4e931af53..409b94503 100644 --- a/postgis/lwgeom_window.c +++ b/postgis/lwgeom_window.c @@ -49,14 +49,14 @@ typedef struct { typedef struct { uint32_t cluster_id; - char is_null; /* NULL may result from a NULL geometry input, or it may be used by - algorithms such as DBSCAN that do not assign all inputs to a - cluster. */ + uint8_t is_null; /* NULL may result from a NULL geometry input, or it may be used by + algorithms such as DBSCAN that do not assign all inputs to a + cluster. */ } cluster_entry; typedef struct { - char is_error; + uint8_t is_error; cluster_entry clusters[1]; } cluster_context; @@ -129,7 +129,7 @@ Datum ST_ClusterDBSCAN(PG_FUNCTION_ARGS) uint32_t i; uint32_t* result_ids; LWGEOM** geoms; - char* is_in_cluster = NULL; + uint8_t *is_in_cluster = NULL; UNIONFIND* uf; bool tolerance_is_null; bool minpoints_is_null; @@ -1035,5 +1035,3 @@ Datum ST_CoverageUnion(PG_FUNCTION_ARGS) PG_RETURN_POINTER(result); } - - ----------------------------------------------------------------------- Summary of changes: .codespellrc | 3 +- .github/workflows/codespell.yml | 5 +++- GNUmakefile.in | 2 +- doc/po/zh_Hans/postgis-manual.po | 2 +- doc/xsl/postgis_comments.sql.xsl | 3 +- doc/xsl/raster_comments.sql.xsl | 6 ++-- doc/xsl/sfcgal_comments.sql.xsl | 3 +- doc/xsl/tiger_geocoder_comments.sql.xsl | 3 +- doc/xsl/topology_comments.sql.xsl | 3 +- liblwgeom/cunit/cu_geos_cluster.c | 4 +-- liblwgeom/cunit/cu_unionfind.c | 4 +-- liblwgeom/lwgeom_geos.c | 2 +- liblwgeom/lwgeom_geos.h | 7 ++++- liblwgeom/lwgeom_geos_cluster.c | 51 +++++++++++++++++++++++---------- liblwgeom/lwunionfind.c | 6 ++-- liblwgeom/lwunionfind.h | 3 +- postgis/lwgeom_geos.c | 12 ++++---- postgis/lwgeom_geos.h | 2 +- postgis/lwgeom_geos_predicates.c | 36 +++++++++++------------ postgis/lwgeom_window.c | 12 ++++---- utils/check_spelling.sh | 44 ++++++++++++++++++++++++++++ 21 files changed, 144 insertions(+), 69 deletions(-) create mode 100755 utils/check_spelling.sh hooks/post-receive -- PostGIS From git at osgeo.org Fri Mar 6 09:45:58 2026 From: git at osgeo.org (git at osgeo.org) Date: Fri, 6 Mar 2026 09:45:58 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-369-gbe42c3370 Message-ID: <20260306174558.9EF9A197C49@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via be42c33700f1f4bd34ae8ee181509cf1e89de680 (commit) via 51fc9568c2fe7507600a97393dedba1d43f2d102 (commit) via ee2614b25095b2c256a8f167601e68605587f93d (commit) from 67d1d0640e2e01d1fff997372bf357250fecc90d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit be42c33700f1f4bd34ae8ee181509cf1e89de680 Author: Darafei Praliaskouski Date: Fri Mar 6 21:28:47 2026 +0400 ci: run codespell directly with repo config diff --git a/.codespellrc b/.codespellrc index 964a27237..b68fd7fbf 100644 --- a/.codespellrc +++ b/.codespellrc @@ -1,4 +1,50 @@ [codespell] -# utils/check_spelling.sh builds a deterministic list of tracked files plus -# generated comment SQL. ignore-words = .codespell.ignore +skip = + ./deps/**, + ./extensions/address_standardizer/**, + ./extensions/*/sql/**, + ./extensions/*/sql_bits/*.sql, + ./extensions/postgis_tiger_geocoder/sql_bits/*.sql.in, + ./doc/html/**, + ./doc/po/**, + ./doc/postgis-out.xml, + ./doc/postgis-nospecial.xml, + ./postgis/*.sql, + ./raster/rt_pg/*.sql, + aclocal.m4, + configure, + libtool, + ./macros/libtool.m4, + spatial_ref_sys.sql, + ./postgis/*for_extension.sql, + ./postgis/*for_extension.sql.in, + ./raster/rt_pg/*for_extension.sql, + ./raster/rt_pg/*for_extension.sql.in, + ./raster/rt_pg/*upgrade*.sql, + ./raster/rt_pg/*upgrade*.sql.in, + ./regress/*garden_result.txt, + ./autom4te.cache/**, + ./build-aux/**, + .deps/**, + .libs/**, + **/.deps/**, + **/.libs/**, + ./regress/00-regress-install/**, + *.po, + *.o, + *.lo, + *.la, + *.a, + *.so, + *.so.*, + *.dll, + *.dylib, + *.pyc, + *.tmp, + *.generated, + *.needlessly-hardcoded, + *.gcda, + *.gcno, + *.gcov, + *~ diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index 617153b0b..a575d9bdd 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -22,11 +22,17 @@ jobs: - name: 'Install codespell' run: | sudo apt-get update - sudo apt-get install -y --no-install-recommends libxml2-utils docbook-xml docbook-xsl docbook-xsl-ns xsltproc + sudo apt-get install -y --no-install-recommends \ + autoconf automake libtool pkg-config \ + postgresql-server-dev-all \ + libgeos-dev libproj-dev libxml2-dev \ + libxml2-utils docbook-xml docbook-xsl docbook-xsl-ns xsltproc sudo pip install codespell - name: 'Build & Test' run: | codespell --version + ./autogen.sh + ./configure --without-raster --without-topology --without-sfcgal --without-json --without-protobuf make -C doc comments - ./utils/check_spelling.sh + codespell --config .codespellrc . diff --git a/GNUmakefile.in b/GNUmakefile.in index e468eed66..2318fc9a7 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -307,7 +307,7 @@ endif check-spell: ifneq (@CODESPELL@,) - cd $(top_srcdir) && ./utils/check_spelling.sh @CODESPELL@ + cd $(top_srcdir) && @CODESPELL@ --config .codespellrc . else @echo "SKIP: spell checking disabled" endif diff --git a/utils/check_spelling.sh b/utils/check_spelling.sh deleted file mode 100755 index 5537675ed..000000000 --- a/utils/check_spelling.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/sh - -set -eu - -CODESPELL=${1:-codespell} - -ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) -cd "$ROOT" - -tmpfiles=$(mktemp) -trap 'rm -f "$tmpfiles"' EXIT HUP INT TERM - -# Keep the check deterministic by starting from tracked files and excluding -# vendor data, generated trees, and authoritative datasets that are not prose. -git ls-files -z -- . \ - ':(exclude)deps' \ - ':(exclude)extensions/address_standardizer' \ - ':(exclude)doc/html' \ - ':(exclude)doc/po' \ - ':(exclude)doc/postgis-out.xml' \ - ':(exclude)doc/postgis-nospecial.xml' \ - ':(exclude)aclocal.m4' \ - ':(exclude)configure' \ - ':(exclude)macros/libtool.m4' \ - ':(exclude)spatial_ref_sys.sql' \ - ':(exclude)extensions/postgis/sql/spatial_ref_sys.sql' \ - ':(glob,exclude)extensions/postgis/sql/postgis--*.sql' \ - ':(glob,exclude)**/*.po' \ - > "$tmpfiles" - -# The comment SQL files are generated from the docs and shipped in release -# artifacts, so include them when they exist. -for generated in doc/postgis_comments.sql \ - doc/raster_comments.sql \ - doc/sfcgal_comments.sql \ - doc/tiger_geocoder_comments.sql \ - doc/topology_comments.sql -do - if [ -f "$generated" ]; then - printf '%s\0' "$generated" >> "$tmpfiles" - fi -done - -xargs -0 "$CODESPELL" --config .codespellrc < "$tmpfiles" commit 51fc9568c2fe7507600a97393dedba1d43f2d102 Author: Darafei Praliaskouski Date: Fri Mar 6 20:58:20 2026 +0400 sfcgal/tests: restore 2-component alpha shape expectations diff --git a/sfcgal/regress/alphashape_components.sql b/sfcgal/regress/alphashape_components.sql index 3dcfa350c..38e896ffd 100644 --- a/sfcgal/regress/alphashape_components.sql +++ b/sfcgal/regress/alphashape_components.sql @@ -1,6 +1,4 @@ --- Normalize POLYGON vs MULTIPOLYGON output so this SFCGAL 2.3+ regression --- checks the stable shape result rather than a raw return-type difference. SELECT 'CG_Optimalalphashape_2components', - ST_AsText(ST_Normalize(ST_Multi(CG_OptimalAlphaShape('MULTIPOINT((10.1 0.2),(8.1 0.1),(6.0 0.0),(4.2 0.3),(2.5 1.0),(1.2 2.3),(0.4 4.0),(0.1 6.1),(0.3 8.2),(1.1 10.1),(2.6 11.2),(4.1 11.9),(6.2 12.1),(8.3 11.8),(10.2 11.1),(9.1 9.9),(7.6 9.8),(6.1 9.9),(4.8 9.2),(3.8 8.0),(3.6 6.2),(3.7 4.1),(4.6 2.9),(6.0 2.3),(7.8 2.2),(9.2 2.4),(40.3 0.4),(40.1 3.1),(39.8 6.2),(40.4 9.0),(40.2 12.3),(40.5 15.2),(41.9 15.6),(43.1 15.3),(54.3 15.2),(55.8 15.0),(55.6 12.1),(55.9 9.2),(55.5 6.0),(55.7 3.3),(55.4 0.5),(52.6 0.1),(49.8 -0.2),(46.9 2.8),(44.2 0.2),(42.1 0.3),(43.0 3.8),(43.3 7.1),(43.1 10.4),(52.9 10.6),(52.7 7.3),(52.8 4.1))', allow_holes => false, nb_components => 2)))); + ST_AsText(CG_OptimalAlphaShape('MULTIPOINT((10.1 0.2),(8.1 0.1),(6.0 0.0),(4.2 0.3),(2.5 1.0),(1.2 2.3),(0.4 4.0),(0.1 6.1),(0.3 8.2),(1.1 10.1),(2.6 11.2),(4.1 11.9),(6.2 12.1),(8.3 11.8),(10.2 11.1),(9.1 9.9),(7.6 9.8),(6.1 9.9),(4.8 9.2),(3.8 8.0),(3.6 6.2),(3.7 4.1),(4.6 2.9),(6.0 2.3),(7.8 2.2),(9.2 2.4),(40.3 0.4),(40.1 3.1),(39.8 6.2),(40.4 9.0),(40.2 12.3),(40.5 15.2),(41.9 15.6),(43.1 15.3),(54.3 15.2),(55.8 15.0),(55.6 12.1),(55.9 9.2),(55.5 6.0),(55.7 3.3),(55.4 0.5),(52.6 0.1),(49.8 -0.2),(46.9 2.8),(44.2 0.2),(42.1 0.3),(43.0 3.8),(43.3 7.1),(43.1 10.4),(52.9 10.6),(52.7 7.3),(52.8 4.1))', allow_holes => false, nb_components => 2)); SELECT 'CG_OptimalAlphaShape_hole_2components', - ST_AsText(ST_Normalize(ST_Multi(CG_OptimalAlphaShape('MULTIPOINT((0 0),(0 1),(0 2),(0 3),(0 4),(0 5),(0 6),(0 7),(0 8),(0 9),(1 10),(2 10),(3 10),(4 10),(4.5 9.5),(5 9),(5.5 8.5),(6 8),(6 7),(6 6),(5.5 5.5),(5 5),(4 5),(3 5),(2 5),(1 5),(1 4),(2 4),(3 4),(4 4),(4.5 3.5),(5 3),(6 2),(6 1),(5.5 0.5),(5 0),(4 0),(3 0),(2 0),(1 0),(0.5 0),(0.5 1),(0.5 2),(0.5 3),(0.5 4),(0.5 5),(0.5 6),(0.5 7),(0.5 8),(0.5 9),(0.5 10),(1 9.5),(2 9.5),(3 9.5),(4 9.5),(4.5 9),(5 8.5),(5.5 8),(5.5 7),(5.5 6),(5.5 6.5),(5 5.5),(4 5.5),(3 5.5),(2 5.5),(1 5.5),(1.5 4.5),(2.5 4.5),(3.5 4.5),(4 4.5),(4.5 4),(5 3.5),(5.5 3),(5.5 2),(5.5 1),(5 0.5),(4 0.5),(3 0.5),(2 0.5),(1 0.5),(12 0),(12 1),(12 2),(12 3),(12 4),(12 5),(12 6),(12 7),(12 8),(12 9),(12 10),(13 10),(14 10),(15 10),(16 10),(16.5 9.5),(17 9),(17.5 8.5),(18 8),(18 7),(18 6),(17.5 5.5),(17 5),(16 5),(15 5),(14 5),(13 5),(12.5 0),(12.5 1),(12.5 2),(12.5 3),(12.5 4),(12.5 5),(12.5 6),(12.5 7),(12.5 8),(12.5 9),(12.5 10),(13 9.5),(14 9.5),(15 9.5) ,(16 9.5),(16.5 9),(17 8.5),(17.5 8),(17.5 7),(17.5 6),(17.5 6.5),(17 5.5),(16 5.5),(15 5.5),(14 5.5),(13 5.5),(13 1),(13 2),(13 3),(13 4),(17.5 7.4),(18 7.3),(5.1 2.5),(5.8 2.5),(0.03 9.82),(0.23 10))', allow_holes => true, nb_components => 2)))); + ST_AsText(CG_OptimalAlphaShape('MULTIPOINT((0 0),(0 1),(0 2),(0 3),(0 4),(0 5),(0 6),(0 7),(0 8),(0 9),(1 10),(2 10),(3 10),(4 10),(4.5 9.5),(5 9),(5.5 8.5),(6 8),(6 7),(6 6),(5.5 5.5),(5 5),(4 5),(3 5),(2 5),(1 5),(1 4),(2 4),(3 4),(4 4),(4.5 3.5),(5 3),(6 2),(6 1),(5.5 0.5),(5 0),(4 0),(3 0),(2 0),(1 0),(0.5 0),(0.5 1),(0.5 2),(0.5 3),(0.5 4),(0.5 5),(0.5 6),(0.5 7),(0.5 8),(0.5 9),(0.5 10),(1 9.5),(2 9.5),(3 9.5),(4 9.5),(4.5 9),(5 8.5),(5.5 8),(5.5 7),(5.5 6),(5.5 6.5),(5 5.5),(4 5.5),(3 5.5),(2 5.5),(1 5.5),(1.5 4.5),(2.5 4.5),(3.5 4.5),(4 4.5),(4.5 4),(5 3.5),(5.5 3),(5.5 2),(5.5 1),(5 0.5),(4 0.5),(3 0.5),(2 0.5),(1 0.5),(12 0),(12 1),(12 2),(12 3),(12 4),(12 5),(12 6),(12 7),(12 8),(12 9),(12 10),(13 10),(14 10),(15 10),(16 10),(16.5 9.5),(17 9),(17.5 8.5),(18 8),(18 7),(18 6),(17.5 5.5),(17 5),(16 5),(15 5),(14 5),(13 5),(12.5 0),(12.5 1),(12.5 2),(12.5 3),(12.5 4),(12.5 5),(12.5 6),(12.5 7),(12.5 8),(12.5 9),(12.5 10),(13 9.5),(14 9.5),(15 9.5),(16 9.5),(16.5 9),(17 8.5),(17.5 8),(17.5 7),(17.5 6),(17.5 6.5),(17 5.5),(16 5.5),(15 5.5),(14 5.5),(13 5.5),(13 1),(13 2),(13 3),(13 4),(17.5 7.4),(18 7.3),(5.1 2.5),(5.8 2.5),(0.03 9.82),(0.23 10))', allow_holes => true, nb_components => 2)); diff --git a/sfcgal/regress/alphashape_components_expected b/sfcgal/regress/alphashape_components_expected index 00efc058f..a30a4ad59 100644 --- a/sfcgal/regress/alphashape_components_expected +++ b/sfcgal/regress/alphashape_components_expected @@ -1,2 +1,2 @@ -CG_Optimalalphashape_2components|MULTIPOLYGON(((39.8 6.2,40.4 9,40.2 12.3,40.5 15.2,41.9 15.6,43.1 15.3,43.1 10.4,43.3 7.1,46.9 2.8,52.8 4.1,52.7 7.3,52.9 10.6,54.3 15.2,55.8 15,55.6 12.1,55.9 9.2,55.5 6,55.7 3.3,55.4 0.5,52.6 0.1,49.8 -0.2,44.2 0.2,42.1 0.3,40.3 0.4,40.1 3.1,39.8 6.2)),((0.1 6.1,0.3 8.2,1.1 10.1,2.6 11.2,4.1 11.9,6.2 12.1,8.3 11.8,10.2 11.1,9.1 9.9,7.6 9.8,3.6 6.2,6 2.3,7.8 2.2,9.2 2.4,10.1 0.2,8.1 0.1,6 0,4.2 0.3,2.5 1,1.2 2.3,0.4 4,0.1 6.1))) -CG_OptimalAlphaShape_hole_2components|MULTIPOLYGON(((0 0,0 1,0 2,0 3,0 4,0 5,0 6,0 7,0 8,0 9,0.03 9.82,0.23 10,0.5 10,1 10,2 10,3 10,4 10,4.5 9.5,5 9,5.5 8.5,6 8,6 7,6 6,5.5 5.5,5 5,4 4.5,4.5 4,5 3.5,5.5 3,5.8 2.5,6 2,6 1,5.5 0.5,5 0,4 0,3 0,2 0,1 0,0.5 0,0 0),(0.5 6,1 5.5,2 5.5,3 5.5,4 5.5,5 5.5,5.5 6,5.5 6.5,5.5 7,5.5 8,5 8.5,4.5 9,4 9.5,3 9.5,2 9.5,1 9.5,0.5 9,0.5 8,0.5 7,0.5 6),(0.5 1,1 0.5,2 0.5,3 0.5,4 0.5,5 0.5,5.5 1,5.5 2,5.1 2.5,5 3,4.5 3.5,4 4,3 4,2 4,1 4,0.5 3,0.5 2,0.5 1)),((12 0,12 1,12 2,12 3,12 4,12 5,12 6,12 7,12 8,12 9,12 10,12.5 10,13 10,14 10,15 10,16 10,16.5 9.5,17 9,17.5 8.5,18 8,18 7.3,18 7,18 6,17.5 5.5,17 5,16 5,15 5,14 5,13 5,13 4,13 3,13 2,13 1,12.5 0,12 0),(12.5 6,13 5.5,14 5.5,15 5.5,16 5.5,17 5.5,17.5 6,17.5 6.5,17.5 7,17.5 7.4,17.5 8,17 8.5,16.5 9,16 9.5,15 9.5,14 9.5,13 9.5,12.5 9,12.5 8,12.5 7,12.5 6))) +CG_Optimalalphashape_2components|MULTIPOLYGON(((8.3 11.8,6.2 12.1,4.1 11.9,2.6 11.2,1.1 10.1,0.3 8.2,0.1 6.1,0.4 4,1.2 2.3,2.5 1,4.2 0.3,6 0,8.1 0.1,10.1 0.2,9.2 2.4,7.8 2.2,6 2.3,3.6 6.2,7.6 9.8,9.1 9.9,10.2 11.1,8.3 11.8)),((55.6 12.1,55.8 15,54.3 15.2,52.9 10.6,52.7 7.3,52.8 4.1,46.9 2.8,43.3 7.1,43.1 10.4,43.1 15.3,41.9 15.6,40.5 15.2,40.2 12.3,40.4 9,39.8 6.2,40.1 3.1,40.3 0.4,42.1 0.3,44.2 0.2,49.8 -0.2,52.6 0.1,55.4 0.5,55.7 3.3,55.5 6,55.9 9.2,55.6 12.1))) +CG_OptimalAlphaShape_hole_2components|MULTIPOLYGON(((5.5 8.5,5 9,4.5 9.5,4 10,3 10,2 10,1 10,0.5 10,0.23 10,0.03 9.82,0 9,0 8,0 7,0 6,0 5,0 4,0 3,0 2,0 1,0 0,0.5 0,1 0,2 0,3 0,4 0,5 0,5.5 0.5,6 1,6 2,5.8 2.5,5.5 3,5 3.5,4.5 4,4 4.5,5 5,5.5 5.5,6 6,6 7,6 8,5.5 8.5),(0.5 2,0.5 3,1 4,2 4,3 4,4 4,4.5 3.5,5 3,5.1 2.5,5.5 2,5.5 1,5 0.5,4 0.5,3 0.5,2 0.5,1 0.5,0.5 1,0.5 2),(0.5 7,0.5 8,0.5 9,1 9.5,2 9.5,3 9.5,4 9.5,4.5 9,5 8.5,5.5 8,5.5 7,5.5 6.5,5.5 6,5 5.5,4 5.5,3 5.5,2 5.5,1 5.5,0.5 6,0.5 7)),((17.5 8.5,17 9,16.5 9.5,16 10,15 10,14 10,13 10,12.5 10,12 10,12 9,12 8,12 7,12 6,12 5,12 4,12 3,12 2,12 1,12 0,12.5 0,13 1,13 2,13 3,13 4,13 5,14 5,15 5,16 5,17 5,17.5 5.5,18 6,18 7,18 7.3,18 8,17.5 8.5),(12.5 7,12.5 8,12.5 9,13 9.5,14 9.5,15 9.5,16 9.5,16.5 9,17 8.5,17.5 8,17.5 7.4,17.5 7,17.5 6.5,17.5 6,17 5.5,16 5.5,15 5.5,14 5.5,13 5.5,12.5 6,12.5 7))) commit ee2614b25095b2c256a8f167601e68605587f93d Author: Darafei Praliaskouski Date: Fri Mar 6 20:41:35 2026 +0400 doc/uk: fix localized XML markup diff --git a/doc/po/uk/postgis-manual.po b/doc/po/uk/postgis-manual.po index 62e629932..9cb094ad0 100644 --- a/doc/po/uk/postgis-manual.po +++ b/doc/po/uk/postgis-manual.po @@ -4750,7 +4750,7 @@ msgid "" "topogeometries created before the upgrade. This function fixes this " "corruption in affected tables." msgstr "" -"??? ????????? ????????? PostGIS <3.6.0 ?? ?????? >3.6.0+ ???? ??????? " +"??? ????????? ????????? PostGIS <3.6.0 ?? ?????? >3.6.0+ ???? ??????? " "?????????? ??????? topogeometry. ?? ?????????? ??????????? ?????????????, " "????????? ?? ?????????. ?? ??????? ????????? ?? ??????????? ? ???????? " "????????." @@ -8653,7 +8653,7 @@ msgid "" msgstr "" "??? ????????? ?????????, ?? ???????????????? ? ????????????, ????????? " "???????? GraphicsMagick (gm convert). GraphicsMagick " -"???????? ?? ??????? " +"???????? ?? ??????? " "http://www.graphicsmagick.org/ ." #. Tag: title @@ -44475,8 +44475,8 @@ msgid "" "postgresql.org/docs/current/rowtypes.html\">composite data type " "containing the fields:" msgstr "" -"geometry_dump ? ?? ???????? ??? ?????, ?? " +"geometry_dump ? ?? ???????? ??? ?????, ?? " "??????? ???? ????:" #. Tag: para ----------------------------------------------------------------------- Summary of changes: .codespellrc | 50 +++++++++++++++++++++++++-- .github/workflows/codespell.yml | 10 ++++-- GNUmakefile.in | 2 +- doc/po/uk/postgis-manual.po | 8 ++--- sfcgal/regress/alphashape_components.sql | 6 ++-- sfcgal/regress/alphashape_components_expected | 4 +-- utils/check_spelling.sh | 44 ----------------------- 7 files changed, 65 insertions(+), 59 deletions(-) delete mode 100755 utils/check_spelling.sh hooks/post-receive -- PostGIS From git at osgeo.org Fri Mar 6 10:41:36 2026 From: git at osgeo.org (git at osgeo.org) Date: Fri, 6 Mar 2026 10:41:36 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-370-g9346e2beb Message-ID: <20260306184136.3F2EE188537@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 9346e2beb44b2b6c873f48dc62e5a2699ef48d44 (commit) from be42c33700f1f4bd34ae8ee181509cf1e89de680 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9346e2beb44b2b6c873f48dc62e5a2699ef48d44 Author: Darafei Praliaskouski Date: Fri Mar 6 21:52:02 2026 +0400 ci: drop PostgreSQL dev package from codespell job diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index a575d9bdd..2549dbc79 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -23,11 +23,10 @@ jobs: run: | sudo apt-get update sudo apt-get install -y --no-install-recommends \ + codespell \ autoconf automake libtool pkg-config \ - postgresql-server-dev-all \ libgeos-dev libproj-dev libxml2-dev \ libxml2-utils docbook-xml docbook-xsl docbook-xsl-ns xsltproc - sudo pip install codespell - name: 'Build & Test' run: | ----------------------------------------------------------------------- Summary of changes: .github/workflows/codespell.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Fri Mar 6 11:01:15 2026 From: git at osgeo.org (git at osgeo.org) Date: Fri, 6 Mar 2026 11:01:15 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-371-g15349103e Message-ID: <20260306190115.D7F4D1886BD@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 15349103ef89627d9be54a67bd81eabed3ca1072 (commit) from 9346e2beb44b2b6c873f48dc62e5a2699ef48d44 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 15349103ef89627d9be54a67bd81eabed3ca1072 Author: Darafei Praliaskouski Date: Fri Mar 6 22:59:46 2026 +0400 ci: note why codespell still uses pip diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml index 2549dbc79..efb5f0bf5 100644 --- a/.github/workflows/codespell.yml +++ b/.github/workflows/codespell.yml @@ -23,10 +23,12 @@ jobs: run: | sudo apt-get update sudo apt-get install -y --no-install-recommends \ - codespell \ autoconf automake libtool pkg-config \ libgeos-dev libproj-dev libxml2-dev \ libxml2-utils docbook-xml docbook-xsl docbook-xsl-ns xsltproc + # Ubuntu's packaged codespell is too old for the skip globs in .codespellrc, + # which makes the job scan generated/vendor trees and fail noisily. + sudo pip install codespell - name: 'Build & Test' run: | ----------------------------------------------------------------------- Summary of changes: .github/workflows/codespell.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) hooks/post-receive -- PostGIS From trac at osgeo.org Fri Mar 6 12:58:44 2026 From: trac at osgeo.org (PostGIS) Date: Fri, 06 Mar 2026 20:58:44 -0000 Subject: [PostGIS] #6055: Specify search_path carefully during extension install Message-ID: <049.b6be645ea57dbb71051ae75581b93595@osgeo.org> #6055: Specify search_path carefully during extension install ---------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: high | Milestone: PostGIS 3.6.2 Component: postgis | Version: 3.2.x Keywords: | ---------------------+--------------------------- In order to keep the permissions situation clean during extension install. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Fri Mar 6 13:11:45 2026 From: git at osgeo.org (git at osgeo.org) Date: Fri, 6 Mar 2026 13:11:45 -0800 (PST) Subject: [SCM] PostGIS branch stable-3.3 updated. 3.3.9-4-g9562c2020 Message-ID: <20260306211145.B9BFF197DFD@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.3 has been updated via 9562c2020b0ecac01cec2d7877666425b41e81a8 (commit) from 1ff46f6490e1ffb1506d9f6bf84188b9179282e7 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9562c2020b0ecac01cec2d7877666425b41e81a8 Author: Paul Ramsey Date: Fri Mar 6 13:11:11 2026 -0800 Remove rare extension priv escalation case, where account with extension create privs can escalate to superuser by piggy backing on an extension creation event. From Sven Klemm (Tiger Data) and Allistair Ishmael Hakim (allistair.sh) References #6055 diff --git a/NEWS b/NEWS index ff1eb5bf2..95563125a 100644 --- a/NEWS +++ b/NEWS @@ -4,7 +4,10 @@ PostGIS 3.3.10 * Bug Fixes and Enhancements * - #5998, [tiger_geododer] Do not create tiger_data as part - of postgis_tiger_geocoder extension, create/update (Regina Obe) + of postgis_tiger_geocoder extension, create/update (Regina Obe) + - #6055, Remove rare extension priv escalation case. + Reported by Sven Klemm (Tiger Data) and Allistair Ishmael Hakim (allistair.sh) + PostGIS 3.3.9 2026-02-09 diff --git a/libpgcommon/sql/AddToSearchPath.sql.inc b/libpgcommon/sql/AddToSearchPath.sql.inc index a5e02279e..ff313406c 100644 --- a/libpgcommon/sql/AddToSearchPath.sql.inc +++ b/libpgcommon/sql/AddToSearchPath.sql.inc @@ -16,10 +16,10 @@ DECLARE BEGIN WITH settings AS ( SELECT unnest(setconfig) config - FROM pg_db_role_setting + FROM pg_catalog.pg_db_role_setting WHERE setdatabase = ( SELECT oid - FROM pg_database + FROM pg_catalog.pg_database WHERE datname = current_database() ) and setrole = 0 ) @@ -30,10 +30,10 @@ BEGIN RAISE NOTICE 'cur_search_path from pg_db_role_setting is %', var_cur_search_path; -- only run this test if person creating the extension is a super user - IF var_cur_search_path IS NULL AND (SELECT rolsuper FROM pg_roles where rolname = CURRENT_USER) THEN + IF var_cur_search_path IS NULL AND (SELECT rolsuper FROM pg_catalog.pg_roles where rolname = CURRENT_USER) THEN SELECT setting INTO var_cur_search_path - FROM pg_file_settings + FROM pg_catalog.pg_file_settings WHERE name = 'search_path' AND applied; RAISE NOTICE 'cur_search_path from pg_file_settings is %', var_cur_search_path; @@ -42,7 +42,7 @@ BEGIN IF var_cur_search_path IS NULL THEN SELECT boot_val INTO var_cur_search_path - FROM pg_settings + FROM pg_catalog.pg_settings WHERE name = 'search_path'; RAISE NOTICE 'cur_search_path from pg_settings is %', var_cur_search_path; @@ -63,7 +63,8 @@ BEGIN RETURN var_result; END $BODY$ -SET search_path = pg_catalog -- make safe +-- explicitly move pg_temp after pg_catalog in search path +SET search_path = pg_catalog, pg_temp LANGUAGE 'plpgsql' VOLATILE STRICT ; ----------------------------------------------------------------------- Summary of changes: NEWS | 5 ++++- libpgcommon/sql/AddToSearchPath.sql.inc | 13 +++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Fri Mar 6 13:11:56 2026 From: trac at osgeo.org (PostGIS) Date: Fri, 06 Mar 2026 21:11:56 -0000 Subject: [PostGIS] #6055: Specify search_path carefully during extension install In-Reply-To: <049.b6be645ea57dbb71051ae75581b93595@osgeo.org> References: <049.b6be645ea57dbb71051ae75581b93595@osgeo.org> Message-ID: <064.2cfae4dc0297d1034d37f0188d237d9c@osgeo.org> #6055: Specify search_path carefully during extension install ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: high | Milestone: PostGIS 3.6.2 Component: postgis | Version: 3.2.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"9562c2020b0ecac01cec2d7877666425b41e81a8/git" 9562c20/git]: {{{#!CommitTicketReference repository="git" revision="9562c2020b0ecac01cec2d7877666425b41e81a8" Remove rare extension priv escalation case, where account with extension create privs can escalate to superuser by piggy backing on an extension creation event. From Sven Klemm (Tiger Data) and Allistair Ishmael Hakim (allistair.sh) References #6055 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Fri Mar 6 13:13:18 2026 From: git at osgeo.org (git at osgeo.org) Date: Fri, 6 Mar 2026 13:13:18 -0800 (PST) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.5-2-gd1b44c115 Message-ID: <20260306211318.7B168189495@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via d1b44c115e202fbec8fb6238f821f38b7efc6ef0 (commit) from 9e5f4cbde747366e62bcd93a9ac30601e310fa6f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d1b44c115e202fbec8fb6238f821f38b7efc6ef0 Author: Paul Ramsey Date: Fri Mar 6 13:13:06 2026 -0800 Remove rare extension priv escalation case, where account with extension create privs can escalate to superuser by piggy backing on an extension creation event. From Sven Klemm (Tiger Data) and Allistair Ishmael Hakim (allistair.sh) References #6055 diff --git a/NEWS b/NEWS index 3dead9499..a66c75e0d 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,10 @@ PostgreSQL 12-18 required. GEOS 3.8+ required. Proj 6.1+ required. * Bug fixes * + - #6055, Remove rare extension priv escalation case. + Reported by Sven Klemm (Tiger Data) and Allistair Ishmael Hakim (allistair.sh) + + PostGIS 3.5.5 2026/02/09 diff --git a/libpgcommon/sql/AddToSearchPath.sql.inc b/libpgcommon/sql/AddToSearchPath.sql.inc index a5e02279e..ff313406c 100644 --- a/libpgcommon/sql/AddToSearchPath.sql.inc +++ b/libpgcommon/sql/AddToSearchPath.sql.inc @@ -16,10 +16,10 @@ DECLARE BEGIN WITH settings AS ( SELECT unnest(setconfig) config - FROM pg_db_role_setting + FROM pg_catalog.pg_db_role_setting WHERE setdatabase = ( SELECT oid - FROM pg_database + FROM pg_catalog.pg_database WHERE datname = current_database() ) and setrole = 0 ) @@ -30,10 +30,10 @@ BEGIN RAISE NOTICE 'cur_search_path from pg_db_role_setting is %', var_cur_search_path; -- only run this test if person creating the extension is a super user - IF var_cur_search_path IS NULL AND (SELECT rolsuper FROM pg_roles where rolname = CURRENT_USER) THEN + IF var_cur_search_path IS NULL AND (SELECT rolsuper FROM pg_catalog.pg_roles where rolname = CURRENT_USER) THEN SELECT setting INTO var_cur_search_path - FROM pg_file_settings + FROM pg_catalog.pg_file_settings WHERE name = 'search_path' AND applied; RAISE NOTICE 'cur_search_path from pg_file_settings is %', var_cur_search_path; @@ -42,7 +42,7 @@ BEGIN IF var_cur_search_path IS NULL THEN SELECT boot_val INTO var_cur_search_path - FROM pg_settings + FROM pg_catalog.pg_settings WHERE name = 'search_path'; RAISE NOTICE 'cur_search_path from pg_settings is %', var_cur_search_path; @@ -63,7 +63,8 @@ BEGIN RETURN var_result; END $BODY$ -SET search_path = pg_catalog -- make safe +-- explicitly move pg_temp after pg_catalog in search path +SET search_path = pg_catalog, pg_temp LANGUAGE 'plpgsql' VOLATILE STRICT ; ----------------------------------------------------------------------- Summary of changes: NEWS | 4 ++++ libpgcommon/sql/AddToSearchPath.sql.inc | 13 +++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Fri Mar 6 13:13:19 2026 From: trac at osgeo.org (PostGIS) Date: Fri, 06 Mar 2026 21:13:19 -0000 Subject: [PostGIS] #6055: Specify search_path carefully during extension install In-Reply-To: <049.b6be645ea57dbb71051ae75581b93595@osgeo.org> References: <049.b6be645ea57dbb71051ae75581b93595@osgeo.org> Message-ID: <064.6eb26462d610fdf96baa7f583f214187@osgeo.org> #6055: Specify search_path carefully during extension install ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: high | Milestone: PostGIS 3.6.2 Component: postgis | Version: 3.2.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"d1b44c115e202fbec8fb6238f821f38b7efc6ef0/git" d1b44c1/git]: {{{#!CommitTicketReference repository="git" revision="d1b44c115e202fbec8fb6238f821f38b7efc6ef0" Remove rare extension priv escalation case, where account with extension create privs can escalate to superuser by piggy backing on an extension creation event. From Sven Klemm (Tiger Data) and Allistair Ishmael Hakim (allistair.sh) References #6055 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Fri Mar 6 13:14:17 2026 From: git at osgeo.org (git at osgeo.org) Date: Fri, 6 Mar 2026 13:14:17 -0800 (PST) Subject: [SCM] PostGIS branch stable-3.6 updated. 3.6.2-2-g20e9ab657 Message-ID: <20260306211417.ABAE9189422@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.6 has been updated via 20e9ab6572a45f5264b033fc1414646a7c0d5190 (commit) from 815ee4faea67d929dc80cbb1f52c81085f31064d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 20e9ab6572a45f5264b033fc1414646a7c0d5190 Author: Paul Ramsey Date: Fri Mar 6 13:14:06 2026 -0800 Remove rare extension priv escalation case, where account with extension create privs can escalate to superuser by piggy backing on an extension creation event. From Sven Klemm (Tiger Data) and Allistair Ishmael Hakim (allistair.sh) References #6055 diff --git a/NEWS b/NEWS index 362a04829..701e08eeb 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,9 @@ topogeometry corruption: * Fixes * +- #6055, Remove rare extension priv escalation case. + Reported by Sven Klemm (Tiger Data) and Allistair Ishmael Hakim (allistair.sh) + PostGIS 3.6.2 2026/02/09 diff --git a/libpgcommon/sql/AddToSearchPath.sql.inc b/libpgcommon/sql/AddToSearchPath.sql.inc index a5e02279e..ff313406c 100644 --- a/libpgcommon/sql/AddToSearchPath.sql.inc +++ b/libpgcommon/sql/AddToSearchPath.sql.inc @@ -16,10 +16,10 @@ DECLARE BEGIN WITH settings AS ( SELECT unnest(setconfig) config - FROM pg_db_role_setting + FROM pg_catalog.pg_db_role_setting WHERE setdatabase = ( SELECT oid - FROM pg_database + FROM pg_catalog.pg_database WHERE datname = current_database() ) and setrole = 0 ) @@ -30,10 +30,10 @@ BEGIN RAISE NOTICE 'cur_search_path from pg_db_role_setting is %', var_cur_search_path; -- only run this test if person creating the extension is a super user - IF var_cur_search_path IS NULL AND (SELECT rolsuper FROM pg_roles where rolname = CURRENT_USER) THEN + IF var_cur_search_path IS NULL AND (SELECT rolsuper FROM pg_catalog.pg_roles where rolname = CURRENT_USER) THEN SELECT setting INTO var_cur_search_path - FROM pg_file_settings + FROM pg_catalog.pg_file_settings WHERE name = 'search_path' AND applied; RAISE NOTICE 'cur_search_path from pg_file_settings is %', var_cur_search_path; @@ -42,7 +42,7 @@ BEGIN IF var_cur_search_path IS NULL THEN SELECT boot_val INTO var_cur_search_path - FROM pg_settings + FROM pg_catalog.pg_settings WHERE name = 'search_path'; RAISE NOTICE 'cur_search_path from pg_settings is %', var_cur_search_path; @@ -63,7 +63,8 @@ BEGIN RETURN var_result; END $BODY$ -SET search_path = pg_catalog -- make safe +-- explicitly move pg_temp after pg_catalog in search path +SET search_path = pg_catalog, pg_temp LANGUAGE 'plpgsql' VOLATILE STRICT ; ----------------------------------------------------------------------- Summary of changes: NEWS | 3 +++ libpgcommon/sql/AddToSearchPath.sql.inc | 13 +++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Fri Mar 6 13:14:19 2026 From: trac at osgeo.org (PostGIS) Date: Fri, 06 Mar 2026 21:14:19 -0000 Subject: [PostGIS] #6055: Specify search_path carefully during extension install In-Reply-To: <049.b6be645ea57dbb71051ae75581b93595@osgeo.org> References: <049.b6be645ea57dbb71051ae75581b93595@osgeo.org> Message-ID: <064.4769702f4ef135aac9817c4c33268446@osgeo.org> #6055: Specify search_path carefully during extension install ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: new Priority: high | Milestone: PostGIS 3.6.2 Component: postgis | Version: 3.2.x Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"20e9ab6572a45f5264b033fc1414646a7c0d5190/git" 20e9ab65/git]: {{{#!CommitTicketReference repository="git" revision="20e9ab6572a45f5264b033fc1414646a7c0d5190" Remove rare extension priv escalation case, where account with extension create privs can escalate to superuser by piggy backing on an extension creation event. From Sven Klemm (Tiger Data) and Allistair Ishmael Hakim (allistair.sh) References #6055 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Fri Mar 6 13:15:11 2026 From: git at osgeo.org (git at osgeo.org) Date: Fri, 6 Mar 2026 13:15:11 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-372-g88ad88be1 Message-ID: <20260306211511.EC5921890F7@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 88ad88be10d113781a2a8f4e67820a3cdb40638b (commit) from 15349103ef89627d9be54a67bd81eabed3ca1072 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 88ad88be10d113781a2a8f4e67820a3cdb40638b Author: Paul Ramsey Date: Fri Mar 6 11:28:09 2026 -0800 Remove rare extension priv escalation case, where account with extension create privs can escalate to superuser by piggy backing on an extension creation event. From Sven Klemm (Tiger Data) and Allistair Ishmael Hakim (allistair.sh) diff --git a/libpgcommon/sql/AddToSearchPath.sql.inc b/libpgcommon/sql/AddToSearchPath.sql.inc index a5e02279e..ff313406c 100644 --- a/libpgcommon/sql/AddToSearchPath.sql.inc +++ b/libpgcommon/sql/AddToSearchPath.sql.inc @@ -16,10 +16,10 @@ DECLARE BEGIN WITH settings AS ( SELECT unnest(setconfig) config - FROM pg_db_role_setting + FROM pg_catalog.pg_db_role_setting WHERE setdatabase = ( SELECT oid - FROM pg_database + FROM pg_catalog.pg_database WHERE datname = current_database() ) and setrole = 0 ) @@ -30,10 +30,10 @@ BEGIN RAISE NOTICE 'cur_search_path from pg_db_role_setting is %', var_cur_search_path; -- only run this test if person creating the extension is a super user - IF var_cur_search_path IS NULL AND (SELECT rolsuper FROM pg_roles where rolname = CURRENT_USER) THEN + IF var_cur_search_path IS NULL AND (SELECT rolsuper FROM pg_catalog.pg_roles where rolname = CURRENT_USER) THEN SELECT setting INTO var_cur_search_path - FROM pg_file_settings + FROM pg_catalog.pg_file_settings WHERE name = 'search_path' AND applied; RAISE NOTICE 'cur_search_path from pg_file_settings is %', var_cur_search_path; @@ -42,7 +42,7 @@ BEGIN IF var_cur_search_path IS NULL THEN SELECT boot_val INTO var_cur_search_path - FROM pg_settings + FROM pg_catalog.pg_settings WHERE name = 'search_path'; RAISE NOTICE 'cur_search_path from pg_settings is %', var_cur_search_path; @@ -63,7 +63,8 @@ BEGIN RETURN var_result; END $BODY$ -SET search_path = pg_catalog -- make safe +-- explicitly move pg_temp after pg_catalog in search path +SET search_path = pg_catalog, pg_temp LANGUAGE 'plpgsql' VOLATILE STRICT ; ----------------------------------------------------------------------- Summary of changes: libpgcommon/sql/AddToSearchPath.sql.inc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Fri Mar 6 13:15:30 2026 From: trac at osgeo.org (PostGIS) Date: Fri, 06 Mar 2026 21:15:30 -0000 Subject: [PostGIS] #6055: Specify search_path carefully during extension install In-Reply-To: <049.b6be645ea57dbb71051ae75581b93595@osgeo.org> References: <049.b6be645ea57dbb71051ae75581b93595@osgeo.org> Message-ID: <064.ec3b6705cd66b5ceaf05b306a3ea3db5@osgeo.org> #6055: Specify search_path carefully during extension install ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: closed Priority: high | Milestone: PostGIS 3.6.2 Component: postgis | Version: 3.2.x Resolution: fixed | Keywords: ----------------------+--------------------------- Changes (by pramsey): * resolution: => fixed * status: new => closed -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Sat Mar 7 03:01:57 2026 From: git at osgeo.org (git at osgeo.org) Date: Sat, 7 Mar 2026 03:01:57 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-373-g14152529d Message-ID: <20260307110157.9E1CC18C124@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 14152529d3f3008be89dbc76505521e819ae78d5 (commit) from 88ad88be10d113781a2a8f4e67820a3cdb40638b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 14152529d3f3008be89dbc76505521e819ae78d5 Author: Darafei Praliaskouski Date: Sat Mar 7 15:00:33 2026 +0400 Fix 32-bit topology and coverage crashes Two CI failures on i386 came from hard-coded Datum and stack struct assumptions that only break on 32-bit builds. In coverage_window_calculation(), the simplifyBoundary argument is declared as boolean in SQL, but the C code decoded it with DatumGetFloat8(). On 32-bit PostgreSQL float8 is pass-by-reference, so reading a bool Datum that way can dereference garbage and crash the backend while running coverage.sql. Decode the argument with DatumGetBool() instead. In the topology SPI backend, several callbacks unconditionally decoded topology primitive IDs with DatumGetInt64() and one face callback always built an INT8[] argument. Topology schemas still default to INT4 IDs unless usesLargeIDs is enabled, so those assumptions are wrong on 32-bit and caused addnode.sql to segfault or raise unsupported byval length errors. Load usesLargeIDs from topology.topology, decode tuple values using their actual column type, and build the face ID array with the matching integer width. Also zero-initialize temporary LWT_ISO_EDGE stack structs on edge split paths so callback update/select filters do not carry uninitialized fields into backend operations. diff --git a/liblwgeom/topo/lwgeom_topo.c b/liblwgeom/topo/lwgeom_topo.c index 07e7ba7cd..d92737705 100644 --- a/liblwgeom/topo/lwgeom_topo.c +++ b/liblwgeom/topo/lwgeom_topo.c @@ -1188,8 +1188,8 @@ lwt_ModEdgeSplit( LWT_TOPOLOGY* topo, LWT_ELEMID edge, LWCOLLECTION *split_col; const LWGEOM *oldedge_geom; const LWGEOM *newedge_geom; - LWT_ISO_EDGE newedge1; - LWT_ISO_EDGE seledge, updedge, excedge; + LWT_ISO_EDGE newedge1 = {0}; + LWT_ISO_EDGE seledge = {0}, updedge = {0}, excedge = {0}; int ret; split_col = _lwt_EdgeSplit( topo, edge, pt, skipISOChecks, &oldedge ); @@ -1345,8 +1345,8 @@ lwt_NewEdgesSplit( LWT_TOPOLOGY* topo, LWT_ELEMID edge, LWCOLLECTION *split_col; const LWGEOM *oldedge_geom; const LWGEOM *newedge_geom; - LWT_ISO_EDGE newedges[2]; - LWT_ISO_EDGE seledge, updedge; + LWT_ISO_EDGE newedges[2] = {{0}}; + LWT_ISO_EDGE seledge = {0}, updedge = {0}; int ret; split_col = _lwt_EdgeSplit( topo, edge, pt, skipISOChecks, &oldedge ); @@ -5611,10 +5611,9 @@ _lwt_SnapEdgeToExistingNode( replacedBy[n] = existingEdgeId; } - - LWT_ISO_EDGE updatedEdge; + LWT_ISO_EDGE updatedEdge = {0}; int updateFlags; - LWT_ISO_EDGE selEdge; + LWT_ISO_EDGE selEdge = {0}; if ( ( replacedBy[0] != 0 && replacedBy[1] == 0 ) || ( replacedBy[1] != 0 && replacedBy[0] == 0 ) ) @@ -6129,7 +6128,7 @@ _lwt_SnapEdgeToExistingNode( /* Neither sides of the snapped edge collapsed to an existing edge */ /* New edge is the outgoing one, by design */ - LWT_ISO_EDGE newEdge; + LWT_ISO_EDGE newEdge = {0}; newEdge.edge_id = lwt_be_getNextEdgeId( topo ); if ( newEdge.edge_id == -1 ) { PGTOPO_BE_ERROR(); diff --git a/postgis/lwgeom_window.c b/postgis/lwgeom_window.c index 409b94503..920f2716d 100644 --- a/postgis/lwgeom_window.c +++ b/postgis/lwgeom_window.c @@ -784,7 +784,9 @@ coverage_window_calculation(PG_FUNCTION_ARGS, int mode) if (!isnull) tolerance = DatumGetFloat8(d); d = WinGetFuncArgCurrent(winobj, 2, &isnull); - if (!isnull) simplifyBoundary = DatumGetFloat8(d); + /* The third SQL argument is boolean, which matters on 32-bit builds. */ + if (!isnull) + simplifyBoundary = DatumGetBool(d); /* GEOSCoverageSimplifyVW is "preserveBoundary" so we invert simplifyBoundary */ output = GEOSCoverageSimplifyVW(input, tolerance, !simplifyBoundary); diff --git a/topology/postgis_topology.c b/topology/postgis_topology.c index 7707ece2b..b815cb901 100644 --- a/topology/postgis_topology.c +++ b/topology/postgis_topology.c @@ -92,6 +92,7 @@ struct LWT_BE_TOPOLOGY_T int32_t srid; double precision; int hasZ; + bool usesLargeIDs; Oid geometryOID; }; @@ -180,8 +181,8 @@ cb_loadTopologyByName(const LWT_BE_DATA* be, const char *name) argtypes[0] = CSTRINGOID; sql = - "SELECT id,srid,precision,null::geometry " - "FROM topology.topology WHERE name = $1::varchar"; + "SELECT id,srid,precision,null::geometry,useslargeids " + "FROM topology.topology WHERE name = $1::varchar"; if ( ! plan ) /* prepare on first call */ { plan = SPI_prepare(sql, 1, argtypes); @@ -226,6 +227,7 @@ cb_loadTopologyByName(const LWT_BE_DATA* be, const char *name) topo->be_data = (LWT_BE_DATA *)be; /* const cast.. */ topo->name = pstrdup(name); topo->hasZ = 0; + topo->usesLargeIDs = false; dat = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull); if ( isnull ) @@ -262,6 +264,12 @@ cb_loadTopologyByName(const LWT_BE_DATA* be, const char *name) topo->precision = DatumGetFloat8(dat); } + dat = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 5, &isnull); + if (!isnull) + { + topo->usesLargeIDs = DatumGetBool(dat); + } + /* we're dynamically querying geometry type here */ topo->geometryOID = TupleDescAttr(SPI_tuptable->tupdesc, 3)->atttypid; @@ -666,6 +674,31 @@ addFaceValues(StringInfo str, LWT_ISO_FACE *face, int32_t srid) } } +static int64 +tuple_get_int64(TupleDesc desc, int col, Datum dat) +{ + Oid typid = TupleDescAttr(desc, col - 1)->atttypid; + + /* + * Topology still defaults to INT4 primitive IDs unless usesLargeIDs is + * requested, so SPI tuple readers must honor the actual column type here. + */ + switch (typid) + { + case INT2OID: + return DatumGetInt16(dat); + case INT4OID: + return DatumGetInt32(dat); + case INT8OID: + return DatumGetInt64(dat); + case OIDOID: + return DatumGetObjectId(dat); + default: + lwpgerror("Unexpected integer type %u for column %d", typid, col); + return -1; + } +} + static void fillEdgeFields(LWT_ISO_EDGE* edge, HeapTuple row, TupleDesc rowdesc, int fields) { @@ -689,11 +722,13 @@ fillEdgeFields(LWT_ISO_EDGE* edge, HeapTuple row, TupleDesc rowdesc, int fields) } else { - val = DatumGetInt64(dat); - POSTGIS_DEBUGF(2, "fillEdgeFields: colno%d (edge_id)" - " has int64 val of %" LWTFMT_ELEMID, - colno, val); - edge->edge_id = val; + val = tuple_get_int64(rowdesc, colno, dat); + POSTGIS_DEBUGF(2, + "fillEdgeFields: colno%d (edge_id)" + " has int64 val of %" LWTFMT_ELEMID, + colno, + val); + edge->edge_id = val; } } @@ -707,10 +742,13 @@ fillEdgeFields(LWT_ISO_EDGE* edge, HeapTuple row, TupleDesc rowdesc, int fields) } else { - val = DatumGetInt64(dat); - POSTGIS_DEBUGF(2, "fillEdgeFields: colno%d (start_node)" - " has int64 val of %" LWTFMT_ELEMID, colno, val); - edge->start_node = val; + val = tuple_get_int64(rowdesc, colno, dat); + POSTGIS_DEBUGF(2, + "fillEdgeFields: colno%d (start_node)" + " has int64 val of %" LWTFMT_ELEMID, + colno, + val); + edge->start_node = val; } } if ( fields & LWT_COL_EDGE_END_NODE ) @@ -723,10 +761,13 @@ fillEdgeFields(LWT_ISO_EDGE* edge, HeapTuple row, TupleDesc rowdesc, int fields) } else { - val = DatumGetInt64(dat); - POSTGIS_DEBUGF(2, "fillEdgeFields: colno%d (end_node)" - " has int64 val of %" LWTFMT_ELEMID, colno, val); - edge->end_node = val; + val = tuple_get_int64(rowdesc, colno, dat); + POSTGIS_DEBUGF(2, + "fillEdgeFields: colno%d (end_node)" + " has int64 val of %" LWTFMT_ELEMID, + colno, + val); + edge->end_node = val; } } if ( fields & LWT_COL_EDGE_FACE_LEFT ) @@ -739,10 +780,13 @@ fillEdgeFields(LWT_ISO_EDGE* edge, HeapTuple row, TupleDesc rowdesc, int fields) } else { - val = DatumGetInt64(dat); - POSTGIS_DEBUGF(2, "fillEdgeFields: colno%d (face_left)" - " has int64 val of %" LWTFMT_ELEMID, colno, val); - edge->face_left = val; + val = tuple_get_int64(rowdesc, colno, dat); + POSTGIS_DEBUGF(2, + "fillEdgeFields: colno%d (face_left)" + " has int64 val of %" LWTFMT_ELEMID, + colno, + val); + edge->face_left = val; } } if ( fields & LWT_COL_EDGE_FACE_RIGHT ) @@ -755,10 +799,13 @@ fillEdgeFields(LWT_ISO_EDGE* edge, HeapTuple row, TupleDesc rowdesc, int fields) } else { - val = DatumGetInt64(dat); - POSTGIS_DEBUGF(2, "fillEdgeFields: colno%d (face_right)" - " has int64 val of %" LWTFMT_ELEMID, colno, val); - edge->face_right = val; + val = tuple_get_int64(rowdesc, colno, dat); + POSTGIS_DEBUGF(2, + "fillEdgeFields: colno%d (face_right)" + " has int64 val of %" LWTFMT_ELEMID, + colno, + val); + edge->face_right = val; } } if ( fields & LWT_COL_EDGE_NEXT_LEFT ) @@ -771,10 +818,13 @@ fillEdgeFields(LWT_ISO_EDGE* edge, HeapTuple row, TupleDesc rowdesc, int fields) } else { - val = DatumGetInt64(dat); - POSTGIS_DEBUGF(2, "fillEdgeFields: colno%d (next_left)" - " has int64 val of %" LWTFMT_ELEMID, colno, val); - edge->next_left = val; + val = tuple_get_int64(rowdesc, colno, dat); + POSTGIS_DEBUGF(2, + "fillEdgeFields: colno%d (next_left)" + " has int64 val of %" LWTFMT_ELEMID, + colno, + val); + edge->next_left = val; } } if ( fields & LWT_COL_EDGE_NEXT_RIGHT ) @@ -787,10 +837,13 @@ fillEdgeFields(LWT_ISO_EDGE* edge, HeapTuple row, TupleDesc rowdesc, int fields) } else { - val = DatumGetInt64(dat); - POSTGIS_DEBUGF(2, "fillEdgeFields: colno%d (next_right)" - " has int64 val of %" LWTFMT_ELEMID, colno, val); - edge->next_right = val; + val = tuple_get_int64(rowdesc, colno, dat); + POSTGIS_DEBUGF(2, + "fillEdgeFields: colno%d (next_right)" + " has int64 val of %" LWTFMT_ELEMID, + colno, + val); + edge->next_right = val; } } if ( fields & LWT_COL_EDGE_GEOM ) @@ -830,13 +883,14 @@ fillNodeFields(LWT_ISO_NODE* node, HeapTuple row, TupleDesc rowdesc, int fields) if ( fields & LWT_COL_NODE_NODE_ID ) { dat = SPI_getbinval(row, rowdesc, ++colno, &isnull); - node->node_id = DatumGetInt64(dat); + node->node_id = tuple_get_int64(rowdesc, colno, dat); } if ( fields & LWT_COL_NODE_CONTAINING_FACE ) { dat = SPI_getbinval(row, rowdesc, ++colno, &isnull); if ( isnull ) node->containing_face = -1; - else node->containing_face = DatumGetInt64(dat); + else + node->containing_face = tuple_get_int64(rowdesc, colno, dat); } if ( fields & LWT_COL_NODE_GEOM ) { @@ -870,7 +924,7 @@ fillFaceFields(LWT_ISO_FACE* face, HeapTuple row, TupleDesc rowdesc, int fields) if ( fields & LWT_COL_FACE_FACE_ID ) { dat = SPI_getbinval(row, rowdesc, ++colno, &isnull); - face->face_id = DatumGetInt64(dat); + face->face_id = tuple_get_int64(rowdesc, colno, dat); } if ( fields & LWT_COL_FACE_MBR ) { @@ -923,7 +977,7 @@ getNotNullInt64( HeapTuple row, TupleDesc desc, int col, int64 *val ) bool isnull; Datum dat = SPI_getbinval( row, desc, col, &isnull ); if ( isnull ) return 0; - *val = DatumGetInt64(dat); + *val = tuple_get_int64(desc, col, dat); return 1; } @@ -1058,12 +1112,24 @@ cb_getEdgeByFace(const LWT_BE_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t *n Datum *datum_ids; Datum values[2]; Oid argtypes[2]; + Oid idtype; + Oid idarraytype; int nargs = 1; GSERIALIZED *gser = NULL; + int16 typlen; + bool typbyval; + char typalign; + /* Match the callback argument type to the topology schema's chosen ID width. */ + idtype = topo->usesLargeIDs ? INT8OID : INT4OID; + idarraytype = topo->usesLargeIDs ? INT8ARRAYOID : INT4ARRAYOID; + get_typlenbyvalalign(idtype, &typlen, &typbyval, &typalign); datum_ids = palloc(sizeof(Datum)*(*numelems)); - for (i=0; i<*numelems; ++i) datum_ids[i] = Int64GetDatum(ids[i]); - array_ids = construct_array(datum_ids, *numelems, INT8OID, 8, true, 's'); + for (i = 0; i < *numelems; ++i) + { + datum_ids[i] = topo->usesLargeIDs ? Int64GetDatum(ids[i]) : Int32GetDatum(ids[i]); + } + array_ids = construct_array(datum_ids, *numelems, idtype, typlen, typbyval, typalign); initStringInfo(sql); appendStringInfoString(sql, "SELECT "); @@ -1074,7 +1140,7 @@ cb_getEdgeByFace(const LWT_BE_TOPOLOGY *topo, const LWT_ELEMID *ids, uint64_t *n topo->name); values[0] = PointerGetDatum(array_ids); - argtypes[0] = INT8ARRAYOID; + argtypes[0] = idarraytype; if ( box ) { @@ -1256,7 +1322,7 @@ cb_getRingEdges(const LWT_BE_TOPOLOGY *topo, LWT_ELEMID edge, uint64_t *numelems *numelems = UINT64_MAX; return NULL; } - val = DatumGetInt64(dat); + val = tuple_get_int64(rowdesc, 1, dat); edges[i] = val; POSTGIS_DEBUGF(1, "Component " UINT64_FORMAT " in ring of edge %" LWTFMT_ELEMID " is edge %d", i, edge, val); @@ -1278,7 +1344,7 @@ cb_getRingEdges(const LWT_BE_TOPOLOGY *topo, LWT_ELEMID edge, uint64_t *numelems *numelems = UINT64_MAX; return NULL; } - nextedge = DatumGetInt64(dat); + nextedge = tuple_get_int64(rowdesc, sidecol, dat); POSTGIS_DEBUGF(1, "Last component in ring of edge %" LWTFMT_ELEMID " (%d) has next_%s_edge %d", edge, val, sidetext, nextedge); ----------------------------------------------------------------------- Summary of changes: liblwgeom/topo/lwgeom_topo.c | 15 ++--- postgis/lwgeom_window.c | 4 +- topology/postgis_topology.c | 148 +++++++++++++++++++++++++++++++------------ 3 files changed, 117 insertions(+), 50 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Sat Mar 7 03:22:58 2026 From: git at osgeo.org (git at osgeo.org) Date: Sat, 7 Mar 2026 03:22:58 -0800 (PST) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-374-g1eb2fa4da Message-ID: <20260307112259.2C40918CB09@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 1eb2fa4daa61a459bb7ae3375279aa7394f25183 (commit) from 14152529d3f3008be89dbc76505521e819ae78d5 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1eb2fa4daa61a459bb7ae3375279aa7394f25183 Author: Darafei Praliaskouski Date: Sat Mar 7 15:22:30 2026 +0400 fuzzers: install yacc tools for oss-fuzz builds PostGIS's OSS-Fuzz build now delegates dependency setup to fuzzers/install_oss_fuzz_build_deps.sh, but the script did not install bison/flex. That leaves the builder without yacc/lex tooling and causes the fuzz build to fail while regenerating lwin_wkt_parse.c with 'No yacc found, cannot build parser'. Add bison and flex to the OSS-Fuzz dependency installer so the upstream fuzz build has the parser generators it needs. diff --git a/fuzzers/install_oss_fuzz_build_deps.sh b/fuzzers/install_oss_fuzz_build_deps.sh index 992d20369..dd3475745 100755 --- a/fuzzers/install_oss_fuzz_build_deps.sh +++ b/fuzzers/install_oss_fuzz_build_deps.sh @@ -16,7 +16,7 @@ export DEBIAN_FRONTEND="${DEBIAN_FRONTEND:-noninteractive}" apt-get update apt-get install -y --no-install-recommends \ - make autoconf automake libtool g++ postgresql-server-dev-all \ + make autoconf automake libtool bison flex g++ postgresql-server-dev-all \ libgeos-dev libproj-dev libxml2-dev pkg-config libjson-c-dev \ libc++-dev libc++abi-dev patchelf ----------------------------------------------------------------------- Summary of changes: fuzzers/install_oss_fuzz_build_deps.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- PostGIS From git at osgeo.org Sun Mar 8 15:48:30 2026 From: git at osgeo.org (git at osgeo.org) Date: Sun, 8 Mar 2026 15:48:30 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-378-g7af31bf2c Message-ID: <20260308224830.CAE451A9093@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 7af31bf2cb1968d7f9f3a275e9723702788b8615 (commit) from 9025206e69f7e8865b26d61ff771eee8d236d614 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7af31bf2cb1968d7f9f3a275e9723702788b8615 Author: Darafei Praliaskouski Date: Mon Mar 9 02:46:35 2026 +0400 #5973: Respect pg_config bindir for utility installs Closes #5973 diff --git a/NEWS b/NEWS index 6ed876e0c..df835634c 100644 --- a/NEWS +++ b/NEWS @@ -32,6 +32,9 @@ This version requires GEOS 3.10 or higher * Bug Fixes * + - #5973, Install PostGIS utilities under `pg_config --bindir` by default + and document `pg_config`-derived install paths more accurately + (Darafei Praliaskouski) - #5948, [topology] Prevent MakeTopologyPrecise from erasing edges when grid size exceeds their extent (Darafei Praliaskouski) - #5959, Prevent histogram target overflow when analysing massive tables (Darafei Praliaskouski) diff --git a/README.postgis b/README.postgis index 21faf6dbf..ed38b126f 100644 --- a/README.postgis +++ b/README.postgis @@ -247,11 +247,9 @@ Installation paths will typically be derived by ``pg_config``: - Lib in ``pg_config --pkglibdir`` - Binaries (loader/dumper) in ``pg_config --bindir`` - - Important support files in ``[prefix]/share/contrib`` - - Manual pages in ``[prefix]/man`` - - Documentation in in ``[prefix]/share/doc`` - -Where `[prefix]` above is extracted from ``pg_config --configure``. + - Important support files in ``pg_config --sharedir``/contrib + - Manual pages in ``pg_config --mandir`` + - Documentation in ``pg_config --docdir`` You can change them using ``./configure`` switches. See CONFIGURATION section. diff --git a/configure.ac b/configure.ac index d5fb6cc1b..ce0e97a11 100644 --- a/configure.ac +++ b/configure.ac @@ -622,6 +622,15 @@ if test "x$SUPPORT_POSTGRESQL" = "xyes"; then dnl { AC_SUBST([PGSQL_BINDIR]) + dnl Keep explicit --bindir, --exec-prefix, and --prefix overrides, but + dnl default utilities to the PostgreSQL bindir when the autoconf install + dnl directories were left entirely untouched. + if test "x$bindir" = 'x${exec_prefix}/bin' \ + && test "x$exec_prefix" = xNONE \ + && test "x$prefix" = xNONE; then + bindir="$PGSQL_BINDIR" + fi + dnl Extract the share directory PGSQL_SHAREDIR=`"$PG_CONFIG" --sharedir` @@ -670,6 +679,7 @@ if test "$prefix" != "NONE" -a "x$PG_CONFIG" != "xno"; then AC_MSG_RESULT([ ignore the --prefix. For your info, using the values determined from ]) AC_MSG_RESULT([ $PG_CONFIG we will be installing: ]) AC_MSG_RESULT([ * postgis shared library in $PGSQL_LIBDIR ]) + AC_MSG_RESULT([ * postgis utilities in $bindir ]) AC_MSG_RESULT([ * postgis SQL files in $PGSQL_SHAREDIR/contrib/postgis-$POSTGIS_MAJOR_VERSION.$POSTGIS_MINOR_VERSION ]) AC_MSG_RESULT([------------------------------------------------------------------------]) fi @@ -2023,6 +2033,8 @@ fi if test "x$SUPPORT_POSTGRESQL" = "xyes"; then AC_MSG_RESULT([ PostgreSQL config: ${PG_CONFIG}]) AC_MSG_RESULT([ PostgreSQL version: ${PGSQL_FULL_VERSION}]) + AC_MSG_RESULT([ PostgreSQL bindir: ${PGSQL_BINDIR}]) + AC_MSG_RESULT([ PostGIS utilities: ${bindir}]) else AC_MSG_RESULT([ PostgreSQL support: DISABLED]) fi ----------------------------------------------------------------------- Summary of changes: NEWS | 3 +++ README.postgis | 8 +++----- configure.ac | 12 ++++++++++++ 3 files changed, 18 insertions(+), 5 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Sun Mar 8 15:48:32 2026 From: trac at osgeo.org (PostGIS) Date: Sun, 08 Mar 2026 22:48:32 -0000 Subject: [PostGIS] #5973: pg_config --bindir not being used as documented. In-Reply-To: <048.9c781bb140f3678f90149a87308440db@osgeo.org> References: <048.9c781bb140f3678f90149a87308440db@osgeo.org> Message-ID: <063.89c8a71c6771505339a5963937fb11eb@osgeo.org> #5973: pg_config --bindir not being used as documented. -----------------------------+--------------------------- Reporter: David Johnston | Owner: robe Type: defect | Status: closed Priority: low | Milestone: PostGIS 3.5.5 Component: documentation | Version: master Resolution: fixed | Keywords: -----------------------------+--------------------------- Changes (by Darafei Praliaskouski ): * resolution: => fixed * status: new => closed Comment: In [changeset:"7af31bf2cb1968d7f9f3a275e9723702788b8615/git" 7af31bf/git]: {{{#!CommitTicketReference repository="git" revision="7af31bf2cb1968d7f9f3a275e9723702788b8615" #5973: Respect pg_config bindir for utility installs Closes #5973 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Sun Mar 8 16:25:55 2026 From: git at osgeo.org (git at osgeo.org) Date: Sun, 8 Mar 2026 16:25:55 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-379-ga586d720e Message-ID: <20260308232556.13D041A98AF@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via a586d720eb01112b22052865feca01a6d4b6eb9e (commit) from 7af31bf2cb1968d7f9f3a275e9723702788b8615 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a586d720eb01112b22052865feca01a6d4b6eb9e Author: Darafei Praliaskouski Date: Mon Mar 9 03:24:04 2026 +0400 Fix #6048 ST_Clip sparse band selection crash Closes #6048 diff --git a/NEWS b/NEWS index df835634c..4bbdc0e1d 100644 --- a/NEWS +++ b/NEWS @@ -39,6 +39,8 @@ This version requires GEOS 3.10 or higher grid size exceeds their extent (Darafei Praliaskouski) - #5959, Prevent histogram target overflow when analysing massive tables (Darafei Praliaskouski) - #4828, geometry_columns handles NOT VALID SRID checks without errors (Darafei Praliaskouski) + - #6048, [raster] ST_Clip no longer crashes when clipping sparse band + selections (Darafei Praliaskouski) - #5645, Docs: keep code operators ("=>") intact in translated manuals by enforcing verbatim CSS (Darafei Praliaskouski) - #5593, Docs: render manual images with GraphicsMagick without temporary files, diff --git a/raster/rt_pg/rtpg_mapalgebra.c b/raster/rt_pg/rtpg_mapalgebra.c index c1cac17c3..bb173aa29 100644 --- a/raster/rt_pg/rtpg_mapalgebra.c +++ b/raster/rt_pg/rtpg_mapalgebra.c @@ -11,6 +11,7 @@ * Copyright (C) 2009-2011 Mateusz Loskot * Copyright (C) 2008-2009 Sandro Santilli * Copyright (C) 2013 Nathaniel Hunter Clay + * Copyright (C) 2026 Darafei Praliaskouski * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -2993,8 +2994,6 @@ Datum RASTER_clip(PG_FUNCTION_ARGS) bool typbyval; char typalign; - int i = 0; - int j = 0; int k = 0; rtpg_clip_arg arg = NULL; LWGEOM *tmpgeom = NULL; @@ -3004,12 +3003,6 @@ Datum RASTER_clip(PG_FUNCTION_ARGS) double nodataval; double offset[4] = {0.}; - int input_x = 0; - int input_y = 0; - int mask_x = 0; - int mask_y = 0; - int x = 0; - int y = 0; int width = 0; int height = 0; int mask_width = 0; @@ -3145,6 +3138,8 @@ Datum RASTER_clip(PG_FUNCTION_ARGS) /* nband (1) */ if (!PG_ARGISNULL(1)) { + uint32_t band_count = 0; + array = PG_GETARG_ARRAYTYPE_P(1); etype = ARR_ELEMTYPE(array); get_typlenbyvalalign(etype, &typlen, &typbyval, &typalign); @@ -3177,23 +3172,26 @@ Datum RASTER_clip(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } - for (i = 0, j = 0; i < arg->numbands; i++) { - if (nulls[i]) continue; + for (uint32_t i = 0; i < (uint32_t)arg->numbands; i++) + { + if (nulls[i]) + continue; switch (etype) { case INT2OID: - arg->band[j].nband = DatumGetInt16(e[i]) - 1; + arg->band[band_count].nband = DatumGetInt16(e[i]) - 1; break; case INT4OID: - arg->band[j].nband = DatumGetInt32(e[i]) - 1; + arg->band[band_count].nband = DatumGetInt32(e[i]) - 1; break; } - j++; + band_count++; } - if (j < arg->numbands) { - arg->band = repalloc(arg->band, sizeof(struct rtpg_clip_band_t) * j); + if (band_count < (uint32_t)arg->numbands) + { + arg->band = repalloc(arg->band, sizeof(struct rtpg_clip_band_t) * band_count); if (arg->band == NULL) { rtpg_clip_arg_destroy(arg); PG_FREE_IF_COPY(pgraster, 0); @@ -3202,12 +3200,14 @@ Datum RASTER_clip(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } - arg->numbands = j; + arg->numbands = (int)band_count; } /* validate band */ - for (i = 0; i < arg->numbands; i++) { - if (!rt_raster_has_band(arg->raster, arg->band[i].nband)) { + for (uint32_t i = 0; i < (uint32_t)arg->numbands; i++) + { + if (!rt_raster_has_band(arg->raster, arg->band[i].nband)) + { elog(NOTICE, "Band at index %d not found in raster", arg->band[i].nband + 1); rtpg_clip_arg_destroy(arg); PG_FREE_IF_COPY(pgraster, 0); @@ -3235,8 +3235,9 @@ Datum RASTER_clip(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } - for (i = 0; i < arg->numbands; i++) { - arg->band[i].nband = i; + for (uint32_t i = 0; i < (uint32_t)arg->numbands; i++) + { + arg->band[i].nband = (int)i; arg->band[i].hasnodata = 0; arg->band[i].nodataval = 0; } @@ -3269,7 +3270,8 @@ Datum RASTER_clip(PG_FUNCTION_ARGS) ); /* it doesn't matter if there are more nodataval */ - for (i = 0, j = 0; i < arg->numbands; i++, j++) { + for (int32_t i = 0, j = 0; i < arg->numbands; i++, j++) + { /* cap j to the last nodataval element */ if (j >= k) j = k - 1; @@ -3359,8 +3361,16 @@ Datum RASTER_clip(PG_FUNCTION_ARGS) mask_band = rt_raster_get_band(arg->mask, 0); - for (i = 0; i < arg->numbands; i++) { + for (uint32_t i = 0; i < (uint32_t)arg->numbands; i++) + { input_band = rt_raster_get_band(arg->raster, arg->band[i].nband); + if (!input_band) + { + rtpg_clip_arg_destroy(arg); + PG_FREE_IF_COPY(pgraster, 0); + elog(ERROR, "RASTER_clip: Could not get input band at index %d", arg->band[i].nband); + PG_RETURN_NULL(); + } /* band metadata */ pixtype = rt_band_get_pixtype(input_band); @@ -3378,7 +3388,8 @@ Datum RASTER_clip(PG_FUNCTION_ARGS) nodataval = rt_band_get_min_value(input_band); } - if (rt_raster_generate_new_band(rtn, pixtype, nodataval, hasnodata, nodataval, i) < 0) { + if (rt_raster_generate_new_band(rtn, pixtype, nodataval, hasnodata, nodataval, (int)i) < 0) + { rtpg_clip_arg_destroy(arg); PG_FREE_IF_COPY(pgraster, 0); elog(ERROR, "RASTER_clip: Could not add new band in output raster"); @@ -3389,16 +3400,32 @@ Datum RASTER_clip(PG_FUNCTION_ARGS) continue; } - output_band = rt_raster_get_band(rtn, arg->band[i].nband); + /* + * Output bands are packed densely in request order, regardless of + * the source band numbers used to populate them. + */ + output_band = rt_raster_get_band(rtn, (int)i); + if (!output_band) + { + rtpg_clip_arg_destroy(arg); + PG_FREE_IF_COPY(pgraster, 0); + elog(ERROR, "RASTER_clip: Could not get output band at index %u", i); + PG_RETURN_NULL(); + } - if (!mask_band) { + if (!mask_band) + { continue; } - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - mask_x = x - (int)offset[2]; - mask_y = y - (int)offset[3]; + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + int mask_x = x - (int)offset[2]; + int mask_y = y - (int)offset[3]; + int input_x = x - (int)offset[0]; + int input_y = y - (int)offset[1]; if (!( mask_x >= 0 && @@ -3420,9 +3447,6 @@ Datum RASTER_clip(PG_FUNCTION_ARGS) continue; } - input_x = x - (int)offset[0]; - input_y = y - (int)offset[1]; - if (rt_band_get_pixel(input_band, input_x, input_y, &value, &isnodata) != ES_NONE) { rtpg_clip_arg_destroy(arg); PG_FREE_IF_COPY(pgraster, 0); diff --git a/raster/test/regress/rt_clip.sql b/raster/test/regress/rt_clip.sql index 462e73b21..af358506c 100644 --- a/raster/test/regress/rt_clip.sql +++ b/raster/test/regress/rt_clip.sql @@ -172,4 +172,61 @@ FROM ST_Clip( 1, '8BUI', 1, 0 ), ST_GeomFromText('POLYGON((0 0.0009999, 0.0001 0.0009999, 0.0001 0.0009, 0 0.0009, 0 0.0009999))') -) AS rast; \ No newline at end of file +) AS rast; + +-- #6048 clipping a sparse band selection should populate dense output bands +WITH test_rast AS ( + SELECT ST_AddBand( + ST_AddBand( + ST_AddBand( + ST_SetSRID( + ST_MakeEmptyRaster(4, 4, 0, 4, 1, -1, 0, 0), + 4326 + ), + '8BUI'::text, 11, 1 + ), + '8BUI'::text, 22, 2 + ), + '8BUI'::text, 33, 3 + ) AS rast +), test_geom AS ( + SELECT ST_SetSRID(ST_MakeEnvelope(1, 1, 3, 3), 4326) AS geom +) +SELECT '#6048.1', + ST_Width(rast), + ST_Height(rast), + ST_NumBands(rast), + ST_BandNoDataValue(rast, 1)::int, + ST_Value(rast, 1, 2, 2)::int +FROM ( + SELECT _ST_Clip(rast, ARRAY[3], geom, ARRAY[255, 255, 255], FALSE) AS rast + FROM test_rast, test_geom +) AS clipped; + +WITH test_rast AS ( + SELECT ST_AddBand( + ST_AddBand( + ST_AddBand( + ST_SetSRID( + ST_MakeEmptyRaster(4, 4, 0, 4, 1, -1, 0, 0), + 4326 + ), + '8BUI'::text, 11, 1 + ), + '8BUI'::text, 22, 2 + ), + '8BUI'::text, 33, 3 + ) AS rast +), test_geom AS ( + SELECT ST_SetSRID(ST_MakeEnvelope(1, 1, 3, 3), 4326) AS geom +) +SELECT '#6048.2', + ST_NumBands(rast), + ST_BandNoDataValue(rast, 1)::int, + ST_BandNoDataValue(rast, 2)::int, + ST_Value(rast, 1, 2, 2)::int, + ST_Value(rast, 2, 2, 2)::int +FROM ( + SELECT _ST_Clip(rast, ARRAY[3, 1], geom, ARRAY[253, 251], FALSE) AS rast + FROM test_rast, test_geom +) AS clipped; diff --git a/raster/test/regress/rt_clip_expected b/raster/test/regress/rt_clip_expected index c704cb356..c2754b520 100644 --- a/raster/test/regress/rt_clip_expected +++ b/raster/test/regress/rt_clip_expected @@ -1065,3 +1065,5 @@ 4|2|5|3|4|4|f|3|POLYGON((3 -3,4 -3,4 -4,3 -4,3 -3))|16 4|2|5|3|4|4|t|3|POLYGON((3 -3,4 -3,4 -4,3 -4,3 -3))|16 0|0.001|10|10 +#6048.1|4|4|1|255|33 +#6048.2|2|253|251|33|11 ----------------------------------------------------------------------- Summary of changes: NEWS | 2 + raster/rt_pg/rtpg_mapalgebra.c | 88 +++++++++++++++++++++++------------- raster/test/regress/rt_clip.sql | 59 +++++++++++++++++++++++- raster/test/regress/rt_clip_expected | 2 + 4 files changed, 118 insertions(+), 33 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Sun Mar 8 16:26:05 2026 From: trac at osgeo.org (PostGIS) Date: Sun, 08 Mar 2026 23:26:05 -0000 Subject: [PostGIS] #6048: postgis_raster crashes in rt_band_set_pixel due to NULL band pointer during ST_Clip operation In-Reply-To: <048.750ab04d7888c92a08ff4b0ad22cd50a@osgeo.org> References: <048.750ab04d7888c92a08ff4b0ad22cd50a@osgeo.org> Message-ID: <063.3a30c3f625925801215615eb08e2363a@osgeo.org> #6048: postgis_raster crashes in rt_band_set_pixel due to NULL band pointer during ST_Clip operation ---------------------+--------------------------- Reporter: maxmli | Owner: robe Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.7.0 Component: raster | Version: master Resolution: fixed | Keywords: ---------------------+--------------------------- Changes (by Darafei Praliaskouski ): * resolution: => fixed * status: new => closed Comment: In [changeset:"a586d720eb01112b22052865feca01a6d4b6eb9e/git" a586d72/git]: {{{#!CommitTicketReference repository="git" revision="a586d720eb01112b22052865feca01a6d4b6eb9e" Fix #6048 ST_Clip sparse band selection crash Closes #6048 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Mon Mar 9 02:09:48 2026 From: git at osgeo.org (git at osgeo.org) Date: Mon, 9 Mar 2026 02:09:48 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-380-g20fcd89ae Message-ID: <20260309090949.4ED3D1AC2B0@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 20fcd89ae646c2557cf892251242bc16a76a927c (commit) from a586d720eb01112b22052865feca01a6d4b6eb9e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 20fcd89ae646c2557cf892251242bc16a76a927c Author: Darafei Praliaskouski Date: Mon Mar 9 13:00:44 2026 +0400 #1599 Improve country-aware address normalization Canonicalize explicit country tokens in the address parser, carry country through norm_addy, and add regressions for country-aware tiger normalization while keeping tiger usable without address_standardizer. Closes #1599 diff --git a/NEWS b/NEWS index 4bbdc0e1d..d9bf639d8 100644 --- a/NEWS +++ b/NEWS @@ -41,6 +41,10 @@ This version requires GEOS 3.10 or higher - #4828, geometry_columns handles NOT VALID SRID checks without errors (Darafei Praliaskouski) - #6048, [raster] ST_Clip no longer crashes when clipping sparse band selections (Darafei Praliaskouski) + - #1599, [address_standardizer] parse_address() and normalize_address() now + canonicalize trailing country tokens to ISO 3166-1 alpha-2 codes and + expose country on normalized addresses + (Darafei Praliaskouski) - #5645, Docs: keep code operators ("=>") intact in translated manuals by enforcing verbatim CSS (Darafei Praliaskouski) - #5593, Docs: render manual images with GraphicsMagick without temporary files, diff --git a/doc/extras_address_standardizer.xml b/doc/extras_address_standardizer.xml index 287151ca4..d5735096d 100644 --- a/doc/extras_address_standardizer.xml +++ b/doc/extras_address_standardizer.xml @@ -14,8 +14,9 @@ The parser works from right to left looking first at the macro elements for postcode, state/province, city, and then looks micro elements to determine if we are dealing with a house number street or intersection or landmark. -It currently does not look for a country code or name, but that could be -introduced in the future. +It conservatively recognizes trailing country tokens and canonicalizes them to +ISO 3166-1 alpha-2 codes. Explicit country aliases update the parsed country, +and otherwise the default US or CA inference still applies. Country code diff --git a/doc/installation.xml b/doc/installation.xml index 35b05227f..e6805f8c0 100644 --- a/doc/installation.xml +++ b/doc/installation.xml @@ -925,7 +925,7 @@ test test-standardize_address_2 ... ok cd extensions/postgis_tiger_geocoder make install make installcheck - + output should look like: ============== dropping database "contrib_regression" ============== DROP DATABASE diff --git a/extensions/address_standardizer/address_parser.c b/extensions/address_standardizer/address_parser.c index 3e1c642bf..cbe318942 100644 --- a/extensions/address_standardizer/address_parser.c +++ b/extensions/address_standardizer/address_parser.c @@ -21,8 +21,10 @@ #endif Datum parse_address(PG_FUNCTION_ARGS); +Datum strip_explicit_country(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(parse_address); +PG_FUNCTION_INFO_V1(strip_explicit_country); Datum parse_address(PG_FUNCTION_ARGS) { @@ -110,3 +112,18 @@ Datum parse_address(PG_FUNCTION_ARGS) return result; } +Datum +strip_explicit_country(PG_FUNCTION_ARGS) +{ + char *input; + char *working; + char country_code[3] = {0}; + + input = text_to_cstring(PG_GETARG_TEXT_P(0)); + working = pstrdup(input); + + if (strip_explicit_country_token(working, country_code)) + PG_RETURN_TEXT_P(cstring_to_text(working)); + + PG_RETURN_TEXT_P(cstring_to_text(input)); +} diff --git a/extensions/address_standardizer/address_standardizer.c b/extensions/address_standardizer/address_standardizer.c index 363185529..5adb43666 100644 --- a/extensions/address_standardizer/address_standardizer.c +++ b/extensions/address_standardizer/address_standardizer.c @@ -386,11 +386,19 @@ static const char * stdaddr_field_value(const STDADDR *stdaddr, size_t offset) { const char *const *field_value; + const char *canonical_country; if (!stdaddr) return NULL; field_value = (const char *const *)((const char *)stdaddr + offset); + if (offset == offsetof(STDADDR, country) && *field_value) + { + canonical_country = country_code_from_name(*field_value); + if (canonical_country) + return canonical_country; + } + return *field_value; } diff --git a/extensions/address_standardizer/address_standardizer_functions.sql.in b/extensions/address_standardizer/address_standardizer_functions.sql.in index 65c3e919b..535a28de3 100644 --- a/extensions/address_standardizer/address_standardizer_functions.sql.in +++ b/extensions/address_standardizer/address_standardizer_functions.sql.in @@ -47,3 +47,7 @@ CREATE OR REPLACE FUNCTION parse_address(IN text, AS 'MODULE_PATHNAME', 'parse_address' LANGUAGE 'c' IMMUTABLE STRICT; +CREATE OR REPLACE FUNCTION strip_explicit_country(IN text) + RETURNS text + AS 'MODULE_PATHNAME', 'strip_explicit_country' + LANGUAGE 'c' IMMUTABLE STRICT; diff --git a/extensions/address_standardizer/expected/test-standardize_address_1.out b/extensions/address_standardizer/expected/test-standardize_address_1.out index 73604c0b6..ff6dbd83d 100644 --- a/extensions/address_standardizer/expected/test-standardize_address_1.out +++ b/extensions/address_standardizer/expected/test-standardize_address_1.out @@ -13,31 +13,31 @@ select * from standardize_address('us_lex'::text, 'us_gaz'::text, 'us_rules'::te SELECT '#2981' As ticket, * FROM standardize_address('us_lex','us_gaz','us_rules', '1566 NEW STATE HWY, RAYNHAM, MA'); ticket | building | house_num | predir | qual | pretype | name | suftype | sufdir | ruralroute | extra | city | state | country | postcode | box | unit --------+----------+-----------+--------+------+---------+-------------------+---------+--------+------------+-------+---------+---------------+---------+----------+-----+------ - #2981 | | 1566 | | | | NEW STATE HIGHWAY | | | | | RAYNHAM | MASSACHUSETTS | USA | | | + #2981 | | 1566 | | | | NEW STATE HIGHWAY | | | | | RAYNHAM | MASSACHUSETTS | US | | | (1 row) SELECT '#2978a' As ticket, * FROM standardize_address('us_lex','us_gaz','us_rules', '10-20 DORRANCE ST PROVIDENCE RI' ); ticket | building | house_num | predir | qual | pretype | name | suftype | sufdir | ruralroute | extra | city | state | country | postcode | box | unit --------+----------+-----------+--------+------+---------+----------+---------+--------+------------+-------+------------+--------------+---------+----------+-----+------ - #2978a | | 10 20 | | | | DORRANCE | STREET | | | | PROVIDENCE | RHODE ISLAND | USA | | | + #2978a | | 10 20 | | | | DORRANCE | STREET | | | | PROVIDENCE | RHODE ISLAND | US | | | (1 row) SELECT '#2978b' As ticket, * FROM standardize_address('us_lex','us_gaz','us_rules', '10 20 DORRANCE ST PROVIDENCE RI' ); ticket | building | house_num | predir | qual | pretype | name | suftype | sufdir | ruralroute | extra | city | state | country | postcode | box | unit --------+----------+-----------+--------+------+---------+----------+---------+--------+------------+-------+------------+--------------+---------+----------+-----+------ - #2978b | | 10 20 | | | | DORRANCE | STREET | | | | PROVIDENCE | RHODE ISLAND | USA | | | + #2978b | | 10 20 | | | | DORRANCE | STREET | | | | PROVIDENCE | RHODE ISLAND | US | | | (1 row) SELECT '#2978c' As ticket, * FROM standardize_address('us_lex','us_gaz','us_rules', '10-20 DORRANCE ST, PROVIDENCE, RI'); ticket | building | house_num | predir | qual | pretype | name | suftype | sufdir | ruralroute | extra | city | state | country | postcode | box | unit --------+----------+-----------+--------+------+---------+----------+---------+--------+------------+-------+------------+--------------+---------+----------+-----+------ - #2978c | | 10 20 | | | | DORRANCE | STREET | | | | PROVIDENCE | RHODE ISLAND | USA | | | + #2978c | | 10 20 | | | | DORRANCE | STREET | | | | PROVIDENCE | RHODE ISLAND | US | | | (1 row) SELECT '#state_only_macro' AS ticket, * FROM standardize_address('us_lex','us_gaz','us_rules', '25 Prince Street, NC 09985'); ticket | building | house_num | predir | qual | pretype | name | suftype | sufdir | ruralroute | extra | city | state | country | postcode | box | unit -------------------+----------+-----------+--------+------+---------+--------+---------+--------+------------+-------+------+----------------+---------+----------+-----+------ - #state_only_macro | | 25 | | | | PRINCE | STREET | | | | | NORTH CAROLINA | USA | 09985 | | + #state_only_macro | | 25 | | | | PRINCE | STREET | | | | | NORTH CAROLINA | US | 09985 | | (1 row) SELECT '#5299a' AS ticket, * FROM standardize_address('us_lex', 'us_gaz', 'us_rules','1 Timepiece Point','Boston, MA, 02220'); @@ -55,7 +55,7 @@ SELECT '#5299b' AS ticket, * FROM standardize_address('us_lex', 'us_gaz', 'us_r SELECT '#5695a' AS ticket, * FROM standardize_address('us_lex', 'us_gaz', 'us_rules', 'ONE E PIMA ST STE 999, TUCSON, AZ'); ticket | building | house_num | predir | qual | pretype | name | suftype | sufdir | ruralroute | extra | city | state | country | postcode | box | unit --------+----------+-----------+--------+------+---------+------+---------+--------+------------+-------+--------+---------+---------+----------+-----+----------- - #5695a | | 1 | EAST | | | PIMA | STREET | | | | TUCSON | ARIZONA | USA | | | SUITE 999 + #5695a | | 1 | EAST | | | PIMA | STREET | | | | TUCSON | ARIZONA | US | | | SUITE 999 (1 row) DO $$ diff --git a/extensions/address_standardizer/parseaddress-api.c b/extensions/address_standardizer/parseaddress-api.c index 8abf1d1b2..408a592f3 100644 --- a/extensions/address_standardizer/parseaddress-api.c +++ b/extensions/address_standardizer/parseaddress-api.c @@ -2,6 +2,7 @@ * parseaddres.c - utility to crack a string into address, city st zip * * Copyright 2006 Stephen Woodbridge + * Copyright 2026 Darafei Praliaskouski * * This code is released under and MIT-X style license, * @@ -9,13 +10,10 @@ * woodbri at swoodbridge.com * woodbr at imaptools.com * - * - * TODO: - * * add recognition of country before or after postalcode - * */ #include +#include #include #include @@ -48,6 +46,23 @@ const char *parseaddress_cvsid(); char *clean_leading_punct(char *s); static int is_parse_separator(unsigned char c); static size_t normalize_address_input(char *s); +static size_t normalize_country_token(const char *src, char *dst, size_t dst_size); +static bool ends_with_supported_macro(const char *s); +static bool extract_trailing_country(char *s, char *country_code); + +static const char *const us_zip_regex = "\\b(\\d{5})[-\\s]{0,1}?(\\d{0,4})?$"; +static const char *const canada_zip_regex = "\\b([a-z]\\d[a-z]\\s?\\d[a-z]\\d)$"; +static const char *const canada_province_regex = "^(?-xism:(?i:(?=[abmnopqsy])(?:n[ltsu]|[am]b|[bq]c|on|pe|sk|yt)))$"; +static const char *const us_ca_state_regex = + "\\b(?-xism:(?i:(?=[abcdfghiklmnopqrstuvwy])(?:a(?:l(?:a(?:bam|sk)a|berta)?|mer(?:ican)?\\ samoa|r(?:k(?:ansas)?|izona)?|[kszb])|s(?:a(?:moa|skatchewan)|outh\\ (?:carolin|dakot)a|\\ (?:carolin|dakot)a|[cdk])|c(?:a(?:lif(?:ornia)?)?|o(?:nn(?:ecticut)?|lorado)?|t)|d(?:e(?:la(?:ware)?)?|istrict\\ of\\ columbia|c)|f(?:l(?:(?:orid)?a)?|ederal\\ states\\ of\\ micronesia|m)|m(?:i(?:c(?:h(?:igan)?|ronesia)|nn(?:esota)?|ss(?:(?:issipp|our)i)?)?|a(?:r(?:shall(?:\\ is(?:l(?:and)?)?)?|yland)|ss(?:achusetts)?|ine|nitoba)?|o(?:nt(?:ana)?)?|[ehdnstpb])|g(?:u(?:am)?|(?:eorgi)?a)|h(?:awai)?i|i(?:d(?:aho)?|l(?:l(?:inois)?)?|n(?:d(?:iana)?)?|(?:ow)?a)|k(?:(?:ansa)?s|(?:entuck)?y)|l(?:a(?:bordor)?|ouisiana)|n(?:e(?:w(?:\\ (?:foundland(?:\\ and\\ labordor)?|hampshire|jersey|mexico|(?:yor|brunswic)k)|foundland)|(?:brask|vad)a)?|o(?:rth(?:\\ (?:mariana(?:\\ is(?:l(?:and)?)?)?|(?:carolin|dakot)a)|west\\ territor(?:ies|y))|va\\ scotia)|\\ (?:carolin|dakot)a|u(?:navut)?|[vhjmycdblsf]|w?t)|o(?:h(?:io)?|k( ?:lahoma)?|r(?:egon)?|n(?:t(?:ario)?)?)|p(?:a(?:lau)?|e(?:nn(?:sylvania)?|i)?|r(?:ince\\ edward\\ island)?|w|uerto\\ rico)|r(?:hode\\ island|i)|t(?:e(?:nn(?:essee)?|xas)|[nx])|ut(?:ah)?|v(?:i(?:rgin(?:\\ islands|ia))?|(?:ermon)?t|a)|w(?:a(?:sh(?:ington)?)?|i(?:sc(?:onsin)?)?|y(?:oming)?|(?:est)?\\ virginia|v)|b(?:ritish\\ columbia|c)|q(?:uebe)?c|y(?:ukon|t))))$"; +typedef struct country_alias { + const char *alias; + const char *alpha2; +} CountryAlias; + +static const CountryAlias country_aliases[] = { +#include "parseaddress-countries.h" +}; static int is_parse_separator(unsigned char c) @@ -97,6 +112,171 @@ normalize_address_input(char *s) return write_pos; } +static size_t +normalize_country_token(const char *src, char *dst, size_t dst_size) +{ + size_t write_pos = 0; + bool previous_was_space = false; + + if (!src || !dst || !dst_size) + return 0; + + for (; *src != '\0' && write_pos + 1 < dst_size; src++) + { + unsigned char current = (unsigned char)*src; + + if (isalpha(current)) + { + dst[write_pos++] = (char)toupper(current); + previous_was_space = false; + continue; + } + + if (isspace(current) || ispunct(current)) + { + if (!write_pos || previous_was_space) + continue; + + dst[write_pos++] = ' '; + previous_was_space = true; + } + } + + if (write_pos && dst[write_pos - 1] == ' ') + write_pos--; + + dst[write_pos] = '\0'; + return write_pos; +} + +static int +compare_country_alias(const void *lhs, const void *rhs) +{ + const CountryAlias *left = (const CountryAlias *)lhs; + const CountryAlias *right = (const CountryAlias *)rhs; + + return strcmp(left->alias, right->alias); +} + +const char * +country_code_from_name(const char *country_name) +{ + CountryAlias key; + char normalized_country[128]; + const CountryAlias *match; + + if (!normalize_country_token(country_name, normalized_country, sizeof(normalized_country))) + return NULL; + + key.alias = normalized_country; + key.alpha2 = NULL; + match = bsearch( + &key, country_aliases, lengthof(country_aliases), sizeof(country_aliases[0]), compare_country_alias); + + return match ? match->alpha2 : NULL; +} + +/* + * Recognize the right-most macro shape that this parser already knows how to + * consume. That lets us conservatively strip trailing countries without + * erasing ordinary trailing qualifiers, and still supports short ZIP fragments + * once they are paired with a valid trailing state/province. + */ +static bool +ends_with_supported_macro(const char *s) +{ + int macro_ovect[OVECCOUNT]; + int rc; + char *state_probe; + + if (!s || *s == '\0') + return false; + + rc = match((char *)us_zip_regex, (char *)s, macro_ovect, 0); + if (rc >= 2) + return true; + + rc = match((char *)canada_zip_regex, (char *)s, macro_ovect, PARSE_CASELESS); + if (rc >= 1) + return true; + + rc = match((char *)us_ca_state_regex, (char *)s, macro_ovect, PARSE_CASELESS); + if (rc > 0) + return true; + + rc = match("\\b(\\d{2,4})$", (char *)s, macro_ovect, 0); + if (rc < 2) + return false; + + state_probe = pstrdup(s); + *(state_probe + macro_ovect[0]) = '\0'; + (void)clean_trailing_punct(state_probe); + + rc = match((char *)us_ca_state_regex, state_probe, macro_ovect, PARSE_CASELESS); + pfree(state_probe); + + return rc > 0; +} + +/* + * Strip a trailing country token before macro parsing so postcode and state + * extraction still see the expected right-most fields. Known US/CA country + * tokens update the country code; other recognized country names are stripped + * without changing the default country inference. + */ +static bool +extract_trailing_country(char *s, char *country_code) +{ + int split_ovect[OVECCOUNT]; + int rc; + const char *matched_country_code; + char saved; + + if (!s || !country_code) + return false; + + rc = match("([\\s,]+)([A-Za-z][A-Za-z\\s]{1,})$", s, split_ovect, 0); + if (rc < 3) + return false; + + saved = s[split_ovect[0]]; + s[split_ovect[0]] = '\0'; + + matched_country_code = country_code_from_name(s + split_ovect[4]); + if (!matched_country_code) + { + s[split_ovect[0]] = saved; + return false; + } + + if (!ends_with_supported_macro(s)) + { + s[split_ovect[0]] = saved; + return false; + } + + strcpy(country_code, matched_country_code); + + (void)clean_trailing_punct(s); + return true; +} + +bool +strip_explicit_country_token(char *s, char *country_code) +{ + size_t normalized_length; + + if (!s || !country_code) + return false; + + normalized_length = normalize_address_input(s); + if (!normalized_length) + return false; + + (void)clean_trailing_punct(s); + return extract_trailing_country(s, country_code); +} + const char * get_state_regex(const char *st) { @@ -253,11 +433,10 @@ parseaddress(HHash *stH, char *s, int *reterr) #include "parseaddress-regex.h" int ovect[OVECCOUNT]; - char *stregx; - char *caregx; char *state = NULL; char *regx; size_t normalized_length; + bool explicit_country = false; int rc; ADDRESS *ret; #ifdef USE_HSEARCH @@ -299,14 +478,16 @@ parseaddress(HHash *stH, char *s, int *reterr) ret->cc = (char *)palloc0(3 * sizeof(char)); strcpy(ret->cc, "US"); + explicit_country = extract_trailing_country(s, ret->cc); + /* get US zipcode components */ - rc = match("\\b(\\d{5})[-\\s]{0,1}?(\\d{0,4})?$", s, ovect, 0); + rc = match((char *)us_zip_regex, s, ovect, 0); if (rc >= 2) { ret->zip = (char *)palloc0((ovect[3] - ovect[2] + 1) * sizeof(char)); strncpy(ret->zip, s + ovect[2], ovect[3] - ovect[2]); - if (rc >= 3) + if (rc >= 3 && ovect[5] > ovect[4]) { ret->zipplus = (char *)palloc0((ovect[5] - ovect[4] + 1) * sizeof(char)); strncpy(ret->zipplus, s + ovect[4], ovect[5] - ovect[4]); @@ -317,27 +498,54 @@ parseaddress(HHash *stH, char *s, int *reterr) /* get canada zipcode components */ else { - rc = match("\\b([a-z]\\d[a-z]\\s?\\d[a-z]\\d)$", s, ovect, PARSE_CASELESS); + rc = match((char *)canada_zip_regex, s, ovect, PARSE_CASELESS); if (rc >= 1) { ret->zip = (char *)palloc0((ovect[1] - ovect[0] + 1) * sizeof(char)); strncpy(ret->zip, s + ovect[0], ovect[1] - ovect[0]); - strcpy(ret->cc, "CA"); + if (!explicit_country) + strcpy(ret->cc, "CA"); /* truncate the postalcode off the string */ *(s + ovect[0]) = '\0'; } + else + { + int state_ovect[OVECCOUNT]; + char *state_probe; + + /* + * Accept a short trailing ZIP fragment only when removing it exposes + * a valid trailing state/province. That keeps "MA 021" working + * without turning arbitrary suffixes like "Suite 201" into ZIPs. + */ + rc = match("\\b(\\d{2,4})$", s, ovect, 0); + if (rc >= 2) + { + state_probe = pstrdup(s); + *(state_probe + ovect[0]) = '\0'; + (void)clean_trailing_punct(state_probe); + + rc = match((char *)us_ca_state_regex, state_probe, state_ovect, PARSE_CASELESS); + pfree(state_probe); + + if (rc > 0) + { + ret->zip = (char *)palloc0((ovect[3] - ovect[2] + 1) * sizeof(char)); + strncpy(ret->zip, s + ovect[2], ovect[3] - ovect[2]); + *(s + ovect[0]) = '\0'; + } + } + } } /* clean trailing punctuation */ (void)clean_trailing_punct(s); + explicit_country = extract_trailing_country(s, ret->cc) || explicit_country; + (void)clean_trailing_punct(s); /* get state components */ - caregx = "^(?-xism:(?i:(?=[abmnopqsy])(?:n[ltsu]|[am]b|[bq]c|on|pe|sk|yt)))$"; - stregx = - "\\b(?-xism:(?i:(?=[abcdfghiklmnopqrstuvwy])(?:a(?:l(?:a(?:bam|sk)a|berta)?|mer(?:ican)?\\ samoa|r(?:k(?:ansas)?|izona)?|[kszb])|s(?:a(?:moa|skatchewan)|outh\\ (?:carolin|dakot)a|\\ (?:carolin|dakot)a|[cdk])|c(?:a(?:lif(?:ornia)?)?|o(?:nn(?:ecticut)?|lorado)?|t)|d(?:e(?:la(?:ware)?)?|istrict\\ of\\ columbia|c)|f(?:l(?:(?:orid)?a)?|ederal\\ states\\ of\\ micronesia|m)|m(?:i(?:c(?:h(?:igan)?|ronesia)|nn(?:esota)?|ss(?:(?:issipp|our)i)?)?|a(?:r(?:shall(?:\\ is(?:l(?:and)?)?)?|yland)|ss(?:achusetts)?|ine|nitoba)?|o(?:nt(?:ana)?)?|[ehdnstpb])|g(?:u(?:am)?|(?:eorgi)?a)|h(?:awai)?i|i(?:d(?:aho)?|l(?:l(?:inois)?)?|n(?:d(?:iana)?)?|(?:ow)?a)|k(?:(?:ansa)?s|(?:entuck)?y)|l(?:a(?:bordor)?|ouisiana)|n(?:e(?:w(?:\\ (?:foundland(?:\\ and\\ labordor)?|hampshire|jersey|mexico|(?:yor|brunswic)k)|foundland)|(?:brask|vad)a)?|o(?:rth(?:\\ (?:mariana(?:\\ is(?:l(?:and)?)?)?|(?:carolin|dakot)a)|west\\ territor(?:ies|y))|va\\ scotia)|\\ (?:carolin|dakot)a|u(?:navut)?|[vhjmycdblsf]|w?t)|o(?:h(?:io)?|k (?:lahoma)?|r(?:egon)?|n(?:t(?:ario)?)?)|p(?:a(?:lau)?|e(?:nn(?:sylvania)?|i)?|r(?:ince\\ edward\\ island)?|w|uerto\\ rico)|r(?:hode\\ island|i)|t(?:e(?:nn(?:essee)?|xas)|[nx])|ut(?:ah)?|v(?:i(?:rgin(?:\\ islands|ia))?|(?:ermon)?t|a)|w(?:a(?:sh(?:ington)?)?|i(?:sc(?:onsin)?)?|y(?:oming)?|(?:est)?\\ virginia|v)|b(?:ritish\\ columbia|c)|q(?:uebe)?c|y(?:ukon|t))))$"; - - rc = match(stregx, s, ovect, PARSE_CASELESS); + rc = match((char *)us_ca_state_regex, s, ovect, PARSE_CASELESS); if (rc > 0) { state = (char *)palloc0((ovect[1] - ovect[0] + 1) * sizeof(char)); @@ -371,8 +579,8 @@ parseaddress(HHash *stH, char *s, int *reterr) } /* check if it a Canadian Province */ - rc = match(caregx, ret->st, ovect, PARSE_CASELESS); - if (rc > 0) + rc = match((char *)canada_province_regex, ret->st, ovect, PARSE_CASELESS); + if (rc > 0 && !explicit_country) { strcpy(ret->cc, "CA"); // if (ret->cc) printf(" CC: %s\n", ret->cc); diff --git a/extensions/address_standardizer/parseaddress-api.h b/extensions/address_standardizer/parseaddress-api.h index 4dffb5ab8..bb47558e7 100644 --- a/extensions/address_standardizer/parseaddress-api.h +++ b/extensions/address_standardizer/parseaddress-api.h @@ -57,6 +57,8 @@ typedef struct address_struct { int clean_trailing_punct(char *s); void strtoupper(char *s); int match(char *pattern, char *s, int *ovect, int options); +const char *country_code_from_name(const char *country_name); +bool strip_explicit_country_token(char *s, char *country_code); ADDRESS *parseaddress(HHash *stH, char *s, int *err); int load_state_hash(HHash *stH); void free_state_hash(HHash *stH); diff --git a/extensions/address_standardizer/parseaddress-countries.h b/extensions/address_standardizer/parseaddress-countries.h new file mode 100644 index 000000000..3b94c4932 --- /dev/null +++ b/extensions/address_standardizer/parseaddress-countries.h @@ -0,0 +1,942 @@ +/* + * Country aliases for parse_address(), generated from iso-codes and + * a small compatibility alias set. Keep this list sorted by alias. + */ +{"ABW", "AW"}, +{"AD", "AD"}, +{"AE", "AE"}, +{"AF", "AF"}, +{"AFG", "AF"}, +{"AFGHANISTAN", "AF"}, +{"AG", "AG"}, +{"AGO", "AO"}, +{"AI", "AI"}, +{"AIA", "AI"}, +{"AL", "AL"}, +{"ALA", "AX"}, +{"ALAND ISLANDS", "AX"}, +{"ALB", "AL"}, +{"ALBANIA", "AL"}, +{"ALGERIA", "DZ"}, +{"AM", "AM"}, +{"AMERICAN SAMOA", "AS"}, +{"AND", "AD"}, +{"ANDORRA", "AD"}, +{"ANGOLA", "AO"}, +{"ANGUILLA", "AI"}, +{"ANTARCTICA", "AQ"}, +{"ANTIGUA AND BARBUDA", "AG"}, +{"AO", "AO"}, +{"AQ", "AQ"}, +{"AR", "AR"}, +{"ARAB REPUBLIC OF EGYPT", "EG"}, +{"ARE", "AE"}, +{"ARG", "AR"}, +{"ARGENTINA", "AR"}, +{"ARGENTINE REPUBLIC", "AR"}, +{"ARM", "AM"}, +{"ARMENIA", "AM"}, +{"ARUBA", "AW"}, +{"AS", "AS"}, +{"ASM", "AS"}, +{"AT", "AT"}, +{"ATA", "AQ"}, +{"ATF", "TF"}, +{"ATG", "AG"}, +{"AU", "AU"}, +{"AUS", "AU"}, +{"AUSTRALIA", "AU"}, +{"AUSTRIA", "AT"}, +{"AUT", "AT"}, +{"AW", "AW"}, +{"AX", "AX"}, +{"AZ", "AZ"}, +{"AZE", "AZ"}, +{"AZERBAIJAN", "AZ"}, +{"BA", "BA"}, +{"BAHAMAS", "BS"}, +{"BAHRAIN", "BH"}, +{"BANGLADESH", "BD"}, +{"BARBADOS", "BB"}, +{"BB", "BB"}, +{"BD", "BD"}, +{"BDI", "BI"}, +{"BE", "BE"}, +{"BEL", "BE"}, +{"BELARUS", "BY"}, +{"BELGIUM", "BE"}, +{"BELIZE", "BZ"}, +{"BEN", "BJ"}, +{"BENIN", "BJ"}, +{"BERMUDA", "BM"}, +{"BES", "BQ"}, +{"BF", "BF"}, +{"BFA", "BF"}, +{"BG", "BG"}, +{"BGD", "BD"}, +{"BGR", "BG"}, +{"BH", "BH"}, +{"BHR", "BH"}, +{"BHS", "BS"}, +{"BHUTAN", "BT"}, +{"BI", "BI"}, +{"BIH", "BA"}, +{"BJ", "BJ"}, +{"BL", "BL"}, +{"BLM", "BL"}, +{"BLR", "BY"}, +{"BLZ", "BZ"}, +{"BM", "BM"}, +{"BMU", "BM"}, +{"BN", "BN"}, +{"BO", "BO"}, +{"BOL", "BO"}, +{"BOLIVARIAN REPUBLIC OF VENEZUELA", "VE"}, +{"BOLIVIA", "BO"}, +{"BOLIVIA PLURINATIONAL STATE OF", "BO"}, +{"BONAIRE SINT EUSTATIUS AND SABA", "BQ"}, +{"BOSNIA AND HERZEGOVINA", "BA"}, +{"BOSNIA HERZEGOVINA", "BA"}, +{"BOTSWANA", "BW"}, +{"BOUVET ISLAND", "BV"}, +{"BQ", "BQ"}, +{"BR", "BR"}, +{"BRA", "BR"}, +{"BRAZIL", "BR"}, +{"BRB", "BB"}, +{"BRITAIN", "GB"}, +{"BRITISH INDIAN OCEAN TERRITORY", "IO"}, +{"BRITISH VIRGIN ISLANDS", "VG"}, +{"BRN", "BN"}, +{"BRUNEI DARUSSALAM", "BN"}, +{"BS", "BS"}, +{"BT", "BT"}, +{"BTN", "BT"}, +{"BULGARIA", "BG"}, +{"BURKINA FASO", "BF"}, +{"BURMA", "MM"}, +{"BURUNDI", "BI"}, +{"BV", "BV"}, +{"BVT", "BV"}, +{"BW", "BW"}, +{"BWA", "BW"}, +{"BY", "BY"}, +{"BZ", "BZ"}, +{"CA", "CA"}, +{"CABO VERDE", "CV"}, +{"CAF", "CF"}, +{"CAMBODIA", "KH"}, +{"CAMEROON", "CM"}, +{"CAN", "CA"}, +{"CANADA", "CA"}, +{"CAYMAN ISLANDS", "KY"}, +{"CC", "CC"}, +{"CCK", "CC"}, +{"CD", "CD"}, +{"CENTRAL AFRICAN REPUBLIC", "CF"}, +{"CF", "CF"}, +{"CG", "CG"}, +{"CH", "CH"}, +{"CHAD", "TD"}, +{"CHE", "CH"}, +{"CHILE", "CL"}, +{"CHINA", "CN"}, +{"CHL", "CL"}, +{"CHN", "CN"}, +{"CHRISTMAS ISLAND", "CX"}, +{"CI", "CI"}, +{"CIV", "CI"}, +{"CK", "CK"}, +{"CL", "CL"}, +{"CM", "CM"}, +{"CMR", "CM"}, +{"CN", "CN"}, +{"CO", "CO"}, +{"COCOS KEELING ISLANDS", "CC"}, +{"COD", "CD"}, +{"COG", "CG"}, +{"COK", "CK"}, +{"COL", "CO"}, +{"COLOMBIA", "CO"}, +{"COM", "KM"}, +{"COMMONWEALTH OF DOMINICA", "DM"}, +{"COMMONWEALTH OF THE BAHAMAS", "BS"}, +{"COMMONWEALTH OF THE NORTHERN MARIANA ISLANDS", "MP"}, +{"COMOROS", "KM"}, +{"CONGO", "CG"}, +{"CONGO THE DEMOCRATIC REPUBLIC OF THE", "CD"}, +{"COOK ISLANDS", "CK"}, +{"COSTA RICA", "CR"}, +{"COTE D IVOIRE", "CI"}, +{"CPV", "CV"}, +{"CR", "CR"}, +{"CRI", "CR"}, +{"CROATIA", "HR"}, +{"CU", "CU"}, +{"CUB", "CU"}, +{"CUBA", "CU"}, +{"CURACAO", "CW"}, +{"CUW", "CW"}, +{"CV", "CV"}, +{"CW", "CW"}, +{"CX", "CX"}, +{"CXR", "CX"}, +{"CY", "CY"}, +{"CYM", "KY"}, +{"CYP", "CY"}, +{"CYPRUS", "CY"}, +{"CZ", "CZ"}, +{"CZE", "CZ"}, +{"CZECH REPUBLIC", "CZ"}, +{"CZECHIA", "CZ"}, +{"DE", "DE"}, +{"DEMOCRATIC PEOPLE S REPUBLIC OF KOREA", "KP"}, +{"DEMOCRATIC REPUBLIC OF SAO TOME AND PRINCIPE", "ST"}, +{"DEMOCRATIC REPUBLIC OF TIMOR LESTE", "TL"}, +{"DEMOCRATIC SOCIALIST REPUBLIC OF SRI LANKA", "LK"}, +{"DENMARK", "DK"}, +{"DEU", "DE"}, +{"DJ", "DJ"}, +{"DJI", "DJ"}, +{"DJIBOUTI", "DJ"}, +{"DK", "DK"}, +{"DM", "DM"}, +{"DMA", "DM"}, +{"DNK", "DK"}, +{"DO", "DO"}, +{"DOM", "DO"}, +{"DOMINICA", "DM"}, +{"DOMINICAN REPUBLIC", "DO"}, +{"DZ", "DZ"}, +{"DZA", "DZ"}, +{"EAST TIMOR", "TL"}, +{"EASTERN REPUBLIC OF URUGUAY", "UY"}, +{"EC", "EC"}, +{"ECU", "EC"}, +{"ECUADOR", "EC"}, +{"EE", "EE"}, +{"EG", "EG"}, +{"EGY", "EG"}, +{"EGYPT", "EG"}, +{"EH", "EH"}, +{"EL SALVADOR", "SV"}, +{"EQUATORIAL GUINEA", "GQ"}, +{"ER", "ER"}, +{"ERI", "ER"}, +{"ERITREA", "ER"}, +{"ES", "ES"}, +{"ESH", "EH"}, +{"ESP", "ES"}, +{"EST", "EE"}, +{"ESTONIA", "EE"}, +{"ESWATINI", "SZ"}, +{"ET", "ET"}, +{"ETH", "ET"}, +{"ETHIOPIA", "ET"}, +{"FALKLAND ISLANDS MALVINAS", "FK"}, +{"FAROE ISLANDS", "FO"}, +{"FEDERAL DEMOCRATIC REPUBLIC OF ETHIOPIA", "ET"}, +{"FEDERAL DEMOCRATIC REPUBLIC OF NEPAL", "NP"}, +{"FEDERAL REPUBLIC OF GERMANY", "DE"}, +{"FEDERAL REPUBLIC OF NIGERIA", "NG"}, +{"FEDERAL REPUBLIC OF SOMALIA", "SO"}, +{"FEDERATED STATES OF MICRONESIA", "FM"}, +{"FEDERATIVE REPUBLIC OF BRAZIL", "BR"}, +{"FI", "FI"}, +{"FIJI", "FJ"}, +{"FIN", "FI"}, +{"FINLAND", "FI"}, +{"FJ", "FJ"}, +{"FJI", "FJ"}, +{"FK", "FK"}, +{"FLK", "FK"}, +{"FM", "FM"}, +{"FO", "FO"}, +{"FR", "FR"}, +{"FRA", "FR"}, +{"FRANCE", "FR"}, +{"FRENCH GUIANA", "GF"}, +{"FRENCH POLYNESIA", "PF"}, +{"FRENCH REPUBLIC", "FR"}, +{"FRENCH SOUTHERN TERRITORIES", "TF"}, +{"FRO", "FO"}, +{"FSM", "FM"}, +{"GA", "GA"}, +{"GAB", "GA"}, +{"GABON", "GA"}, +{"GABONESE REPUBLIC", "GA"}, +{"GAMBIA", "GM"}, +{"GB", "GB"}, +{"GBR", "GB"}, +{"GD", "GD"}, +{"GE", "GE"}, +{"GEO", "GE"}, +{"GEORGIA", "GE"}, +{"GERMANY", "DE"}, +{"GF", "GF"}, +{"GG", "GG"}, +{"GGY", "GG"}, +{"GH", "GH"}, +{"GHA", "GH"}, +{"GHANA", "GH"}, +{"GI", "GI"}, +{"GIB", "GI"}, +{"GIBRALTAR", "GI"}, +{"GIN", "GN"}, +{"GL", "GL"}, +{"GLP", "GP"}, +{"GM", "GM"}, +{"GMB", "GM"}, +{"GN", "GN"}, +{"GNB", "GW"}, +{"GNQ", "GQ"}, +{"GP", "GP"}, +{"GQ", "GQ"}, +{"GR", "GR"}, +{"GRAND DUCHY OF LUXEMBOURG", "LU"}, +{"GRC", "GR"}, +{"GRD", "GD"}, +{"GREAT BRITAIN", "GB"}, +{"GREECE", "GR"}, +{"GREENLAND", "GL"}, +{"GRENADA", "GD"}, +{"GRL", "GL"}, +{"GS", "GS"}, +{"GT", "GT"}, +{"GTM", "GT"}, +{"GU", "GU"}, +{"GUADELOUPE", "GP"}, +{"GUAM", "GU"}, +{"GUATEMALA", "GT"}, +{"GUERNSEY", "GG"}, +{"GUF", "GF"}, +{"GUINEA", "GN"}, +{"GUINEA BISSAU", "GW"}, +{"GUM", "GU"}, +{"GUY", "GY"}, +{"GUYANA", "GY"}, +{"GW", "GW"}, +{"GY", "GY"}, +{"HAITI", "HT"}, +{"HASHEMITE KINGDOM OF JORDAN", "JO"}, +{"HEARD ISLAND AND MCDONALD ISLANDS", "HM"}, +{"HELLENIC REPUBLIC", "GR"}, +{"HK", "HK"}, +{"HKG", "HK"}, +{"HM", "HM"}, +{"HMD", "HM"}, +{"HN", "HN"}, +{"HND", "HN"}, +{"HOLY SEE VATICAN CITY STATE", "VA"}, +{"HONDURAS", "HN"}, +{"HONG KONG", "HK"}, +{"HONG KONG SPECIAL ADMINISTRATIVE REGION OF CHINA", "HK"}, +{"HR", "HR"}, +{"HRV", "HR"}, +{"HT", "HT"}, +{"HTI", "HT"}, +{"HU", "HU"}, +{"HUN", "HU"}, +{"HUNGARY", "HU"}, +{"ICELAND", "IS"}, +{"ID", "ID"}, +{"IDN", "ID"}, +{"IE", "IE"}, +{"IL", "IL"}, +{"IM", "IM"}, +{"IMN", "IM"}, +{"IN", "IN"}, +{"IND", "IN"}, +{"INDEPENDENT STATE OF PAPUA NEW GUINEA", "PG"}, +{"INDEPENDENT STATE OF SAMOA", "WS"}, +{"INDIA", "IN"}, +{"INDONESIA", "ID"}, +{"IO", "IO"}, +{"IOT", "IO"}, +{"IQ", "IQ"}, +{"IR", "IR"}, +{"IRAN", "IR"}, +{"IRAN ISLAMIC REPUBLIC OF", "IR"}, +{"IRAQ", "IQ"}, +{"IRELAND", "IE"}, +{"IRL", "IE"}, +{"IRN", "IR"}, +{"IRQ", "IQ"}, +{"IS", "IS"}, +{"ISL", "IS"}, +{"ISLAMIC REPUBLIC OF AFGHANISTAN", "AF"}, +{"ISLAMIC REPUBLIC OF IRAN", "IR"}, +{"ISLAMIC REPUBLIC OF MAURITANIA", "MR"}, +{"ISLAMIC REPUBLIC OF PAKISTAN", "PK"}, +{"ISLE OF MAN", "IM"}, +{"ISR", "IL"}, +{"ISRAEL", "IL"}, +{"IT", "IT"}, +{"ITA", "IT"}, +{"ITALIAN REPUBLIC", "IT"}, +{"ITALY", "IT"}, +{"IVORY COAST", "CI"}, +{"JAM", "JM"}, +{"JAMAICA", "JM"}, +{"JAPAN", "JP"}, +{"JE", "JE"}, +{"JERSEY", "JE"}, +{"JEY", "JE"}, +{"JM", "JM"}, +{"JO", "JO"}, +{"JOR", "JO"}, +{"JORDAN", "JO"}, +{"JP", "JP"}, +{"JPN", "JP"}, +{"KAZ", "KZ"}, +{"KAZAKHSTAN", "KZ"}, +{"KE", "KE"}, +{"KEN", "KE"}, +{"KENYA", "KE"}, +{"KG", "KG"}, +{"KGZ", "KG"}, +{"KH", "KH"}, +{"KHM", "KH"}, +{"KI", "KI"}, +{"KINGDOM OF BAHRAIN", "BH"}, +{"KINGDOM OF BELGIUM", "BE"}, +{"KINGDOM OF BHUTAN", "BT"}, +{"KINGDOM OF CAMBODIA", "KH"}, +{"KINGDOM OF DENMARK", "DK"}, +{"KINGDOM OF ESWATINI", "SZ"}, +{"KINGDOM OF LESOTHO", "LS"}, +{"KINGDOM OF MOROCCO", "MA"}, +{"KINGDOM OF NORWAY", "NO"}, +{"KINGDOM OF SAUDI ARABIA", "SA"}, +{"KINGDOM OF SPAIN", "ES"}, +{"KINGDOM OF SWEDEN", "SE"}, +{"KINGDOM OF THAILAND", "TH"}, +{"KINGDOM OF THE NETHERLANDS", "NL"}, +{"KINGDOM OF TONGA", "TO"}, +{"KIR", "KI"}, +{"KIRIBATI", "KI"}, +{"KM", "KM"}, +{"KN", "KN"}, +{"KNA", "KN"}, +{"KOR", "KR"}, +{"KOREA DEMOCRATIC PEOPLE S REPUBLIC OF", "KP"}, +{"KOREA REPUBLIC OF", "KR"}, +{"KP", "KP"}, +{"KR", "KR"}, +{"KUWAIT", "KW"}, +{"KW", "KW"}, +{"KWT", "KW"}, +{"KY", "KY"}, +{"KYRGYZ REPUBLIC", "KG"}, +{"KYRGYZSTAN", "KG"}, +{"KZ", "KZ"}, +{"LA", "LA"}, +{"LAO", "LA"}, +{"LAO PEOPLE S DEMOCRATIC REPUBLIC", "LA"}, +{"LAOS", "LA"}, +{"LATVIA", "LV"}, +{"LB", "LB"}, +{"LBN", "LB"}, +{"LBR", "LR"}, +{"LBY", "LY"}, +{"LC", "LC"}, +{"LCA", "LC"}, +{"LEBANESE REPUBLIC", "LB"}, +{"LEBANON", "LB"}, +{"LESOTHO", "LS"}, +{"LI", "LI"}, +{"LIBERIA", "LR"}, +{"LIBYA", "LY"}, +{"LIE", "LI"}, +{"LIECHTENSTEIN", "LI"}, +{"LITHUANIA", "LT"}, +{"LK", "LK"}, +{"LKA", "LK"}, +{"LR", "LR"}, +{"LS", "LS"}, +{"LSO", "LS"}, +{"LT", "LT"}, +{"LTU", "LT"}, +{"LU", "LU"}, +{"LUX", "LU"}, +{"LUXEMBOURG", "LU"}, +{"LV", "LV"}, +{"LVA", "LV"}, +{"LY", "LY"}, +{"MA", "MA"}, +{"MAC", "MO"}, +{"MACAO", "MO"}, +{"MACAO SPECIAL ADMINISTRATIVE REGION OF CHINA", "MO"}, +{"MADAGASCAR", "MG"}, +{"MAF", "MF"}, +{"MALAWI", "MW"}, +{"MALAYSIA", "MY"}, +{"MALDIVES", "MV"}, +{"MALI", "ML"}, +{"MALTA", "MT"}, +{"MAR", "MA"}, +{"MARSHALL ISLANDS", "MH"}, +{"MARTINIQUE", "MQ"}, +{"MAURITANIA", "MR"}, +{"MAURITIUS", "MU"}, +{"MAYOTTE", "YT"}, +{"MC", "MC"}, +{"MCO", "MC"}, +{"MD", "MD"}, +{"MDA", "MD"}, +{"MDG", "MG"}, +{"MDV", "MV"}, +{"ME", "ME"}, +{"MEX", "MX"}, +{"MEXICO", "MX"}, +{"MF", "MF"}, +{"MG", "MG"}, +{"MH", "MH"}, +{"MHL", "MH"}, +{"MICRONESIA", "FM"}, +{"MICRONESIA FEDERATED STATES OF", "FM"}, +{"MK", "MK"}, +{"MKD", "MK"}, +{"ML", "ML"}, +{"MLI", "ML"}, +{"MLT", "MT"}, +{"MM", "MM"}, +{"MMR", "MM"}, +{"MN", "MN"}, +{"MNE", "ME"}, +{"MNG", "MN"}, +{"MNP", "MP"}, +{"MO", "MO"}, +{"MOLDOVA", "MD"}, +{"MOLDOVA REPUBLIC OF", "MD"}, +{"MONACO", "MC"}, +{"MONGOLIA", "MN"}, +{"MONTENEGRO", "ME"}, +{"MONTSERRAT", "MS"}, +{"MOROCCO", "MA"}, +{"MOZ", "MZ"}, +{"MOZAMBIQUE", "MZ"}, +{"MP", "MP"}, +{"MQ", "MQ"}, +{"MR", "MR"}, +{"MRT", "MR"}, +{"MS", "MS"}, +{"MSR", "MS"}, +{"MT", "MT"}, +{"MTQ", "MQ"}, +{"MU", "MU"}, +{"MUS", "MU"}, +{"MV", "MV"}, +{"MW", "MW"}, +{"MWI", "MW"}, +{"MX", "MX"}, +{"MY", "MY"}, +{"MYANMAR", "MM"}, +{"MYS", "MY"}, +{"MYT", "YT"}, +{"MZ", "MZ"}, +{"NA", "NA"}, +{"NAM", "NA"}, +{"NAMIBIA", "NA"}, +{"NAURU", "NR"}, +{"NC", "NC"}, +{"NCL", "NC"}, +{"NE", "NE"}, +{"NEPAL", "NP"}, +{"NER", "NE"}, +{"NETHERLANDS", "NL"}, +{"NEW CALEDONIA", "NC"}, +{"NEW ZEALAND", "NZ"}, +{"NF", "NF"}, +{"NFK", "NF"}, +{"NG", "NG"}, +{"NGA", "NG"}, +{"NI", "NI"}, +{"NIC", "NI"}, +{"NICARAGUA", "NI"}, +{"NIGER", "NE"}, +{"NIGERIA", "NG"}, +{"NIU", "NU"}, +{"NIUE", "NU"}, +{"NL", "NL"}, +{"NLD", "NL"}, +{"NO", "NO"}, +{"NOR", "NO"}, +{"NORFOLK ISLAND", "NF"}, +{"NORTH KOREA", "KP"}, +{"NORTH MACEDONIA", "MK"}, +{"NORTHERN MARIANA ISLANDS", "MP"}, +{"NORWAY", "NO"}, +{"NP", "NP"}, +{"NPL", "NP"}, +{"NR", "NR"}, +{"NRU", "NR"}, +{"NU", "NU"}, +{"NZ", "NZ"}, +{"NZL", "NZ"}, +{"OM", "OM"}, +{"OMAN", "OM"}, +{"OMN", "OM"}, +{"PA", "PA"}, +{"PAK", "PK"}, +{"PAKISTAN", "PK"}, +{"PALAU", "PW"}, +{"PALESTINE", "PS"}, +{"PALESTINE STATE OF", "PS"}, +{"PAN", "PA"}, +{"PANAMA", "PA"}, +{"PAPUA NEW GUINEA", "PG"}, +{"PARAGUAY", "PY"}, +{"PCN", "PN"}, +{"PE", "PE"}, +{"PEOPLE S DEMOCRATIC REPUBLIC OF ALGERIA", "DZ"}, +{"PEOPLE S REPUBLIC OF BANGLADESH", "BD"}, +{"PEOPLE S REPUBLIC OF CHINA", "CN"}, +{"PER", "PE"}, +{"PERU", "PE"}, +{"PF", "PF"}, +{"PG", "PG"}, +{"PH", "PH"}, +{"PHILIPPINES", "PH"}, +{"PHL", "PH"}, +{"PITCAIRN", "PN"}, +{"PK", "PK"}, +{"PL", "PL"}, +{"PLURINATIONAL STATE OF BOLIVIA", "BO"}, +{"PLW", "PW"}, +{"PM", "PM"}, +{"PN", "PN"}, +{"PNG", "PG"}, +{"POL", "PL"}, +{"POLAND", "PL"}, +{"PORTUGAL", "PT"}, +{"PORTUGUESE REPUBLIC", "PT"}, +{"PR", "PR"}, +{"PRI", "PR"}, +{"PRINCIPALITY OF ANDORRA", "AD"}, +{"PRINCIPALITY OF LIECHTENSTEIN", "LI"}, +{"PRINCIPALITY OF MONACO", "MC"}, +{"PRK", "KP"}, +{"PRT", "PT"}, +{"PRY", "PY"}, +{"PS", "PS"}, +{"PSE", "PS"}, +{"PT", "PT"}, +{"PUERTO RICO", "PR"}, +{"PW", "PW"}, +{"PY", "PY"}, +{"PYF", "PF"}, +{"QA", "QA"}, +{"QAT", "QA"}, +{"QATAR", "QA"}, +{"RE", "RE"}, +{"REPUBLIC OF ALBANIA", "AL"}, +{"REPUBLIC OF ANGOLA", "AO"}, +{"REPUBLIC OF ARMENIA", "AM"}, +{"REPUBLIC OF AUSTRIA", "AT"}, +{"REPUBLIC OF AZERBAIJAN", "AZ"}, +{"REPUBLIC OF BELARUS", "BY"}, +{"REPUBLIC OF BENIN", "BJ"}, +{"REPUBLIC OF BOSNIA AND HERZEGOVINA", "BA"}, +{"REPUBLIC OF BOTSWANA", "BW"}, +{"REPUBLIC OF BULGARIA", "BG"}, +{"REPUBLIC OF BURUNDI", "BI"}, +{"REPUBLIC OF CABO VERDE", "CV"}, +{"REPUBLIC OF CAMEROON", "CM"}, +{"REPUBLIC OF CHAD", "TD"}, +{"REPUBLIC OF CHILE", "CL"}, +{"REPUBLIC OF COLOMBIA", "CO"}, +{"REPUBLIC OF COSTA RICA", "CR"}, +{"REPUBLIC OF COTE D IVOIRE", "CI"}, +{"REPUBLIC OF CROATIA", "HR"}, +{"REPUBLIC OF CUBA", "CU"}, +{"REPUBLIC OF CYPRUS", "CY"}, +{"REPUBLIC OF DJIBOUTI", "DJ"}, +{"REPUBLIC OF ECUADOR", "EC"}, +{"REPUBLIC OF EL SALVADOR", "SV"}, +{"REPUBLIC OF EQUATORIAL GUINEA", "GQ"}, +{"REPUBLIC OF ESTONIA", "EE"}, +{"REPUBLIC OF FIJI", "FJ"}, +{"REPUBLIC OF FINLAND", "FI"}, +{"REPUBLIC OF GHANA", "GH"}, +{"REPUBLIC OF GUATEMALA", "GT"}, +{"REPUBLIC OF GUINEA", "GN"}, +{"REPUBLIC OF GUINEA BISSAU", "GW"}, +{"REPUBLIC OF GUYANA", "GY"}, +{"REPUBLIC OF HAITI", "HT"}, +{"REPUBLIC OF HONDURAS", "HN"}, +{"REPUBLIC OF ICELAND", "IS"}, +{"REPUBLIC OF INDIA", "IN"}, +{"REPUBLIC OF INDONESIA", "ID"}, +{"REPUBLIC OF IRAQ", "IQ"}, +{"REPUBLIC OF KAZAKHSTAN", "KZ"}, +{"REPUBLIC OF KENYA", "KE"}, +{"REPUBLIC OF KIRIBATI", "KI"}, +{"REPUBLIC OF LATVIA", "LV"}, +{"REPUBLIC OF LIBERIA", "LR"}, +{"REPUBLIC OF LITHUANIA", "LT"}, +{"REPUBLIC OF MADAGASCAR", "MG"}, +{"REPUBLIC OF MALAWI", "MW"}, +{"REPUBLIC OF MALDIVES", "MV"}, +{"REPUBLIC OF MALI", "ML"}, +{"REPUBLIC OF MALTA", "MT"}, +{"REPUBLIC OF MAURITIUS", "MU"}, +{"REPUBLIC OF MOLDOVA", "MD"}, +{"REPUBLIC OF MOZAMBIQUE", "MZ"}, +{"REPUBLIC OF MYANMAR", "MM"}, +{"REPUBLIC OF NAMIBIA", "NA"}, +{"REPUBLIC OF NAURU", "NR"}, +{"REPUBLIC OF NICARAGUA", "NI"}, +{"REPUBLIC OF NORTH MACEDONIA", "MK"}, +{"REPUBLIC OF PALAU", "PW"}, +{"REPUBLIC OF PANAMA", "PA"}, +{"REPUBLIC OF PARAGUAY", "PY"}, +{"REPUBLIC OF PERU", "PE"}, +{"REPUBLIC OF POLAND", "PL"}, +{"REPUBLIC OF SAN MARINO", "SM"}, +{"REPUBLIC OF SENEGAL", "SN"}, +{"REPUBLIC OF SERBIA", "RS"}, +{"REPUBLIC OF SEYCHELLES", "SC"}, +{"REPUBLIC OF SIERRA LEONE", "SL"}, +{"REPUBLIC OF SINGAPORE", "SG"}, +{"REPUBLIC OF SLOVENIA", "SI"}, +{"REPUBLIC OF SOUTH AFRICA", "ZA"}, +{"REPUBLIC OF SOUTH SUDAN", "SS"}, +{"REPUBLIC OF SURINAME", "SR"}, +{"REPUBLIC OF TAJIKISTAN", "TJ"}, +{"REPUBLIC OF THE CONGO", "CG"}, +{"REPUBLIC OF THE GAMBIA", "GM"}, +{"REPUBLIC OF THE MARSHALL ISLANDS", "MH"}, +{"REPUBLIC OF THE NIGER", "NE"}, +{"REPUBLIC OF THE PHILIPPINES", "PH"}, +{"REPUBLIC OF THE SUDAN", "SD"}, +{"REPUBLIC OF TRINIDAD AND TOBAGO", "TT"}, +{"REPUBLIC OF TUNISIA", "TN"}, +{"REPUBLIC OF TURKIYE", "TR"}, +{"REPUBLIC OF UGANDA", "UG"}, +{"REPUBLIC OF UZBEKISTAN", "UZ"}, +{"REPUBLIC OF VANUATU", "VU"}, +{"REPUBLIC OF YEMEN", "YE"}, +{"REPUBLIC OF ZAMBIA", "ZM"}, +{"REPUBLIC OF ZIMBABWE", "ZW"}, +{"REU", "RE"}, +{"REUNION", "RE"}, +{"RO", "RO"}, +{"ROMANIA", "RO"}, +{"ROU", "RO"}, +{"RS", "RS"}, +{"RU", "RU"}, +{"RUS", "RU"}, +{"RUSSIA", "RU"}, +{"RUSSIAN FEDERATION", "RU"}, +{"RW", "RW"}, +{"RWA", "RW"}, +{"RWANDA", "RW"}, +{"RWANDESE REPUBLIC", "RW"}, +{"SA", "SA"}, +{"SAINT BARTHELEMY", "BL"}, +{"SAINT HELENA ASCENSION AND TRISTAN DA CUNHA", "SH"}, +{"SAINT KITTS AND NEVIS", "KN"}, +{"SAINT LUCIA", "LC"}, +{"SAINT MARTIN FRENCH PART", "MF"}, +{"SAINT PIERRE AND MIQUELON", "PM"}, +{"SAINT VINCENT AND THE GRENADINES", "VC"}, +{"SAMOA", "WS"}, +{"SAN MARINO", "SM"}, +{"SAO TOME AND PRINCIPE", "ST"}, +{"SAU", "SA"}, +{"SAUDI ARABIA", "SA"}, +{"SB", "SB"}, +{"SC", "SC"}, +{"SD", "SD"}, +{"SDN", "SD"}, +{"SE", "SE"}, +{"SEN", "SN"}, +{"SENEGAL", "SN"}, +{"SERBIA", "RS"}, +{"SEYCHELLES", "SC"}, +{"SG", "SG"}, +{"SGP", "SG"}, +{"SGS", "GS"}, +{"SH", "SH"}, +{"SHN", "SH"}, +{"SI", "SI"}, +{"SIERRA LEONE", "SL"}, +{"SINGAPORE", "SG"}, +{"SINT MAARTEN DUTCH PART", "SX"}, +{"SJ", "SJ"}, +{"SJM", "SJ"}, +{"SK", "SK"}, +{"SL", "SL"}, +{"SLB", "SB"}, +{"SLE", "SL"}, +{"SLOVAK REPUBLIC", "SK"}, +{"SLOVAKIA", "SK"}, +{"SLOVENIA", "SI"}, +{"SLV", "SV"}, +{"SM", "SM"}, +{"SMR", "SM"}, +{"SN", "SN"}, +{"SO", "SO"}, +{"SOCIALIST REPUBLIC OF VIET NAM", "VN"}, +{"SOLOMON ISLANDS", "SB"}, +{"SOM", "SO"}, +{"SOMALIA", "SO"}, +{"SOUTH AFRICA", "ZA"}, +{"SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS", "GS"}, +{"SOUTH KOREA", "KR"}, +{"SOUTH SUDAN", "SS"}, +{"SPAIN", "ES"}, +{"SPM", "PM"}, +{"SR", "SR"}, +{"SRB", "RS"}, +{"SRI LANKA", "LK"}, +{"SS", "SS"}, +{"SSD", "SS"}, +{"ST", "ST"}, +{"STATE OF ISRAEL", "IL"}, +{"STATE OF KUWAIT", "KW"}, +{"STATE OF QATAR", "QA"}, +{"STP", "ST"}, +{"SUDAN", "SD"}, +{"SULTANATE OF OMAN", "OM"}, +{"SUR", "SR"}, +{"SURINAME", "SR"}, +{"SV", "SV"}, +{"SVALBARD AND JAN MAYEN", "SJ"}, +{"SVK", "SK"}, +{"SVN", "SI"}, +{"SWE", "SE"}, +{"SWEDEN", "SE"}, +{"SWISS CONFEDERATION", "CH"}, +{"SWITZERLAND", "CH"}, +{"SWZ", "SZ"}, +{"SX", "SX"}, +{"SXM", "SX"}, +{"SY", "SY"}, +{"SYC", "SC"}, +{"SYR", "SY"}, +{"SYRIA", "SY"}, +{"SYRIAN ARAB REPUBLIC", "SY"}, +{"SZ", "SZ"}, +{"TAIWAN", "TW"}, +{"TAIWAN PROVINCE OF CHINA", "TW"}, +{"TAJIKISTAN", "TJ"}, +{"TANZANIA", "TZ"}, +{"TANZANIA UNITED REPUBLIC OF", "TZ"}, +{"TC", "TC"}, +{"TCA", "TC"}, +{"TCD", "TD"}, +{"TD", "TD"}, +{"TF", "TF"}, +{"TG", "TG"}, +{"TGO", "TG"}, +{"TH", "TH"}, +{"THA", "TH"}, +{"THAILAND", "TH"}, +{"THE STATE OF ERITREA", "ER"}, +{"THE STATE OF PALESTINE", "PS"}, +{"TIMOR LESTE", "TL"}, +{"TJ", "TJ"}, +{"TJK", "TJ"}, +{"TK", "TK"}, +{"TKL", "TK"}, +{"TKM", "TM"}, +{"TL", "TL"}, +{"TLS", "TL"}, +{"TM", "TM"}, +{"TN", "TN"}, +{"TO", "TO"}, +{"TOGO", "TG"}, +{"TOGOLESE REPUBLIC", "TG"}, +{"TOKELAU", "TK"}, +{"TON", "TO"}, +{"TONGA", "TO"}, +{"TR", "TR"}, +{"TRINIDAD AND TOBAGO", "TT"}, +{"TT", "TT"}, +{"TTO", "TT"}, +{"TUN", "TN"}, +{"TUNISIA", "TN"}, +{"TUR", "TR"}, +{"TURKEY", "TR"}, +{"TURKIYE", "TR"}, +{"TURKMENISTAN", "TM"}, +{"TURKS AND CAICOS ISLANDS", "TC"}, +{"TUV", "TV"}, +{"TUVALU", "TV"}, +{"TV", "TV"}, +{"TW", "TW"}, +{"TWN", "TW"}, +{"TZ", "TZ"}, +{"TZA", "TZ"}, +{"U K", "GB"}, +{"U S", "US"}, +{"U S A", "US"}, +{"UA", "UA"}, +{"UG", "UG"}, +{"UGA", "UG"}, +{"UGANDA", "UG"}, +{"UK", "GB"}, +{"UKR", "UA"}, +{"UKRAINE", "UA"}, +{"UM", "UM"}, +{"UMI", "UM"}, +{"UNION OF THE COMOROS", "KM"}, +{"UNITED ARAB EMIRATES", "AE"}, +{"UNITED KINGDOM", "GB"}, +{"UNITED KINGDOM OF GREAT BRITAIN AND NORTHERN IRELAND", "GB"}, +{"UNITED MEXICAN STATES", "MX"}, +{"UNITED REPUBLIC OF TANZANIA", "TZ"}, +{"UNITED STATES", "US"}, +{"UNITED STATES MINOR OUTLYING ISLANDS", "UM"}, +{"UNITED STATES OF AMERICA", "US"}, +{"URUGUAY", "UY"}, +{"URY", "UY"}, +{"US", "US"}, +{"USA", "US"}, +{"UY", "UY"}, +{"UZ", "UZ"}, +{"UZB", "UZ"}, +{"UZBEKISTAN", "UZ"}, +{"VA", "VA"}, +{"VANUATU", "VU"}, +{"VAT", "VA"}, +{"VATICAN CITY", "VA"}, +{"VC", "VC"}, +{"VCT", "VC"}, +{"VE", "VE"}, +{"VEN", "VE"}, +{"VENEZUELA", "VE"}, +{"VENEZUELA BOLIVARIAN REPUBLIC OF", "VE"}, +{"VG", "VG"}, +{"VGB", "VG"}, +{"VI", "VI"}, +{"VIET NAM", "VN"}, +{"VIETNAM", "VN"}, +{"VIR", "VI"}, +{"VIRGIN ISLANDS BRITISH", "VG"}, +{"VIRGIN ISLANDS OF THE UNITED STATES", "VI"}, +{"VIRGIN ISLANDS U S", "VI"}, +{"VN", "VN"}, +{"VNM", "VN"}, +{"VU", "VU"}, +{"VUT", "VU"}, +{"WALLIS AND FUTUNA", "WF"}, +{"WESTERN SAHARA", "EH"}, +{"WF", "WF"}, +{"WLF", "WF"}, +{"WS", "WS"}, +{"WSM", "WS"}, +{"YE", "YE"}, +{"YEM", "YE"}, +{"YEMEN", "YE"}, +{"YT", "YT"}, +{"ZA", "ZA"}, +{"ZAF", "ZA"}, +{"ZAMBIA", "ZM"}, +{"ZIMBABWE", "ZW"}, +{"ZM", "ZM"}, +{"ZMB", "ZM"}, +{"ZW", "ZW"}, +{"ZWE", "ZW"}, diff --git a/extensions/address_standardizer/test-parseaddress.sql.in b/extensions/address_standardizer/test-parseaddress.sql.in index b2a1224c0..f327354f5 100644 --- a/extensions/address_standardizer/test-parseaddress.sql.in +++ b/extensions/address_standardizer/test-parseaddress.sql.in @@ -69,6 +69,15 @@ copy test_parse_address (instring, outstring) from stdin; @@ sttype words$ 123 oak ln, marie ny (123,"oak ln",,"123 oak ln",marie,NY,,,US) 123 oak ln, new marie ny (123,"oak ln",,"123 oak ln","new marie",NY,,,US) +529 Main Street, Boston, MA 021 (529,"Main Street",,"529 Main Street",Boston,MA,021,,US) +529 Main Street, Boston, MA 021, France (529,"Main Street",,"529 Main Street",Boston,MA,021,,FR) +100 Peachtree St, Atlanta, Georgia (100,"Peachtree St",,"100 Peachtree St",Atlanta,GA,,,US) +212 n 3rd ave, Minneapolis, mn 55401, USA (212,"n 3rd ave",,"212 n 3rd ave",Minneapolis,MN,55401,,US) +26 Court Street, Boston, Massachusetts 02109, FR (26,"Court Street",,"26 Court Street",Boston,MA,02109,,FR) +26 Court Street, Boston, MA 02109, Rear (26,"Court Street, Boston, MA 02109",,"26 Court Street, Boston, MA 02109",Rear,,,,US) +212 N 3rd Ave, Minneapolis, MN 55401, Suite A (212,"N 3rd Ave, Minneapolis, MN 55401",,"212 N 3rd Ave, Minneapolis, MN 55401","Suite A",,,,US) +26 Court Street, Boston, Massachusetts 02109, France (26,"Court Street",,"26 Court Street",Boston,MA,02109,,FR) +10 Main Street, Toronto, ON M5V 2T6, France (10,"Main Street",,"10 Main Street",Toronto,ON,"M5V 2T6",,FR) \. select id, instring, outstring as expected, parse_address(instring) as got_result diff --git a/extensions/postgis_tiger_geocoder/Makefile.in b/extensions/postgis_tiger_geocoder/Makefile.in index e0faf1caf..d2b5029d4 100644 --- a/extensions/postgis_tiger_geocoder/Makefile.in +++ b/extensions/postgis_tiger_geocoder/Makefile.in @@ -30,7 +30,7 @@ DATA_built = \ $(NULL) REGRESS = test-normalize_address test-upgrade -REGRESS_OPTS = --load-extension=fuzzystrmatch --load-extension=postgis --load-extension=$(EXTENSION) +REGRESS_OPTS = --load-extension=fuzzystrmatch --load-extension=postgis EXTSCHEMA_SUPPORTED = yes ## PostgreSQL < 16 doesn't understand new @extschema:extname@ syntax, so strip it @@ -46,6 +46,7 @@ ifeq (@ADDRESS_STANDARDIZER@,address_standardizer) REGRESS += test-pagc_normalize_address REGRESS_OPTS += --load-extension=address_standardizer endif +REGRESS_OPTS += --load-extension=$(EXTENSION) all: sql/$(EXTENSION)_pre.sql sql/$(EXTENSION)--$(EXTVERSION).sql sql/$(EXTENSION)--unpackaged--$(EXTVERSION).sql sql/$(EXTENSION)--ANY--$(EXTVERSION).sql sql/test-normalize_address.sql sql/test-pagc_normalize_address.sql expected/test-normalize_address.out expected/test-pagc_normalize_address.out sql/test-upgrade.sql expected/test-upgrade.out diff --git a/extensions/postgis_tiger_geocoder/postgis_tiger_geocoder.control.in b/extensions/postgis_tiger_geocoder/postgis_tiger_geocoder.control.in index 647cba6b8..ed256b89d 100644 --- a/extensions/postgis_tiger_geocoder/postgis_tiger_geocoder.control.in +++ b/extensions/postgis_tiger_geocoder/postgis_tiger_geocoder.control.in @@ -5,4 +5,4 @@ relocatable = false schema = tiger requires = 'postgis,fuzzystrmatch' superuser= false -no_relocate = 'postgis,fuzzystrmatch' \ No newline at end of file +no_relocate = 'postgis,fuzzystrmatch' diff --git a/extensions/postgis_tiger_geocoder/sql_bits/norm_addy_create.sql.in b/extensions/postgis_tiger_geocoder/sql_bits/norm_addy_create.sql.in index 7b70bf876..121548f8b 100644 --- a/extensions/postgis_tiger_geocoder/sql_bits/norm_addy_create.sql.in +++ b/extensions/postgis_tiger_geocoder/sql_bits/norm_addy_create.sql.in @@ -9,5 +9,6 @@ CREATE TYPE norm_addy AS ( stateAbbrev VARCHAR, zip VARCHAR, parsed BOOLEAN, - zip4 varchar, - address_alphanumeric varchar); + zip4 varchar(4), + address_alphanumeric varchar, + country varchar(2)); diff --git a/extensions/postgis_tiger_geocoder/sql_bits/norm_addy_upgrade.sql.in b/extensions/postgis_tiger_geocoder/sql_bits/norm_addy_upgrade.sql.in index 99bf4364c..77561fa14 100644 --- a/extensions/postgis_tiger_geocoder/sql_bits/norm_addy_upgrade.sql.in +++ b/extensions/postgis_tiger_geocoder/sql_bits/norm_addy_upgrade.sql.in @@ -1,2 +1,3 @@ ALTER TYPE tiger.norm_addy ADD ATTRIBUTE zip4 varchar(4); -ALTER TYPE tiger.norm_addy ADD ATTRIBUTE address_alphanumeric varchar; \ No newline at end of file +ALTER TYPE tiger.norm_addy ADD ATTRIBUTE address_alphanumeric varchar; +ALTER TYPE tiger.norm_addy ADD ATTRIBUTE country varchar(2); diff --git a/extensions/postgis_tiger_geocoder/sql_bits/upgrade_before.sql.in b/extensions/postgis_tiger_geocoder/sql_bits/upgrade_before.sql.in index 5bba06428..bcaba281d 100644 --- a/extensions/postgis_tiger_geocoder/sql_bits/upgrade_before.sql.in +++ b/extensions/postgis_tiger_geocoder/sql_bits/upgrade_before.sql.in @@ -1,10 +1,41 @@ -- these introduced in PostGIS 2.4 DO language plpgsql $$ - BEGIN - ALTER TYPE tiger.norm_addy ADD ATTRIBUTE zip4 varchar; +DECLARE + norm_addy_relid oid := (SELECT typrelid FROM pg_type WHERE oid = 'tiger.norm_addy'::regtype); +BEGIN + /* + * Check each attribute independently so upgrades from releases that already + * have zip4/address_alphanumeric still pick up newer additions like country. + */ + IF NOT EXISTS ( + SELECT 1 + FROM pg_attribute + WHERE attrelid = norm_addy_relid + AND attname = 'zip4' + AND NOT attisdropped + ) THEN + ALTER TYPE tiger.norm_addy ADD ATTRIBUTE zip4 varchar(4); + END IF; + + IF NOT EXISTS ( + SELECT 1 + FROM pg_attribute + WHERE attrelid = norm_addy_relid + AND attname = 'address_alphanumeric' + AND NOT attisdropped + ) THEN ALTER TYPE tiger.norm_addy ADD ATTRIBUTE address_alphanumeric varchar; - EXCEPTION - WHEN others THEN -- ignore the error probably cause it already exists - END; -$$; \ No newline at end of file + END IF; + + IF NOT EXISTS ( + SELECT 1 + FROM pg_attribute + WHERE attrelid = norm_addy_relid + AND attname = 'country' + AND NOT attisdropped + ) THEN + ALTER TYPE tiger.norm_addy ADD ATTRIBUTE country varchar(2); + END IF; +END; +$$; diff --git a/extras/tiger_geocoder/create_geocode.sql b/extras/tiger_geocoder/create_geocode.sql index 58647c154..daaa98f33 100644 --- a/extras/tiger_geocoder/create_geocode.sql +++ b/extras/tiger_geocoder/create_geocode.sql @@ -34,7 +34,7 @@ CREATE TYPE norm_addy AS ( location VARCHAR, stateAbbrev VARCHAR, zip VARCHAR, - parsed BOOLEAN, zip4 varchar, address_alphanumeric varchar); + parsed BOOLEAN, zip4 varchar(4), address_alphanumeric varchar, country varchar(2)); -- System/General helper functions \i utility/utmzone.sql @@ -82,4 +82,4 @@ COMMIT; -- Tiger to PostGIS Topology -- only usable if you have topology installed -\i topology/tiger_topology_loader.sql \ No newline at end of file +\i topology/tiger_topology_loader.sql diff --git a/extras/tiger_geocoder/normalize/normalize_address.sql b/extras/tiger_geocoder/normalize/normalize_address.sql index 7af89b318..59bd9f148 100644 --- a/extras/tiger_geocoder/normalize/normalize_address.sql +++ b/extras/tiger_geocoder/normalize/normalize_address.sql @@ -71,6 +71,8 @@ DECLARE rec RECORD; ws VARCHAR; rawInput VARCHAR; + parse_address_helper oid := to_regprocedure('parse_address(text)'); + strip_country_helper oid := to_regprocedure('strip_explicit_country(text)'); -- is this a highway -- (we treat these differently since the road name often comes after the streetType) isHighway boolean := false; @@ -87,6 +89,22 @@ BEGIN RETURN result; END IF; + /* + * Legacy tiger SQL can still be installed without address_standardizer. + * Probe for the newer country helpers before using them. + */ + IF parse_address_helper IS NOT NULL THEN + EXECUTE 'SELECT NULLIF((parse_address($1)).country, '''')' + INTO result.country + USING rawInput; + END IF; + + IF strip_country_helper IS NOT NULL THEN + EXECUTE 'SELECT strip_explicit_country($1)' + INTO rawInput + USING rawInput; + END IF; + ws := E'[ ,.\t\n\f\r]'; IF debug_flag THEN diff --git a/extras/tiger_geocoder/normalize/pprint_addy.sql b/extras/tiger_geocoder/normalize/pprint_addy.sql index 900ee952b..f9ad31347 100644 --- a/extras/tiger_geocoder/normalize/pprint_addy.sql +++ b/extras/tiger_geocoder/normalize/pprint_addy.sql @@ -37,7 +37,13 @@ BEGIN || COALESCE(input.stateAbbrev || ' ' , '') || cull_null(input.zip) || COALESCE('-' || input.zip4, ''); - RETURN trim(result); + result := trim(result); + + IF result <> '' AND input.country IS NOT NULL THEN + result := result || ', ' || input.country; + END IF; + + RETURN result; END; $_$ LANGUAGE plpgsql IMMUTABLE; diff --git a/extras/tiger_geocoder/pagc_normalize/pagc_normalize_address.sql b/extras/tiger_geocoder/pagc_normalize/pagc_normalize_address.sql index e1acdaddc..befce7643 100644 --- a/extras/tiger_geocoder/pagc_normalize/pagc_normalize_address.sql +++ b/extras/tiger_geocoder/pagc_normalize/pagc_normalize_address.sql @@ -20,10 +20,12 @@ BEGIN rawInput := trim(in_rawinput); var_parse_rec := parse_address(rawInput); + result.location := var_parse_rec.city; result.stateAbbrev := trim(var_parse_rec.state); result.zip := var_parse_rec.zip; result.zip4 := NULLIF(var_parse_rec.zipplus,''); + result.country := NULLIF(var_parse_rec.country,''); var_rec := standardize_address('pagc_lex' , 'pagc_gaz' @@ -39,6 +41,7 @@ BEGIN result.streetName := trim(var_rec.name); result.location := trim(var_rec.city); result.stateAbbrev := trim(var_rec.state); + result.country := COALESCE(NULLIF(var_rec.country,''), result.country); --this should be broken out separately like pagc, but normalizer doesn't have a slot for it result.streettypeAbbrev := trim(COALESCE(var_rec.suftype, var_rec.pretype)); result.preDirAbbrev := trim(var_rec.predir); @@ -49,4 +52,4 @@ BEGIN END $$ LANGUAGE plpgsql IMMUTABLE STRICT - COST 100; \ No newline at end of file + COST 100; diff --git a/extras/tiger_geocoder/regress/normalize_address_regress b/extras/tiger_geocoder/regress/normalize_address_regress index 6a417acaa..676bb7698 100644 --- a/extras/tiger_geocoder/regress/normalize_address_regress +++ b/extras/tiger_geocoder/regress/normalize_address_regress @@ -1,45 +1,51 @@ -#887|2450|N|COLORADO|St|||PHILADELPHIA|PA|19132|t||2450 -#1051a|212||3rd|Ave|N|Suite 560|Minneapolis|MN|55401|t||212 -#1051b|3937||43RD|Ave|S||MINNEAPOLIS|MN|55406|t||3937 -#1051c|212|N|3rd|Ave|||Minneapolis|MN|55401|t||212 -#1051d|212||3rd|Ave|N||Minneapolis|MN|55401|t||212 -529||Main|St|||Boston|MA|02129|t||529 -529||Main|St|||Boston|MA|02129|t||529 -529||Main|St|||Boston|MA||t||529 -529||Main|St||Apt 201|Boston|MA|02129|t||529 -529||Main|St||Apt 201|Boston|MA|02129|t||529 -529||Main|St||Apt 201|Boston|MA||t||529 -#1108a|529||Main|St||Suite 201|Boston|MA|02129|t||529 -#1073a|212||3rd|Ave|N||MINNEAPOLIS|MN|553404|t|4|212 -#1073b|212||3rd|Ave|N||MINNEAPOLIS|MN|55401|t||212 -#1073c|529||Main|St|||Boston|MA|021|t||529 -#1086a|949|N|3rd|St|||New Hyde Park|NY|11040|t||949 -#1086b|949|N|3rd|St|||New Hyde Park|NY|11040|t||949 -#1076a|16725||24|Co Rd|||Plymouth|MN|55447|t||16725 -#1076b|16725||24|Co Rd|||Plymouth|MN|55447|t||16725 -#1076c|13800||9|Co Hwy|||Andover|MN|55304|t||13800 -#1076d|13800||9||||Andover|MN|55304|t||13800 -#1076e|14||Forest|Rd|||Acton|MA||t||14 -#1076f|1940||C|Co Rd|W||Roseville|MN|55113|t||1940 -#1076g|3900||6|Rte|||Eastham|MA|02642|t||3900 -#1076h|4533||PARK|Ave|S||MINNEAPOLIS|MN|55407|t||4533 -#1076i|4533||33|Co Rd|||MINNEAPOLIS|MN|55407|t||4533 -#1109a|4373||LAKE|Dr|||ROBBINSDALE|MN|55422|t||4373 -#1109b|4373||LAKE|Dr|||ROBBINSDALE|MN|55422|t||4373 -#1074a|3420||RHODE ISLAND|Ave|S||ST. LOUIS PARK|MN|55426|t||3420 -#1074b|26||Court|St|||Boston|MA|02109|t||26 -#1112a|8401|W|35W|Svc Dr|NE||Blaine|MN|55449|t||8401 -#1112b|8401||35W||||Blaine|MN|55449|t||8401 -#1112c|8401||35W||W||Blaine|MN|55449|t||8401 -#1112d|8401|W|35W||||Blaine|MN|55449|t||8401 -#1112e|8401|W|35W||||Blaine|MN|55449|t||8401 -#1125a|19596 Co Rd 480, COLCORD, OK 74338 -#1125b|4345 353 Rte, SALAMANCA, NY 14779|4345||353|Rte|||SALAMANCA|NY|14779|t||4345 -#1125c|19799 State Rte O, COSBY, MO 64436|19799||O|State Rte|||COSBY|MO|64436|t||19799 -#1125d|Interstate Interstate 90, Boston, MA|||Interstate 90||||Boston|MA||t||Interstate -#1125e|I-90 I-90,Boston, MA|||I-90,Boston|||||MA||t||I-90 -#1125f|I I 90, Boston, MA|||I 90||||Boston|MA||t||I -#1310a|1110 W CAPITOL Ave, WEST SACRAMENTO, CA|1110|W|CAPITOL|Ave|||WEST SACRAMENTO|CA||t||1110 -#1614a|8435 Co Rd 20 SE, ROCHESTER, MN 55904|8435||20|Co Rd|SE||ROCHESTER|MN|55904|t||8435 -#1614b|3208 US Hwy 52, Rochester, MN 55901|3208||52|US Hwy|||Rochester|MN|55901|t||3208 -#1108a|529 Main St, Suite 201, Boston, MA 02129|529||Main|St||Suite 201|Boston|MA|02129|t||529 +#887|2450|N|COLORADO|St|||PHILADELPHIA|PA|19132|t||2450|US +#1051a|212||3rd|Ave|N|Suite 560|Minneapolis|MN|55401|t||212|US +#1051b|3937||43RD|Ave|S||MINNEAPOLIS|MN|55406|t||3937|US +#1051c|212|N|3rd|Ave|||Minneapolis|MN|55401|t||212|US +#1599|212|N|3rd|Ave|||Minneapolis|MN|55401|t||212|US +#1599b|212|N|3rd|Ave|||Minneapolis|MN|55401|t||212|FR +#1599c|26||Court|St|||Boston|MA|02109|t||26|FR +#1599d|529||Main|St|||Boston|MA|021|t||529|FR +#1599e|26||Court|St|||Boston|MA|02109|t||26|FR +#1051d|212||3rd|Ave|N||Minneapolis|MN|55401|t||212|US +529||Main|St|||Boston|MA|02129|t||529|US +529||Main|St|||Boston|MA|02129|t||529|US +529||Main|St|||Boston|MA||t||529|US +529||Main|St||Apt 201|Boston|MA|02129|t||529|US +529||Main|St||Apt 201|Boston|MA|02129|t||529|US +529||Main|St||Apt 201|Boston|MA||t||529|US +#1108a|529||Main|St||Suite 201|Boston|MA|02129|t||529|US +#1073a|212||3rd|Ave|N||MINNEAPOLIS|MN|553404|t|4|212|US +#1073b|212||3rd|Ave|N||MINNEAPOLIS|MN|55401|t||212|US +#1073c|529||Main|St|||Boston|MA|021|t||529|US +#1086a|949|N|3rd|St|||New Hyde Park|NY|11040|t||949|US +#1086b|949|N|3rd|St|||New Hyde Park|NY|11040|t||949|US +#1076a|16725||24|Co Rd|||Plymouth|MN|55447|t||16725|US +#1076b|16725||24|Co Rd|||Plymouth|MN|55447|t||16725|US +#1076c|13800||9|Co Hwy|||Andover|MN|55304|t||13800|US +#1076d|13800||9||||Andover|MN|55304|t||13800|US +#1076e|14||Forest|Rd|||Acton|MA||t||14|US +#1076f|1940||C|Co Rd|W||Roseville|MN|55113|t||1940|US +#1076g|3900||6|Rte|||Eastham|MA|02642|t||3900|US +#1076h|4533||PARK|Ave|S||MINNEAPOLIS|MN|55407|t||4533|US +#1076i|4533||33|Co Rd|||MINNEAPOLIS|MN|55407|t||4533|US +#1109a|4373||LAKE|Dr|||ROBBINSDALE|MN|55422|t||4373|US +#1109b|4373||LAKE|Dr|||ROBBINSDALE|MN|55422|t||4373|US +#1074a|3420||RHODE ISLAND|Ave|S||ST. LOUIS PARK|MN|55426|t||3420|US +#1074b|26||Court|St|||Boston|MA|02109|t||26|US +#1112a|8401|W|35W|Svc Dr|NE||Blaine|MN|55449|t||8401|US +#1112b|8401||35W||||Blaine|MN|55449|t||8401|US +#1112c|8401||35W||W||Blaine|MN|55449|t||8401|US +#1112d|8401|W|35W||||Blaine|MN|55449|t||8401|US +#1112e|8401|W|35W||||Blaine|MN|55449|t||8401|US +#1125a|19596 Co Rd 480, COLCORD, OK 74338, US +#1125b|4345 353 Rte, SALAMANCA, NY 14779, US|4345||353|Rte|||SALAMANCA|NY|14779|t||4345|US +#1125c|19799 State Rte O, COSBY, MO 64436, US|19799||O|State Rte|||COSBY|MO|64436|t||19799|US +#1125d|Interstate Interstate 90, Boston, MA, US|||Interstate 90||||Boston|MA||t||Interstate|US +#1125e|I-90 I-90,Boston, MA, US|||I-90,Boston|||||MA||t||I-90|US +#1125f|I I 90, Boston, MA, US|||I 90||||Boston|MA||t||I|US +#1599g| +#1310a|1110 W CAPITOL Ave, WEST SACRAMENTO, CA, US|1110|W|CAPITOL|Ave|||WEST SACRAMENTO|CA||t||1110|US +#1614a|8435 Co Rd 20 SE, ROCHESTER, MN 55904, US|8435||20|Co Rd|SE||ROCHESTER|MN|55904|t||8435|US +#1614b|3208 US Hwy 52, Rochester, MN 55901, US|3208||52|US Hwy|||Rochester|MN|55901|t||3208|US +#1108a|529 Main St, Suite 201, Boston, MA 02129, US|529||Main|St||Suite 201|Boston|MA|02129|t||529|US diff --git a/extras/tiger_geocoder/regress/normalize_address_regress.sql b/extras/tiger_geocoder/regress/normalize_address_regress.sql index 0447bdfdf..46749542e 100644 --- a/extras/tiger_geocoder/regress/normalize_address_regress.sql +++ b/extras/tiger_geocoder/regress/normalize_address_regress.sql @@ -3,6 +3,11 @@ SELECT '#887' As ticket, * FROM normalize_address('2450 N COLORADO ST, PHILADELP SELECT '#1051a' As ticket, * FROM normalize_address('212 3rd Ave N Suite 560, Minneapolis, MN 55401'); SELECT '#1051b' As ticket, * FROM normalize_address('3937 43RD AVE S, MINNEAPOLIS, MN 55406'); SELECT '#1051c' As ticket, * FROM normalize_address('212 N 3rd Ave, Minneapolis, MN 55401'); +SELECT '#1599' As ticket, * FROM normalize_address('212 n 3rd ave, Minneapolis, mn 55401, USA'); +SELECT '#1599b' As ticket, * FROM normalize_address('212 n 3rd ave, Minneapolis, mn 55401, France'); +SELECT '#1599c' As ticket, * FROM normalize_address('26 Court Street, Boston, Massachusetts 02109, France'); +SELECT '#1599d' As ticket, * FROM normalize_address('529 Main Street, Boston, MA 021, France'); +SELECT '#1599e' As ticket, * FROM normalize_address('26 Court Street, Boston, Massachusetts 02109, FR'); -- City missing , -- NOTE this one won't normalize right if you don't have MN data loaded SELECT '#1051d' As ticket, * FROM normalize_address('212 3rd Ave N Minneapolis, MN 55401'); -- comma in wrong spot @@ -86,6 +91,7 @@ SELECT '#1125d' As ticket, pprint_addy(addy), addy.* FROM normalize_address('Int SELECT '#1125e' As ticket, pprint_addy(addy), addy.* FROM normalize_address('I-90,Boston, MA') As addy; --broke this one too SELECT '#1125f' As ticket, pprint_addy(addy), addy.* FROM normalize_address('I 90,Boston, MA') As addy; +SELECT '#1599g' As ticket, pprint_addy(ROW(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,true,NULL,NULL,'US')::norm_addy); -- location with prefixes getting caught in post prefix SELECT '#1310a' As ticket, pprint_addy(addy), addy.* FROM normalize_address('1110 W CAPITOL AVE, WEST SACRAMENTO, CA') As addy; diff --git a/extras/tiger_geocoder/regress/pagc_normalize_address_regress b/extras/tiger_geocoder/regress/pagc_normalize_address_regress index 95216890b..9ea5fefd6 100644 --- a/extras/tiger_geocoder/regress/pagc_normalize_address_regress +++ b/extras/tiger_geocoder/regress/pagc_normalize_address_regress @@ -1,53 +1,58 @@ true -#887|2450|N|COLORADO|ST|||PHILADELPHIA|PA|19132|t||2450 -#1051a|212||3RD|AVE|N|STE 560|MINNEAPOLIS|MN|55401|t||212 -#1051b|3937||43RD|AVE|S||MINNEAPOLIS|MN|55406|t||3937 -#1051c|212|N|3RD|AVE|||MINNEAPOLIS|MN|55401|t||212 -#1051d|212||3RD|AVE|N||MINNEAPOLIS|MN|55401|t||212 -529||MAIN|ST|||BOSTON|MA|02129|t||529 -529||MAIN|ST|||BOSTON|MA|02129|t||529 -529||MAIN|ST|||BOSTON|MA||t||529 -529||MAIN|ST||APT 201|BOSTON|MA|02129|t||529 -529||MAIN|ST||APT 201|BOSTON|MA|02129|t||529 -529||MAIN|ST||APT 201|BOSTON|MA||t||529 -#1108a|529||MAIN|ST||STE 201|BOSTON|MA|02129|t||529 -#1073a|212||3RD|AVE|N||MINNEAPOLIS|MN|55340|t|4|212 -#1073b|212||3RD|AVE|N||MINNEAPOLIS|MN|55401|t||212 -#1073c|529||MAIN|ST||BOSTON|MASSACHUSETTS||021|t||529 -#1086a|949|N|3RD|ST|||NEW HYDE PARK|NY|11040|t||949 -#1086b|949|N|3RD|ST|||NEW HYDE PARK|NY|11040|t||949 -#1076a|16725||24|CO RD|||PLYMOUTH|MN|55447|t||16725 -#1076b|16725||24|CO RD|||PLYMOUTH|MN|55447|t||16725 -#1076c|13800||9|CO HWY|||ANDOVER|MN|55304|t||13800 -#1076d|13800||9||||ANDOVER|MN|55304|t||13800 -#1076e|14||FOREST|RD|||ACTON|MA||t||14 -#1076f|1940||C|CO RD|W||ROSEVILLE|MN|55113|t||1940 -#1076g|3900||6|RTE|||EASTHAM|MA|02642|t||3900 -#1076h|4533||PARK|AVE|S||MINNEAPOLIS|MN|55407|t||4533 -#1076i|4533||33|CO RD|||MINNEAPOLIS|MN|55407|t||4533 -#1109a|4373||LAKE|DR|||ROBBINSDALE|MN|55422|t||4373 -#1109b|4373||LAKE|DR|||ROBBINSDALE|MN|55422|t||4373 -#1074a|3420||RHODE ISLAND|AVE|S||SAINT LOUIS PARK|MN|55426|t||3420 -#1074b|26||COURT|ST|||BOSTON|MA|02109|t||26 -#1112a|8401|W|35 W|SVC DR|NE||BLAINE|MN|55449|t||8401 -#1112b|8401||35 W||||BLAINE|MN|55449|t||8401 -#1112c|8401||35 W||W||BLAINE|MN|55449|t||8401 -#1112d|8401|W|35||W||BLAINE|MN|55449|t||8401 -#1112e|8401|W|35||W||BLAINE|MN|55449|t||8401 -#1125a|19596 CO RD 480, COLCORD, OK 74338 -#1125b|4345 353 RTE, SALAMANCA, NY 14779|4345||353|RTE|||SALAMANCA|NY|14779|t||4345 -#1125c|19799 STATE RTE 0, COSBY, MO 64436|19799||0|STATE RTE|||COSBY|MO|64436|t||19799 -#1125d|||||||||||t|| -#1125e|||||||||||t|| -#1125f|||||||||||t|| -#1310a|1110 W CAPITOL AVE, WEST SACRAMENTO, CA|1110|W|CAPITOL|AVE|||WEST SACRAMENTO|CA||t||1110 -#1614a|8435 CO RD 20 SE, ROCHESTER, MN 55904|8435||20|CO RD|SE||ROCHESTER|MN|55904|t||8435 -#1614b|3208 US RTE 52, ROCHESTER, MN 55901|3208||52|US RTE|||ROCHESTER|MN|55901|t||3208 -#1108a|529 MAIN ST, STE 201, BOSTON, MA 02129|529||MAIN|ST||STE 201|BOSTON|MA|02129|t||529 -#3259a|212||3RD|AVE|N|STE 560|MINNEAPOLIS|MN|55401|t||212 -#3259b|3937||43RD|AVE|S||MINNEAPOLIS|MN|55406|t||3937 -#2981|1566||NEW STATE HWY||||RAYNHAM|MA||t||1566 -#2978a|10||DORRANCE|ST|||PROVIDENCE|RI||t||10 20 -#2978b|10||DORRANCE|ST|||PROVIDENCE|RI||t||10 20 -#2978c|10||DORRANCE|ST|||PROVIDENCE|RI||t||10 20 +#887|2450|N|COLORADO|ST|||PHILADELPHIA|PA|19132|t||2450|US +#1051a|212||3RD|AVE|N|STE 560|MINNEAPOLIS|MN|55401|t||212|US +#1051b|3937||43RD|AVE|S||MINNEAPOLIS|MN|55406|t||3937|US +#1051c|212|N|3RD|AVE|||MINNEAPOLIS|MN|55401|t||212|US +#1599|212|N|3RD|AVE|||MINNEAPOLIS|MN|55401|t||212|US +#1599b|212|N|3RD|AVE|||MINNEAPOLIS|MN|55401|t||212|FR +#1599c|26||COURT|ST|||BOSTON|MA|02109|t||26|FR +#1599d|529||MAIN|ST|||BOSTON|MA|021|t||529|FR +#1599e|26||COURT|ST|||BOSTON|MA|02109|t||26|FR +#1051d|212||3RD|AVE|N||MINNEAPOLIS|MN|55401|t||212|US +529||MAIN|ST|||BOSTON|MA|02129|t||529|US +529||MAIN|ST|||BOSTON|MA|02129|t||529|US +529||MAIN|ST|||BOSTON|MA||t||529|US +529||MAIN|ST||APT 201|BOSTON|MA|02129|t||529|US +529||MAIN|ST||APT 201|BOSTON|MA|02129|t||529|US +529||MAIN|ST||APT 201|BOSTON|MA||t||529|US +#1108a|529||MAIN|ST||STE 201|BOSTON|MA|02129|t||529|US +#1073a|212||3RD|AVE|N||MINNEAPOLIS|MN|55340|t|4|212|US +#1073b|212||3RD|AVE|N||MINNEAPOLIS|MN|55401|t||212|US +#1073c|529||MAIN|ST|||BOSTON|MA|021|t||529|US +#1086a|949|N|3RD|ST|||NEW HYDE PARK|NY|11040|t||949|US +#1086b|949|N|3RD|ST|||NEW HYDE PARK|NY|11040|t||949|US +#1076a|16725||24|CO RD|||PLYMOUTH|MN|55447|t||16725|US +#1076b|16725||24|CO RD|||PLYMOUTH|MN|55447|t||16725|US +#1076c|13800||9|CO HWY|||ANDOVER|MN|55304|t||13800|US +#1076d|13800||9||||ANDOVER|MN|55304|t||13800|US +#1076e|14||FOREST|RD|||ACTON|MA||t||14|US +#1076f|1940||C|CO RD|W||ROSEVILLE|MN|55113|t||1940|US +#1076g|3900||6|RTE|||EASTHAM|MA|02642|t||3900|US +#1076h|4533||PARK|AVE|S||MINNEAPOLIS|MN|55407|t||4533|US +#1076i|4533||33|CO RD|||MINNEAPOLIS|MN|55407|t||4533|US +#1109a|4373||LAKE|DR|||ROBBINSDALE|MN|55422|t||4373|US +#1109b|4373||LAKE|DR|||ROBBINSDALE|MN|55422|t||4373|US +#1074a|3420||RHODE ISLAND|AVE|S||SAINT LOUIS PARK|MN|55426|t||3420|US +#1074b|26||COURT|ST|||BOSTON|MA|02109|t||26|US +#1112a|8401|W|35 W|SVC DR|NE||BLAINE|MN|55449|t||8401|US +#1112b|8401||35 W||||BLAINE|MN|55449|t||8401|US +#1112c|8401||35 W||W||BLAINE|MN|55449|t||8401|US +#1112d|8401|W|35||W||BLAINE|MN|55449|t||8401|US +#1112e|8401|W|35||W||BLAINE|MN|55449|t||8401|US +#1125a|19596 CO RD 480, COLCORD, OK 74338, US +#1125b|4345 353 RTE, SALAMANCA, NY 14779, US|4345||353|RTE|||SALAMANCA|NY|14779|t||4345|US +#1125c|19799 STATE RTE 0, COSBY, MO 64436, US|19799||0|STATE RTE|||COSBY|MO|64436|t||19799|US +#1125d|||||||||||t|||US +#1125e|||||||||||t|||US +#1125f|||||||||||t|||US +#1310a|1110 W CAPITOL AVE, WEST SACRAMENTO, CA, US|1110|W|CAPITOL|AVE|||WEST SACRAMENTO|CA||t||1110|US +#1614a|8435 CO RD 20 SE, ROCHESTER, MN 55904, US|8435||20|CO RD|SE||ROCHESTER|MN|55904|t||8435|US +#1614b|3208 US RTE 52, ROCHESTER, MN 55901, US|3208||52|US RTE|||ROCHESTER|MN|55901|t||3208|US +#1108a|529 MAIN ST, STE 201, BOSTON, MA 02129, US|529||MAIN|ST||STE 201|BOSTON|MA|02129|t||529|US +#3259a|212||3RD|AVE|N|STE 560|MINNEAPOLIS|MN|55401|t||212|US +#3259b|3937||43RD|AVE|S||MINNEAPOLIS|MN|55406|t||3937|US +#2981|1566||NEW STATE HWY||||RAYNHAM|MA||t||1566|US +#2978a|10||DORRANCE|ST|||PROVIDENCE|RI||t||10 20|US +#2978b|10||DORRANCE|ST|||PROVIDENCE|RI||t||10 20|US +#2978c|10||DORRANCE|ST|||PROVIDENCE|RI||t||10 20|US false diff --git a/extras/tiger_geocoder/regress/pagc_normalize_address_regress.sql b/extras/tiger_geocoder/regress/pagc_normalize_address_regress.sql index abd6d094b..783732fce 100644 --- a/extras/tiger_geocoder/regress/pagc_normalize_address_regress.sql +++ b/extras/tiger_geocoder/regress/pagc_normalize_address_regress.sql @@ -7,6 +7,11 @@ SELECT '#1051a' As ticket, * FROM normalize_address('212 3rd Ave N Suite 560, Mi SELECT '#1051b' As ticket, * FROM normalize_address('3937 43RD AVE S, MINNEAPOLIS, MN 55406'); -- this currently turns 3rd to 3, we want to fix to keep 3rd as is SELECT '#1051c' As ticket, * FROM normalize_address('212 N 3rd Ave, Minneapolis, MN 55401'); +SELECT '#1599' As ticket, * FROM normalize_address('212 n 3rd ave, Minneapolis, mn 55401, USA'); +SELECT '#1599b' As ticket, * FROM normalize_address('212 n 3rd ave, Minneapolis, mn 55401, France'); +SELECT '#1599c' As ticket, * FROM normalize_address('26 Court Street, Boston, Massachusetts 02109, France'); +SELECT '#1599d' As ticket, * FROM normalize_address('529 Main Street, Boston, MA 021, France'); +SELECT '#1599e' As ticket, * FROM normalize_address('26 Court Street, Boston, Massachusetts 02109, FR'); -- this currently turns 3rd to 3, we want to fix to keep 3rd as is SELECT '#1051d' As ticket, * FROM normalize_address('212 3rd Ave N Minneapolis, MN 55401'); -- comma in wrong spot diff --git a/extras/tiger_geocoder/upgrade_geocode.sql b/extras/tiger_geocoder/upgrade_geocode.sql index 1057a3a8b..c98decd9f 100644 --- a/extras/tiger_geocoder/upgrade_geocode.sql +++ b/extras/tiger_geocoder/upgrade_geocode.sql @@ -28,12 +28,43 @@ ALTER TABLE state_lookup ADD CONSTRAINT state_lookup_statefp_key UNIQUE(statefp) -- these introduced in PostGIS 2.4 DO language plpgsql $$ - BEGIN - ALTER TYPE tiger.norm_addy ADD ATTRIBUTE zip4 varchar; +DECLARE + norm_addy_relid oid := (SELECT typrelid FROM pg_type WHERE oid = 'tiger.norm_addy'::regtype); +BEGIN + /* + * Check each attribute independently so upgrades from releases that already + * have zip4/address_alphanumeric still pick up newer additions like country. + */ + IF NOT EXISTS ( + SELECT 1 + FROM pg_attribute + WHERE attrelid = norm_addy_relid + AND attname = 'zip4' + AND NOT attisdropped + ) THEN + ALTER TYPE tiger.norm_addy ADD ATTRIBUTE zip4 varchar(4); + END IF; + + IF NOT EXISTS ( + SELECT 1 + FROM pg_attribute + WHERE attrelid = norm_addy_relid + AND attname = 'address_alphanumeric' + AND NOT attisdropped + ) THEN ALTER TYPE tiger.norm_addy ADD ATTRIBUTE address_alphanumeric varchar; - EXCEPTION - WHEN others THEN -- ignore the error probably cause it already exists - END; + END IF; + + IF NOT EXISTS ( + SELECT 1 + FROM pg_attribute + WHERE attrelid = norm_addy_relid + AND attname = 'country' + AND NOT attisdropped + ) THEN + ALTER TYPE tiger.norm_addy ADD ATTRIBUTE country varchar(2); + END IF; +END; $$; CREATE INDEX idx_tiger_edges_countyfp ON edges USING btree(countyfp); ----------------------------------------------------------------------- Summary of changes: NEWS | 4 + doc/extras_address_standardizer.xml | 5 +- doc/installation.xml | 2 +- extensions/address_standardizer/address_parser.c | 17 + .../address_standardizer/address_standardizer.c | 8 + .../address_standardizer_functions.sql.in | 4 + .../expected/test-standardize_address_1.out | 12 +- extensions/address_standardizer/parseaddress-api.c | 242 +++++- extensions/address_standardizer/parseaddress-api.h | 2 + .../address_standardizer/parseaddress-countries.h | 942 +++++++++++++++++++++ .../address_standardizer/test-parseaddress.sql.in | 9 + extensions/postgis_tiger_geocoder/Makefile.in | 3 +- .../postgis_tiger_geocoder.control.in | 2 +- .../sql_bits/norm_addy_create.sql.in | 5 +- .../sql_bits/norm_addy_upgrade.sql.in | 3 +- .../sql_bits/upgrade_before.sql.in | 43 +- extras/tiger_geocoder/create_geocode.sql | 4 +- .../tiger_geocoder/normalize/normalize_address.sql | 18 + extras/tiger_geocoder/normalize/pprint_addy.sql | 8 +- .../pagc_normalize/pagc_normalize_address.sql | 5 +- .../regress/normalize_address_regress | 96 ++- .../regress/normalize_address_regress.sql | 6 + .../regress/pagc_normalize_address_regress | 107 +-- .../regress/pagc_normalize_address_regress.sql | 5 + extras/tiger_geocoder/upgrade_geocode.sql | 41 +- 25 files changed, 1451 insertions(+), 142 deletions(-) create mode 100644 extensions/address_standardizer/parseaddress-countries.h hooks/post-receive -- PostGIS From trac at osgeo.org Mon Mar 9 02:09:57 2026 From: trac at osgeo.org (PostGIS) Date: Mon, 09 Mar 2026 09:09:57 -0000 Subject: [PostGIS] #1599: normalize_address() confused by country In-Reply-To: <051.d971ae23b4cc45973d91a5cb2a22fabe@osgeo.org> References: <051.d971ae23b4cc45973d91a5cb2a22fabe@osgeo.org> Message-ID: <066.956e295e23824d8248c5700abf49c0ea@osgeo.org> #1599: normalize_address() confused by country ----------------------------------+----------------------------- Reporter: mikepease | Owner: robe Type: defect | Status: closed Priority: medium | Milestone: PostGIS Fund Me Component: pagc_address_parser | Version: master Resolution: fixed | Keywords: ----------------------------------+----------------------------- Changes (by Darafei Praliaskouski ): * resolution: => fixed * status: assigned => closed Comment: In [changeset:"20fcd89ae646c2557cf892251242bc16a76a927c/git" 20fcd89/git]: {{{#!CommitTicketReference repository="git" revision="20fcd89ae646c2557cf892251242bc16a76a927c" #1599 Improve country-aware address normalization Canonicalize explicit country tokens in the address parser, carry country through norm_addy, and add regressions for country-aware tiger normalization while keeping tiger usable without address_standardizer. Closes #1599 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Mon Mar 9 04:23:45 2026 From: git at osgeo.org (git at osgeo.org) Date: Mon, 9 Mar 2026 04:23:45 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-381-gd2a87d630 Message-ID: <20260309112345.CC3611AFF96@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via d2a87d6305a558906618f7df087ffdcf8a60d988 (commit) from 20fcd89ae646c2557cf892251242bc16a76a927c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d2a87d6305a558906618f7df087ffdcf8a60d988 Author: Darafei Praliaskouski Date: Mon Mar 9 14:34:50 2026 +0400 Fix #1461 geocode_intersection spacing fallback Add a narrow normalized-fullname comparison so geocode_intersection matches TIGER highway names when spacing around hyphens differs, without changing suffix-form route parsing or type-less second-street scoring. Closes #1461 diff --git a/NEWS b/NEWS index d9bf639d8..c6d77cc77 100644 --- a/NEWS +++ b/NEWS @@ -41,6 +41,9 @@ This version requires GEOS 3.10 or higher - #4828, geometry_columns handles NOT VALID SRID checks without errors (Darafei Praliaskouski) - #6048, [raster] ST_Clip no longer crashes when clipping sparse band selections (Darafei Praliaskouski) + - #1461, [tiger geocoder] geocode_intersection now tolerates irregular + spacing in highway names such as `I- 635` vs `I-635` + (OpenAI) - #1599, [address_standardizer] parse_address() and normalize_address() now canonicalize trailing country tokens to ISO 3166-1 alpha-2 codes and expose country on normalized addresses diff --git a/extensions/postgis_tiger_geocoder/Makefile.in b/extensions/postgis_tiger_geocoder/Makefile.in index d2b5029d4..c103b3069 100644 --- a/extensions/postgis_tiger_geocoder/Makefile.in +++ b/extensions/postgis_tiger_geocoder/Makefile.in @@ -29,7 +29,7 @@ DATA_built = \ sql/$(EXTENSION)--unpackaged--$(EXTVERSION).sql \ $(NULL) -REGRESS = test-normalize_address test-upgrade +REGRESS = test-normalize_address test-geocode_intersection_spacing test-upgrade REGRESS_OPTS = --load-extension=fuzzystrmatch --load-extension=postgis EXTSCHEMA_SUPPORTED = yes @@ -48,7 +48,7 @@ ifeq (@ADDRESS_STANDARDIZER@,address_standardizer) endif REGRESS_OPTS += --load-extension=$(EXTENSION) -all: sql/$(EXTENSION)_pre.sql sql/$(EXTENSION)--$(EXTVERSION).sql sql/$(EXTENSION)--unpackaged--$(EXTVERSION).sql sql/$(EXTENSION)--ANY--$(EXTVERSION).sql sql/test-normalize_address.sql sql/test-pagc_normalize_address.sql expected/test-normalize_address.out expected/test-pagc_normalize_address.out sql/test-upgrade.sql expected/test-upgrade.out +all: sql/$(EXTENSION)_pre.sql sql/$(EXTENSION)--$(EXTVERSION).sql sql/$(EXTENSION)--unpackaged--$(EXTVERSION).sql sql/$(EXTENSION)--ANY--$(EXTVERSION).sql sql/test-normalize_address.sql sql/test-geocode_intersection_spacing.sql sql/test-pagc_normalize_address.sql expected/test-normalize_address.out expected/test-geocode_intersection_spacing.out expected/test-pagc_normalize_address.out sql/test-upgrade.sql expected/test-upgrade.out .PHONY: expected @@ -71,6 +71,9 @@ endif expected/test-normalize_address.out: sql_bits/test_tuples_only_unaligned.sql.in ../../extras/tiger_geocoder/regress/normalize_address_regress | expected cat $^ > $@ +expected/test-geocode_intersection_spacing.out: sql_bits/test_tuples_only_unaligned.sql.in sql_bits/test-geocode_intersection_spacing.out.in | expected + cat $^ > $@ + expected/test-pagc_normalize_address.out: sql_bits/test_tuples_only_unaligned.sql.in ../../extras/tiger_geocoder/regress/pagc_normalize_address_regress | expected cat $^ > $@ @@ -78,6 +81,9 @@ expected/test-pagc_normalize_address.out: sql_bits/test_tuples_only_unaligned.sq sql/test-normalize_address.sql: sql_bits/test_tuples_only_unaligned.sql.in ../../extras/tiger_geocoder/regress/normalize_address_regress.sql | sql cat $^ > $@ +sql/test-geocode_intersection_spacing.sql: sql_bits/test_tuples_only_unaligned.sql.in sql_bits/test-geocode_intersection_spacing.sql.in | sql + cat $^ > $@ + sql/test-upgrade.sql: | sql echo 'ALTER EXTENSION ${EXTENSION} UPDATE TO "ANY"; ALTER EXTENSION ${EXTENSION} UPDATE TO "$(EXTVERSION)"' > $@ diff --git a/extensions/postgis_tiger_geocoder/sql_bits/test-geocode_intersection_spacing.out.in b/extensions/postgis_tiger_geocoder/sql_bits/test-geocode_intersection_spacing.out.in new file mode 100644 index 000000000..805fad2d3 --- /dev/null +++ b/extensions/postgis_tiger_geocoder/sql_bits/test-geocode_intersection_spacing.out.in @@ -0,0 +1,4 @@ +#1461c|353|Rte +#1461a|100 N Belt Line Rd, Coppell, TX 75019|POINT(-96.99 32.986)|5 +#1461b|100 N Belt Line Rd, Coppell, TX 75019|POINT(-96.99 32.986)|5 +#1461d|50 Weld Ave, Coppell, TX 75019|POINT(-96.98 32.98)|4 diff --git a/extensions/postgis_tiger_geocoder/sql_bits/test-geocode_intersection_spacing.sql.in b/extensions/postgis_tiger_geocoder/sql_bits/test-geocode_intersection_spacing.sql.in new file mode 100644 index 000000000..304f928ee --- /dev/null +++ b/extensions/postgis_tiger_geocoder/sql_bits/test-geocode_intersection_spacing.sql.in @@ -0,0 +1,63 @@ +\o /dev/null +BEGIN; + +INSERT INTO tiger.zip_lookup_base(zip, state, county, city, statefp) +VALUES ('75019', 'Texas', 'Dallas', 'Coppell', '48'); + +INSERT INTO tiger.place(statefp, placefp, plcidfp, name) +VALUES ('48', '00001', '4800001', 'Coppell'); + +INSERT INTO tiger.faces(tfid, statefp, placefp) +VALUES (2001, '48', '00001'); + +INSERT INTO tiger.edges(statefp, countyfp, tlid, tfidl, tfidr, fullname, tnidf, tnidt, the_geom) +VALUES + ('48', '113', 1001, 2001, 2001, 'N Belt Line Rd', 10, 11, + ST_GeomFromText('MULTILINESTRING((-96.990000 32.986000,-96.990000 32.987000))', 4269)), + ('48', '113', 1002, 2001, 2001, 'I- 635', 10, 12, + ST_GeomFromText('MULTILINESTRING((-96.991000 32.986000,-96.989000 32.986000))', 4269)), + ('48', '113', 1003, 2001, 2001, 'Weld Ave', 20, 21, + ST_GeomFromText('MULTILINESTRING((-96.980000 32.980000,-96.980000 32.982000))', 4269)), + ('48', '113', 1004, 2001, 2001, 'School Terrace', 20, 22, + ST_GeomFromText('MULTILINESTRING((-96.981000 32.980000,-96.980000 32.980000))', 4269)), + ('48', '113', 1005, 2001, 2001, 'Schools', 21, 23, + ST_GeomFromText('MULTILINESTRING((-96.981000 32.982000,-96.980000 32.982000))', 4269)); + +INSERT INTO tiger.featnames(statefp, tlid, fullname, name, predirabrv, suftypabrv, pretypabrv) +VALUES + ('48', 1001, 'N Belt Line Rd', 'Belt Line', 'N', 'Rd', NULL), + ('48', 1002, 'I- 635', '635', NULL, NULL, 'I-'), + ('48', 1003, 'Weld Ave', 'Weld', NULL, 'Ave', NULL), + ('48', 1004, 'School Terrace', 'School', NULL, 'Ter', NULL), + ('48', 1005, 'Schools', 'Schools', NULL, NULL, NULL); + +INSERT INTO tiger.addr(statefp, tlid, fromhn, tohn, side, zip) +VALUES + ('48', 1001, '100', '198', 'L', '75019'), + ('48', 1002, '0', '0', 'L', '75019'), + ('48', 1003, '50', '98', 'L', '75019'), + ('48', 1004, '0', '0', 'L', '75019'), + ('48', 1005, '0', '0', 'L', '75019'); + +\o +SELECT '#1461c' AS ticket, streetname, streettypeabbrev +FROM normalize_address('0 353 Rte, Coppell, TX'); + +SELECT '#1461a' AS ticket, pprint_addy(addy), ST_AsText(ST_SnapToGrid(geomout, 0.000001)), rating +FROM geocode_intersection('N. Belt Line', 'I- 635', 'TX', 'Coppell') +ORDER BY rating +LIMIT 1; + +SELECT '#1461b' AS ticket, pprint_addy(addy), ST_AsText(ST_SnapToGrid(geomout, 0.000001)), rating +FROM geocode_intersection('N. Belt Line', 'I-635', 'TX', 'Coppell') +ORDER BY rating +LIMIT 1; + +SELECT '#1461d' AS ticket, pprint_addy(addy), ST_AsText(ST_SnapToGrid(geomout, 0.000001)), rating +FROM geocode_intersection('Weld', 'School', 'TX', 'Coppell') +ORDER BY rating +LIMIT 1; + +\o /dev/null +ROLLBACK; +\o diff --git a/extras/tiger_geocoder/geocode/geocode_intersection.sql b/extras/tiger_geocoder/geocode/geocode_intersection.sql index 3029e23c1..599a1e108 100644 --- a/extras/tiger_geocoder/geocode/geocode_intersection.sql +++ b/extras/tiger_geocoder/geocode/geocode_intersection.sql @@ -23,6 +23,12 @@ $$ DECLARE var_na_road norm_addy; var_na_inter1 norm_addy; + var_road_name text; + var_road_fullname text; + var_inter_name text; + var_inter_fullname text; + var_road_input_normalized text; + var_inter_input_normalized text; var_sql text := ''; var_zip varchar(5)[]; in_statefp varchar(2) ; @@ -36,6 +42,12 @@ BEGIN var_na_road := normalize_address('0 ' || roadway1 || ', ' || COALESCE(in_city,'') || ', ' || in_state || ' ' || in_zip); var_na_inter1 := normalize_address('0 ' || roadway2 || ', ' || COALESCE(in_city,'') || ', ' || in_state || ' ' || in_zip); END IF; + var_road_name := trim(lower(COALESCE(var_na_road.streetName, ''))); + var_road_fullname := trim(lower(var_na_road.streetName || ' ' || COALESCE(var_na_road.streetTypeAbbrev,''))); + var_inter_name := trim(lower(COALESCE(var_na_inter1.streetName, ''))); + var_inter_fullname := trim(lower(var_na_inter1.streetName || ' ' || COALESCE(var_na_inter1.streetTypeAbbrev,''))); + var_road_input_normalized := normalize_street_name(trim(lower(roadway1))); + var_inter_input_normalized := normalize_street_name(trim(lower(roadway2))); in_statefp := statefp FROM state_lookup As s WHERE s.abbrev = upper(in_state); IF COALESCE(in_zip,'') > '' THEN -- limit search to 2 plus or minus the input zip var_zip := zip_range(in_zip, -2,2); @@ -54,42 +66,61 @@ BEGIN END IF; var_sql := ' WITH - a1 AS (SELECT f.*, addr.fromhn, addr.tohn, addr.side , addr.zip - FROM (SELECT * FROM tiger.featnames - WHERE statefp = $1 AND ( lower(name) = $2 ' || - CASE WHEN length(var_na_road.streetName) > 5 THEN ' or lower(fullname) LIKE $6 || ''%'' ' ELSE '' END || ')' - || ') AS f LEFT JOIN (SELECT * FROM tiger.addr As addr WHERE addr.statefp = $1) As addr ON (addr.tlid = f.tlid AND addr.statefp = f.statefp) - WHERE $5::text[] IS NULL OR addr.zip = ANY($5::text[]) OR addr.zip IS NULL - ORDER BY CASE WHEN lower(f.fullname) = $6 THEN 0 ELSE 1 END - LIMIT 50000 - ), + a1 AS (SELECT f.*, addr.fromhn, addr.tohn, addr.side , addr.zip + FROM (SELECT * FROM tiger.featnames + WHERE statefp = $1 AND ( + lower(name) = $2 ' || + CASE WHEN length(var_na_road.streetName) > 5 THEN ' or lower(fullname) LIKE $6 || ''%'' ' ELSE '' END || + ' or normalize_street_name(fullname) = $10)' + || ') AS f LEFT JOIN (SELECT * FROM tiger.addr As addr WHERE addr.statefp = $1) As addr ON (addr.tlid = f.tlid AND addr.statefp = f.statefp) + WHERE $5::text[] IS NULL OR addr.zip = ANY($5::text[]) OR addr.zip IS NULL + ORDER BY CASE + WHEN lower(f.fullname) = $6 OR normalize_street_name(f.fullname) = $10 THEN 0 + ELSE 1 END + LIMIT 50000 + ), a2 AS (SELECT f.*, addr.fromhn, addr.tohn, addr.side , addr.zip - FROM (SELECT * FROM tiger.featnames - WHERE statefp = $1 AND ( lower(name) = $4 ' || - CASE WHEN length(var_na_inter1.streetName) > 5 THEN ' or lower(fullname) LIKE $7 || ''%'' ' ELSE '' END || ')' - || ' ) AS f LEFT JOIN (SELECT * FROM tiger.addr As addr WHERE addr.statefp = $1) AS addr ON (addr.tlid = f.tlid AND addr.statefp = f.statefp) - WHERE $5::text[] IS NULL OR addr.zip = ANY($5::text[]) or addr.zip IS NULL - ORDER BY CASE WHEN lower(f.fullname) = $7 THEN 0 ELSE 1 END - LIMIT 50000 - ), - e1 AS (SELECT e.the_geom, e.tnidf, e.tnidt, a.*, - CASE WHEN a.side = ''L'' THEN e.tfidl ELSE e.tfidr END AS tfid - FROM a1 As a - INNER JOIN tiger.edges AS e ON (e.statefp = a.statefp AND a.tlid = e.tlid) - WHERE e.statefp = $1 - ORDER BY CASE WHEN lower(a.name) = $4 THEN 0 ELSE 1 END + CASE WHEN lower(e.fullname) = $7 THEN 0 ELSE 1 END - LIMIT 5000) , - e2 AS (SELECT e.the_geom, e.tnidf, e.tnidt, a.*, - CASE WHEN a.side = ''L'' THEN e.tfidl ELSE e.tfidr END AS tfid - FROM (SELECT * FROM tiger.edges WHERE statefp = $1) AS e INNER JOIN a2 AS a ON (e.statefp = a.statefp AND a.tlid = e.tlid) - INNER JOIN e1 ON (e.statefp = e1.statefp - AND ARRAY[e.tnidf, e.tnidt] && ARRAY[e1.tnidf, e1.tnidt] ) + FROM (SELECT * FROM tiger.featnames + WHERE statefp = $1 AND ( + lower(name) = $4 ' || + CASE WHEN length(var_na_inter1.streetName) > 5 THEN ' or lower(fullname) LIKE $7 || ''%'' ' ELSE '' END || + ' or normalize_street_name(fullname) = $11)' + || ' ) AS f LEFT JOIN (SELECT * FROM tiger.addr As addr WHERE addr.statefp = $1) AS addr ON (addr.tlid = f.tlid AND addr.statefp = f.statefp) + WHERE $5::text[] IS NULL OR addr.zip = ANY($5::text[]) or addr.zip IS NULL + ORDER BY CASE + WHEN lower(f.fullname) = $7 OR normalize_street_name(f.fullname) = $11 THEN 0 + ELSE 1 END + LIMIT 50000 + ), + e1 AS (SELECT e.the_geom, e.tnidf, e.tnidt, a.*, + CASE WHEN a.side = ''L'' THEN e.tfidl ELSE e.tfidr END AS tfid + FROM a1 As a + INNER JOIN tiger.edges AS e ON (e.statefp = a.statefp AND a.tlid = e.tlid) + WHERE e.statefp = $1 + ORDER BY CASE + WHEN lower(a.name) = $4 THEN 0 ELSE 1 END + + CASE + WHEN lower(e.fullname) = $7 OR normalize_street_name(e.fullname) = $11 THEN 0 + ELSE 1 END + LIMIT 5000) , + e2 AS (SELECT e.the_geom, e.tnidf, e.tnidt, a.*, + CASE WHEN a.side = ''L'' THEN e.tfidl ELSE e.tfidr END AS tfid + FROM (SELECT * FROM tiger.edges WHERE statefp = $1) AS e INNER JOIN a2 AS a ON (e.statefp = a.statefp AND a.tlid = e.tlid) + INNER JOIN e1 ON (e.statefp = e1.statefp + AND ARRAY[e.tnidf, e.tnidt] && ARRAY[e1.tnidf, e1.tnidt] ) - WHERE (lower(e.fullname) = $7 or lower(a.name) LIKE $4 || ''%'') - ORDER BY CASE WHEN lower(a.name) = $4 THEN 0 ELSE 1 END + CASE WHEN lower(e.fullname) = $7 THEN 0 ELSE 1 END - LIMIT 5000 - ), - segs AS (SELECT DISTINCT ON(e1.tlid, e1.side) + WHERE ( + lower(e.fullname) = $7 + OR normalize_street_name(e.fullname) = $11 + OR lower(a.name) LIKE $4 || ''%'') + ORDER BY CASE + WHEN lower(a.name) = $4 THEN 0 ELSE 1 END + + CASE + WHEN lower(e.fullname) = $7 OR normalize_street_name(e.fullname) = $11 THEN 0 + ELSE 1 END + LIMIT 5000 + ), + segs AS (SELECT DISTINCT ON(e1.tlid, e1.side) CASE WHEN e1.tnidf = e2.tnidf OR e1.tnidf = e2.tnidt THEN e1.fromhn ELSE @@ -101,9 +132,15 @@ BEGIN ELSE ST_EndPoint(ST_GeometryN(ST_Multi(e1.the_geom),1)) END AS geom , CASE WHEN lower(p.name) = $3 THEN 0 ELSE 1 END + tiger.levenshtein_ignore_case(p.name, $3) - + tiger.levenshtein_ignore_case(e1.name || COALESCE('' '' || e1.sufqualabr, ''''),$2) + - CASE WHEN e1.fullname = $6 THEN 0 ELSE tiger.levenshtein_ignore_case(e1.fullname, $6) END + - + tiger.levenshtein_ignore_case(e2.name || COALESCE('' '' || e2.sufqualabr, ''''),$4) + + tiger.levenshtein_ignore_case(e1.name || COALESCE('' '' || e1.sufqualabr, ''''),$2) + + CASE + WHEN lower(e1.fullname) = $6 OR normalize_street_name(e1.fullname) = $10 THEN 0 + ELSE tiger.levenshtein_ignore_case(e1.fullname, $6) + END + + CASE + WHEN normalize_street_name(e2.fullname) = $11 THEN 0 + ELSE tiger.levenshtein_ignore_case(e2.name || COALESCE('' '' || e2.sufqualabr, ''''),$4) + END AS a_rating FROM e1 INNER JOIN e2 ON ( @@ -115,23 +152,16 @@ BEGIN FROM segs ORDER BY a_rating LIMIT $9'; IF var_debug THEN - RAISE NOTICE 'sql: %', replace(replace(replace( - replace(replace(replace( - replace( - replace( - replace(var_sql, '$1', quote_nullable(in_statefp)), - '$2', quote_nullable(lower(var_na_road.streetName) ) ), - '$3', quote_nullable(lower(in_city)) ), - '$4', quote_nullable(lower(var_na_inter1.streetName) ) ), - '$5', quote_nullable(var_zip) ), - '$6', quote_nullable(lower(var_na_road.streetName || ' ' || COALESCE(var_na_road.streetTypeAbbrev,'') )) ) , - '$7', quote_nullable(trim(lower(var_na_inter1.streetName || ' ' || COALESCE(var_na_inter1.streetTypeAbbrev,'') )) ) ) , - '$8', quote_nullable(in_state ) ), '$9', num_results::text ); + RAISE NOTICE 'sql: %', var_sql; + RAISE NOTICE 'args: %, %, %, %, %, %, %, %, %, %, %', + in_statefp, var_road_name, lower(in_city), var_inter_name, var_zip, + var_road_fullname, var_inter_fullname, in_state, num_results, + var_road_input_normalized, var_inter_input_normalized; END IF; - FOR results IN EXECUTE var_sql USING in_statefp, trim(lower(var_na_road.streetName)), lower(in_city), lower(var_na_inter1.streetName), var_zip, - trim(lower(var_na_road.streetName || ' ' || COALESCE(var_na_road.streetTypeAbbrev,''))), - trim(lower(var_na_inter1.streetName || ' ' || COALESCE(var_na_inter1.streetTypeAbbrev,''))), in_state, num_results LOOP + FOR results IN EXECUTE var_sql USING in_statefp, var_road_name, lower(in_city), var_inter_name, var_zip, + var_road_fullname, var_inter_fullname, in_state, num_results, + var_road_input_normalized, var_inter_input_normalized LOOP ADDY.preDirAbbrev := results.fedirp; ADDY.streetName := results.fename; ADDY.streetTypeAbbrev := results.fetype; diff --git a/extras/tiger_geocoder/geocode/other_helper_functions.sql b/extras/tiger_geocoder/geocode/other_helper_functions.sql index 41513bc1e..4af024ca5 100644 --- a/extras/tiger_geocoder/geocode/other_helper_functions.sql +++ b/extras/tiger_geocoder/geocode/other_helper_functions.sql @@ -30,6 +30,24 @@ $$ SELECT abs(to_number( CASE WHEN trim(substring($1,1,5)) ~ '^[0-9]+$' THEN $1 LANGUAGE sql IMMUTABLE STRICT COST 200 PARALLEL SAFE; +-- Canonicalize separator-only formatting differences in road names without +-- collapsing all punctuation, so highway names like I-635 and I- 635 +-- compare equally while still distinguishing unrelated names. +CREATE OR REPLACE FUNCTION normalize_street_name(input_street varchar) + RETURNS varchar AS +$$ + SELECT trim( + regexp_replace( + regexp_replace(lower($1), E'\\s*-\\s*', '-', 'g'), + E'\\s+', + ' ', + 'g' + ) + )::varchar; +$$ +LANGUAGE sql IMMUTABLE STRICT +COST 5 PARALLEL SAFE; + -- function return true or false if 2 numeric streets are equal such as 15th St, 23rd st -- it compares just the numeric part of the street for equality -- PURPOSE: handle bad formats such as 23th St so 23th St = 23rd St ----------------------------------------------------------------------- Summary of changes: NEWS | 3 + extensions/postgis_tiger_geocoder/Makefile.in | 10 +- .../test-geocode_intersection_spacing.out.in | 4 + .../test-geocode_intersection_spacing.sql.in | 63 ++++++++++ .../geocode/geocode_intersection.sql | 134 +++++++++++++-------- .../geocode/other_helper_functions.sql | 18 +++ 6 files changed, 178 insertions(+), 54 deletions(-) create mode 100644 extensions/postgis_tiger_geocoder/sql_bits/test-geocode_intersection_spacing.out.in create mode 100644 extensions/postgis_tiger_geocoder/sql_bits/test-geocode_intersection_spacing.sql.in hooks/post-receive -- PostGIS From trac at osgeo.org Mon Mar 9 04:23:57 2026 From: trac at osgeo.org (PostGIS) Date: Mon, 09 Mar 2026 11:23:57 -0000 Subject: [PostGIS] #1461: Tiger Geocoder doesn't anticipate irregular spacing in road name In-Reply-To: <052.169bc5a7154bec2415d1e0203ba66609@osgeo.org> References: <052.169bc5a7154bec2415d1e0203ba66609@osgeo.org> Message-ID: <067.920d1717709f10982f868378de008569@osgeo.org> #1461: Tiger Geocoder doesn't anticipate irregular spacing in road name ----------------------------------+----------------------------- Reporter: arencambre | Owner: robe Type: defect | Status: closed Priority: medium | Milestone: PostGIS Fund Me Component: pagc_address_parser | Version: master Resolution: fixed | Keywords: ----------------------------------+----------------------------- Changes (by Darafei Praliaskouski ): * resolution: => fixed * status: new => closed Comment: In [changeset:"d2a87d6305a558906618f7df087ffdcf8a60d988/git" d2a87d6/git]: {{{#!CommitTicketReference repository="git" revision="d2a87d6305a558906618f7df087ffdcf8a60d988" Fix #1461 geocode_intersection spacing fallback Add a narrow normalized-fullname comparison so geocode_intersection matches TIGER highway names when spacing around hyphens differs, without changing suffix-form route parsing or type-less second-street scoring. Closes #1461 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Mon Mar 9 11:12:27 2026 From: git at osgeo.org (git at osgeo.org) Date: Mon, 9 Mar 2026 11:12:27 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-382-g08054a171 Message-ID: <20260309181227.EFFDF1B1176@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 08054a171b90f96bc4ad4ba89ada81c4709cb141 (commit) from d2a87d6305a558906618f7df087ffdcf8a60d988 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 08054a171b90f96bc4ad4ba89ada81c4709cb141 Author: Sandro Santilli Date: Mon Mar 9 19:12:08 2026 +0100 Have codespell ignore generated sql files under doc/ (comments) diff --git a/.codespellrc b/.codespellrc index b68fd7fbf..2e8dc1b78 100644 --- a/.codespellrc +++ b/.codespellrc @@ -9,6 +9,7 @@ skip = ./doc/html/**, ./doc/po/**, ./doc/postgis-out.xml, + ./doc/*.sql, ./doc/postgis-nospecial.xml, ./postgis/*.sql, ./raster/rt_pg/*.sql, ----------------------------------------------------------------------- Summary of changes: .codespellrc | 1 + 1 file changed, 1 insertion(+) hooks/post-receive -- PostGIS From git at osgeo.org Mon Mar 9 13:27:31 2026 From: git at osgeo.org (git at osgeo.org) Date: Mon, 9 Mar 2026 13:27:31 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-383-gbd6ef65e8 Message-ID: <20260309202732.2D8481B17D6@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via bd6ef65e8d418d17064225b182347478ebe84b11 (commit) from 08054a171b90f96bc4ad4ba89ada81c4709cb141 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bd6ef65e8d418d17064225b182347478ebe84b11 Author: Darafei Praliaskouski Date: Tue Mar 10 00:25:07 2026 +0400 #2459 Improve tiger geocoder wrapper normalization Speed up pagc_normalize_address with a single standardize_address() call while preserving ZIP+4, country, and ZIP-only fallbacks. Convert several expression-only tiger wrappers to SQL where install order allows, preserve extension schema qualifications, and refresh the related docs and regression coverage. Closes #2459 diff --git a/NEWS b/NEWS index c6d77cc77..6d6847db0 100644 --- a/NEWS +++ b/NEWS @@ -41,9 +41,16 @@ This version requires GEOS 3.10 or higher - #4828, geometry_columns handles NOT VALID SRID checks without errors (Darafei Praliaskouski) - #6048, [raster] ST_Clip no longer crashes when clipping sparse band selections (Darafei Praliaskouski) + - #2459, [tiger geocoder] Speed up pagc_normalize_address by avoiding + redundant wrapper parsing while preserving ZIP+4 and country + details from the structured parser (Darafei Praliaskouski) + - [tiger geocoder] Replace several expression-only PL/pgSQL wrappers with + SQL functions in helper and text geocode entry points while + preserving extension schema qualifications + (Darafei Praliaskouski) - #1461, [tiger geocoder] geocode_intersection now tolerates irregular spacing in highway names such as `I- 635` vs `I-635` - (OpenAI) + (Darafei Praliaskouski) - #1599, [address_standardizer] parse_address() and normalize_address() now canonicalize trailing country tokens to ISO 3166-1 alpha-2 codes and expose country on normalized addresses diff --git a/doc/extras_tigergeocoder.xml b/doc/extras_tigergeocoder.xml index 2889f6286..ec4906a2e 100644 --- a/doc/extras_tigergeocoder.xml +++ b/doc/extras_tigergeocoder.xml @@ -1104,9 +1104,7 @@ FROM pagc_normalize_address('9000 E ROO ST STE 999, Springfield, CO') AS addy; ---------+--------------+------------+------------------+---------------+-----------+-------------+-------------+-----+-------- 9000 | E | ROO | ST | | SUITE 999 | SPRINGFIELD | CO | | t - Batch call. There are currently speed issues with the way postgis_tiger_geocoder wraps the address_standardizer. These will hopefully -be resolved in later editions. To work around them, if you need speed for batch geocoding to call generate a normaddy in batch mode, you are encouraged -to directly call the address_standardizer standardize_address function as shown below which is similar exercise to what we did in that uses data created in . + Batch call. pagc_normalize_address now follows the same single-address standardizer path internally, but for large set-based geocoding jobs you may still prefer to call standardize_address directly when materializing norm_addy rows in SQL, as shown below. This is similar to the exercise in that uses data created in . WITH g AS (SELECT address, ROW((sa).house_num, (sa).predir, (sa).name , (sa).suftype, (sa).sufdir, (sa).unit , (sa).city, (sa).state, (sa).postcode, true)::norm_addy As na diff --git a/extensions/address_standardizer/address_standardizer.c b/extensions/address_standardizer/address_standardizer.c index 5adb43666..7eee099b0 100644 --- a/extensions/address_standardizer/address_standardizer.c +++ b/extensions/address_standardizer/address_standardizer.c @@ -1,3 +1,7 @@ +/* + * Copyright (c) 2026 Darafei Praliaskouski + */ + #include "postgres.h" #include "fmgr.h" #include "funcapi.h" @@ -496,6 +500,22 @@ parse_address_wrapper_input(const char *function_name, const char *raw_address, return parsed_address; } +/* + * Preserve ZIP+4 details from structured parses so callers can reuse the + * standardized postcode without reparsing the original address text. + */ +static char * +build_postcode_component(const ADDRESS *parsed_address) +{ + if (!parsed_address || !parsed_address->zip || parsed_address->zip[0] == '\0') + return NULL; + + if (parsed_address->zipplus && parsed_address->zipplus[0] != '\0') + return psprintf("%s-%s", parsed_address->zip, parsed_address->zipplus); + + return pstrdup(parsed_address->zip); +} + /* * The explicit SQL macro argument models city/state/postcode text, not a full * address. parseaddress() mostly gives us that split already, but when a city @@ -523,6 +543,10 @@ parse_macro_input(const char *function_name, const char *raw_macro) return parsed_macro; } +/* + * Diagnostic entry point that returns tokenization, rule matching, and the + * final standardized address for either split or one-line input. + */ PG_FUNCTION_INFO_V1(debug_standardize_address); Datum @@ -751,6 +775,7 @@ standardize_address(PG_FUNCTION_ARGS) char **values; HeapTuple tuple; ADDRESS *parsed_macro = NULL; + char *postcode = NULL; DBG("Start standardize_address"); @@ -777,9 +802,10 @@ standardize_address(PG_FUNCTION_ARGS) if (parsed_macro) { + postcode = build_postcode_component(parsed_macro); DBG("calling std_standardize('%s', ... parsed macro)", micro); stdaddr = std_standardize( - std, micro, parsed_macro->city, parsed_macro->st, parsed_macro->zip, parsed_macro->cc, 0); + std, micro, parsed_macro->city, parsed_macro->st, postcode, parsed_macro->cc, 0); } else { @@ -806,6 +832,10 @@ standardize_address(PG_FUNCTION_ARGS) PG_RETURN_DATUM(result); } +/* + * One-line standardization entry point. Parse the raw address first so the + * structured postcode and country can be preserved during normalization. + */ PG_FUNCTION_INFO_V1(standardize_address1); Datum @@ -824,6 +854,7 @@ standardize_address1(PG_FUNCTION_ARGS) char **values; HeapTuple tuple; ADDRESS *parsed_address; + char *postcode; DBG("Start standardize_address"); @@ -840,6 +871,7 @@ standardize_address1(PG_FUNCTION_ARGS) attinmeta = TupleDescGetAttInMetadata(tuple_desc); parsed_address = parse_address_wrapper_input(__func__, addr, µ, NULL); + postcode = build_postcode_component(parsed_address); DBG("calling GetStdUsingFCInfo(fcinfo, '%s', '%s', '%s')", lextab, gaztab, rultab); std = GetStdUsingFCInfo(fcinfo, lextab, gaztab, rultab); @@ -848,7 +880,7 @@ standardize_address1(PG_FUNCTION_ARGS) DBG("calling std_standardize('%s', ...)", micro); stdaddr = std_standardize( - std, micro, parsed_address->city, parsed_address->st, parsed_address->zip, parsed_address->cc, 0); + std, micro, parsed_address->city, parsed_address->st, postcode, parsed_address->cc, 0); DBG("back from fetch_stdaddr"); diff --git a/extensions/address_standardizer/expected/test-standardize_address_1.out b/extensions/address_standardizer/expected/test-standardize_address_1.out index ff6dbd83d..849732c2e 100644 --- a/extensions/address_standardizer/expected/test-standardize_address_1.out +++ b/extensions/address_standardizer/expected/test-standardize_address_1.out @@ -58,6 +58,18 @@ SELECT '#5695a' AS ticket, * FROM standardize_address('us_lex', 'us_gaz', 'us_ru #5695a | | 1 | EAST | | | PIMA | STREET | | | | TUCSON | ARIZONA | US | | | SUITE 999 (1 row) +SELECT '#2459a' AS ticket, * FROM standardize_address('us_lex', 'us_gaz', 'us_rules', '26 Court Street, Boston, Massachusetts 02109, France'); + ticket | building | house_num | predir | qual | pretype | name | suftype | sufdir | ruralroute | extra | city | state | country | postcode | box | unit +--------+----------+-----------+--------+------+---------+-------+---------+--------+------------+-------+--------+---------------+---------+----------+-----+------ + #2459a | | 26 | | | | COURT | STREET | | | | BOSTON | MASSACHUSETTS | FR | 02109 | | +(1 row) + +SELECT '#2459b' AS ticket, * FROM standardize_address('us_lex', 'us_gaz', 'us_rules', '212 3rd Ave N, MINNEAPOLIS, MN 553404'); + ticket | building | house_num | predir | qual | pretype | name | suftype | sufdir | ruralroute | extra | city | state | country | postcode | box | unit +--------+----------+-----------+--------+------+---------+------+---------+--------+------------+-------+-------------+-----------+---------+----------+-----+------ + #2459b | | 212 | | | | 3 | AVENUE | NORTH | | | MINNEAPOLIS | MINNESOTA | US | 55340-4 | | +(1 row) + DO $$ BEGIN PERFORM standardize_address('us_lex', 'us_gaz', 'us_rules', ' '); diff --git a/extensions/address_standardizer/standard.c b/extensions/address_standardizer/standard.c index fbd35a319..f88e8af31 100644 --- a/extensions/address_standardizer/standard.c +++ b/extensions/address_standardizer/standard.c @@ -7,6 +7,7 @@ Prototype 7H08 (This file was written by Walter Sinclair). This file is part of PAGC. Copyright (c) 2009 Walter Bruce Sinclair +Copyright (c) 2026 Darafei Praliaskouski Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: @@ -452,31 +453,53 @@ STDADDR *std_standardize_one(STANDARDIZER *std, char *address_one_line, int opti } */ +/* Replace one STDADDR field with a caller-supplied structured component. */ +static void +replace_stdaddr_component(char **field, const char *value) +{ + if (!field) + return; + + if (*field) + { + free(*field); + *field = NULL; + } + + if (value && value[0] != '\0') + *field = strdup(value); +} + /* * The string-based analyzer can collapse a supplied state into the city slot - * when there is no city component. When the caller provides structured macro - * components, preserve that split in the final STDADDR. + * when there is no city component. When callers provide structured city/state/ + * postcode/country pieces, restore those values onto the final STDADDR. */ static void -apply_component_split_to_stdaddr(STDADDR *stdaddr, const char *city, const char *state) +apply_component_values_to_stdaddr( + STDADDR *stdaddr, const char *city, const char *state, const char *postcode, const char *country) { if (!stdaddr) return; - if ((city && city[0] != '\0') || !state || state[0] == '\0') - return; - - if (stdaddr->state && stdaddr->state[0] != '\0') - return; - - if (stdaddr->city && stdaddr->city[0] != '\0') + if ((!city || city[0] == '\0') && state && state[0] != '\0' && (!stdaddr->state || stdaddr->state[0] == '\0')) { - stdaddr->state = stdaddr->city; - stdaddr->city = NULL; - return; + if (stdaddr->city && stdaddr->city[0] != '\0') + { + stdaddr->state = stdaddr->city; + stdaddr->city = NULL; + } + else + { + stdaddr->state = strdup(state); + } } - stdaddr->state = strdup(state); + if (postcode && postcode[0] != '\0') + replace_stdaddr_component(&stdaddr->postcode, postcode); + + if (country && country[0] != '\0') + replace_stdaddr_component(&stdaddr->country, country); } /* @@ -617,7 +640,7 @@ std_standardize(STANDARDIZER *std, if (macro) free(macro); - apply_component_split_to_stdaddr(stdaddr, city, state); + apply_component_values_to_stdaddr(stdaddr, city, state, postcode, country); return stdaddr; } diff --git a/extensions/address_standardizer/test-standardize_address_1.sql.in b/extensions/address_standardizer/test-standardize_address_1.sql.in index b67017e57..7084c9384 100644 --- a/extensions/address_standardizer/test-standardize_address_1.sql.in +++ b/extensions/address_standardizer/test-standardize_address_1.sql.in @@ -8,6 +8,8 @@ SELECT '#state_only_macro' AS ticket, * FROM standardize_address('us_lex','us_ga SELECT '#5299a' AS ticket, * FROM standardize_address('us_lex', 'us_gaz', 'us_rules','1 Timepiece Point','Boston, MA, 02220'); SELECT '#5299b' AS ticket, * FROM standardize_address('us_lex', 'us_gaz', 'us_rules','50 Gold Piece Drive','Boston, MA, 02020'); SELECT '#5695a' AS ticket, * FROM standardize_address('us_lex', 'us_gaz', 'us_rules', 'ONE E PIMA ST STE 999, TUCSON, AZ'); +SELECT '#2459a' AS ticket, * FROM standardize_address('us_lex', 'us_gaz', 'us_rules', '26 Court Street, Boston, Massachusetts 02109, France'); +SELECT '#2459b' AS ticket, * FROM standardize_address('us_lex', 'us_gaz', 'us_rules', '212 3rd Ave N, MINNEAPOLIS, MN 553404'); DO $$ BEGIN PERFORM standardize_address('us_lex', 'us_gaz', 'us_rules', ' '); diff --git a/extensions/postgis_tiger_geocoder/Makefile.in b/extensions/postgis_tiger_geocoder/Makefile.in index c103b3069..a4335489a 100644 --- a/extensions/postgis_tiger_geocoder/Makefile.in +++ b/extensions/postgis_tiger_geocoder/Makefile.in @@ -126,11 +126,11 @@ sql/$(EXTENSION)--$(EXTVERSION)next--$(EXTVERSION).sql: sql/$(EXTENSION)--$(EXTV sql/tiger_geocoder_minor.sql.in: ../../extras/tiger_geocoder/utility/set_search_path.sql \ sql_bits/upgrade_before.sql.in \ ../../extras/tiger_geocoder/geocode_settings.sql \ - ../../extras/tiger_geocoder/tiger_loader_2025.sql \ + ../../extras/tiger_geocoder/tiger_loader_2025.sql \ ../../extras/tiger_geocoder/utility/utmzone.sql \ ../../extras/tiger_geocoder/utility/cull_null.sql \ - ../../extras/tiger_geocoder/utility/nullable_levenshtein.sql \ ../../extras/tiger_geocoder/utility/levenshtein_ignore_case.sql \ + ../../extras/tiger_geocoder/utility/nullable_levenshtein.sql \ ../../extras/tiger_geocoder/normalize/end_soundex.sql \ ../../extras/tiger_geocoder/normalize/count_words.sql \ ../../extras/tiger_geocoder/normalize/state_extract.sql \ @@ -166,8 +166,8 @@ sql/tiger_geocoder.sql.in: sql_bits/norm_addy_create.sql.in \ ../../extras/tiger_geocoder/utility/set_search_path.sql \ ../../extras/tiger_geocoder/utility/utmzone.sql \ ../../extras/tiger_geocoder/utility/cull_null.sql \ - ../../extras/tiger_geocoder/utility/nullable_levenshtein.sql \ ../../extras/tiger_geocoder/utility/levenshtein_ignore_case.sql \ + ../../extras/tiger_geocoder/utility/nullable_levenshtein.sql \ ../../extras/tiger_geocoder/normalize/end_soundex.sql \ ../../extras/tiger_geocoder/normalize/count_words.sql \ ../../extras/tiger_geocoder/normalize/state_extract.sql \ diff --git a/extras/tiger_geocoder/create_geocode.sql b/extras/tiger_geocoder/create_geocode.sql index daaa98f33..9f48e8766 100644 --- a/extras/tiger_geocoder/create_geocode.sql +++ b/extras/tiger_geocoder/create_geocode.sql @@ -39,8 +39,8 @@ CREATE TYPE norm_addy AS ( -- System/General helper functions \i utility/utmzone.sql \i utility/cull_null.sql -\i utility/nullable_levenshtein.sql \i utility/levenshtein_ignore_case.sql +\i utility/nullable_levenshtein.sql ---- Address normalizer -- General helpers diff --git a/extras/tiger_geocoder/geocode/geocode.sql b/extras/tiger_geocoder/geocode/geocode.sql index 34df34fd7..b1c547fe8 100644 --- a/extras/tiger_geocoder/geocode/geocode.sql +++ b/extras/tiger_geocoder/geocode/geocode.sql @@ -1,42 +1,5 @@ -CREATE OR REPLACE FUNCTION geocode( - input VARCHAR, max_results integer DEFAULT 10, - restrict_geom geometry DEFAULT NULL, - OUT ADDY NORM_ADDY, - OUT GEOMOUT GEOMETRY, - OUT RATING INTEGER -) RETURNS SETOF RECORD -AS $_$ -DECLARE - rec RECORD; -BEGIN - - IF input IS NULL THEN - RETURN; - END IF; - - -- Pass the input string into the address normalizer - ADDY := normalize_address(input); - IF NOT ADDY.parsed THEN - RETURN; - END IF; - -/* FOR rec IN SELECT * FROM geocode(ADDY) - LOOP - - ADDY := rec.addy; - GEOMOUT := rec.geomout; - RATING := rec.rating; - - RETURN NEXT; - END LOOP;*/ - - RETURN QUERY SELECT g.addy, g.geomout, g.rating FROM geocode(ADDY, max_results, restrict_geom) As g ORDER BY g.rating; - -END; -$_$ LANGUAGE plpgsql COST 1000 -STABLE PARALLEL SAFE -ROWS 1; - +-- Geocode an already parsed address, preferring precise address matches and +-- falling back to broader location matches when needed. CREATE OR REPLACE FUNCTION geocode( IN_ADDY NORM_ADDY, max_results integer DEFAULT 10, @@ -131,3 +94,30 @@ $_$ LANGUAGE plpgsql COST 1000 STABLE PARALLEL SAFE ROWS 1; + +-- Normalize free-form input once, then only delegate to the structured +-- geocoder overload when parsing succeeds. +CREATE OR REPLACE FUNCTION geocode( + input VARCHAR, max_results integer DEFAULT 10, + restrict_geom geometry DEFAULT NULL, + OUT ADDY NORM_ADDY, + OUT GEOMOUT GEOMETRY, + OUT RATING INTEGER +) RETURNS SETOF RECORD +AS $$ + WITH normalized AS ( + SELECT @extschema at .normalize_address(input) AS addy + WHERE input IS NOT NULL + ), + parsed AS ( + SELECT addy + FROM normalized + WHERE (addy).parsed + ) + SELECT g.addy, g.geomout, g.rating + FROM parsed + CROSS JOIN LATERAL @extschema at .geocode(addy, max_results, restrict_geom) AS g + ORDER BY g.rating; +$$ LANGUAGE sql COST 1000 +STABLE PARALLEL SAFE +ROWS 1; diff --git a/extras/tiger_geocoder/geocode/rate_attributes.sql b/extras/tiger_geocoder/geocode/rate_attributes.sql index 1949dcbde..1e19be911 100644 --- a/extras/tiger_geocoder/geocode/rate_attributes.sql +++ b/extras/tiger_geocoder/geocode/rate_attributes.sql @@ -1,31 +1,3 @@ --- rate_attributes(dirpA, dirpB, streetNameA, streetNameB, streetTypeA, --- streetTypeB, dirsA, dirsB, locationA, locationB) --- Rates the street based on the given attributes. The locations must be --- non-null. The other eight values are handled by the other rate_attributes --- function, so it's requirements must also be met. --- changed: 2010-10-18 Regina Obe - all references to verbose to var_verbose since causes compile errors in 9.0 --- changed: 2011-06-25 revise to use real named args and fix direction rating typo -CREATE OR REPLACE FUNCTION rate_attributes(dirpA VARCHAR, dirpB VARCHAR, streetNameA VARCHAR, streetNameB VARCHAR, - streetTypeA VARCHAR, streetTypeB VARCHAR, dirsA VARCHAR, dirsB VARCHAR, locationA VARCHAR, locationB VARCHAR, prequalabr VARCHAR) RETURNS INTEGER -AS $_$ -DECLARE - result INTEGER := 0; - locationWeight INTEGER := 14; - var_verbose BOOLEAN := FALSE; -BEGIN - IF locationA IS NOT NULL AND locationB IS NOT NULL THEN - result := tiger.levenshtein_ignore_case(locationA, locationB); - ELSE - IF var_verbose THEN - RAISE NOTICE 'rate_attributes() - Location names cannot be null!'; - END IF; - RETURN NULL; - END IF; - result := result + rate_attributes($1, $2, streetNameA, streetNameB, $5, $6, $7, $8,prequalabr); - RETURN result; -END; -$_$ LANGUAGE plpgsql IMMUTABLE; - -- rate_attributes(dirpA, dirpB, streetNameA, streetNameB, streetTypeA, -- streetTypeB, dirsA, dirsB) -- Rates the street based on the given attributes. Only streetNames are @@ -76,3 +48,20 @@ BEGIN return result; END; $_$ LANGUAGE plpgsql IMMUTABLE; + +-- rate_attributes(dirpA, dirpB, streetNameA, streetNameB, streetTypeA, +-- streetTypeB, dirsA, dirsB, locationA, locationB) +-- Rates the street based on the given attributes. The locations must be +-- non-null. The other eight values are handled by the other rate_attributes +-- function, so it's requirements must also be met. +-- changed: 2010-10-18 Regina Obe - all references to verbose to var_verbose since causes compile errors in 9.0 +-- changed: 2011-06-25 revise to use real named args and fix direction rating typo +CREATE OR REPLACE FUNCTION rate_attributes(dirpA VARCHAR, dirpB VARCHAR, streetNameA VARCHAR, streetNameB VARCHAR, + streetTypeA VARCHAR, streetTypeB VARCHAR, dirsA VARCHAR, dirsB VARCHAR, locationA VARCHAR, locationB VARCHAR, prequalabr VARCHAR) RETURNS INTEGER +AS $$ + SELECT CASE + WHEN locationA IS NULL OR locationB IS NULL THEN NULL + ELSE @extschema at .levenshtein_ignore_case(locationA, locationB) + + @extschema at .rate_attributes($1, $2, streetNameA, streetNameB, $5, $6, $7, $8, prequalabr) + END; +$$ LANGUAGE sql IMMUTABLE; diff --git a/extras/tiger_geocoder/normalize/end_soundex.sql b/extras/tiger_geocoder/normalize/end_soundex.sql index 36a8bda56..be9e71c6a 100644 --- a/extras/tiger_geocoder/normalize/end_soundex.sql +++ b/extras/tiger_geocoder/normalize/end_soundex.sql @@ -2,16 +2,8 @@ -- Words are allowed to be separated by space, comma, period, new-line -- tab or form feed. CREATE OR REPLACE FUNCTION end_soundex(VARCHAR) RETURNS VARCHAR -AS $_$ -DECLARE - tempString VARCHAR; -BEGIN - tempString := substring($1, E'[ ,.\n\t\f]([a-zA-Z0-9]*)$'); - IF tempString IS NOT NULL THEN - tempString := @extschema:fuzzystrmatch at .soundex(tempString); - ELSE - tempString := @extschema:fuzzystrmatch at .soundex($1); - END IF; - return tempString; -END; -$_$ LANGUAGE plpgsql IMMUTABLE; +AS $$ + SELECT @extschema:fuzzystrmatch at .soundex( + COALESCE(substring($1, E'[ ,.\n\t\f]([a-zA-Z0-9]*)$'), $1) + ); +$$ LANGUAGE sql IMMUTABLE; diff --git a/extras/tiger_geocoder/normalize/location_extract_place_exact.sql b/extras/tiger_geocoder/normalize/location_extract_place_exact.sql index 1ab610164..373e1e8de 100644 --- a/extras/tiger_geocoder/normalize/location_extract_place_exact.sql +++ b/extras/tiger_geocoder/normalize/location_extract_place_exact.sql @@ -7,54 +7,14 @@ CREATE OR REPLACE FUNCTION location_extract_place_exact( fullStreet VARCHAR, stateAbbrev VARCHAR ) RETURNS VARCHAR -AS $_$ -DECLARE - ws VARCHAR; - location VARCHAR; - tempInt INTEGER; - lstate VARCHAR; - rec RECORD; -BEGIN - ws := E'[ ,.\n\f\t]'; - - -- Try for an exact match against places - IF stateAbbrev IS NOT NULL THEN - lstate := statefp FROM state WHERE stusps = stateAbbrev; - SELECT INTO tempInt count(*) FROM place - WHERE place.statefp = lstate AND fullStreet ILIKE '%' || name || '%' - AND texticregexeq(fullStreet, '(?i)' || name || '$'); - ELSE - SELECT INTO tempInt count(*) FROM place - WHERE fullStreet ILIKE '%' || name || '%' AND - texticregexeq(fullStreet, '(?i)' || name || '$'); - END IF; - - IF tempInt > 0 THEN - -- Some matches were found. Look for the last one in the string. - IF stateAbbrev IS NOT NULL THEN - FOR rec IN SELECT substring(fullStreet, '(?i)(' - || name || ')$') AS value, name FROM place - WHERE place.statefp = lstate AND fullStreet ILIKE '%' || name || '%' - AND texticregexeq(fullStreet, '(?i)' - || name || '$') ORDER BY length(name) DESC LOOP - -- Since the regex is end of string, only the longest (first) result - -- is useful. - location := rec.value; - EXIT; - END LOOP; - ELSE - FOR rec IN SELECT substring(fullStreet, '(?i)(' - || name || ')$') AS value, name FROM place - WHERE fullStreet ILIKE '%' || name || '%' AND texticregexeq(fullStreet, '(?i)' - || name || '$') ORDER BY length(name) DESC LOOP - -- Since the regex is end of string, only the longest (first) result - -- is useful. - location := rec.value; - EXIT; - END LOOP; - END IF; - END IF; - - RETURN location; -END; -$_$ LANGUAGE plpgsql STABLE COST 100; +AS $$ + SELECT ( + SELECT substring(fullStreet, '(?i)(' || name || ')$') + FROM place + WHERE (stateAbbrev IS NULL OR place.statefp = (SELECT statefp FROM state WHERE stusps = stateAbbrev)) + AND fullStreet ILIKE '%' || name || '%' + AND texticregexeq(fullStreet, '(?i)' || name || '$') + ORDER BY length(name) DESC + LIMIT 1 + ); +$$ LANGUAGE sql STABLE COST 100; diff --git a/extras/tiger_geocoder/pagc_normalize/pagc_normalize_address.sql b/extras/tiger_geocoder/pagc_normalize/pagc_normalize_address.sql index befce7643..15d0734fd 100644 --- a/extras/tiger_geocoder/pagc_normalize/pagc_normalize_address.sql +++ b/extras/tiger_geocoder/pagc_normalize/pagc_normalize_address.sql @@ -4,51 +4,51 @@ -- zip code, depending on what can be found in the string. -- This is a drop in replacement for packaged normalize_address -- that uses the pagc address standardizer C library instead +-- Keep the wrapper in plpgsql so the optional address_standardizer extension +-- is only resolved when PAGC parsing is invoked, while still using a single +-- standardize_address() call to preserve the wrapper speedup work. -- USAGE: SELECT * FROM tiger.pagc_normalize_address('One Devonshire Place, PH 301, Boston, MA 02109'); SELECT tiger.SetSearchPathForInstall('tiger'); CREATE OR REPLACE FUNCTION pagc_normalize_address(in_rawinput character varying) RETURNS norm_addy AS $$ DECLARE - result norm_addy; - var_rec RECORD; - var_parse_rec RECORD; - rawInput VARCHAR; - + sa RECORD; + parsed RECORD; + raw_input VARCHAR; BEGIN - result.parsed := FALSE; + raw_input := trim(in_rawinput); - rawInput := trim(in_rawinput); - var_parse_rec := parse_address(rawInput); + -- Preserve parse_address()'s macro-only ZIP and country detection for + -- non-street inputs while keeping a single standardize_address() call. + SELECT * + INTO parsed + FROM parse_address(raw_input); - result.location := var_parse_rec.city; - result.stateAbbrev := trim(var_parse_rec.state); - result.zip := var_parse_rec.zip; - result.zip4 := NULLIF(var_parse_rec.zipplus,''); - result.country := NULLIF(var_parse_rec.country,''); + SELECT * + INTO sa + FROM standardize_address( + 'pagc_lex', + 'pagc_gaz', + 'pagc_rules', + raw_input + ) AS sa; - var_rec := standardize_address('pagc_lex' - , 'pagc_gaz' - , 'pagc_rules' -, COALESCE(var_parse_rec.address1,''), - COALESCE(var_parse_rec.city,'') || COALESCE(', ' || var_parse_rec.state, '') || COALESCE(' ' || var_parse_rec.zip,'') ) ; - - -- For address number only put numbers and stop if reach a non-number e.g. 123-456 will return 123 - result.address := to_number(substring(var_rec.house_num, '[0-9]+'), '99999999'); - result.address_alphanumeric := var_rec.house_num; - --get rid of extraneous spaces before we return - result.zip := COALESCE(var_rec.postcode,result.zip); - result.streetName := trim(var_rec.name); - result.location := trim(var_rec.city); - result.stateAbbrev := trim(var_rec.state); - result.country := COALESCE(NULLIF(var_rec.country,''), result.country); - --this should be broken out separately like pagc, but normalizer doesn't have a slot for it - result.streettypeAbbrev := trim(COALESCE(var_rec.suftype, var_rec.pretype)); - result.preDirAbbrev := trim(var_rec.predir); - result.postDirAbbrev := trim(var_rec.sufdir); - result.internal := trim(regexp_replace(replace(var_rec.unit, '#',''), '([0-9]+)\s+([A-Za-z]){0,1}', E'\\1\\2')); - result.parsed := TRUE; - RETURN result; + RETURN ROW( + to_number(substring(sa.house_num, '[0-9]+'), '99999999'), + NULLIF(trim(sa.predir), ''), + NULLIF(trim(sa.name), ''), + NULLIF(trim(COALESCE(sa.suftype, sa.pretype)), ''), + NULLIF(trim(sa.sufdir), ''), + NULLIF(trim(regexp_replace(replace(COALESCE(sa.unit, ''), '#', ''), '([0-9]+)\s+([A-Za-z]){0,1}', E'\\1\\2')), ''), + COALESCE(NULLIF(trim(sa.city), ''), NULLIF(trim(parsed.city), '')), + COALESCE(NULLIF(trim(sa.state), ''), NULLIF(trim(parsed.state), '')), + COALESCE(NULLIF(split_part(COALESCE(sa.postcode, ''), '-', 1), ''), NULLIF(parsed.zip, '')), + TRUE, + COALESCE(NULLIF(split_part(COALESCE(sa.postcode, ''), '-', 2), ''), NULLIF(parsed.zipplus, '')), + NULLIF(sa.house_num, ''), + COALESCE(NULLIF(trim(sa.country), ''), NULLIF(trim(parsed.country), ''), 'US') + )::norm_addy; END $$ LANGUAGE plpgsql IMMUTABLE STRICT diff --git a/extras/tiger_geocoder/regress/normalize_address_regress b/extras/tiger_geocoder/regress/normalize_address_regress index 676bb7698..4814836f0 100644 --- a/extras/tiger_geocoder/regress/normalize_address_regress +++ b/extras/tiger_geocoder/regress/normalize_address_regress @@ -49,3 +49,12 @@ #1614a|8435 Co Rd 20 SE, ROCHESTER, MN 55904, US|8435||20|Co Rd|SE||ROCHESTER|MN|55904|t||8435|US #1614b|3208 US Hwy 52, Rochester, MN 55901, US|3208||52|US Hwy|||Rochester|MN|55901|t||3208|US #1108a|529 Main St, Suite 201, Boston, MA 02129, US|529||Main|St||Suite 201|Boston|MA|02129|t||529|US +#sqlify1|S363|S363| +#sqlify2||3|3|1 +#sqlify3|0| +#sqlify4| +#sqlify5|0 +#sqlify6|t +#sqlify7|t +#sqlify8|t|t +#sqlify9|t|t diff --git a/extras/tiger_geocoder/regress/normalize_address_regress.sql b/extras/tiger_geocoder/regress/normalize_address_regress.sql index 46749542e..1f99fcba2 100644 --- a/extras/tiger_geocoder/regress/normalize_address_regress.sql +++ b/extras/tiger_geocoder/regress/normalize_address_regress.sql @@ -102,4 +102,39 @@ SELECT '#1614b' As ticket, pprint_addy(addy), addy.* FROM normalize_address('320 --internal address prefix sometimes get caught in post dir SELECT '#1108a' As ticket, pprint_addy(addy), addy.* FROM normalize_address('529 Main Street, Suite 201, Boston, MA 02129') AS addy; + +-- direct helper coverage for SQL wrappers +SELECT '#sqlify1' As ticket, end_soundex('123 Main Street'), end_soundex('Street'), end_soundex(NULL::varchar); +SELECT '#sqlify2' As ticket, nullable_levenshtein(NULL::varchar, 'foo'), nullable_levenshtein('foo', NULL::varchar), nullable_levenshtein('foo', ''), nullable_levenshtein('foo', 'food'); +SELECT '#sqlify3' As ticket, rate_attributes('N','N','MAIN','MAIN','ST','ST',NULL,NULL,'BOSTON','BOSTON',NULL), rate_attributes('N','N','MAIN','MAIN','ST','ST',NULL,NULL,NULL,'BOSTON',NULL); +SELECT '#sqlify4' As ticket, location_extract_place_exact('999 Main Street, Boston', 'MA'); +SELECT '#sqlify5' As ticket, count(*) FROM geocode(NULL::varchar, 1) AS g; +SELECT '#sqlify6' As ticket, strpos( + pg_get_functiondef(to_regprocedure((SELECT n.nspname || '.nullable_levenshtein(character varying,character varying)' FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace WHERE e.extname = 'postgis_tiger_geocoder'))), + (SELECT n.nspname || '.levenshtein_ignore_case' FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace WHERE e.extname = 'postgis_tiger_geocoder') +) > 0; +SELECT '#sqlify7' As ticket, CASE + WHEN current_setting('server_version_num')::integer >= 160000 THEN strpos( + pg_get_functiondef(to_regprocedure((SELECT n.nspname || '.end_soundex(character varying)' FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace WHERE e.extname = 'postgis_tiger_geocoder'))), + (SELECT n.nspname || '.soundex' FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace WHERE e.extname = 'fuzzystrmatch') + ) > 0 + ELSE strpos( + pg_get_functiondef(to_regprocedure((SELECT n.nspname || '.end_soundex(character varying)' FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace WHERE e.extname = 'postgis_tiger_geocoder'))), + 'soundex(' + ) > 0 +END; +SELECT '#sqlify8' As ticket, strpos( + pg_get_functiondef(to_regprocedure((SELECT n.nspname || '.geocode(character varying,integer,geometry)' FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace WHERE e.extname = 'postgis_tiger_geocoder'))), + (SELECT n.nspname || '.normalize_address' FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace WHERE e.extname = 'postgis_tiger_geocoder') +) > 0, strpos( + pg_get_functiondef(to_regprocedure((SELECT n.nspname || '.geocode(character varying,integer,geometry)' FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace WHERE e.extname = 'postgis_tiger_geocoder'))), + (SELECT n.nspname || '.geocode(addy, max_results, restrict_geom)' FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace WHERE e.extname = 'postgis_tiger_geocoder') +) > 0; +SELECT '#sqlify9' As ticket, strpos( + pg_get_functiondef(to_regprocedure((SELECT n.nspname || '.rate_attributes(character varying,character varying,character varying,character varying,character varying,character varying,character varying,character varying,character varying,character varying,character varying)' FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace WHERE e.extname = 'postgis_tiger_geocoder'))), + (SELECT n.nspname || '.levenshtein_ignore_case' FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace WHERE e.extname = 'postgis_tiger_geocoder') +) > 0, strpos( + pg_get_functiondef(to_regprocedure((SELECT n.nspname || '.rate_attributes(character varying,character varying,character varying,character varying,character varying,character varying,character varying,character varying,character varying,character varying,character varying)' FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace WHERE e.extname = 'postgis_tiger_geocoder'))), + (SELECT n.nspname || '.rate_attributes(' FROM pg_extension e JOIN pg_namespace n ON n.oid = e.extnamespace WHERE e.extname = 'postgis_tiger_geocoder') +) > 0; --\timing diff --git a/extras/tiger_geocoder/regress/pagc_normalize_address_regress b/extras/tiger_geocoder/regress/pagc_normalize_address_regress index 9ea5fefd6..507db6bfe 100644 --- a/extras/tiger_geocoder/regress/pagc_normalize_address_regress +++ b/extras/tiger_geocoder/regress/pagc_normalize_address_regress @@ -42,9 +42,9 @@ true #1125a|19596 CO RD 480, COLCORD, OK 74338, US #1125b|4345 353 RTE, SALAMANCA, NY 14779, US|4345||353|RTE|||SALAMANCA|NY|14779|t||4345|US #1125c|19799 STATE RTE 0, COSBY, MO 64436, US|19799||0|STATE RTE|||COSBY|MO|64436|t||19799|US -#1125d|||||||||||t|||US -#1125e|||||||||||t|||US -#1125f|||||||||||t|||US +#1125d|Boston, MA, US|||||||Boston|MA||t|||US +#1125e|Boston, MA, US|||||||Boston|MA||t|||US +#1125f|Boston, MA, US|||||||Boston|MA||t|||US #1310a|1110 W CAPITOL AVE, WEST SACRAMENTO, CA, US|1110|W|CAPITOL|AVE|||WEST SACRAMENTO|CA||t||1110|US #1614a|8435 CO RD 20 SE, ROCHESTER, MN 55904, US|8435||20|CO RD|SE||ROCHESTER|MN|55904|t||8435|US #1614b|3208 US RTE 52, ROCHESTER, MN 55901, US|3208||52|US RTE|||ROCHESTER|MN|55901|t||3208|US @@ -55,4 +55,8 @@ true #2978a|10||DORRANCE|ST|||PROVIDENCE|RI||t||10 20|US #2978b|10||DORRANCE|ST|||PROVIDENCE|RI||t||10 20|US #2978c|10||DORRANCE|ST|||PROVIDENCE|RI||t||10 20|US +#2459|1000|S|FREMONT|AVE|||ALHAMBRA|CA|91803|t||1000|US +#2459zipa|||||||||02109|t|||US +#2459zipb|||||||||02109|t|1234||US +#2459zipc|||||||Minneapolis|MN|55401|t|||US false diff --git a/extras/tiger_geocoder/regress/pagc_normalize_address_regress.sql b/extras/tiger_geocoder/regress/pagc_normalize_address_regress.sql index 783732fce..cf2a11b07 100644 --- a/extras/tiger_geocoder/regress/pagc_normalize_address_regress.sql +++ b/extras/tiger_geocoder/regress/pagc_normalize_address_regress.sql @@ -112,6 +112,10 @@ SELECT '#2981' As ticket, * FROM normalize_address('1566 NEW STATE HWY, RAYNHAM, SELECT '#2978a' As ticket, * FROM normalize_address('10-20 DORRANCE ST PROVIDENCE RI' ) ; SELECT '#2978b' As ticket, * FROM normalize_address('10 20 DORRANCE ST PROVIDENCE RI' ) ; SELECT '#2978c' As ticket, * FROM normalize_address('10-20 DORRANCE ST, PROVIDENCE. RI' ) ; +SELECT '#2459' As ticket, * FROM normalize_address(E'1000 S. Fremont Ave.,\nBldg. A-11,\nAlhambra, CA 91803'); +SELECT '#2459zipa' As ticket, * FROM normalize_address('02109'); +SELECT '#2459zipb' As ticket, * FROM normalize_address('02109-1234'); +SELECT '#2459zipc' As ticket, * FROM normalize_address('Minneapolis, MN 55401'); --\timing SELECT set_geocode_setting('use_pagc_address_parser', 'false'); diff --git a/extras/tiger_geocoder/upgrade_geocode.sql b/extras/tiger_geocoder/upgrade_geocode.sql index c98decd9f..775f18a1b 100644 --- a/extras/tiger_geocoder/upgrade_geocode.sql +++ b/extras/tiger_geocoder/upgrade_geocode.sql @@ -286,8 +286,8 @@ SELECT create_census_base_tables(); -- System/General helper functions \i utility/utmzone.sql \i utility/cull_null.sql -\i utility/nullable_levenshtein.sql \i utility/levenshtein_ignore_case.sql +\i utility/nullable_levenshtein.sql ---- Address normalizer -- General helpers diff --git a/extras/tiger_geocoder/utility/nullable_levenshtein.sql b/extras/tiger_geocoder/utility/nullable_levenshtein.sql index e0ee3beca..bbeff98b1 100644 --- a/extras/tiger_geocoder/utility/nullable_levenshtein.sql +++ b/extras/tiger_geocoder/utility/nullable_levenshtein.sql @@ -4,25 +4,10 @@ -- 3, otherwise it is the levenshtein difference between the two. -- Change 2010-10-18 Regina Obe - name verbose to var_verbose since get compile error in PostgreSQL 9.0 CREATE OR REPLACE FUNCTION nullable_levenshtein(VARCHAR, VARCHAR) RETURNS INTEGER -AS $_$ -DECLARE - given_string VARCHAR; - result INTEGER := 3; - var_verbose BOOLEAN := FALSE; /**change from verbose to param_verbose since its a keyword and get compile error in 9.0 **/ -BEGIN - IF $1 IS NULL THEN - IF var_verbose THEN - RAISE NOTICE 'nullable_levenshtein - given string is NULL!'; - END IF; - RETURN NULL; - ELSE - given_string := $1; - END IF; - - IF $2 IS NOT NULL AND $2 != '' THEN - result := @extschema:fuzzystrmatch at .levenshtein_ignore_case_ignore_case(given_string, $2); - END IF; - - RETURN result; -END -$_$ LANGUAGE plpgsql IMMUTABLE COST 10; +AS $$ + SELECT CASE + WHEN $1 IS NULL THEN NULL + WHEN $2 IS NOT NULL AND $2 != '' THEN @extschema at .levenshtein_ignore_case($1, $2) + ELSE 3 + END; +$$ LANGUAGE sql IMMUTABLE COST 10; ----------------------------------------------------------------------- Summary of changes: NEWS | 9 ++- doc/extras_tigergeocoder.xml | 4 +- .../address_standardizer/address_standardizer.c | 36 ++++++++++- .../expected/test-standardize_address_1.out | 12 ++++ extensions/address_standardizer/standard.c | 53 +++++++++++----- .../test-standardize_address_1.sql.in | 2 + extensions/postgis_tiger_geocoder/Makefile.in | 6 +- extras/tiger_geocoder/create_geocode.sql | 2 +- extras/tiger_geocoder/geocode/geocode.sql | 68 +++++++++------------ extras/tiger_geocoder/geocode/rate_attributes.sql | 45 ++++++-------- extras/tiger_geocoder/normalize/end_soundex.sql | 18 ++---- .../normalize/location_extract_place_exact.sql | 62 ++++--------------- .../pagc_normalize/pagc_normalize_address.sql | 70 +++++++++++----------- .../regress/normalize_address_regress | 9 +++ .../regress/normalize_address_regress.sql | 35 +++++++++++ .../regress/pagc_normalize_address_regress | 10 +++- .../regress/pagc_normalize_address_regress.sql | 4 ++ extras/tiger_geocoder/upgrade_geocode.sql | 2 +- .../utility/nullable_levenshtein.sql | 29 +++------ 19 files changed, 259 insertions(+), 217 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Mon Mar 9 13:27:34 2026 From: trac at osgeo.org (PostGIS) Date: Mon, 09 Mar 2026 20:27:34 -0000 Subject: [PostGIS] #2459: Speed up pagc_normalize_address In-Reply-To: <046.11c0ea620d0afb94afcd80a194f17e79@osgeo.org> References: <046.11c0ea620d0afb94afcd80a194f17e79@osgeo.org> Message-ID: <061.a84653fce734409e49c20aa327e16d8c@osgeo.org> #2459: Speed up pagc_normalize_address ----------------------------------+----------------------------- Reporter: robe | Owner: robe Type: enhancement | Status: closed Priority: medium | Milestone: PostGIS Fund Me Component: pagc_address_parser | Version: master Resolution: fixed | Keywords: ----------------------------------+----------------------------- Changes (by Darafei Praliaskouski ): * resolution: => fixed * status: new => closed Comment: In [changeset:"bd6ef65e8d418d17064225b182347478ebe84b11/git" bd6ef65/git]: {{{#!CommitTicketReference repository="git" revision="bd6ef65e8d418d17064225b182347478ebe84b11" #2459 Improve tiger geocoder wrapper normalization Speed up pagc_normalize_address with a single standardize_address() call while preserving ZIP+4, country, and ZIP-only fallbacks. Convert several expression-only tiger wrappers to SQL where install order allows, preserve extension schema qualifications, and refresh the related docs and regression coverage. Closes #2459 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Tue Mar 10 15:59:28 2026 From: git at osgeo.org (git at osgeo.org) Date: Tue, 10 Mar 2026 15:59:28 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-384-gda7611d73 Message-ID: <20260310225928.6DB2E1B75A3@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via da7611d733bd175a55ca9ce02298650bcb1f8123 (commit) from bd6ef65e8d418d17064225b182347478ebe84b11 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit da7611d733bd175a55ca9ce02298650bcb1f8123 Author: Darafei Praliaskouski Date: Wed Mar 11 02:56:50 2026 +0400 Optimize PostGIS module self-calls under LTO Detect -fno-semantic-interposition when the compiler supports it and pass it into PostgreSQL extension module builds so LTO can replace same-DSO PLT calls with direct internal calls. Add a NEWS note with the local pgbench ST_Collect benchmark result. diff --git a/NEWS b/NEWS index 6d6847db0..bf6108365 100644 --- a/NEWS +++ b/NEWS @@ -32,6 +32,12 @@ This version requires GEOS 3.10 or higher * Bug Fixes * + - Build PostgreSQL extension modules with `-fno-semantic-interposition` when + available so LTO can optimize same-DSO calls to exported PostGIS + entry points directly instead of routing through the module PLT; in + a local PostgreSQL 18 `pgbench` microbenchmark over 100k four-point + groups this reduced `ST_Collect` aggregate latency by about 4% + (Darafei Praliaskouski) - #5973, Install PostGIS utilities under `pg_config --bindir` by default and document `pg_config`-derived install paths more accurately (Darafei Praliaskouski) diff --git a/configure.ac b/configure.ac index ce0e97a11..9fad2de51 100644 --- a/configure.ac +++ b/configure.ac @@ -81,6 +81,15 @@ dnl PICFLAGS="$lt_prog_compiler_pic" AC_SUBST([PICFLAGS]) +dnl +dnl PostgreSQL extension modules can call exported PostGIS entry points across +dnl translation units. Disable semantic interposition when supported so the +dnl compiler can optimize those same-DSO calls directly. +dnl +MODULE_CFLAGS="" +_LT_COMPILER_OPTION([if $compiler supports -fno-semantic-interposition], [_cv_nosemanticinterposition], [-fno-semantic-interposition], [], [MODULE_CFLAGS="$MODULE_CFLAGS -fno-semantic-interposition"], []) +AC_SUBST([MODULE_CFLAGS]) + _LT_COMPILER_OPTION([if $compiler supports -fno-math-errno], [_cv_nomatherrno], [-fno-math-errno], [], [CFLAGS="$CFLAGS -fno-math-errno"], []) _LT_COMPILER_OPTION([if $compiler supports -fno-signed-zeros], [_cv_nosignedzeros], [-fno-signed-zeros], [], [CFLAGS="$CFLAGS -fno-signed-zeros"], []) _LT_COMPILER_OPTION([if $compiler supports -std=gnu11], [_cv_std], -std=gnu11, [], [CFLAGS="-std=gnu11 $CFLAGS"], []) diff --git a/extensions/address_standardizer/Makefile.in b/extensions/address_standardizer/Makefile.in index f4929b010..78158c87b 100644 --- a/extensions/address_standardizer/Makefile.in +++ b/extensions/address_standardizer/Makefile.in @@ -53,7 +53,7 @@ sql/$(EXTENSION)_data_us--$(EXTVERSION)next--$(EXTVERSION).sql sql/$(EXTENSION)_ sql/test-init-extensions.sql sql/test-parseaddress.sql sql/test-standardize_address_1.sql sql/test-standardize_address_2.sql sql/test-debug_standardize_address.sql DOCS = README.address_standardizer -PG_CPPFLAGS = @CFLAGS@ @CPPFLAGS@ -DPCRE_VERSION=@PCRE_VERSION@ +PG_CPPFLAGS = @CFLAGS@ @MODULE_CFLAGS@ @CPPFLAGS@ -DPCRE_VERSION=@PCRE_VERSION@ SHLIB_LINK = @SHLIB_LINK@ @PCRE_LDFLAGS@ EXTRA_CLEAN = sql/ usps-st-city-name.txt mk-st-regexp mk-city-regex test_main diff --git a/postgis/Makefile.in b/postgis/Makefile.in index 03955ba39..e433d51f6 100644 --- a/postgis/Makefile.in +++ b/postgis/Makefile.in @@ -145,7 +145,7 @@ OBJS=$(PG_OBJS) # to an existing liblwgeom.so in the PostgreSQL $libdir supplied by an # older version of PostGIS, rather than with the static liblwgeom.a # supplied with newer versions of PostGIS -PG_CPPFLAGS += -I at top_srcdir@/liblwgeom -I at top_builddir@/liblwgeom @CFLAGS@ -I at top_srcdir@/libpgcommon $(FLATGEOBUF_INCLUDE) $(WAYGU_INCLUDE) $(UTHASH_INCLUDE) @CPPFLAGS@ @PICFLAGS@ +PG_CPPFLAGS += -I at top_srcdir@/liblwgeom -I at top_builddir@/liblwgeom @CFLAGS@ @MODULE_CFLAGS@ -I at top_srcdir@/libpgcommon $(FLATGEOBUF_INCLUDE) $(WAYGU_INCLUDE) $(UTHASH_INCLUDE) @CPPFLAGS@ @PICFLAGS@ SHLIB_LINK_F = $(WAYGU_LIB) $(FLATGEOBUF_LIB) ../libpgcommon/libpgcommon.a ../liblwgeom/.libs/liblwgeom.a @SHLIB_LINK@ # Extra files to remove during 'make clean' diff --git a/raster/rt_pg/Makefile.in b/raster/rt_pg/Makefile.in index 7b0627fe9..4cac36116 100644 --- a/raster/rt_pg/Makefile.in +++ b/raster/rt_pg/Makefile.in @@ -79,6 +79,7 @@ PG_CPPFLAGS += \ $(LIBLWGEOM_CFLAGS) \ @CPPFLAGS@ \ @CFLAGS@ \ + @MODULE_CFLAGS@ \ $(LIBGDAL_CFLAGS) \ $(LIBPGCOMMON_CFLAGS) \ $(LIBPROJ_CFLAGS) \ diff --git a/sfcgal/Makefile.in b/sfcgal/Makefile.in index 61ebe0842..98bec98ad 100644 --- a/sfcgal/Makefile.in +++ b/sfcgal/Makefile.in @@ -55,7 +55,7 @@ OBJS = lwgeom_sfcgal.o postgis_sfcgal_legacy.o # to an existing liblwgeom.so in the PostgreSQL $libdir supplied by an # older version of PostGIS, rather than with the static liblwgeom.a # supplied with newer versions of PostGIS -PG_CPPFLAGS += -I at top_builddir@/liblwgeom -I at top_srcdir@/liblwgeom -I at top_srcdir@/libpgcommon @CFLAGS@ @CPPFLAGS@ @PICFLAGS@ +PG_CPPFLAGS += -I at top_builddir@/liblwgeom -I at top_srcdir@/liblwgeom -I at top_srcdir@/libpgcommon @CFLAGS@ @MODULE_CFLAGS@ @CPPFLAGS@ @PICFLAGS@ SHLIB_LINK_F = @top_builddir@/libpgcommon/libpgcommon.a @top_builddir@/liblwgeom/.libs/liblwgeom.a @SHLIB_LINK@ # Add SFCGAL Flags if defined diff --git a/topology/Makefile.in b/topology/Makefile.in index 608f5e76a..24f155599 100644 --- a/topology/Makefile.in +++ b/topology/Makefile.in @@ -52,7 +52,7 @@ OBJS = postgis_topology.o # to an existing liblwgeom.so in the PostgreSQL $libdir supplied by an # older version of PostGIS, rather than with the static liblwgeom.a # supplied with newer versions of PostGIS -PG_CPPFLAGS += -I at top_builddir@/liblwgeom -I at top_srcdir@/liblwgeom -I at top_srcdir@/libpgcommon @CFLAGS@ @CPPFLAGS@ @PICFLAGS@ +PG_CPPFLAGS += -I at top_builddir@/liblwgeom -I at top_srcdir@/liblwgeom -I at top_srcdir@/libpgcommon @CFLAGS@ @MODULE_CFLAGS@ @CPPFLAGS@ @PICFLAGS@ SHLIB_LINK_F = @top_builddir@/libpgcommon/libpgcommon.a @top_builddir@/liblwgeom/.libs/liblwgeom.a @SHLIB_LINK@ # Add SFCGAL Flags if defined ----------------------------------------------------------------------- Summary of changes: NEWS | 6 ++++++ configure.ac | 9 +++++++++ extensions/address_standardizer/Makefile.in | 2 +- postgis/Makefile.in | 2 +- raster/rt_pg/Makefile.in | 1 + sfcgal/Makefile.in | 2 +- topology/Makefile.in | 2 +- 7 files changed, 20 insertions(+), 4 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Wed Mar 11 04:30:36 2026 From: trac at osgeo.org (PostGIS) Date: Wed, 11 Mar 2026 11:30:36 -0000 Subject: [PostGIS] #5928: ST_Collect creates invalid result with only valid input In-Reply-To: <050.84e3da0ea6a49235b6bfb1faab70c23d@osgeo.org> References: <050.84e3da0ea6a49235b6bfb1faab70c23d@osgeo.org> Message-ID: <065.2510b3c36ad02de4866f5ffcf8e6a554@osgeo.org> #5928: ST_Collect creates invalid result with only valid input --------------------------------+--------------------------- Reporter: Lars Aksel Opsahl | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.0 Component: postgis | Version: 3.5.x Resolution: worksforme | Keywords: --------------------------------+--------------------------- Comment (by Lars Aksel Opsahl): Here we another case that reports invalid {{{ POSTGIS="3.7.0dev 3.6.0rc2-305-g3b3488ddf" [EXTENSION] PGSQL="160" GEOS="3.12.1-CAPI-1.18.1" PROJ="8.2.1 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj DATABASE_PATH=/usr/share/proj/proj.db" (compiled against PROJ 8.2.1) LIBXML="2.9.13" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 (Internal)" TOPOLOGY PostgreSQL 16.13 (Ubuntu 16.13-1.pgdg22.04+1) on x86_64-pc-linux-gnu, compiled by gcc POSTGIS="3.7.0dev 3.6.0rc2-305-g3b3488ddf" [EXTENSION] PGSQL="160" GEOS="3.14.0beta3-CAPI-1.20.2" PROJ="9.3.0 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj DATABASE_PATH=/usr/local/share/proj/proj.db" (compiled against PROJ 9.3.0) LIBXML="2.9.13" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 PostgreSQL 16.4 (Ubuntu 16.4-1.pgdg22.04+1) on x86_64-pc-linux-gnu, compiled by gcc POSTGIS="3.4.2 c19ce56" [EXTENSION] PGSQL="160" GEOS="3.12.1-CAPI-1.18.1" (compiled against GEOS 3.10.2) SFCGAL="SFCGAL 1.4.1, CGAL 5.3.1, BOOST 1.74.0" PROJ="8.2.1 NETWORK_ENABLED=OFF URL_ENDPOINT=https://cdn.proj.org USER_WRITABLE_DIRECTORY=/tmp/proj DATABASE_PATH=/usr/share/proj/proj.db" GDAL="GDAL 3.4.1, released 2021/12/27" LIBXML="2.9.13" LIBJSON="0.15" LIBPROTOBUF="1.3.3" WAGYU="0.5.0 (Internal)" TOPOLOGY RASTER PostgreSQL 16.3 (Ubuntu 16.3-1.pgdg22.04+1) on x86_64-pc-linux-gnu, compiled by gcc }}} with this SQL {{{ SELECT st_isvalid('MULTIPOLYGON(((12.73351507 66.6119868,12.72915463 66.61146327,12.72920119 66.60972247,12.72945039 66.60975288,12.73086236 66.60987212,12.73225836 66.60991913,12.73311671 66.61016498,12.73362813 66.61025306,12.73434255 66.61034415,12.73575726 66.61043645,12.7386931 66.61068521,12.73988777 66.61071138,12.74061663 66.61089232,12.74076635 66.61098432,12.74086396 66.61107749,12.73850885 66.61179694,12.73501412 66.61224321,12.73351507 66.6119868)),((12.72464326 66.6047916,12.72509264 66.60481597,12.72582554 66.60495225,12.72602674 66.60508232,12.72603872 66.60509007,12.7267101 66.60515356,12.72723185 66.60537653,12.72751001 66.60554212,12.72772402 66.60567088,12.72772215 66.60594021,12.72750993 66.60603578,12.72660539 66.60604961,12.7256939 66.6058928,12.72486593 66.60583665,12.72434737 66.60580148,12.72412926 66.60571753,12.72406373 66.60544731,12.72423639 66.60528825,12.72485844 66.60515366,12.72446238 66.60504021,12.72440707 66.60490477,12.72464326 66.6047916)),((12.72785797 66.60865523,12.72763914 66.6085689,12.72730494 66.60851909,12.72522934 66.6084981,12.72489657 66.60843035,12.72482116 66.6082677,12.72545361 66.60777422,12.72573269 66.60768851,12.72640825 66.60770736,12.72721032 66.60782659,12.72845445 66.60805104,12.72886242 66.60817634,12.73007995 66.60855026,12.73013634 66.60867683,12.73098171 66.60881471,12.73148102 66.60903725,12.73154189 66.60911003,12.73164482 66.60921922,12.73188105 66.60959953,12.73180518 66.60968828,12.73114001 66.60955292,12.73062205 66.60953654,12.73041331 66.60959627,12.72956277 66.60951225,12.72923266 66.60941763,12.72906475 66.60928066,12.72921382 66.60913014,12.72950374 66.60917032,12.72956074 66.60928774,12.7297871 66.60928213,12.72984042 66.60919314,12.72968418 66.60917293,12.72921628 66.60910324,12.72877257 66.60901604,12.72785797 66.60865523)),((12.73199805 66.60681972,12.73168389 66.6072327,12.73166897 66.60722696,12.73076767 66.60720496,12.73020794 66.60715199,12.72968801 66.60691102,12.72935792 66.60681648,12.72930011 66.60670794,12.73042939 66.60670632,12.73065902 66.60666476,12.73065123 66.60650308,12.73054584 66.60642087,12.72987666 66.60633032,12.72970714 66.60621119,12.72891063 66.60602913,12.72845286 66.60585196,12.72846291 66.60549317,12.72879506 66.60531837,12.72966186 66.6052232,12.73056228 66.60525417,12.7312749 66.60536321,12.73173701 66.60549555,12.73196047 66.60576814,12.73234428 66.60601602,12.73273465 66.6061922,12.73263215 66.60632527,12.73184734 66.6065114,12.73188898 66.60679922,12.73199805 66.60681972)),((12.73501412 66.61224321,12.73850885 66.61179694,12.74086396 66.61107749,12.7411196 66.6113215,12.74189603 66.61147628,12.74201596 66.61136007,12.74542231 66.61212045,12.74544837 66.61215563,12.74595556 66.61228857,12.74651463 66.61235045,12.74668694 66.61244268,12.74657412 66.61269238,12.74577594 66.61302199,12.74594826 66.61311422,12.74674897 66.61325138,12.74680661 66.61361132,12.74646416 66.61365119,12.74651717 66.61381352,12.74729591 66.61419269,12.74719752 66.61428112,12.74696949 66.61430469,12.74638863 66.61423353,12.74465746 66.61414584,12.74347271 66.61425448,12.74323027 66.61418816,12.74362602 66.61405922,12.74329987 66.61391989,12.7430759 66.61389872,12.74278479 66.61411893,12.74267985 66.61427907,12.74149695 66.61436968,12.73962089 66.61462991,12.73697154 66.61469946,12.73691847 66.61478845,12.73628819 66.61476141,12.73532734 66.61464883,12.73471494 66.61467589,12.73414006 66.61478437,12.73307809 66.614787,12.73229014 66.61475758,12.73069452 66.61491404,12.72969859 66.61493555,12.72935116 66.61502926,12.72901275 66.61502436,12.7287929 66.61495835,12.72827566 66.61493292,12.7277744 66.61497961,12.72755314 66.61493144,12.72743563 66.61473227,12.72720555 66.61453148,12.72715694 66.613337,12.72676485 66.61317874,12.72676635 66.61291847,12.72643597 66.61282393,12.72637662 66.61223964,12.72576027 66.61181783,12.72537679 66.61181228,12.72509342 66.61170046,12.72492742 66.61129415,12.72480995 66.61035897,12.72464185 66.61022181,12.72458651 66.61008646,12.72476333 66.60988249,12.72477142 66.6095506,12.72521703 66.60936847,12.72579405 66.60923331,12.72658184 66.60926258,12.72747089 66.60941907,12.7281996 66.60960024,12.72920119 66.60972247,12.72915463 66.61146327,12.73351507 66.6119868,12.73501412 66.61224321)),((13.22577765 66.67543727,13.22606296 66.67535461,13.22609082 66.67537664,13.22613021 66.67540185,13.22616388 66.67542485,13.22620612 66.67545458,13.2262548 66.67546401,13.22630894 66.67546991,13.22636625 66.67547594,13.22643214 66.6754853,13.22649212 66.67549818,13.22654908 66.6755121,13.22659456 66.67552823,13.22661366 66.67555232,13.22663361 66.67556143,13.22668009 66.67554472,13.22671799 66.67552774,13.22676428 66.67552,13.22677771 66.67554744,13.22675682 66.67557349,13.22671833 66.6756051,13.22669153 66.67563459,13.22667872 66.67567438,13.22667814 66.67569824,13.2266939 66.67574041,13.22671861 66.6757747,13.22672951 66.67579636,13.22671135 66.67582236,13.22667899 66.6758473,13.22664915 66.67588134,13.22663645 66.67591646,13.22663562 66.67594382,13.22666567 66.67598562,13.22661911 66.67600035,13.22620044 66.67583671,13.2262 66.67583652,13.22637713 66.67578494,13.22577765 66.67543727)),((13.23020803 66.67515154,13.23022813 66.67512377,13.23031378 66.67500583,13.23020168 66.67479745,13.22996078 66.67483881,13.22985477 66.6749628,13.22985056 66.67496796,13.22977083 66.67493359,13.22966834 66.67488523,13.2296721 66.6748833,13.22984137 66.67479906,13.22980719 66.67470409,13.22968287 66.67463171,13.22958072 66.67463872,13.22950541 66.67464389,13.2295044 66.67464208,13.22949659 66.67462154,13.2294889 66.67459309,13.22945828 66.67456224,13.22941906 66.67453128,13.22940857 66.67450389,13.22939536 66.67446398,13.22938759 66.6744333,13.2293654 66.6744081,13.22933493 66.67437841,13.22929591 66.67433831,13.2292637 66.67430761,13.22929812 66.67429481,13.22930103 66.67425733,13.2296393 66.67413039,13.23003912 66.67420937,13.23038481 66.67429501,13.23084593 66.67478603,13.23203652 66.67493546,13.23391416 66.67437307,13.23396182 66.67435871,13.23396914 66.67435771,13.23400744 66.67433176,13.23402528 66.67431024,13.2340714 66.67430475,13.23412305 66.67431071,13.23417109 66.67432911,13.23422775 66.67435675,13.2342754 66.67439336,13.2343034 66.6744197,13.23430819 66.67444138,13.23427824 66.67448672,13.23425149 66.6745093,13.23422782 66.6745365,13.23420435 66.67455122,13.23415713 66.67458165,13.23412504 66.67459978,13.23406398 66.67462099,13.23406073 66.674638,13.23408277 66.67466544,13.23411036 66.67469752,13.23413533 66.67472831,13.23416899 66.67475471,13.23420015 66.67476852,13.23424852 66.67478243,13.23430537 66.67480425,13.23433929 66.67482383,13.2343326 66.67484772,13.23430045 66.67486683,13.23425398 66.67488022,13.23419014 66.67489924,13.23412924 66.67491498,13.23403421 66.67492693,13.23398297 66.67491531,13.23391144 66.6749024,13.23386256 66.67490212,13.23381669 66.6749008,13.23375675 66.67489366,13.23370171 66.67490363,13.23363856 66.67490328,13.23359847 66.67489404,13.23354166 66.6748812,13.23348153 66.67486724,13.23340729 66.67485429,13.23330105 66.6748583,13.23327168 66.67487637,13.23326237 66.67489574,13.23324966 66.67493427,13.2332206 66.67495127,13.23318545 66.67496469,13.23311346 66.67496774,13.23305916 66.67496408,13.23303274 66.67498209,13.23299774 66.67499668,13.23299128 66.67502057,13.23297882 66.67505238,13.23296361 66.67507509,13.23295984 66.67510574,13.23298457 66.67513662,13.2330177 66.67517997,13.2329681 66.67519916,13.23293861 66.67522853,13.23293797 66.67525015,13.23293969 66.6752831,13.23295836 66.67533222,13.23296052 66.6753527,13.23294252 66.67537646,13.23289215 66.67541601,13.23283974 66.67543974,13.23281363 66.67545659,13.23276934 66.67548714,13.23271425 66.67550393,13.23265925 66.67551955,13.2325588 66.67551223,13.2325212 66.67551881,13.2325036 66.67553692,13.23247674 66.67556749,13.23244459 66.67558328,13.23238994 66.6755876,13.23233238 66.67558839,13.23228651 66.67558707,13.23226027 66.67559942,13.23225628 66.67562675,13.2322095 66.67565718,13.23215781 66.67565813,13.23210622 66.67565782,13.23203944 66.6756734,13.23199048 66.67567429,13.23195847 66.67569125,13.23190907 66.6757046,13.23184598 66.67570658,13.23178946 66.6756801,13.23176144 66.67565718,13.23173319 66.67563433,13.23167085 66.67561012,13.23160527 66.67559951,13.23157987 66.6755811,13.23155779 66.67556057,13.23152397 66.6755365,13.23150884 66.67555805,13.2314397 66.67556562,13.23138848 66.67555059,13.23132882 66.67553323,13.23127208 66.67550343,13.23121845 66.67547465,13.23116775 66.6754459,13.23108538 66.67541366,13.23103118 66.67540542,13.23095408 66.67539136,13.23088273 66.67537279,13.23078887 66.67534616,13.23068658 66.67531378,13.23058979 66.67528703,13.2304646 66.67524883,13.23041062 66.67522812,13.23032789 66.67520727,13.23029127 66.67518433,13.23024897 66.67516474,13.23020803 66.67515154)),((13.22309161 66.67505241,13.22511523 66.67615246,13.2262 66.67583652,13.22620044 66.67583671,13.22661911 66.67600035,13.22666567 66.67598562,13.22668504 66.67601231,13.22672084 66.67606252,13.22674818 66.676098,13.2268047 66.67613696,13.22686643 66.67617597,13.22691139 66.67620573,13.22695667 66.67623101,13.22703334 66.67625754,13.22705563 66.67627816,13.22706926 66.67629653,13.22709422 66.67632732,13.22711943 66.67635139,13.22717673 66.67636074,13.22723371 66.67637125,13.22726159 66.67638969,13.22728099 66.67641593,13.22732628 66.67644121,13.22738081 66.67644488,13.22743554 66.67643939,13.22748192 66.67642726,13.22754302 66.67640246,13.22760922 66.67639486,13.22766886 66.67641564,13.22775115 66.67644896,13.22782719 66.67649378,13.22787212 66.67652704,13.22790589 66.67654878,13.22794841 66.67656838,13.22800521 66.67658454,13.22805357 66.67659846,13.22808767 66.67661239,13.22811291 66.67663295,13.22812901 66.67667056,13.22814558 66.67668887,13.22812723 66.67672061,13.2280409 66.67672475,13.22798645 66.67671992,13.22793164 66.67672639,13.22791952 66.67675031,13.22791285 66.67677069,13.2279178 66.67680269,13.22791996 66.67682309,13.22795086 66.67684372,13.22801936 66.67685777,13.22806791 66.67686594,13.22814768 66.67689026,13.22817859 66.67690748,13.22822978 66.67692933,13.2282951 66.67694675,13.22837785 66.67696429,13.22842323 66.67698499,13.22844865 66.6769999,13.22848519 66.677024,13.22852461 66.67704581,13.22858129 66.67707004,13.22865818 66.67709657,13.22872939 66.67711398,13.22878635 66.67712799,13.2288003 66.67714511,13.22881407 66.67716456,13.22884161 66.67719421,13.22889827 66.67722186,13.22894376 66.67723798,13.22897164 66.67725975,13.22899932 66.67729057,13.22902381 66.67733742,13.22904314 66.67736474,13.22905953 66.67738879,13.22909276 66.67742425,13.22911757 66.67745728,13.22916852 66.67747922,13.22921461 66.67748063,13.22922104 66.677451,13.22923077 66.67742266,13.22929965 66.67742191,13.22933646 66.67743911,13.22936188 66.67745411,13.22938984 66.67747471,13.22944387 66.67750116,13.22949217 66.67751274,13.2295577 66.67753358,13.22959966 66.67756115,13.22962212 66.67757944,13.22966157 66.67761039,13.22970636 66.67764249,13.22975737 66.67765751,13.22979746 66.67766675,13.22982862 66.67768056,13.22985386 66.67770122,13.22987887 66.67772519,13.22991289 66.6777402,13.23001004 66.67775888,13.2300627 66.67781718,13.23009319 66.67784363,13.22706787 66.67874052,13.22702484 66.67875322,13.22700455 66.6787425,13.22695629 66.67872401,13.2268798 66.67869174,13.22679724 66.67866523,13.22673736 66.67864777,13.22667761 66.67863158,13.22664639 66.67861543,13.22660723 66.67858681,13.22657671 66.67855138,13.22655486 66.67851829,13.226527 66.67849312,13.22648464 66.67847129,13.22643363 66.6784437,13.22637726 66.67841839,13.22632649 66.67838739,13.22628712 66.67835868,13.22623945 66.67832557,13.2262177 66.6782879,13.22620153 66.67825138,13.22617146 66.67820339,13.22613514 66.67816681,13.22609031 66.67814154,13.22602772 66.67812074,13.22595105 66.67809421,13.22588587 66.67806538,13.22583231 66.67803553,13.2257932 66.678,13.22577412 66.67796927,13.22576064 66.67793619,13.22574417 66.6779133,13.22570484 66.67789033,13.22564793 66.67786618,13.22557404 66.67784192,13.22548588 66.67782101,13.22540619 66.67779552,13.22534403 66.67776565,13.22529007 66.67774144,13.2252393 66.67771054,13.22519991 66.67768524,13.22516344 66.67766338,13.22510677 66.67763582,13.22503307 66.67760582,13.22493925 66.67757237,13.22483434 66.67753547,13.22473772 66.67750306,13.22462949 66.67746837,13.22457662 66.67744785,13.22455106 66.67740655,13.22312366 66.67510419,13.22309161 66.67505241)),((13.22489005 66.67378623,13.22435241 66.67356174,13.22297643 66.67341044,13.22247757 66.67401376,13.22256566 66.67419289,13.22244167 66.67399353,13.22121075 66.67201759,13.22096229 66.67172672,13.22468265 66.67217543,13.22724258 66.67246803,13.22695369 66.67338405,13.22613165 66.67339067,13.2257825 66.67324638,13.22546299 66.67340206,13.22567275 66.67356757,13.22628639 66.67362259,13.22655299 66.67376576,13.22723131 66.67356297,13.2272889 66.67359961,13.22728711 66.67359941,13.22717202 66.67363849,13.22709713 66.6736599,13.22701887 66.67368101,13.22694121 66.67370319,13.22687156 66.67372108,13.2267888 66.673745,13.22668548 66.67377462,13.22660735 66.67380021,13.22652309 66.67382923,13.22643595 66.67385723,13.22637838 66.67387722,13.22627906 66.67390787,13.22617426 66.67393909,13.22609788 66.67396865,13.22624118 66.67387415,13.2257688 66.67376545,13.22549691 66.67393262,13.22537784 66.67414377,13.22578962 66.67422308,13.22595816 66.67406067,13.22594648 66.67408145,13.22592065 66.67411328,13.2258961 66.67414944,13.22587371 66.67418382,13.22585783 66.67422214,13.22584436 66.67424891,13.2258066 66.67428294,13.22576626 66.67431829,13.22572935 66.67434668,13.22565375 66.67437491,13.22553395 66.67440703,13.22562304 66.674459,13.22575278 66.67442403,13.22585745 66.6743851,13.22590873 66.67434566,13.22595147 66.67430854,13.22596226 66.67429876,13.2260058 66.67424553,13.22609747 66.67427097,13.22615785 66.6742959,13.22626392 66.6743397,13.2262419 66.6743651,13.22625277 66.67437843,13.22620325 66.67439645,13.22613665 66.6744097,13.22609353 66.67441747,13.22605279 66.67442984,13.22603195 66.67444899,13.22601705 66.67447054,13.22600445 66.67449776,13.22598616 66.67453184,13.22596486 66.67456363,13.22594067 66.67460096,13.22593131 66.67463047,13.22592443 66.67466009,13.22590967 66.67468281,13.22589439 66.67470651,13.22589002 66.67474532,13.2258981 66.67477143,13.22589989 66.67480331,13.2259047 66.67483405,13.22591215 66.67486599,13.22592303 66.67489106,13.22592731 66.67493544,13.22590941 66.67495462,13.22590582 66.6749763,13.22593941 66.67500037,13.22600737 66.67503138,13.22608687 66.67506251,13.22611786 66.67507866,13.22616529 66.67512442,13.2261787 66.67515517,13.22616913 66.67518136,13.22613713 66.67519823,13.22606812 66.6751944,13.22599355 66.67518611,13.22595035 66.67519495,13.22593261 66.67521189,13.22593451 66.67523588,13.22594514 66.67526435,13.22597022 66.67528725,13.22600682 66.6753136,13.22606296 66.67535461,13.22577765 66.67543727,13.22523208 66.6751209,13.22475963 66.67412693,13.22489005 66.67378623)))'); NOTICE: 00000: Self-intersection at or near point 13.226665669999999 66.675985620000006 LOCATION: pg_notice, lwgeom_pg.c:354 st_isvalid ------------ f (1 row) }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Mar 11 04:31:00 2026 From: trac at osgeo.org (PostGIS) Date: Wed, 11 Mar 2026 11:31:00 -0000 Subject: [PostGIS] #5928: ST_Collect creates invalid result with only valid input In-Reply-To: <050.84e3da0ea6a49235b6bfb1faab70c23d@osgeo.org> References: <050.84e3da0ea6a49235b6bfb1faab70c23d@osgeo.org> Message-ID: <065.43455bfccf6aadd11859152860388375@osgeo.org> #5928: ST_Collect creates invalid result with only valid input --------------------------------+--------------------------- Reporter: Lars Aksel Opsahl | Owner: pramsey Type: defect | Status: reopened Priority: medium | Milestone: PostGIS 3.6.0 Component: postgis | Version: 3.5.x Resolution: | Keywords: --------------------------------+--------------------------- Changes (by Lars Aksel Opsahl): * resolution: worksforme => * status: closed => reopened -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Mar 11 14:18:10 2026 From: trac at osgeo.org (PostGIS) Date: Wed, 11 Mar 2026 21:18:10 -0000 Subject: [PostGIS] #6053: Spin off address_standardizer as separate project In-Reply-To: <049.f4d1eb5ea5ce334e1b08e74f1d6e7c99@osgeo.org> References: <049.f4d1eb5ea5ce334e1b08e74f1d6e7c99@osgeo.org> Message-ID: <064.4a7340ec68f608de40ec0c5623a00607@osgeo.org> #6053: Spin off address_standardizer as separate project ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: assigned Priority: medium | Milestone: PostGIS 3.7.0 Component: postgis | Version: master Resolution: | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"68dde711039986b47eb62feda45bb24b13b0ea37/git" 68dde71/git]: {{{#!CommitTicketReference repository="git" revision="68dde711039986b47eb62feda45bb24b13b0ea37" Remove address_standardizer extension, as it has moved to its own repo at https://github.com/postgis/address_standardizer References #6053 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Mar 11 14:19:28 2026 From: trac at osgeo.org (PostGIS) Date: Wed, 11 Mar 2026 21:19:28 -0000 Subject: [PostGIS] #5771: address_standardizer_data_us upgrade sql script can be incorrect In-Reply-To: <046.524edd8cd58c25ff7f532911ec4b217b@osgeo.org> References: <046.524edd8cd58c25ff7f532911ec4b217b@osgeo.org> Message-ID: <061.82b604ef281f6f7d53f7611b1deac30d@osgeo.org> #5771: address_standardizer_data_us upgrade sql script can be incorrect ----------------------+--------------------------- Reporter: evsi | Owner: robe Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.5.5 Component: postgis | Version: 3.4.x Resolution: wontfix | Keywords: ----------------------+--------------------------- Changes (by pramsey): * resolution: => wontfix * status: new => closed Comment: Re-file at https://github.com/postgis/address_standardizer -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Mar 11 14:20:11 2026 From: trac at osgeo.org (PostGIS) Date: Wed, 11 Mar 2026 21:20:11 -0000 Subject: [PostGIS] #6053: Spin off address_standardizer as separate project In-Reply-To: <049.f4d1eb5ea5ce334e1b08e74f1d6e7c99@osgeo.org> References: <049.f4d1eb5ea5ce334e1b08e74f1d6e7c99@osgeo.org> Message-ID: <064.0e43465d9734a120f6ce600841be4e82@osgeo.org> #6053: Spin off address_standardizer as separate project ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.7.0 Component: postgis | Version: master Resolution: fixed | Keywords: ----------------------+--------------------------- Changes (by pramsey): * resolution: => fixed * status: assigned => closed -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Mar 11 16:20:53 2026 From: trac at osgeo.org (PostGIS) Date: Wed, 11 Mar 2026 23:20:53 -0000 Subject: [PostGIS] #5928: ST_Collect creates invalid result with only valid input In-Reply-To: <050.84e3da0ea6a49235b6bfb1faab70c23d@osgeo.org> References: <050.84e3da0ea6a49235b6bfb1faab70c23d@osgeo.org> Message-ID: <065.4b1cbb9090bfce2b191f7eaea39ef1dd@osgeo.org> #5928: ST_Collect creates invalid result with only valid input --------------------------------+--------------------------- Reporter: Lars Aksel Opsahl | Owner: pramsey Type: defect | Status: reopened Priority: medium | Milestone: PostGIS 3.6.0 Component: postgis | Version: 3.5.x Resolution: | Keywords: --------------------------------+--------------------------- Comment (by mdavis): Replying to [comment:6 Lars Aksel Opsahl]: > Here we another case that reports invalid That is an invalid MultiPolygon, so `ST_ISValid` is working as expected. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Wed Mar 11 22:09:34 2026 From: trac at osgeo.org (PostGIS) Date: Thu, 12 Mar 2026 05:09:34 -0000 Subject: [PostGIS] #5928: ST_Collect creates invalid result with only valid input In-Reply-To: <050.84e3da0ea6a49235b6bfb1faab70c23d@osgeo.org> References: <050.84e3da0ea6a49235b6bfb1faab70c23d@osgeo.org> Message-ID: <065.00d623837ab99d68967ee40ad4bf7ae7@osgeo.org> #5928: ST_Collect creates invalid result with only valid input --------------------------------+--------------------------- Reporter: Lars Aksel Opsahl | Owner: pramsey Type: defect | Status: closed Priority: medium | Milestone: PostGIS 3.6.0 Component: postgis | Version: 3.5.x Resolution: worksforme | Keywords: --------------------------------+--------------------------- Changes (by Lars Aksel Opsahl): * resolution: => worksforme * status: reopened => closed Comment: Thanks this mean that if we collect many polygons we have to keep it as a collection in cases where we have many shared borders because of cases like this. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Mar 12 10:43:51 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 12 Mar 2026 10:43:51 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-386-g6cf2d9572 Message-ID: <20260312174351.D4F2F1A062C@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 6cf2d95722ad8e9ad6247491b6ae2e11bb9438a1 (commit) from 68dde711039986b47eb62feda45bb24b13b0ea37 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6cf2d95722ad8e9ad6247491b6ae2e11bb9438a1 Author: Regina Obe Date: Thu Mar 12 13:43:46 2026 -0400 Fix typo in winnie config diff --git a/ci/winnie/regress_postgis.sh b/ci/winnie/regress_postgis.sh index b3ac5bd47..2f5098aa9 100644 --- a/ci/winnie/regress_postgis.sh +++ b/ci/winnie/regress_postgis.sh @@ -160,7 +160,7 @@ for EXTNAME in $extensions_to_install; do done #cp -r ${PGPATH}/share/extension/postgis*${POSTGIS_MICRO_VER}.sql ${PGPATHEDB}/share/extension #cp -r ${PGPATH}/share/extension/postgis*${POSTGIS_MICRO_VER}next.sql ${PGPATHEDB}/share/extension - p -r extensions/*/*.control ${PGPATHEDB}/share/extension +cp -r extensions/*/*.control ${PGPATHEDB}/share/extension cp -r extensions/*/*.dll ${PGPATHEDB}/lib make check RUNTESTFLAGS="--extension -v" ----------------------------------------------------------------------- Summary of changes: ci/winnie/regress_postgis.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Mar 12 11:07:56 2026 From: trac at osgeo.org (PostGIS) Date: Thu, 12 Mar 2026 18:07:56 -0000 Subject: [PostGIS] #6056: Woodie will be moved to osgeo10 Message-ID: <046.6b3dd0406746a94e9ebd6d7e910d7486@osgeo.org> #6056: Woodie will be moved to osgeo10 --------------------------+-------------------------------------- Reporter: robe | Owner: robe Type: defect | Status: new Priority: medium | Milestone: Website Management, Bots Component: QA/buildbots | Version: 3.5.x Keywords: | --------------------------+-------------------------------------- Woodie server has not been working today, bu anyway I'll be moving it to osgeo10 and troubleshoot the issue there. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Mar 12 11:12:58 2026 From: trac at osgeo.org (PostGIS) Date: Thu, 12 Mar 2026 18:12:58 -0000 Subject: [PostGIS] #6056: Woodie will be moved to osgeo10 In-Reply-To: <046.6b3dd0406746a94e9ebd6d7e910d7486@osgeo.org> References: <046.6b3dd0406746a94e9ebd6d7e910d7486@osgeo.org> Message-ID: <061.b95e5bae6e25ed2b3c4c1369f0249b63@osgeo.org> #6056: Woodie will be moved to osgeo10 ---------------------------+-------------------------------------- Reporter: robe | Owner: robe Type: defect | Status: new Priority: medium | Milestone: Website Management, Bots Component: QA/buildbots | Version: 3.5.x Resolution: | Keywords: ---------------------------+-------------------------------------- Comment (by robe): okay got it working again on osgeo8, but will move later tonight to osgeo10 -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Mar 12 11:14:19 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 12 Mar 2026 11:14:19 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-387-gaa6812e6c Message-ID: <20260312181419.7B8B21A4DDB@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via aa6812e6c38ddbdac6491115f6abbee2a72ad993 (commit) from 6cf2d95722ad8e9ad6247491b6ae2e11bb9438a1 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit aa6812e6c38ddbdac6491115f6abbee2a72ad993 Author: Paul Ramsey Date: Thu Mar 12 11:13:14 2026 -0700 Fully qualify calls to format in packaging script. Reported by Daniel Bakker diff --git a/utils/create_unpackaged.pl b/utils/create_unpackaged.pl index e7021d87a..e3cc4ba7f 100755 --- a/utils/create_unpackaged.pl +++ b/utils/create_unpackaged.pl @@ -186,10 +186,10 @@ AS \$\$ DECLARE sql text; proc regproc; - obj text := format('%s %s', type, sig); + obj text := pg_catalog.format('%s %s', type, sig); BEGIN - sql := format('ALTER EXTENSION ${extname} ADD %s', obj); + sql := pg_catalog.format('ALTER EXTENSION ${extname} ADD %s', obj); EXECUTE sql; RAISE NOTICE 'newly registered %', obj; @@ -359,7 +359,7 @@ BEGIN 'Changing ownership of function % from % to % to match ext', rec.oid::regprocedure, rec.proowner::regrole, rec.extowner::regrole; - sql := format( + sql := pg_catalog.format( 'ALTER FUNCTION %s OWNER TO %I', rec.oid::regprocedure, rec.extowner::regrole ----------------------------------------------------------------------- Summary of changes: utils/create_unpackaged.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Mar 12 11:33:42 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 12 Mar 2026 11:33:42 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-388-gcc9117fda Message-ID: <20260312183342.477EF1A56EB@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via cc9117fdae5549464c8dd243c3d296f93f2a5a3f (commit) from aa6812e6c38ddbdac6491115f6abbee2a72ad993 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit cc9117fdae5549464c8dd243c3d296f93f2a5a3f Author: Regina Obe Date: Thu Mar 12 14:33:36 2026 -0400 Winnie: fix no dlls left in extensions folder now that address_standardizer is gone diff --git a/ci/winnie/regress_postgis.sh b/ci/winnie/regress_postgis.sh index 2f5098aa9..d30575c6c 100644 --- a/ci/winnie/regress_postgis.sh +++ b/ci/winnie/regress_postgis.sh @@ -161,7 +161,7 @@ done #cp -r ${PGPATH}/share/extension/postgis*${POSTGIS_MICRO_VER}.sql ${PGPATHEDB}/share/extension #cp -r ${PGPATH}/share/extension/postgis*${POSTGIS_MICRO_VER}next.sql ${PGPATHEDB}/share/extension cp -r extensions/*/*.control ${PGPATHEDB}/share/extension -cp -r extensions/*/*.dll ${PGPATHEDB}/lib +#cp -r extensions/*/*.dll ${PGPATHEDB}/lib make check RUNTESTFLAGS="--extension -v" ----------------------------------------------------------------------- Summary of changes: ci/winnie/regress_postgis.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Mar 12 11:43:31 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 12 Mar 2026 11:43:31 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-389-g379a6998a Message-ID: <20260312184331.70C8D1A64BE@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 379a6998ac744150a7d9fbacaf153b6b951d3903 (commit) from cc9117fdae5549464c8dd243c3d296f93f2a5a3f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 379a6998ac744150a7d9fbacaf153b6b951d3903 Author: Regina Obe Date: Thu Mar 12 14:43:20 2026 -0400 Put back pagc_tables. postgis_tiger_geocoder will need those if address_standardizer is used for geocoding diff --git a/extensions/postgis_tiger_geocoder/Makefile.in b/extensions/postgis_tiger_geocoder/Makefile.in index 65456e715..ee6875577 100644 --- a/extensions/postgis_tiger_geocoder/Makefile.in +++ b/extensions/postgis_tiger_geocoder/Makefile.in @@ -131,6 +131,8 @@ sql/tiger_geocoder_minor.sql.in: ../../extras/tiger_geocoder/utility/set_search_ ../../extras/tiger_geocoder/normalize/location_extract.sql \ ../../extras/tiger_geocoder/normalize/normalize_address.sql \ ../../extras/tiger_geocoder/normalize/pprint_addy.sql \ + ../../extras/tiger_geocoder/pagc_normalize/pagc_tables.sql \ + ../../extras/tiger_geocoder/pagc_normalize/pagc_normalize_address.sql \ ../../extras/tiger_geocoder/geocode/other_helper_functions.sql \ ../../extras/tiger_geocoder/geocode/rate_attributes.sql \ ../../extras/tiger_geocoder/geocode/includes_address.sql \ ----------------------------------------------------------------------- Summary of changes: extensions/postgis_tiger_geocoder/Makefile.in | 2 ++ 1 file changed, 2 insertions(+) hooks/post-receive -- PostGIS From git at osgeo.org Thu Mar 12 12:05:11 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 12 Mar 2026 12:05:11 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.6 updated. 3.6.2-3-g6d032d7f2 Message-ID: <20260312190512.148D61A63F2@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.6 has been updated via 6d032d7f203aca9e77badfcc26e9c84968cd3655 (commit) from 20e9ab6572a45f5264b033fc1414646a7c0d5190 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 6d032d7f203aca9e77badfcc26e9c84968cd3655 Author: Paul Ramsey Date: Thu Mar 12 11:59:35 2026 -0700 Remove priv escalation scenario. Reported by Daniel Bakker References #6054 diff --git a/NEWS b/NEWS index 701e08eeb..ab8ac0c4e 100644 --- a/NEWS +++ b/NEWS @@ -16,7 +16,8 @@ topogeometry corruption: * Fixes * - #6055, Remove rare extension priv escalation case. - Reported by Sven Klemm (Tiger Data) and Allistair Ishmael Hakim (allistair.sh) + Reported by Sven Klemm (Tiger Data), Allistair Ishmael Hakim (allistair.sh) + and Daniel Bakker PostGIS 3.6.2 diff --git a/utils/create_unpackaged.pl b/utils/create_unpackaged.pl index e7021d87a..e3cc4ba7f 100755 --- a/utils/create_unpackaged.pl +++ b/utils/create_unpackaged.pl @@ -186,10 +186,10 @@ AS \$\$ DECLARE sql text; proc regproc; - obj text := format('%s %s', type, sig); + obj text := pg_catalog.format('%s %s', type, sig); BEGIN - sql := format('ALTER EXTENSION ${extname} ADD %s', obj); + sql := pg_catalog.format('ALTER EXTENSION ${extname} ADD %s', obj); EXECUTE sql; RAISE NOTICE 'newly registered %', obj; @@ -359,7 +359,7 @@ BEGIN 'Changing ownership of function % from % to % to match ext', rec.oid::regprocedure, rec.proowner::regrole, rec.extowner::regrole; - sql := format( + sql := pg_catalog.format( 'ALTER FUNCTION %s OWNER TO %I', rec.oid::regprocedure, rec.extowner::regrole ----------------------------------------------------------------------- Summary of changes: NEWS | 3 ++- utils/create_unpackaged.pl | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Mar 12 12:05:16 2026 From: trac at osgeo.org (PostGIS) Date: Thu, 12 Mar 2026 19:05:16 -0000 Subject: [PostGIS] #6054: Lock down search path during install In-Reply-To: <046.d130944804e39b7d3a159db8f685fa61@osgeo.org> References: <046.d130944804e39b7d3a159db8f685fa61@osgeo.org> Message-ID: <061.3108b85104157d4d37c54a2b26de8a56@osgeo.org> #6054: Lock down search path during install ----------------------+---------------------------- Reporter: robe | Owner: robe Type: defect | Status: assigned Priority: medium | Milestone: PostGIS 3.2.10 Component: install | Version: 3.2.x Resolution: | Keywords: ----------------------+---------------------------- Comment (by Paul Ramsey ): In [changeset:"6d032d7f203aca9e77badfcc26e9c84968cd3655/git" 6d032d7/git]: {{{#!CommitTicketReference repository="git" revision="6d032d7f203aca9e77badfcc26e9c84968cd3655" Remove priv escalation scenario. Reported by Daniel Bakker References #6054 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Mar 12 12:06:10 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 12 Mar 2026 12:06:10 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.5 updated. 3.5.5-3-g1bd2c415c Message-ID: <20260312190610.5EFB21A63F3@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.5 has been updated via 1bd2c415cd830ec5e67a9c1987cbfb97aeec9c43 (commit) from d1b44c115e202fbec8fb6238f821f38b7efc6ef0 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1bd2c415cd830ec5e67a9c1987cbfb97aeec9c43 Author: Paul Ramsey Date: Thu Mar 12 12:01:24 2026 -0700 Remove priv escalation scenario. Reported by Daniel Bakker References #6054 diff --git a/NEWS b/NEWS index a66c75e0d..ff7816473 100644 --- a/NEWS +++ b/NEWS @@ -7,7 +7,8 @@ PostgreSQL 12-18 required. GEOS 3.8+ required. Proj 6.1+ required. * Bug fixes * - #6055, Remove rare extension priv escalation case. - Reported by Sven Klemm (Tiger Data) and Allistair Ishmael Hakim (allistair.sh) + Reported by Sven Klemm (Tiger Data), Allistair Ishmael Hakim (allistair.sh) + and Daniel Bakker PostGIS 3.5.5 diff --git a/utils/create_unpackaged.pl b/utils/create_unpackaged.pl index e7021d87a..e3cc4ba7f 100755 --- a/utils/create_unpackaged.pl +++ b/utils/create_unpackaged.pl @@ -186,10 +186,10 @@ AS \$\$ DECLARE sql text; proc regproc; - obj text := format('%s %s', type, sig); + obj text := pg_catalog.format('%s %s', type, sig); BEGIN - sql := format('ALTER EXTENSION ${extname} ADD %s', obj); + sql := pg_catalog.format('ALTER EXTENSION ${extname} ADD %s', obj); EXECUTE sql; RAISE NOTICE 'newly registered %', obj; @@ -359,7 +359,7 @@ BEGIN 'Changing ownership of function % from % to % to match ext', rec.oid::regprocedure, rec.proowner::regrole, rec.extowner::regrole; - sql := format( + sql := pg_catalog.format( 'ALTER FUNCTION %s OWNER TO %I', rec.oid::regprocedure, rec.extowner::regrole ----------------------------------------------------------------------- Summary of changes: NEWS | 3 ++- utils/create_unpackaged.pl | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Mar 12 12:06:12 2026 From: trac at osgeo.org (PostGIS) Date: Thu, 12 Mar 2026 19:06:12 -0000 Subject: [PostGIS] #6054: Lock down search path during install In-Reply-To: <046.d130944804e39b7d3a159db8f685fa61@osgeo.org> References: <046.d130944804e39b7d3a159db8f685fa61@osgeo.org> Message-ID: <061.c6db124448157e68ae928d17832f41e7@osgeo.org> #6054: Lock down search path during install ----------------------+---------------------------- Reporter: robe | Owner: robe Type: defect | Status: assigned Priority: medium | Milestone: PostGIS 3.2.10 Component: install | Version: 3.2.x Resolution: | Keywords: ----------------------+---------------------------- Comment (by Paul Ramsey ): In [changeset:"1bd2c415cd830ec5e67a9c1987cbfb97aeec9c43/git" 1bd2c41/git]: {{{#!CommitTicketReference repository="git" revision="1bd2c415cd830ec5e67a9c1987cbfb97aeec9c43" Remove priv escalation scenario. Reported by Daniel Bakker References #6054 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Mar 12 12:06:12 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 12 Mar 2026 12:06:12 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.4 updated. 3.4.5-6-gcf26d1a4e Message-ID: <20260312190612.90C011A63F4@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.4 has been updated via cf26d1a4efc3c886de779335c6662bf682e43daa (commit) via d33ee69b158bcde54ad407b5939c11442f8e2d7c (commit) from 86e45c71c55b00b62c64a51d081ffff0a896222c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit cf26d1a4efc3c886de779335c6662bf682e43daa Author: Paul Ramsey Date: Thu Mar 12 12:02:44 2026 -0700 Remove priv escalation scenario. Reported by Daniel Bakker References #6054 diff --git a/NEWS b/NEWS index 53c688b01..385b3bd13 100644 --- a/NEWS +++ b/NEWS @@ -7,7 +7,8 @@ Proj 6.1+ required. * Bug Fixes * - #6055, Remove rare extension priv escalation case. - Reported by Sven Klemm (Tiger Data) and Allistair Ishmael Hakim (allistair.sh) + Reported by Sven Klemm (Tiger Data), Allistair Ishmael Hakim (allistair.sh) + and Daniel Bakker PostGIS 3.4.5 diff --git a/utils/create_unpackaged.pl b/utils/create_unpackaged.pl index a50725158..d505ed747 100755 --- a/utils/create_unpackaged.pl +++ b/utils/create_unpackaged.pl @@ -186,10 +186,10 @@ AS \$\$ DECLARE sql text; proc regproc; - obj text := format('%s %s', type, sig); + obj text := pg_catalog.format('%s %s', type, sig); BEGIN - sql := format('ALTER EXTENSION ${extname} ADD %s', obj); + sql := pg_catalog.format('ALTER EXTENSION ${extname} ADD %s', obj); EXECUTE sql; RAISE NOTICE 'newly registered %', obj; commit d33ee69b158bcde54ad407b5939c11442f8e2d7c Author: Paul Ramsey Date: Fri Mar 6 13:12:28 2026 -0800 Remove rare extension priv escalation case, where account with extension create privs can escalate to superuser by piggy backing on an extension creation event. From Sven Klemm (Tiger Data) and Allistair Ishmael Hakim (allistair.sh) References #6055 diff --git a/NEWS b/NEWS index 00e232b57..53c688b01 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ Proj 6.1+ required. * Bug Fixes * + - #6055, Remove rare extension priv escalation case. + Reported by Sven Klemm (Tiger Data) and Allistair Ishmael Hakim (allistair.sh) PostGIS 3.4.5 diff --git a/libpgcommon/sql/AddToSearchPath.sql.inc b/libpgcommon/sql/AddToSearchPath.sql.inc index a5e02279e..ff313406c 100644 --- a/libpgcommon/sql/AddToSearchPath.sql.inc +++ b/libpgcommon/sql/AddToSearchPath.sql.inc @@ -16,10 +16,10 @@ DECLARE BEGIN WITH settings AS ( SELECT unnest(setconfig) config - FROM pg_db_role_setting + FROM pg_catalog.pg_db_role_setting WHERE setdatabase = ( SELECT oid - FROM pg_database + FROM pg_catalog.pg_database WHERE datname = current_database() ) and setrole = 0 ) @@ -30,10 +30,10 @@ BEGIN RAISE NOTICE 'cur_search_path from pg_db_role_setting is %', var_cur_search_path; -- only run this test if person creating the extension is a super user - IF var_cur_search_path IS NULL AND (SELECT rolsuper FROM pg_roles where rolname = CURRENT_USER) THEN + IF var_cur_search_path IS NULL AND (SELECT rolsuper FROM pg_catalog.pg_roles where rolname = CURRENT_USER) THEN SELECT setting INTO var_cur_search_path - FROM pg_file_settings + FROM pg_catalog.pg_file_settings WHERE name = 'search_path' AND applied; RAISE NOTICE 'cur_search_path from pg_file_settings is %', var_cur_search_path; @@ -42,7 +42,7 @@ BEGIN IF var_cur_search_path IS NULL THEN SELECT boot_val INTO var_cur_search_path - FROM pg_settings + FROM pg_catalog.pg_settings WHERE name = 'search_path'; RAISE NOTICE 'cur_search_path from pg_settings is %', var_cur_search_path; @@ -63,7 +63,8 @@ BEGIN RETURN var_result; END $BODY$ -SET search_path = pg_catalog -- make safe +-- explicitly move pg_temp after pg_catalog in search path +SET search_path = pg_catalog, pg_temp LANGUAGE 'plpgsql' VOLATILE STRICT ; ----------------------------------------------------------------------- Summary of changes: NEWS | 3 +++ libpgcommon/sql/AddToSearchPath.sql.inc | 13 +++++++------ utils/create_unpackaged.pl | 4 ++-- 3 files changed, 12 insertions(+), 8 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Mar 12 12:06:13 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 12 Mar 2026 12:06:13 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.3 updated. 3.3.9-5-ge64883525 Message-ID: <20260312190614.02B631A6833@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.3 has been updated via e648835255fc4de9e838bb1a4a0fe97423ad1269 (commit) from 9562c2020b0ecac01cec2d7877666425b41e81a8 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e648835255fc4de9e838bb1a4a0fe97423ad1269 Author: Paul Ramsey Date: Thu Mar 12 12:03:36 2026 -0700 Remove priv escalation scenario. Reported by Daniel Bakker References #6054 diff --git a/NEWS b/NEWS index 95563125a..f3cfc3eb3 100644 --- a/NEWS +++ b/NEWS @@ -6,7 +6,8 @@ PostGIS 3.3.10 - #5998, [tiger_geododer] Do not create tiger_data as part of postgis_tiger_geocoder extension, create/update (Regina Obe) - #6055, Remove rare extension priv escalation case. - Reported by Sven Klemm (Tiger Data) and Allistair Ishmael Hakim (allistair.sh) + Reported by Sven Klemm (Tiger Data), Allistair Ishmael Hakim (allistair.sh) + and Daniel Bakker PostGIS 3.3.9 diff --git a/utils/create_unpackaged.pl b/utils/create_unpackaged.pl index a50725158..d505ed747 100755 --- a/utils/create_unpackaged.pl +++ b/utils/create_unpackaged.pl @@ -186,10 +186,10 @@ AS \$\$ DECLARE sql text; proc regproc; - obj text := format('%s %s', type, sig); + obj text := pg_catalog.format('%s %s', type, sig); BEGIN - sql := format('ALTER EXTENSION ${extname} ADD %s', obj); + sql := pg_catalog.format('ALTER EXTENSION ${extname} ADD %s', obj); EXECUTE sql; RAISE NOTICE 'newly registered %', obj; ----------------------------------------------------------------------- Summary of changes: NEWS | 3 ++- utils/create_unpackaged.pl | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Mar 12 12:06:14 2026 From: trac at osgeo.org (PostGIS) Date: Thu, 12 Mar 2026 19:06:14 -0000 Subject: [PostGIS] #6055: Specify search_path carefully during extension install In-Reply-To: <049.b6be645ea57dbb71051ae75581b93595@osgeo.org> References: <049.b6be645ea57dbb71051ae75581b93595@osgeo.org> Message-ID: <064.15a3a3f6e259263ab4906fa1733ffa09@osgeo.org> #6055: Specify search_path carefully during extension install ----------------------+--------------------------- Reporter: pramsey | Owner: pramsey Type: defect | Status: closed Priority: high | Milestone: PostGIS 3.6.2 Component: postgis | Version: 3.2.x Resolution: fixed | Keywords: ----------------------+--------------------------- Comment (by Paul Ramsey ): In [changeset:"d33ee69b158bcde54ad407b5939c11442f8e2d7c/git" d33ee69b/git]: {{{#!CommitTicketReference repository="git" revision="d33ee69b158bcde54ad407b5939c11442f8e2d7c" Remove rare extension priv escalation case, where account with extension create privs can escalate to superuser by piggy backing on an extension creation event. From Sven Klemm (Tiger Data) and Allistair Ishmael Hakim (allistair.sh) References #6055 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Mar 12 12:06:14 2026 From: trac at osgeo.org (PostGIS) Date: Thu, 12 Mar 2026 19:06:14 -0000 Subject: [PostGIS] #6054: Lock down search path during install In-Reply-To: <046.d130944804e39b7d3a159db8f685fa61@osgeo.org> References: <046.d130944804e39b7d3a159db8f685fa61@osgeo.org> Message-ID: <061.55150d4ea3aeb880d79b3aa3f915a0c6@osgeo.org> #6054: Lock down search path during install ----------------------+---------------------------- Reporter: robe | Owner: robe Type: defect | Status: assigned Priority: medium | Milestone: PostGIS 3.2.10 Component: install | Version: 3.2.x Resolution: | Keywords: ----------------------+---------------------------- Comment (by Paul Ramsey ): In [changeset:"cf26d1a4efc3c886de779335c6662bf682e43daa/git" cf26d1a/git]: {{{#!CommitTicketReference repository="git" revision="cf26d1a4efc3c886de779335c6662bf682e43daa" Remove priv escalation scenario. Reported by Daniel Bakker References #6054 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Mar 12 12:06:15 2026 From: trac at osgeo.org (PostGIS) Date: Thu, 12 Mar 2026 19:06:15 -0000 Subject: [PostGIS] #6054: Lock down search path during install In-Reply-To: <046.d130944804e39b7d3a159db8f685fa61@osgeo.org> References: <046.d130944804e39b7d3a159db8f685fa61@osgeo.org> Message-ID: <061.a61a64fef882c38ad404f1785dcd22ff@osgeo.org> #6054: Lock down search path during install ----------------------+---------------------------- Reporter: robe | Owner: robe Type: defect | Status: assigned Priority: medium | Milestone: PostGIS 3.2.10 Component: install | Version: 3.2.x Resolution: | Keywords: ----------------------+---------------------------- Comment (by Paul Ramsey ): In [changeset:"e648835255fc4de9e838bb1a4a0fe97423ad1269/git" e6488352/git]: {{{#!CommitTicketReference repository="git" revision="e648835255fc4de9e838bb1a4a0fe97423ad1269" Remove priv escalation scenario. Reported by Daniel Bakker References #6054 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Mar 12 12:06:15 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 12 Mar 2026 12:06:15 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.2 updated. 3.2.9-3-g2396083a5 Message-ID: <20260312190615.C8A991A6D82@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.2 has been updated via 2396083a5445169d4db8095722f23df711e71b19 (commit) from 9bed75f7f186dfa4f60039d68103a73c91a69b8e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2396083a5445169d4db8095722f23df711e71b19 Author: Paul Ramsey Date: Thu Mar 12 12:04:34 2026 -0700 Remove priv escalation scenario. Reported by Daniel Bakker References #6054 diff --git a/NEWS b/NEWS index 99442f6b4..04a241768 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,8 @@ Proj 4.9+ required. - #5998, [tiger_geododer] Do not create tiger_data as part of postgis_tiger_geocoder extension, create/update (Regina Obe) + - #6054, Remove priv escalation scenario. Reported by Daniel Bakker + PostGIS 3.2.9 2026/02/08 diff --git a/utils/create_unpackaged.pl b/utils/create_unpackaged.pl index a50725158..d505ed747 100755 --- a/utils/create_unpackaged.pl +++ b/utils/create_unpackaged.pl @@ -186,10 +186,10 @@ AS \$\$ DECLARE sql text; proc regproc; - obj text := format('%s %s', type, sig); + obj text := pg_catalog.format('%s %s', type, sig); BEGIN - sql := format('ALTER EXTENSION ${extname} ADD %s', obj); + sql := pg_catalog.format('ALTER EXTENSION ${extname} ADD %s', obj); EXECUTE sql; RAISE NOTICE 'newly registered %', obj; ----------------------------------------------------------------------- Summary of changes: NEWS | 2 ++ utils/create_unpackaged.pl | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) hooks/post-receive -- PostGIS From trac at osgeo.org Thu Mar 12 12:06:17 2026 From: trac at osgeo.org (PostGIS) Date: Thu, 12 Mar 2026 19:06:17 -0000 Subject: [PostGIS] #6054: Lock down search path during install In-Reply-To: <046.d130944804e39b7d3a159db8f685fa61@osgeo.org> References: <046.d130944804e39b7d3a159db8f685fa61@osgeo.org> Message-ID: <061.ced293aa314b09739ad5d5de4d7fc7fb@osgeo.org> #6054: Lock down search path during install ----------------------+---------------------------- Reporter: robe | Owner: robe Type: defect | Status: assigned Priority: medium | Milestone: PostGIS 3.2.10 Component: install | Version: 3.2.x Resolution: | Keywords: ----------------------+---------------------------- Comment (by Paul Ramsey ): In [changeset:"2396083a5445169d4db8095722f23df711e71b19/git" 2396083/git]: {{{#!CommitTicketReference repository="git" revision="2396083a5445169d4db8095722f23df711e71b19" Remove priv escalation scenario. Reported by Daniel Bakker References #6054 }}} -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From trac at osgeo.org Thu Mar 12 15:10:15 2026 From: trac at osgeo.org (PostGIS) Date: Thu, 12 Mar 2026 22:10:15 -0000 Subject: [PostGIS] #6057: Remove postgis_extension_AddToSearchPath Message-ID: <049.9ab2c7a5b0db3ab355b4fd09c0bd8107@osgeo.org> #6057: Remove postgis_extension_AddToSearchPath ----------------------------+--------------------------- Reporter: pramsey | Owner: robe Type: defect | Status: assigned Priority: blocker | Milestone: PostGIS 3.7.0 Component: tiger geocoder | Version: master Keywords: | ----------------------------+--------------------------- When the tiger geocoder is extracted from postgis, remove all trace of the postgis_extension_AddToSearchPath function from the build. It is only used by tiger and is the locus of some security concerns. -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Thu Mar 12 15:19:58 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 12 Mar 2026 15:19:58 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-390-g419c29443 Message-ID: <20260312221959.1DD561A0875@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 419c294431361ab9a15a497c23ab54f1d546aa1b (commit) from 379a6998ac744150a7d9fbacaf153b6b951d3903 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 419c294431361ab9a15a497c23ab54f1d546aa1b Author: Sandro Santilli Date: Thu Mar 12 23:18:56 2026 +0100 Revert "Disable topology testing on bessie until regressions fixed" This reverts commit 1a44e0fdca9141e7e5c844ec4b537015219b4be9 as the regression could have been fixed by commit 14152529d3f3008be89dbc76505521e819ae78d5 diff --git a/ci/bessie/postgis_regress.sh b/ci/bessie/postgis_regress.sh index 18d5fdf5a..bec7bb73b 100644 --- a/ci/bessie/postgis_regress.sh +++ b/ci/bessie/postgis_regress.sh @@ -8,8 +8,7 @@ sh autogen.sh ./configure \ --with-projdir=/usr/local \ --with-libiconv=/usr/local \ - --with-library-minor-version \ - --without-topology + --with-library-minor-version #make distclean make export PGUSER=postgres ----------------------------------------------------------------------- Summary of changes: ci/bessie/postgis_regress.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Mar 12 21:30:16 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 12 Mar 2026 21:30:16 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-391-gfdb442fb8 Message-ID: <20260313043016.580451A1152@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via fdb442fb88c0d413598e090cc00662aa0863efae (commit) from 419c294431361ab9a15a497c23ab54f1d546aa1b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fdb442fb88c0d413598e090cc00662aa0863efae Author: Regina Obe Date: Fri Mar 13 00:30:11 2026 -0400 WINNIE packaging fix: Don't search for dlls in extension folder diff --git a/ci/winnie/package_postgis.sh b/ci/winnie/package_postgis.sh index c706d7a75..1c8857626 100644 --- a/ci/winnie/package_postgis.sh +++ b/ci/winnie/package_postgis.sh @@ -187,7 +187,7 @@ done #cp ${PGPATH}/share/extension/postgis*${POSTGIS_MICRO_VER}next.sql ${RELDIR}/${RELVERDIR}/share/extension cp -r extensions/*/*.control ${RELDIR}/${RELVERDIR}/share/extension -cp -r extensions/*/*.dll ${RELDIR}/${RELVERDIR}/lib +#cp -r extensions/*/*.dll ${RELDIR}/${RELVERDIR}/lib #cp extensions/postgis_topology/sql/* ${RELDIR}/${RELVERDIR}/share/extension #cp extensions/postgis_topology/*.control ${RELDIR}/${RELVERDIR}/share/extension cp -r ${RELDIR}/packaging_notes/* ${RELDIR}/${RELVERDIR}/ ----------------------------------------------------------------------- Summary of changes: ci/winnie/package_postgis.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) hooks/post-receive -- PostGIS From git at osgeo.org Thu Mar 12 21:36:47 2026 From: git at osgeo.org (git at osgeo.org) Date: Thu, 12 Mar 2026 21:36:47 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-392-gcf897cf35 Message-ID: <20260313043647.865481A7BEC@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via cf897cf35d100480c80e20e07f2784d5accea5ec (commit) from fdb442fb88c0d413598e090cc00662aa0863efae (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit cf897cf35d100480c80e20e07f2784d5accea5ec Author: Regina Obe Date: Fri Mar 13 00:36:01 2026 -0400 Put back pagc gaz tables and pagc normalize addy function for create extension postgis_tiger_geocoder diff --git a/extensions/postgis_tiger_geocoder/Makefile.in b/extensions/postgis_tiger_geocoder/Makefile.in index ee6875577..e064d6f0b 100644 --- a/extensions/postgis_tiger_geocoder/Makefile.in +++ b/extensions/postgis_tiger_geocoder/Makefile.in @@ -168,6 +168,8 @@ sql/tiger_geocoder.sql.in: sql_bits/norm_addy_create.sql.in \ ../../extras/tiger_geocoder/normalize/location_extract.sql \ ../../extras/tiger_geocoder/normalize/normalize_address.sql \ ../../extras/tiger_geocoder/normalize/pprint_addy.sql \ + ../../extras/tiger_geocoder/pagc_normalize/pagc_tables.sql \ + ../../extras/tiger_geocoder/pagc_normalize/pagc_normalize_address.sql \ ../../extras/tiger_geocoder/geocode/other_helper_functions.sql \ ../../extras/tiger_geocoder/geocode/rate_attributes.sql \ ../../extras/tiger_geocoder/geocode/includes_address.sql \ ----------------------------------------------------------------------- Summary of changes: extensions/postgis_tiger_geocoder/Makefile.in | 2 ++ 1 file changed, 2 insertions(+) hooks/post-receive -- PostGIS From trac at osgeo.org Fri Mar 13 02:14:56 2026 From: trac at osgeo.org (PostGIS) Date: Fri, 13 Mar 2026 09:14:56 -0000 Subject: [PostGIS] #6056: Woodie will be moved to osgeo10 In-Reply-To: <046.6b3dd0406746a94e9ebd6d7e910d7486@osgeo.org> References: <046.6b3dd0406746a94e9ebd6d7e910d7486@osgeo.org> Message-ID: <061.b0a003744e32e1b2e53b8901f0a7191a@osgeo.org> #6056: Woodie will be moved to osgeo10 ---------------------------+-------------------------------------- Reporter: robe | Owner: robe Type: defect | Status: closed Priority: medium | Milestone: Website Management, Bots Component: QA/buildbots | Version: 3.5.x Resolution: fixed | Keywords: ---------------------------+-------------------------------------- Changes (by robe): * resolution: => fixed * status: new => closed -- Ticket URL: PostGIS The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project. From git at osgeo.org Sat Mar 14 09:58:50 2026 From: git at osgeo.org (git at osgeo.org) Date: Sat, 14 Mar 2026 09:58:50 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-393-g7c18321e1 Message-ID: <20260314165850.8E9031AF3F7@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via 7c18321e17bfba6d24600e39d11271616ae71124 (commit) from cf897cf35d100480c80e20e07f2784d5accea5ec (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 7c18321e17bfba6d24600e39d11271616ae71124 Author: Paul Ramsey Date: Fri Mar 13 08:24:55 2026 -0700 Remove unused extension helper functions from topology upgrade scripts diff --git a/extensions/postgis_topology/Makefile.in b/extensions/postgis_topology/Makefile.in index 0bc04fc56..ccd8472b3 100644 --- a/extensions/postgis_topology/Makefile.in +++ b/extensions/postgis_topology/Makefile.in @@ -41,10 +41,8 @@ DATA_built = \ # NOTE: order matters EXTENSION_UPGRADE_SCRIPTS = \ extlock.sql \ - ../postgis_extension_helper.sql \ sql/topology_upgrade.sql \ - sql_bits/mark_editable_objects.sql.in \ - ../postgis_extension_helper_uninstall.sql + sql_bits/mark_editable_objects.sql.in EXTRA_CLEAN = sql/ ----------------------------------------------------------------------- Summary of changes: extensions/postgis_topology/Makefile.in | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Mon Mar 16 03:09:17 2026 From: git at osgeo.org (git at osgeo.org) Date: Mon, 16 Mar 2026 03:09:17 -0700 (PDT) Subject: [SCM] postgis.net branch website updated. clarity-final-180-g8f687a2 Message-ID: <20260316100917.739A61B5A22@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "postgis.net". The branch, website has been updated via 8f687a26d24cd29558ab3d159ecf5a675d7e5fae (commit) from 3c223d1bfb08417cca4aefa1b8f565fc7d081237 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8f687a26d24cd29558ab3d159ecf5a675d7e5fae Author: Regina Obe Date: Mon Mar 16 06:09:09 2026 -0400 Announce the release of windows PostGIS 3.6.2 bundle diff --git a/content/documentation/getting_started/install_windows/released_versions.md b/content/documentation/getting_started/install_windows/released_versions.md index 73619da..00ed37e 100644 --- a/content/documentation/getting_started/install_windows/released_versions.md +++ b/content/documentation/getting_started/install_windows/released_versions.md @@ -1,23 +1,22 @@ --- title: Latest Released Version -date: 2025-10-05 +date: 2026-03-16 weight: 10 geekdocHidden: true geekdocHiddenTocTree: false --- -PostGIS 3.6.1 came out Nov 13th, 2025. Windows PostGIS Bundle 3.6.1 installers for PostgreSQL 13-18 was last released Nov 20th-22nd 2025. +PostGIS 3.6.2 was released Feb 6th, 2026. Windows PostGIS Bundle 3.6.2 installers for PostgreSQL 14-18 was released Mar 16th, 2026. -Binaries for versions of PostgreSQL 13-18 (64-bit) available in `Unreleased PostGIS Versions` and [OSGeo downloads][5]). Installers for 18(64-bit) available on [OSGeo downloads][5] and application stackbuilder. -Installers for PostgreSQL 13-17 will be available soon. +Binaries for versions of PostgreSQL 13-18 (64-bit) available in `Unreleased PostGIS Versions` and [OSGeo downloads][5]). Installers for 14-18(64-bit) available on [OSGeo downloads][5] and application stackbuilder. Note: This is the first release that includes pgSphere -PostGIS 3.6.1 bundle includes: +PostGIS 3.6.2 bundle includes: - * PostGIS 3.6.1 with MVT support, with raster, [GEOS](https://libgeos.org/posts/2025-08-21-geos-3-14-released/) 3.14.1, [PROJ](https://proj.org/download.html#past-releases) 8.2.1, [SFCGAL](http://sfcgal.org) support (2.2.0), address_standardizer, topology + * PostGIS 3.6.2 with MVT support, with raster, [GEOS](https://libgeos.org/posts/2025-08-21-geos-3-14-released/) 3.14.1, [PROJ](https://proj.org/download.html#past-releases) 8.2.1, [SFCGAL](http://sfcgal.org) support (2.2.0), address_standardizer, topology * PostGIS Tiger geocoder extension - Tiger 2025 - * pgRouting 4.0 [pgRouting 4.0.0](https://docs.pgrouting.org/4.0/en/index.html) + * pgRouting 4.0 [pgRouting 4.0.1](https://docs.pgrouting.org/4.0/en/index.html) * Commandline raster loader (raster2pgsql), shapefile import/export (shp2pgsql,pgsql2shp) * Commandline [osm2pgrouting 3.0.0](https://github.com/pgRouting/osm2pgrouting/tree/v3.0.0) for loading data from .osm files into pgRouting routable format * [ogrfdw 1.1.7](https://github.com/pramsey/pgsql-ogr-fdw/releases/tag/v1.1.7) - spatial foreign data wrapper for @@ -28,7 +27,7 @@ PostGIS 3.6.1 bundle includes: for querying LIDAR point cloud and in/out functions to convert to PostGIS geometry * [h3-pg](https://github.com/zachasme/h3-pg) 4.1.4 for using Uber h3 api and converting h3 index representations to postgis geometry/geography/raster (raster support is new in this release). - * [MobilityDB](https://mobilitydb.com) [v1.3.0-alpha](https://github.com/MobilityDB/MobilityDB/releases/tag/v1.3.0-alpha) + * [MobilityDB](https://mobilitydb.com) [v1.3.0rc1](https://github.com/MobilityDB/MobilityDB/releases/tag/v1.3.0rc1) for managing trajectories. Includes many temporal spatial and non-spatial types and functions and operators for them. Refer to [Enabling PostGIS Extensions: MobilityDb](../enabling_postgis/#mobilitydb) for guidance. * [pgSphere](https://github.com/postgrespro/pgsphere)[1.5.2](https://github.com/postgrespro/pgsphere/releases/tag/1.5.2) for spherical geometries. (NEW in this release) ----------------------------------------------------------------------- Summary of changes: .../getting_started/install_windows/released_versions.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) hooks/post-receive -- postgis.net From git at osgeo.org Mon Mar 16 13:19:54 2026 From: git at osgeo.org (git at osgeo.org) Date: Mon, 16 Mar 2026 13:19:54 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-394-gb2b07453d Message-ID: <20260316201955.23EE21B9011@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via b2b07453dcfbe5c99c3e9d841adb8fe8ab44971e (commit) from 7c18321e17bfba6d24600e39d11271616ae71124 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit b2b07453dcfbe5c99c3e9d841adb8fe8ab44971e Author: Paul Ramsey Date: Mon Mar 16 13:19:48 2026 -0700 Build on latest Pg19 master diff --git a/postgis/flatgeobuf.c b/postgis/flatgeobuf.c index eb29f8920..ae3f8fb53 100644 --- a/postgis/flatgeobuf.c +++ b/postgis/flatgeobuf.c @@ -313,12 +313,12 @@ static void decode_properties(struct flatgeobuf_decode_ctx *ctx, Datum *values, break; } case flatgeobuf_column_type_byte: { - int8_t value; - if (offset + sizeof(int8_t) > size) + char value; + if (offset + sizeof(char) > size) elog(ERROR, "flatgeobuf: decode_properties: Invalid size for byte value"); - memcpy(&value, data + offset, sizeof(int8_t)); - values[ci] = Int8GetDatum(value); - offset += sizeof(int8_t); + memcpy(&value, data + offset, sizeof(char)); + values[ci] = CharGetDatum(value); + offset += sizeof(char); break; } case flatgeobuf_column_type_ubyte: { diff --git a/raster/rt_pg/rtpg_mapalgebra.c b/raster/rt_pg/rtpg_mapalgebra.c index bb173aa29..a97d98f0f 100644 --- a/raster/rt_pg/rtpg_mapalgebra.c +++ b/raster/rt_pg/rtpg_mapalgebra.c @@ -6568,6 +6568,7 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS) case ET_FIRST: i = 0; /* fall through */ + __attribute__((fallthrough)); case ET_SECOND: if (i > 1) i = 1; ----------------------------------------------------------------------- Summary of changes: postgis/flatgeobuf.c | 10 +++++----- raster/rt_pg/rtpg_mapalgebra.c | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Mon Mar 16 13:21:01 2026 From: git at osgeo.org (git at osgeo.org) Date: Mon, 16 Mar 2026 13:21:01 -0700 (PDT) Subject: [SCM] PostGIS branch stable-3.6 updated. 3.6.2-4-gd3171abe3 Message-ID: <20260316202101.BB43D1B972B@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, stable-3.6 has been updated via d3171abe3b30c898bd15e37b072fb34c3b6cc675 (commit) from 6d032d7f203aca9e77badfcc26e9c84968cd3655 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit d3171abe3b30c898bd15e37b072fb34c3b6cc675 Author: Paul Ramsey Date: Mon Mar 16 13:20:54 2026 -0700 Build on latest Pg19 master diff --git a/postgis/flatgeobuf.c b/postgis/flatgeobuf.c index eb29f8920..ae3f8fb53 100644 --- a/postgis/flatgeobuf.c +++ b/postgis/flatgeobuf.c @@ -313,12 +313,12 @@ static void decode_properties(struct flatgeobuf_decode_ctx *ctx, Datum *values, break; } case flatgeobuf_column_type_byte: { - int8_t value; - if (offset + sizeof(int8_t) > size) + char value; + if (offset + sizeof(char) > size) elog(ERROR, "flatgeobuf: decode_properties: Invalid size for byte value"); - memcpy(&value, data + offset, sizeof(int8_t)); - values[ci] = Int8GetDatum(value); - offset += sizeof(int8_t); + memcpy(&value, data + offset, sizeof(char)); + values[ci] = CharGetDatum(value); + offset += sizeof(char); break; } case flatgeobuf_column_type_ubyte: { diff --git a/raster/rt_pg/rtpg_mapalgebra.c b/raster/rt_pg/rtpg_mapalgebra.c index c1cac17c3..e08c65975 100644 --- a/raster/rt_pg/rtpg_mapalgebra.c +++ b/raster/rt_pg/rtpg_mapalgebra.c @@ -6544,6 +6544,7 @@ Datum RASTER_mapAlgebra2(PG_FUNCTION_ARGS) case ET_FIRST: i = 0; /* fall through */ + __attribute__((fallthrough)); case ET_SECOND: if (i > 1) i = 1; ----------------------------------------------------------------------- Summary of changes: postgis/flatgeobuf.c | 10 +++++----- raster/rt_pg/rtpg_mapalgebra.c | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) hooks/post-receive -- PostGIS From git at osgeo.org Mon Mar 16 18:16:39 2026 From: git at osgeo.org (git at osgeo.org) Date: Mon, 16 Mar 2026 18:16:39 -0700 (PDT) Subject: [SCM] PostGIS branch master updated. 3.6.0rc2-395-ge27a0d0ba Message-ID: <20260317011639.CEAF91B8BA7@trac.osgeo.org> This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "PostGIS". The branch, master has been updated via e27a0d0ba496937ed6676ac7e84e76b821a6b172 (commit) from b2b07453dcfbe5c99c3e9d841adb8fe8ab44971e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e27a0d0ba496937ed6676ac7e84e76b821a6b172 Author: Teramoto Ikuhiro Date: Tue Mar 17 00:16:44 2026 +0000 Translated PostGIS Manual using Weblate (Japanese) Currently translated at 99.9% (5888 of 5893 strings) Translation: postgis/PostGIS Manual Translate-URL: https://weblate.osgeo.org/projects/postgis/postgis-manual/ja/ diff --git a/doc/po/ja/postgis-manual.po b/doc/po/ja/postgis-manual.po index b512408b0..9815baf0c 100644 --- a/doc/po/ja/postgis-manual.po +++ b/doc/po/ja/postgis-manual.po @@ -10,7 +10,7 @@ msgstr "" "Project-Id-Version: postgis 3.5\n" "Report-Msgid-Bugs-To: https://bugs.kde.org\n" "POT-Creation-Date: 2025-11-13 16:23+0000\n" -"PO-Revision-Date: 2026-03-05 01:51+0000\n" +"PO-Revision-Date: 2026-03-17 01:16+0000\n" "Last-Translator: Teramoto Ikuhiro \n" "Language-Team: Japanese \n" @@ -19,7 +19,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.16.1\n" +"X-Generator: Weblate 5.16.2\n" #. Tag: chapter #, no-c-format @@ -9059,7 +9059,7 @@ msgstr "" "??????????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "Currently, the make check relies on the PATH " "and PGPORT environment variables when performing the checks - " @@ -9069,12 +9069,12 @@ msgid "" "installation during configuration or be prepared to deal with the impending " "headaches." msgstr "" -"??????make check??????????? ???" -"?PATH?PGPORT????????" -"????????????????--with-pgconfig?????" -"???PostgreSQL????????PATH??????" +"??????make check???????????????" +"PATH?PGPORT??????????????????????" +"??PostgreSQL???????????--with-" +"pgconfig??????????????????PATH??????" "??????????????????PostgreSQL???????????????" -"????????????????????????????" +"????????????????????????????????" #. Tag: para #, no-c-format @@ -34890,14 +34890,15 @@ msgstr "" "Arguments\" (??: ??????????????SQL???)??????????" #. Tag: para -#, fuzzy, no-c-format +#, no-c-format msgid "" "The text[] argument to the callbackfunc is " "required, regardless of whether you choose to pass any arguments to the " "callback function for processing or not." msgstr "" -"callbackfunc??text[]???????????" -"??????????????????????????????????" +"text[]???callbackfunc?????????" +"??????????????????????????????????????" +"????" #. Tag: para #, no-c-format ----------------------------------------------------------------------- Summary of changes: doc/po/ja/postgis-manual.po | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) hooks/post-receive -- PostGIS