summaryrefslogtreecommitdiff
path: root/contrib/tablefunc/README.tablefunc
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tablefunc/README.tablefunc')
-rw-r--r--contrib/tablefunc/README.tablefunc642
1 files changed, 0 insertions, 642 deletions
diff --git a/contrib/tablefunc/README.tablefunc b/contrib/tablefunc/README.tablefunc
deleted file mode 100644
index c54f53231bb..00000000000
--- a/contrib/tablefunc/README.tablefunc
+++ /dev/null
@@ -1,642 +0,0 @@
-/*
- * tablefunc
- *
- * Sample to demonstrate C functions which return setof scalar
- * and setof composite.
- * Joe Conway <[email protected]>
- * And contributors:
- * Nabil Sayegh <[email protected]>
- *
- * Copyright (c) 2002-2007, PostgreSQL Global Development Group
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without a written agreement
- * is hereby granted, provided that the above copyright notice and this
- * paragraph and the following two paragraphs appear in all copies.
- *
- * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
- * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
- * DOCUMENTATION, EVEN IF THE AUTHOR OR DISTRIBUTORS HAVE BEEN ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAS NO OBLIGATIONS TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- */
-Version 0.1 (20 July, 2002):
- First release
-
-Release Notes:
-
- Version 0.1
- - initial release
-
-Installation:
- Place these files in a directory called 'tablefunc' under 'contrib' in the
- PostgreSQL source tree. Then run:
-
- make
- make install
-
- You can use tablefunc.sql to create the functions in your database of choice, e.g.
-
- psql -U postgres template1 < tablefunc.sql
-
- installs following functions into database template1:
-
- normal_rand(int numvals, float8 mean, float8 stddev)
- - returns a set of normally distributed float8 values
-
- crosstabN(text sql)
- - returns a set of row_name plus N category value columns
- - crosstab2(), crosstab3(), and crosstab4() are defined for you,
- but you can create additional crosstab functions per the instructions
- in the documentation below.
-
- crosstab(text sql)
- - returns a set of row_name plus N category value columns
- - requires anonymous composite type syntax in the FROM clause. See
- the instructions in the documentation below.
-
- crosstab(text sql, N int)
- - obsolete version of crosstab()
- - the argument N is now ignored, since the number of value columns
- is always determined by the calling query
-
- connectby(text relname, text keyid_fld, text parent_keyid_fld
- [, text orderby_fld], text start_with, int max_depth
- [, text branch_delim])
- - returns keyid, parent_keyid, level, and an optional branch string
- and an optional serial column for ordering siblings
- - requires anonymous composite type syntax in the FROM clause. See
- the instructions in the documentation below.
-
-Documentation
-==================================================================
-Name
-
-normal_rand(int, float8, float8) - returns a set of normally
- distributed float8 values
-
-Synopsis
-
-normal_rand(int numvals, float8 mean, float8 stddev)
-
-Inputs
-
- numvals
- the number of random values to be returned from the function
-
- mean
- the mean of the normal distribution of values
-
- stddev
- the standard deviation of the normal distribution of values
-
-Outputs
-
- Returns setof float8, where the returned set of random values are normally
- distributed (Gaussian distribution)
-
-Example usage
-
- test=# SELECT * FROM
- test=# normal_rand(1000, 5, 3);
- normal_rand
-----------------------
- 1.56556322244898
- 9.10040991424657
- 5.36957140345079
- -0.369151492880995
- 0.283600703686639
- .
- .
- .
- 4.82992125404908
- 9.71308014517282
- 2.49639286969028
-(1000 rows)
-
- Returns 1000 values with a mean of 5 and a standard deviation of 3.
-
-==================================================================
-Name
-
-crosstabN(text) - returns a set of row_name plus N category value columns
-
-Synopsis
-
-crosstabN(text sql)
-
-Inputs
-
- sql
-
- A SQL statement which produces the source set of data. The SQL statement
- must return one row_name column, one category column, and one value
- column. row_name and value must be of type text.
-
- e.g. provided sql must produce a set something like:
-
- row_name cat value
- ----------+-------+-------
- row1 cat1 val1
- row1 cat2 val2
- row1 cat3 val3
- row1 cat4 val4
- row2 cat1 val5
- row2 cat2 val6
- row2 cat3 val7
- row2 cat4 val8
-
-Outputs
-
- Returns setof tablefunc_crosstab_N, which is defined by:
-
- CREATE TYPE tablefunc_crosstab_N AS (
- row_name TEXT,
- category_1 TEXT,
- category_2 TEXT,
- .
- .
- .
- category_N TEXT
- );
-
- for the default installed functions, where N is 2, 3, or 4.
-
- e.g. the provided crosstab2 function produces a set something like:
- <== values columns ==>
- row_name category_1 category_2
- ---------+------------+------------
- row1 val1 val2
- row2 val5 val6
-
-Notes
-
- 1. The sql result must be ordered by 1,2.
-
- 2. The number of values columns depends on the tuple description
- of the function's declared return type.
-
- 3. Missing values (i.e. not enough adjacent rows of same row_name to
- fill the number of result values columns) are filled in with nulls.
-
- 4. Extra values (i.e. too many adjacent rows of same row_name to fill
- the number of result values columns) are skipped.
-
- 5. Rows with all nulls in the values columns are skipped.
-
- 6. The installed defaults are for illustration purposes. You
- can create your own return types and functions based on the
- crosstab() function of the installed library. See below for
- details.
-
-
-Example usage
-
-create table ct(id serial, rowclass text, rowid text, attribute text, value text);
-insert into ct(rowclass, rowid, attribute, value) values('group1','test1','att1','val1');
-insert into ct(rowclass, rowid, attribute, value) values('group1','test1','att2','val2');
-insert into ct(rowclass, rowid, attribute, value) values('group1','test1','att3','val3');
-insert into ct(rowclass, rowid, attribute, value) values('group1','test1','att4','val4');
-insert into ct(rowclass, rowid, attribute, value) values('group1','test2','att1','val5');
-insert into ct(rowclass, rowid, attribute, value) values('group1','test2','att2','val6');
-insert into ct(rowclass, rowid, attribute, value) values('group1','test2','att3','val7');
-insert into ct(rowclass, rowid, attribute, value) values('group1','test2','att4','val8');
-
-select * from crosstab3(
- 'select rowid, attribute, value
- from ct
- where rowclass = ''group1''
- and (attribute = ''att2'' or attribute = ''att3'') order by 1,2;');
-
- row_name | category_1 | category_2 | category_3
-----------+------------+------------+------------
- test1 | val2 | val3 |
- test2 | val6 | val7 |
-(2 rows)
-
-==================================================================
-Name
-
-crosstab(text) - returns a set of row_names plus category value columns
-
-Synopsis
-
-crosstab(text sql)
-
-crosstab(text sql, int N)
-
-Inputs
-
- sql
-
- A SQL statement which produces the source set of data. The SQL statement
- must return one row_name column, one category column, and one value
- column.
-
- e.g. provided sql must produce a set something like:
-
- row_name cat value
- ----------+-------+-------
- row1 cat1 val1
- row1 cat2 val2
- row1 cat3 val3
- row1 cat4 val4
- row2 cat1 val5
- row2 cat2 val6
- row2 cat3 val7
- row2 cat4 val8
-
- N
-
- Obsolete argument; ignored if supplied (formerly this had to match
- the number of category columns determined by the calling query)
-
-Outputs
-
- Returns setof record, which must be defined with a column definition
- in the FROM clause of the SELECT statement, e.g.:
-
- SELECT *
- FROM crosstab(sql) AS ct(row_name text, category_1 text, category_2 text);
-
- the example crosstab function produces a set something like:
- <== values columns ==>
- row_name category_1 category_2
- ---------+------------+------------
- row1 val1 val2
- row2 val5 val6
-
-Notes
-
- 1. The sql result must be ordered by 1,2.
-
- 2. The number of values columns is determined by the column definition
- provided in the FROM clause. The FROM clause must define one
- row_name column (of the same datatype as the first result column
- of the sql query) followed by N category columns (of the same
- datatype as the third result column of the sql query). You can
- set up as many category columns as you wish.
-
- 3. Missing values (i.e. not enough adjacent rows of same row_name to
- fill the number of result values columns) are filled in with nulls.
-
- 4. Extra values (i.e. too many adjacent rows of same row_name to fill
- the number of result values columns) are skipped.
-
- 5. Rows with all nulls in the values columns are skipped.
-
- 6. You can avoid always having to write out a FROM clause that defines the
- output columns by setting up a custom crosstab function that has
- the desired output row type wired into its definition.
-
- There are two ways you can set up a custom crosstab function:
-
- A. Create a composite type to define your return type, similar to the
- examples in the installation script. Then define a unique function
- name accepting one text parameter and returning setof your_type_name.
- For example, if your source data produces row_names that are TEXT,
- and values that are FLOAT8, and you want 5 category columns:
-
- CREATE TYPE my_crosstab_float8_5_cols AS (
- row_name TEXT,
- category_1 FLOAT8,
- category_2 FLOAT8,
- category_3 FLOAT8,
- category_4 FLOAT8,
- category_5 FLOAT8
- );
-
- CREATE OR REPLACE FUNCTION crosstab_float8_5_cols(text)
- RETURNS setof my_crosstab_float8_5_cols
- AS '$libdir/tablefunc','crosstab' LANGUAGE C STABLE STRICT;
-
- B. Use OUT parameters to define the return type implicitly.
- The same example could also be done this way:
-
- CREATE OR REPLACE FUNCTION crosstab_float8_5_cols(IN text,
- OUT row_name TEXT,
- OUT category_1 FLOAT8,
- OUT category_2 FLOAT8,
- OUT category_3 FLOAT8,
- OUT category_4 FLOAT8,
- OUT category_5 FLOAT8)
- RETURNS setof record
- AS '$libdir/tablefunc','crosstab' LANGUAGE C STABLE STRICT;
-
-
-Example usage
-
-create table ct(id serial, rowclass text, rowid text, attribute text, value text);
-insert into ct(rowclass, rowid, attribute, value) values('group1','test1','att1','val1');
-insert into ct(rowclass, rowid, attribute, value) values('group1','test1','att2','val2');
-insert into ct(rowclass, rowid, attribute, value) values('group1','test1','att3','val3');
-insert into ct(rowclass, rowid, attribute, value) values('group1','test1','att4','val4');
-insert into ct(rowclass, rowid, attribute, value) values('group1','test2','att1','val5');
-insert into ct(rowclass, rowid, attribute, value) values('group1','test2','att2','val6');
-insert into ct(rowclass, rowid, attribute, value) values('group1','test2','att3','val7');
-insert into ct(rowclass, rowid, attribute, value) values('group1','test2','att4','val8');
-
-SELECT *
-FROM crosstab(
- 'select rowid, attribute, value
- from ct
- where rowclass = ''group1''
- and (attribute = ''att2'' or attribute = ''att3'') order by 1,2;', 3)
-AS ct(row_name text, category_1 text, category_2 text, category_3 text);
-
- row_name | category_1 | category_2 | category_3
-----------+------------+------------+------------
- test1 | val2 | val3 |
- test2 | val6 | val7 |
-(2 rows)
-
-==================================================================
-Name
-
-crosstab(text, text) - returns a set of row_name, extra, and
- category value columns
-
-Synopsis
-
-crosstab(text source_sql, text category_sql)
-
-Inputs
-
- source_sql
-
- A SQL statement which produces the source set of data. The SQL statement
- must return one row_name column, one category column, and one value
- column. It may also have one or more "extra" columns.
-
- The row_name column must be first. The category and value columns
- must be the last two columns, in that order. "extra" columns must be
- columns 2 through (N - 2), where N is the total number of columns.
-
- The "extra" columns are assumed to be the same for all rows with the
- same row_name. The values returned are copied from the first row
- with a given row_name and subsequent values of these columns are ignored
- until row_name changes.
-
- e.g. source_sql must produce a set something like:
- SELECT row_name, extra_col, cat, value FROM foo;
-
- row_name extra_col cat value
- ----------+------------+-----+---------
- row1 extra1 cat1 val1
- row1 extra1 cat2 val2
- row1 extra1 cat4 val4
- row2 extra2 cat1 val5
- row2 extra2 cat2 val6
- row2 extra2 cat3 val7
- row2 extra2 cat4 val8
-
- category_sql
-
- A SQL statement which produces the distinct set of categories. The SQL
- statement must return one category column only. category_sql must produce
- at least one result row or an error will be generated. category_sql
- must not produce duplicate categories or an error will be generated.
-
- e.g. SELECT DISTINCT cat FROM foo;
-
- cat
- -------
- cat1
- cat2
- cat3
- cat4
-
-Outputs
-
- Returns setof record, which must be defined with a column definition
- in the FROM clause of the SELECT statement, e.g.:
-
- SELECT * FROM crosstab(source_sql, cat_sql)
- AS ct(row_name text, extra text, cat1 text, cat2 text, cat3 text, cat4 text);
-
- the example crosstab function produces a set something like:
- <== values columns ==>
- row_name extra cat1 cat2 cat3 cat4
- ---------+-------+------+------+------+------
- row1 extra1 val1 val2 val4
- row2 extra2 val5 val6 val7 val8
-
-Notes
-
- 1. source_sql must be ordered by row_name (column 1).
-
- 2. The number of values columns is determined at run-time. The
- column definition provided in the FROM clause must provide for
- the correct number of columns of the proper data types.
-
- 3. Missing values (i.e. not enough adjacent rows of same row_name to
- fill the number of result values columns) are filled in with nulls.
-
- 4. Extra values (i.e. source rows with category not found in category_sql
- result) are skipped.
-
- 5. Rows with a null row_name column are skipped.
-
- 6. You can create predefined functions to avoid having to write out
- the result column names/types in each query. See the examples
- for crosstab(text).
-
-
-Example usage
-
-create table cth(id serial, rowid text, rowdt timestamp, attribute text, val text);
-insert into cth values(DEFAULT,'test1','01 March 2003','temperature','42');
-insert into cth values(DEFAULT,'test1','01 March 2003','test_result','PASS');
-insert into cth values(DEFAULT,'test1','01 March 2003','volts','2.6987');
-insert into cth values(DEFAULT,'test2','02 March 2003','temperature','53');
-insert into cth values(DEFAULT,'test2','02 March 2003','test_result','FAIL');
-insert into cth values(DEFAULT,'test2','02 March 2003','test_startdate','01 March 2003');
-insert into cth values(DEFAULT,'test2','02 March 2003','volts','3.1234');
-
-SELECT * FROM crosstab
-(
- 'SELECT rowid, rowdt, attribute, val FROM cth ORDER BY 1',
- 'SELECT DISTINCT attribute FROM cth ORDER BY 1'
-)
-AS
-(
- rowid text,
- rowdt timestamp,
- temperature int4,
- test_result text,
- test_startdate timestamp,
- volts float8
-);
- rowid | rowdt | temperature | test_result | test_startdate | volts
--------+--------------------------+-------------+-------------+--------------------------+--------
- test1 | Sat Mar 01 00:00:00 2003 | 42 | PASS | | 2.6987
- test2 | Sun Mar 02 00:00:00 2003 | 53 | FAIL | Sat Mar 01 00:00:00 2003 | 3.1234
-(2 rows)
-
-==================================================================
-Name
-
-connectby(text, text, text[, text], text, text, int[, text]) - returns a set
- representing a hierarchy (tree structure)
-
-Synopsis
-
-connectby(text relname, text keyid_fld, text parent_keyid_fld
- [, text orderby_fld], text start_with, int max_depth
- [, text branch_delim])
-
-Inputs
-
- relname
-
- Name of the source relation
-
- keyid_fld
-
- Name of the key field
-
- parent_keyid_fld
-
- Name of the key_parent field
-
- orderby_fld
-
- If optional ordering of siblings is desired:
- Name of the field to order siblings
-
- start_with
-
- root value of the tree input as a text value regardless of keyid_fld type
-
- max_depth
-
- zero (0) for unlimited depth, otherwise restrict level to this depth
-
- branch_delim
-
- If optional branch value is desired, this string is used as the delimiter.
- When not provided, a default value of '~' is used for internal
- recursion detection only, and no "branch" field is returned.
-
-Outputs
-
- Returns setof record, which must defined with a column definition
- in the FROM clause of the SELECT statement, e.g.:
-
- SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'row2', 0, '~')
- AS t(keyid text, parent_keyid text, level int, branch text);
-
- - or -
-
- SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'row2', 0)
- AS t(keyid text, parent_keyid text, level int);
-
- - or -
-
- SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0, '~')
- AS t(keyid text, parent_keyid text, level int, branch text, pos int);
-
- - or -
-
- SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0)
- AS t(keyid text, parent_keyid text, level int, pos int);
-
-Notes
-
- 1. keyid and parent_keyid must be the same data type
-
- 2. The column definition *must* include a third column of type INT4 for
- the level value output
-
- 3. If the branch field is not desired, omit both the branch_delim input
- parameter *and* the branch field in the query column definition. Note
- that when branch_delim is not provided, a default value of '~' is used
- for branch_delim for internal recursion detection, even though the branch
- field is not returned.
-
- 4. If the branch field is desired, it must be the fourth column in the query
- column definition, and it must be type TEXT.
-
- 5. The parameters representing table and field names must include double
- quotes if the names are mixed-case or contain special characters.
-
- 6. If sorting of siblings is desired, the orderby_fld input parameter *and*
- a name for the resulting serial field (type INT32) in the query column
- definition must be given.
-
-Example usage
-
-CREATE TABLE connectby_tree(keyid text, parent_keyid text, pos int);
-
-INSERT INTO connectby_tree VALUES('row1',NULL, 0);
-INSERT INTO connectby_tree VALUES('row2','row1', 0);
-INSERT INTO connectby_tree VALUES('row3','row1', 0);
-INSERT INTO connectby_tree VALUES('row4','row2', 1);
-INSERT INTO connectby_tree VALUES('row5','row2', 0);
-INSERT INTO connectby_tree VALUES('row6','row4', 0);
-INSERT INTO connectby_tree VALUES('row7','row3', 0);
-INSERT INTO connectby_tree VALUES('row8','row6', 0);
-INSERT INTO connectby_tree VALUES('row9','row5', 0);
-
--- with branch, without orderby_fld
-SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'row2', 0, '~')
- AS t(keyid text, parent_keyid text, level int, branch text);
- keyid | parent_keyid | level | branch
--------+--------------+-------+---------------------
- row2 | | 0 | row2
- row4 | row2 | 1 | row2~row4
- row6 | row4 | 2 | row2~row4~row6
- row8 | row6 | 3 | row2~row4~row6~row8
- row5 | row2 | 1 | row2~row5
- row9 | row5 | 2 | row2~row5~row9
-(6 rows)
-
--- without branch, without orderby_fld
-SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'row2', 0)
- AS t(keyid text, parent_keyid text, level int);
- keyid | parent_keyid | level
--------+--------------+-------
- row2 | | 0
- row4 | row2 | 1
- row6 | row4 | 2
- row8 | row6 | 3
- row5 | row2 | 1
- row9 | row5 | 2
-(6 rows)
-
--- with branch, with orderby_fld (notice that row5 comes before row4)
-SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0, '~')
- AS t(keyid text, parent_keyid text, level int, branch text, pos int) ORDER BY t.pos;
- keyid | parent_keyid | level | branch | pos
--------+--------------+-------+---------------------+-----
- row2 | | 0 | row2 | 1
- row5 | row2 | 1 | row2~row5 | 2
- row9 | row5 | 2 | row2~row5~row9 | 3
- row4 | row2 | 1 | row2~row4 | 4
- row6 | row4 | 2 | row2~row4~row6 | 5
- row8 | row6 | 3 | row2~row4~row6~row8 | 6
-(6 rows)
-
--- without branch, with orderby_fld (notice that row5 comes before row4)
-SELECT * FROM connectby('connectby_tree', 'keyid', 'parent_keyid', 'pos', 'row2', 0)
- AS t(keyid text, parent_keyid text, level int, pos int) ORDER BY t.pos;
- keyid | parent_keyid | level | pos
--------+--------------+-------+-----
- row2 | | 0 | 1
- row5 | row2 | 1 | 2
- row9 | row5 | 2 | 3
- row4 | row2 | 1 | 4
- row6 | row4 | 2 | 5
- row8 | row6 | 3 | 6
-(6 rows)
-
-==================================================================
--- Joe Conway
-