@@ -91,6 +91,11 @@ PG_FUNCTION_INFO_V1(cube_distance);
9191PG_FUNCTION_INFO_V1 (distance_chebyshev );
9292PG_FUNCTION_INFO_V1 (cube_is_point );
9393PG_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*/
110115static double distance_1D (double a1 , double a2 , double b1 , double b2 );
111116static 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+ }
0 commit comments