Opened 7 years ago

Closed 7 years ago

#3760 closed defect (fixed)

raster blocksize check failing on PostgreSQL 10 _raster_constraint_info_blocksize is broken

Reported by: robe Owned by: robe
Priority: blocker Milestone: PostGIS 2.4.0
Component: raster Version: master
Keywords: Cc:

Description

regarding the #3759, one of the other raster failures is that the query of blocksize is returning null even when the constraint is set.

Here is an example to exercise the problem:

CREATE TABLE test_rast(rid serial, rast raster);

INSERT INTO test_rast(rast)
SELECT r
FROM  ST_Tile(ST_MakeEmptyRaster(500, 500, 0,500, 1, 1, 0, 0, 0), 50, 50) AS r;

SELECT AddRasterConstraints(current_schema(), 'test_rast', 'rast'::name, 'blocksize');

In both PostgreSQL 9.6 and 10 I see the constraint for width and height are set as expected

ALTER TABLE public.test_rast
  ADD CONSTRAINT enforce_height_rast CHECK (st_height(rast) = 50);

ALTER TABLE public.test_rast
  ADD CONSTRAINT enforce_width_rast CHECK (st_width(rast) = 50);

However doing a query such as:

SELECT _raster_constraint_info_blocksize('public', 'test_rast', 'rast', 'width') AS width,
     _raster_constraint_info_blocksize('public', 'test_rast', 'rast', 'width') AS height;

which is the function internally used by raster_columns view:

In 10 returns nulls:

 width | height
-------+--------
  NULL |   NULL
(1 row)

But in 9.6 and lower returns expected value:

 width | height
-------+--------
    50 |     50
(1 row)

I'm not seeing a difference in constraint definitions between the two so must be something different in catalogs how this is stored

Change History (3)

comment:1 by robe, 7 years ago

okay figured out problem. Has to do with change of how set returning functions are processed in CASE statements. Boy I didn't realized this change when I read about it would cause so much grief.

So problem is our use of regexp_matches:

	CASE
			WHEN strpos(s.consrc, 'ANY (ARRAY[') > 0 THEN
				split_part((regexp_matches(s.consrc, E'ARRAY\\[(.*?){1}\\]'))[1], ',', 1)::integer
			ELSE
				regexp_replace(
					split_part(s.consrc, '= ', 2),
					'[\(\)]', '', 'g'
				)::integer
			END

I think in pre-postgresql 10 the CASE statement would short-circuit before it hit the regexp_matches test and since regexp_matches is as set returning, when it returns nothing it causes the row not to be output.

This feels to me like an unintended consequence, but I guess I'll read the fine print in the release notes, and whine if it seems unintended.

comment:2 by robe, 7 years ago

Okay the release notes say this, so grudge-only I guess this is expected behavior change I can't complain about.


This also prevents conditionals like CASE from controlling the execution of set-returning functions because set-returning functions are now executed earlier.


comment:3 by robe, 7 years ago

Resolution: fixed
Status: assignedclosed

In 15404:

Revise to use substring function instead of regexp_matches.
This fixes most of the raster regress issues noted in #3759 and
Closes #3760 for PostGIS 2.4.0 (trunk)

Note: See TracTickets for help on using tickets.