/contrib/cube improvements:

Update the calling convention for all external facing functions. By
external facing, I mean all functions that are directly referenced in
cube.sql. Prior to my update, all functions used the older V0 calling
convention. They now use V1.

New Functions:

cube(float[]), which makes a zero volume cube from a float array

cube(float[], float[]), which allows the user to create a cube from
two float arrays; one for the upper right and one for the lower left
coordinate.

cube_subset(cube, int4[]), to allow you to reorder or choose a subset of
dimensions from a cube, using index values specified in the array.

Joshua Reich
This commit is contained in:
Bruce Momjian 2006-07-25 23:23:45 +00:00
parent e6284649b9
commit 796de9c1ed
7 changed files with 663 additions and 197 deletions

View File

@ -1,4 +1,28 @@
********************************************************************************
Changes that were made in July 2006 by Joshua Reich I.
********************************************************************************
Code Cleanup:
Update the calling convention for all external facing functions. By external
facing, I mean all functions that are directly referenced in cube.sql. Prior
to my update, all functions used the older V0 calling convention. They now
use V1.
New Functions:
cube(float[]), which makes a zero volume cube from a float array
cube(float[], float[]), which allows the user to create a cube from
two float arrays; one for the upper right and one for the lower left
coordinate.
cube_subset(cube, int4[]), to allow you to reorder or choose a subset of
dimensions from a cube, using index values specified in the array.
********************************************************************************
Changes that were made in August/September 2002 by Bruno Wolff III. Changes that were made in August/September 2002 by Bruno Wolff III.
********************************************************************************
Note that this was based on a 7.3 development version and changes may not Note that this was based on a 7.3 development version and changes may not
directly work with earlier versions. directly work with earlier versions.

View File

@ -244,6 +244,16 @@ cube(float8, float8) returns cube
This makes a one dimensional cube. This makes a one dimensional cube.
cube(1,2) == '(1),(2)' cube(1,2) == '(1),(2)'
cube(float8[]) returns cube
This makes a zero-volume cube using the coordinates defined by the
array.
cube(ARRAY[1,2]) == '(1,2)'
cube(float8[], float8[]) returns cube
This makes a cube, with upper right and lower left coordinates as
defined by the 2 float arrays. Arrays must be of the same length.
cube('{1,2}'::float[], '{3,4}'::float[]) == '(1,2),(3,4)'
cube(cube, float8) returns cube cube(cube, float8) returns cube
This builds a new cube by adding a dimension on to an existing cube with This builds a new cube by adding a dimension on to an existing cube with
the same values for both parts of the new coordinate. This is useful for the same values for both parts of the new coordinate. This is useful for
@ -267,6 +277,13 @@ cube_ur_coord(cube, int) returns double
cube_ur_coord returns the nth coordinate value for the upper right corner cube_ur_coord returns the nth coordinate value for the upper right corner
of a cube. This is useful for doing coordinate transformations. of a cube. This is useful for doing coordinate transformations.
cube_subset(cube, int[]) returns cube
Builds a new cube from an existing cube, using a list of dimension indexes
from an array. Can be used to find both the ll and ur coordinate of single
dimenion, e.g.: cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[2]) = '(3),(7)'
Or can be used to drop dimensions, or reorder them as desired, e.g.:
cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]) = '(5, 3, 1, 1),(8, 7, 6, 6)'
cube_is_point(cube) returns bool cube_is_point(cube) returns bool
cube_is_point returns true if a cube is also a point. This is true when the cube_is_point returns true if a cube is also a point. This is true when the
two defining corners are the same. two defining corners are the same.
@ -327,3 +344,10 @@ in August/September of 2002.
These include changing the precision from single precision to double These include changing the precision from single precision to double
precision and adding some new functions. precision and adding some new functions.
------------------------------------------------------------------------
Additional updates were made by Joshua Reich <josh@root.net> in July 2006.
These include cube(float8[], float8[]) and cleaning up the code to use
the V1 call protocol instead of the deprecated V0 form.

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,14 @@ RETURNS cube
AS 'MODULE_PATHNAME' AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE STRICT; LANGUAGE C IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION cube(float8[], float8[]) RETURNS cube
AS 'MODULE_PATHNAME', 'cube_a_f8_f8'
LANGUAGE C IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION cube(float8[]) RETURNS cube
AS 'MODULE_PATHNAME', 'cube_a_f8'
LANGUAGE C IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION cube_out(cube) CREATE OR REPLACE FUNCTION cube_out(cube)
RETURNS cstring RETURNS cstring
AS 'MODULE_PATHNAME' AS 'MODULE_PATHNAME'
@ -129,6 +137,11 @@ LANGUAGE C IMMUTABLE STRICT;
-- Misc N-dimensional functions -- Misc N-dimensional functions
CREATE OR REPLACE FUNCTION cube_subset(cube, int4[])
RETURNS cube
AS 'MODULE_PATHNAME'
LANGUAGE C IMMUTABLE STRICT;
-- proximity routines -- proximity routines
CREATE OR REPLACE FUNCTION cube_distance(cube, cube) CREATE OR REPLACE FUNCTION cube_distance(cube, cube)

View File

@ -8,7 +8,9 @@
\set ECHO none \set ECHO none
psql:cube.sql:10: NOTICE: type "cube" is not yet defined psql:cube.sql:10: NOTICE: type "cube" is not yet defined
DETAIL: Creating a shell type definition. DETAIL: Creating a shell type definition.
psql:cube.sql:15: NOTICE: argument type cube is only a shell psql:cube.sql:14: NOTICE: return type cube is only a shell
psql:cube.sql:18: NOTICE: return type cube is only a shell
psql:cube.sql:23: NOTICE: argument type cube is only a shell
-- --
-- testing the input and output functions -- testing the input and output functions
-- --
@ -395,6 +397,37 @@ SELECT '(0)'::text::cube;
(0) (0)
(1 row) (1 row)
--
-- Test the float[] -> cube cast
--
SELECT cube('{0,1,2}'::float[], '{3,4,5}'::float[]);
cube
---------------------
(0, 1, 2),(3, 4, 5)
(1 row)
SELECT cube('{0,1,2}'::float[], '{3}'::float[]);
ERROR: UR and LL arrays must be of same length
SELECT cube(NULL::float[], '{3}'::float[]);
cube
------
(1 row)
SELECT cube('{0,1,2}'::float[]);
cube
-----------
(0, 1, 2)
(1 row)
SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]);
cube_subset
---------------------------
(5, 3, 1, 1),(8, 7, 6, 6)
(1 row)
SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]);
ERROR: Index out of bounds
-- --
-- Testing limit of CUBE_MAX_DIM dimensions check in cube_in. -- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
-- --
@ -1021,24 +1054,24 @@ SELECT cube_enlarge('(2,-2),(-3,7)'::cube, -3, 2);
CREATE TABLE test_cube (c cube); CREATE TABLE test_cube (c cube);
\copy test_cube from 'data/test_cube.data' \copy test_cube from 'data/test_cube.data'
CREATE INDEX test_cube_ix ON test_cube USING gist (c); CREATE INDEX test_cube_ix ON test_cube USING gist (c);
SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)'; SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)' ORDER BY c;
c c
-------------------------- --------------------------
(2424, 160),(2424, 81)
(759, 187),(662, 163)
(1444, 403),(1346, 344)
(337, 455),(240, 359)
(1594, 1043),(1517, 971) (1594, 1043),(1517, 971)
(337, 455),(240, 359)
(1444, 403),(1346, 344)
(759, 187),(662, 163)
(2424, 160),(2424, 81)
(5 rows) (5 rows)
-- Test sorting -- Test sorting
SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)' GROUP BY c; SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)' GROUP BY c ORDER BY c;
c c
-------------------------- --------------------------
(337, 455),(240, 359)
(759, 187),(662, 163)
(1444, 403),(1346, 344)
(1594, 1043),(1517, 971) (1594, 1043),(1517, 971)
(337, 455),(240, 359)
(1444, 403),(1346, 344)
(759, 187),(662, 163)
(2424, 160),(2424, 81) (2424, 160),(2424, 81)
(5 rows) (5 rows)

View File

@ -110,6 +110,16 @@ SELECT cube(cube(cube(1,2),3,4),5,6);
SELECT '(0)'::text::cube; SELECT '(0)'::text::cube;
--
-- Test the float[] -> cube cast
--
SELECT cube('{0,1,2}'::float[], '{3,4,5}'::float[]);
SELECT cube('{0,1,2}'::float[], '{3}'::float[]);
SELECT cube(NULL::float[], '{3}'::float[]);
SELECT cube('{0,1,2}'::float[]);
SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[3,2,1,1]);
SELECT cube_subset(cube('(1,3,5),(6,7,8)'), ARRAY[4,0]);
-- --
-- Testing limit of CUBE_MAX_DIM dimensions check in cube_in. -- Testing limit of CUBE_MAX_DIM dimensions check in cube_in.
-- --
@ -269,7 +279,7 @@ CREATE TABLE test_cube (c cube);
\copy test_cube from 'data/test_cube.data' \copy test_cube from 'data/test_cube.data'
CREATE INDEX test_cube_ix ON test_cube USING gist (c); CREATE INDEX test_cube_ix ON test_cube USING gist (c);
SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)'; SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)' ORDER BY c;
-- Test sorting -- Test sorting
SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)' GROUP BY c; SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)' GROUP BY c ORDER BY c;

View File

@ -46,6 +46,12 @@ DROP FUNCTION cube(cube, float8);
DROP FUNCTION cube(float8, float8); DROP FUNCTION cube(float8, float8);
DROP FUNCTION cube(float8[], float8[]);
DROP FUNCTION cube(float8[]);
DROP FUNCTION cube_subset(cube, int4[]);
DROP FUNCTION cube(float8); DROP FUNCTION cube(float8);
DROP FUNCTION cube_ur_coord(cube, int4); DROP FUNCTION cube_ur_coord(cube, int4);