[SCM] PostGIS branch master updated. 3.6.0rc2-687-g4e470f153
git at osgeo.org
git at osgeo.org
Tue Jun 30 13:50:51 PDT 2026
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 4e470f1534795ae4a4c52ad5ad35b8744af9d708 (commit)
via d7754dccc14914701e4a913473225bdefe5ce88a (commit)
via 4fcff9df99ea140f0062047b91dc694a5647c624 (commit)
via 356914a6311a2606de1e9089fc2ced8c4064e3f3 (commit)
via b006ec7715a91c4f6dc9ffb50e608b31b2a3087b (commit)
via 99c75c3f5ad5e7ab66f17a3ec23e46b87d12a82b (commit)
via 0e07c23d019a731a2e95c1a366510a4cdade4bd7 (commit)
via 6db6b531f34aa23a775548f98b761ea624930b82 (commit)
via a8683ba6ead9f81c08a13cb54fc770fbe452c5d3 (commit)
from 57fd420a7e9843c925b241c726ba436ad9f2aeb9 (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 4e470f1534795ae4a4c52ad5ad35b8744af9d708
Author: Darafei Praliaskouski <me at komzpa.net>
Date: Tue Jun 30 01:33:41 2026 +0400
ci: keep Winnie SFCGAL runs optional
(cherry picked from commit e06ab2f4f307f80a489d56a9c6ae4c642d480537)
diff --git a/ci/winnie/regress_postgis.sh b/ci/winnie/regress_postgis.sh
index 8ae8cea39..deba4fdb1 100644
--- a/ci/winnie/regress_postgis.sh
+++ b/ci/winnie/regress_postgis.sh
@@ -77,6 +77,11 @@ fi
#LDFLAGS="-Wl,--enable-auto-import -L${PGPATH}/lib -L${PROJECTS}/gdal/rel-${GDAL_VER}w${OS_BUILD}${GCC_TYPE}/lib -L${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD}${GCC_TYPE}/lib" \
+SFCGAL_CONFIGURE_ARG=""
+if [ -n "${SFCGAL_VER:-}" ]; then
+ SFCGAL_CONFIGURE_ARG="--with-sfcgal=${PROJECTS}/CGAL/rel-sfcgal-${SFCGAL_VER}w${OS_BUILD}${GCC_TYPE}/bin/sfcgal-config"
+fi
+
CPPFLAGS="-I${PGPATH}/include -I${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD}${GCC_TYPE}/include" \
LDFLAGS="-Wl,--enable-auto-import -L${PGPATH}/lib -L${LZ4_PATH}/lib -L${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD}${GCC_TYPE}/lib -L${PROJECTS}/zlib/rel-zlib-${ZLIB_VER}w${OS_BUILD}${GCC_TYPE}/lib" \
./configure \
@@ -85,7 +90,7 @@ LDFLAGS="-Wl,--enable-auto-import -L${PGPATH}/lib -L${LZ4_PATH}/lib -L${PROJECTS
--with-geosconfig=${PROJECTS}/geos/rel-${GEOS_VER}w${OS_BUILD}${GCC_TYPE}/bin/geos-config \
--with-libiconv=${PROJECTS}/rel-libiconv-${ICON_VER}w${OS_BUILD}${GCC_TYPE} \
--with-gui --with-gettext=no \
- --with-sfcgal=${PROJECTS}/CGAL/rel-sfcgal-${SFCGAL_VER}w${OS_BUILD}${GCC_TYPE}/bin/sfcgal-config \
+ ${SFCGAL_CONFIGURE_ARG} \
--prefix=${PROJECTS}/postgis/liblwgeom-${POSTGIS_VER}w${OS_BUILD}${GCC_TYPE} \
${EXTRA_CONFIGURE_ARGS}
@@ -117,7 +122,9 @@ if [ "${MAKE_EXTENSION:-0}" == "1" ]; then
cp -r topology/*.dll ${PGPATHEDB}/lib
fi
cp postgis/postgis*.dll ${PGPATHEDB}/lib
- cp sfcgal/*.dll ${PGPATHEDB}/lib
+ if [ -n "${SFCGAL_VER:-}" ]; then
+ cp sfcgal/*.dll ${PGPATHEDB}/lib
+ fi
if [ "${REGRESS_WITHOUT_RASTER:-0}" == "0" ]; then
cp raster/rt_pg/postgis_raster-*.dll ${PGPATHEDB}/lib
@@ -135,7 +142,10 @@ value=${value//UPGRADEABLE_VERSIONS = /}
#echo $value
export UPGRADEABLE_VERSIONS=$value
export WIN_RELEASED_VERSIONS="2.0.0 2.0.1 2.0.3 2.0.4 2.0.6 2.1.4 2.1.7 2.1.8 2.2.0 2.2.3 2.3.0 2.3.7 2.4.0 2.4.4"
-export extensions_to_install="postgis postgis_sfcgal"
+export extensions_to_install="postgis"
+if [ -n "${SFCGAL_VER:-}" ]; then
+ extensions_to_install="${extensions_to_install} postgis_sfcgal"
+fi
if [ "${REGRESS_WITHOUT_TOPOLOGY:-0}" == "0" ]; then
extensions_to_install="${extensions_to_install} postgis_topology"
commit d7754dccc14914701e4a913473225bdefe5ce88a
Author: Darafei Praliaskouski <me at komzpa.net>
Date: Tue Jun 16 23:10:59 2026 +0400
ci: harden utility scripts and doc version list
(cherry picked from commit cd61527547061a91866fdac44b4c48bc9bdafb62)
diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml
index 62eb71c43..6292eeb96 100644
--- a/.github/workflows/codespell.yml
+++ b/.github/workflows/codespell.yml
@@ -25,13 +25,16 @@ jobs:
sudo apt-get install -y --no-install-recommends \
autoconf automake libtool pkg-config \
libgeos-dev libproj-dev libxml2-dev \
- libxml2-utils docbook-xml docbook-xsl docbook-xsl-ns xsltproc
+ libxml2-utils docbook-xml docbook-xsl docbook-xsl-ns xsltproc \
+ python3-venv
# 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
+ python3 -m venv "${RUNNER_TEMP}/codespell-venv"
+ "${RUNNER_TEMP}/codespell-venv/bin/python" -m pip install 'codespell==2.4.1'
- name: 'Build & Test'
run: |
+ export PATH="${RUNNER_TEMP}/codespell-venv/bin:${PATH}"
codespell --version
./autogen.sh
./configure --without-raster --without-topology --without-sfcgal --without-json --without-protobuf
diff --git a/ci/winnie/regress_postgis.sh b/ci/winnie/regress_postgis.sh
index 241a261f3..8ae8cea39 100644
--- a/ci/winnie/regress_postgis.sh
+++ b/ci/winnie/regress_postgis.sh
@@ -60,15 +60,15 @@ sh autogen.sh
# excluding topology cause it's erroring out on some tests
#EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --without-topology"
-if [ $INCLUDE_MINOR_LIB == "1" ]; then
+if [ "${INCLUDE_MINOR_LIB:-0}" == "1" ]; then
EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --with-library-minor-version"
fi
-if [ $REGRESS_WITHOUT_TOPOLOGY == "1" ]; then
+if [ "${REGRESS_WITHOUT_TOPOLOGY:-0}" == "1" ]; then
EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --without-topology"
fi
-if [ $REGRESS_WITHOUT_RASTER == "1" ]; then
+if [ "${REGRESS_WITHOUT_RASTER:-0}" == "1" ]; then
EXTRA_CONFIGURE_ARGS="${EXTRA_CONFIGURE_ARGS} --without-raster"
fi
@@ -99,12 +99,12 @@ make -j 2
make install
# don't run tests twice. Only run regular if extension test is not asked for
-if [ "$MAKE_EXTENSION" == "0" ]; then
+if [ "${MAKE_EXTENSION:-0}" == "0" ]; then
make check RUNTESTFLAGS=-v
fi
-if [ "$MAKE_EXTENSION" == "1" ]; then
+if [ "${MAKE_EXTENSION:-0}" == "1" ]; then
export PGUSER=postgres
#need to copy install files to EDB install (since not done by make install
cd ${POSTGIS_SRC}
@@ -113,13 +113,13 @@ if [ "$MAKE_EXTENSION" == "1" ]; then
#strip raster/rt_pg/postgis_raster-*.dll
#strip sfcgal/*.dll
- if [ $REGRESS_WITHOUT_TOPOLOGY == "0" ]; then
+ if [ "${REGRESS_WITHOUT_TOPOLOGY:-0}" == "0" ]; then
cp -r topology/*.dll ${PGPATHEDB}/lib
fi
cp postgis/postgis*.dll ${PGPATHEDB}/lib
cp sfcgal/*.dll ${PGPATHEDB}/lib
- if [ $REGRESS_WITHOUT_RASTER == "0" ]; then
+ if [ "${REGRESS_WITHOUT_RASTER:-0}" == "0" ]; then
cp raster/rt_pg/postgis_raster-*.dll ${PGPATHEDB}/lib
fi
@@ -137,11 +137,11 @@ export UPGRADEABLE_VERSIONS=$value
export WIN_RELEASED_VERSIONS="2.0.0 2.0.1 2.0.3 2.0.4 2.0.6 2.1.4 2.1.7 2.1.8 2.2.0 2.2.3 2.3.0 2.3.7 2.4.0 2.4.4"
export extensions_to_install="postgis postgis_sfcgal"
-if [ $REGRESS_WITHOUT_TOPOLOGY == "0" ]; then
+if [ "${REGRESS_WITHOUT_TOPOLOGY:-0}" == "0" ]; then
extensions_to_install="${extensions_to_install} postgis_topology"
fi
-if [ $REGRESS_WITHOUT_RASTER == "0" ]; then
+if [ "${REGRESS_WITHOUT_RASTER:-0}" == "0" ]; then
extensions_to_install="${extensions_to_install} postgis_raster"
fi
@@ -165,14 +165,14 @@ cp -r extensions/*/*.control ${PGPATHEDB}/share/extension
make check RUNTESTFLAGS="--extension -v"
-if [ "$UPGRADE_TEST" == "1" ]; then
+if [ "${UPGRADE_TEST:-0}" == "1" ]; then
export CURRENTVERSION=${POSTGIS_MAJOR_VERSION}.${POSTGIS_MINOR_VERSION}.${POSTGIS_MICRO_VERSION}
RUNTESTFLAGS='--extension' ${POSTGIS_SRC}/utils/check_all_upgrades.sh -s "${CURRENTVERSION}" --skip "unpackaged"
fi
fi
-if [ "$DUMP_RESTORE" == "1" ]; then
+if [ "${DUMP_RESTORE:-0}" == "1" ]; then
echo "Dump restore test"
make install
make check RUNTESTFLAGS="-v --dumprestore"
@@ -181,7 +181,7 @@ if [ "$DUMP_RESTORE" == "1" ]; then
fi
fi
-if [ "$MAKE_GARDEN" == "1" ]; then
+if [ "${MAKE_GARDEN:-0}" == "1" ]; then
export PGUSER=postgres
make garden
fi
diff --git a/doc/xsl-config.xml b/doc/xsl-config.xml
index 686de356e..69a876d56 100644
--- a/doc/xsl-config.xml
+++ b/doc/xsl-config.xml
@@ -23,7 +23,6 @@
<postgis_versions>
<v>3.7</v>
<v>3.6</v>
- <v>3.6</v>
<v>3.5</v>
<v>3.4</v>
<v>3.3</v>
diff --git a/utils/check_all_upgrades.sh b/utils/check_all_upgrades.sh
index 5fac212ea..8e02e21a1 100755
--- a/utils/check_all_upgrades.sh
+++ b/utils/check_all_upgrades.sh
@@ -3,7 +3,7 @@
EXIT_ON_FIRST_FAILURE=0
EXTDIR=`pg_config --sharedir`/extension/
CTBDIR=`pg_config --sharedir`/contrib/
-TMPDIR=/tmp/check_all_upgrades-$$-tmp
+TMPDIR=$(mktemp -d "${TMPDIR:-/tmp}/check_all_upgrades.XXXXXX") || exit 1
PGVER=`pg_config --version | awk '{print $2}'`
PGVER_MAJOR=$(echo "${PGVER}" | sed 's/\.[^\.]*//' | sed 's/\(alpha\|beta\|rc\).*//' )
SKIP_LABEL_REGEXP=
@@ -51,11 +51,10 @@ if test -z "$to_version_param"; then
exit 1
fi
-mkdir -p ${TMPDIR}
cleanup()
{
echo "Cleaning up"
- rm -rf ${TMPDIR}
+ rm -rf "${TMPDIR}"
}
trap 'cleanup' EXIT
@@ -182,23 +181,32 @@ compatible_upgrade()
fi
}
+run_check()
+{
+ if command -v unbuffer >/dev/null 2>&1; then
+ unbuffer ${MAKE} -C "${REGDIR}" check "TESTS=${SRCDIR}/regress/core/regress.sql" ${MAKE_ARGS}
+ else
+ ${MAKE} -C "${REGDIR}" check "TESTS=${SRCDIR}/regress/core/regress.sql" ${MAKE_ARGS}
+ fi
+}
+
check_downgrade()
{
RUNTESTFLAGS="-v --extension --upgrade-path=${UPGRADE_PATH} ${USERTESTFLAGS}" \
- unbuffer ${MAKE} -C ${REGDIR} check "TESTS=${SRCDIR}/regress/core/regress.sql" ${MAKE_ARGS} > ${TMPDIR}/log 2>&1
+ run_check > "${TMPDIR}/log" 2>&1
if test $? = 0; then
echo "FAIL: ${test_label} did not error out:"
- tail ${TMPDIR}/log
+ tail "${TMPDIR}/log"
failed
else
- ERR=$( grep 'ERROR:.*Downgrade .* forbidden' ${TMPDIR}/log )
- test -n "$ERR" && {
+ ERR=$( grep 'ERROR:.*Downgrade .* forbidden' "${TMPDIR}/log" )
+ if test -n "$ERR"; then
echo "PASS: ${test_label} gave $ERR"
- } || {
+ else
echo "FAIL: ${test_label} gave some other error:"
- tail ${TMPDIR}/log
+ tail "${TMPDIR}/log"
failed
- }
+ fi
fi
}
commit 4fcff9df99ea140f0062047b91dc694a5647c624
Author: Darafei Praliaskouski <me at komzpa.net>
Date: Fri Jun 19 14:29:33 2026 +0400
postgis: test BRIN mergeability support procs
(cherry picked from commit 564e99eb99bb4f37687f46d62862c0b5b85a1efe)
diff --git a/regress/core/regress_brin_index_3d.sql b/regress/core/regress_brin_index_3d.sql
index ccfc87403..cd0fb6081 100644
--- a/regress/core/regress_brin_index_3d.sql
+++ b/regress/core/regress_brin_index_3d.sql
@@ -28,6 +28,16 @@ $$;
-- BRIN indexes
+SELECT 'brin_proc_12', opc.opcname, amp.amprocnum, pro.proname
+FROM pg_catalog.pg_opclass AS opc
+JOIN pg_catalog.pg_amproc AS amp
+ ON amp.amprocfamily = opc.opcfamily
+JOIN pg_catalog.pg_proc AS pro
+ ON pro.oid = amp.amproc
+WHERE opc.opcname IN ('brin_geometry_inclusion_ops_3d', 'brin_geometry_inclusion_ops_4d')
+ AND amp.amprocnum = 12
+ORDER BY opc.opcname;
+
-- 2D
CREATE INDEX brin_2d on test using brin (the_geom) WITH (pages_per_range = 10);
diff --git a/regress/core/regress_brin_index_3d_expected b/regress/core/regress_brin_index_3d_expected
index b80bee3ec..f3874881b 100644
--- a/regress/core/regress_brin_index_3d_expected
+++ b/regress/core/regress_brin_index_3d_expected
@@ -1,3 +1,5 @@
+brin_proc_12|brin_geometry_inclusion_ops_3d|12|geom3d_brin_inclusion_mergeable
+brin_proc_12|brin_geometry_inclusion_ops_4d|12|geom4d_brin_inclusion_mergeable
scan_seq|Seq Scan
1250|POINT Z (125 125 125)
1251|POINT Z (125.1 125.1 125.1)
diff --git a/regress/core/regress_brin_index_geography.sql b/regress/core/regress_brin_index_geography.sql
index 6ba5e1f41..1eacba73b 100644
--- a/regress/core/regress_brin_index_geography.sql
+++ b/regress/core/regress_brin_index_geography.sql
@@ -27,6 +27,15 @@ $$;
-- BRIN indexes
+SELECT 'brin_proc_12', opc.opcname, amp.amprocnum, pro.proname
+FROM pg_catalog.pg_opclass AS opc
+JOIN pg_catalog.pg_amproc AS amp
+ ON amp.amprocfamily = opc.opcfamily
+JOIN pg_catalog.pg_proc AS pro
+ ON pro.oid = amp.amproc
+WHERE opc.opcname = 'brin_geography_inclusion_ops'
+ AND amp.amprocnum = 12;
+
-- 2D
CREATE INDEX brin_geog on test using brin (the_geog) WITH (pages_per_range = 10);
diff --git a/regress/core/regress_brin_index_geography_expected b/regress/core/regress_brin_index_geography_expected
index c83d7b9c9..90420fcf6 100644
--- a/regress/core/regress_brin_index_geography_expected
+++ b/regress/core/regress_brin_index_geography_expected
@@ -1,3 +1,4 @@
+brin_proc_12|brin_geography_inclusion_ops|12|geog_brin_inclusion_mergeable
scan_seq|Seq Scan
42.01|POINT Z (42.01 42.01 42.01)
42.03|POINT Z (42.03 42.03 42.03)
commit 356914a6311a2606de1e9089fc2ced8c4064e3f3
Author: Darafei Praliaskouski <me at komzpa.net>
Date: Fri Jun 19 01:15:13 2026 +0400
postgis: upgrade BRIN mergeability support procs
(cherry picked from commit 77c6842375bc693f5a7844b15374847355177085)
diff --git a/NEWS b/NEWS
index 8c00aab71..a636077cb 100644
--- a/NEWS
+++ b/NEWS
@@ -142,6 +142,8 @@ To take advantage of all postgis_sfcgal extension features SFCGAL 2.3+ is needed
detoasting them (Darafei Praliaskouski)
- GH-889, ST_Relate pattern inversion avoids out-of-bounds access on
short DE-9IM patterns (Darafei Praliaskouski)
+ - GH-890, Avoid GIDX BRIN summary merges across mismatched dimensions
+ (Darafei Praliaskouski)
- 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
diff --git a/postgis/postgis_after_upgrade.sql b/postgis/postgis_after_upgrade.sql
index 7d86c9a5b..4a867234b 100644
--- a/postgis/postgis_after_upgrade.sql
+++ b/postgis/postgis_after_upgrade.sql
@@ -341,6 +341,58 @@ BEGIN
END;
END IF;
+ -- Check if the mergeability function is already associated with any operator class
+ IF NOT EXISTS (
+ SELECT 1
+ FROM pg_catalog.pg_amproc
+ WHERE amproc::text = 'geom3d_brin_inclusion_mergeable'
+ ) THEN
+ BEGIN
+ -- Create a temporary operator class with the new function
+ CREATE OPERATOR CLASS brin_geometry_inclusion_ops_3d_temp
+ FOR TYPE geometry USING brin AS
+ FUNCTION 12 geom3d_brin_inclusion_mergeable(internal, internal);
+
+ -- Change the pg_amproc association to the existing opclass
+ WITH a AS (
+ SELECT n.oid AS oid_nfamily, o.oid AS oid_ofamily
+ FROM pg_catalog.pg_opfamily AS n
+ CROSS JOIN (
+ SELECT oid FROM pg_catalog.pg_opfamily
+ WHERE opfname = 'brin_geometry_inclusion_ops_3d_temp'
+ ) AS o
+ WHERE n.opfname = 'brin_geometry_inclusion_ops_3d'
+ ), amupdate AS (
+ UPDATE pg_catalog.pg_amproc AS amp
+ SET amprocfamily = a.oid_nfamily
+ FROM a
+ WHERE
+ amp.amprocfamily = a.oid_ofamily
+ AND amp.amproc::text = 'geom3d_brin_inclusion_mergeable'
+ RETURNING amp.*
+ )
+ -- Change the opclass dependency to the existing one
+ UPDATE pg_depend AS d
+ SET refobjid = (
+ SELECT n.oid
+ FROM pg_catalog.pg_opclass AS n
+ WHERE opcname = 'brin_geometry_inclusion_ops_3d'
+ )
+ FROM amupdate
+ WHERE d.objid = amupdate.oid AND
+ refobjid = (
+ SELECT o.oid
+ FROM pg_catalog.pg_opclass AS o
+ WHERE opcname = 'brin_geometry_inclusion_ops_3d_temp'
+ );
+
+ -- Dropping the autogenerated temporary family which cascades to temporary class
+ DROP OPERATOR FAMILY brin_geometry_inclusion_ops_3d_temp USING brin;
+ EXCEPTION WHEN OTHERS THEN
+ RAISE EXCEPTION 'Could not add geom3d_brin_inclusion_mergeable to brin_geometry_inclusion_ops_3d class: %', SQLERRM;
+ END;
+ END IF;
+
-- Check if the function is already associated with any operator class
IF NOT EXISTS (
SELECT 1
@@ -393,6 +445,60 @@ BEGIN
END;
END IF;
+ -- Check if the mergeability function is already associated with any operator class
+ IF NOT EXISTS (
+ SELECT 1
+ FROM pg_catalog.pg_amproc
+ WHERE amproc::text = 'geom4d_brin_inclusion_mergeable'
+ ) THEN
+ BEGIN
+ -- Create a temporary operator class with the new function
+ CREATE OPERATOR CLASS brin_geometry_inclusion_ops_4d_temp
+ FOR TYPE geometry USING brin AS
+ FUNCTION 12 geom4d_brin_inclusion_mergeable(internal, internal);
+
+ -- Change the pg_amproc association to the existing opclass
+ WITH a AS (
+ SELECT n.oid AS oid_nfamily, o.oid AS oid_ofamily
+ FROM pg_catalog.pg_opfamily AS n
+ CROSS JOIN (
+ SELECT oid FROM pg_catalog.pg_opfamily
+ WHERE opfname = 'brin_geometry_inclusion_ops_4d_temp'
+ ) AS o
+ WHERE n.opfname = 'brin_geometry_inclusion_ops_4d'
+ ) , amupdate AS (
+ UPDATE pg_catalog.pg_amproc AS amp
+ SET amprocfamily = a.oid_nfamily
+ FROM a
+ WHERE
+ amp.amprocfamily = a.oid_ofamily
+ AND amp.amproc::text = 'geom4d_brin_inclusion_mergeable'
+ RETURNING amp.*
+ )
+ -- Change the opclass dependency to the existing one
+ UPDATE pg_depend AS d
+ SET refobjid = (
+ SELECT n.oid
+ FROM pg_catalog.pg_opclass AS n
+ WHERE opcname = 'brin_geometry_inclusion_ops_4d'
+ )
+ FROM amupdate
+ WHERE d.objid = amupdate.oid AND
+ refobjid = (
+ SELECT o.oid
+ FROM pg_catalog.pg_opclass AS o
+ WHERE opcname = 'brin_geometry_inclusion_ops_4d_temp'
+ );
+
+ -- Dropping the autogenerated temporary family also drops the temporary class
+ DROP OPERATOR FAMILY brin_geometry_inclusion_ops_4d_temp USING brin;
+ EXCEPTION WHEN OTHERS THEN
+ RAISE EXCEPTION
+ 'Could not add geom4d_brin_inclusion_mergeable to brin_geometry_inclusion_ops_4d class: %',
+ SQLERRM;
+ END;
+ END IF;
+
-- Check if the function is already associated with any operator class
IF NOT EXISTS (
SELECT 1
@@ -503,6 +609,63 @@ BEGIN
SQLERRM;
END;
END IF;
+
+-- geography brin mergeability
+ -- Check if the function 'geog_brin_inclusion_mergeable' already exists
+ IF NOT EXISTS (
+ SELECT 1
+ FROM pg_catalog.pg_amproc
+ WHERE amproc::text = 'geog_brin_inclusion_mergeable'
+ ) THEN
+ BEGIN
+ -- Create a temporary operator class for 'brin_geography_inclusion_ops_temp'
+ CREATE OPERATOR CLASS brin_geography_inclusion_ops_temp
+ FOR TYPE geography USING brin AS
+ FUNCTION 12 geog_brin_inclusion_mergeable(internal, internal);
+
+ -- find current and new operator family OIDs
+ WITH a AS (
+ SELECT n.oid AS oid_nfamily, o.oid AS oid_ofamily
+ FROM pg_catalog.pg_opfamily AS n
+ CROSS JOIN (
+ SELECT oid
+ FROM pg_catalog.pg_opfamily
+ WHERE opfname = 'brin_geography_inclusion_ops_temp'
+ ) AS o
+ WHERE n.opfname = 'brin_geography_inclusion_ops'
+ ),
+ -- Update the amprocfamily in pg_amproc
+ amupdate AS (
+ UPDATE pg_catalog.pg_amproc AS amp
+ SET amprocfamily = a.oid_nfamily
+ FROM a
+ WHERE amp.amprocfamily = a.oid_ofamily AND
+ amp.amproc::text = 'geog_brin_inclusion_mergeable'
+ RETURNING amp.*
+ )
+ -- Update dependencies in pg_depend to the existing operator class
+ UPDATE pg_depend AS d
+ SET refobjid = (
+ SELECT n.oid
+ FROM pg_catalog.pg_opclass AS n
+ WHERE opcname = 'brin_geography_inclusion_ops'
+ )
+ FROM amupdate
+ WHERE d.objid = amupdate.oid AND
+ refobjid = (
+ SELECT o.oid
+ FROM pg_catalog.pg_opclass AS o
+ WHERE opcname = 'brin_geography_inclusion_ops_temp'
+ );
+
+ -- Drop the temporary operator family after use
+ DROP OPERATOR FAMILY brin_geography_inclusion_ops_temp USING brin;
+ EXCEPTION WHEN OTHERS THEN
+ RAISE EXCEPTION
+ 'Could not add geog_brin_inclusion_mergeable to brin_geography_inclusion_ops class: %',
+ SQLERRM;
+ END;
+ END IF;
END;
$$;
commit b006ec7715a91c4f6dc9ffb50e608b31b2a3087b
Author: Darafei Praliaskouski <me at komzpa.net>
Date: Fri Jun 19 01:15:13 2026 +0400
Guard GIDX BRIN merges by dimension
(cherry picked from commit 9fea3b87cdb8dc1cddedcc140687e5285a7292c7)
diff --git a/postgis/brin_nd.c b/postgis/brin_nd.c
index 246be78de..2cfb79ea4 100644
--- a/postgis/brin_nd.c
+++ b/postgis/brin_nd.c
@@ -17,6 +17,7 @@ static Datum gidx_brin_inclusion_add_value(
static GIDX * gidx_brin_inclusion_merge(
GIDX *gidx_key, GIDX *gidx_geom);
+static bool gidx_brin_inclusion_mergeable(GIDX *gidx_key, GIDX *gidx_geom);
/*
* As for the GiST case, geographies are converted into GIDX before
@@ -195,6 +196,9 @@ gidx_brin_inclusion_add_value(__attribute__((__unused__)) BrinDesc *bdesc,
static GIDX *
gidx_brin_inclusion_merge(GIDX *gidx_key, GIDX *gidx_geom)
{
+ if (!gidx_brin_inclusion_mergeable(gidx_key, gidx_geom))
+ return gidx_key;
+
if (!gidx_contains(gidx_key, gidx_geom))
{
for (uint32_t i = 0; i < GIDX_NDIMS(gidx_key); i++)
@@ -211,6 +215,12 @@ gidx_brin_inclusion_merge(GIDX *gidx_key, GIDX *gidx_geom)
return gidx_key;
}
+static bool
+gidx_brin_inclusion_mergeable(GIDX *gidx_key, GIDX *gidx_geom)
+{
+ return GIDX_NDIMS(gidx_key) == GIDX_NDIMS(gidx_geom);
+}
+
PG_FUNCTION_INFO_V1(geog_brin_inclusion_merge);
Datum geog_brin_inclusion_merge(PG_FUNCTION_ARGS)
{
@@ -220,6 +230,16 @@ Datum geog_brin_inclusion_merge(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(gidx_brin_inclusion_merge(key, geom));
}
+PG_FUNCTION_INFO_V1(geog_brin_inclusion_mergeable);
+Datum
+geog_brin_inclusion_mergeable(PG_FUNCTION_ARGS)
+{
+ GIDX *key = (GIDX *)PG_GETARG_POINTER(0);
+ GIDX *geom = (GIDX *)PG_GETARG_POINTER(1);
+
+ PG_RETURN_BOOL(gidx_brin_inclusion_mergeable(key, geom));
+}
+
PG_FUNCTION_INFO_V1(geom3d_brin_inclusion_merge);
Datum geom3d_brin_inclusion_merge(PG_FUNCTION_ARGS)
{
@@ -229,6 +249,16 @@ Datum geom3d_brin_inclusion_merge(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(gidx_brin_inclusion_merge(key, geom));
}
+PG_FUNCTION_INFO_V1(geom3d_brin_inclusion_mergeable);
+Datum
+geom3d_brin_inclusion_mergeable(PG_FUNCTION_ARGS)
+{
+ GIDX *key = (GIDX *)PG_GETARG_POINTER(0);
+ GIDX *geom = (GIDX *)PG_GETARG_POINTER(1);
+
+ PG_RETURN_BOOL(gidx_brin_inclusion_mergeable(key, geom));
+}
+
PG_FUNCTION_INFO_V1(geom4d_brin_inclusion_merge);
Datum geom4d_brin_inclusion_merge(PG_FUNCTION_ARGS)
{
@@ -238,4 +268,12 @@ Datum geom4d_brin_inclusion_merge(PG_FUNCTION_ARGS)
PG_RETURN_POINTER(gidx_brin_inclusion_merge(key, geom));
}
+PG_FUNCTION_INFO_V1(geom4d_brin_inclusion_mergeable);
+Datum
+geom4d_brin_inclusion_mergeable(PG_FUNCTION_ARGS)
+{
+ GIDX *key = (GIDX *)PG_GETARG_POINTER(0);
+ GIDX *geom = (GIDX *)PG_GETARG_POINTER(1);
+ PG_RETURN_BOOL(gidx_brin_inclusion_mergeable(key, geom));
+}
diff --git a/postgis/geography_brin.sql.in b/postgis/geography_brin.sql.in
index 694e0aa92..f9760ed37 100644
--- a/postgis/geography_brin.sql.in
+++ b/postgis/geography_brin.sql.in
@@ -65,6 +65,12 @@ RETURNS internal
AS 'MODULE_PATHNAME','geog_brin_inclusion_merge'
LANGUAGE 'c' PARALLEL SAFE;
+-- Availability: 3.7.0
+CREATE OR REPLACE FUNCTION geog_brin_inclusion_mergeable(internal, internal)
+RETURNS boolean
+ AS 'MODULE_PATHNAME','geog_brin_inclusion_mergeable'
+ LANGUAGE 'c' PARALLEL SAFE;
+
-- Availability: 2.3.0
CREATE OPERATOR CLASS brin_geography_inclusion_ops
DEFAULT FOR TYPE geography
@@ -74,6 +80,7 @@ CREATE OPERATOR CLASS brin_geography_inclusion_ops
FUNCTION 3 brin_inclusion_consistent(internal, internal, internal),
FUNCTION 4 brin_inclusion_union(internal, internal, internal),
FUNCTION 11 geog_brin_inclusion_merge(internal, internal),
+ FUNCTION 12 geog_brin_inclusion_mergeable(internal, internal),
OPERATOR 3 &&(geography, geography),
OPERATOR 3 &&(geography, gidx),
OPERATOR 3 &&(gidx, geography),
diff --git a/postgis/postgis_brin.sql.in b/postgis/postgis_brin.sql.in
index 9009a7420..73a4f469c 100644
--- a/postgis/postgis_brin.sql.in
+++ b/postgis/postgis_brin.sql.in
@@ -210,6 +210,12 @@ RETURNS internal
AS 'MODULE_PATHNAME','geom3d_brin_inclusion_merge'
LANGUAGE 'c' PARALLEL SAFE _COST_DEFAULT;
+-- Availability: 3.7.0
+CREATE OR REPLACE FUNCTION geom3d_brin_inclusion_mergeable(internal, internal)
+RETURNS boolean
+AS 'MODULE_PATHNAME','geom3d_brin_inclusion_mergeable'
+LANGUAGE 'c' PARALLEL SAFE _COST_DEFAULT;
+
-- Availability: 2.3.0
CREATE OR REPLACE FUNCTION geom4d_brin_inclusion_add_value(internal, internal, internal, internal)
RETURNS boolean
@@ -222,6 +228,12 @@ RETURNS internal
AS 'MODULE_PATHNAME','geom4d_brin_inclusion_merge'
LANGUAGE 'c' PARALLEL SAFE _COST_DEFAULT;
+-- Availability: 3.7.0
+CREATE OR REPLACE FUNCTION geom4d_brin_inclusion_mergeable(internal, internal)
+RETURNS boolean
+AS 'MODULE_PATHNAME','geom4d_brin_inclusion_mergeable'
+LANGUAGE 'c' PARALLEL SAFE _COST_DEFAULT;
+
-- Availability: 2.3.0
CREATE OPERATOR CLASS brin_geometry_inclusion_ops_2d
DEFAULT FOR TYPE geometry
@@ -259,6 +271,7 @@ CREATE OPERATOR CLASS brin_geometry_inclusion_ops_3d
FUNCTION 3 brin_inclusion_consistent(internal, internal, internal),
FUNCTION 4 brin_inclusion_union(internal, internal, internal),
FUNCTION 11 geom3d_brin_inclusion_merge(internal, internal),
+ FUNCTION 12 geom3d_brin_inclusion_mergeable(internal, internal),
OPERATOR 3 &&&(geometry, geometry),
OPERATOR 3 &&&(geometry, gidx),
OPERATOR 3 &&&(gidx, geometry),
@@ -278,6 +291,7 @@ CREATE OPERATOR CLASS brin_geometry_inclusion_ops_4d
FUNCTION 3 brin_inclusion_consistent(internal, internal, internal),
FUNCTION 4 brin_inclusion_union(internal, internal, internal),
FUNCTION 11 geom4d_brin_inclusion_merge(internal, internal),
+ FUNCTION 12 geom4d_brin_inclusion_mergeable(internal, internal),
OPERATOR 3 &&&(geometry, geometry),
OPERATOR 3 &&&(geometry, gidx),
OPERATOR 3 &&&(gidx, geometry),
commit 99c75c3f5ad5e7ab66f17a3ec23e46b87d12a82b
Author: Darafei Praliaskouski <me at komzpa.net>
Date: Tue Jun 16 17:16:28 2026 +0400
Guard ST_Relate pattern inversion
Short DE-9IM patterns can reach the prepared ST_Relate inversion path. Make the inversion length-aware so each matrix-position swap is guarded by the available pattern length instead of assuming a nine-character string.
Cache the pattern length once, and normalize pattern bytes through unsigned-char toupper() to avoid signed-char undefined behavior.
Closes https://github.com/postgis/postgis/pull/889
(cherry picked from commit 073f45c60c59efde4607fdb59eee410dc55116ee)
diff --git a/NEWS b/NEWS
index 3ea346e04..8c00aab71 100644
--- a/NEWS
+++ b/NEWS
@@ -140,6 +140,8 @@ To take advantage of all postgis_sfcgal extension features SFCGAL 2.3+ is needed
MinGW builds (Darafei Praliaskouski)
- GH-886, ST_ClusterRelateWin validates NULL relate matrices before
detoasting them (Darafei Praliaskouski)
+ - GH-889, ST_Relate pattern inversion avoids out-of-bounds access on
+ short DE-9IM patterns (Darafei Praliaskouski)
- 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
diff --git a/postgis/lwgeom_geos_predicates.c b/postgis/lwgeom_geos_predicates.c
index 2a283e17c..c400ebca7 100644
--- a/postgis/lwgeom_geos_predicates.c
+++ b/postgis/lwgeom_geos_predicates.c
@@ -22,6 +22,7 @@
* Copyright 2009-2014 Sandro Santilli <strk at kbt.io>
* Copyright 2008 Paul Ramsey <pramsey at cleverelephant.ca>
* Copyright 2001-2003 Refractions Research Inc.
+ * Copyright 2026 Darafei Praliaskouski <me at komzpa.net>
*
**********************************************************************/
@@ -951,14 +952,33 @@ Datum coveredby(PG_FUNCTION_ARGS)
* Flip the DE9IM matrix around the diagonal to
* account for flipping the order of the operands
* to the GEOSPreparedRelatePattern function.
+ *
+ * Short patterns are invalid for GEOS, but they can still reach this helper
+ * before GEOS reports the error, so every swapped position must be guarded by
+ * the actual pattern length.
*/
static void
-imInvert(char *im)
+imInvert(char *im, size_t len)
{
char t;
- t = im[1]; im[1] = im[3]; im[3] = t;
- t = im[2]; im[2] = im[6]; im[6] = t;
- t = im[5]; im[5] = im[7]; im[7] = t;
+ if (len > 3)
+ {
+ t = im[1];
+ im[1] = im[3];
+ im[3] = t;
+ }
+ if (len > 6)
+ {
+ t = im[2];
+ im[2] = im[6];
+ im[6] = t;
+ }
+ if (len > 7)
+ {
+ t = im[5];
+ im[5] = im[7];
+ im[7] = t;
+ }
}
#endif
@@ -975,7 +995,8 @@ Datum relate_pattern(PG_FUNCTION_ARGS)
PG_GETARG_DATUM(2), Int32GetDatum(9)));
char *im = text_to_cstring(imPtr);
int8_t result;
- uint32_t i;
+ size_t im_len = strlen(im);
+ size_t i;
#if POSTGIS_GEOS_VERSION >= 31300
PrepGeomCache *prep_cache;
#endif
@@ -985,8 +1006,8 @@ Datum relate_pattern(PG_FUNCTION_ARGS)
/*
** Need to make sure 't' and 'f' are upper-case before handing to GEOS
*/
- for (i = 0; i < strlen(im); i++)
- im[i] = toupper(im[i]);
+ for (i = 0; i < im_len; i++)
+ im[i] = toupper((unsigned char)im[i]);
initGEOS(lwpgnotice, lwgeom_geos_error);
@@ -1002,7 +1023,7 @@ Datum relate_pattern(PG_FUNCTION_ARGS)
else
{
g = POSTGIS2GEOS(geom1);
- imInvert(im);
+ imInvert(im, im_len);
}
if (!g) HANDLE_GEOS_ERROR("Geometry could not be converted to GEOS");
diff --git a/regress/core/relate.sql b/regress/core/relate.sql
index a7172a40d..107e91fe3 100644
--- a/regress/core/relate.sql
+++ b/regress/core/relate.sql
@@ -553,3 +553,9 @@ SELECT '552', ST_Relate('MULTIPOINT(20 20,80 70,140 120,200 170)','MULTIPOINT(80
SELECT '553', ST_Relate('MULTIPOINT(80 70,20 20,200 170,140 120)','MULTIPOINT(140 120,80 70)');
SELECT '554', ST_Relate('MULTIPOINT(80 70,20 20,200 170,140 120)','MULTIPOINT(80 170,140 120,200 80)');
SELECT '555', ST_Relate('MULTIPOINT(80 70,20 20,200 170,140 120)','MULTIPOINT(80 170,140 120,200 80,80 70)');
+
+SELECT 'relate_short_pattern_prepared', id, ST_Relate(g, 'POINT(0 0)'::geometry, 'T')
+FROM (VALUES
+ (1, 'POINT(0 0)'::geometry),
+ (2, 'POINT(1 1)'::geometry)
+) AS v(id, g);
diff --git a/regress/core/relate_expected b/regress/core/relate_expected
index b48ef45fc..52e64ff3b 100644
--- a/regress/core/relate_expected
+++ b/regress/core/relate_expected
@@ -553,3 +553,4 @@
553|0F0FFFFF2
554|0F0FFF0F2
555|0F0FFF0F2
+ERROR: GEOSRelatePattern: IllegalArgumentException: IllegalArgumentException: Should be length 9, is [T] instead
commit 0e07c23d019a731a2e95c1a366510a4cdade4bd7
Author: Darafei Praliaskouski <me at komzpa.net>
Date: Wed Jun 17 01:26:40 2026 +0400
raster: align IntersectionFractions test with GEOS float output
(cherry picked from commit c02ab2f5a15e81b9db6c51618b9a0f3295290be8)
diff --git a/raster/rt_core/rt_spatial_relationship.c b/raster/rt_core/rt_spatial_relationship.c
index e799bc921..a71ce179e 100644
--- a/raster/rt_core/rt_spatial_relationship.c
+++ b/raster/rt_core/rt_spatial_relationship.c
@@ -1334,10 +1334,10 @@ rt_raster_intersection_fractions(
/* Shallow clone a new raster with no bands */
rast_out = rt_raster_clone(rast_in, 0);
- /* Add a float8 band because GEOSGridIntersectionFractions writes doubles */
+ /* Add a float4 band matching GEOSGridIntersectionFractions' float buffer */
band_num = rt_raster_generate_new_band(
rast_out, /* rast */
- PT_64BF, /* pixel type */
+ PT_32BF, /* pixel type */
0.0, /* initial value */
0, 0.0, /* hasnodata, nodataval */
0); /* index */
@@ -1388,4 +1388,3 @@ rt_raster_intersection_fractions(
return rast_out; /* Return the newly created raster and band*/
}
#endif /* POSTGIS_GEOS_VERSION >= 31400 */
-
diff --git a/raster/test/regress/rt_intersection_fractions_expected b/raster/test/regress/rt_intersection_fractions_expected
index 575021720..601ee1f9c 100644
--- a/raster/test/regress/rt_intersection_fractions_expected
+++ b/raster/test/regress/rt_intersection_fractions_expected
@@ -1,4 +1,4 @@
-pixeltype|64BF
+pixeltype|32BF
polygon|2x2 raster covering 0,0 to 10,10|{{0.5,0.5},{0.5,0.5}}
polygon|10x10 raster covering 0,0 to 10,10|{{0,0,0,0,0.5,0.5,0,0,0,0},{0,0,0,0.5,1,1,0.5,0,0,0},{0,0,0.5,1,1,1,1,0.5,0,0},{0,0.5,1,1,1,1,1,1,0.5,0},{0.5,1,1,1,1,1,1,1,1,0.5},{0.5,1,1,1,1,1,1,1,1,0.5},{0,0.5,1,1,1,1,1,1,0.5,0},{0,0,0.5,1,1,1,1,0.5,0,0},{0,0,0,0.5,1,1,0.5,0,0,0},{0,0,0,0,0.5,0.5,0,0,0,0}}
polygon|2x2 raster covering -10,-10 to 0,0|{{0,0},{0,0}}
commit 6db6b531f34aa23a775548f98b761ea624930b82
Author: Darafei Praliaskouski <me at komzpa.net>
Date: Tue Jun 16 17:15:29 2026 +0400
Fix IntersectionFractions raster band size
(cherry picked from commit 23b9d0e074d4eb40dc04aaeadae16fd4332fcc45)
diff --git a/raster/rt_core/rt_spatial_relationship.c b/raster/rt_core/rt_spatial_relationship.c
index 374dd07f2..e799bc921 100644
--- a/raster/rt_core/rt_spatial_relationship.c
+++ b/raster/rt_core/rt_spatial_relationship.c
@@ -1334,10 +1334,10 @@ rt_raster_intersection_fractions(
/* Shallow clone a new raster with no bands */
rast_out = rt_raster_clone(rast_in, 0);
- /* Add a float4 band to the empty raster */
+ /* Add a float8 band because GEOSGridIntersectionFractions writes doubles */
band_num = rt_raster_generate_new_band(
rast_out, /* rast */
- PT_32BF, /* pixel type */
+ PT_64BF, /* pixel type */
0.0, /* initial value */
0, 0.0, /* hasnodata, nodataval */
0); /* index */
diff --git a/raster/test/regress/rt_intersection_fractions.sql b/raster/test/regress/rt_intersection_fractions.sql
index f3ea96d16..662025f7a 100644
--- a/raster/test/regress/rt_intersection_fractions.sql
+++ b/raster/test/regress/rt_intersection_fractions.sql
@@ -48,6 +48,14 @@ INSERT INTO raster_proportions_rast (name, rast) VALUES (
));
SET extra_float_digits = -8;
+
+SELECT 'pixeltype', ST_BandPixelType(
+ ST_IntersectionFractions(
+ rast,
+ 'POLYGON((5 0, 0 5, 5 10, 10 5, 5 0))'::geometry), 1)
+FROM raster_proportions_rast
+WHERE name = '2x2 raster covering 0,0 to 10,10';
+
SELECT 'polygon', name, ST_DumpValues(
ST_IntersectionFractions(
rast,
diff --git a/raster/test/regress/rt_intersection_fractions_expected b/raster/test/regress/rt_intersection_fractions_expected
index 7318eb76f..575021720 100644
--- a/raster/test/regress/rt_intersection_fractions_expected
+++ b/raster/test/regress/rt_intersection_fractions_expected
@@ -1,3 +1,4 @@
+pixeltype|64BF
polygon|2x2 raster covering 0,0 to 10,10|{{0.5,0.5},{0.5,0.5}}
polygon|10x10 raster covering 0,0 to 10,10|{{0,0,0,0,0.5,0.5,0,0,0,0},{0,0,0,0.5,1,1,0.5,0,0,0},{0,0,0.5,1,1,1,1,0.5,0,0},{0,0.5,1,1,1,1,1,1,0.5,0},{0.5,1,1,1,1,1,1,1,1,0.5},{0.5,1,1,1,1,1,1,1,1,0.5},{0,0.5,1,1,1,1,1,1,0.5,0},{0,0,0.5,1,1,1,1,0.5,0,0},{0,0,0,0.5,1,1,0.5,0,0,0},{0,0,0,0,0.5,0.5,0,0,0,0}}
polygon|2x2 raster covering -10,-10 to 0,0|{{0,0},{0,0}}
commit a8683ba6ead9f81c08a13cb54fc770fbe452c5d3
Author: Darafei Praliaskouski <me at komzpa.net>
Date: Fri Jun 19 02:07:05 2026 +0400
Fix ST_ClusterRelateWin NULL matrix handling
Validate the window relate matrix before detoasting it so NULL input reports the existing invalid-matrix error instead of dereferencing a NULL text datum. Add GEOS 3.13-gated regression coverage for the window function path.
Closes https://github.com/postgis/postgis/pull/886
(cherry picked from commit 9234e0417d493a59888180c6a8238a5161962f7c)
diff --git a/NEWS b/NEWS
index 5ff5a916a..3ea346e04 100644
--- a/NEWS
+++ b/NEWS
@@ -138,6 +138,8 @@ To take advantage of all postgis_sfcgal extension features SFCGAL 2.3+ is needed
dropping the tail (Darafei Praliaskouski)
- #6003, Avoid size_t formats in liblwgeom logging/error wrappers for
MinGW builds (Darafei Praliaskouski)
+ - GH-886, ST_ClusterRelateWin validates NULL relate matrices before
+ detoasting them (Darafei Praliaskouski)
- 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
diff --git a/postgis/lwgeom_window.c b/postgis/lwgeom_window.c
index 9b0e6e976..32f5b7a7d 100644
--- a/postgis/lwgeom_window.c
+++ b/postgis/lwgeom_window.c
@@ -20,6 +20,7 @@
*
* Copyright 2016 Paul Ramsey <pramsey at cleverelephant.ca>
* Copyright 2016 Daniel Baston <dbaston at gmail.com>
+ * Copyright 2026 Darafei Praliaskouski <me at komzpa.net>
*
**********************************************************************/
@@ -375,11 +376,22 @@ Datum ST_ClusterRelateWin(PG_FUNCTION_ARGS)
GEOSGeometry** geoms = palloc0(ngeoms * sizeof(GEOSGeometry*));
UNIONFIND* uf = UF_create(ngeoms);
char *matrix;
- text *txtIm = DatumGetTextP(WinGetFuncArgCurrent(win_obj, 1, &matrix_is_null));
- if (matrix_is_null || VARSIZE_ANY_EXHDR(txtIm) != 9)
+ /*
+ * Window arguments must be checked for NULL before detoasting.
+ * DatumGetTextP() is not allowed to inspect a NULL Datum.
+ */
+ Datum matrix_datum = WinGetFuncArgCurrent(win_obj, 1, &matrix_is_null);
+ text *txtIm;
+
+ if (matrix_is_null)
{
- elog(ERROR,"Invalid relate matrix provided");
- PG_RETURN_NULL();
+ elog(ERROR, "Invalid relate matrix provided");
+ }
+
+ txtIm = DatumGetTextP(matrix_datum);
+ if (VARSIZE_ANY_EXHDR(txtIm) != 9)
+ {
+ elog(ERROR, "Invalid relate matrix provided");
}
matrix = text_to_cstring(txtIm);
diff --git a/regress/core/cluster_geos313.sql b/regress/core/cluster_geos313.sql
new file mode 100644
index 000000000..64e677767
--- /dev/null
+++ b/regress/core/cluster_geos313.sql
@@ -0,0 +1,8 @@
+CREATE TEMPORARY TABLE cluster_geos313_inputs (id int, geom geometry);
+INSERT INTO cluster_geos313_inputs VALUES
+(1, 'LINESTRING (0 0, 1 1)'),
+(2, 'LINESTRING (5 5, 4 4)');
+
+SELECT 'cluster_relate_null_matrix', ST_ClusterRelateWin(geom, NULL) OVER ()
+FROM cluster_geos313_inputs
+LIMIT 1;
diff --git a/regress/core/cluster_geos313_expected b/regress/core/cluster_geos313_expected
new file mode 100644
index 000000000..823cdd774
--- /dev/null
+++ b/regress/core/cluster_geos313_expected
@@ -0,0 +1 @@
+ERROR: Invalid relate matrix provided
diff --git a/regress/core/tests.mk.in b/regress/core/tests.mk.in
index 73426ab2a..1b14fbeeb 100644
--- a/regress/core/tests.mk.in
+++ b/regress/core/tests.mk.in
@@ -172,6 +172,11 @@ else
$(top_srcdir)/regress/core/concave_hull
endif
+ifeq ($(shell expr "$(POSTGIS_GEOS_VERSION)" ">=" 31300),1)
+ TESTS += \
+ $(top_srcdir)/regress/core/cluster_geos313
+endif
+
ifeq ($(shell expr "$(POSTGIS_GEOS_VERSION)" ">=" 31500),1)
TESTS += \
$(top_srcdir)/regress/core/geos315
-----------------------------------------------------------------------
Summary of changes:
.github/workflows/codespell.yml | 7 +-
NEWS | 6 +
ci/winnie/regress_postgis.sh | 40 +++--
doc/xsl-config.xml | 1 -
postgis/brin_nd.c | 38 +++++
postgis/geography_brin.sql.in | 7 +
postgis/lwgeom_geos_predicates.c | 37 ++++-
postgis/lwgeom_window.c | 20 ++-
postgis/postgis_after_upgrade.sql | 163 +++++++++++++++++++++
postgis/postgis_brin.sql.in | 14 ++
raster/rt_core/rt_spatial_relationship.c | 3 +-
raster/test/regress/rt_intersection_fractions.sql | 8 +
.../regress/rt_intersection_fractions_expected | 1 +
regress/core/cluster_geos313.sql | 8 +
regress/core/cluster_geos313_expected | 1 +
regress/core/regress_brin_index_3d.sql | 10 ++
regress/core/regress_brin_index_3d_expected | 2 +
regress/core/regress_brin_index_geography.sql | 9 ++
regress/core/regress_brin_index_geography_expected | 1 +
regress/core/relate.sql | 6 +
regress/core/relate_expected | 1 +
regress/core/tests.mk.in | 5 +
utils/check_all_upgrades.sh | 28 ++--
23 files changed, 374 insertions(+), 42 deletions(-)
create mode 100644 regress/core/cluster_geos313.sql
create mode 100644 regress/core/cluster_geos313_expected
hooks/post-receive
--
PostGIS
More information about the postgis-tickets
mailing list