-# $PostgreSQL: pgsql/contrib/Makefile,v 1.54 2005/03/12 15:36:24 neilc Exp $
+# $PostgreSQL: pgsql/contrib/Makefile,v 1.55 2005/06/22 22:56:25 tgl Exp $
subdir = contrib
top_builddir = ..
isbn_issn \
lo \
ltree \
- miscutil \
- mysql \
- noupdate \
oid2name \
pg_autovacuum \
pg_buffercache \
- pg_dumplo \
pg_trgm \
pgbench \
pgcrypto \
rtree_gist \
seg \
spi \
- string \
tablefunc \
tips \
- tsearch \
tsearch2 \
userlock \
vacuumlo
# Missing:
# adddepend \ (does not have a makefile)
-# array \ (removed all but the README)
-# ipc_check \ (does not have a makefile)
# mSQL-interface \ (requires msql installed)
# mac \ (does not have a makefile)
# oracle \ (does not have a makefile)
-# pg_upgrade \ (does not have a makefile)
# reindexdb \ (does not have a makefile)
# start-scripts \ (does not have a makefile)
-# tools \ (does not have a makefile)
-# xml \ (non-standard makefile)
# xml2 \ (non-standard makefile)
Add object dependency information to pre-7.3 objects.
by Rod Taylor <rbt@rbt.ca>
-array -
- Array iterator functions (now obsolete due to backend improvements)
- by Massimo Dal Zotto <dz@cs.unitn.it>
-
btree_gist -
Support for emulating BTREE indexing in GiST
by Oleg Bartunov <oleg@sai.msu.su> and Teodor Sigaev <teodor@sigaev.ru>
Index support for arrays of int4, using GiST
by Teodor Sigaev <teodor@sigaev.ru> and Oleg Bartunov <oleg@sai.msu.su>
-ipc_check -
- Simple test script to help in configuring IPC.
- FreeBSD only, for now.
-
isbn_issn -
PostgreSQL type extensions for ISBN (books) and ISSN (serials)
by Garrett A. Wollman <wollman@khavrinen.lcs.mit.edu>
Support functions for MAC address types
by Lawrence E. Rosenman <ler@lerctr.org>
-miscutil -
- PostgreSQL assert checking and various utility functions
- by Massimo Dal Zotto <dz@cs.unitn.it>
-
-mysql -
- Utility to convert MySQL schema dumps to SQL92 and PostgreSQL
- by Thomas Lockhart <lockhart@alumni.caltech.edu>
- Max Rudensky <fonin@ziet.zhitomir.ua>
- Valentine Danilchuk <valdan@ziet.zhitomir.ua>
-
-noupdate -
- Trigger to prevent updates on single columns
-
oid2name -
Maps numeric files to table names
by B Palmer <bpalmer@crimelabs.net>
Real time queries on the shared buffer cache
by Mark Kirkwood <markir@paradise.net.nz>
-pg_dumplo -
- Dump large objects
- by Karel Zak <zakkr@zf.jcu.cz>
-
pg_trgm -
Functions for determining the similarity of text based on trigram
matching.
by Oleg Bartunov <oleg@sai.msu.su> and Teodor Sigaev <teodor@sigaev.ru>
-pg_upgrade -
- Upgrade from previous PostgreSQL version without pg_dump/reload
- by Bruce Momjian <pgman@candle.pha.pa.us>
-
pgbench -
TPC-B like benchmarking tool
by Tatsuo Ishii <t-ishii@sra.co.jp>
start-scripts -
Scripts for starting the server at boot time.
-
-string -
- C-like input/output conversion routines for strings
- by Massimo Dal Zotto <dz@cs.unitn.it>
tablefunc -
Examples of functions returning tables
Getting Apache to log to PostgreSQL
by Terry Mackintosh <terry@terrym.com>
-tools -
- Assorted developer tools
- by Massimo Dal Zotto <dz@cs.unitn.it>
-
-tsearch -
- Full-text-index support using GiST (obsolete version)
- by Teodor Sigaev <teodor@sigaev.ru> and Oleg Bartunov
- <oleg@sai.msu.su>.
-
tsearch2 -
Full-text-index support using GiST
by Teodor Sigaev <teodor@sigaev.ru> and Oleg Bartunov
Remove orphaned large objects
by Peter T Mount <peter@retep.org.uk>
-xml -
- Storing XML in PostgreSQL (obsolete version)
- by John Gray <jgray@azuli.co.uk>
-
xml2 -
Storing XML in PostgreSQL
by John Gray <jgray@azuli.co.uk>
+++ /dev/null
-Array iterator functions have been removed as of PostgreSQL 7.4, because
-equivalent functionality is now available built in to the backend.
-
-For example, previously, using contrib/array, you might have used the
-following construct:
-
- create table t(id int4[], txt text[]);
-
- -- select tuples with some id element equal to 123
- select * from t where t.id *= 123;
-
-Now you would do this instead:
-
- -- select tuples with some id element equal to 123
- select * from t where 123 = any (t.id);
-
- -- or you could also do this
- select * from t where 123 = some (t.id);
-
-Similarly, if using contrib/array, you did the following:
-
- -- select tuples with all txt elements matching '^[A-Z]'
- select * from t where t.txt[1:3] **~ '^[A-Z]';
-
-Now do this instead:
-
- -- select tuples with all txt elements matching '^[A-Z]'
- select * from t where '^[A-Z]' ~ all (t.txt[1:3]);
-
-See this section in the PostgreSQL documentation for more detail:
- The SQL Language => Functions and Operators => Row and Array Comparisons
+++ /dev/null
-
-This simple perl script was designed under FreeBSD, and, right now, is
-limited to it. It provides a simple way of determining and directing
-administrators in what has to be done to get IPC working, and configured.
-
-Usage:
-
-ipc_check.pl
-
- - simply checks for semaphores and shared memory being enabled
- - if one or other is not enabled, appropriate "options" are provided
- to get it compiled into the kernel
-
-ipc_check.pl -B <# of buffers>
-
- - checks to see if there are sufficient shared memory buffers to
- run the postmaster with a -B option as provided
- - if insufficient buffers are provided, appropriate 'sysctl' commands,
- and instructions, are provided to the administrator to increase
- them
-
-
+++ /dev/null
-#!/usr/bin/perl
-
-# Notes ... -B 1 == 8k
-
-if(@ARGV > 1) {
- if($ARGV[0] eq "-B") {
- $buffers = $ARGV[1];
- }
-}
-
-if($buffers > 0) {
- $kb_memory_required = $buffers * 8;
-}
-
-$shm = `sysctl kern.ipc | grep shmall`;
-( $junk, $shm_amt ) = split(/ /, $shm);
-chomp($shm_amt);
-$sem = `sysctl kern.ipc | grep semmap`;
-
-print "\n\n";
-if(length($shm) > 0) {
- printf "shared memory enabled: %d kB available\n", $shm_amt * 4;
- if($buffers > 0) {
- if($kb_memory_required / 4 > $shm_amt) {
- print "\n";
- print "to provide enough shared memory for a \"-B $buffers\" setting\n";
- print "issue the following command\n\n";
- printf "\tsysctl -w kern.ipc.shmall=%d\n", $kb_memory_required / 4;
- print "\nand add the following to your /etc/sysctl.conf file:\n\n";
- printf "\tkern.ipc.shmall=%d\n", $kb_memory_required / 4;
- } else {
- print "\n";
- print "no changes to kernel required for a \"-B $buffers\" setting\n";
- }
- }
-} else {
- print "no shared memory support available\n";
- print "add the following option to your kernel config:\n\n";
- print "\toptions SYSVSHM\n\n";
-}
-
-print "\n==========================\n\n";
-if(length($sem) > 0) {
- print "semaphores enabled\n";
-} else {
- print "no semaphore support available\n";
- print "add the following option to your kernel config:\n\n";
- print "\toptions SYSVSEM\n\n";
-}
-
-
+++ /dev/null
-# $PostgreSQL: pgsql/contrib/miscutil/Makefile,v 1.18 2004/08/20 20:13:05 momjian Exp $
-
-MODULES = misc_utils
-DATA_built = misc_utils.sql
-DOCS = README.misc_utils
-
-ifdef USE_PGXS
-PGXS = $(shell pg_config --pgxs)
-include $(PGXS)
-else
-subdir = contrib/miscutil
-top_builddir = ../..
-include $(top_builddir)/src/Makefile.global
-include $(top_srcdir)/contrib/contrib-global.mk
-endif
+++ /dev/null
-Miscellaneous utility functions for PostgreSQL.
-Copyright (C) 1999, Massimo Dal Zotto <dz@cs.unitn.it>
-
-This software is distributed under the GNU General Public License
-either version 2, or (at your option) any later version.
-
-backend_pid()
-
- return the pid of our corresponding backend.
-
-unlisten(relname)
-
- unlisten from a relation or from all relations if the argument
- is null, empty or '*'.
- It is now obsoleted by the new unlisten command but still useful
- if you want unlisten a name computed by the query.
- Note that a listen/notify relname can be any ascii string, not
- just valid relation names.
-
-min(x,y)
-max(x,y)
-
- return the min or max of two integers.
-
---
-Massimo Dal Zotto <dz@cs.unitn.it>
+++ /dev/null
-/*
- * misc_utils.c --
- *
- * This file defines miscellaneous PostgreSQL utility functions.
- *
- * Copyright (C) 1999, Massimo Dal Zotto <dz@cs.unitn.it>
- *
- * This file is distributed under the GNU General Public License
- * either version 2, or (at your option) any later version.
- */
-
-#include "postgres.h"
-
-#include <unistd.h>
-#include <signal.h>
-
-#include "access/heapam.h"
-#include "access/htup.h"
-#include "access/relscan.h"
-#include "access/skey.h"
-#include "access/tupdesc.h"
-#include "catalog/pg_listener.h"
-#include "commands/async.h"
-#include "fmgr.h"
-#include "storage/lmgr.h"
-#include "utils/fmgroids.h"
-#include "utils/rel.h"
-#include "utils/tqual.h"
-
-#include "misc_utils.h"
-
-
-int
-backend_pid(void)
-{
- return getpid();
-}
-
-int
-unlisten(char *relname)
-{
- Async_Unlisten(relname, getpid());
- return 0;
-}
-
-int
-int4max(int x, int y)
-{
- return Max(x, y);
-}
-
-int
-int4min(int x, int y)
-{
- return Min(x, y);
-}
-
-/*
- * Return the number of active listeners on a relation name.
- */
-int
-active_listeners(text *relname)
-{
- HeapTuple lTuple;
- Relation lRel;
- HeapScanDesc sRel;
- TupleDesc tdesc;
- ScanKeyData key;
- Datum d;
- bool isnull;
- int len,
- pid;
- int count = 0;
- int ourpid = getpid();
- char listen_name[NAMEDATALEN];
-
- lRel = heap_open(ListenerRelationId, AccessShareLock);
- tdesc = RelationGetDescr(lRel);
-
- if (relname && (VARSIZE(relname) > VARHDRSZ))
- {
- MemSet(listen_name, 0, NAMEDATALEN);
- len = Min(VARSIZE(relname) - VARHDRSZ, NAMEDATALEN - 1);
- memcpy(listen_name, VARDATA(relname), len);
- ScanKeyInit(&key,
- Anum_pg_listener_relname,
- BTEqualStrategyNumber, F_NAMEEQ,
- PointerGetDatum(listen_name));
- sRel = heap_beginscan(lRel, SnapshotNow, 1, &key);
- }
- else
- sRel = heap_beginscan(lRel, SnapshotNow, 0, (ScanKey) NULL);
-
- while ((lTuple = heap_getnext(sRel, ForwardScanDirection)) != NULL)
- {
- d = heap_getattr(lTuple, Anum_pg_listener_pid, tdesc, &isnull);
- pid = DatumGetInt32(d);
- if ((pid == ourpid) || (kill(pid, 0) == 0))
- count++;
- }
- heap_endscan(sRel);
-
- heap_close(lRel, AccessShareLock);
-
- return count;
-}
+++ /dev/null
-#ifndef MISC_UTILS_H
-#define MISC_UTILS_H
-
-int backend_pid(void);
-int unlisten(char *relname);
-int int4max(int x, int y);
-int int4min(int x, int y);
-int active_listeners(text *relname);
-
-#endif
+++ /dev/null
--- misc_utils.sql --
---
--- SQL code to define misc functions.
---
--- Copyright (c) 1998, Massimo Dal Zotto <dz@cs.unitn.it>
---
--- This file is distributed under the GNU General Public License
--- either version 2, or (at your option) any later version.
-
--- Return the pid of the backend.
---
-
--- Adjust this setting to control where the objects get created.
-SET search_path = public;
-
-CREATE OR REPLACE FUNCTION backend_pid()
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE 'C';
-
--- Unlisten from a relation.
---
-CREATE OR REPLACE FUNCTION "unlisten"(name)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE 'C';
-
--- Unlisten from all relations for this backend.
---
-CREATE OR REPLACE FUNCTION "unlisten"()
-RETURNS int4
-AS 'SELECT "unlisten"(''*'')'
-LANGUAGE 'SQL';
-
--- min(x,y)
---
-CREATE OR REPLACE FUNCTION min(int4,int4)
-RETURNS int4
-AS 'MODULE_PATHNAME', 'int4min'
-LANGUAGE 'C' STRICT;
-
--- max(x,y)
---
-CREATE OR REPLACE FUNCTION max(int4,int4)
-RETURNS int4
-AS 'MODULE_PATHNAME', 'int4max'
-LANGUAGE 'C' STRICT;
-
--- Return the number of active listeners on a relation
---
-CREATE OR REPLACE FUNCTION active_listeners(text)
-RETURNS int4
-AS 'MODULE_PATHNAME'
-LANGUAGE 'C';
+++ /dev/null
-# mysql conversion Perl scripts
-# $PostgreSQL: pgsql/contrib/mysql/Makefile,v 1.1 2004/11/04 06:09:21 neilc Exp $
-
-MODULES =
-SCRIPTS = my2pg.pl mysql2pgsql
-DOCS = README.mysql
-
-ifdef USE_PGXS
-PGXS = $(shell pg_config --pgxs)
-include $(PGXS)
-else
-subdir = contrib/mysql
-top_builddir = ../..
-include $(top_builddir)/src/Makefile.global
-include $(top_srcdir)/contrib/contrib-global.mk
-endif
+++ /dev/null
-Here are two conversion utilities for MySQL dumps. Use the one you prefer.
-
-The most recent version of my2pg.pl can be obtained from:
-
- http://www.omnistarinc.com/~fonin/downloads.php#my2pg
-
-my2pg.diff has additional changes for CREATE FUNCTION.
-
-Another tool, mysql2pgsql, can be found at:
-
- http://gborg.postgresql.org/project/mysql2psql/projdisplay.php
-
+++ /dev/null
-*** /laptop/my2pg.pl Mon Apr 19 18:51:44 2004
---- my2pg.pl Mon Apr 19 18:59:09 2004
-***************
-*** 38,43 ****
---- 38,50 ----
- # $My2pg: my2pg.pl,v 1.28 2001/12/06 19:32:20 fonin Exp $
- # $Id: my2pg.diff,v 1.1 2004/04/19 23:18:12 momjian Exp $
-
-+ # Custom patch
-+ # Revision 1.9 2002/08/22 00:01:39 tgl
-+ # Add a bunch of pseudo-types to replace the behavior formerly associated
-+ # with OPAQUE, as per recent pghackers discussion. I still want to do some
-+ # more work on the 'cstring' pseudo-type, but I'm going to commit the bulk
-+ # of the changes now before the tree starts shifting under me ...
-+
- #
- # $Log: my2pg.diff,v $
- # Revision 1.1 2004/04/19 23:18:12 momjian
- # Update to my2pg version 1.28, add docs, update URL for newest version.
- #
- # Create diff of custom changes Tom made to the utility for CREATE
- # FUNCTION.
- #
- # This will make moving this utility out of CVS easier.
- #
- # Revision 1.28 2002/11/30 12:03:48 fonin
-***************
-*** 332,342 ****
- print LIBTYPES "\n * Types for table ".uc($table_name);
- print LIBTYPES "\n */\n";
-
-! $types.="\nCREATE FUNCTION $typename"."_in (opaque)
- RETURNS $typename
- AS '$libtypename'
- LANGUAGE 'c'
-! WITH (ISCACHABLE);\n";
-
- # creating output function
- my $func_out="
---- 339,349 ----
- print LIBTYPES "\n * Types for table ".uc($table_name);
- print LIBTYPES "\n */\n";
-
-! $types.="\nCREATE FUNCTION $typename"."_in (cstring)
- RETURNS $typename
- AS '$libtypename'
- LANGUAGE 'c'
-! WITH (ISSTRICT, ISCACHABLE);\n";
-
- # creating output function
- my $func_out="
-***************
-*** 386,396 ****
- return (*a>=*b);
- }\n";
-
-! $types.="\nCREATE FUNCTION $typename"."_out (opaque)
-! RETURNS opaque
- AS '$libtypename'
- LANGUAGE 'c'
-! WITH (ISCACHABLE);\n";
-
- $types.="\nCREATE TYPE $typename (
- internallength = 2,
---- 393,403 ----
- return (*a>=*b);
- }\n";
-
-! $types.="\nCREATE FUNCTION $typename"."_out ($typename)
-! RETURNS cstring
- AS '$libtypename'
- LANGUAGE 'c'
-! WITH (ISSTRICT, ISCACHABLE);\n";
-
- $types.="\nCREATE TYPE $typename (
- internallength = 2,
-***************
-*** 532,538 ****
- print LIBTYPES "\n * Types for table ".uc($table_name);
- print LIBTYPES "\n */\n";
-
-! $types.="\nCREATE FUNCTION $typename"."_in (opaque)
- RETURNS $typename
- AS '$libtypename'
- LANGUAGE 'c';\n";
---- 539,545 ----
- print LIBTYPES "\n * Types for table ".uc($table_name);
- print LIBTYPES "\n */\n";
-
-! $types.="\nCREATE FUNCTION $typename"."_in (cstring)
- RETURNS $typename
- AS '$libtypename'
- LANGUAGE 'c';\n";
-***************
-*** 584,591 ****
-
- \n";
-
-! $types.="\nCREATE FUNCTION $typename"."_out (opaque)
-! RETURNS opaque
- AS '$libtypename'
- LANGUAGE 'c';\n";
-
---- 591,598 ----
-
- \n";
-
-! $types.="\nCREATE FUNCTION $typename"."_out ($typename)
-! RETURNS cstring
- AS '$libtypename'
- LANGUAGE 'c';\n";
-
+++ /dev/null
-<HTML>
-<HEAD>
-<TITLE>my2pg - MySQL -> PostgreSQL dump conversion utility.</TITLE>
-<LINK REV="made" HREF="mailto:bhcompile@daffy.perf.redhat.com">
-</HEAD>
-
-<BODY>
-
-<A NAME="__index__"></A>
-<!-- INDEX BEGIN -->
-
-<UL>
-
- <LI><A HREF="#name">NAME</A></LI>
- <LI><A HREF="#syntax">SYNTAX</A></LI>
- <LI><A HREF="#overview">OVERVIEW</A></LI>
- <LI><A HREF="#commandline options">COMMAND-LINE OPTIONS</A></LI>
- <LI><A HREF="#side effects">SIDE EFFECTS</A></LI>
- <LI><A HREF="#bugs">BUGS</A></LI>
- <LI><A HREF="#authors">AUTHORS</A></LI>
- <LI><A HREF="#credits">CREDITS</A></LI>
- <LI><A HREF="#license">LICENSE</A></LI>
-</UL>
-<!-- INDEX END -->
-
-<HR>
-<P>
-<H1><A NAME="name">NAME</A></H1>
-<P>my2pg - MySQL -> PostgreSQL dump conversion utility.</P>
-<P>
-<HR>
-<H1><A NAME="syntax">SYNTAX</A></H1>
-<PRE>
- mysqldump db | ./my2pg.pl [-nds] > pgsqldump.sql
- vi libtypes.c
- make
- psql database < pgsqldump.txt
-where</PRE>
-<DL>
-<DT><STRONG><A NAME="item_pgsqldump%2Esql"><EM>pgsqldump.sql</EM></A></STRONG><BR>
-<DD>
-- file suitable for loading into PostgreSQL.
-<P></P>
-<DT><STRONG><A NAME="item_libtypes%2Ec"><EM>libtypes.c</EM></A></STRONG><BR>
-<DD>
-- C source for emulated MySQL types (ENUM, SET) generated by <STRONG>my2pg</STRONG>
-<P></P></DL>
-<P>
-<HR>
-<H1><A NAME="overview">OVERVIEW</A></H1>
-<P><STRONG>my2pg</STRONG> utility attempts to convert MySQL database dump to Postgres's one.
-<STRONG>my2pg</STRONG> performs such conversions:</P>
-<UL>
-<LI><STRONG><A NAME="item_Type_conversion%2E">Type conversion.</A></STRONG><BR>
-
-It tries to find proper Postgres
-type for each column.
-Unknown types are silently pushing to output dump;
-ENUM and SET types implemented via user types
-(C source for such types can be found in
-<STRONG>libtypes.c</STRONG> file);
-<P></P>
-<LI><STRONG><A NAME="item_Encloses_identifiers_into_double_quotes%2E">Encloses identifiers into double quotes.</A></STRONG><BR>
-
-All column and table
-names should be enclosed to double-quotes to prevent
-conflict with reserved SQL keywords;
-<P></P>
-<LI><STRONG><A NAME="item_Converting">Converting</A></STRONG><BR>
-
-AUTO_INCREMENT fields to SERIAL. Actually, creating the sequence and
-setting default value to nextval('seq'), well, you know :)
-<P></P>
-<LI><STRONG>Converting</STRONG><BR>
-
-<CODE>KEY(field)</CODE> to CREATE INDEX i_field on table (field);
-<P></P>
-<LI><STRONG><A NAME="item_The_same">The same</A></STRONG><BR>
-
-for UNIQUE keys;
-<P></P>
-<LI><STRONG><A NAME="item_Indices">Indices</A></STRONG><BR>
-
-are creating AFTER rows insertion (to speed up the load);
-<P></P>
-<LI><STRONG><A NAME="item_Translates_%27%23%27">Translates '#'</A></STRONG><BR>
-
-MySQL comments to ANSI SQL '--'
-<P></P></UL>
-<P>It encloses dump in transaction block to prevent single errors
-during data load.</P>
-<P>
-<HR>
-<H1><A NAME="commandline options">COMMAND-LINE OPTIONS</A></H1>
-<P>My2pg takes the following command-line options:</P>
-<DL>
-<DT><STRONG><A NAME="item_%2Dn">-n</A></STRONG><BR>
-<DD>
-Convert *CHAR DEFAULT '' NOT NULL types to *CHAR NULL.
-Postgres can't load empty '' strings in NOT NULL fields.
-<P></P>
-<DT><STRONG><A NAME="item_%2Dd">-d</A></STRONG><BR>
-<DD>
-Add double quotes around table and column names
-<P></P>
-<DT><STRONG><A NAME="item_%2Dh">-h</A></STRONG><BR>
-<DD>
-Show usage banner.
-<P></P>
-<DT><STRONG><A NAME="item_%2Ds">-s</A></STRONG><BR>
-<DD>
-Do not attempt to convert data. Currently my2pg only tries to convert
-date and time data.
-<P></P></DL>
-<P>
-<HR>
-<H1><A NAME="side effects">SIDE EFFECTS</A></H1>
-<UL>
-<LI><STRONG><A NAME="item_creates">creates</A></STRONG><BR>
-
-file <STRONG>libtypes.c</STRONG> in current directory
-overwriting existed file without any checks;
-<P></P>
-<LI><STRONG><A NAME="item_the_same">the same</A></STRONG><BR>
-
-for Makefile.
-<P></P></UL>
-<P>
-<HR>
-<H1><A NAME="bugs">BUGS</A></H1>
-<P>Known bugs are:</P>
-<UL>
-<LI><STRONG><A NAME="item_Possible_problems_with_the_timestamp_data%2E">Possible problems with the timestamp data.</A></STRONG><BR>
-
-PostgreSQL does not accept incorrect date/time values like <STRONG>2002-00-15</STRONG>,
-while MySQL does not care about that. Currently my2pg cannot handle this
-issue. You should care yourself to convert such a data.
-<P></P>
-<LI><STRONG><A NAME="item_Use_%2Ds_option_if_your_numeric_data_are_broken_du">Use -s option if your numeric data are broken during conversion.</A></STRONG><BR>
-
-My2pg attempts to convert MySQL timestamps of the form <STRONG>yyyymmdd</STRONG> to
-<STRONG>yyyy-mm-dd</STRONG> and <STRONG>yyyymmddhhmmss</STRONG> to <STRONG>yyyy-mm-dd hh:mm:ss</STRONG>. It performs
-some heuristic checks to ensure that the month,day,hour,minutes and seconds have
-values from the correct range (0..12, 0..31, 0..23, 0..59, 0..59 respectively).
-It is still possible that your numeric values that satisfy these conditions
-will get broken.
-<P></P>
-<LI><STRONG><A NAME="item_Possible_problems_with_enclosing_identifiers_in_do">Possible problems with enclosing identifiers in double quotes.</A></STRONG><BR>
-
-All identifiers such as table and column names should be enclosed in double
-quotes. Program can't handle upper-case identifiers,
-like DBA. Lower-case identifiers are OK.
-<P></P>
-<LI><STRONG><A NAME="item_SET_type_emulation_is_not_full%2E_LIKE_operation_o">SET type emulation is not full. LIKE operation on</A></STRONG><BR>
-
-SETs, raw integer input values should be implemented
-<P></P>
-<LI><STRONG><A NAME="item_Makefile"><STRONG>Makefile</STRONG></A></STRONG><BR>
-
-generated during output is
-platform-dependent and surely works only on
-Linux/gcc (FreeBSD/gcc probably works as well - not tested)
-<P></P>
-<LI><STRONG><A NAME="item_Generated_libtypes%2Ec_contain_line">Generated <STRONG>libtypes.c</STRONG> contain line</A></STRONG><BR>
-
-<PRE>
- #include <postgres.h></PRE>
-<P>This file may be located not in standard compiler
-include path, you need to check it before compiling.</P>
-</UL>
-<P>
-<HR>
-<H1><A NAME="authors">AUTHORS</A></H1>
-<P><STRONG>(c) 2000-2002 Maxim V. Rudensky (<A HREF="mailto:fonin@omnistaronline.com">fonin@ziet.zhitomir.ua</A>)</STRONG> (developer, maintainer)</P>
-<P><STRONG>(c) 2000 Valentine V. Danilchuk (<A HREF="mailto:valdan@ziet.zhitomir.ua">valdan@ziet.zhitomir.ua</A>)</STRONG> (original script)</P>
-<P>
-<HR>
-<H1><A NAME="credits">CREDITS</A></H1>
-<P>Great thanks to all those people who provided feedback and make development
-of this tool easier.</P>
-<P>Jeff Waugh <<A HREF="mailto:jaw@ic.net">jaw@ic.net</A>></P>
-<P>Joakim Lemström <<A HREF="mailto:jocke@bytewize.com">jocke@bytewize.com</A>> || <<A HREF="mailto:buddyh19@hotmail.com">buddyh19@hotmail.com</A>></P>
-<P>Yunliang Yu <<A HREF="mailto:yu@math.duke.edu">yu@math.duke.edu</A>></P>
-<P>Brad Hilton <<A HREF="mailto:bhilton@vpop.net">bhilton@vpop.net</A>></P>
-<P>If you are not listed here please write to me.</P>
-<P>
-<HR>
-<H1><A NAME="license">LICENSE</A></H1>
-<P><STRONG>BSD</STRONG></P>
-
-</BODY>
-
-</HTML>
+++ /dev/null
-#!/usr/bin/perl
-
-#
-# My2Pg: MySQL to PostgreSQL dump conversion utility
-#
-# (c) 2000,2001 Maxim Rudensky <fonin@ziet.zhitomir.ua>
-# (c) 2000 Valentine Danilchuk <valdan@ziet.zhitomir.ua>
-# All right reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1. Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# 2. Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-# 3. All advertising materials mentioning features or use of this software
-# must display the following acknowledgement:
-# This product includes software developed by the Max Rudensky
-# and its contributors.
-# 4. Neither the name of the author nor the names of its contributors
-# may be used to endorse or promote products derived from this software
-# without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-# SUCH DAMAGE.
-#
-# $My2pg: my2pg.pl,v 1.28 2001/12/06 19:32:20 fonin Exp $
-# $Id: my2pg.pl,v 1.13 2004/04/19 23:18:12 momjian Exp $
-
-# Custom patch
-# Revision 1.9 2002/08/22 00:01:39 tgl
-# Add a bunch of pseudo-types to replace the behavior formerly associated
-# with OPAQUE, as per recent pghackers discussion. I still want to do some
-# more work on the 'cstring' pseudo-type, but I'm going to commit the bulk
-# of the changes now before the tree starts shifting under me ...
-
-#
-# $Log: my2pg.pl,v $
-# Revision 1.13 2004/04/19 23:18:12 momjian
-# Update to my2pg version 1.28, add docs, update URL for newest version.
-#
-# Create diff of custom changes Tom made to the utility for CREATE
-# FUNCTION.
-#
-# This will make moving this utility out of CVS easier.
-#
-# Revision 1.12 2004/04/19 23:11:49 momjian
-# Update to my2pg 1.28, from:
-#
-# http://www.omnistarinc.com/~fonin/downloads.php#my2pg
-#
-# Revision 1.28 2002/11/30 12:03:48 fonin
-# PostgreSQL does not support indexes on the partial length of column,
-# e.g.
-# CREATE INDEX i_index ON table (column(16));
-# will not work. Fixed.
-#
-# Added command-line option -s that prevents my2pg from attempting convert
-# the data (currently only timestamps).
-#
-# Better timestamps conversion.
-#
-# Revision 1.27 2002/07/16 14:54:07 fonin
-# Bugfix - didn't quote the fields inside PRIMARY KEY with -d option.
-# Fix by Milan P. Stanic <mps@rns-nis.co.yu>.
-#
-# Revision 1.26 2002/07/14 10:30:27 fonin
-# Bugfix - MySQL keywords inside data (INSERT INTO sentence) were replaced
-# with Postgres keywords and therefore messed up the data.
-#
-# Revision 1.25 2002/07/05 09:20:25 fonin
-# - fixed data that contains two consecutive timestamps - thanks to
-# Ben Darnell <bdarnell@google.com>
-# - word 'default' was converted to upper case inside the data - fixed.
-# Thanks to Madsen Wikholm <madsen@iki.fi>
-#
-# Revision 1.24 2002/04/20 14:15:43 fonin
-# Patch by Felipe Nievinski <fnievinski@terra.com.br>.
-# A table I was re-creating had a composite primary key, and I was using
-# the -d switch to maintain the table and column names
-# adding double quotes around them.
-#
-# The SQL code generated was something like this:
-#
-# CREATE TABLE "rinav" (
-# "UnidadeAtendimento" INT8 DEFAULT '0' NOT NULL,
-# "NumeroRinav" INT8 DEFAULT '0' NOT NULL,
-# -- ...
-# PRIMARY KEY ("UnidadeAtendimento"," NumeroRinav")
-# );
-#
-# Please note the space inside the second column name string in the PK
-# definition. Because of this PostgreSQL was not able to create the table.
-#
-# FIXED.
-#
-# Revision 1.23 2002/02/07 22:13:52 fonin
-# Bugfix by Hans-Juergen Schoenig <hs@cybertec.at>: additional space after
-# FLOAT8 is required.
-#
-# Revision 1.22 2001/12/06 19:32:20 fonin
-# Patch: On line 594 where you check for UNIQUE, I believe the regex should try
-# and match 'UNIQUE KEY'. Otherwise it outputs no unique indexes for the
-# postgres dump.
-# Thanks to Brad Hilton <bhilton@vpop.net>
-#
-# Revision 1.21 2001/08/25 18:55:28 fonin
-# Incorporated changes from Yunliang Yu <yu@math.duke.edu>:
-# - By default table & column names are not quoted; use the new
-# "-d" option if you want to,
-# - Use conditional substitutions to speed up and preserve
-# the data integrity.
-# Fixes by Max:
-# - timestamps conversion fix. Shouldn't break now matching binary data and
-# strings.
-#
-# Revision 1.21 2001/07/23 03:04:39 yu
-# Updates & fixes by Yunliang Yu <yu@math.duke.edu>
-# . By default table & column names are not quoted; use the new
-# "-d" option if you want to,
-# . Use conditional substitutions to speed up and preserve
-# the data integrity.
-#
-# Revision 1.20 2001/07/05 12:45:05 fonin
-# Timestamp conversion enhancement from Joakim Lemström <jocke@bytewize.com>
-#
-# Revision 1.19 2001/05/07 19:36:38 fonin
-# Fixed a bug in quoting PRIMARY KEYs, KEYs and UNIQUE indexes with more than 2 columns. Thanks to Jeff Waugh <jaw@ic.net>.
-#
-# Revision 1.18 2001/03/06 22:25:40 fonin
-# Documentation up2dating.
-#
-# Revision 1.17 2001/03/04 13:01:50 fonin
-# Fixes to make work it right with MySQL 3.23 dumps. Tested on mysqldump 8.11.
-# Also, AUTO_INCREMENT->SERIAL fields no more have DEFAULT and NOT NULL
-# definitions.
-#
-# Revision 1.16 2001/02/02 08:15:34 fonin
-# Sequences should be created BEFORE creating any objects \nthat depends on it.
-#
-# Revision 1.15 2001/01/30 10:13:36 fonin
-# Re-released under BSD-like license.
-#
-# Revision 1.14 2000/12/18 20:55:13 fonin
-# Better -n implementation.
-#
-# Revision 1.13 2000/12/18 15:26:33 fonin
-# Added command-line options. -n forces *CHAR DEFAULT '' NOT NULL to be
-# converted to *CHAR NULL.
-# AUTO_INCREMENT fields converted not in SERIAL but in
-# INT* NOT NULL DEFAULT nextval('seqname').
-# Documentation refreshed.
-# Dump enclosed in single transaction from now.
-#
-# Revision 1.12 2000/12/14 20:57:15 fonin
-# Doublequotation bug fixed (in CREATE INDEX ON TABLE (field1,field2))
-#
-# Revision 1.10 2000/11/27 14:18:22 fonin
-# Fixed bug - occasionaly was broken CREATE SEQUENCE generation
-#
-# Revision 1.8 2000/11/24 15:24:16 fonin
-# TIMESTAMP fix: MySQL output YYYYMMDDmmhhss to YYYYMMDD mmhhss
-#
-# Revision 1.7 2000/11/22 23:04:41 fonin
-# TIMESTAMP field fix. Better doublequoting. Splitting output dump
-# into 2 transactions - create/load/indexing first, sequence setvals then.
-# Added POD documentation.
-#
-#
-
-use Getopt::Std;
-
-my %opts; # command line options
-my $chareg=''; # CHAR conversion regexps
-my $dq=''; # double quote
-
-# parse command line
-getopts('nhds',\%opts);
-
-# output syntax
-if($opts{h} ne '') {
- usage();
- exit;
-}
-
-# convert CHAR types from NOT NULL DEFAULT '' to NULL
-if($opts{n} ne '') {
- $chareg='\s*?(default\s*?\'\')*?\s*?not\s*?null';
-}
-# want double quotes
-if($opts{d} ne '') {
- $dq='"';
-}
-
-if($opts{s} ne '') {
- $safe_data_conv=1;
-}
-else {
- $safe_data_conv=0;
-}
-
-$|=1;
-
-print("------------------------------------------------------------------");
-print("\n-- My2Pg 1.28 translated dump");
-print("\n--");
-print("\n------------------------------------------------------------------");
-
-print("\n\nBEGIN;\n\n\n");
-
-my %index; # contains array of CREATE INDEX for each table
-my %seq; # contains CREATE SEQUENCE for each table
-my %primary; # contains primary (eg SERIAL) fields for each table
-my %identifier; # contains generated by this program identifiers
-my $j=-1; # current position in $index{table}
-my @check; # CHECK constraint for current
-
-# generating full path to libtypes.c
-my $libtypesource='libtypes.c';
-my $libtypename=`pwd`;
-chomp($libtypename);
-$libtypename.='/libtypes.so';
-
-# push header to libtypes.c
-open(LIBTYPES,">$libtypesource");
-print LIBTYPES "/******************************************************";
-print LIBTYPES "\n * My2Pg 1.27 \translated dump";
-print LIBTYPES "\n * User types definitions";
-print LIBTYPES "\n ******************************************************/";
-print LIBTYPES "\n\n#include <postgres.h>\n";
-print LIBTYPES "\n#define ADD_COMMA if(strcmp(result,\"\")!=0) strcat(result,\",\")\n";
-
-# reading STDIN...
-my $tabledef=0; # we are outside a table definition
-while (<>) {
- if(!$tabledef && /^CREATE TABLE \S+/i){
- $tabledef=1;
- } elsif($tabledef && /^\) type=\w*;/i){ # /^\w/i
- $tabledef=0;
- }
-
-# Comments start with -- in SQL
- if(/^#/) {# !/insert into.*\(.*#.*\)/i, in mysqldump output
- s/#/--/;
- }
-
- if($tabledef) {
-# Convert numeric types
- s/tinyint\(\d+\)/INT2/i;
- s/smallint\(\d+\)/INT2/i;
- s/mediumint\(\d+\)/INT4/i;
- s/bigint\(\d+\)/INT8/i;
- s/int\(\d+\)/INT4/i;
- s/float(\(\d+,\d*\))/DECIMAL$1/i;
- s/double precision/FLOAT8 /i;
- s/([\W])double(\(\d+,\d*\))/$1DECIMAL$2/i;
- s/([\W])double[\W]/$1FLOAT8 /i;
- s/([\W])real[\W]/$1FLOAT8 /i;
- s/([\W])real(\(\d+,\d*\))/$1DECIMAL$2/i;
-
-# Convert string types
- s/\w*blob$chareg/text/i;
- s/mediumtext$chareg/text/i;
- s/tinytext$chareg/text/i;
- s/\stext\s+not\s+null/ TEXT DEFAULT '' NOT NULL/i;
- s/(.*?char\(.*?\))$chareg/$1/i;
-
-# Old and New are reserved words in Postgres
- s/^(\s+)Old /${1}MyOld /;
- s/^(\s+)New /${1}MyNew /;
-
-# Convert DATE types
- s/datetime/TIMESTAMP/;
- s/timestamp\(\d+\)/TIMESTAMP/i;
- s/ date / DATE /i;
- if((/date/ig || /time/ig) && /[,(]\d{4}(\d{2})(\d{2})[,)]/ &&
- $1>=0 && $1<=12 && $2>=0 && $2<=31) {
- s/,(\d{4})(\d{2})(\d{2}),/,'$1-$2-$3 00:00:00',/g;
- }
-
-# small hack - convert "default" to uppercase, because below we
-# enclose all lowercase words in double quotes
- if(!/^INSERT/) {
- s/default/DEFAULT/;
- }
-
-# Change all AUTO_INCREMENT fields to SERIAL ones with a pre-defined sequence
- if(/([\w\d]+)\sint.*auto_increment/i) {
- $tmpseq=new_name("$table_name"."_"."$+"."_SEQ",28);
- $seq{$table_name}=$tmpseq;
- $primary{$table_name}=$+;
- s/(int.*?) .*AUTO_INCREMENT/$1 DEFAULT nextval\('$tmpseq'\)/i;
- }
-
-# convert UNSIGNED to CHECK constraints
- if(/^\s+?([\w\d_]+).*?unsigned/i) {
- $check.=",\n CHECK ($dq$1$dq>=0)";
- }
- s/unsigned//i;
-
-# Limited ENUM support - little heuristic
- s/enum\('N','Y'\)/BOOL/i;
- s/enum\('Y','N'\)/BOOL/i;
-# ENUM support
- if(/^\s+?([\w\d_]+).*?enum\((.*?)\)/i) {
- my $enumlist=$2;
- my @item;
- $item[0]='';
- while($enumlist=~s/'([\d\w_]+)'//i) {
- $item[++$#item]=$1;
- }
-# forming identifier name
- $typename=new_name('enum_'.$table_name.'_'.$item[1],28);
-# creating input type function
- my $func_in="
-int2* $typename"."_in (char *str) {
- int2* result;
-
- if(str==NULL)
- return NULL;
-
- result=(int2*)palloc(sizeof(int2));
- *result=-1;";
- for(my $i=0;$i<=$#item;$i++) {
- $func_in.="
- if(strcmp(str,\"$item[$i]\")==0) {
- *result=$i;
- }";
- }
- $func_in.="
- if(*result == -1) {
- elog(ERROR,\"$typename"."_in: incorrect input value\");
- return NULL;
- }
- return (result);
-}\n";
- $types.="\n---";
- $types.="\n--- Types for table ".uc($table_name);
- $types.="\n---\n";
- print LIBTYPES "\n/*";
- print LIBTYPES "\n * Types for table ".uc($table_name);
- print LIBTYPES "\n */\n";
-
- $types.="\nCREATE FUNCTION $typename"."_in (cstring)
- RETURNS $typename
- AS '$libtypename'
- LANGUAGE 'c'
- WITH (ISSTRICT, ISCACHABLE);\n";
-
-# creating output function
- my $func_out="
-char* $typename"."_out (int2 *outvalue) {
- char* result;
-
- if(outvalue==NULL)
- return NULL;
-
- result=(char*)palloc(10);
- switch (*outvalue) {";
- for(my $i=0;$i<=$#item;$i++) {
- $func_out.="
- case $i:
- strcpy(result,\"$item[$i]\");
- break;";
- }
- $func_out.="
- default :
- elog(ERROR,\"$typename"."_out: incorrect stored value\");
- return NULL;
- break;
- }
- return result;
-}\n";
- $func_out.="\nbool $typename"."_eq(int2* a, int2* b) {
- return (*a==*b);
-}
-
-bool $typename"."_ne(int2* a, int2* b) {
- return (*a!=*b);
-}
-
-bool $typename"."_lt(int2* a, int2* b) {
- return (*a<*b);
-}
-
-bool $typename"."_le(int2* a, int2* b) {
- return (*a<=*b);
-}
-
-bool $typename"."_gt(int2* a, int2* b) {
- return (*a>*b);
-}
-
-bool $typename"."_ge(int2* a, int2* b) {
- return (*a>=*b);
-}\n";
-
- $types.="\nCREATE FUNCTION $typename"."_out ($typename)
- RETURNS cstring
- AS '$libtypename'
- LANGUAGE 'c'
- WITH (ISSTRICT, ISCACHABLE);\n";
-
- $types.="\nCREATE TYPE $typename (
- internallength = 2,
- input = $typename\_in,
- output = $typename\_out
-);\n";
-
- $types.="\nCREATE FUNCTION $typename"."_eq ($typename,$typename)
- RETURNS bool
- AS '$libtypename'
- LANGUAGE 'c';
-
-CREATE FUNCTION $typename"."_lt ($typename,$typename)
- RETURNS bool
- AS '$libtypename'
- LANGUAGE 'c';
-
-CREATE FUNCTION $typename"."_le ($typename,$typename)
- RETURNS bool
- AS '$libtypename'
- LANGUAGE 'c';
-
-CREATE FUNCTION $typename"."_gt ($typename,$typename)
- RETURNS bool
- AS '$libtypename'
- LANGUAGE 'c';
-
-CREATE FUNCTION $typename"."_ge ($typename,$typename)
- RETURNS bool
- AS '$libtypename'
- LANGUAGE 'c';
-
-CREATE FUNCTION $typename"."_ne ($typename,$typename)
- RETURNS bool
- AS '$libtypename'
- LANGUAGE 'c';
-
-CREATE OPERATOR < (
- leftarg = $typename,
- rightarg = $typename,
--- negator = >=,
- procedure = $typename"."_lt
-);
-
-CREATE OPERATOR <= (
- leftarg = $typename,
- rightarg = $typename,
--- negator = >,
- procedure = $typename"."_le
-);
-
-CREATE OPERATOR = (
- leftarg = $typename,
- rightarg = $typename,
- commutator = =,
--- negator = <>,
- procedure = $typename"."_eq
-);
-
-CREATE OPERATOR >= (
- leftarg = $typename,
- rightarg = $typename,
- negator = <,
- procedure = $typename"."_ge
-);
-
-CREATE OPERATOR > (
- leftarg = $typename,
- rightarg = $typename,
- negator = <=,
- procedure = $typename"."_gt
-);
-
-CREATE OPERATOR <> (
- leftarg = $typename,
- rightarg = $typename,
- negator = =,
- procedure = $typename"."_ne
-);\n";
-
- print LIBTYPES $func_in;
- print LIBTYPES $func_out;
- s/enum\(.*?\)/$typename/i;
- }
-
-# SET support
- if(/^\s+?([\w\d_]+).*?set\((.*?)\)/i) {
- my $setlist=$2;
- my @item;
- $item[0]='';
- my $maxlen=0; # maximal string length
- while($setlist=~s/'([\d\w_]+)'//i) {
- $item[++$#item]=$1;
- $maxlen+=length($item[$#item])+1;
- }
- $maxlen+=1;
- my $typesize=int($#item/8);
- if($typesize<2) {
- $typesize=2;
- }
- $internalsize=$typesize;
- $typesize='int'.$typesize;
- $typename=new_name('set_'.$table_name.'_'.$item[1],28);
-# creating input type function
- my $func_in="
-$typesize* $typename"."_in (char *str) {
- $typesize* result;
- char* token;
-
- if(str==NULL)
- return NULL;
-
- result=($typesize*)palloc(sizeof($typesize));
- *result=0;
- if(strcmp(str,\"\")==0)
- return result;
- for(token=strtok(str,\",\");token!=NULL;token=strtok(NULL,\",\")) {";
- for(my $i=0,my $j=1;$i<=$#item;$i++,$j*=2) {
- $func_in.="
- if(strcmp(token,\"$item[$i]\")==0) {
- *result|=$j;
- continue;
- }";
- }
- $func_in.="
- }
-
- if(*result == 0) {
- elog(ERROR,\"$typename"."_in: incorrect input value\");
- return NULL;
- }
- return (result);
-
-}\n";
- $types.="\n---";
- $types.="\n--- Types for table ".uc($table_name);
- $types.="\n---\n";
- print LIBTYPES "\n/*";
- print LIBTYPES "\n * Types for table ".uc($table_name);
- print LIBTYPES "\n */\n";
-
- $types.="\nCREATE FUNCTION $typename"."_in (cstring)
- RETURNS $typename
- AS '$libtypename'
- LANGUAGE 'c';\n";
-
-# creating output function
- my $func_out="
-char* $typename"."_out ($typesize *outvalue) {
- char* result;
- int i;
-
- if(outvalue==NULL)
- return NULL;
-
- result=(char*)palloc($maxlen);
- strcpy(result,\"\");
- for(i=1;i<=2 << (sizeof(int2)*8);i*=2) {
- switch (*outvalue & i) {";
- for(my $i=0,$j=1;$i<=$#item;$i++,$j*=2) {
- $func_out.="
- case $j:";
- if($item[$i] ne '') {
- $func_out.="ADD_COMMA;";
- }
- $func_out.="strcat(result,\"$item[$i]\");
- break;";
- }
- $func_out.="
- default :
- break;
- }
- }
-
- return result;
-}\n";
- $func_out.="\nbool $typename"."_eq($typesize* a, $typesize* b) {
- return (*a==*b);
-}
-
-$typesize find_in_set($typesize *a, $typesize *b) {
- int i;
-
- for(i=1;i<=sizeof($typesize)*8;i*=2) {
- if(*a & *b) {
- return 1;
- }
- }
- return 0;
-}
-
-\n";
-
- $types.="\nCREATE FUNCTION $typename"."_out ($typename)
- RETURNS cstring
- AS '$libtypename'
- LANGUAGE 'c';\n";
-
- $types.="\nCREATE TYPE $typename (
- internallength = $internalsize,
- input = $typename\_in,
- output = $typename\_out
-);\n";
-
- $types.="\nCREATE FUNCTION $typename"."_eq ($typename,$typename)
- RETURNS bool
- AS '$libtypename'
- LANGUAGE 'c';
-
-CREATE FUNCTION find_in_set ($typename,$typename)
- RETURNS bool
- AS '$libtypename'
- LANGUAGE 'c';
-
-CREATE OPERATOR = (
- leftarg = $typename,
- rightarg = $typename,
- commutator = =,
- procedure = $typename"."_eq
-);
-
-CREATE OPERATOR <> (
- leftarg = $typename,
- rightarg = $typename,
- commutator = <>,
- negator = =,
- procedure = $typename"."_eq
-);
-
-\n";
-
- print LIBTYPES $func_in;
- print LIBTYPES $func_out;
- s/set\(.*?\)/$typename/i;
- }
-
-# Change multy-field keys to multi-field indices
-# MySQL Dump usually ends the CREATE TABLE statement like this:
-# CREATE TABLE bids (
-# ...
-# PRIMARY KEY (bids_id),
-# KEY offer_id (offer_id,user_id,the_time),
-# KEY bid_value (bid_value)
-# );
-# We want to replace this with smth like
-# CREATE TABLE bids (
-# ...
-# PRIMARY KEY (bids_id),
-# );
-# CREATE INDEX offer_id ON bids (offer_id,user_id,the_time);
-# CREATE INDEX bid_value ON bids (bid_value);
- if (s/CREATE TABLE (.*) /CREATE TABLE $dq$1$dq /i) {
- if($oldtable ne $table_name) {
- $oldtable=$table_name;
- $j=-1;
- $check='';
-
- if($seq{$table_name} ne '') {
- print "\n\n--";
- print "\n-- Sequences for table ".uc($table_name);
- print "\n--\n";
- print "\nCREATE SEQUENCE ".$seq{$table_name}.";\n\n";
- }
-
- print $types;
- $types='';
- $dump=~s/,\n\).*;/\n\);/gmi;
-# removing table options after closing bracket:
-# ) TYPE=ISAM PACK_KEYS=1;
- $dump=~s/\n\).*/\n\);/gmi;
- print $dump;
- $dump='';
- }
- $table_name=$1;
- }
-
-# output CHECK constraints instead UNSIGNED modifiers
- if(/PRIMARY KEY\s+\((.*)\)/i) {
- my $tmpfld=$1;
- $tmpfld=~s/,/","/g if $dq;
- $tmpfld=~s/ //g;
- s/PRIMARY KEY\s+(\(.*\))/PRIMARY KEY \($dq$tmpfld$dq\)/i;
- s/(PRIMARY KEY \(.*\)).*/$1$check\n/i;
- }
-
- if(/^\s*KEY ([\w\d_]+)\s*\((.*)\).*/i) {
- my $tmpfld=$2; my $ky=$1;
- $tmpfld=~s/\s*,\s*/","/g if $dq;
- $tmpfld=~s/(\(\d+\))//g;
- $index{$table_name}[++$j]="CREATE INDEX ${ky}_$table_name\_index ON $dq$table_name$dq ($dq$tmpfld$dq);";
- }
- if(/^\s*UNIQUE.*?([\w\d_]+)\s*\((.*)\).*/i) {
- my $tmpfld=$2; my $ky=$1;
- $tmpfld=~s/,/","/g if $dq;
- $tmpfld=~s/(\(\d+\))//g;
- $index{$table_name}[++$j]="CREATE UNIQUE INDEX ${ky}_$table_name\_index ON $dq$table_name$dq ($dq$tmpfld$dq);";
- }
- s/^\s*UNIQUE (.+).*(\(.*\)).*\n//i;
- s/^\s*KEY (.+).*(\(.*\)).*\n//i;
-
- if($dq && !/^\s*(PRIMARY KEY|UNIQUE |KEY |CREATE TABLE|INSERT INTO|\);)/i) {
- s/\s([A-Za-z_\d]+)\s/ $dq$+$dq /;
- }
- } # end of if($tabledef)
-
- s/INSERT INTO\s+?(.*?)\s+?/INSERT INTO $dq$1$dq /i;
-
-# if not defined -s command-line option (safe data conversion),
-# attempting to convert timestamp data
- if(!$safe_data_conv) {
-# Fix timestamps
- s/'0000-00-00/'0001-01-01/g;
-# may corrupt data !!!
- s/([,(])00000000000000(?=[,)])/$1'00010101 000000'/g;
- if(/[,(]\d{4}(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})[,)]/ &&
- $1>=0 && $1<=12 && $2>=0 && $2<=31 && $3>=0 && $3<=23 &&
- $4>=0 && $4<=59 && $5>=0 && $5<=59) {
- s/([,(])(\d{8})(\d{6})(?=[,)])/$1'$2 $3'/g;
- }
- if(/[,(]\d{4}(\d{2})(\d{2})[,)]/ &&
- $2>=0 && $2<=12 && $3>=0 && $3<=31) {
- s/([,(])(\d{4})(\d{2})(\d{2})(?=[,)])/$1'$2-$3-$4 00:00:00'/g;
- }
- }
-
- $dump.=$_;
-}
-
-if($seq{$table_name} ne '') {
- print "\n\n--";
- print "\n-- Sequences for table ".uc($table_name);
- print "\n--\n";
- print "\nCREATE SEQUENCE ".$seq{$table_name}.";\n\n";
-}
-print $types;
-$dump=~s/,\n\).*;/\n\);/gmi;
-$dump=~s/\n\).*/\n\);/gmi;
-print $dump;
-
-# Output indices for tables
-while(my($table,$ind)=each(%index)) {
- print "\n\n--";
- print "\n-- Indexes for table ".uc($table);
- print "\n--\n";
- for(my $i=0;$i<=$#{$ind};$i++) {
- print "\n$ind->[$i]";
- }
-
-}
-
-while(my($table,$s)=each(%seq)) {
- print "\n\n--";
- print "\n-- Sequences for table ".uc($table);
- print "\n--\n";
-
- # setting SERIAL sequence values right
- if($primary{$table} ne '') {
- print "\nSELECT SETVAL('".$seq{$table}."',(select case when max($dq".$primary{$table}."$dq)>0 then max($dq".$primary{$table}."$dq)+1 else 1 end from $dq$table$dq));";
- }
-}
-
-print("\n\nCOMMIT;\n");
-close(LIBTYPES);
-
-open(MAKE,">Makefile");
-print MAKE "#
-# My2Pg \$Revision: 1.13 $ \translated dump
-# Makefile
-#
-
-all: libtypes.so
-
-libtypes.o: libtypes.c
- gcc -c -fPIC -g -O libtypes.c
-libtypes.so: libtypes.o
- ld -Bshareable -o libtypes.so libtypes.o";
-close(MAKE);
-
-#
-# Function generates unique identifier
-# Args : template name, max length
-# Globals: %identifier
-#
-sub new_name() {
- my $name=lc(shift @_);
- my $len=shift @_;
-
-# truncate long names
- if(length($name)>$len) {
- $name=~s/(.{$len}).*/$1/i;
- }
-
-# find reserved identifiers
- if($identifier{$name}!=1) {
- $identifier{$name}=1;
- return $name;
- }
- else {
- for(my $i=1,my $tmpname=$name.$i;$identifier{$tmpname}!=1;) {
- $tmpname=$name.$i
- }
- $identifier{$tmpname}=1;
- return $tmpname;
- }
-
- die "Error during unique identifier generation :-(";
-}
-
-sub usage() {
-print <<EOF
-my2pg - MySQL to PostgreSQL database dump converter
-
-Copyright (c) 2000-2002 Max Rudensky <fonin\@ziet.zhitomir.ua>
-Copyright (c) 2000 Valentine Danilchuk <valdan\@ziet.zhitomir.ua>
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-code source for license details.
-
-SYNTAX:
- my2pg [-hnds]
-
-OPTIONS:
- h - this help
- n - convert *CHAR NOT NULL DEFAULT '' types to *CHAR NULL
- d - double quotes around table and column names
- s - do not attempt to convert data (timestamps at the moment)
-EOF
-;
-}
-
-
-=head1 NAME
-
-my2pg - MySQL -> PostgreSQL dump conversion utility.
-
-=head1 SYNTAX
-
- mysqldump db | ./my2pg.pl [-nds] > pgsqldump.sql
- vi libtypes.c
- make
- psql database < pgsqldump.txt
-where
-
-=over 4
-
-=item F<pgsqldump.sql>
-
-- file suitable for loading into PostgreSQL.
-
-=item F<libtypes.c>
-
-- C source for emulated MySQL types (ENUM, SET) generated by B<my2pg>
-
-=back
-
-=head1 OVERVIEW
-
-B<my2pg> utility attempts to convert MySQL database dump to Postgres's one.
-B<my2pg> performs such conversions:
-
-=over 4
-
-=item * Type conversion.
-
-It tries to find proper Postgres
-type for each column.
-Unknown types are silently pushing to output dump;
-ENUM and SET types implemented via user types
-(C source for such types can be found in
-B<libtypes.c> file);
-
-=item * Encloses identifiers into double quotes.
-
-All column and table
-names should be enclosed to double-quotes to prevent
-conflict with reserved SQL keywords;
-
-=item * Converting
-
-AUTO_INCREMENT fields to SERIAL. Actually, creating the sequence and
-setting default value to nextval('seq'), well, you know :)
-
-=item * Converting
-
-KEY(field) to CREATE INDEX i_field on table (field);
-
-=item * The same
-
-for UNIQUE keys;
-
-=item * Indices
-
-are creating AFTER rows insertion (to speed up the load);
-
-=item * Translates '#'
-
-MySQL comments to ANSI SQL '--'
-
-=back
-
-It encloses dump in transaction block to prevent single errors
-during data load.
-
-=head1 COMMAND-LINE OPTIONS
-
-My2pg takes the following command-line options:
-
-=over 2
-
-=item -n
-
-Convert *CHAR DEFAULT '' NOT NULL types to *CHAR NULL.
-Postgres can't load empty '' strings in NOT NULL fields.
-
-=item -d
-
-Add double quotes around table and column names
-
-=item -h
-
-Show usage banner.
-
-=item -s
-
-Do not attempt to convert data. Currently my2pg only tries to convert
-date and time data.
-
-=back
-
-=head1 SIDE EFFECTS
-
-=over 4
-
-=item * creates
-
-file B<libtypes.c> in current directory
-overwriting existed file without any checks;
-
-=item * the same
-
-for Makefile.
-
-=back
-
-=head1 BUGS
-
-Known bugs are:
-
-=over 4
-
-=item * Possible problems with the timestamp data.
-
-PostgreSQL does not accept incorrect date/time values like B<2002-00-15>,
-while MySQL does not care about that. Currently my2pg cannot handle this
-issue. You should care yourself to convert such a data.
-
-=item * Use -s option if your numeric data are broken during conversion.
-
-My2pg attempts to convert MySQL timestamps of the form B<yyyymmdd> to
-B<yyyy-mm-dd> and B<yyyymmddhhmmss> to B<yyyy-mm-dd hh:mm:ss>. It performs
-some heuristic checks to ensure that the month,day,hour,minutes and seconds have
-values from the correct range (0..12, 0..31, 0..23, 0..59, 0..59 respectively).
-It is still possible that your numeric values that satisfy these conditions
-will get broken.
-
-=item * Possible problems with enclosing identifiers in double quotes.
-
-All identifiers such as table and column names should be enclosed in double
-quotes. Program can't handle upper-case identifiers,
-like DBA. Lower-case identifiers are OK.
-
-=item * SET type emulation is not full. LIKE operation on
-
-SETs, raw integer input values should be implemented
-
-=item * B<Makefile>
-
-generated during output is
-platform-dependent and surely works only on
-Linux/gcc (FreeBSD/gcc probably works as well - not tested)
-
-=item * Generated B<libtypes.c> contain line
-
- #include <postgres.h>
-
-This file may be located not in standard compiler
-include path, you need to check it before compiling.
-
-=back
-
-=head1 AUTHORS
-
-B<(c) 2000-2002 Maxim V. Rudensky (fonin@ziet.zhitomir.ua)> (developer, maintainer)
-
-B<(c) 2000 Valentine V. Danilchuk (valdan@ziet.zhitomir.ua)> (original script)
-
-=head1 CREDITS
-
-Great thanks to all those people who provided feedback and make development
-of this tool easier.
-
-Jeff Waugh <jaw@ic.net>
-
-Joakim Lemström <jocke@bytewize.com> || <buddyh19@hotmail.com>
-
-Yunliang Yu <yu@math.duke.edu>
-
-Brad Hilton <bhilton@vpop.net>
-
-If you are not listed here please write to me.
-
-=head1 LICENSE
-
-B<BSD>
-
-=cut
+++ /dev/null
-#!/usr/bin/perl
-# mysql2pgsql
-# Take a MySQL schema dump and turn it into SQL92 and PostgreSQL form.
-# Thomas Lockhart, (c) 2000, PostgreSQL Inc.
-# Thanks to Tim Perdue at SourceForge.Net for testing and feedback.
-#
-
-eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
- & eval 'exec perl -S $0 $argv:q'
- if 0;
-
-use IO::File;
-use Getopt::Long;
-
-my $progname = "mysql2pgsql";
-my $version = "0.3";
-
-GetOptions("debug!", "verbose!", "version", "path=s", "help", "data!");
-
-my $debug = $opt_debug || 0;
-my $verbose = $opt_verbose || 0;
-my $pathfrom = $opt_path || "";
-my $nodata = (! $opt_data);
-
-$pathfrom = "$pathfrom/" if ($pathfrom =~ /.*[^\/]$/);
-
-print "$0: $progname version $version\n"
- if ($opt_version || $opt_help);
-print "\t(c) 2000 Thomas Lockhart PostgreSQL Inc.\n"
- if ($opt_version && $opt_verbose || $opt_help);
-
-if ($opt_help) {
- print "$0 --verbose --version --help --path=dir --nodata infile ...\n";
- exit;
-}
-
-while (@ARGV) {
- my $ostem;
- my $oname;
- my $pname;
- my @xargs;
-
- $iname = shift @ARGV;
- $ostem = $iname;
- $ostem = $1 if ($ostem =~ /.+\/([^\/]+)$/);
- $ostem = $1 if ($ostem =~ /(.+)[.][^.]*$/);
-
- $oname = "$ostem.sql92";
- $pname = "$ostem.init";
-
- @xargs = ($iname, $oname);
- push @xargs, $pname unless ($nodata);
-
- print "@xargs\n" if ($debug);
-
- TransformDumpFile($iname, $oname, $pname);
-}
-
-exit;
-
-sub TransformDumpFile {
- local ($iname, $oname, $pname) = @_;
- local @dlines;
- local @slines;
- local @plines;
- local @tables; # list of tables created
- local %pkeys;
- local %pseqs;
- local %sequences;
-
- open(IN, "<$iname") || die "Unable to open file $iname";
-
- while (<IN>) {
- chomp;
- push @dlines, $_;
- }
-
- print("Calling CreateSchema with $#dlines lines\n") if ($debug);
- @slines = CreateSchema(@dlines);
-
- open(OUT, ">$oname") || die "Unable to open output file $oname";
-
- foreach (@slines) {
- print "> $_" if ($debug);
- print OUT "$_";
- }
- close(OUT);
-
- return if (! defined($pname));
-
- @plines = PopulateSchema(@tables);
-
- open(OUT, ">$pname") || die "Unable to open output file $pname";
-
- foreach (@plines) {
- print "> $_" if ($debug);
- print OUT "$_";
- }
- close(OUT);
-}
-
-sub PopulateSchema {
- local @tables = @_;
- local @out;
- local $pkey;
- local $pseq;
-
- foreach (@tables) {
- $table = $_;
- $tpath = "$pathfrom$table";
-
- print "Table is $table\n" if ($debug);
- push @out, "\n";
- push @out, "copy $table from '$tpath.txt';\n";
- if (defined($pkeys{$table})) {
- foreach ($pkeys{$table}) {
- $pkey = $_;
- $pseq = $pseqs{$table};
-
- print "Key for $table is $pkey on $pseq\n" if ($debug);
-
-# //push @out, "\$value = select max($pkey) from $table;\n";
- push @out, "select setval ('$pseq', (select max($pkey) from $table));\n";
- }
- }
- }
-
- return @out;
-}
-
-sub CreateSchema {
- local @lines = @_;
- local @out;
-
-# undef $last;
- local %knames;
-
- push @out, "--\n";
- push @out, "-- Generated from mysql2pgsql\n";
- push @out, "-- (c) 2000, Thomas Lockhart, PostgreSQL Inc.\n";
- push @out, "--\n";
- push @out, "\n";
-
- while (@lines) {
- $_ = shift @lines;
- print "< $_\n" if ($debug);
- # Replace hash comments with SQL9x standard syntax
- $_ = "-- $1" if (/^[\#](.*)/);
-
- # Found a CREATE TABLE statement?
- if (/(create\s+table)\s+(\w+)\s+([(])\s*$/i) {
- $table = $2;
- $table = "\"$1\"" if ($table =~ /^(user)$/);
- push @tables, $table;
- push @tabledef, "create table $table (";
-# push @out, "$_\n";
-
- while (@lines) {
- $_ = shift @lines;
- print "< $_\n" if ($debug);
-
- # Replace int(11) with SQL9x standard syntax
- while (/int\(\d*\)/gi) {
- $_ = "$`integer$'";
- }
-
- # Replace float(10,2) with SQL9x standard syntax
- while (/(float)\((\d+),\s*(\d+)\)/gi) {
- $_ = "$`$1($2)$'";
- }
-
- # Replace smallinteger with SQL9x syntax
- while (/smallinteger/gi) {
- $_ = "$`integer$'";
- }
-
- # Replace mediumtext with PostgreSQL syntax
- while (/(longtext|mediumtext|blob|largeblob)/gi) {
- $_ = "$`text$'";
- }
-
- # Replace integer ... auto_increment with PostgreSQL syntax
- while (/(\s*)(\w+)\s+integer\s+(.*)\s+auto_increment/gi) {
- $serid = $table . "_pk_seq";
- push @out, "-- serial identifier $serid will likely be truncated\n"
- if (length($serid) >= 32);
-
- if (length($serid) >= 32) {
- $excess=(length($serid)-31);
- $serid = substr($table,0,-($excess)) . "_pk_seq";
- push @out, "-- serial identifier $serid was truncated\n";
- }
- push @out, "CREATE SEQUENCE $serid;\n\n";
- $pkeys{$table} = $2;
- $pseqs{$table} = $serid;
- push @out, "-- key is $pkeys{$table}, sequence is $pseqs{$table}\n" if ($debug);
- $_ = "$`$1$2 integer default nextval('$serid') $3$'";
- }
-
- # Replace date with double-quoted name
-# while (/^(\s*)(date|time)(\s+)/gi) {
-# $_ = "$1\"$2\"$3$'";
-# }
-
- # Found "KEY"? Then remove it from the CREATE TABLE statement
- # and instead write a CREATE INDEX statement.
- if (/^\s*key\s+(\w+)\s*[(](\w[()\w\d,\s]*)[)][,]?/i) {
- $iname = $1;
- $column = $2;
- $iname = $1 if ($iname =~ /^idx_(\w[\_\w\d]+)/);
- # Sheesh, there can be upper bounds on index string sizes?
- # Get rid of the length specifier (e.g. filename(45) -> filename)
- while ($column =~ /(\w[\w\d])[(]\d+[)]/g) {
- $column = "$`$1$'";
- }
-# $column = $1 if ($column =~ /(\w+)[(]\d+[)]/);
-# push @out, "Index on $table($column) is $iname\n";
- if (defined($knames{$iname})) {
- push @out, "-- $iname already exists";
-# sprintf($iname, "idx_%_%s", $table, $iname);
-# $iname = "idx_" . $table . "_" . $column;
- # Do not bother with more to the name; it will be too big anyway
- $iname = $table . "_" . $column;
- push @out, "; use $iname instead\n";
- }
- $knames{$iname} = $iname;
- $keydef{$column} = $iname;
-# push @out, "! $_\n";
-# $last = $tabledef[$#tabledef];
-# push @out, "? $#tabledef $last\n";
-# push @out, "match $1\n" if ($last =~ /(.*),\s*$/);
- # Remove the trailing comma from the previous line, if necessary
- $tabledef[$#tabledef] = $1
- if (($#tabledef > 0) && ($tabledef[$#tabledef] =~ /(.*),\s*$/));
-# push @out, "? $tabledef[$#tabledef]\n";
-
- # If this is the end of the statement, save it and exit loop
- } elsif (/^\s*[)]\;/) {
- push @tabledef, $_;
-# push @out, "< $_\n";
- last;
-
- # Otherwise, just save the line
- } else {
-# push @out, "$last\n" if (defined($last));
-# $last = $_;
- push @tabledef, $_;
-# push @out, "$_\n";
- }
- }
-
- foreach $t (@tabledef) {
- push @out, "$t\n";
- }
- undef @tabledef;
-
- foreach $k (keys %keydef) {
- push @out, "create index $keydef{$k} on $table ($k);\n";
- }
- undef %keydef;
-
- } else {
- push @out, "$_\n";
- }
- }
-
-# push @out, "$last\n" if (defined($last));
-
- foreach (keys %pkeys) {
- my $val = $pkeys{$_};
- print "key is $val\n" if ($debug);
- }
-
- return @out;
-}
-
-sub StripComma {
- local $line = shift @_;
-
- $line = "$1" if ($line =~ /(.*)[,]\s*$/);
-
- return $line;
-}
+++ /dev/null
-# $PostgreSQL: pgsql/contrib/noupdate/Makefile,v 1.11 2004/08/20 20:13:05 momjian Exp $
-
-MODULES = noup
-DATA_built = noup.sql
-DOCS = README.noup
-
-ifdef USE_PGXS
-PGXS = $(shell pg_config --pgxs)
-include $(PGXS)
-else
-subdir = contrib/noupdate
-top_builddir = ../..
-include $(top_builddir)/src/Makefile.global
-include $(top_srcdir)/contrib/contrib-global.mk
-endif
+++ /dev/null
-
-
-noupdate
-~~~~~~~~
-
- - trigger to prevent updates on single columns.
-
-
-Example:
-~~~~~~~
-
-CREATE TABLE TEST ( COL1 INT, COL2 INT, COL3 INT );
-
-CREATE TRIGGER BT BEFORE UPDATE ON TEST FOR EACH ROW
- EXECUTE PROCEDURE
- noup ('COL1');
-
--- Now Try
-INSERT INTO TEST VALUES (10,20,30);
-UPDATE TEST SET COL1 = 5;
+++ /dev/null
-/*
- * noup.c -- functions to remove update permission from a column
- */
-
-#include "executor/spi.h" /* this is what you need to work with SPI */
-#include "commands/trigger.h" /* -"- and triggers */
-#include <ctype.h> /* tolower () */
-
-extern Datum noup(PG_FUNCTION_ARGS);
-
-/*
- * noup () -- revoke permission on column
- *
- * Though it's called without args You have to specify referenced
- * table/column while creating trigger:
- * EXECUTE PROCEDURE noup ('col').
- */
-
-PG_FUNCTION_INFO_V1(noup);
-
-Datum
-noup(PG_FUNCTION_ARGS)
-{
- TriggerData *trigdata = (TriggerData *) fcinfo->context;
- Trigger *trigger; /* to get trigger name */
- int nargs; /* # of args specified in CREATE TRIGGER */
- char **args; /* arguments: column names and table name */
- int nkeys; /* # of key columns (= nargs / 2) */
- Datum *kvals; /* key values */
- Relation rel; /* triggered relation */
- HeapTuple tuple = NULL; /* tuple to return */
- TupleDesc tupdesc; /* tuple description */
- bool isnull; /* to know is some column NULL or not */
- int ret;
- int i;
-
- /*
- * Some checks first...
- */
-
- /* Called by trigger manager ? */
- if (!CALLED_AS_TRIGGER(fcinfo))
- /* internal error */
- elog(ERROR, "noup: not fired by trigger manager");
-
- /* Should be called for ROW trigger */
- if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
- /* internal error */
- elog(ERROR, "noup: can't process STATEMENT events");
-
- /* Should not be called for INSERT */
- if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
- /* internal error */
- elog(ERROR, "noup: can't process INSERT events");
-
- /* Should not be called for DELETE */
- else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
- /* internal error */
- elog(ERROR, "noup: can't process DELETE events");
-
- /* check new Tuple */
- tuple = trigdata->tg_newtuple;
-
- trigger = trigdata->tg_trigger;
- nargs = trigger->tgnargs;
- args = trigger->tgargs;
-
- nkeys = nargs;
- rel = trigdata->tg_relation;
- tupdesc = rel->rd_att;
-
- /* Connect to SPI manager */
- if ((ret = SPI_connect()) < 0)
- /* internal error */
- elog(ERROR, "noup: SPI_connect returned %d", ret);
-
- /*
- * We use SPI plan preparation feature, so allocate space to place key
- * values.
- */
- kvals = (Datum *) palloc(nkeys * sizeof(Datum));
-
- /* For each column in key ... */
- for (i = 0; i < nkeys; i++)
- {
- /* get index of column in tuple */
- int fnumber = SPI_fnumber(tupdesc, args[i]);
-
- /* Bad guys may give us un-existing column in CREATE TRIGGER */
- if (fnumber < 0)
- /* internal error */
- elog(ERROR, "noup: there is no attribute %s in relation %s",
- args[i], SPI_getrelname(rel));
-
- /* Well, get binary (in internal format) value of column */
- kvals[i] = SPI_getbinval(tuple, tupdesc, fnumber, &isnull);
-
- /*
- * If it's NOT NULL then cancel update
- */
- if (!isnull)
- {
- elog(WARNING, "%s: update not allowed", args[i]);
- SPI_finish();
- return PointerGetDatum(NULL);
- }
-
- }
-
- SPI_finish();
- return PointerGetDatum(tuple);
-}
+++ /dev/null
--- Adjust this setting to control where the objects get created.
-SET search_path = public;
-
-CREATE OR REPLACE FUNCTION noup ()
-RETURNS trigger
-AS 'MODULE_PATHNAME'
-LANGUAGE 'C';
+++ /dev/null
-# $PostgreSQL: pgsql/contrib/pg_dumplo/Makefile,v 1.14 2005/03/25 18:17:11 momjian Exp $
-
-PROGRAM = pg_dumplo
-OBJS = main.o lo_export.o lo_import.o utils.o
-
-PG_CPPFLAGS = -I$(libpq_srcdir)
-PG_LIBS = $(libpq_pgport)
-
-DOCS = README.pg_dumplo
-
-ifdef USE_PGXS
-PGXS = $(shell pg_config --pgxs)
-include $(PGXS)
-else
-subdir = contrib/pg_dumplo
-top_builddir = ../..
-include $(top_builddir)/src/Makefile.global
-include $(top_srcdir)/contrib/contrib-global.mk
-endif
+++ /dev/null
-$PostgreSQL: pgsql/contrib/pg_dumplo/README.pg_dumplo,v 1.3 2003/11/29 19:51:35 pgsql Exp $
-
-pg_dumplo - PostgreSQL large object dumper
-==========================================
-
-By Karel Zak <zakkr@zf.jcu.cz>
-
-
-Compilation:
-===========
-
- * run master ./configure in the PG source top directory
- * gmake all
- * gmake install
-
-THANKS:
-======
-
- <??? I lost his e-mail ???>
- * option '--all' and pg_class usage
-
- Pavel JanÃk ml. <Pavel.Janik@linux.cz>
- * HOWTO (the rest of this file)
-
-
-How to use pg_dumplo?
-=====================
-
-(c) 2000, Pavel JanÃk ml. <Pavel.Janik@linux.cz>
-
-
-Q: How do you use pg_dumplo?
-============================
-
-A: This is a small demo of backing up the database table with Large Objects:
-
-
-We will create a demo database and a small and useless table `lo' inside
-it:
-
-SnowWhite:$ createdb test
-CREATE DATABASE
-
-Ok, our database with the name 'test' is created. Now we should create demo
-table which will contain only one column with the name 'id' which will hold
-the OID number of a Large Object:
-
-SnowWhite:$ psql test
-Welcome to psql, the PostgreSQL interactive terminal.
-
-Type: \copyright for distribution terms
- \h for help with SQL commands
- \? for help on internal slash commands
- \g or terminate with semicolon to execute query
- \q to quit
-
-test=# CREATE TABLE lo (id oid);
-CREATE
-test=# \lo_import /etc/aliases
-lo_import 19338
-test=# INSERT INTO lo VALUES (19338);
-INSERT 19352 1
-test=# select * from lo;
- id
--------
- 19338
-(1 row)
-
-test=# \q
-
-In the above example you can see that we have also imported one "Large
-Object" - the file /etc/aliases. It has an oid of 19338 so we have inserted
-this oid number to the database table lo to the column id. The final SELECT
-shows that we have one record in the table.
-
-Now we can demonstrate the work of pg_dumplo. We will create a dump directory
-which will contain the whole dump of large objects (/tmp/dump):
-
-mkdir -p /tmp/dump
-
-Now we can dump all large objects from the database `test' which have OIDs
-stored in the column `id' in the table `lo':
-
-SnowWhite:$ pg_dumplo -s /tmp/dump -d test -l lo.id
-pg_dumplo: dump lo.id (1 large obj)
-
-Voila, we have the dump of all Large Objects in our directory:
-
-SnowWhite:$ tree /tmp/dump/
-/tmp/dump/
-`-- test
- |-- lo
- | `-- id
- | `-- 19338
- `-- lo_dump.index
-
-3 directories, 2 files
-SnowWhite:$
-
-In practice, we'd probably use
-
-SnowWhite:$ pg_dumplo -s /tmp/dump -d test -e
-
-to export all large objects that are referenced by any OID-type column
-in the database. Calling out specific column(s) with -l is only needed
-for a selective dump.
-
-For routine backup purposes, the dump directory could now be converted into
-an archive file with tar and stored on tape. Notice that a single dump
-directory can hold the dump of multiple databases.
-
-Now, how can we recreate the contents of the table lo and the Large Object
-database when something went wrong? To do this, we expect that pg_dump is
-also used to store the definition and contents of the regular tables in
-the database.
-
-SnowWhite:$ pg_dump test >test.backup
-
-Now, if we lose the database:
-
-SnowWhite:$ dropdb test
-DROP DATABASE
-
-we can recreate it and reload the regular tables from the dump file:
-
-SnowWhite:$ createdb test
-CREATE DATABASE
-
-SnowWhite:$ psql test <test.backup
-
-But at this point our database has no large objects in it. What's more,
-the large-object-referencing columns contain the OIDs of the old large
-objects, which will not be the OIDs they'll have when reloaded. Never
-fear: pg_dumplo will fix the large object references at the same time
-it reloads the large objects. We reload the LO data from the dump
-directory like this:
-
-SnowWhite:$ pg_dumplo -s /tmp/dump -d test -i
-19338 lo id test/lo/id/19338
-SnowWhite:$
-
-And this is everything. The contents of table lo will be automatically
-updated to refer to the new large object OIDs.
-
-Summary: In this small example we have shown that pg_dumplo can be used to
-completely dump the database's Large Objects very easily.
-
-For more information see the help ( pg_dumplo -h ).
+++ /dev/null
-/* -------------------------------------------------------------------------
- * pg_dumplo
- *
- * $PostgreSQL: pgsql/contrib/pg_dumplo/lo_export.c,v 1.13 2004/11/28 23:49:49 tgl Exp $
- *
- * Karel Zak 1999-2004
- * -------------------------------------------------------------------------
- */
-
-#include "postgres_fe.h"
-
-#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-#include "libpq-fe.h"
-#include "libpq/libpq-fs.h"
-
-#include "pg_dumplo.h"
-
-extern int errno;
-
-
-void
-load_lolist(LODumpMaster * pgLO)
-{
- LOlist *ll;
- int i;
- int n;
-
- /*
- * Now find any candidate tables who have columns of type oid.
- *
- * NOTE: System tables including pg_largeobject will be ignored.
- * Otherwise we'd end up dumping all LOs, referenced or not.
- *
- * NOTE: the system oid column is ignored, as it has attnum < 1. This
- * shouldn't matter for correctness, but it saves time.
- */
- pgLO->res = PQexec(pgLO->conn, "SELECT c.relname, a.attname, n.nspname "
- "FROM pg_catalog.pg_class c, pg_catalog.pg_attribute a, "
- " pg_catalog.pg_type t, pg_catalog.pg_namespace n "
- "WHERE a.attnum > 0 "
- " AND a.attrelid = c.oid "
- " AND a.atttypid = t.oid "
- " AND t.typname = 'oid' "
- " AND c.relkind = 'r' "
- " AND c.relname NOT LIKE 'pg_%' "
- " AND n.oid = c.relnamespace");
-
- if (PQresultStatus(pgLO->res) != PGRES_TUPLES_OK)
- {
- fprintf(stderr, "%s: Failed to get LO OIDs:\n%s", progname,
- PQerrorMessage(pgLO->conn));
- exit(RE_ERROR);
- }
-
- if ((n = PQntuples(pgLO->res)) == 0)
- {
- fprintf(stderr, "%s: No OID columns in the database.\n", progname);
- exit(RE_ERROR);
- }
-
- pgLO->lolist = (LOlist *) malloc((n + 1) * sizeof(LOlist));
- memset(pgLO->lolist, 0, (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));
- ll->lo_schema = strdup(PQgetvalue(pgLO->res, i, 2));
- }
-
- PQclear(pgLO->res);
-}
-
-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\tschema\n#\n");
- }
-
- pgLO->counter = 0;
-
- for (ll = pgLO->lolist; ll->lo_table != NULL; ll++)
- {
- /*
- * Query: find the LOs referenced by this column
- */
- snprintf(Qbuff, QUERY_BUFSIZ,
- "SELECT DISTINCT l.loid FROM \"%s\".\"%s\" x, pg_catalog.pg_largeobject l "
- "WHERE x.\"%s\" = l.loid",
- ll->lo_schema, ll->lo_table, ll->lo_attr);
-
- /* puts(Qbuff); */
-
- pgLO->res = PQexec(pgLO->conn, Qbuff);
-
- if (PQresultStatus(pgLO->res) != PGRES_TUPLES_OK)
- {
- fprintf(stderr, "%s: Failed to get LO OIDs:\n%s", progname,
- PQerrorMessage(pgLO->conn));
- }
- else if ((tuples = PQntuples(pgLO->res)) == 0)
- {
- if (!pgLO->quiet && pgLO->action == ACTION_EXPORT_ATTR)
- printf("%s: no large objects in \"%s\".\"%s\".\"%s\"\n",
- progname, ll->lo_schema, ll->lo_table, ll->lo_attr);
- }
- else
- {
-
- int t;
- char *val;
-
- /*
- * Create DIR/FILE
- */
- if (pgLO->action != ACTION_SHOW)
- {
-
- snprintf(path, BUFSIZ, "%s/%s/%s", pgLO->space, pgLO->db,
- ll->lo_schema);
-
- if (mkdir(path, DIR_UMASK) == -1)
- {
- if (errno != EEXIST)
- {
- perror(path);
- exit(RE_ERROR);
- }
- }
-
- snprintf(path, BUFSIZ, "%s/%s/%s/%s", pgLO->space, pgLO->db,
- ll->lo_schema, ll->lo_table);
-
- if (mkdir(path, DIR_UMASK) == -1)
- {
- if (errno != EEXIST)
- {
- perror(path);
- exit(RE_ERROR);
- }
- }
-
- snprintf(path, BUFSIZ, "%s/%s/%s/%s/%s", pgLO->space, pgLO->db,
- ll->lo_schema, ll->lo_table, ll->lo_attr);
-
- if (mkdir(path, DIR_UMASK) == -1)
- {
- if (errno != EEXIST)
- {
- perror(path);
- exit(RE_ERROR);
- }
- }
-
- if (!pgLO->quiet)
- printf("dump %s.%s.%s (%d large obj)\n",
- ll->lo_schema, ll->lo_table, ll->lo_attr, tuples);
- }
-
- pgLO->counter += tuples;
-
- for (t = 0; t < tuples; t++)
- {
- Oid lo;
-
- val = PQgetvalue(pgLO->res, t, 0);
-
- lo = atooid(val);
-
- if (pgLO->action == ACTION_SHOW)
- {
- printf("%s.%s.%s: %u\n", ll->lo_schema, ll->lo_table, ll->lo_attr, lo);
- continue;
- }
-
- snprintf(path, BUFSIZ, "%s/%s/%s/%s/%s/%s", pgLO->space,
- pgLO->db, ll->lo_schema, ll->lo_table, ll->lo_attr, val);
-
- if (lo_export(pgLO->conn, lo, path) < 0)
- fprintf(stderr, "%s: lo_export failed:\n%s", progname,
- PQerrorMessage(pgLO->conn));
-
- else
- fprintf(pgLO->index, "%s\t%s\t%s\t%s/%s/%s/%s/%s\t%s\n",
- val, ll->lo_table, ll->lo_attr, pgLO->db,
- ll->lo_schema, ll->lo_table, ll->lo_attr,
- val, ll->lo_schema);
- }
- }
-
- PQclear(pgLO->res);
- }
-}
+++ /dev/null
-/* -------------------------------------------------------------------------
- * pg_dumplo
- *
- * $PostgreSQL: pgsql/contrib/pg_dumplo/lo_import.c,v 1.11 2004/11/28 23:49:49 tgl Exp $
- *
- * Karel Zak 1999-2004
- * -------------------------------------------------------------------------
- */
-
-#include "postgres_fe.h"
-
-#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/stat.h>
-
-#include "libpq-fe.h"
-#include "libpq/libpq-fs.h"
-
-#include "pg_dumplo.h"
-
-extern int errno;
-
-void
-pglo_import(LODumpMaster * pgLO)
-{
- LOlist loa;
- Oid new_oid;
- int ret, line=0;
- char tab[MAX_TABLE_NAME],
- attr[MAX_ATTR_NAME],
- sch[MAX_SCHEMA_NAME],
- path[BUFSIZ],
- lo_path[BUFSIZ],
- Qbuff[QUERY_BUFSIZ];
-
- while (fgets(Qbuff, QUERY_BUFSIZ, pgLO->index))
- {
- line++;
-
- if (*Qbuff == '#')
- continue;
-
- if (!pgLO->remove && !pgLO->quiet)
- printf(Qbuff);
-
- if ((ret=sscanf(Qbuff, "%u\t%s\t%s\t%s\t%s\n", &loa.lo_oid, tab, attr, path, sch)) < 5)
- {
- /* backward compatible mode */
- ret = sscanf(Qbuff, "%u\t%s\t%s\t%s\n", &loa.lo_oid, tab, attr, path);
- strcpy(sch, "public");
- }
- if (ret < 4)
- {
- fprintf(stderr, "%s: index file reading failed at line %d\n", progname, line);
- PQexec(pgLO->conn, "ROLLBACK");
- fprintf(stderr, "\n%s: ROLLBACK\n", progname);
- exit(RE_ERROR);
- }
-
- loa.lo_schema = sch;
- loa.lo_table = tab;
- loa.lo_attr = attr;
-
- if (path && *path=='/')
- /* absolute path */
- snprintf(lo_path, BUFSIZ, "%s", path);
- else
- snprintf(lo_path, BUFSIZ, "%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, loa.lo_oid) < 0)
- fprintf(stderr, "%s: can't remove LO %u:\n%s",
- progname, loa.lo_oid, PQerrorMessage(pgLO->conn));
-
- else if (!pgLO->quiet)
- printf("remove old %u and create new %u\n",
- loa.lo_oid, new_oid);
- notice(pgLO, TRUE);
- }
-
- pgLO->counter++;
-
- /*
- * UPDATE oid in tab
- */
- snprintf(Qbuff, QUERY_BUFSIZ,
- "UPDATE \"%s\".\"%s\" SET \"%s\"=%u WHERE \"%s\"=%u",
- loa.lo_schema, loa.lo_table, loa.lo_attr, new_oid, loa.lo_attr, loa.lo_oid);
-
- /*fprintf(stderr, Qbuff);*/
-
- pgLO->res = PQexec(pgLO->conn, Qbuff);
-
- if (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);
- }
- PQclear(pgLO->res);
- }
-}
+++ /dev/null
-/* -------------------------------------------------------------------------
- * pg_dumplo
- *
- * $PostgreSQL: pgsql/contrib/pg_dumplo/main.c,v 1.22 2004/11/28 23:49:49 tgl Exp $
- *
- * Karel Zak 1999-2000
- * -------------------------------------------------------------------------
- */
-
-#include "postgres_fe.h"
-
-#include <errno.h>
-#include <unistd.h>
-
-#include "libpq-fe.h"
-#include "libpq/libpq-fs.h"
-
-#include "pg_dumplo.h"
-
-#ifndef HAVE_STRDUP
-#include "strdup.h"
-#endif
-
-#include "getopt_long.h"
-
-#ifndef HAVE_INT_OPTRESET
-int optreset;
-#endif
-
-char *progname = NULL;
-
-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->port = 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;
- 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'},
- {"port", required_argument, 0, 'o'},
- {"space", required_argument, 0, 's'},
- {"import", no_argument, 0, 'i'},
- {"export", no_argument, 0, 'e'},
- {"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, "?aeho:u:p:qd:l:t:irs:w", l_opt, &l_index)) != -1)
- {
- switch (arg)
- {
- case '?':
- case 'h':
- usage();
- exit(RE_OK);
- case 'u':
- pgLO->user = strdup(optarg);
- break;
- case 't':
- pgLO->host = strdup(optarg);
- break;
- case 'o':
- pgLO->port = 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 -%c\n", progname, arg);
- usage();
- exit(RE_ERROR);
- }
- }
- }
- else
- {
- usage();
- exit(RE_ERROR);
- }
-
- /*
- * Check space
- */
- if (pgLO->space==NULL && pgLO->action != ACTION_SHOW)
- {
- if (!(pgLO->space = getenv("PWD")))
- pgLO->space = ".";
- }
-
- if (!pgLO->action)
- {
- fprintf(stderr, "%s: What do you want - export or import?\n", progname);
- exit(RE_ERROR);
- }
-
- /*
- * Make connection
- */
- pgLO->conn = PQsetdbLogin(pgLO->host, pgLO->port, 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 != ACTION_SHOW)
- index_file(pgLO);
-
- PQexec(pgLO->conn, "SET search_path = public");
-
- PQexec(pgLO->conn, "BEGIN");
-
- switch (pgLO->action)
- {
-
- case ACTION_SHOW:
- case ACTION_EXPORT_ALL:
- load_lolist(pgLO);
- /* FALL THROUGH */
-
- case ACTION_EXPORT_ATTR:
- pglo_export(pgLO);
- if (!pgLO->quiet)
- {
- if (pgLO->action == ACTION_SHOW)
- printf("\nDatabase '%s' contains %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, *loc2,
- buff[MAX_SCHEMA_NAME + MAX_TABLE_NAME + MAX_ATTR_NAME + 3];
-
- 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_SCHEMA_NAME + MAX_TABLE_NAME + MAX_ATTR_NAME + 2);
-
- if ((loc = strchr(buff, '.')) == NULL || *(loc+1)=='\0')
- {
- fprintf(stderr, "%s: '%s' is bad 'table.attr' or 'schema.table.attr'\n", progname, buff);
- exit(RE_ERROR);
- }
- loc2 = strchr(loc+1, '.');
- *loc = '\0';
-
- if (loc2)
- {
- /* "schema.table.attr"
- */
- *loc2 = '\0';
- ll->lo_schema = strdup(buff);
- ll->lo_table = strdup(loc+1);
- ll->lo_attr = strdup(loc2+1);
- }
- else
- {
- ll->lo_schema = strdup("public");
- ll->lo_table = strdup(buff);
- ll->lo_attr = strdup(loc+1);
- }
- }
- ll++;
- ll->lo_table = ll->lo_attr = (char *) NULL;
-}
-
-
-static void
-usage(void)
-{
- printf("\npg_dumplo %s - PostgreSQL large objects dump\n", PG_VERSION);
- puts("pg_dumplo [option]\n\n"
- "-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"
- "-o --port=<port> database server port (default: 5432)\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 <schema.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"
- "\n"
- "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"
- " * default schema is \"public\"\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 option -s is not set, pg_dumplo uses $PWD or \".\"\n"
- ); /* puts() */
-}
+++ /dev/null
-/* -------------------------------------------------------------------------
- * pg_dumplo.h
- *
- * $PostgreSQL: pgsql/contrib/pg_dumplo/pg_dumplo.h,v 1.11 2004/11/28 23:49:49 tgl Exp $
- *
- * Karel Zak 1999-2004
- * -------------------------------------------------------------------------
- */
-
-#ifndef PG_DUMPLO_H
-#define PG_DUMPLO_H
-
-#include "postgres_ext.h"
-
-/* ----------
- * Define
- * ----------
- */
-#define QUERY_BUFSIZ (8*1024)
-#define DIR_UMASK 0755
-#define FILE_UMASK 0644
-
-#define TRUE 1
-#define FALSE 0
-#define RE_OK 0
-#define RE_ERROR 1
-
-#define MAX_SCHEMA_NAME 128
-#define MAX_TABLE_NAME 128
-#define MAX_ATTR_NAME 128
-
-#define atooid(x) ((Oid) strtoul((x), NULL, 10))
-
-/* ----------
- * LO struct
- * ----------
- */
-typedef struct
-{
- char *lo_schema,
- *lo_table,
- *lo_attr;
- Oid lo_oid;
-} LOlist;
-
-typedef struct
-{
- int action;
- LOlist *lolist;
- char **argv,
- *user,
- *db,
- *host,
- *port,
- *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 char *progname;
-
-extern void notice(LODumpMaster * pgLO, int set);
-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_DUMPLO_H */
+++ /dev/null
-/* -------------------------------------------------------------------------
- * pg_dumplo
- *
- * $PostgreSQL: pgsql/contrib/pg_dumplo/utils.c,v 1.9 2004/08/29 05:06:36 momjian Exp $
- *
- * Karel Zak 1999-2000
- * -------------------------------------------------------------------------
- */
-
-#include "postgres_fe.h"
-
-#include <fcntl.h>
-#include <errno.h>
-#include <time.h>
-#include <unistd.h>
-#include <sys/stat.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];
- int sz;
-
- if (pgLO->action == ACTION_SHOW)
- return;
-
- snprintf(path, BUFSIZ, "%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);
- }
- }
-
- sz = strlen(path);
- strncat(path, "/lo_dump.index", BUFSIZ - sz);
-
- if ((pgLO->index = fopen(path, "w")) == NULL)
- {
- perror(path);
- exit(RE_ERROR);
- }
-
- }
- else if (pgLO->action != ACTION_NONE)
- {
- sz = strlen(path);
- strncat(path, "/lo_dump.index", BUFSIZ - sz);
-
- if ((pgLO->index = fopen(path, "r")) == NULL)
- {
- perror(path);
- exit(RE_ERROR);
- }
- }
-}
-
-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);
-}
+++ /dev/null
- pg_upgrade
-
-
-PG_UPGRADE IS NOT AVAILABLE FOR UPGRADES FROM 7.2.X.
-
-This is a version of pg_upgrade which will allow a 7.3 to 7.3 migration
-if you need to perform an initdb. It has been only lightly tested.
-Please report any problems to the PostgreSQL lists.
-
-Read the manual page for more information. To view it:
-
- nroff -man pg_upgrade.1 | more
-
-Bruce Momjian
-
-2002-07-03
+++ /dev/null
-#!/bin/sh
-#
-# pg_upgrade: update a database without needing a full dump/reload cycle.
-# CAUTION: Read the manual page before trying to use this!
-
-# $PostgreSQL: pgsql/contrib/pg_upgrade/pg_upgrade,v 1.16 2003/11/29 19:51:35 pgsql Exp $
-#
-# To migrate this to newer versions of PostgreSQL:
-# 1) Update the version numbers at the top of the file
-# 2) Search for specific version mentions in the script and update
-# accordingly.
-# 3) Add changes for next version.
-
-#set -x
-
-# UPGRADE_VERSION is the expected old database version
-UPGRADE_VERSION="7.3"
-CUR_VERSION="7.3"
-
-# Set this to "Y" to enable this program
-ENABLE="Y"
-
-if [ "$ENABLE" != "Y" ]
-then
- echo "Sorry, $0 cannot upgrade database version $SRC_VERSION to $DST_VERSION." 1>&2
- echo "The on-disk structure of tables has changed." 1>&2
- echo "You will need to dump and restore using pg_dumpall." 1>&2
- exit 1
-fi
-
-
-trap "rm -f /tmp/$$.*" 0 1 2 3 15
-
-BASENAME=`basename "$0"`
-PHASE=""
-
-while [ "$#" -ne 0 ]
-do
- if [ "X$1" = "X-1" ]
- then PHASE="1"
- shift
- elif [ "X$1" = "X-2" ]
- then PHASE="2"
- shift
- elif [ "X$1" = "X-D" ]
- then PGDATA="$2"
- shift 2
- fi
-done
-
-if [ "$PHASE" = "" ]
-then echo "You must run $BASENAME in either mode 1 or mode 2." 1>&2
- echo "Usage: $BASENAME [-D datadir] -1 | -2" 1>&2
- exit 1
-fi
-
-if [ "$PGDATA" = "" ]
-then echo "You must set the PGDATA environment variable or specify it with -D." 1>&2
- echo "Usage: $BASENAME [-D datadir] -1 | -2" 1>&2
- exit 1
-fi
-
-if [ ! -d "$PGDATA" ]
-then echo "$PGDATA does not exist. Exiting." 1>&2
- if [ "$PHASE" -eq 2 ]
- then echo "Perhaps you didn't run initdb." 1>&2
- fi
- exit 1
-fi
-
-if [ "$USER" = "root" -o ! -r "$PGDATA"/PG_VERSION ]
-then echo "You must run this as the PostgreSQL superuser. Exiting." 1>&2
- exit 1
-fi
-
-# Strip off the trailing directory name and store our data there
-# in the hope we are in the same filesystem so 'mv 'works.
-
-INFODIR=`dirname "$PGDATA"`/pg_upgrade_info
-SAVEDATA="$INFODIR"/data
-
-make_dbobjoidmap()
-{
- psql -d template1 -At -c "SELECT datname FROM pg_database" |
- grep -v '^template0$' |
- while read DB
- do
- QUERY="SELECT relname, oid
- FROM pg_class
- WHERE relkind = 'r' OR
- relkind = 'i' OR
- relkind = 'S' OR
- relkind = 't';"
-
- psql -d "$DB" -At -F' ' -c "$QUERY" |
- while read RELNAME_OID
- do
- echo "$DB $RELNAME_OID"
- done
- done
-}
-
-
-make_dboidmap()
-{
- psql -d template1 -At -F' ' -c \
- 'SELECT datname, oid FROM pg_database;' |
- grep -v '^template0$'
-}
-
-
-move_objfiles()
-{
- # Test to make sure there is a matching file in each place
-
- if [ ! -f "$SAVEDATA"/base/"$SRC_DBOID"/"$SRC_OID" -a \
- ! -h "$SAVEDATA"/base/"$SRC_DBOID"/"$SRC_OID" ]
- then echo "Moving of database $DB, OID $SRC_OID, object $OBJ failed." 1>&2
- echo "File not found. Exiting." 1>&2
- return 1
- fi
-
- if [ ! -f "$PGDATA"/base/"$DST_DBOID"/"$DST_OID" -a \
- ! -h "$PGDATA"/base/"$DST_DBOID"/"$DST_OID" ]
- then echo "Moving of database $DB, OID $DST_OID, object $OBJ failed." 1>&2
- echo "File not found. Exiting." 1>&2
- return 1
- fi
-
- # Move files
-
- mv -f "$SAVEDATA"/base/"$SRC_DBOID"/"$SRC_OID" "$PGDATA"/base/"$DST_DBOID"/"$DST_OID"
- if [ "$?" -ne 0 ]
- then echo "Moving of database $DB, OID $SRC_OID, object $OBJ" 1>&2
- echo "to $DST_OID failed. Exiting" 1>&2
- return 1
- fi
-
- # handle table extents
-
- ls "$SAVEDATA"/base/"$SRC_DBOID"/"$SRC_OID".* 2> /dev/null | while read FILE
- do
- EXT=`basename "$FILE" | sed 's/^.*\.\(.*\)$/\1/'`
- mv -f "$FILE" "$PGDATA"/base/"$DST_DBOID"/"$DST_OID"."$EXT"
- if [ "$?" -ne 0 ]
- then echo "Moving of database $DB, OID $SRC_OID, object $OBJ" 1>&2
- echo "to $DST_OID failed. Exiting." 1>&2
- return 1
- fi
- done
-}
-
-if [ "$PHASE" -eq 1 ]
-then
-
- ##########################
- # Phase 1 starts here #
- ##########################
-
-
- if [ ! -d "$PGDATA"/base/1 ]
- then echo "There is no database template1 in $PGDATA/base." 1>&2
- exit 1
- fi
-
- # get version
- SRC_VERSION=`cat "$PGDATA"/PG_VERSION`
- if [ "$SRC_VERSION" = "" ]
- then echo "$BASENAME can not find the PostgreSQL version file" 1>&2
- echo "'$PGDATA/PG_VERSION'. Exiting." 1>&2
- exit 1
- fi
-
- if [ "$SRC_VERSION" != "$CUR_VERSION" -a \
- "$SRC_VERSION" != "$UPGRADE_VERSION" ]
- then echo "$BASENAME supports versions $UPGRADE_VERSION and $CUR_VERSION only." 1>&2
- echo "However, your database is version $SRC_VERSION." 1>&2
- echo "You will need to dump and restore using pg_dumpall. Exiting." 1>&2
- exit 1
- fi
-
- # If server is down, start it so we can do some work.
- if ! pg_ctl status | sed -n '1p' | grep "is running" > /dev/null 2>&1
- then pg_ctl -w start
- if [ $? -ne 0 ]
- then echo "Can not start server. Exiting." 1>&2
- exit 1
- fi
- fi
-
- # create directory for our data
- if ! rm -rf "$INFODIR"
- then echo "Deletion of old pg_upgrade_info directory $INFODIR failed." 1>&2
- echo "Exiting." 1>&2
- exit 1
- fi
- if ! mkdir "$INFODIR"
- then echo "Creation of new pg_upgrade_info directory $INFODIR failed." 1>&2
- echo "Exiting." 1>&2
- exit 1
- fi
-
- if ! chmod og-rwx "$INFODIR"
- then echo "Permission change on new pg_upgrade_info directory $INFODIR failed." 1>&2
- echo "Exiting." 1>&2
- exit 1
- fi
-
-
- # Dump schema
- pg_dumpall -s > "$INFODIR"/schema
- if [ $? -ne 0 ]
- then echo "Can not dump schema. Exiting." 1>&2
- exit 1
- fi
-
- # Generate mappings for database
- make_dboidmap > "$INFODIR"/dboidmap || exit "$?"
- make_dbobjoidmap > "$INFODIR"/dbobjoidmap || exit "$?"
-
- # Vacuum all databases to remove exipired rows.
- # We will lose our transaction log file during the upgrade so we
- # have to do this.
-
- vacuumdb -a
- if [ $? -ne 0 ]
- then echo "Can not vacuum server. Exiting." 1>&2
- exit 1
- fi
-
- # Stop server so we can move the directory.
- pg_ctl -w stop
- if [ $? -ne 0 ]
- then echo "Can not stop server. Exiting." 1>&2
- exit 1
- fi
-
- # No matter what the directory name, call it data
- mv "$PGDATA" "$INFODIR"/data
- if [ $? -ne 0 ]
- then echo "Can not move old $PGDATA out of the way. Exiting." 1>&2
- exit 1
- fi
- echo
- echo
- echo "$BASENAME phase 1 completed."
- echo "Continue with the steps outlined in the $BASENAME manual page."
- exit 0
-fi
-
-
- ##########################
- # Phase 2 starts here #
- ##########################
-
-# check things
-
-if [ ! -d "$INFODIR" ]
-then echo "There is no '$INFODIR' directory from the phase 1 run of $BASENAME." 1>&2
- exit 1
-fi
-
-if [ ! -d "$SAVEDATA" ]
-then echo "There is no '$SAVEDATA' directory from the phase 1 run of $BASENAME." 1>&2
- exit 1
-fi
-
-if [ ! -f "$SAVEDATA/PG_VERSION" ]
-then echo "Cannot read '$SAVEDATA/PG_VERSION' --- something is wrong." 1>&2
- exit 1
-fi
-
-if [ ! -f "$PGDATA/PG_VERSION" ]
-then echo "Cannot read '$PGDATA/PG_VERSION' --- something is wrong." 1>&2
- exit 1
-fi
-
-if [ ! -d "$PGDATA/base/1" ]
-then echo "Cannot find database template1 in '$PGDATA/base'." 1>&2
- echo "Are you running $BASENAME as the postgres superuser?" 1>&2
- exit 1
-fi
-
-# Get the actual versions seen in the data dirs.
-
-SRC_VERSION=`cat "$SAVEDATA"/PG_VERSION`
-DST_VERSION=`cat "$PGDATA"/PG_VERSION`
-
-# Check for version compatibility.
-# This code will need to be updated/reviewed for each new PostgreSQL release.
-
-if [ "$DST_VERSION" != "$CUR_VERSION" ]
-then echo "$BASENAME is for PostgreSQL version $CUR_VERSION" 1>&2
- echo "but $PGDATA/PG_VERSION contains $DST_VERSION." 1>&2
- echo "Did you run initdb for version $UPGRADE_VERSION by mistake?" 1>&2
- exit 1
-fi
-
-# Stop server for pg_resetxlog use
-
-if pg_ctl status | sed -n '1p' | grep "is running" > /dev/null 2>&1
-then pg_ctl -w stop
- if [ $? -ne 0 ]
- then echo "Can not start server. Exiting." 1>&2
- exit 1
- fi
-fi
-
-# check for proper pg_resetxlog version
-
-pg_resetxlog 2> /dev/null
-# file not found status is normally 127, not 1
-if [ "$?" -ne 1 ]
-then echo "Unable to find pg_resetxlog in your path." 1>&2
- echo "Install it from pgsql/contrib/pg_resetxlog and continue. Exiting." 1>&2
- exit 1
-fi
-
-if ! pg_resetxlog -x 2>&1 | grep 'xid' > /dev/null 2>&1
-then echo "Old version of pg_resetxlog found in path." 1>&2
- echo "Install a newer version of pg_resetxlog from pgsql/contrib/pg_resetxlog." 1>&2
- echo "Exiting." 1>&2
- exit 1
-fi
-
-SRC_XID=`pg_resetxlog -n "$SAVEDATA" | grep "NextXID" | awk -F' *' '{print $4}'`
-DST_XID=`pg_resetxlog -n "$PGDATA" | grep "NextXID" | awk -F' *' '{print $4}'`
-
-# compare locales to make sure they match
-
-pg_resetxlog -n "$SAVEDATA" | grep "^LC_" > /tmp/$$.0
-pg_resetxlog -n "$PGDATA" | grep "^LC_" > /tmp/$$.1
-if ! diff /tmp/$$.0 /tmp/$$.1 > /dev/null
-then echo "Locales do not match between the two versions. Exiting." 1>&2
- exit 1
-fi
-
-# Restart postmaster
-
-pg_ctl -w start
-if [ $? -ne 0 ]
-then echo "Can not start server. Exiting." 1>&2
- exit 1
-fi
-
-
-###################################
-# Checking done. Ready to proceed.
-###################################
-
-
-# Execute the schema script to create everything
-
-psql template1 < "$INFODIR"/schema
-if [ $? -ne 0 ]
-then echo "There were errors in the input script. Exiting." 1>&2
- exit 1
-fi
-
-echo "Input script completed, fixing row commit statuses..."
-
-# Generate mappings for new database
-make_dboidmap > /tmp/$$.dboidmap || exit "$?"
-make_dbobjoidmap > /tmp/$$.dbobjoidmap || exit "$?"
-
-# we are done with SQL database access
-# shutdown forces buffers to disk
-
-pg_ctl -w stop
-if [ "$?" -ne 0 ]
-then echo "Unable to stop database server. Exiting." 1>&2
- exit 1
-fi
-
-echo "Commit fixes complete, moving data files..."
-
-# Move table/index/sequence files
-
-cat "$INFODIR"/dbobjoidmap | while read LINE
-do
- DB=`echo "$LINE" | awk '{print $1}'`
- OBJ=`echo "$LINE" | awk '{print $2}'`
-
- # Skip system tables, except for pg_largeobject
- # pg_toast tables are handled later as part of the
- # base table move
- if [ `expr X"$OBJ" : X'pg_'` -eq 4 -a \
- `expr X"$OBJ" : X'pg_largeobject'` -ne 15 ]
- then continue
- fi
-
- SRC_OID=`echo "$LINE" | awk '{print $3}'`
- SRC_DBOID=`grep "^$DB " "$INFODIR"/dboidmap | awk '{print $2}'`
- DST_DBOID=`grep "^$DB " /tmp/$$.dboidmap | awk '{print $2}'`
- DST_OID=`grep "^$DB $OBJ " /tmp/$$.dbobjoidmap | awk '{print $3}'`
-
- move_objfiles
-
- # Handle TOAST files if they exist
- if grep "^$DB pg_toast_$SRC_OID " "$INFODIR"/dbobjoidmap \
- > /dev/null 2>&1
- then # toast heap
- SAVE_SRC_OID="$SRC_OID"
- SAVE_DST_OID="$DST_OID"
- SRC_OID=`grep "^$DB pg_toast_$SAVE_SRC_OID " \
- "$INFODIR"/dbobjoidmap | awk '{print $3}'`
- DST_OID=`grep "^$DB pg_toast_$SAVE_DST_OID " \
- /tmp/$$.dbobjoidmap | awk '{print $3}'`
- move_objfiles
- # toast index
- SRC_OID=`grep "^$DB pg_toast_${SAVE_SRC_OID}_idx " \
- "$INFODIR"/dbobjoidmap | awk '{print $3}'`
- DST_OID=`grep "^$DB pg_toast_${SAVE_DST_OID}_idx " \
- /tmp/$$.dbobjoidmap | awk '{print $3}'`
- move_objfiles
- fi
-done
-
-
-# Set this so future backends don't think these tuples are their own
-# because it matches their own XID.
-# Commit status already updated by vacuum above
-# Set to maximum XID just in case SRC wrapped around recently and
-# is lower than DST's database
-
-if [ "$SRC_XID" -gt "$DST_XID" ]
-then MAX_XID="$SRC_XID"
-else MAX_XID="$DST_XID"
-fi
-
-pg_resetxlog -x "$MAX_XID" "$PGDATA"
-if [ "$?" -ne 0 ]
-then echo "Unable to set new XID. Exiting." 1>&2
- exit 1
-fi
-
-# Move over old WAL
-
-rm -r "$PGDATA"/pg_xlog
-mv -f "$SAVEDATA"/pg_xlog "$PGDATA"
-
-# Move over old clog
-
-rm -r "$PGDATA"/pg_clog
-mv -f "$SAVEDATA"/pg_clog "$PGDATA"
-
-# Set last log file id and segment from old database
-
-LOG_ID=`pg_resetxlog -n "$SAVEDATA" | grep "Current log file id:" |
- awk -F' *' '{print $5}'`
-if [ "$LOG_ID" = "" ]
-then echo "Unable to get old log file id. Exiting." 1>&2
- exit 1
-fi
-SEG_ID=`pg_resetxlog -n "$SAVEDATA" | grep "Next log file segment:" |
- awk -F' *' '{print $5}'`
-if [ "$SEG_ID" = "" ]
-then echo "Unable to get old log segment id. Exiting." 1>&2
- exit 1
-fi
-
-# Set