PostgreSQL 10 PostGIS 兼容性 FIX

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS PostgreSQL Serverless,0.5-4RCU 50GB 3个月
推荐场景:
对影评进行热评分析
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介:

标签

PostgreSQL , PostGIS , regexp_matches , _raster_constraint_info_blocksize


背景

PostGIS 的PG 10有一点兼容性问题:

创建extension时报错如下:

ERROR:  set-returning functions are not allowed in CASE  
LINE 6:                                 split_part((regexp_matches(s...  
                                                    ^  
HINT:  You might be able to move the set-returning function into a LATERAL FROM item.  

分析对应的.sql文件,出错的是这个FUNCTION。

CREATE OR REPLACE FUNCTION _raster_constraint_info_blocksize(rastschema name, rasttable name, rastcolumn name, axis text)  
        RETURNS integer AS $$  
        SELECT  
                CASE  
                        WHEN strpos(s.consrc, 'ANY (ARRAY[') > 0 THEN  
                                split_part((regexp_matches(s.consrc, E'ARRAY\\[(.*?){1}\\]'))[1], ',', 1)::integer   -- 改成regexp_match  
                        ELSE  
                                regexp_replace(  
                                        split_part(s.consrc, '= ', 2),  
                                        '[\(\)]', '', 'g'  
                                )::integer  
                        END  
        FROM pg_class c, pg_namespace n, pg_attribute a, pg_constraint s  
        WHERE n.nspname = $1  
                AND c.relname = $2  
                AND a.attname = $3  
                AND a.attrelid = c.oid  
                AND s.connamespace = n.oid  
                AND s.conrelid = c.oid  
                AND a.attnum = ANY (s.conkey)  
                AND s.consrc LIKE '%st_' || $4 || '(%= %';  
        $$ LANGUAGE sql STABLE STRICT  
  COST 100;  

修正方法

regexp_matches改成regexp_match。

修正后的验证,正常返回约束即可。

postgres=# CREATE TABLE test_rast(rid serial, rast raster);  
CREATE TABLE  
postgres=#   
postgres=# INSERT INTO test_rast(rast)  
postgres-# SELECT r  
postgres-# FROM  ST_Tile(ST_MakeEmptyRaster(500, 500, 0,500, 1, 1, 0, 0, 0), 50, 50) AS r;  
INSERT 0 100  
postgres=#   
postgres=# SELECT AddRasterConstraints(current_schema(), 'test_rast', 'rast'::name, 'blocksize');  
NOTICE:  Adding blocksize-X constraint  
NOTICE:  Adding blocksize-Y constraint  
 addrasterconstraints   
----------------------  
 t  
(1 row)  
  
postgres=# \d+ test_rast  
                                                 Table "public.test_rast"  
 Column |  Type   | Collation | Nullable |                Default                 | Storage  | Stats target | Description   
--------+---------+-----------+----------+----------------------------------------+----------+--------------+-------------  
 rid    | integer |           | not null | nextval('test_rast_rid_seq'::regclass) | plain    |              |   
 rast   | raster  |           |          |                                        | extended |              |   
Check constraints:  
    "enforce_height_rast" CHECK (st_height(rast) = 50)  
    "enforce_width_rast" CHECK (st_width(rast) = 50)  
  
postgres=# SELECT _raster_constraint_info_blocksize('public', 'test_rast', 'rast', 'width') AS width,  
postgres-#      _raster_constraint_info_blocksize('public', 'test_rast', 'rast', 'width') AS height;  
 width | height   
-------+--------  
    50 |     50  
(1 row)  

扩展阅读

PostgreSQL 10新增了一个规则匹配函数regexp_match,分别用于返回单行和多行。

如下

Function Return Type Description Example Result
regexp_match(string text, pattern text [, flags text]) text[] Return captured substring(s) resulting from the first match of a POSIX regular expression to the string. See Section 9.7.3 for more information. regexp_match('foobarbequebaz', '(bar)(beque)') {bar,beque}
regexp_matches(string text, pattern text [, flags text]) setof text[] Return captured substring(s) resulting from matching a POSIX regular expression to the string. See Section 9.7.3 for more information. regexp_matches('foobarbequebaz', 'ba.', 'g') {bar} {baz} (2 rows)

10以前的版本如下,只有一个regexp_matches函数,效果与regexp_match类似。虽然返回的是SRF。

Function Return Type Description Example Result
regexp_matches(string text, pattern text [, flags text]) setof text[] Return all captured substrings resulting from matching a POSIX regular expression against the string. See Section 9.7.3 for more information. regexp_matches('foobarbequebaz', '(bar)(beque)') {bar,beque}

因此PostgreSQL 10我们在PostGIS的postgis--2.3.2.sql中修正为regexp_match是可行的。

另一方面,实际上SRF函数在非SRF中调用并返回结果时,实际上返回的也是第一个匹配行,如下:

-- 非SRF函数中调用SRF。  
postgres=# create or replace function f() returns int as $$  
postgres$# select * from (values (1),(2),(3)) t(id);  
postgres$# $$ language sql strict;  
CREATE FUNCTION  
  
postgres=# select f();  
 f   
---  
 1  
(1 row)  
  
  
-- SRF函数中调用SRF。  
postgres=# drop function f();  
DROP FUNCTION  
postgres=# create or replace function f() returns setof int as $$  
select * from (values (1),(2),(3)) t(id);  
$$ language sql strict;  
CREATE FUNCTION  
postgres=# select f();  
 f   
---  
 1  
 2  
 3  
(3 rows)  

PostGIS插件安装中用到的一些字符串处理函数

PostGIS插件安装中用到了大量字符串处理函数,列举一些:

strpos  
  
split_part  
  
regexp_match  
  
regexp_replace  

例子

postgres=# select strpos('abc','a');  
 strpos   
--------  
      1  
(1 row)  
  
postgres=# select strpos('abc','b');  
 strpos   
--------  
      2  
(1 row)  
  
postgres=# select split_part('a.b.c','.',1);  
 split_part   
------------  
 a  
(1 row)  
  
postgres=# select split_part('a.b.c','.',2);  
 split_part   
------------  
 b  
(1 row)  
  
postgres=# select split_part('a.b.c','.',3);  
 split_part   
------------  
 c  
(1 row)  
  
postgres=# select regexp_match('foobarbequebaz', '(bar)(beque)');  
 regexp_match   
--------------  
 {bar,beque}  
(1 row)  
  
postgres=# select regexp_matches('foobarbequebaz', 'ba.', 'g');  
 regexp_matches   
----------------  
 {bar}  
 {baz}  
(2 rows)  
  
postgres=# select regexp_replace('Thomas', '.[mN]a.', 'M');  
 regexp_replace   
----------------  
 ThM  
(1 row)  

参考

https://trac.osgeo.org/postgis/ticket/3760#no1

《PostgreSQL 使用递归SQL 找出数据库对象之间的依赖关系》

《PostgreSQL 10.0 解读》

https://www.postgresql.org/docs/10/static/functions-string.html

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
2月前
|
关系型数据库 PostgreSQL Docker
PostgreSQL - 01 PostgreSQL + PostGIS + Docker 空间计算!判断坐标点是否在某个区域中 POINT MULTIPOLYGON ST_Contains
PostgreSQL - 01 PostgreSQL + PostGIS + Docker 空间计算!判断坐标点是否在某个区域中 POINT MULTIPOLYGON ST_Contains
47 0
|
7月前
|
关系型数据库 数据库 PostgreSQL
Docker【应用 03】给Docker部署的PostgreSQL数据库安装PostGIS插件(安装流程及问题说明)
Docker【应用 03】给Docker部署的PostgreSQL数据库安装PostGIS插件(安装流程及问题说明)
457 0
|
7月前
|
SQL 关系型数据库 PostgreSQL
PostgreSQL【部署 01】离线安装PostgreSQL+PostGIS踩坑及问题解决经验分享(含安装文件PostgreSQL+PostGIS及多个依赖+测试SQL)
PostgreSQL【部署 01】离线安装PostgreSQL+PostGIS踩坑及问题解决经验分享(含安装文件PostgreSQL+PostGIS及多个依赖+测试SQL)
839 0
|
SQL 关系型数据库 Unix
|
关系型数据库 Linux PostgreSQL
linux安装postgresql、postgis并且使用geoserver发布服务
linux安装postgresql、postgis并且使用geoserver发布服务
|
SQL 监控 关系型数据库
PostgreSQL Oracle 兼容性之 - performance insight - AWS performance insight 理念与实现解读 - 珍藏级
PostgreSQL , perf insight , 等待事件 , 采样 , 发现问题 , Oracle 兼容性
846 0
|
SQL 监控 数据可视化
解读PostgreSQL Oracle 兼容性之 - performance insight(性能洞察)
标签 PostgreSQL , perf insight , 等待事件 , 采样 , 发现问题 , Oracle 兼容性 背景 通常普通的监控会包括系统资源的监控: cpu io 内存 网络 等,但是仅凭资源的监控,当问题发生时,如何快速的定位到问题在哪里?需要更高级的监控: 更高级的监控方法通常是从数据库本身的
934 0
|
SQL 存储 Oracle
PostgreSQL , EDB EPAS PPAS(兼容Oracle) , Oracle 对比(兼容性、特性优劣势) - 企业去O,去IOE
标签 PostgreSQL , PPAS , EPAS , edb , enterprisedb , Oracle , 兼容性 , 优缺点 背景 EPAS为EDB的PostgreSQL Oracle兼容企业版,基于PostgreSQL社区版本开发,2004年发布了第一个Oracle兼容版,已经在ORACLE兼容性上耕耘了15年。 2018年推出EPAS 11 版本,完成了 Oracle
2183 0
|
弹性计算 关系型数据库 PostgreSQL
PostgreSQL PostGIS 性能提升 - by new GEOS代码
标签 PostgreSQL , PostGIS , geos 背景 http://lin-ear-th-inking.blogspot.com/2019/02/betterfaster-stpointonsurface-for.html 使用GEOS新的代码,提升PostGIS重计算的函数性能。 The improved ST_PointOnSurface runs 13 times
787 0
|
SQL 存储 Oracle
PostgreSQL Oracle 兼容性 - Oracle 19c 新特性在PostgreSQL中的使用
PostgreSQL Oracle 兼容性 - Oracle 19c 新特性在PostgreSQL中的使用
2906 0

相关产品

  • 云原生数据库 PolarDB
  • 云数据库 RDS PostgreSQL 版