mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Move most /contrib README files into SGML. Some still need conversion
or will never be converted.
This commit is contained in:
@ -1,355 +0,0 @@
|
||||
This directory contains the code for the user-defined type,
|
||||
CUBE, representing multidimensional cubes.
|
||||
|
||||
|
||||
FILES
|
||||
-----
|
||||
|
||||
Makefile building instructions for the shared library
|
||||
|
||||
README.cube the file you are now reading
|
||||
|
||||
cube.c the implementation of this data type in c
|
||||
|
||||
cube.sql.in SQL code needed to register this type with postgres
|
||||
(transformed to cube.sql by make)
|
||||
|
||||
cubedata.h the data structure used to store the cubes
|
||||
|
||||
cubeparse.y the grammar file for the parser (used by cube_in() in cube.c)
|
||||
|
||||
cubescan.l scanner rules (used by cube_yyparse() in cubeparse.y)
|
||||
|
||||
|
||||
INSTALLATION
|
||||
============
|
||||
|
||||
To install the type, run
|
||||
|
||||
make
|
||||
make install
|
||||
|
||||
The user running "make install" may need root access; depending on how you
|
||||
configured the PostgreSQL installation paths.
|
||||
|
||||
This only installs the type implementation and documentation. To make the
|
||||
type available in any particular database, as a postgres superuser do:
|
||||
|
||||
psql -d databasename < cube.sql
|
||||
|
||||
If you install the type in the template1 database, all subsequently created
|
||||
databases will inherit it.
|
||||
|
||||
To test the new type, after "make install" do
|
||||
|
||||
make installcheck
|
||||
|
||||
If it fails, examine the file regression.diffs to find out the reason (the
|
||||
test code is a direct adaptation of the regression tests from the main
|
||||
source tree).
|
||||
|
||||
By default the external functions are made executable by anyone.
|
||||
|
||||
SYNTAX
|
||||
======
|
||||
|
||||
The following are valid external representations for the CUBE type:
|
||||
|
||||
'x' A floating point value representing
|
||||
a one-dimensional point or one-dimensional
|
||||
zero length cubement
|
||||
|
||||
'(x)' Same as above
|
||||
|
||||
'x1,x2,x3,...,xn' A point in n-dimensional space,
|
||||
represented internally as a zero volume box
|
||||
|
||||
'(x1,x2,x3,...,xn)' Same as above
|
||||
|
||||
'(x),(y)' 1-D cubement starting at x and ending at y
|
||||
or vice versa; the order does not matter
|
||||
|
||||
'(x1,...,xn),(y1,...,yn)' n-dimensional box represented by
|
||||
a pair of its opposite corners, no matter which.
|
||||
Functions take care of swapping to achieve
|
||||
"lower left -- upper right" representation
|
||||
before computing any values
|
||||
|
||||
Grammar
|
||||
-------
|
||||
|
||||
rule 1 box -> O_BRACKET paren_list COMMA paren_list C_BRACKET
|
||||
rule 2 box -> paren_list COMMA paren_list
|
||||
rule 3 box -> paren_list
|
||||
rule 4 box -> list
|
||||
rule 5 paren_list -> O_PAREN list C_PAREN
|
||||
rule 6 list -> FLOAT
|
||||
rule 7 list -> list COMMA FLOAT
|
||||
|
||||
Tokens
|
||||
------
|
||||
|
||||
n [0-9]+
|
||||
integer [+-]?{n}
|
||||
real [+-]?({n}\.{n}?|\.{n})
|
||||
FLOAT ({integer}|{real})([eE]{integer})?
|
||||
O_BRACKET \[
|
||||
C_BRACKET \]
|
||||
O_PAREN \(
|
||||
C_PAREN \)
|
||||
COMMA \,
|
||||
|
||||
|
||||
Examples of valid CUBE representations:
|
||||
--------------------------------------
|
||||
|
||||
'x' A floating point value representing
|
||||
a one-dimensional point (or, zero-length
|
||||
one-dimensional interval)
|
||||
|
||||
'(x)' Same as above
|
||||
|
||||
'x1,x2,x3,...,xn' A point in n-dimensional space,
|
||||
represented internally as a zero volume cube
|
||||
|
||||
'(x1,x2,x3,...,xn)' Same as above
|
||||
|
||||
'(x),(y)' A 1-D interval starting at x and ending at y
|
||||
or vice versa; the order does not matter
|
||||
|
||||
'[(x),(y)]' Same as above
|
||||
|
||||
'(x1,...,xn),(y1,...,yn)' An n-dimensional box represented by
|
||||
a pair of its diagonally opposite corners,
|
||||
regardless of order. Swapping is provided
|
||||
by all comarison routines to ensure the
|
||||
"lower left -- upper right" representation
|
||||
before actaul comparison takes place.
|
||||
|
||||
'[(x1,...,xn),(y1,...,yn)]' Same as above
|
||||
|
||||
|
||||
White space is ignored, so '[(x),(y)]' can be: '[ ( x ), ( y ) ]'
|
||||
|
||||
|
||||
DEFAULTS
|
||||
========
|
||||
|
||||
I believe this union:
|
||||
|
||||
select cube_union('(0,5,2),(2,3,1)','0');
|
||||
cube_union
|
||||
-------------------
|
||||
(0, 0, 0),(2, 5, 2)
|
||||
(1 row)
|
||||
|
||||
does not contradict to the common sense, neither does the intersection
|
||||
|
||||
select cube_inter('(0,-1),(1,1)','(-2),(2)');
|
||||
cube_inter
|
||||
-------------
|
||||
(0, 0),(1, 0)
|
||||
(1 row)
|
||||
|
||||
In all binary operations on differently sized boxes, I assume the smaller
|
||||
one to be a cartesian projection, i. e., having zeroes in place of coordinates
|
||||
omitted in the string representation. The above examples are equivalent to:
|
||||
|
||||
cube_union('(0,5,2),(2,3,1)','(0,0,0),(0,0,0)');
|
||||
cube_inter('(0,-1),(1,1)','(-2,0),(2,0)');
|
||||
|
||||
|
||||
The following containment predicate uses the point syntax,
|
||||
while in fact the second argument is internally represented by a box.
|
||||
This syntax makes it unnecessary to define the special Point type
|
||||
and functions for (box,point) predicates.
|
||||
|
||||
select cube_contains('(0,0),(1,1)', '0.5,0.5');
|
||||
cube_contains
|
||||
--------------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
|
||||
PRECISION
|
||||
=========
|
||||
|
||||
Values are stored internally as 64-bit floating point numbers. This means that
|
||||
numbers with more than about 16 significant digits will be truncated.
|
||||
|
||||
|
||||
USAGE
|
||||
=====
|
||||
|
||||
The access method for CUBE is a GiST index (gist_cube_ops), which is a
|
||||
generalization of R-tree. GiSTs allow the postgres implementation of
|
||||
R-tree, originally encoded to support 2-D geometric types such as
|
||||
boxes and polygons, to be used with any data type whose data domain
|
||||
can be partitioned using the concepts of containment, intersection and
|
||||
equality. In other words, everything that can intersect or contain
|
||||
its own kind can be indexed with a GiST. That includes, among other
|
||||
things, all geometric data types, regardless of their dimensionality
|
||||
(see also contrib/seg).
|
||||
|
||||
The operators supported by the GiST access method include:
|
||||
|
||||
a = b Same as
|
||||
|
||||
The cubements a and b are identical.
|
||||
|
||||
a && b Overlaps
|
||||
|
||||
The cubements a and b overlap.
|
||||
|
||||
a @> b Contains
|
||||
|
||||
The cubement a contains the cubement b.
|
||||
|
||||
a <@ b Contained in
|
||||
|
||||
The cubement a is contained in b.
|
||||
|
||||
(Before PostgreSQL 8.2, the containment operators @> and <@ were
|
||||
respectively called @ and ~. These names are still available, but are
|
||||
deprecated and will eventually be retired. Notice that the old names
|
||||
are reversed from the convention formerly followed by the core geometric
|
||||
datatypes!)
|
||||
|
||||
Although the mnemonics of the following operators is questionable, I
|
||||
preserved them to maintain visual consistency with other geometric
|
||||
data types defined in Postgres.
|
||||
|
||||
Other operators:
|
||||
|
||||
[a, b] < [c, d] Less than
|
||||
[a, b] > [c, d] Greater than
|
||||
|
||||
These operators do not make a lot of sense for any practical
|
||||
purpose but sorting. These operators first compare (a) to (c),
|
||||
and if these are equal, compare (b) to (d). That accounts for
|
||||
reasonably good sorting in most cases, which is useful if
|
||||
you want to use ORDER BY with this type
|
||||
|
||||
The following functions are available:
|
||||
|
||||
cube_distance(cube, cube) returns double
|
||||
cube_distance returns the distance between two cubes. If both cubes are
|
||||
points, this is the normal distance function.
|
||||
|
||||
cube(float8) returns cube
|
||||
This makes a one dimensional cube with both coordinates the same.
|
||||
If the type of the argument is a numeric type other than float8 an
|
||||
explicit cast to float8 may be needed.
|
||||
cube(1) == '(1)'
|
||||
|
||||
cube(float8, float8) returns cube
|
||||
This makes a one dimensional cube.
|
||||
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
|
||||
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
|
||||
building cubes piece by piece from calculated values.
|
||||
cube('(1)',2) == '(1,2),(1,2)'
|
||||
|
||||
cube(cube, float8, float8) returns cube
|
||||
This builds a new cube by adding a dimension on to an existing cube.
|
||||
This is useful for building cubes piece by piece from calculated values.
|
||||
cube('(1,2)',3,4) == '(1,3),(2,4)'
|
||||
|
||||
cube_dim(cube) returns int
|
||||
cube_dim returns the number of dimensions stored in the the data structure
|
||||
for a cube. This is useful for constraints on the dimensions of a cube.
|
||||
|
||||
cube_ll_coord(cube, int) returns double
|
||||
cube_ll_coord returns the nth coordinate value for the lower left corner
|
||||
of a cube. This is useful for doing coordinate transformations.
|
||||
|
||||
cube_ur_coord(cube, int) returns double
|
||||
cube_ur_coord returns the nth coordinate value for the upper right corner
|
||||
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 returns true if a cube is also a point. This is true when the
|
||||
two defining corners are the same.
|
||||
|
||||
cube_enlarge(cube, double, int) returns cube
|
||||
cube_enlarge increases the size of a cube by a specified radius in at least
|
||||
n dimensions. If the radius is negative the box is shrunk instead. This
|
||||
is useful for creating bounding boxes around a point for searching for
|
||||
nearby points. All defined dimensions are changed by the radius. If n
|
||||
is greater than the number of defined dimensions and the cube is being
|
||||
increased (r >= 0) then 0 is used as the base for the extra coordinates.
|
||||
LL coordinates are decreased by r and UR coordinates are increased by r. If
|
||||
a LL coordinate is increased to larger than the corresponding UR coordinate
|
||||
(this can only happen when r < 0) than both coordinates are set to their
|
||||
average. To make it harder for people to break things there is an effective
|
||||
maximum on the dimension of cubes of 100. This is set in cubedata.h if
|
||||
you need something bigger.
|
||||
|
||||
There are a few other potentially useful functions defined in cube.c
|
||||
that vanished from the schema because I stopped using them. Some of
|
||||
these were meant to support type casting. Let me know if I was wrong:
|
||||
I will then add them back to the schema. I would also appreciate
|
||||
other ideas that would enhance the type and make it more useful.
|
||||
|
||||
For examples of usage, see sql/cube.sql
|
||||
|
||||
|
||||
CREDITS
|
||||
=======
|
||||
|
||||
This code is essentially based on the example written for
|
||||
Illustra, http://garcia.me.berkeley.edu/~adong/rtree
|
||||
|
||||
My thanks are primarily to Prof. Joe Hellerstein
|
||||
(http://db.cs.berkeley.edu/~jmh/) for elucidating the gist of the GiST
|
||||
(http://gist.cs.berkeley.edu/), and to his former student, Andy Dong
|
||||
(http://best.me.berkeley.edu/~adong/), for his exemplar.
|
||||
I am also grateful to all postgres developers, present and past, for enabling
|
||||
myself to create my own world and live undisturbed in it. And I would like to
|
||||
acknowledge my gratitude to Argonne Lab and to the U.S. Department of Energy
|
||||
for the years of faithful support of my database research.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
Gene Selkov, Jr.
|
||||
Computational Scientist
|
||||
Mathematics and Computer Science Division
|
||||
Argonne National Laboratory
|
||||
9700 S Cass Ave.
|
||||
Building 221
|
||||
Argonne, IL 60439-4844
|
||||
|
||||
selkovjr@mcs.anl.gov
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Minor updates to this package were made by Bruno Wolff III <bruno@wolff.to>
|
||||
in August/September of 2002.
|
||||
|
||||
These include changing the precision from single precision to double
|
||||
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.
|
Reference in New Issue
Block a user