如何在复合类型文字中指定PostGIS地理值?

时间:2018-04-21 09:32:12

标签: postgresql postgis

我有自定义复合类型:

CREATE TYPE place AS (
    name text,
    location geography(point, 4326)
);

我想使用文字创建该类型的值:

SELECT $$("name", "ST_GeogFromText('POINT(121.560800 29.901200)')")$$::place;

这失败了:

HINT:  "ST" <-- parse error at position 2 within geometry
ERROR:  parse error - invalid geometry

但这执行得很好:

SELECT ST_GeogFromText('POINT(121.560800 29.901200)');

我想知道在复合类型文字中指定PostGIS地理值的正确方法是什么?

1 个答案:

答案 0 :(得分:2)

您正在尝试将函数调用ST_GeogFromText推送到文本字符串中。这是不允许的,因为它为SQL注入创造了可能性。

在第二次调用中,您需要ST_GeogFromText来标记输入的类型。对于复合类型,您已经在类型定义中执行了此操作,因此您可以跳过该部分:

[local] gis@gis=# SELECT $$("name", "POINT(121.560800 29.901200)")$$::place;
┌───────────────────────────────────────────────────────────┐
│                           place                           │
├───────────────────────────────────────────────────────────┤
│ (name,0101000020E610000032E6AE25E4635E40BB270F0BB5E63D40) │
└───────────────────────────────────────────────────────────┘
(1 row)
Time: 0,208 ms

另一种选择是使用非文字形式,它允许函数调用:

[local] gis@gis=# SELECT ('name', ST_GeogFromText('POINT(121.560800 29.901200)'))::place;;
┌───────────────────────────────────────────────────────────┐
│                            row                            │
├───────────────────────────────────────────────────────────┤
│ (name,0101000020E610000032E6AE25E4635E40BB270F0BB5E63D40) │
└───────────────────────────────────────────────────────────┘
(1 row)

Time: 5,004 ms