Opened 9 years ago

Closed 9 years ago

#3283 closed defect (fixed)

Corrupt cached bboxes gets created (m-value)

Reported by: nicklas Owned by: pramsey
Priority: medium Milestone: PostGIS 2.2.0
Component: postgis Version: master
Keywords: temporal Cc: strk

Description

This one really confuses me.

to reproduce: Load the attached table (problem.backup).

Then run:

select st_cpawithin(
(select geom from p where gid = 1)
,
(select geom from p where gid = 2)
,1000);

it is 2 trajectories that do not have overlapping m-values so should just return false. Instead I get:

ERROR:  Could not find point with M=0 on first geom

After some investigation I have found that even if they do not have overlapping m-values, the cached bboxes have the same max-value in one as the min-value in the other.

That it is the cached box that is the problem I think I can prove by running:

select st_cpawithin(
(select PostGIS_DropBBox(geom) from p where gid = 1 and ST_IsValidTrajectory(geom))
,
(select PostGIS_DropBBox(geom) from p where gid = 2 and ST_IsValidTrajectory(geom))
,1000);

which gives the right answer.

I also haven't successed to get the error when putting wkt or wkb other formats without cached box in the function with the exactly same geometries.

postgis_full_version

POSTGIS="2.2.0dev r14034" GEOS="3.5.0dev-CAPI-1.9.0 r4082" PROJ="Rel. 4.9.1, 04 March 2015" GDAL="GDAL 2.1.0dev, released 2015/99/99" LIBXML="2.9.1" LIBJSON="0.12.99" RASTER

Attachments (1)

problem.backup (234.8 KB ) - added by nicklas 9 years ago.
2 geoemtries causing corrupt bbox

Download all attachments as: .zip

Change History (9)

by nicklas, 9 years ago

Attachment: problem.backup added

2 geoemtries causing corrupt bbox

comment:1 by strk, 9 years ago

Keywords: temporal added

comment:2 by robe, 9 years ago

SAme result here. What I don't understand is why adding the bbox back gives a slightly different error message. It's almost like we have two separate cache box adders and the one on restore is different from the add_bbox one.

When I do this:

select st_cpawithin(
(select PostGIS_AddBBox(PostGIS_DropBBox(geom)) from p where gid = 1 and ST_IsValidTrajectory(geom))
,
(select PostGIS_AddBBox(PostGIS_DropBBox(geom)) from p where gid = 2 and ST_IsValidTrajectory(geom))
,1000);

I get:

ERROR:  Could not find point with M=9.28441e-309 on first geom
********** Error **********

ERROR: Could not find point with M=9.28441e-309 on first geom
SQL state: XX000


But with just restoring, I got the same M=0 error message you got. I know they are off by a smidge so could be just some windows artifact.

This is testing on:

PostgreSQL 9.4.4, compiled by Visual C++ build 1800, 64-bit POSTGIS="2.2.0dev r14083" GEOS="3.5.0-CAPI-1.9.0 r4088" PROJ="Rel. 4.9.1, 04 March 2015" GDAL="GDAL 2.0.0, released 2015/06/14" LIBXML="2.7.8" LIBJSON="0.12" RASTER

comment:3 by nicklas, 9 years ago

I have seen some different error-messages too, just like you describe.

What worries a little is that it might be something outside just the temporal function.

I mean the cpawithin function just calls the same box-making functions as all other functions I guess.

But I have not had time to try to find out if it happens in other situations too. It is a little harder to test by just using the common functions since it is the m-value in this case that is problematic.

But I did put a notice message at the box creation function (don't ask me where I found it) and it seemed to create the correct box. Then the result went stright into ST_Spe function with a bad cached bbox.

Maybe this is even the first function using m-value from box?

comment:4 by pramsey, 9 years ago

Just to be precise about numbers, the actual min/max M values are this:

    min     |    max     | gid 
------------+------------+-----
 1441014776 | 1441029714 |   1
 1440992184 | 1441014568 |   2

Gathered by dumping the points and getting their extrema. And the actual values of the bounding boxes coming in from the cache are:

(lldb) p *g1->bbox
(GBOX) $2 = (flags = '\x06', xmin = 332854.125, xmax = 333364.5625, ymin = 6726488.5, ymax = 6726756, zmin = 7.2911292855948646E-304, zmax = 0, mmin = 1441014656, mmax = 1441029760)
(lldb) p *g2->bbox
(GBOX) $4 = (flags = '\x06', xmin = 332893.0625, xmax = 333092.53125, ymin = 6726633, ymax = 6726818.5, zmin = 7.2911292855948646E-304, zmax = 0, mmin = 1440992128, mmax = 1441014656)

Now, remember that bounding boxes are rounding outwards slightly so they are always a little overdetermined, but not in ways that are usually visible. But in this case we are dealing with quite large absolute values, so I think the outward rounding is visible.

I just monkey-patched at r14089

comment:5 by pramsey, 9 years ago

Resolution: fixed
Status: newclosed

comment:6 by strk, 9 years ago

Resolution: fixed
Status: closedreopened

Sorry but I think the correct behavior here was to raise an exception. Isn't it what you get when you pass unsuspectably not-overlapping-in-time trajectories ? It could be it was just the message being confused (I hadn't double-checked).

comment:7 by strk, 9 years ago

Sorry, I'm taking it back, CPAWithin is ok to return false on missing overlap

comment:8 by strk, 9 years ago

Resolution: fixed
Status: reopenedclosed
Note: See TracTickets for help on using tickets.