diff --git a/contrib/Contrib.index b/contrib/Contrib.index new file mode 100644 index 0000000000..3fc460cc47 --- /dev/null +++ b/contrib/Contrib.index @@ -0,0 +1,88 @@ + +The PostgreSQL contrib: +~~~~~~~~~~~~~~~~~~~~~~ + +apache_logging - + Getting Apache to log to PostgreSQL + by Terry Mackintosh + +array - + Array iterator functions + by Massimo Dal Zotto + +earthdistance - + Operator for computing earth distance for two points + by Hal Snyder + +findoidjoins - + Finds the joins used by oid columns by examining the actual + values in the oid columns and row oids. + by Bruce Momjian + +fulltextindex - + Full text indexing using triggers + by Maarten Boekhold + +isbn_issn - + PostgreSQL type extensions for ISBN (books) and ISSN (serials) + by Garrett A. Wollman + +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 + +linux - + Start postgres back end system + by Thomas Lockhart + +lo - + Large Object maintenance + by Peter Mount + +miscutil - + Postgres assert checking and various utility functions + by Dal Zotto + +mSQL-interface - + mSQL API translation library + by Aldrin Leal + +noupdate - + trigger to prevent updates on single columns + + +pg_dumplo - + Dump large objects + by Karel Zak + +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 + +tools - + Assorted developer tools + by Massimo Dal Zotto + +unixdate - + Conversions from integer to datetime + by Thomas Lockhart + +userlock - + User locks + by Massimo Dal Zotto + +vacuumlo - + Remove orphaned large objects + by Peter T Mount + +pgbench - + TPC-B like benchmarking tool + by Tatsuo Ishii diff --git a/contrib/Makefile.global b/contrib/Makefile.global new file mode 100644 index 0000000000..43cbf853b8 --- /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 0000000000..fdb4552f8a --- /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 0000000000..6b6d68e490 --- /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 = ); + + return $n;; +} + +sub get_password { + print "Password: "; + + system("stty -echo < /dev/tty"); + chop($pwd = ); + 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 0000000000..e0da2353c5 --- /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 0000000000..a1d891d7bc --- /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 + +#include +#include + +/* + * 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 0000000000..e0b90eca33 --- /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 0000000000..2c779ac8aa --- /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 0000000000..947ced4f48 --- /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 0000000000..2472715a3d --- /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 0000000000..0c0da2cfd6 --- /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 0000000000..b5dbd38229 --- /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 0000000000..8536e21ceb --- /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 0000000000..d510749208 --- /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 0000000000..15733527a9 --- /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: +~~~~~~ + + * option '--all' and pg_class usage + + Pavel Janík ml. + * HOWTO + + + + Karel Zak + + + + + diff --git a/contrib/pg_dumplo/Makefile.out b/contrib/pg_dumplo/Makefile.out new file mode 100644 index 0000000000..15bae55e20 --- /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 0000000000..80d401902c --- /dev/null +++ b/contrib/pg_dumplo/lo_export.c @@ -0,0 +1,176 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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; tres, 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 0000000000..98d81f19fa --- /dev/null +++ b/contrib/pg_dumplo/lo_import.c @@ -0,0 +1,89 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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 0000000000..bc75476a1d --- /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 +#include +#include +#include +#include + +#ifndef OUT_OF_PG + #include "postgres.h" +#endif + +#include +#include + +#ifdef HAVE_GETOPT_LONG + #include + #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 for connection to server\n" + "-p --password= password for connection to server\n" + "-d --db= database name\n" + "-t --host= server hostname\n" + "-s --space= 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 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 for connection to server\n" + "-p password for connection to server\n" + "-d database name\n" + "-t server hostname\n" + "-s 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 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 0000000000..d9132ba059 --- /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 0000000000..70bfb8b5db --- /dev/null +++ b/contrib/pg_dumplo/utils.c @@ -0,0 +1,94 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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 0000000000..da33c31744 --- /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]$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 + +$Be$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;~JN,;~$O(B + 1 $B$H$J$j$^$9!#(Bpgbench $B$OF1;~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 + $BpJs$,I=<($5$l$^$9!#(B + +$B"#%G!<%?%Y!<%9$N=i4|2=(B + +pgbench $B$G%Y%s%A%^!<%/%F%9%H$r(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$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$rr7o(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