Exclusion constraint with custom operator not working as expected
"Rhys A.D. Stewart" <[email protected]> Tue, 22 Jun 2021 15:29:34 -0500
| Newsgroups | gmane.comp.gis.postgis,gmane.comp.db.postgresql.general |
|---|---|
| Message-ID | <CACg0vTmVJD64Tm1CPeJduAQfPzuBoZFS2zFXcv0YUxLkXfMYPg@mail.gmail.com> |
--===============3998830929787789230==
Content-Type: multipart/alternative; boundary="0000000000007d662205c560a7f6"
--0000000000007d662205c560a7f6
Content-Type: text/plain; charset="UTF-8"
Greetings All,
Firstly, apologies for cross posting.
I would like to create a table which will contain postGIS geometries,
specifically linestrings. Each line string should be unique, unique in the
sense that no linestring should st_equals any other. (see
https://postgis.net/docs/manual-3.1/ST_Equals.html)
So, LINESTRING(10 10, 50 50) and LINESTRING(50 50, 10 10) are "st_equal".
I did the following:
BEGIN;
DROP OPERATOR IF EXISTS |*| (geometry, geometry) CASCADE;
CREATE OPERATOR |*| (
FUNCTION = st_equals,
LEFTARG = geometry,
RIGHTARG = geometry,
COMMUTATOR = |*|
);
CREATE OPERATOR CLASS my_ops FOR TYPE geometry
USING gist FAMILY gist_geometry_ops_2d AS
OPERATOR 99 |*| (geometry, geometry);
-- This returns True
SELECT 'LINESTRING(10 10, 50 50)'::geometry |*| 'LINESTRING(50 50, 10
10)'::geometry;
DROP TABLE IF EXISTS test_1 ;
CREATE TABLE test_1 (
fid integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
g geometry,
EXCLUDE USING GIST (g WITH |*|)
);
INSERT INTO test_1 (g) VALUES ('LINESTRING(10 10, 50 50)') ON CONFLICT DO
NOTHING;
INSERT INTO test_1 (g) VALUES ('LINESTRING(50 50, 10 10)') ON CONFLICT DO
NOTHING; -- This should do nothing;
SELECT fid, st_astext(g) FROM test_1; -- both rows returned, exclusion
doesn't work as I think it should.
ROLLBACK;
But where I expected the second insert to 'DO NOTHING', it very much did
something. So clearly I am missing something somewhere or my understanding
of exclusion constraints is lacking...or both. Any suggestions to get the
desired outcome? (Using a trigger doesn't count :-D )
But
Rhys
Peace & Love | Live Long & Prosper
--0000000000007d662205c560a7f6
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div dir=3D"auto"><div dir=3D"ltr"><div class=3D"gmail_def=
ault" style=3D"font-family:trebuchet ms,sans-serif">Greetings All,</div><di=
v class=3D"gmail_default" style=3D"font-family:trebuchet ms,sans-serif"><br=
></div><div class=3D"gmail_default" style=3D"font-family:trebuchet ms,sans-=
serif">Firstly, apologies for cross posting.=C2=A0</div><div class=3D"gmail=
_default" style=3D"font-family:trebuchet ms,sans-serif" dir=3D"auto">I woul=
d like to create a table which will contain postGIS geometries, specificall=
y linestrings.=C2=A0 Each line string should be unique, unique in the sense=
that no linestring should st_equals any other. (see <a href=3D"https://pos=
tgis.net/docs/manual-3.1/ST_Equals.html">https://postgis.net/docs/manual-3.=
1/ST_Equals.html</a>)</div><div class=3D"gmail_default" style=3D"font-famil=
y:trebuchet ms,sans-serif" dir=3D"auto"><br></div><div class=3D"gmail_defau=
lt" style=3D"font-family:trebuchet ms,sans-serif">So, LINESTRING(10 10, 50 =
50) and LINESTRING(50 50, 10 10) are "st_equal".</div><div class=
=3D"gmail_default" style=3D"font-family:trebuchet ms,sans-serif"><br></div>=
<div class=3D"gmail_default" style=3D"font-family:trebuchet ms,sans-serif">=
=C2=A0I did the following:<br></div><div class=3D"gmail_default" style=3D"f=
ont-family:trebuchet ms,sans-serif"><br></div><div class=3D"gmail_default" =
style=3D"font-family:trebuchet ms,sans-serif"></div><div class=3D"gmail_def=
ault" style=3D"font-family:trebuchet ms,sans-serif">BEGIN; <br><br>DROP OPE=
RATOR IF EXISTS |*| (geometry, geometry) CASCADE;<br><br>CREATE OPERATOR |*=
| (<br> FUNCTION =3D st_equals,<br> LEFTARG =3D geometry,<br> RIGHTARG =3D =
geometry,<br> COMMUTATOR =3D |*|<br> );<br><br>CREATE OPERATOR CLASS my_ops=
FOR TYPE geometry<br> USING gist FAMILY gist_geometry_ops_2d AS<br> OPERAT=
OR 99 |*| (geometry, geometry);<br><br>-- This returns True<br>SELECT =C2=
=A0'LINESTRING(10 10, 50 50)'::geometry |*| 'LINESTRING(50 50, =
10 10)'::geometry;<br><br>DROP TABLE IF EXISTS test_1 ;<br>CREATE TABLE=
test_1 (<br> fid integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY,<br> g g=
eometry,<br> EXCLUDE USING GIST (g WITH |*|)<br>);<br><br>INSERT INTO test_=
1 (g) VALUES ('LINESTRING(10 10, 50 50)') ON CONFLICT DO NOTHING;<b=
r>INSERT INTO test_1 (g) VALUES ('LINESTRING(50 50, 10 10)') ON CON=
FLICT DO NOTHING; -- This should do nothing; <br><br>SELECT fid, st_astext(=
g) FROM test_1; -- both rows returned, exclusion doesn't work as I thin=
k it should.<br><br>ROLLBACK;</div><div class=3D"gmail_default" style=3D"fo=
nt-family:trebuchet ms,sans-serif"><br></div><div class=3D"gmail_default" s=
tyle=3D"font-family:trebuchet ms,sans-serif">But where I expected the secon=
d insert to 'DO NOTHING', it very much did something. So clearly I =
am missing something somewhere or my understanding of exclusion constraints=
is lacking...or both.=C2=A0 Any suggestions to get the desired outcome? (U=
sing a trigger doesn't count :-D )<br></div><div class=3D"gmail_default=
" style=3D"font-family:trebuchet ms,sans-serif"><br></div><div class=3D"gma=
il_default" style=3D"font-family:trebuchet ms,sans-serif">But <br clear=3D"=
all"></div><div><div dir=3D"ltr" data-smartmail=3D"gmail_signature"><div di=
r=3D"ltr"><div><div dir=3D"ltr"><div>Rhys</div>Peace & Love | Live Long=
& Prosper</div></div></div></div></div></div></div>
</div>
--0000000000007d662205c560a7f6--
--===============3998830929787789230==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
postgis-users mailing list
[email protected]
https://lists.osgeo.org/mailman/listinfo/postgis-users
--===============3998830929787789230==--