Skip to content

Commit c02c760

Browse files
Kirill PaninCommitfest Bot
authored andcommitted
Add binary operators for cubes
1 parent 6551a05 commit c02c760

File tree

8 files changed

+310
-2
lines changed

8 files changed

+310
-2
lines changed

contrib/cube/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ OBJS = \
99

1010
EXTENSION = cube
1111
DATA = cube--1.2.sql cube--1.2--1.3.sql cube--1.3--1.4.sql cube--1.4--1.5.sql \
12-
cube--1.1--1.2.sql cube--1.0--1.1.sql
12+
cube--1.1--1.2.sql cube--1.0--1.1.sql cube--1.5--1.6.sql
1313
PGFILEDESC = "cube - multidimensional cube data type"
1414

1515
HEADERS = cubedata.h

contrib/cube/cube--1.5--1.6.sql

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* contrib/cube/cube--1.5--1.6.sql */
2+
3+
-- complain if script is sourced in psql, rather than via ALTER EXTENSION
4+
\echo Use "ALTER EXTENSION cube UPDATE TO '1.6'" to load this file. \quit
5+
6+
CREATE FUNCTION cube_add(cube, cube)
7+
RETURNS cube
8+
AS 'MODULE_PATHNAME'
9+
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
10+
11+
CREATE FUNCTION cube_sub(cube, cube)
12+
RETURNS cube
13+
AS 'MODULE_PATHNAME'
14+
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
15+
16+
CREATE FUNCTION cube_mul_cf(cube, float8)
17+
RETURNS cube
18+
AS 'MODULE_PATHNAME'
19+
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
20+
21+
CREATE FUNCTION cube_mul_fc(float8, cube)
22+
RETURNS cube
23+
AS 'MODULE_PATHNAME'
24+
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
25+
26+
CREATE FUNCTION cube_div(cube, float8)
27+
RETURNS cube
28+
AS 'MODULE_PATHNAME'
29+
LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
30+
31+
-- Add coordinate-wise binary operators
32+
33+
CREATE OPERATOR + (
34+
LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_add,
35+
COMMUTATOR = '+'
36+
);
37+
38+
CREATE OPERATOR - (
39+
LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_sub
40+
);
41+
42+
-- Add coordinate-wise binary operators with scalars
43+
44+
CREATE OPERATOR / (
45+
LEFTARG = cube, RIGHTARG = float8, PROCEDURE = cube_div
46+
);
47+
48+
CREATE OPERATOR * (
49+
LEFTARG = cube, RIGHTARG = float8, PROCEDURE = cube_mul_cf,
50+
COMMUTATOR = '*'
51+
);
52+
53+
CREATE OPERATOR * (
54+
LEFTARG = float8, RIGHTARG = cube, PROCEDURE = cube_mul_fc,
55+
COMMUTATOR = '*'
56+
);

contrib/cube/cube.c

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ PG_FUNCTION_INFO_V1(cube_distance);
9191
PG_FUNCTION_INFO_V1(distance_chebyshev);
9292
PG_FUNCTION_INFO_V1(cube_is_point);
9393
PG_FUNCTION_INFO_V1(cube_enlarge);
94+
PG_FUNCTION_INFO_V1(cube_add);
95+
PG_FUNCTION_INFO_V1(cube_sub);
96+
PG_FUNCTION_INFO_V1(cube_div);
97+
PG_FUNCTION_INFO_V1(cube_mul_cf);
98+
PG_FUNCTION_INFO_V1(cube_mul_fc);
9499

95100
/*
96101
** For internal use only
@@ -109,6 +114,8 @@ bool g_cube_internal_consistent(NDBOX *key, NDBOX *query, StrategyNumber strate
109114
*/
110115
static double distance_1D(double a1, double a2, double b1, double b2);
111116
static bool cube_is_point_internal(NDBOX *cube);
117+
static NDBOX *cube_binop_helper(NDBOX *a, NDBOX *b);
118+
static NDBOX *cube_alloc_shape(NDBOX *a);
112119

113120

114121
/*****************************************************************************
@@ -1911,3 +1918,124 @@ cube_c_f8_f8(PG_FUNCTION_ARGS)
19111918
PG_FREE_IF_COPY(cube, 0);
19121919
PG_RETURN_NDBOX_P(result);
19131920
}
1921+
1922+
static NDBOX *
1923+
cube_alloc_shape(NDBOX *a) {
1924+
NDBOX *result;
1925+
int dim = DIM(a);
1926+
int size;
1927+
1928+
if (IS_POINT(a)) {
1929+
size = POINT_SIZE(dim);
1930+
result = (NDBOX *) palloc0(size);
1931+
SET_POINT_BIT(result);
1932+
} else {
1933+
size = CUBE_SIZE(dim);
1934+
result = (NDBOX *) palloc0(size);
1935+
}
1936+
1937+
SET_VARSIZE(result, size);
1938+
SET_DIM(result, dim);
1939+
1940+
return result;
1941+
}
1942+
1943+
NDBOX *
1944+
cube_binop_helper(NDBOX *a, NDBOX *b)
1945+
{
1946+
if (DIM(a) != DIM(b))
1947+
ereport(ERROR,
1948+
(errcode(ERRCODE_CARDINALITY_VIOLATION),
1949+
errmsg("cubes have different lengths: %d != %d", DIM(a), DIM(b))));
1950+
1951+
if (IS_POINT(a) != IS_POINT(b))
1952+
ereport(ERROR,
1953+
(errcode(ERRCODE_DATA_EXCEPTION),
1954+
errmsg("it's POINTless to add these cubes: %d != %d", IS_POINT(a), IS_POINT(b))));
1955+
1956+
return cube_alloc_shape(a);
1957+
}
1958+
1959+
/*
1960+
* Function returns coordinate-wise sum of cubes.
1961+
*/
1962+
Datum
1963+
cube_add(PG_FUNCTION_ARGS)
1964+
{
1965+
NDBOX *a = PG_GETARG_NDBOX_P(0);
1966+
NDBOX *b = PG_GETARG_NDBOX_P(1);
1967+
NDBOX *result = cube_binop_helper(a, b);
1968+
int i;
1969+
int n = DIM(a) * (IS_POINT(a) ? 1 : 2);
1970+
1971+
for (i = 0; i < n; i++)
1972+
result->x[i] = a->x[i] + b->x[i];
1973+
1974+
PG_RETURN_NDBOX_P(result);
1975+
}
1976+
1977+
/*
1978+
* Function returns coordinate-wise difference of cubes.
1979+
*/
1980+
Datum
1981+
cube_sub(PG_FUNCTION_ARGS)
1982+
{
1983+
NDBOX *a = PG_GETARG_NDBOX_P(0);
1984+
NDBOX *b = PG_GETARG_NDBOX_P(1);
1985+
NDBOX *result = cube_binop_helper(a, b);
1986+
int i;
1987+
int n = DIM(a) * (IS_POINT(a) ? 1 : 2);
1988+
1989+
for (i = 0; i < n; i++)
1990+
result->x[i] = a->x[i] - b->x[i];
1991+
1992+
PG_RETURN_NDBOX_P(result);
1993+
}
1994+
1995+
/*
1996+
* Functions return scaled cube.
1997+
*/
1998+
Datum
1999+
cube_div(PG_FUNCTION_ARGS)
2000+
{
2001+
NDBOX *a = PG_GETARG_NDBOX_P(0);
2002+
double s = PG_GETARG_FLOAT8(1);
2003+
NDBOX *result = cube_alloc_shape(a);
2004+
int i;
2005+
int n = DIM(a) * (IS_POINT(a) ? 1 : 2);
2006+
2007+
for (i = 0; i < n; i++)
2008+
result->x[i] = a->x[i] / s;
2009+
2010+
PG_RETURN_NDBOX_P(result);
2011+
}
2012+
2013+
Datum
2014+
cube_mul_cf(PG_FUNCTION_ARGS)
2015+
{
2016+
NDBOX *a = PG_GETARG_NDBOX_P(0);
2017+
double s = PG_GETARG_FLOAT8(1);
2018+
NDBOX *result = cube_alloc_shape(a);
2019+
int i;
2020+
int n = DIM(a) * (IS_POINT(a) ? 1 : 2);
2021+
2022+
for (i = 0; i < n; i++)
2023+
result->x[i] = a->x[i] * s;
2024+
2025+
PG_RETURN_NDBOX_P(result);
2026+
}
2027+
2028+
Datum
2029+
cube_mul_fc(PG_FUNCTION_ARGS)
2030+
{
2031+
double s = PG_GETARG_FLOAT8(0);
2032+
NDBOX *a = PG_GETARG_NDBOX_P(1);
2033+
NDBOX *result = cube_alloc_shape(a);
2034+
int i;
2035+
int n = DIM(a) * (IS_POINT(a) ? 1 : 2);
2036+
2037+
for (i = 0; i < n; i++)
2038+
result->x[i] = a->x[i] * s;
2039+
2040+
PG_RETURN_NDBOX_P(result);
2041+
}

contrib/cube/cube.control

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# cube extension
22
comment = 'data type for multidimensional cubes'
3-
default_version = '1.5'
3+
default_version = '1.6'
44
module_pathname = '$libdir/cube'
55
relocatable = true
66
trusted = true

contrib/cube/expected/cube.out

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1973,3 +1973,64 @@ SELECT c~>(-4), c FROM test_cube ORDER BY c~>(-4) LIMIT 15; -- descending by upp
19731973
(15 rows)
19741974

19751975
RESET enable_indexscan;
1976+
-- Test of binary operators
1977+
SELECT '(-7,7)'::cube + '(-1,1)'::cube;
1978+
?column?
1979+
----------
1980+
(-8, 8)
1981+
(1 row)
1982+
1983+
SELECT '(-7,7)'::cube - '(-1,1)'::cube;
1984+
?column?
1985+
----------
1986+
(-6, 6)
1987+
(1 row)
1988+
1989+
SELECT '(-1,2)'::cube * 2;
1990+
?column?
1991+
----------
1992+
(-2, 4)
1993+
(1 row)
1994+
1995+
SELECT '(-2,4)'::cube / 2;
1996+
?column?
1997+
----------
1998+
(-1, 2)
1999+
(1 row)
2000+
2001+
SELECT 2 * '(-1,2)'::cube;
2002+
?column?
2003+
----------
2004+
(-2, 4)
2005+
(1 row)
2006+
2007+
SELECT '(-7,7),(2,9)'::cube + '(-1,1),(5,12)'::cube;
2008+
?column?
2009+
-----------------
2010+
(-8, 8),(7, 21)
2011+
(1 row)
2012+
2013+
SELECT '(-7,7),(2,9)'::cube - '(-1,1),(5,12)'::cube;
2014+
?column?
2015+
------------------
2016+
(-6, 6),(-3, -3)
2017+
(1 row)
2018+
2019+
SELECT '(-1,2),(2,9)'::cube * 2;
2020+
?column?
2021+
-----------------
2022+
(-2, 4),(4, 18)
2023+
(1 row)
2024+
2025+
SELECT '(-2,4),(3,7)'::cube / 2;
2026+
?column?
2027+
--------------------
2028+
(-1, 2),(1.5, 3.5)
2029+
(1 row)
2030+
2031+
SELECT 2 * '(-1,2),(2,9)'::cube;
2032+
?column?
2033+
-----------------
2034+
(-2, 4),(4, 18)
2035+
(1 row)
2036+

contrib/cube/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ install_data(
4040
'cube--1.2--1.3.sql',
4141
'cube--1.3--1.4.sql',
4242
'cube--1.4--1.5.sql',
43+
'cube--1.5--1.6.sql',
4344
kwargs: contrib_data_args,
4445
)
4546

contrib/cube/sql/cube.sql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,3 +436,15 @@ SELECT c~>(-2), c FROM test_cube ORDER BY c~>(-2) LIMIT 15; -- descending by rig
436436
SELECT c~>(-3), c FROM test_cube ORDER BY c~>(-3) LIMIT 15; -- descending by lower bound
437437
SELECT c~>(-4), c FROM test_cube ORDER BY c~>(-4) LIMIT 15; -- descending by upper bound
438438
RESET enable_indexscan;
439+
440+
-- Test of binary operators
441+
SELECT '(-7,7)'::cube + '(-1,1)'::cube;
442+
SELECT '(-7,7)'::cube - '(-1,1)'::cube;
443+
SELECT '(-1,2)'::cube * 2;
444+
SELECT '(-2,4)'::cube / 2;
445+
SELECT 2 * '(-1,2)'::cube;
446+
SELECT '(-7,7),(2,9)'::cube + '(-1,1),(5,12)'::cube;
447+
SELECT '(-7,7),(2,9)'::cube - '(-1,1),(5,12)'::cube;
448+
SELECT '(-1,2),(2,9)'::cube * 2;
449+
SELECT '(-2,4),(3,7)'::cube / 2;
450+
SELECT 2 * '(-1,2),(2,9)'::cube;

doc/src/sgml/cube.sgml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,56 @@
218218
Computes the Chebyshev (L-inf metric) distance between the two cubes.
219219
</para></entry>
220220
</row>
221+
222+
<row>
223+
<entry role="func_table_entry"><para role="func_signature">
224+
<type>cube</type> <literal>+</literal> <type>cube</type>
225+
<returnvalue>cube</returnvalue>
226+
</para>
227+
<para>
228+
Computes the coordinate-wise sum of two cubes.
229+
</para></entry>
230+
</row>
231+
232+
<row>
233+
<entry role="func_table_entry"><para role="func_signature">
234+
<type>cube</type> <literal>-</literal> <type>cube</type>
235+
<returnvalue>cube</returnvalue>
236+
</para>
237+
<para>
238+
Computes the coordinate-wise difference of two cubes.
239+
</para></entry>
240+
</row>
241+
242+
<row>
243+
<entry role="func_table_entry"><para role="func_signature">
244+
<type>cube</type> <literal>*</literal> <type>float8</type>
245+
<returnvalue>cube</returnvalue>
246+
</para>
247+
<para>
248+
Computes the coordinate-wise multiplication of a cube by a scalar value.
249+
</para></entry>
250+
</row>
251+
252+
<row>
253+
<entry role="func_table_entry"><para role="func_signature">
254+
<type>float8</type> <literal>*</literal> <type>cube</type>
255+
<returnvalue>cube</returnvalue>
256+
</para>
257+
<para>
258+
Computes the coordinate-wise multiplication of a cube by a scalar value.
259+
</para></entry>
260+
</row>
261+
262+
<row>
263+
<entry role="func_table_entry"><para role="func_signature">
264+
<type>cube</type> <literal>/</literal> <type>float8</type>
265+
<returnvalue>cube</returnvalue>
266+
</para>
267+
<para>
268+
Computes the coordinate-wise division of a cube by a scalar value.
269+
</para></entry>
270+
</row>
221271
</tbody>
222272
</tgroup>
223273
</table>

0 commit comments

Comments
 (0)