From 53ae7acbba6a107dde4d71c3835ad576e08a87b1 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 3 Dec 2007 04:18:47 +0000 Subject: [PATCH] Add SGML documentation for contrib/spi and contrib/test_parser. The spi documentation is pretty rudimentary, but it's a start. --- doc/src/sgml/contrib-spi.sgml | 215 ++++++++++++++++++++++++++++++++++ doc/src/sgml/contrib.sgml | 4 +- doc/src/sgml/filelist.sgml | 4 +- doc/src/sgml/test-parser.sgml | 87 ++++++++++++++ 4 files changed, 308 insertions(+), 2 deletions(-) create mode 100644 doc/src/sgml/contrib-spi.sgml create mode 100644 doc/src/sgml/test-parser.sgml diff --git a/doc/src/sgml/contrib-spi.sgml b/doc/src/sgml/contrib-spi.sgml new file mode 100644 index 0000000000..62a95af1d6 --- /dev/null +++ b/doc/src/sgml/contrib-spi.sgml @@ -0,0 +1,215 @@ + + + + spi + + + SPI + examples + + + + The contrib/spi module provides several workable examples + of using SPI and triggers. While these functions are of some value in + their own right, they are even more useful as examples to modify for + your own purposes. The functions are general enough to be used + with any table, but you have to specify table and field names (as described + below) while creating a trigger. + + + + refint.c — functions for implementing referential integrity + + + check_primary_key() and + check_foreign_key() are used to check foreign key constraints. + (This functionality is long since superseded by the built-in foreign + key mechanism, of course, but the module is still useful as an example.) + + + + check_primary_key() checks the referencing table. + To use, create a BEFORE INSERT OR UPDATE trigger using this + function on a table referencing another table. You are to specify + as trigger arguments: triggered table column names which correspond + to foreign key, referenced table name and column names in referenced + table which correspond to primary/unique key. To handle multiple + foreign keys, create a trigger for each reference. + + + + check_foreign_key() checks the referenced table. + To use, create a BEFORE DELETE OR UPDATE trigger using this + function on a table referenced by other table(s). You are to specify + as trigger arguments: number of references for which the function has to + perform checking, action if referencing key found ('cascade' — to delete + corresponding foreign key, 'restrict' — to abort transaction if foreign keys + exist, 'setnull' — to set foreign key referencing primary/unique key + being deleted to null), triggered table column names which correspond + to primary/unique key, then referencing table name and column names + corresponding to foreign key (repeated for as many referencing tables/keys + as were specified by first argument). Note that the primary/unique key + columns should be marked NOT NULL and should have a unique index. + + + + There are examples in refint.example. + + + + + timetravel.c — functions for implementing time travel + + + Long ago, PostgreSQL had a built-in time travel feature + that kept the insert and delete times for each tuple. This can be + emulated using these functions. To use these functions, + you are to add to a table two columns of abstime type to store + the date when a tuple was inserted (start_date) and changed/deleted + (stop_date): + + +CREATE TABLE mytab ( + ... ... + start_date abstime default now(), + stop_date abstime default 'infinity' + ... ... +); + + + So, tuples being inserted with unspecified start_date/stop_date will get + the current time in start_date and infinity in + stop_date. + + + + Tuples with stop_date equal to infinity are valid + now: when trigger will be fired for UPDATE/DELETE of a tuple with + stop_date NOT equal to infinity then + this tuple will not be changed/deleted! + + + + If stop_date is equal to infinity then on + update only the stop_date in the tuple being updated will be changed (to + current time) and a new tuple with new data (coming from SET ... in UPDATE) + will be inserted. Start_date in this new tuple will be set to current time + and stop_date to infinity. + + + + A delete does not actually remove the tuple but only set its stop_date + to current time. + + + + To query for tuples valid now, include + stop_date = 'infinity' in the query's WHERE condition. + (You might wish to incorporate that in a view.) + + + + You can't change start/stop date columns with UPDATE! + Use set_timetravel (below) if you need this. + + + + timetravel() is the general trigger function that supports + this behavior. Create a BEFORE INSERT OR UPDATE OR DELETE trigger using this + function on each time-traveled table. You are to specify two trigger arguments: + name of start_date column and name of stop_date column in triggered table. + Optionally, you can specify one to three more arguments, which must refer + to columns of type text. The trigger will store the name of + the current user into the first of these columns during INSERT, the + second column during UPDATE, and the third during DELETE. + + + + set_timetravel() allows you to turn time-travel on or off for + a table. + set_timetravel('mytab', 1) will turn TT ON for table mytab. + set_timetravel('mytab', 0) will turn TT OFF for table mytab. + In both cases the old status is reported. While TT is off, you can modify + the start_date and stop_date columns freely. + + + + get_timetravel() returns the TT state for a table without + changing it. + + + + There is an example in timetravel.example. + + + + + autoinc.c — functions for autoincrementing fields + + + autoinc() is a trigger that stores the next value of + a sequence into an integer field. This has some overlap with the + built-in serial column feature, but it is not the same: + autoinc() will override attempts to substitute a + different field value during inserts, and optionally it can be + used to increment the field during updates, too. + + + + To use, create a BEFORE INSERT (or optionally BEFORE INSERT OR UPDATE) + trigger using this function. You are to specify + as trigger arguments: the name of the integer column to be modified, + and the name of the sequence object that will supply values. + (Actually, you can specify any number of pairs of such names, if + you'd like to update more than one autoincrementing column.) + + + + There is an example in autoinc.example. + + + + + + insert_username.c — functions for tracking who changed a table + + + insert_username() is a trigger that stores the current + user's name into a text field. This can be useful for tracking + who last modified a particular row within a table. + + + + To use, create a BEFORE INSERT and/or UPDATE + trigger using this function. You are to specify a single trigger + argument: the name of the text column to be modified. + + + + There is an example in insert_username.example. + + + + + + moddatetime.c — functions for tracking last modification time + + + moddatetime() is a trigger that stores the current + time into a timestamp field. This can be useful for tracking + the last modification time of a particular row within a table. + + + + To use, create a BEFORE UPDATE + trigger using this function. You are to specify a single trigger + argument: the name of the timestamp column to be modified. + + + + There is an example in moddatetime.example. + + + + + diff --git a/doc/src/sgml/contrib.sgml b/doc/src/sgml/contrib.sgml index f077e55bb8..69e109398d 100644 --- a/doc/src/sgml/contrib.sgml +++ b/doc/src/sgml/contrib.sgml @@ -1,4 +1,4 @@ - + Additional Supplied Modules @@ -103,8 +103,10 @@ psql -d dbname -f SHAREDIR/contrib/module.sql &pgstattuple; &pgtrgm; &seg; + &contrib-spi; &sslinfo; &tablefunc; + &test-parser; &tsearch2; &uuid-ossp; &vacuumlo; diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml index 4c229d1984..b6305dc535 100644 --- a/doc/src/sgml/filelist.sgml +++ b/doc/src/sgml/filelist.sgml @@ -1,4 +1,4 @@ - + @@ -117,8 +117,10 @@ + + diff --git a/doc/src/sgml/test-parser.sgml b/doc/src/sgml/test-parser.sgml new file mode 100644 index 0000000000..323a297a78 --- /dev/null +++ b/doc/src/sgml/test-parser.sgml @@ -0,0 +1,87 @@ + + + + test_parser + + + test_parser + + + + This is an example of a custom parser for full text search. + + + + It recognizes space-delimited words and returns just two token types: + + +mydb=# SELECT * FROM ts_token_type('testparser'); + tokid | alias | description +-------+-------+--------------- + 3 | word | Word + 12 | blank | Space symbols +(2 rows) + + + These token numbers have been chosen to be compatible with the default + parser's numbering. This allows us to use its headline() + function, thus keeping the example simple. + + + + Usage + + + Running the installation script creates a text search parser + testparser. It has no user-configurable parameters. + + + + You can test the parser with, for example, + + +mydb=# SELECT * FROM ts_parse('testparser', 'That''s my first own parser'); + tokid | token +-------+-------- + 3 | That's + 12 | + 3 | my + 12 | + 3 | first + 12 | + 3 | own + 12 | + 3 | parser + + + + + Real-world use requires setting up a text search configuration + that uses the parser. For example, + + +mydb=# CREATE TEXT SEARCH CONFIGURATION testcfg ( PARSER = testparser ); +CREATE TEXT SEARCH CONFIGURATION + +mydb=# ALTER TEXT SEARCH CONFIGURATION testcfg +mydb-# ADD MAPPING FOR word WITH english_stem; +ALTER TEXT SEARCH CONFIGURATION + +mydb=# SELECT to_tsvector('testcfg', 'That''s my first own parser'); + to_tsvector +------------------------------- + 'that':1 'first':3 'parser':5 +(1 row) + +mydb=# SELECT ts_headline('testcfg', 'Supernovae stars are the brightest phenomena in galaxies', +mydb(# to_tsquery('testcfg', 'star')); + ts_headline +----------------------------------------------------------------- + Supernovae <b>stars</b> are the brightest phenomena in galaxies +(1 row) + + + + + +