diff --git a/contrib/Contrib.index b/contrib/Contrib.index new file mode 100644 index 0000000000000000000000000000000000000000..3fc460cc473e6d742da405c2a6c05ad065697261 --- /dev/null +++ b/contrib/Contrib.index @@ -0,0 +1,88 @@ + +The PostgreSQL contrib: +~~~~~~~~~~~~~~~~~~~~~~ + +apache_logging - + Getting Apache to log to PostgreSQL + by Terry Mackintosh <terry@terrym.com> + +array - + Array iterator functions + by Massimo Dal Zotto <dz@cs.unitn.it> + +earthdistance - + Operator for computing earth distance for two points + by Hal Snyder <hal@vailsys.com> + +findoidjoins - + Finds the joins used by oid columns by examining the actual + values in the oid columns and row oids. + by Bruce Momjian <root@candle.pha.pa.us> + +fulltextindex - + Full text indexing using triggers + by Maarten Boekhold <maartenb@dutepp0.et.tudelft.nl> + +isbn_issn - + PostgreSQL type extensions for ISBN (books) and ISSN (serials) + by Garrett A. Wollman <wollman@khavrinen.lcs.mit.edu> + +likeplanning - + Scripts to enable/disable new planning code for LIKE and regexp + pattern match operators. These will go away again once the code + is mature enough to enable by default. + by Tom Lane <tgl@sss.pgh.pa.us> + +linux - + Start postgres back end system + by Thomas Lockhart <lockhart@alumni.caltech.edu> + +lo - + Large Object maintenance + by Peter Mount <peter@retep.org.uk> + +miscutil - + Postgres assert checking and various utility functions + by Dal Zotto <dz@cs.unitn.it> + +mSQL-interface - + mSQL API translation library + by Aldrin Leal <aldrin@americasnet.com> + +noupdate - + trigger to prevent updates on single columns + + +pg_dumplo - + Dump large objects + by Karel Zak <zakkr@zf.jcu.cz> + +soundex - + Prototype for soundex function + +spi - + A general trigger function autoinc() and so on. + +string - + C-like input/output conversion routines for strings + by Massimo Dal Zotto <dz@cs.unitn.it> + +tools - + Assorted developer tools + by Massimo Dal Zotto <dz@cs.unitn.it> + +unixdate - + Conversions from integer to datetime + by Thomas Lockhart <lockhart@alumni.caltech.edu> + +userlock - + User locks + by Massimo Dal Zotto <dz@cs.unitn.it> + +vacuumlo - + Remove orphaned large objects + by Peter T Mount <peter@retep.org.uk> + +pgbench - + TPC-B like benchmarking tool + by Tatsuo Ishii <t-ishii@sra.co.jp> diff --git a/contrib/Makefile.global b/contrib/Makefile.global new file mode 100644 index 0000000000000000000000000000000000000000..43cbf853b8aacac44301454b91477c3f94321d42 --- /dev/null +++ b/contrib/Makefile.global @@ -0,0 +1,44 @@ + +#------------------------------------------------------------------------- +# +# Makefile.global +# Build and install PostgreSQL contrib. +# +# Portions Copyright (c) 1999-2000, PostgreSQL, Inc +# +# +# IDENTIFICATION +# $Header: /cvsroot/pgsql/contrib/Attic/Makefile.global,v 1.1 2000/06/15 19:04:37 momjian Exp $ +# +#------------------------------------------------------------------------- + +SRCDIR = $(TOPDIR)/src +include $(SRCDIR)/Makefile.global + +### --------------------------------------------------------- +### DELETE THIS PART if ../src/Makefile.global is standardize +### (has define all next definitions itself) + +DOCDIR=$(POSTDOCDIR) + +# not $PGDATA, but anything like '/usr/local/pgsql/share' +DATADIR=$(LIBDIR) + +### ---------------------------------------------------------- + +# execute-able +CONTRIB_BINDIR = $(BINDIR) +# *.so +CONTRIB_MODDIR = $(LIBDIR)/modules +# *.doc +CONTRIB_DOCDIR = $(DOCDIR)/contrib +# *.sql +CONTRIB_SQLDIR = $(DATADIR)/sql +# *.examples +CONTRIB_EXAMPLESDIR = $(CONTRIB_DOCDIR)/examples + + +RM = rm -f +SED = sed + + diff --git a/contrib/earthdistance/earthdistance.sql.in b/contrib/earthdistance/earthdistance.sql.in new file mode 100644 index 0000000000000000000000000000000000000000..fdb4552f8aab630797628ebd6734bf137b151d8b --- /dev/null +++ b/contrib/earthdistance/earthdistance.sql.in @@ -0,0 +1,23 @@ + +--------------- geo_distance + +DROP FUNCTION geo_distance (point, point); +CREATE FUNCTION geo_distance (point, point) RETURNS float8 + AS 'MODULE_PATHNAME' LANGUAGE 'c'; + +SELECT geo_distance ('(1,2)'::point, '(3,4)'::point); + +--------------- geo_distance as operator <@> + +DROP OPERATOR <@> (point, point); +CREATE OPERATOR <@> ( + leftarg = point, + rightarg = point, + procedure = geo_distance, + commutator = <@> +); + +-- ( 87.6, 41.8) is in Chicago +-- (106.7, 35.1) is in Albuquerque +-- The cities are about 1100 miles apart +SELECT '(87.6,41.8)'::point <@> '(106.7,35.1)'::point; diff --git a/contrib/fulltextindex/fti.pl b/contrib/fulltextindex/fti.pl new file mode 100644 index 0000000000000000000000000000000000000000..6b6d68e4900ac35412c907dbf977179817d74431 --- /dev/null +++ b/contrib/fulltextindex/fti.pl @@ -0,0 +1,204 @@ +#!/usr/bin/perl +# +# This script substracts all substrings out of a specific column in a table +# and generates output that can be loaded into a new table with the +# psql '\copy' command. The new table should have the following structure: +# +# create table tab ( +# string text, +# id oid +# ); +# +# Note that you cannot use 'copy' (the SQL-command) directly, because +# there's no '\.' included at the end of the output. +# +# The output can be fed through the UNIX commands 'uniq' and 'sort' +# to generate the smallest and sorted output to populate the fti-table. +# +# Example: +# +# fti.pl -u -d mydb -t mytable -c mycolumn -f myfile +# sort -o myoutfile myfile +# uniq myoutfile sorted-file +# +# psql -u mydb +# +# \copy my_fti_table from myfile +# +# create index fti_idx on my_fti_table (string,id); +# +# create function fti() returns opaque as +# '/path/to/fti/file/fti.so' +# language 'newC'; +# +# create trigger my_fti_trigger after update or insert or delete +# on mytable +# for each row execute procedure fti(my_fti_table, mycolumn); +# +# Make sure you have an index on mytable(oid) to be able to do somewhat +# efficient substring searches. + +#use lib '/usr/local/pgsql/lib/perl5/'; +use lib '/mnt/web/guide/postgres/lib/perl5/site_perl'; +use Pg; +use Getopt::Std; + +$PGRES_EMPTY_QUERY = 0 ; +$PGRES_COMMAND_OK = 1 ; +$PGRES_TUPLES_OK = 2 ; +$PGRES_COPY_OUT = 3 ; +$PGRES_COPY_IN = 4 ; +$PGRES_BAD_RESPONSE = 5 ; +$PGRES_NONFATAL_ERROR = 6 ; +$PGRES_FATAL_ERROR = 7 ; + +$[ = 0; # make sure string offsets start at 0 + +sub break_up { + my $string = pop @_; + + @strings = split(/\W+/, $string); + @subs = (); + + foreach $s (@strings) { + $len = length($s); + next if ($len < 4); + + $lpos = $len-1; + while ($lpos >= 3) { + $fpos = $lpos - 3; + while ($fpos >= 0) { + $sub = substr($s, $fpos, $lpos - $fpos + 1); + push(@subs, $sub); + $fpos = $fpos - 1; + } + $lpos = $lpos - 1; + } + } + + return @subs; +} + +sub connect_db { + my $dbname = shift @_; + my $user = shift @_; + my $passwd = shift @_; + + if (!defined($dbname) || $dbname eq "") { + return 1; + } + $connect_string = "dbname=$dbname"; + + if ($user ne "") { + if ($passwd eq "") { + return 0; + } + $connect_string = "$connect_string user=$user password=$passwd ". + "authtype=password"; + } + + $PG_CONN = PQconnectdb($connect_string); + + if (PQstatus($PG_CONN)) { + print STDERR "Couldn't make connection with database!\n"; + print STDERR PQerrorMessage($PG_CONN), "\n"; + return 0; + } + + return 1; +} + +sub quit_prog { + close(OUT); + unlink $opt_f; + if (defined($PG_CONN)) { + PQfinish($PG_CONN); + } + exit 1; +} + +sub get_username { + print "Username: "; + chop($n = <STDIN>); + + return $n;; +} + +sub get_password { + print "Password: "; + + system("stty -echo < /dev/tty"); + chop($pwd = <STDIN>); + print "\n"; + system("stty echo < /dev/tty"); + + return $pwd; +} + +sub main { + getopts('d:t:c:f:u'); + + if (!$opt_d || !$opt_t || !$opt_c || !$opt_f) { + print STDERR "usage: $0 [-u] -d database -t table -c column ". + "-f output-file\n"; + return 1; + } + + if (defined($opt_u)) { + $uname = get_username(); + $pwd = get_password(); + } else { + $uname = ""; + $pwd = ""; + } + + $SIG{'INT'} = 'quit_prog'; + if (!connect_db($opt_d, $uname, $pwd)) { + print STDERR "Connecting to database failed!\n"; + return 1; + } + + if (!open(OUT, ">$opt_f")) { + print STDERR "Couldnt' open file '$opt_f' for output!\n"; + return 1; + } + + PQexec($PG_CONN, "begin"); + + $query = "declare C cursor for select $opt_c, oid from $opt_t"; + $res = PQexec($PG_CONN, $query); + if (!$res || (PQresultStatus($res) != $PGRES_COMMAND_OK)) { + print STDERR "Error declaring cursor!\n"; + print STDERR PQerrorMessage($PG_CONN), "\n"; + PQfinish($PG_CONN); + return 1; + } + PQclear($res); + + $query = "fetch in C"; + while (($res = PQexec($PG_CONN, $query)) && + (PQresultStatus($res) == $PGRES_TUPLES_OK) && + (PQntuples($res) == 1)) { + $col = PQgetvalue($res, 0, 0); + $oid = PQgetvalue($res, 0, 1); + + @subs = break_up($col); + foreach $i (@subs) { + print OUT "$i\t$oid\n"; + } + } + + if (!$res || (PQresultStatus($res) != PGRES_TUPLES_OK)) { + print STDERR "Error retrieving data from backend!\n"; + print STDERR PQerrorMEssage($PG_CONN), "\n"; + PQfinish($PG_CONN); + return 1; + } + + PQclear($res); + PQfinish($PG_CONN); + + return 0; +} + +exit main(); diff --git a/contrib/fulltextindex/fti.sql.in b/contrib/fulltextindex/fti.sql.in new file mode 100644 index 0000000000000000000000000000000000000000..e0da2353c52447eb1b019fb516d827abf4842c21 --- /dev/null +++ b/contrib/fulltextindex/fti.sql.in @@ -0,0 +1,3 @@ +create function fti() returns opaque as + 'MODULE_PATHNAME' + language 'C'; \ No newline at end of file diff --git a/contrib/isbn_issn/isbn_issn.c b/contrib/isbn_issn/isbn_issn.c new file mode 100644 index 0000000000000000000000000000000000000000..a1d891d7bcf4b30b63e0fa838583e916cb95699b --- /dev/null +++ b/contrib/isbn_issn/isbn_issn.c @@ -0,0 +1,378 @@ +/* + * PostgreSQL type definitions for ISBNs. + * + * $Id: isbn_issn.c,v 1.1 2000/06/15 19:04:50 momjian Exp $ + */ + +#include <stdio.h> + +#include <postgres.h> +#include <utils/palloc.h> + +/* + * This is the internal storage format for ISBNs. + * NB: This is an intentional type pun with builtin type `char16'. + */ + +typedef struct isbn +{ + char num[13]; + char pad[3]; +} isbn; + +/* + * Various forward declarations: + */ + +isbn *isbn_in(char *str); +char *isbn_out(isbn * addr); + +bool isbn_lt(isbn * a1, isbn * a2); +bool isbn_le(isbn * a1, isbn * a2); +bool isbn_eq(isbn * a1, isbn * a2); +bool isbn_ge(isbn * a1, isbn * a2); +bool isbn_gt(isbn * a1, isbn * a2); + +bool isbn_ne(isbn * a1, isbn * a2); + +int4 isbn_cmp(isbn * a1, isbn * a2); + +int4 isbn_sum(char *str); + +/* + * ISBN reader. + */ + +isbn * +isbn_in(char *str) +{ + isbn *result; + + if (strlen(str) != 13) + { + elog(ERROR, "isbn_in: invalid ISBN \"%s\"", str); + return (NULL); + } + if (isbn_sum(str) != 0) + { + elog(ERROR, "isbn_in: purported ISBN \"%s\" failed checksum", + str); + return (NULL); + } + + result = (isbn *) palloc(sizeof(isbn)); + + strncpy(result->num, str, 13); + memset(result->pad, ' ', 3); + return (result); +} + +/* + * The ISBN checksum is defined as follows: + * + * Number the digits from 1 to 9 (call this N). + * Compute the sum, S, of N * D_N. + * The check digit, C, is the value which satisfies the equation + * S + 10*C === 0 (mod 11) + * The value 10 for C is written as `X'. + * + * For our purposes, we want the complete sum including the check + * digit; if this is zero, then the checksum passed. We also check + * the syntactic validity if the provided string, and return 12 + * if any errors are found. + */ +int4 +isbn_sum(char *str) +{ + int4 sum = 0, + dashes = 0, + val; + int i; + + for (i = 0; str[i] && i < 13; i++) + { + switch (str[i]) + { + case '-': + if (++dashes > 3) + return 12; + continue; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + val = str[i] - '0'; + break; + + case 'X': + case 'x': + val = 10; + break; + + default: + return 12; + } + + sum += val * (i + 1 - dashes); + } + return (sum % 11); +} + +/* + * ISBN output function. + */ + +char * +isbn_out(isbn * num) +{ + char *result; + + if (num == NULL) + return (NULL); + + result = (char *) palloc(14); + + result[0] = '\0'; + strncat(result, num->num, 13); + return (result); +} + +/* + * Boolean tests for magnitude. + */ + +bool +isbn_lt(isbn * a1, isbn * a2) +{ + return (strncmp(a1->num, a2->num, 13) < 0); +}; + +bool +isbn_le(isbn * a1, isbn * a2) +{ + return (strncmp(a1->num, a2->num, 13) <= 0); +}; + +bool +isbn_eq(isbn * a1, isbn * a2) +{ + return (strncmp(a1->num, a2->num, 13) == 0); +}; + +bool +isbn_ge(isbn * a1, isbn * a2) +{ + return (strncmp(a1->num, a2->num, 13) >= 0); +}; + +bool +isbn_gt(isbn * a1, isbn * a2) +{ + return (strncmp(a1->num, a2->num, 13) > 0); +}; + +bool +isbn_ne(isbn * a1, isbn * a2) +{ + return (strncmp(a1->num, a2->num, 13) != 0); +}; + +/* + * Comparison function for sorting: + */ + +int4 +isbn_cmp(isbn * a1, isbn * a2) +{ + return (strncmp(a1->num, a2->num, 13)); +} + + +/* ----------------------------- ISSN --------------------------- */ + +/* + * This is the internal storage format for ISSNs. + * NB: This is an intentional type pun with builtin type `char16'. + */ + +typedef struct issn +{ + char num[9]; + char pad[7]; +} issn; + +/* + * Various forward declarations: + */ + +issn *issn_in(char *str); +char *issn_out(issn * addr); + +bool issn_lt(issn * a1, issn * a2); +bool issn_le(issn * a1, issn * a2); +bool issn_eq(issn * a1, issn * a2); +bool issn_ge(issn * a1, issn * a2); +bool issn_gt(issn * a1, issn * a2); + +bool issn_ne(issn * a1, issn * a2); + +int4 issn_cmp(issn * a1, issn * a2); + +int4 issn_sum(char *str); + +/* + * ISSN reader. + */ + +issn * +issn_in(char *str) +{ + issn *result; + + if (strlen(str) != 9) + { + elog(ERROR, "issn_in: invalid ISSN \"%s\"", str); + return (NULL); + } + if (issn_sum(str) != 0) + { + elog(ERROR, "issn_in: purported ISSN \"%s\" failed checksum", + str); + return (NULL); + } + + result = (issn *) palloc(sizeof(issn)); + + strncpy(result->num, str, 9); + memset(result->pad, ' ', 7); + return (result); +} + +/* + * The ISSN checksum works just like the ISBN sum, only different + * (of course!). + * Here, the weights start at 8 and decrease. + */ +int4 +issn_sum(char *str) +{ + int4 sum = 0, + dashes = 0, + val; + int i; + + for (i = 0; str[i] && i < 9; i++) + { + switch (str[i]) + { + case '-': + if (++dashes > 1) + return 12; + continue; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + val = str[i] - '0'; + break; + + case 'X': + case 'x': + val = 10; + break; + + default: + return 12; + } + + sum += val * (8 - (i - dashes)); + } + return (sum % 11); +} + +/* + * ISSN output function. + */ + +char * +issn_out(issn * num) +{ + char *result; + + if (num == NULL) + return (NULL); + + result = (char *) palloc(14); + + result[0] = '\0'; + strncat(result, num->num, 9); + return (result); +} + +/* + * Boolean tests for magnitude. + */ + +bool +issn_lt(issn * a1, issn * a2) +{ + return (strncmp(a1->num, a2->num, 9) < 0); +}; + +bool +issn_le(issn * a1, issn * a2) +{ + return (strncmp(a1->num, a2->num, 9) <= 0); +}; + +bool +issn_eq(issn * a1, issn * a2) +{ + return (strncmp(a1->num, a2->num, 9) == 0); +}; + +bool +issn_ge(issn * a1, issn * a2) +{ + return (strncmp(a1->num, a2->num, 9) >= 0); +}; + +bool +issn_gt(issn * a1, issn * a2) +{ + return (strncmp(a1->num, a2->num, 9) > 0); +}; + +bool +issn_ne(issn * a1, issn * a2) +{ + return (strncmp(a1->num, a2->num, 9) != 0); +}; + +/* + * Comparison function for sorting: + */ + +int4 +issn_cmp(issn * a1, issn * a2) +{ + return (strncmp(a1->num, a2->num, 9)); +} + +/* + * eof + */ diff --git a/contrib/isbn_issn/isbn_issn.sql.in b/contrib/isbn_issn/isbn_issn.sql.in new file mode 100644 index 0000000000000000000000000000000000000000..e0b90eca338ff782bcf8c1895afeb88cb5d8d706 --- /dev/null +++ b/contrib/isbn_issn/isbn_issn.sql.in @@ -0,0 +1,228 @@ +-- +-- PostgreSQL code for ISSNs. +-- +-- $Id: isbn_issn.sql.in,v 1.1 2000/06/15 19:04:50 momjian Exp $ +-- + + +-- +-- Input and output functions and the type itself: +-- + +create function issn_in(opaque) + returns opaque + as 'MODULE_PATHNAME' + language 'c'; + +create function issn_out(opaque) + returns opaque + as 'MODULE_PATHNAME' + language 'c'; + +create type issn ( + internallength = 16, + externallength = 9, + input = issn_in, + output = issn_out +); + +-- +-- The various boolean tests: +-- + +create function issn_lt(issn, issn) + returns bool + as 'MODULE_PATHNAME' + language 'c'; + +create function issn_le(issn, issn) + returns bool + as 'MODULE_PATHNAME' + language 'c'; + +create function issn_eq(issn, issn) + returns bool + as 'MODULE_PATHNAME' + language 'c'; + +create function issn_ge(issn, issn) + returns bool + as 'MODULE_PATHNAME' + language 'c'; + +create function issn_gt(issn, issn) + returns bool + as 'MODULE_PATHNAME' + language 'c'; + +create function issn_ne(issn, issn) + returns bool + as 'MODULE_PATHNAME' + language 'c'; + +-- +-- Now the operators. Note how some of the parameters to some +-- of the 'create operator' commands are commented out. This +-- is because they reference as yet undefined operators, and +-- will be implicitly defined when those are, further down. +-- + +create operator < ( + leftarg = issn, + rightarg = issn, +-- negator = >=, + procedure = issn_lt +); + +create operator <= ( + leftarg = issn, + rightarg = issn, +-- negator = >, + procedure = issn_le +); + +create operator = ( + leftarg = issn, + rightarg = issn, + commutator = =, +-- negator = <>, + procedure = issn_eq +); + +create operator >= ( + leftarg = issn, + rightarg = issn, + negator = <, + procedure = issn_ge +); + +create operator > ( + leftarg = issn, + rightarg = issn, + negator = <=, + procedure = issn_gt +); + +create operator <> ( + leftarg = issn, + rightarg = issn, + negator = =, + procedure = issn_ne +); + +-- +-- eof +-- +-- +-- PostgreSQL code for ISBNs. +-- +-- $Id: isbn_issn.sql.in,v 1.1 2000/06/15 19:04:50 momjian Exp $ +-- +-- +-- Input and output functions and the type itself: +-- + +create function isbn_in(opaque) + returns opaque + as 'MODULE_PATHNAME' + language 'c'; + +create function isbn_out(opaque) + returns opaque + as 'MODULE_PATHNAME' + language 'c'; + +create type isbn ( + internallength = 16, + externallength = 13, + input = isbn_in, + output = isbn_out +); + +-- +-- The various boolean tests: +-- + +create function isbn_lt(isbn, isbn) + returns bool + as 'MODULE_PATHNAME' + language 'c'; + +create function isbn_le(isbn, isbn) + returns bool + as 'MODULE_PATHNAME' + language 'c'; + +create function isbn_eq(isbn, isbn) + returns bool + as 'MODULE_PATHNAME' + language 'c'; + +create function isbn_ge(isbn, isbn) + returns bool + as 'MODULE_PATHNAME' + language 'c'; + +create function isbn_gt(isbn, isbn) + returns bool + as 'MODULE_PATHNAME' + language 'c'; + +create function isbn_ne(isbn, isbn) + returns bool + as 'MODULE_PATHNAME' + language 'c'; + +-- +-- Now the operators. Note how some of the parameters to some +-- of the 'create operator' commands are commented out. This +-- is because they reference as yet undefined operators, and +-- will be implicitly defined when those are, further down. +-- + +create operator < ( + leftarg = isbn, + rightarg = isbn, +-- negator = >=, + procedure = isbn_lt +); + +create operator <= ( + leftarg = isbn, + rightarg = isbn, +-- negator = >, + procedure = isbn_le +); + +create operator = ( + leftarg = isbn, + rightarg = isbn, + commutator = =, +-- negator = <>, + procedure = isbn_eq +); + +create operator >= ( + leftarg = isbn, + rightarg = isbn, + negator = <, + procedure = isbn_ge +); + +create operator > ( + leftarg = isbn, + rightarg = isbn, + negator = <=, + procedure = isbn_gt +); + +create operator <> ( + leftarg = isbn, + rightarg = isbn, + negator = =, + procedure = isbn_ne +); + +-- +-- eof +-- diff --git a/contrib/likeplanning/Makefile b/contrib/likeplanning/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..2c779ac8aa7f3580e7e124bc0446c741e42e559e --- /dev/null +++ b/contrib/likeplanning/Makefile @@ -0,0 +1,43 @@ +# +# $Header: /cvsroot/pgsql/contrib/likeplanning/Attic/Makefile,v 1.1 2000/06/15 19:04:56 momjian Exp $ +# + +TOPDIR=../.. + +include ../Makefile.global + +NAME = + +PROGRAM = +OBJS = +DOCS = likeplanning.doc +SQLS = disablelike.sql enablelike.sql +BINS = +EXAMPLES= +MODS = + +OTHER_CLEAN = + +all:: + +install: install_doc install_sql + +install_doc: + for inst_file in $(DOCS); do \ + $(INSTALL) $(INSTL_LIB_OPTS) $$inst_file $(CONTRIB_DOCDIR); \ + done + +install_sql: + for inst_file in $(SQLS); do \ + $(INSTALL) $(INSTL_LIB_OPTS) $$inst_file $(CONTRIB_SQLDIR); \ + done + +depend dep: + $(CC) -MM -MG $(CFLAGS) *.c > depend + +clean: + $(RM) *~ $(OBJS) $(MODS) $(PROGRAM) depend $(OTHER_CLEAN) core log + +ifeq (depend,$(wildcard depend)) +include depend +endif diff --git a/contrib/linux/Makefile b/contrib/linux/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..947ced4f487252b9b895df0536c8edf37bab5818 --- /dev/null +++ b/contrib/linux/Makefile @@ -0,0 +1,40 @@ +# +# $Header: /cvsroot/pgsql/contrib/linux/Attic/Makefile,v 1.1 2000/06/15 19:04:57 momjian Exp $ +# + +TOPDIR=../.. + +include ../Makefile.global + +NAME = + +PROGRAM = +OBJS = +DOCS = +SQLS = +BINS = +BINS = postgres.init.csh postgres.init.sh + +EXAMPLES= +MODS = + +OTHER_CLEAN = + +all: + +install: install_bin + +install_bin: + for inst_file in $(BINS); do \ + $(INSTALL) $(INSTL_EXE_OPTS) $$inst_file $(CONTRIB_BINDIR); \ + done + +depend dep: + $(CC) -MM -MG $(CFLAGS) *.c > depend + +clean: + $(RM) *~ $(OBJS) $(MODS) $(PROGRAM) depend $(OTHER_CLEAN) core log + +ifeq (depend,$(wildcard depend)) +include depend +endif diff --git a/contrib/lo/lo_drop.sql b/contrib/lo/lo_drop.sql new file mode 100644 index 0000000000000000000000000000000000000000..2472715a3d5779a55d08ddb82caf1accf8385724 --- /dev/null +++ b/contrib/lo/lo_drop.sql @@ -0,0 +1,21 @@ +-- +-- This removes the type (and a test table) +-- It's used just for development +-- + +-- remove our test table +drop table a; + +-- now drop any sql based functions associated with the lo type +drop function oid(lo); + +-- now drop the type +drop type lo; + +-- as the type is gone, remove the C based functions +drop function lo_in(opaque); +drop function lo_out(opaque); +drop function lo(oid); +drop function lo_manage(); + +-- the lo stuff is now removed from the system diff --git a/contrib/lo/lo_test.sql b/contrib/lo/lo_test.sql new file mode 100644 index 0000000000000000000000000000000000000000..0c0da2cfd65fe0f0e7327004779461dfd7cea781 --- /dev/null +++ b/contrib/lo/lo_test.sql @@ -0,0 +1,57 @@ +-- +-- This runs some common tests against the type +-- +-- It's used just for development +-- + +-- ignore any errors here - simply drop the table if it already exists +drop table a; + +-- create the test table +create table a (fname name,image lo); + +-- insert a null object +insert into a values ('null'); + +-- insert an empty large object +insert into a values ('empty',''); + +-- insert a large object based on a file +insert into a values ('/etc/group',lo_import('/etc/group')::lo); + +-- now select the table +select * from a; + +-- this select also returns an oid based on the lo column +select *,image::oid from a; + +-- now test the trigger +create trigger t_a before update or delete on a for each row execute procedure lo_manage(image); + +-- insert +insert into a values ('aa',''); +select * from a where fname like 'aa%'; + +-- update +update a set image=lo_import('/etc/group')::lo where fname='aa'; +select * from a where fname like 'aa%'; + +-- update the 'empty' row which should be null +update a set image=lo_import('/etc/hosts')::lo where fname='empty'; +select * from a where fname like 'empty%'; +update a set image=null where fname='empty'; +select * from a where fname like 'empty%'; + +-- delete the entry +delete from a where fname='aa'; +select * from a where fname like 'aa%'; + +-- This deletes the table contents. Note, if you comment this out, and +-- expect the drop table to remove the objects, think again. The trigger +-- doesn't get thrown by drop table. +delete from a; + +-- finally drop the table +drop table a; + +-- end of tests diff --git a/contrib/mSQL-interface/Makefile b/contrib/mSQL-interface/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..b5dbd38229d5c2ea76aff066ba5d68d3e81fdecb --- /dev/null +++ b/contrib/mSQL-interface/Makefile @@ -0,0 +1,35 @@ +# +# $Header: /cvsroot/pgsql/contrib/mSQL-interface/Attic/Makefile,v 1.1 2000/06/15 19:05:03 momjian Exp $ +# + +TOPDIR=../.. + +include ../Makefile.global + +NAME = mpgsql + +PROGRAM = +OBJS = +DOCS = $(NAME).doc $(NAME).c +SQLS = +BINS = +EXAMPLES= +MODS = + +OTHER_CLEAN = + +all:: + +install: install_doc + +install_doc: + for inst_file in $(DOCS); do \ + $(INSTALL) $(INSTL_LIB_OPTS) $$inst_file $(CONTRIB_DOCDIR); \ + done + +clean: + $(RM) *~ $(OBJS) $(MODS) $(PROGRAM) depend $(OTHER_CLEAN) core log + +ifeq (depend,$(wildcard depend)) +include depend +endif diff --git a/contrib/noupdate/Makefile b/contrib/noupdate/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..8536e21cebd5699c65cb28df9911ae25bf344d8a --- /dev/null +++ b/contrib/noupdate/Makefile @@ -0,0 +1,53 @@ +# +# $Header: /cvsroot/pgsql/contrib/noupdate/Attic/Makefile,v 1.1 2000/06/15 19:05:04 momjian Exp $ +# + +TOPDIR=../.. + +include ../Makefile.global + +NAME = noup + +PROGRAM = +OBJS = $(NAME).o +DOCS = $(NAME).doc +SQLS = $(NAME).sql +BINS = +EXAMPLES= +MODS = $(NAME)$(DLSUFFIX) + +CFLAGS += -I. $(CFLAGS_SL) + +OTHER_CLEAN = $(SQLS) + +all: $(MODS) $(SQLS) + +%.sql: %.sql.in + $(SED) "s|MODULE_PATHNAME|$(CONTRIB_MODDIR)/$@|" < $< > $@ + +install: install_doc install_sql install_mod + +install_doc: + for inst_file in $(DOCS); do \ + $(INSTALL) $(INSTL_LIB_OPTS) $$inst_file $(CONTRIB_DOCDIR); \ + done + +install_sql: + for inst_file in $(SQLS); do \ + $(INSTALL) $(INSTL_LIB_OPTS) $$inst_file $(CONTRIB_SQLDIR); \ + done + +install_mod: + for inst_file in $(MODS); do \ + $(INSTALL) $(INSTL_SHLIB_OPTS) $$inst_file $(CONTRIB_MODDIR); \ + done + +depend dep: + $(CC) -MM -MG $(CFLAGS) *.c > depend + +clean: + $(RM) *~ $(OBJS) $(MODS) $(PROGRAM) depend $(OTHER_CLEAN) core log + +ifeq (depend,$(wildcard depend)) +include depend +endif diff --git a/contrib/noupdate/noup.sql.in b/contrib/noupdate/noup.sql.in new file mode 100644 index 0000000000000000000000000000000000000000..d5107492089e399efc88f0d4b3fa28db7a01eb63 --- /dev/null +++ b/contrib/noupdate/noup.sql.in @@ -0,0 +1,7 @@ +DROP FUNCTION noup (); + +CREATE FUNCTION noup () + RETURNS opaque + AS 'MODULE_PATHNAME' + LANGUAGE 'C' +; diff --git a/contrib/pg_dumplo/INSTALL b/contrib/pg_dumplo/INSTALL new file mode 100644 index 0000000000000000000000000000000000000000..15733527a90c54b3ea4c7ee3142c6586366091c9 --- /dev/null +++ b/contrib/pg_dumplo/INSTALL @@ -0,0 +1,37 @@ + + +pg_dumplo - PostgreSQL large object dumper +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +For more information see the help ( pg_dumplo -h ) and examples in +this help or the cool HOWTO. + + +Compilation: +~~~~~~~~~~~ + - In the PG contrib tree: + * run master ./configure in the PG source top directory + * run 'make' + * run 'make install' + + - Out of PG contrib: + * edit Makefile.out + * run 'make -f Makefile.out' + + +THANKS: +~~~~~~ + <??? I lost his e-mail ???> + * option '--all' and pg_class usage + + Pavel JanÃk ml. <Pavel.Janik@linux.cz> + * HOWTO + + + + Karel Zak <zakkr@zf.jcu.cz> + + + + + diff --git a/contrib/pg_dumplo/Makefile.out b/contrib/pg_dumplo/Makefile.out new file mode 100644 index 0000000000000000000000000000000000000000..15bae55e2067968f4b289d652b57b87dc40a04c7 --- /dev/null +++ b/contrib/pg_dumplo/Makefile.out @@ -0,0 +1,42 @@ + +# ---------- +# pg_dumplo - Makefile for compilation out of PostgreSQL contrib tree +# ---------- + + +# Set correct values +# +CFLAGS = -Wall -fpic +CC = gcc +RM = rm +INCLUDE = -I/usr/include/pgsql +LIBS =-L/usr/lib/postgresql/lib -lpq + +# Comment this option if your system not has getopt_long() +# +HAVE_GETOPT_LONG = -DHAVE_GETOPT_LONG + + +# --------------------------- not edit --------------------------------- + +PROGRAM = pg_dumplo + +OBJECTS = main.o lo_export.o lo_import.o utils.o + +CFLAGS += -DOUT_OF_PG $(HAVE_GETOPT_LONG) + +COMPILE = $(CC) $(CPPFLAGS) $(CFLAGS) $(INCLUDE) +LINK = $(CC) $(CFLAGS) -o $@ $(LIBS) + + +all: $(PROGRAM) + +$(PROGRAM): $(OBJECTS) + $(LINK) $(OBJECTS) + +.c.o: $< + $(COMPILE) -c $< + +clean: + $(RM) -f *~ $(OBJECTS) $(PROGRAM) + diff --git a/contrib/pg_dumplo/lo_export.c b/contrib/pg_dumplo/lo_export.c new file mode 100644 index 0000000000000000000000000000000000000000..80d401902c1721b02126eb3c0342546488bd1596 --- /dev/null +++ b/contrib/pg_dumplo/lo_export.c @@ -0,0 +1,176 @@ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <fcntl.h> +#include <errno.h> +#include <time.h> + +#include <libpq-fe.h> +#include <libpq/libpq-fs.h> + +#include "pg_dumplo.h" + +extern int errno; + +#define LOAD_LOLIST_QUERY "\ + SELECT c.relname, a.attname \ + FROM pg_class c, pg_attribute a, pg_type t \ + WHERE a.attnum > 0 \ + AND a.attrelid = c.oid \ + AND a.atttypid = t.oid \ + AND t.typname = 'oid' \ + AND c.relname NOT LIKE 'pg_%'" + + +void +load_lolist( LODumpMaster *pgLO ) +{ + LOlist *ll; + int i; + int n; + + /* ---------- + * Now find any candidate tables who have columns of type oid (the + * column oid is ignored, as it has attnum < 1) + * ---------- + */ + if (!(pgLO->res = PQexec(pgLO->conn, LOAD_LOLIST_QUERY))) { + + fprintf(stderr, "%s: Select from pg_class failed.\n", progname); + exit(RE_ERROR); + } + + if ((n = PQntuples(pgLO->res)) == 0) { + + fprintf(stderr, "%s: No large objects in the database.\n", progname); + exit(RE_ERROR); + } + + pgLO->lolist = (LOlist *) malloc((n + 1) * sizeof(LOlist)); + + if (!pgLO->lolist) { + fprintf(stderr, "%s: can't allocate memory\n", progname); + exit(RE_ERROR); + } + + for (i = 0, ll = pgLO->lolist; i < n; i++, ll++) { + ll->lo_table = strdup(PQgetvalue(pgLO->res, i, 0)); + ll->lo_attr = strdup(PQgetvalue(pgLO->res, i, 1)); + } + + PQclear(pgLO->res); + ll++; + ll->lo_table = ll->lo_attr = (char *) NULL; +} + +void +pglo_export(LODumpMaster *pgLO) +{ + LOlist *ll; + int tuples; + char path[BUFSIZ], + Qbuff[QUERY_BUFSIZ]; + + if (pgLO->action != ACTION_SHOW) { + time_t t; + time(&t); + fprintf(pgLO->index, "#\n# This is the PostgreSQL large object dump index\n#\n"); + fprintf(pgLO->index, "#\tDate: %s", ctime(&t)); + fprintf(pgLO->index, "#\tHost: %s\n", pgLO->host); + fprintf(pgLO->index, "#\tDatabase: %s\n", pgLO->db); + fprintf(pgLO->index, "#\tUser: %s\n", pgLO->user); + fprintf(pgLO->index, "#\n# oid\ttable\tattribut\tinfile\n#\n"); + } + + pgLO->counter = 0; + + for(ll=pgLO->lolist; ll->lo_table != NULL; ll++) { + + /* ---------- + * Query + * ---------- + */ + sprintf(Qbuff, "SELECT x.%s FROM %s x, pg_class c WHERE x.%s = c.oid and c.relkind = 'l'", + ll->lo_attr, ll->lo_table, ll->lo_attr); + + /* puts(Qbuff); */ + + pgLO->res = PQexec(pgLO->conn, Qbuff); + + if ((tuples = PQntuples(pgLO->res)) == 0) { + + if (!pgLO->quiet && pgLO->action == ACTION_EXPORT_ATTR) + printf("%s: not large objets in '%s'\n", progname, ll->lo_table); + continue; + + } else if (check_res(pgLO)) { + + int t; + char *val; + + /* ---------- + * Create DIR/FILE + * ---------- + */ + if (tuples && pgLO->action != ACTION_SHOW) { + + sprintf(path, "%s/%s/%s", pgLO->space, pgLO->db, ll->lo_table); + + if (mkdir(path, DIR_UMASK) == -1) { + if (errno != EEXIST) { + perror(path); + exit(RE_ERROR); + } + } + + sprintf(path, "%s/%s", path, ll->lo_attr); + + if (mkdir(path, DIR_UMASK) == -1) { + if (errno != EEXIST) { + perror(path); + exit(RE_ERROR); + } + } + + if (!pgLO->quiet) + printf("dump %s.%s (%d lagre obj)\n", + ll->lo_table, ll->lo_attr, tuples); + } + + pgLO->counter += tuples; + + for(t=0; t<tuples; t++) { + + Oid lo = (Oid) 0; + + val = PQgetvalue(pgLO->res, t, 0); + + if (!val) + continue; + else + lo = (Oid) atol(val); + + if (pgLO->action == ACTION_SHOW) { + printf("%s.%s: %ld\n", ll->lo_table, + ll->lo_attr, (long) lo); + continue; + } + + sprintf(path, "%s/%s/%s/%s/%s", pgLO->space, + pgLO->db, ll->lo_table, ll->lo_attr, val); + + if (lo_export(pgLO->conn, lo, path) < 0) + fprintf(stderr, "%s: %s\n", PQerrorMessage(pgLO->conn), progname); + + else + fprintf(pgLO->index, "%s\t%s\t%s\t%s/%s/%s/%s\n", val, + ll->lo_table, ll->lo_attr, pgLO->db, ll->lo_table, ll->lo_attr, val); + } + } + } + } + diff --git a/contrib/pg_dumplo/lo_import.c b/contrib/pg_dumplo/lo_import.c new file mode 100644 index 0000000000000000000000000000000000000000..98d81f19faf0b1d32a6199266538f8f9bfa84c12 --- /dev/null +++ b/contrib/pg_dumplo/lo_import.c @@ -0,0 +1,89 @@ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <fcntl.h> +#include <errno.h> +#include <time.h> + +#include <libpq-fe.h> +#include <libpq/libpq-fs.h> + +#include "pg_dumplo.h" + +extern int errno; + +void +pglo_import(LODumpMaster *pgLO) +{ + LOlist loa; + long new_oid; + char tab[MAX_TABLE_NAME], attr[MAX_ATTR_NAME], + path[BUFSIZ], lo_path[BUFSIZ], + Qbuff[QUERY_BUFSIZ]; + + while(fgets(Qbuff, QUERY_BUFSIZ, pgLO->index)) { + + if (*Qbuff == '#') + continue; + + if (! pgLO->remove && ! pgLO->quiet) + printf(Qbuff); + + sscanf(Qbuff, "%ld\t%s\t%s\t%s\n", &loa.lo_oid, tab, attr, path); + loa.lo_table = tab; + loa.lo_attr = attr; + + sprintf(lo_path, "%s/%s", pgLO->space, path); + + /* ---------- + * Import LO + * ---------- + */ + if ((new_oid = lo_import(pgLO->conn, lo_path)) <= 0) { + + fprintf(stderr, "%s: %s\n", progname, PQerrorMessage(pgLO->conn)); + + PQexec(pgLO->conn, "ROLLBACK"); + fprintf(stderr, "\n%s: ROLLBACK\n", progname); + exit(RE_ERROR); + } + + if (pgLO->remove) { + notice(pgLO, FALSE); + if (lo_unlink(pgLO->conn, (Oid) loa.lo_oid) < 0) + fprintf(stderr, "%s: can't remove LO: %ld (%s)\n", + progname, loa.lo_oid, PQerrorMessage(pgLO->conn)); + + else if (!pgLO->quiet) + printf("remove old %ld and create new %ld\n", + loa.lo_oid, new_oid); + notice(pgLO, TRUE); + } + + pgLO->counter++; + + /* ---------- + * UPDATE oid in tab + * ---------- + */ + sprintf(Qbuff, "UPDATE %s SET %s=%ld WHERE %s=%ld", + loa.lo_table, loa.lo_attr, new_oid, loa.lo_attr, loa.lo_oid); + + /*fprintf(stderr, Qbuff);*/ + + pgLO->res = PQexec(pgLO->conn, Qbuff); + + if (!pgLO->res && PQresultStatus(pgLO->res) != PGRES_COMMAND_OK) { + + fprintf(stderr, "%s: %s\n",progname, PQerrorMessage(pgLO->conn)); + PQclear(pgLO->res); + PQexec(pgLO->conn, "ROLLBACK"); + fprintf(stderr, "\n%s: ROLLBACK\n", progname); + exit(RE_ERROR); + } + } + } diff --git a/contrib/pg_dumplo/main.c b/contrib/pg_dumplo/main.c new file mode 100644 index 0000000000000000000000000000000000000000..bc75476a1d8b91e689fcc842ed8fd5f24bb84d5b --- /dev/null +++ b/contrib/pg_dumplo/main.c @@ -0,0 +1,308 @@ + +/* ------------------------------------------------------------------------- + * pg_dumplo + * + * Portions Copyright (c) 1999-2000, PostgreSQL, Inc + * + * $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/main.c,v 1.1 2000/06/15 19:05:08 momjian Exp $ + * + * Karel Zak 1999-2000 + * ------------------------------------------------------------------------- + */ + + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#ifndef OUT_OF_PG + #include "postgres.h" +#endif + +#include <libpq-fe.h> +#include <libpq/libpq-fs.h> + +#ifdef HAVE_GETOPT_LONG + #include <getopt.h> + #define no_argument 0 + #define required_argument 1 +#endif + +extern int errno; + +char *progname = NULL; + +#include "pg_dumplo.h" + +int main(int argc, char **argv); +static void usage(void); +static void parse_lolist (LODumpMaster *pgLO); + + +/*----- + * The mother of all C functions + *----- + */ +int +main(int argc, char **argv) +{ + LODumpMaster _pgLO, *pgLO = &_pgLO; + char *pwd = NULL; + + pgLO->argv = argv; + pgLO->argc = argc; + pgLO->action = 0; + pgLO->lolist = NULL; + pgLO->user = NULL; + pgLO->db = NULL; + pgLO->host = NULL; + pgLO->space = NULL; + pgLO->index = NULL; + pgLO->remove = FALSE; + pgLO->quiet = FALSE; + pgLO->counter = 0; + pgLO->lolist_start = 0; + + progname = argv[0]; + + /* ---------- + * Parse ARGV + * ---------- + */ + if (argc > 1) { + int arg; + extern int optind; + +#ifdef HAVE_GETOPT_LONG + int l_index=0; + static struct option l_opt[] = { + { "help", no_argument, 0, 'h' }, + { "user", required_argument, 0, 'u' }, + { "pwd", required_argument, 0, 'p' }, + { "db", required_argument, 0, 'd' }, + { "host", required_argument, 0, 'h' }, + { "space", required_argument, 0, 's' }, + { "import", no_argument, 0, 'i' }, + { "remove", no_argument, 0, 'r' }, + { "quiet", no_argument, 0, 'q' }, + { "all", no_argument, 0, 'a' }, + { "show", no_argument, 0, 'w' }, + { NULL, 0, 0, 0 } + }; + + while((arg = getopt_long(argc, argv, "?aehu:p:qd:l:t:irs:w", l_opt, &l_index)) != -1) { +#else + while((arg = getopt(argc, argv, "?aehu:p:qd:l:t:irs:w")) != -1) { +#endif + switch(arg) { + case '?': + case 'h': + usage(); + exit(RE_OK); + case 'u': + pgLO->user = strdup(optarg); + break; + case 't': + pgLO->host = strdup(optarg); + break; + case 'p': + pwd = strdup(optarg); + break; + case 'd': + pgLO->db = strdup(optarg); + break; + case 's': + pgLO->space = strdup(optarg); + break; + case 'i': + pgLO->action = ACTION_IMPORT; + break; + case 'l': + pgLO->action = ACTION_EXPORT_ATTR; + pgLO->lolist_start = optind-1; + parse_lolist (pgLO); + break; + case 'e': + case 'a': + pgLO->action = ACTION_EXPORT_ALL; + break; + case 'w': + pgLO->action = ACTION_SHOW; + break; + case 'r': + pgLO->remove = TRUE; + break; + case 'q': + pgLO->quiet = TRUE; + break; + default: + fprintf(stderr, "%s: bad arg!\n", progname); + usage(); + exit(RE_ERROR); + } + } + } else { + usage(); + exit(RE_ERROR); + } + + /* ---------- + * Check space + * ---------- + */ + if (! pgLO->space) { + if (!(pgLO->space = getenv("PWD"))) { + fprintf(stderr, "%s: not set space for dump-tree (option '-s' or $PWD).\n", progname); + exit(RE_ERROR); + } + } + + /* ---------- + * Make connection + * ---------- + */ + pgLO->conn = PQsetdbLogin(pgLO->host, NULL, NULL, NULL, pgLO->db, + pgLO->user, pwd); + + if (PQstatus(pgLO->conn) == CONNECTION_BAD) { + fprintf(stderr, "%s (connection): %s\n", progname, PQerrorMessage(pgLO->conn)); + exit(RE_ERROR); + } + pgLO->host = PQhost(pgLO->conn) ? PQhost(pgLO->conn) : "localhost"; + pgLO->db = PQdb(pgLO->conn); + pgLO->user = PQuser(pgLO->conn); + + + /* ---------- + * Init index file + * ---------- + */ + if (pgLO->action) { + index_file(pgLO); + } else { + fprintf(stderr, "%s: What do you want - export or import?\n", progname); + exit(RE_ERROR); + } + + PQexec(pgLO->conn, "BEGIN"); + + switch(pgLO->action) { + + case ACTION_SHOW: + case ACTION_EXPORT_ALL: + load_lolist(pgLO); + + case ACTION_EXPORT_ATTR: + pglo_export(pgLO); + if (!pgLO->quiet) { + if (pgLO->action == ACTION_SHOW) + printf("\nDatabase '%s' content %d large objects.\n\n", pgLO->db, pgLO->counter); + else + printf("\nExported %d large objects.\n\n", pgLO->counter); + } + break; + + case ACTION_IMPORT: + pglo_import(pgLO); + if (!pgLO->quiet) + printf("\nImported %d large objects.\n\n", pgLO->counter); + break; + } + + PQexec(pgLO->conn, "COMMIT"); + PQfinish(pgLO->conn); + + if (pgLO->action != ACTION_SHOW) + fclose(pgLO->index); + + exit(RE_OK); +} + +static void +parse_lolist (LODumpMaster *pgLO) +{ + LOlist *ll; + char **d, + *loc, + buff[MAX_TABLE_NAME + MAX_ATTR_NAME +1]; + + pgLO->lolist = (LOlist *) malloc(pgLO->argc * sizeof(LOlist)); + + if (! pgLO->lolist) { + fprintf(stderr, "%s: can't allocate memory\n", progname); + exit(RE_ERROR); + } + + for( d=pgLO->argv + pgLO->lolist_start, ll=pgLO->lolist; + *d != NULL; + d++, ll++) { + + strncpy(buff, *d, MAX_TABLE_NAME + MAX_ATTR_NAME); + + if ((loc = strchr(buff, '.')) == NULL) { + fprintf(stderr, "%s: '%s' is bad 'table.attr'\n", progname, buff); + exit(RE_ERROR); + } + *loc = '\0'; + ll->lo_table = strdup(buff); + ll->lo_attr = strdup(++loc); + } + ll++; + ll->lo_table = ll->lo_attr = (char *) NULL; +} + + +static void +usage() +{ + printf("\npg_dumplo %s - PostgreSQL large objects dump\n", VERSION); + puts("pg_dumplo [option]\n\n" + +#ifdef HAVE_GETOPT_LONG + + "-h --help this help\n" + "-u --user=<username> username for connection to server\n" + "-p --password=<password> password for connection to server\n" + "-d --db=<database> database name\n" + "-t --host=<hostname> server hostname\n" + "-s --space=<dir> directory with dump tree (for export/import)\n" + "-i --import import large obj dump tree to DB\n" + "-e --export export (dump) large obj to dump tree\n" + "-l <table.attr ...> dump attribute (columns) with LO to dump tree\n" + "-a --all dump all LO in DB (default)\n" + "-r --remove if is set '-i' try remove old LO\n" + "-q --quiet run quietly\n" + "-w --show not dump, but show all LO in DB\n" + ); /* puts() */ + +#else + "-h this help\n" + "-u <username> username for connection to server\n" + "-p <password> password for connection to server\n" + "-d <database> database name\n" + "-t <hostname> server hostname\n" + "-s <dir> directory with dump tree (for export/import)\n" + "-i import large obj dump tree to DB\n" + "-e export (dump) large obj to dump tree\n" + "-l <table.attr ...> dump attribute (columns) with LO to dump tree\n" + "-a dump all LO in DB (default)\n" + "-r if is set '-i' try remove old LO\n" + "-q run quietly\n" + "-w not dump, but show all LO in DB\n" + ); /* puts() */ + +#endif + + puts( + "Example (dump): pg_dumplo -d my_db -s /my_dump/dir -l t1.a t1.b t2.a\n" + " pg_dumplo -a -d my_db -s /my_dump/dir\n" + "Example (import): pg_dumplo -i -d my_db -s /my_dump/dir\n" + "Example (show): pg_dumplo -w -d my_db\n\n" + "Note: * option '-l' must be last option!\n" + " * option '-i' without option '-r' make new large obj in DB\n" + " not rewrite old, the '-i' UPDATE oid numbers in table.attr only!\n" + " * if is not set option -s, the pg_dumplo use $PWD\n" + ); /* puts()*/ +} diff --git a/contrib/pg_dumplo/pg_dumplo.h b/contrib/pg_dumplo/pg_dumplo.h new file mode 100644 index 0000000000000000000000000000000000000000..d9132ba059abcced5c5a8d9fefe3da63faaff96e --- /dev/null +++ b/contrib/pg_dumplo/pg_dumplo.h @@ -0,0 +1,68 @@ + +#ifndef _PG_LODUMP_H_ +#define _PG_LODUMP_H_ + +#define VERSION "0.0.5" + +/* ---------- + * Define + * ---------- + */ +#define QUERY_BUFSIZ (8*1024) +#define DIR_UMASK 0755 +#define FILE_UMASK 0666 + +#define TRUE 1 +#define FALSE 0 +#define RE_OK 0 +#define RE_ERROR 1 + +#define MAX_TABLE_NAME 128 +#define MAX_ATTR_NAME 128 + +extern char *progname; + +/* ---------- + * LO struct + * ---------- + */ +typedef struct { + char *lo_table, + *lo_attr; + long lo_oid; +} LOlist; + +typedef struct { + int action; + LOlist *lolist; + char **argv, + *user, + *db, + *host, + *space; + FILE *index; + int counter, + argc, + lolist_start, + remove, + quiet; + PGresult *res; + PGconn *conn; +} LODumpMaster; + +typedef enum { + ACTION_NONE, + ACTION_SHOW, + ACTION_EXPORT_ATTR, + ACTION_EXPORT_ALL, + ACTION_IMPORT +} PGLODUMP_ACTIONS; + +extern void notice (LODumpMaster *pgLO, int set); +extern int check_res (LODumpMaster *pgLO); +extern void index_file (LODumpMaster *pgLO); +extern void load_lolist (LODumpMaster *pgLO); +extern void pglo_export (LODumpMaster *pgLO); +extern void pglo_import (LODumpMaster *pgLO); + +#endif /* _PG_LODUMP_H */ diff --git a/contrib/pg_dumplo/utils.c b/contrib/pg_dumplo/utils.c new file mode 100644 index 0000000000000000000000000000000000000000..70bfb8b5dbcdfe80095923dd05e00a73e12f8a50 --- /dev/null +++ b/contrib/pg_dumplo/utils.c @@ -0,0 +1,94 @@ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <fcntl.h> +#include <errno.h> +#include <time.h> + +#include <libpq-fe.h> +#include <libpq/libpq-fs.h> + +#include "pg_dumplo.h" + +extern int errno; + +static void Dummy_NoticeProcessor(void * arg, const char * message); +static void Default_NoticeProcessor(void * arg, const char * message); + + +void +index_file(LODumpMaster *pgLO) +{ + char path[BUFSIZ]; + + if (pgLO->action == ACTION_SHOW) + return; + + sprintf(path, "%s/%s", pgLO->space, pgLO->db); + + if (pgLO->action == ACTION_EXPORT_ATTR || + pgLO->action == ACTION_EXPORT_ALL) { + + if (mkdir(path, DIR_UMASK) == -1) { + if (errno != EEXIST) { + perror(path); + exit(RE_ERROR); + } + } + + sprintf(path, "%s/lo_dump.index", path); + + if ((pgLO->index = fopen(path, "w")) == NULL) { + perror(path); + exit(RE_ERROR); + } + + } else if (pgLO->action != ACTION_NONE ) { + + sprintf(path, "%s/lo_dump.index", path); + + if ((pgLO->index = fopen(path, "r")) == NULL) { + perror(path); + exit(RE_ERROR); + } + } +} + +int +check_res(LODumpMaster *pgLO) +{ + if (!pgLO->res && PQresultStatus(pgLO->res) != PGRES_COMMAND_OK) { + fprintf(stderr, "%s: %s\n", progname, PQerrorMessage(pgLO->conn)); + PQclear(pgLO->res); + return FALSE; + } + if (PQresultStatus(pgLO->res) != PGRES_TUPLES_OK) { + fprintf(stderr, "%s: Tuples is not OK.\n", progname); + PQclear(pgLO->res); + return FALSE; + } + return TRUE; +} + +static +void Dummy_NoticeProcessor(void * arg, const char * message) +{ + ; +} + +static +void Default_NoticeProcessor(void * arg, const char * message) +{ + fprintf(stderr, "%s", message); +} + +void +notice(LODumpMaster *pgLO, int set) +{ + if (set)PQsetNoticeProcessor(pgLO->conn, Default_NoticeProcessor, NULL); + else PQsetNoticeProcessor(pgLO->conn, Dummy_NoticeProcessor, NULL); +} diff --git a/contrib/pgbench/pgbench_jis.doc b/contrib/pgbench/pgbench_jis.doc new file mode 100644 index 0000000000000000000000000000000000000000..da33c317446e9fb14f10e540843c2ee35bd7f78f --- /dev/null +++ b/contrib/pgbench/pgbench_jis.doc @@ -0,0 +1,166 @@ +pgbench 1.2 README 2000/1/15 Tatsuo Ishii (t-ishii@sra.co.jp) + +$B"#(Bpgbench $B$H$O!)(B + +pgbench $B$O(B TPC-B$B$K;w$?%Y%s%A%^!<%/%F%9%H$r9T$J$&%W%m%0%i%`$G$9!#:#$N$H(B +$B$3$m(B PostgreSQL $B@lMQ$G$9!#(B + +pgbench $B$O(B select/update/insert $B$r4^$`%H%i%s%6%/%7%g%s$r<B9T$7!"A4BN$N(B +$B<B9T;~4V$H<B:]$K40N;$7$?%H%i%s%6%/%7%g%s$N?t$+$i(B 1 $BIC4V$K<B9T$G$-$?%H(B +$B%i%s%6%/%7%g%s?t(B (tps) $B$rI=<($7$^$9!#=hM}$NBP>]$H$J$k%F!<%V%k$O%G%U%)(B +$B%k%H$G$O(B 10$BK|%?%W%k$N%G!<%?$r4^$_$^$9!#(B + +$B<B:]$NI=<($O0J2<$N$h$&$J46$8$G$9!#(B + +number of clients: 4 +number of transactions per client: 100 +number of processed transactions: 400/400 +tps = 19.875015(including connections establishing) +tps = 20.098827(excluding connections establishing) + +pgbench $B$O(B JDBCBench $B$H$$$&!"$b$H$b$H$O(B MySQL $BMQ$K=q$+$l$?(B JDBC $BMQ$N%Y(B +$B%s%A%^!<%/%W%m%0%i%`$r;29M$K:n@.$5$l$^$7$?!#(B + +$B"#(Bpgbench $B$NFCD'(B + +o C $B8@8l$H(B libpq $B$@$1$G=q$+$l$F$$$k$N$G0\?"@-$,9b$/!"4JC1$K%$%s%9%H!<(B +$B%k$G$-$^$9!#(B + +o pgbench $B$O(B libpq $B$NHsF14|=hM}5!G=$r;H$C$F%^%k%A%f!<%64D6-$r%7%_%e%l!<(B +$B%H$7$^$9!#MF0W$KF1;~@\B34D6-$r%F%9%H$G$-$^$9!#(B + +$B"#(Bpgbench $B$N%$%s%9%H!<%k(B + +Makefile$B$N0lHV>e$K$"$k(B + + POSTGRESHOME = /usr/local/pgsql + +$B$rI,MW$K1~$8$F=$@5$7!"(Bconfigure;make $B$9$k$@$1$G$9!#(B + +$B"#(Bpgbench $B$N;H$$J}(B + +$B4pK\E*$J;H$$J}$O!"(B + +$ pgbench [$B%G!<%?%Y!<%9L>(B] + +$B$G$9!#%G!<%?%Y!<%9L>$r>JN,$9$k$H!"%f!<%6L>$HF1$8%G!<%?%Y!<%9$r;XDj$7$?(B +$B$b$N$H$_$J$7$^$9!#%G!<%?%Y!<%9$O8e=R$N(B -i $B%*%W%7%g%s$r;H$C$F$"$i$+$8$a(B +$B=i4|2=$7$F$*$/I,MW$,$"$j$^$9!#(B + +pgbench $B$K$O$$$m$$$m$J%*%W%7%g%s$,$"$j$^$9!#(B + +-h $B%[%9%HL>(B PostgreSQL$B$N%G!<%?%Y!<%9%G!<%b%s(B postmaster $B$NF0(B + $B$$$F$$$k%[%9%HL>$r;XDj$7$^$9!#>JN,$9$k$H<+%[%9%H$K(B Unix domain + socket $B$G@\B3$7$^$9!#(B + +-p $B%]!<%HHV9f(B postmaster $B$N;HMQ$9$k%]!<%HHV9f$r;XDj$7$^$9!#>JN,$9$k$H(B 5432 + $B$,;XDj$5$l$?$b$N$H$_$J$7$^$9!#(B + +-c $B%/%i%$%"%s%H?t(B $BF1;~<B9T%/%i%$%"%s%H?t$r;XDj$7$^$9!#>JN,;~$O(B + 1 $B$H$J$j$^$9!#(Bpgbench $B$OF1;~<B9T%/%i%$%"%s%HKh$K(B + $B%U%!%$%k%G%#%9%/%j%W%?$r;HMQ$9$k$N$G!";HMQ2DG=(B + $B%U%!%$%k%G%#%9%/%j%W%??t$r1[$($k%/%i%$%"%s%H?t$O(B + $B;XDj$G$-$^$;$s!#;HMQ2DG=%U%!%$%k%G%#%9%/%j%W%??t(B + $B$O(B limit $B$d(B ulimit $B%3%^%s%I$GCN$k$3$H$,$G$-$^$9!#(B + +-t $B%H%i%s%6%/%7%g%s?t(B $B3F%/%i%$%"%s%H$,<B9T$9$k%H%i%s%6%/%7%g%s?t$r(B + $B;XDj$7$^$9!#>JN,;~$O(B 10 $B$H$J$j$^$9!#(B + +-s $B%9%1!<%j%s%0%U%!%/%?!<(B + + -i $B%*%W%7%g%s$H0l=o$K;HMQ$7$^$9!#(B + $B%9%1!<%j%s%0%U%!%/%?!<$O(B1$B0J>e$N@0?t!#%9%1!<%j%s%0%U%!(B + $B%/%?!<$rJQ$($k$3$H$K$h$j!"%F%9%H$NBP>]$H$J$k%F!<%V%k$N(B + $BBg$-$5$,(B 10$BK|(B x [$B%9%1!<%j%s%0%U%!%/%?!<(B]$B$K$J$j$^$9!#(B + $B%G%U%)%k%H$N%9%1!<%j%s%0%U%!%/%?!<$O(B 1 $B$G$9!#(B + +-v $B$3$N%*%W%7%g%s$r;XDj$9$k$H!"%Y%s%A%^!<%/3+;OA0$K(B vacuum $B$H(B + history $B$N%/%j%"$r9T$J$$$^$9!#(B-v $B$H(B -n $B$r>JN,$9$k$H!"(B + $B:G>.8B$N(B vacuum $B$J$I$r9T$$$^$9!#$9$J$o$A!"(Bhistory $B$N:o=|!"(B + $B$H(B history, branches, history $B$N(B vacuum $B$r9T$$$^$9!#(B + $B$3$l$O!"(Bvacuum $B$N;~4V$r:G>.8B$K$7$J$,$i!"%Q%U%)!<%^%s%9$K(B + $B1F6A$9$k%4%_A]=|$r8z2LE*$K9T$$$^$9!#DL>o$O(B -v $B$H(B -n $B$r(B + $B>JN,$9$k$3$H$r$*$9$9$a$7$^$9!#(B + +-n $B$3$N%*%W%7%g%s$r;XDj$9$k$H!"%Y%s%A%^!<%/3+;OA0$K(B vacuum $B$H(B + history $B$N%/%j%"$r9T$J$$$^$;$s!#(B + +-S TPC-B$B$N%H%i%s%6%/%7%g%s$G$O$J$/!"8!:w$N$_$N%H%i%s%6%/%7%g%s$r(B + $B<B9T$7$^$9!#8!:w%9%T!<%I$rB,Dj$7$?$$$H$-$K;H$$$^$9!#(B + +-d $B%G%P%C%0%*%W%7%g%s!#MM!9$J>pJs$,I=<($5$l$^$9!#(B + +$B"#%G!<%?%Y!<%9$N=i4|2=(B + +pgbench $B$G%Y%s%A%^!<%/%F%9%H$r<B;\$9$k$?$a$K$O!"$"$i$+$8$a%G!<%?%Y!<%9(B +$B$r=i4|2=$7!"%F%9%H%G!<%?$r:n$kI,MW$,$"$j$^$9!#(B + +$ pgbench -i [$B%G!<%?%Y!<%9L>(B] + +$B$3$l$K$h$j0J2<$N%F!<%V%k$,:n$i$l$^$9(B($B%9%1!<%j%s%0%U%!%/%?!<(B == 1 $B$N>l9g(B)$B!#(B + +$B!vCm0U!v(B +$BF1$8L>A0$N%F!<%V%k$,$"$k$H:o=|$5$l$F$7$^$&$N$G$4Cm0U2<$5$$!*!*(B + +$B%F!<%V%kL>(B $B%?%W%k?t(B +------------------------- +branches 1 +tellers 10 +accounts 100000 +history 0 + +$B%9%1!<%j%s%0%U%!%/%?!<$r(B 10,100,1000 $B$J$I$KJQ99$9$k$H!">e5-%?%W%k?t$O(B +$B$=$l$K1~$8$F(B10$BG\!"(B100$BG\!"(B1000$BG\$K$J$j$^$9!#$?$H$($P!"%9%1!<%j%s%0%U%!(B +$B%/%?!<$r(B 10 $B$H$9$k$H!"(B + +$B%F!<%V%kL>(B $B%?%W%k?t(B +------------------------- +branches 10 +tellers 100 +accounts 1000000 +history 0 + +$B$K$J$j$^$9!#(B + +$B"#!V%H%i%s%6%/%7%g%s!W$NDj5A(B + +pgbench $B$G$O!"0J2<$N%7!<%1%s%9$rA4It40N;$7$F(B1$B%H%i%s%6%/%7%g%s$H?t$($F(B +$B$$$^$9!#(B + +(1) begin; + +(2) update accounts set abalance = abalance + :delta where aid = :aid; + $B$3$3$G!"(B:delta$B$O(B1$B$+$i(B1000$B$^$G$NCM$r<h$kMp?t!"(B:aid $B$O(B 1$B$+$i(B100000$B$^$G(B + $B$NCM$r<h$kMp?t$G$9!#0J2<!"Mp?t$NCM$O$=$l$>$l$3$N%H%i%s%6%/%7%g%s$N(B + $BCf$G$OF1$8CM$r;H$$$^$9!#(B + +(3) select abalance from accounts where aid = :aid; + $B$3$3$G$O(B1$B7o$@$18!:w$5$l$^$9!#(B + +(4) update tellers set tbalance = tbalance + :delta where tid = :tid; + $B$3$3$G(B :tid $B$O(B 1$B$+$i(B10$B$N4V$NCM$r$H$kMp?t$G$9!#(B + +(5) update branches set bbalance = bbalance + :delta where bid = :bid; + $B$3$3$G(B :bid $B$O(B 1 $B$+$i(B[$B%9%1%j%s%0%U%!%/%?!<(B]$B$N4V$NCM$r<h$kMp?t$G$9!#(B + +(6) insert into history(tid,bid,aid,delta) values(:tid,:bid,:aid,:delta); + +(7) end; + +$B"#:n<T$H%i%$%;%s%9>r7o(B + +pgbench $B$O@P0f(B $BC#IW$K$h$C$F=q$+$l$^$7$?!#%i%$%;%s%9>r7o$O(B pgbench.c $B$N(B +$BKAF,$K=q$$$F$"$j$^$9!#$3$N>r7o$r<i$k8B$jL5=~$GMxMQ$7!"$^$?<+M3$K:FG[IU(B +$B$G$-$^$9!#(B + +$B"#2~DjMzNr(B + +2000/1/15 pgbench-1.2 $B$O(B PostgreSQL $B$K(B contribute $B$5$l$^$7$?!#(B + * -v $B%*%W%7%g%sDI2C(B + +1999/09/29 pgbench-1.1 $B%j%j!<%9(B + * $BC+ED$5$s$K$h$k(Bcygwin$BBP1~%Q%C%A<h$j9~$_(B + * $B%P%C%/%(%s%I%/%i%C%7%e;~$NBP1~(B + * -S $B%*%W%7%g%sDI2C(B + +1999/09/04 pgbench-1.0 $B%j%j!<%9(B diff --git a/contrib/spi/autoinc.sql.in b/contrib/spi/autoinc.sql.in new file mode 100644 index 0000000000000000000000000000000000000000..d587b567b37b33e85b1f144796c55b9dfd24c49b --- /dev/null +++ b/contrib/spi/autoinc.sql.in @@ -0,0 +1,6 @@ +DROP FUNCTION autoinc(); + +CREATE FUNCTION autoinc() + RETURNS opaque + AS 'MODULE_PATHNAME' + LANGUAGE 'newC'; diff --git a/contrib/spi/insert_username.sql.in b/contrib/spi/insert_username.sql.in new file mode 100644 index 0000000000000000000000000000000000000000..d60aebc1b0e73434b55de2872c85ea200c4fbb00 --- /dev/null +++ b/contrib/spi/insert_username.sql.in @@ -0,0 +1,6 @@ +DROP FUNCTION insert_username(); + +CREATE FUNCTION insert_username() + RETURNS opaque + AS 'MODULE_PATHNAME' + LANGUAGE 'newC'; diff --git a/contrib/spi/moddatetime.sql.in b/contrib/spi/moddatetime.sql.in new file mode 100644 index 0000000000000000000000000000000000000000..cfb7c3c508b0af84458ab44ddf5937fef565703b --- /dev/null +++ b/contrib/spi/moddatetime.sql.in @@ -0,0 +1,6 @@ +DROP FUNCTION moddatetime(); + +CREATE FUNCTION moddatetime() + RETURNS opaque + AS 'MODULE_PATHNAME' + LANGUAGE 'newC'; diff --git a/contrib/spi/refint.sql.in b/contrib/spi/refint.sql.in new file mode 100644 index 0000000000000000000000000000000000000000..91448e8a2ed03e82cb68fc050427dc6d70a0cfdf --- /dev/null +++ b/contrib/spi/refint.sql.in @@ -0,0 +1,14 @@ +DROP FUNCTION check_primary_key (); +DROP FUNCTION check_foreign_key (); + +CREATE FUNCTION check_primary_key () + RETURNS opaque + AS 'MODULE_PATHNAME' + LANGUAGE 'newC' +; + +CREATE FUNCTION check_foreign_key () + RETURNS opaque + AS 'MODULE_PATHNAME' + LANGUAGE 'newC' +; diff --git a/contrib/spi/timetravel.sql.in b/contrib/spi/timetravel.sql.in new file mode 100644 index 0000000000000000000000000000000000000000..0de680cb39ad5427202d15023bd16684136de5c2 --- /dev/null +++ b/contrib/spi/timetravel.sql.in @@ -0,0 +1,12 @@ +DROP FUNCTION timetravel(); +DROP FUNCTION set_timetravel(name, int4); + +CREATE FUNCTION timetravel() + RETURNS opaque + AS 'MODULE_PATHNAME' + LANGUAGE 'newC'; + +CREATE FUNCTION set_timetravel(name, int4) + RETURNS int4 + AS 'MODULE_PATHNAME' + LANGUAGE 'newC' WITH (isStrict); diff --git a/contrib/tips/Makefile b/contrib/tips/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..4ad5db146d99f4d6e8f130bc53ad4ff86b7a8264 --- /dev/null +++ b/contrib/tips/Makefile @@ -0,0 +1,30 @@ +# +# $Header: /cvsroot/pgsql/contrib/tips/Attic/Makefile,v 1.1 2000/06/15 19:05:17 momjian Exp $ +# + +TOPDIR=../.. + +include ../Makefile.global + +NAME = + +PROGRAM = +OBJS = +DOCS = apachelog.doc +SQLS = +BINS = +EXAMPLES= +MODS = + +all:: + +install: install_doc + +install_doc: + for inst_file in $(DOCS); do \ + $(INSTALL) $(INSTL_LIB_OPTS) $$inst_file $(CONTRIB_DOCDIR); \ + done + +clean: + $(RM) *~ + diff --git a/contrib/unixdate/Makefile b/contrib/unixdate/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..7481202998677be79f54a13914581326b4a2457c --- /dev/null +++ b/contrib/unixdate/Makefile @@ -0,0 +1,30 @@ +# +# $Header: /cvsroot/pgsql/contrib/unixdate/Attic/Makefile,v 1.1 2000/06/15 19:05:22 momjian Exp $ +# + +TOPDIR=../.. + +include ../Makefile.global + +NAME = unixdate + +PROGRAM = +OBJS = +DOCS = +SQLS = $(NAME).sql +BINS = +EXAMPLES= +MODS = + +all:: + +install: install_sql + +install_sql: + for inst_file in $(SQLS); do \ + $(INSTALL) $(INSTL_LIB_OPTS) $$inst_file $(CONTRIB_SQLDIR); \ + done + +clean: + $(RM) *~ +