Skip to content

Commit 100a85c

Browse files
committed
Add wrappers for postgres geometric types.
For simple `Copy` types, just newtype them and add impls for FromDatum and ToDatum. For more complex variable length types, create zero-copy and owned structs with impls for FromDatum and ToDatum as well as SqlTranslatable.
1 parent 6bbe8ff commit 100a85c

File tree

3 files changed

+560
-19
lines changed

3 files changed

+560
-19
lines changed

pgrx-tests/src/tests/geo_tests.rs

Lines changed: 115 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,129 @@ mod tests {
1313
#[allow(unused_imports)]
1414
use crate as pgrx_tests;
1515

16+
use pgrx::datum::geo::*;
1617
use pgrx::prelude::*;
1718

1819
#[pg_test]
19-
fn test_point_into_datum() -> spi::Result<()> {
20+
fn test_point_datum() -> spi::Result<()> {
21+
let p = Spi::get_one::<Point>("SELECT '42, 99'::point")?.expect("SPI result was null");
22+
assert_eq!(p, Point { x: 42.0, y: 99.0 });
23+
let p2 = Spi::get_one_with_args::<Point>(
24+
"SELECT $1",
25+
vec![(Point::type_oid().into(), p.into_datum())],
26+
)?
27+
.expect("SPI result was null");
28+
assert_eq!(p, p2);
29+
Ok(())
30+
}
31+
32+
#[pg_test]
33+
fn test_box_datum() -> spi::Result<()> {
34+
let b = Spi::get_one::<Box>("SELECT '1,2,3,4'::box")?.expect("SPI result was null");
35+
assert_eq!(b, Box { high: Point { x: 3.0, y: 4.0 }, low: Point { x: 1.0, y: 2.0 } });
36+
let b2 = Spi::get_one_with_args::<Box>(
37+
"SELECT $1",
38+
vec![(Box::type_oid().into(), b.into_datum())],
39+
)?
40+
.expect("SPI result was null");
41+
assert_eq!(b, b2);
42+
Ok(())
43+
}
44+
45+
#[pg_test]
46+
fn test_lseg_datum() -> spi::Result<()> {
47+
let l = Spi::get_one::<LineSegment>("SELECT '(1,2),(3,4)'::lseg")?
48+
.expect("SPI result was null");
49+
assert_eq!(l.p, [Point { x: 1.0, y: 2.0 }, Point { x: 3.0, y: 4.0 }]);
50+
let l2 = Spi::get_one_with_args::<LineSegment>(
51+
"SELECT $1",
52+
vec![(LineSegment::type_oid().into(), l.into_datum())],
53+
)?
54+
.expect("SPI result was null");
55+
assert_eq!(l.p, l2.p);
56+
Ok(())
57+
}
58+
59+
#[pg_test]
60+
fn test_path_datum() -> spi::Result<()> {
61+
// Closed path
62+
let p = Spi::get_one::<Path>("SELECT '((1,2),(3,4))'::path")?.expect("SPI result was null");
63+
assert_eq!(p.points(), [Point { x: 1.0, y: 2.0 }, Point { x: 3.0, y: 4.0 }]);
64+
assert_eq!(p.closed(), true);
65+
let p2 = Spi::get_one_with_args::<Path>(
66+
"SELECT $1",
67+
vec![(Path::type_oid().into(), p.clone().into_datum())],
68+
)?
69+
.expect("SPI result was null");
70+
assert_eq!(p.points(), p2.points());
71+
assert_eq!(p.closed(), p2.closed());
72+
73+
// Open path
74+
let p = Spi::get_one::<Path>("SELECT '[(1,2),(3,4)]'::path")?.expect("SPI result was null");
75+
assert_eq!(p.points(), [Point { x: 1.0, y: 2.0 }, Point { x: 3.0, y: 4.0 }]);
76+
assert_eq!(p.closed(), false);
77+
let p2 = Spi::get_one_with_args::<Path>(
78+
"SELECT $1",
79+
vec![(Path::type_oid().into(), p.clone().into_datum())],
80+
)?
81+
.expect("SPI result was null");
82+
assert_eq!(p.points(), p2.points());
83+
assert_eq!(p.closed(), p2.closed());
84+
85+
Ok(())
86+
}
87+
88+
#[pg_test]
89+
fn test_raw_path_from_datum() -> spi::Result<()> {
90+
// Closed path
2091
let p =
21-
Spi::get_one::<pg_sys::Point>("SELECT '42, 99'::point")?.expect("SPI result was null");
22-
assert_eq!(p.x, 42.0);
23-
assert_eq!(p.y, 99.0);
92+
Spi::get_one::<RawPath>("SELECT '((1,2),(3,4))'::path")?.expect("SPI result was null");
93+
assert_eq!(p.points()[0], Point { x: 1.0, y: 2.0 });
94+
assert_eq!(p.points()[1], Point { x: 3.0, y: 4.0 });
95+
assert_eq!(p.closed(), true);
96+
97+
// Open path
98+
let p =
99+
Spi::get_one::<RawPath>("SELECT '[(1,2),(3,4)]'::path")?.expect("SPI result was null");
100+
assert_eq!(p.points()[0], Point { x: 1.0, y: 2.0 });
101+
assert_eq!(p.points()[1], Point { x: 3.0, y: 4.0 });
102+
assert_eq!(p.closed(), false);
103+
Ok(())
104+
}
105+
106+
#[pg_test]
107+
fn test_polygon_datum() -> spi::Result<()> {
108+
let p = Spi::get_one::<Polygon>("SELECT '((1,2),(3,4),(0,5))'::polygon")?
109+
.expect("SPI result was null");
110+
assert_eq!(
111+
p.points(),
112+
[Point { x: 1.0, y: 2.0 }, Point { x: 3.0, y: 4.0 }, Point { x: 0.0, y: 5.0 }]
113+
);
114+
assert_eq!(
115+
p.boundbox(),
116+
Box { high: Point { x: 3.0, y: 5.0 }, low: Point { x: 0.0, y: 2.0 } }
117+
);
118+
let p2 = Spi::get_one_with_args::<Polygon>(
119+
"SELECT $1",
120+
vec![(Polygon::type_oid().into(), p.clone().into_datum())],
121+
)?
122+
.expect("SPI result was null");
123+
assert_eq!(p.points(), p2.points());
124+
assert_eq!(p.boundbox(), p2.boundbox());
24125
Ok(())
25126
}
26127

27128
#[pg_test]
28-
fn test_box_into_datum() -> spi::Result<()> {
29-
let b = Spi::get_one::<pg_sys::BOX>("SELECT '1,2,3,4'::box")?.expect("SPI result was null");
30-
assert_eq!(b.high.x, 3.0);
31-
assert_eq!(b.high.y, 4.0);
32-
assert_eq!(b.low.x, 1.0);
33-
assert_eq!(b.low.y, 2.0);
129+
fn test_raw_polygon_from_datum() -> spi::Result<()> {
130+
let p = Spi::get_one::<RawPolygon>("SELECT '((1,2),(3,4),(0,5))'::polygon")?
131+
.expect("SPI result was null");
132+
assert_eq!(p.points()[0], Point { x: 1.0, y: 2.0 });
133+
assert_eq!(p.points()[1], Point { x: 3.0, y: 4.0 });
134+
assert_eq!(p.points()[2], Point { x: 0.0, y: 5.0 });
135+
assert_eq!(
136+
p.boundbox(),
137+
Box { high: Point { x: 3.0, y: 5.0 }, low: Point { x: 0.0, y: 2.0 } }
138+
);
34139
Ok(())
35140
}
36141
}

0 commit comments

Comments
 (0)