扩展运算符(*)在PostgreSQL中如何工作?

时间:2018-08-28 21:19:32

标签: sql database postgresql geometry gis

我刚刚开始学习PostgreSQL,我不知道缩放运算符如何处理几何类型。

例如select '((1, 1), (0, 0))'::box * '(2, 0)'::point;返回((2,2),(0,0))

select '((1, 1), (0, 0))'::box * '(0, 2)'::point;返回((0,2),(-2,0))

因此,在两种情况下,框都按2的比例缩放(对于两个轴),但是框的移动方式对我来说毫无意义。

Official documentation仅显示了此运算符用法的一个示例,而没有显示其工作原理。

如果有人知道更好的学习PostgreSQL的资源,请共享它。

谢谢。

1 个答案:

答案 0 :(得分:2)

这是函数box_mul的实现,该函数位于*(box, point)运算符之后(来自https://github.com/postgres/postgres/blob/master/src/backend/utils/adt/geo_ops.c):

static inline void
point_mul_point(Point *result, Point *pt1, Point *pt2)
{
    point_construct(result,
                    float8_mi(float8_mul(pt1->x, pt2->x),
                              float8_mul(pt1->y, pt2->y)),
                    float8_pl(float8_mul(pt1->x, pt2->y),
                              float8_mul(pt1->y, pt2->x)));
}

Datum
box_mul(PG_FUNCTION_ARGS)
{
    BOX        *box = PG_GETARG_BOX_P(0);
    Point      *p = PG_GETARG_POINT_P(1);
    BOX        *result;
    Point       high,
                low;

    result = (BOX *) palloc(sizeof(BOX));

    point_mul_point(&high, &box->high, p);
    point_mul_point(&low, &box->low, p);

    box_construct(result, &high, &low);

    PG_RETURN_BOX_P(result);
}

或翻译成更“人类”的语言:

((x1, y1), (x2, y2)) * (x, y) :- ((x1*x - y1*y, x1*y + y1*x), (x2*x - y2*y, x2*y + y2*x))

以您为例

((1,1),(0,0)) * (0,2) = ((1*0 - 1*2, 1*2 + 1*0), (0*0 - 0*2, 0*2 + 0 * 0)) = ((-2,2),(0,0))

最后box_construct()将其转换为(0,2),(-2,0)(只需检查select '((-2,2),(0,0))'::box;

如果您知道/记住这些转换的几何含义,请在此处发布最终答案。