mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-29 22:49:41 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			360 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			360 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| 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(text) returns cube
 | |
|   cube takes text input and returns a cube. This is useful for making cubes
 | |
|   from computed strings.
 | |
| 
 | |
| 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.
 |