This commit was manufactured by cvs2git to create branch 'ecpg_big_bison'.

Sprout from master 2002-06-20 20:29:54 UTC Bruce Momjian <bruce@momjian.us> 'Update copyright to 2002.'
Delete:
    COPYRIGHT
    GNUmakefile.in
    HISTORY
    INSTALL
    Makefile
    README
    aclocal.m4
    config/ac_func_accept_argtypes.m4
    config/c-compiler.m4
    config/c-library.m4
    config/config.guess
    config/config.sub
    config/cxx.m4
    config/docbook.m4
    config/general.m4
    config/install-sh
    config/java.m4
    config/libtool.m4
    config/missing
    config/mkinstalldirs
    config/perl.m4
    config/prep_buildtree
    config/programs.m4
    config/python.m4
    config/tcl.m4
    configure
    configure.in
    contrib/Makefile
    contrib/README
    contrib/array/Makefile
    contrib/array/README.array_iterator
    contrib/array/array_iterator.c
    contrib/array/array_iterator.h
    contrib/array/array_iterator.sql.in
    contrib/btree_gist/Makefile
    contrib/btree_gist/README.btree_gist
    contrib/btree_gist/btree_gist.c
    contrib/btree_gist/btree_gist.sql.in
    contrib/btree_gist/data/test_btree.data
    contrib/btree_gist/data/test_btree_ts.data
    contrib/btree_gist/expected/btree_gist.out
    contrib/btree_gist/sql/btree_gist.sql
    contrib/chkpass/Makefile
    contrib/chkpass/README.chkpass
    contrib/chkpass/chkpass.c
    contrib/chkpass/chkpass.sql.in
    contrib/contrib-global.mk
    contrib/cube/Makefile
    contrib/cube/README.cube
    contrib/cube/buffer.c
    contrib/cube/buffer.h
    contrib/cube/cube.c
    contrib/cube/cube.sql.in
    contrib/cube/cubedata.h
    contrib/cube/cubeparse.y
    contrib/cube/cubescan.l
    contrib/cube/data/test_cube.data
    contrib/cube/expected/cube.out
    contrib/cube/sql/cube.sql
    contrib/dbase/Makefile
    contrib/dbase/README.dbf2pg
    contrib/dbase/dbf.c
    contrib/dbase/dbf.h
    contrib/dbase/dbf2pg.1
    contrib/dbase/dbf2pg.c
    contrib/dbase/endian.c
    contrib/dblink/Makefile
    contrib/dblink/README.dblink
    contrib/dblink/dblink.c
    contrib/dblink/dblink.h
    contrib/dblink/dblink.sql.in
    contrib/dbsize/Makefile
    contrib/dbsize/README.dbsize
    contrib/dbsize/dbsize.c
    contrib/dbsize/dbsize.sql.in
    contrib/earthdistance/Makefile
    contrib/earthdistance/README.earthdistance
    contrib/earthdistance/earthdistance.c
    contrib/earthdistance/earthdistance.sql.in
    contrib/findoidjoins/Makefile
    contrib/findoidjoins/README.findoidjoins
    contrib/findoidjoins/findoidjoins.c
    contrib/findoidjoins/make_oidjoins_check
    contrib/fulltextindex/Makefile
    contrib/fulltextindex/README.fti
    contrib/fulltextindex/TODO
    contrib/fulltextindex/fti.c
    contrib/fulltextindex/fti.pl
    contrib/fulltextindex/fti.sql.in
    contrib/fulltextindex/timings.sh
    contrib/fuzzystrmatch/Makefile
    contrib/fuzzystrmatch/README.fuzzystrmatch
    contrib/fuzzystrmatch/README.soundex
    contrib/fuzzystrmatch/fuzzystrmatch.c
    contrib/fuzzystrmatch/fuzzystrmatch.h
    contrib/fuzzystrmatch/fuzzystrmatch.sql.in
    contrib/intagg/Makefile
    contrib/intagg/README.int_aggregate
    contrib/intagg/int_aggregate.c
    contrib/intagg/int_aggregate.sql.in
    contrib/intarray/Makefile
    contrib/intarray/README.intarray
    contrib/intarray/_int.c
    contrib/intarray/_int.sql.in
    contrib/intarray/bench/bench.pl
    contrib/intarray/bench/create_test.pl
    contrib/intarray/data/test__int.data
    contrib/intarray/expected/_int.out
    contrib/intarray/sql/_int.sql
    contrib/ipc_check/README
    contrib/ipc_check/ipc_check.pl
    contrib/isbn_issn/Makefile
    contrib/isbn_issn/README.isbn_issn
    contrib/isbn_issn/isbn_issn.c
    contrib/isbn_issn/isbn_issn.sql.in
    contrib/lo/Makefile
    contrib/lo/README.lo
    contrib/lo/lo.c
    contrib/lo/lo.sql.in
    contrib/lo/lo_drop.sql
    contrib/lo/lo_test.sql
    contrib/mSQL-interface/Makefile
    contrib/mSQL-interface/README.mpgsql
    contrib/mSQL-interface/mpgsql.c
    contrib/mac/README.mac
    contrib/mac/createoui
    contrib/mac/dropoui
    contrib/mac/ouiparse.awk
    contrib/mac/updateoui
    contrib/miscutil/Makefile
    contrib/miscutil/README.misc_utils
    contrib/miscutil/misc_utils.c
    contrib/miscutil/misc_utils.h
    contrib/miscutil/misc_utils.sql.in
    contrib/mysql/README
    contrib/mysql/my2pg.pl
    contrib/mysql/mysql2pgsql
    contrib/noupdate/Makefile
    contrib/noupdate/README.noup
    contrib/noupdate/noup.c
    contrib/noupdate/noup.sql.in
    contrib/oid2name/Makefile
    contrib/oid2name/README.oid2name
    contrib/oid2name/oid2name.c
    contrib/oracle/CHANGES
    contrib/oracle/Ora2Pg.pm
    contrib/oracle/README.ora2pg
    contrib/oracle/TODO
    contrib/oracle/ora2pg.html
    contrib/oracle/ora2pg.pl
    contrib/pg_controldata/Makefile
    contrib/pg_controldata/README.pg_controldata
    contrib/pg_controldata/pg_controldata.c
    contrib/pg_dumplo/Makefile
    contrib/pg_dumplo/README.pg_dumplo
    contrib/pg_dumplo/lo_export.c
    contrib/pg_dumplo/lo_import.c
    contrib/pg_dumplo/main.c
    contrib/pg_dumplo/pg_dumplo.h
    contrib/pg_dumplo/utils.c
    contrib/pg_logger/Makefile
    contrib/pg_logger/README.pg_logger
    contrib/pg_logger/pg_logger.c
    contrib/pg_resetxlog/Makefile
    contrib/pg_resetxlog/README.pg_resetxlog
    contrib/pg_resetxlog/pg_resetxlog.c
    contrib/pg_upgrade/README
    contrib/pg_upgrade/pg_upgrade
    contrib/pg_upgrade/pg_upgrade.1
    contrib/pgbench/Makefile
    contrib/pgbench/README.pgbench
    contrib/pgbench/README.pgbench_jis
    contrib/pgbench/pgbench.c
    contrib/pgcrypto/API
    contrib/pgcrypto/Makefile
    contrib/pgcrypto/README.pgcrypto
    contrib/pgcrypto/blf.c
    contrib/pgcrypto/blf.h
    contrib/pgcrypto/crypt-blowfish.c
    contrib/pgcrypto/crypt-des.c
    contrib/pgcrypto/crypt-gensalt.c
    contrib/pgcrypto/crypt-md5.c
    contrib/pgcrypto/expected/blowfish.out
    contrib/pgcrypto/expected/crypt-blowfish.out
    contrib/pgcrypto/expected/crypt-des.out
    contrib/pgcrypto/expected/crypt-md5.out
    contrib/pgcrypto/expected/crypt-xdes.out
    contrib/pgcrypto/expected/hmac-md5.out
    contrib/pgcrypto/expected/hmac-sha1.out
    contrib/pgcrypto/expected/init.out
    contrib/pgcrypto/expected/md5.out
    contrib/pgcrypto/expected/rijndael.out
    contrib/pgcrypto/expected/sha1.out
    contrib/pgcrypto/internal.c
    contrib/pgcrypto/md5.c
    contrib/pgcrypto/md5.h
    contrib/pgcrypto/mhash.c
    contrib/pgcrypto/misc.c
    contrib/pgcrypto/openssl.c
    contrib/pgcrypto/pgcrypto.c
    contrib/pgcrypto/pgcrypto.h
    contrib/pgcrypto/pgcrypto.sql.in
    contrib/pgcrypto/px-crypt.c
    contrib/pgcrypto/px-crypt.h
    contrib/pgcrypto/px-hmac.c
    contrib/pgcrypto/px.c
    contrib/pgcrypto/px.h
    contrib/pgcrypto/random.c
    contrib/pgcrypto/rijndael.c
    contrib/pgcrypto/rijndael.h
    contrib/pgcrypto/rijndael.tbl
    contrib/pgcrypto/sha1.c
    contrib/pgcrypto/sha1.h
    contrib/pgcrypto/sql/blowfish.sql
    contrib/pgcrypto/sql/crypt-blowfish.sql
    contrib/pgcrypto/sql/crypt-des.sql
    contrib/pgcrypto/sql/crypt-md5.sql
    contrib/pgcrypto/sql/crypt-xdes.sql
    contrib/pgcrypto/sql/hmac-md5.sql
    contrib/pgcrypto/sql/hmac-sha1.sql
    contrib/pgcrypto/sql/init.sql
    contrib/pgcrypto/sql/md5.sql
    contrib/pgcrypto/sql/rijndael.sql
    contrib/pgcrypto/sql/sha1.sql
    contrib/pgstattuple/Makefile
    contrib/pgstattuple/README.pgstattuple
    contrib/pgstattuple/README.pgstattuple.euc_jp
    contrib/pgstattuple/pgstattuple.c
    contrib/pgstattuple/pgstattuple.sql.in
    contrib/retep/CHANGELOG
    contrib/retep/Implementation
    contrib/retep/Makefile
    contrib/retep/README
    contrib/retep/build.xml
    contrib/retep/data/cds.dtd
    contrib/retep/data/cds.xml
    contrib/retep/retep.jpx
    contrib/retep/uk/org/retep/dtu/DCollection.java
    contrib/retep/uk/org/retep/dtu/DConstants.java
    contrib/retep/uk/org/retep/dtu/DElement.java
    contrib/retep/uk/org/retep/dtu/DEnvironment.java
    contrib/retep/uk/org/retep/dtu/DModule.java
    contrib/retep/uk/org/retep/dtu/DModuleXML.java
    contrib/retep/uk/org/retep/dtu/DNode.java
    contrib/retep/uk/org/retep/dtu/DProcessor.java
    contrib/retep/uk/org/retep/dtu/DTransform.java
    contrib/retep/uk/org/retep/tools/Tool.java
    contrib/retep/uk/org/retep/tools.properties
    contrib/retep/uk/org/retep/util/ExceptionDialog.java
    contrib/retep/uk/org/retep/util/Globals.java
    contrib/retep/uk/org/retep/util/Logger.java
    contrib/retep/uk/org/retep/util/Main.java
    contrib/retep/uk/org/retep/util/StandaloneApp.java
    contrib/retep/uk/org/retep/util/hba/Editor.java
    contrib/retep/uk/org/retep/util/hba/Main.java
    contrib/retep/uk/org/retep/util/hba/Record.java
    contrib/retep/uk/org/retep/util/misc/IPAddress.java
    contrib/retep/uk/org/retep/util/misc/PropertiesIO.java
    contrib/retep/uk/org/retep/util/misc/WStringTokenizer.java
    contrib/retep/uk/org/retep/util/models/HBATableModel.java
    contrib/retep/uk/org/retep/util/models/PropertiesTableModel.java
    contrib/retep/uk/org/retep/util/proped/Main.java
    contrib/retep/uk/org/retep/util/proped/PropertyEditor.java
    contrib/retep/uk/org/retep/xml/core/XMLFactory.java
    contrib/retep/uk/org/retep/xml/core/XMLFactoryException.java
    contrib/retep/uk/org/retep/xml/jdbc/XMLDatabase.java
    contrib/retep/uk/org/retep/xml/jdbc/XMLResultSet.java
    contrib/retep/uk/org/retep/xml/parser/TagHandler.java
    contrib/retep/uk/org/retep/xml/parser/TagListener.java
    contrib/retep/uk/org/retep/xml/test/XMLExport.java
    contrib/rserv/ApplySnapshot.in
    contrib/rserv/CleanLog.in
    contrib/rserv/GetSyncID.in
    contrib/rserv/InitRservTest.in
    contrib/rserv/Makefile
    contrib/rserv/MasterAddTable.in
    contrib/rserv/MasterInit.in
    contrib/rserv/MasterSync.in
    contrib/rserv/PrepareSnapshot.in
    contrib/rserv/README.rserv
    contrib/rserv/RServ.pm
    contrib/rserv/Replicate.in
    contrib/rserv/RservTest.in
    contrib/rserv/SlaveAddTable.in
    contrib/rserv/SlaveInit.in
    contrib/rserv/master.sql.in
    contrib/rserv/regress.sh
    contrib/rserv/rserv.c
    contrib/rserv/slave.sql.in
    contrib/rtree_gist/Makefile
    contrib/rtree_gist/README.rtree_gist
    contrib/rtree_gist/bench/bench.pl
    contrib/rtree_gist/bench/create_test.pl
    contrib/rtree_gist/data/test_box.data
    contrib/rtree_gist/expected/rtree_gist.out
    contrib/rtree_gist/rtree_gist.c
    contrib/rtree_gist/rtree_gist.sql.in
    contrib/rtree_gist/sql/rtree_gist.sql
    contrib/seg/Makefile
    contrib/seg/README.seg
    contrib/seg/buffer.c
    contrib/seg/buffer.h
    contrib/seg/data/test_seg.data
    contrib/seg/expected/seg.out
    contrib/seg/seg-validate.pl
    contrib/seg/seg.c
    contrib/seg/seg.sql.in
    contrib/seg/segdata.h
    contrib/seg/segparse.y
    contrib/seg/segscan.l
    contrib/seg/sort-segments.pl
    contrib/seg/sql/seg.sql
    contrib/spi/Makefile
    contrib/spi/README.spi
    contrib/spi/autoinc.c
    contrib/spi/autoinc.example
    contrib/spi/autoinc.sql.in
    contrib/spi/insert_username.c
    contrib/spi/insert_username.example
    contrib/spi/insert_username.sql.in
    contrib/spi/moddatetime.c
    contrib/spi/moddatetime.example
    contrib/spi/moddatetime.sql.in
    contrib/spi/preprocessor/README.MAX
    contrib/spi/preprocessor/example.sql
    contrib/spi/preprocessor/step1.c
    contrib/spi/preprocessor/step1.e
    contrib/spi/preprocessor/step2.pl
    contrib/spi/refint.c
    contrib/spi/refint.example
    contrib/spi/refint.sql.in
    contrib/spi/timetravel.c
    contrib/spi/timetravel.example
    contrib/spi/timetravel.sql.in
    contrib/start-scripts/freebsd
    contrib/start-scripts/linux
    contrib/string/Makefile
    contrib/string/README.string_io
    contrib/string/string_io.c
    contrib/string/string_io.h
    contrib/string/string_io.sql.in
    contrib/tips/Makefile
    contrib/tips/README.apachelog
    contrib/tools/add-emacs-variables
    contrib/tools/find-sources
    contrib/tools/make-tags
    contrib/tsearch/Makefile
    contrib/tsearch/README.tsearch
    contrib/tsearch/crc32.c
    contrib/tsearch/crc32.h
    contrib/tsearch/data/test_tsearch.data
    contrib/tsearch/deflex.h
    contrib/tsearch/dict/porter_english.dct
    contrib/tsearch/dict/russian_stemming.dct
    contrib/tsearch/dict.h
    contrib/tsearch/expected/tsearch.out
    contrib/tsearch/gistidx.c
    contrib/tsearch/gistidx.h
    contrib/tsearch/makedict/makedict.pl
    contrib/tsearch/morph.c
    contrib/tsearch/morph.h
    contrib/tsearch/parser.h
    contrib/tsearch/parser.l
    contrib/tsearch/query.c
    contrib/tsearch/query.h
    contrib/tsearch/rewrite.c
    contrib/tsearch/rewrite.h
    contrib/tsearch/sql/tsearch.sql
    contrib/tsearch/tsearch.sql.in
    contrib/tsearch/txtidx.c
    contrib/tsearch/txtidx.h
    contrib/userlock/Makefile
    contrib/userlock/README.user_locks
    contrib/userlock/user_locks.c
    contrib/userlock/user_locks.h
    contrib/userlock/user_locks.sql.in
    contrib/vacuumlo/Makefile
    contrib/vacuumlo/README.vacuumlo
    contrib/vacuumlo/vacuumlo.c
    contrib/xml/Makefile
    contrib/xml/README
    contrib/xml/TODO
    contrib/xml/pgxml.c
    contrib/xml/pgxml.h
    contrib/xml/pgxml.source
    contrib/xml/pgxml_dom.c
    contrib/xml/pgxml_dom.source
    doc/FAQ
    doc/FAQ_AIX
    doc/FAQ_DEV
    doc/FAQ_HPUX
    doc/FAQ_IRIX
    doc/FAQ_MSWIN
    doc/FAQ_QNX4
    doc/FAQ_SCO
    doc/FAQ_Solaris
    doc/FAQ_german
    doc/FAQ_japanese
    doc/FAQ_polish
    doc/FAQ_russian
    doc/KNOWN_BUGS
    doc/MISSING_FEATURES
    doc/Makefile
    doc/README.mb.big5
    doc/README.mb.jp
    doc/TODO
    doc/TODO.detail/README
    doc/TODO.detail/atttypmod
    doc/TODO.detail/crossdb
    doc/TODO.detail/cursor
    doc/TODO.detail/drop
    doc/TODO.detail/exists
    doc/TODO.detail/foreign
    doc/TODO.detail/fsync
    doc/TODO.detail/inheritance
    doc/TODO.detail/java
    doc/TODO.detail/mmap
    doc/TODO.detail/namedatalen
    doc/TODO.detail/optimizer
    doc/TODO.detail/performance
    doc/TODO.detail/persistent
    doc/TODO.detail/pool
    doc/TODO.detail/prepare
    doc/TODO.detail/privileges
    doc/TODO.detail/replication
    doc/TODO.detail/schema
    doc/TODO.detail/tablespaces
    doc/TODO.detail/thread
    doc/TODO.detail/transactions
    doc/TODO.detail/typeconv
    doc/TODO.detail/update
    doc/TODO.detail/vacuum
    doc/TODO.detail/view
    doc/TODO.detail/win32
    doc/TODO.detail/yacc
    doc/bug.template
    doc/src/FAQ/FAQ.html
    doc/src/FAQ/FAQ_DEV.html
    doc/src/FAQ/FAQ_german.html
    doc/src/FAQ/FAQ_japanese.html
    doc/src/FAQ/FAQ_polish.html
    doc/src/FAQ/FAQ_russian.html
    doc/src/Makefile
    doc/src/graphics/catalogs.ag
    doc/src/graphics/catalogs.cgm
    doc/src/graphics/catalogs.gif
    doc/src/graphics/catalogs.ps
    doc/src/graphics/clientserver.ag
    doc/src/graphics/clientserver.gif
    doc/src/graphics/connections.ag
    doc/src/graphics/connections.gif
    doc/src/sgml/Makefile
    doc/src/sgml/admin.sgml
    doc/src/sgml/advanced.sgml
    doc/src/sgml/arch-dev.sgml
    doc/src/sgml/arch-pg.sgml
    doc/src/sgml/array.sgml
    doc/src/sgml/backup.sgml
    doc/src/sgml/biblio.sgml
    doc/src/sgml/bki.sgml
    doc/src/sgml/book-decl.sgml
    doc/src/sgml/catalogs.sgml
    doc/src/sgml/charset.sgml
    doc/src/sgml/client-auth.sgml
    doc/src/sgml/compiler.sgml
    doc/src/sgml/contacts.sgml
    doc/src/sgml/cvs.sgml
    doc/src/sgml/datatype.sgml
    doc/src/sgml/datetime.sgml
    doc/src/sgml/developer.sgml
    doc/src/sgml/dfunc.sgml
    doc/src/sgml/diskusage.sgml
    doc/src/sgml/docguide.sgml
    doc/src/sgml/ecpg.sgml
    doc/src/sgml/extend.sgml
    doc/src/sgml/features.sgml
    doc/src/sgml/filelist.sgml
    doc/src/sgml/fixrtf
    doc/src/sgml/func-ref.sgml
    doc/src/sgml/func.sgml
    doc/src/sgml/geqo.sgml
    doc/src/sgml/gist.sgml
    doc/src/sgml/history.sgml
    doc/src/sgml/indexcost.sgml
    doc/src/sgml/indices.sgml
    doc/src/sgml/info.sgml
    doc/src/sgml/inherit.sgml
    doc/src/sgml/install-win32.sgml
    doc/src/sgml/installation.sgml
    doc/src/sgml/intro.sgml
    doc/src/sgml/jdbc.sgml
    doc/src/sgml/keywords.sgml
    doc/src/sgml/legal.sgml
    doc/src/sgml/libpgeasy.sgml
    doc/src/sgml/libpgtcl.sgml
    doc/src/sgml/libpq++.sgml
    doc/src/sgml/libpq.sgml
    doc/src/sgml/lobj.sgml
    doc/src/sgml/maintenance.sgml
    doc/src/sgml/manage-ag.sgml
    doc/src/sgml/manage.sgml
    doc/src/sgml/monitoring.sgml
    doc/src/sgml/mvcc.sgml
    doc/src/sgml/nls.sgml
    doc/src/sgml/notation.sgml
    doc/src/sgml/odbc.sgml
    doc/src/sgml/page.sgml
    doc/src/sgml/perform.sgml
    doc/src/sgml/plperl.sgml
    doc/src/sgml/plpython.sgml
    doc/src/sgml/plsql.sgml
    doc/src/sgml/pltcl.sgml
    doc/src/sgml/postgres.sgml
    doc/src/sgml/problems.sgml
    doc/src/sgml/programmer.sgml
    doc/src/sgml/protocol.sgml
    doc/src/sgml/pygresql.sgml
    doc/src/sgml/queries.sgml
    doc/src/sgml/query.sgml
    doc/src/sgml/recovery.sgml
    doc/src/sgml/ref/abort.sgml
    doc/src/sgml/ref/allfiles.sgml
    doc/src/sgml/ref/alter_database.sgml
    doc/src/sgml/ref/alter_group.sgml
    doc/src/sgml/ref/alter_table.sgml
    doc/src/sgml/ref/alter_trigger.sgml
    doc/src/sgml/ref/alter_user.sgml
    doc/src/sgml/ref/analyze.sgml
    doc/src/sgml/ref/begin.sgml
    doc/src/sgml/ref/checkpoint.sgml
    doc/src/sgml/ref/close.sgml
    doc/src/sgml/ref/cluster.sgml
    doc/src/sgml/ref/comment.sgml
    doc/src/sgml/ref/commit.sgml
    doc/src/sgml/ref/copy.sgml
    doc/src/sgml/ref/create_aggregate.sgml
    doc/src/sgml/ref/create_constraint.sgml
    doc/src/sgml/ref/create_database.sgml
    doc/src/sgml/ref/create_domain.sgml
    doc/src/sgml/ref/create_function.sgml
    doc/src/sgml/ref/create_group.sgml
    doc/src/sgml/ref/create_index.sgml
    doc/src/sgml/ref/create_language.sgml
    doc/src/sgml/ref/create_operator.sgml
    doc/src/sgml/ref/create_rule.sgml
    doc/src/sgml/ref/create_schema.sgml
    doc/src/sgml/ref/create_sequence.sgml
    doc/src/sgml/ref/create_table.sgml
    doc/src/sgml/ref/create_table_as.sgml
    doc/src/sgml/ref/create_trigger.sgml
    doc/src/sgml/ref/create_type.sgml
    doc/src/sgml/ref/create_user.sgml
    doc/src/sgml/ref/create_view.sgml
    doc/src/sgml/ref/createdb.sgml
    doc/src/sgml/ref/createlang.sgml
    doc/src/sgml/ref/createuser.sgml
    doc/src/sgml/ref/current_date.sgml
    doc/src/sgml/ref/current_time.sgml
    doc/src/sgml/ref/current_timestamp.sgml
    doc/src/sgml/ref/current_user.sgml
    doc/src/sgml/ref/declare.sgml
    doc/src/sgml/ref/delete.sgml
    doc/src/sgml/ref/drop_aggregate.sgml
    doc/src/sgml/ref/drop_database.sgml
    doc/src/sgml/ref/drop_domain.sgml
    doc/src/sgml/ref/drop_function.sgml
    doc/src/sgml/ref/drop_group.sgml
    doc/src/sgml/ref/drop_index.sgml
    doc/src/sgml/ref/drop_language.sgml
    doc/src/sgml/ref/drop_operator.sgml
    doc/src/sgml/ref/drop_rule.sgml
    doc/src/sgml/ref/drop_sequence.sgml
    doc/src/sgml/ref/drop_table.sgml
    doc/src/sgml/ref/drop_trigger.sgml
    doc/src/sgml/ref/drop_type.sgml
    doc/src/sgml/ref/drop_user.sgml
    doc/src/sgml/ref/drop_view.sgml
    doc/src/sgml/ref/dropdb.sgml
    doc/src/sgml/ref/droplang.sgml
    doc/src/sgml/ref/dropuser.sgml
    doc/src/sgml/ref/ecpg-ref.sgml
    doc/src/sgml/ref/end.sgml
    doc/src/sgml/ref/explain.sgml
    doc/src/sgml/ref/fetch.sgml
    doc/src/sgml/ref/grant.sgml
    doc/src/sgml/ref/initdb.sgml
    doc/src/sgml/ref/initlocation.sgml
    doc/src/sgml/ref/insert.sgml
    doc/src/sgml/ref/ipcclean.sgml
    doc/src/sgml/ref/listen.sgml
    doc/src/sgml/ref/load.sgml
    doc/src/sgml/ref/lock.sgml
    doc/src/sgml/ref/move.sgml
    doc/src/sgml/ref/notify.sgml
    doc/src/sgml/ref/pg_config-ref.sgml
    doc/src/sgml/ref/pg_ctl-ref.sgml
    doc/src/sgml/ref/pg_dump.sgml
    doc/src/sgml/ref/pg_dumpall.sgml
    doc/src/sgml/ref/pg_restore.sgml
    doc/src/sgml/ref/pgaccess-ref.sgml
    doc/src/sgml/ref/pgtclsh.sgml
    doc/src/sgml/ref/pgtksh.sgml
    doc/src/sgml/ref/postgres-ref.sgml
    doc/src/sgml/ref/postmaster.sgml
    doc/src/sgml/ref/psql-ref.sgml
    doc/src/sgml/ref/reindex.sgml
    doc/src/sgml/ref/reset.sgml
    doc/src/sgml/ref/revoke.sgml
    doc/src/sgml/ref/rollback.sgml
    doc/src/sgml/ref/select.sgml
    doc/src/sgml/ref/select_into.sgml
    doc/src/sgml/ref/set.sgml
    doc/src/sgml/ref/set_constraints.sgml
    doc/src/sgml/ref/set_session_auth.sgml
    doc/src/sgml/ref/set_transaction.sgml
    doc/src/sgml/ref/show.sgml
    doc/src/sgml/ref/truncate.sgml
    doc/src/sgml/ref/unlisten.sgml
    doc/src/sgml/ref/update.sgml
    doc/src/sgml/ref/vacuum.sgml
    doc/src/sgml/ref/vacuumdb.sgml
    doc/src/sgml/refentry.sgml
    doc/src/sgml/reference.ced
    doc/src/sgml/reference.sgml
    doc/src/sgml/regress.sgml
    doc/src/sgml/release.sgml
    doc/src/sgml/rules.sgml
    doc/src/sgml/runtime.sgml
    doc/src/sgml/sources.sgml
    doc/src/sgml/spi.sgml
    doc/src/sgml/sql.sgml
    doc/src/sgml/standalone-install.sgml
    doc/src/sgml/start.sgml
    doc/src/sgml/stylesheet.css
    doc/src/sgml/stylesheet.dsl
    doc/src/sgml/syntax.sgml
    doc/src/sgml/trigger.sgml
    doc/src/sgml/tutorial.sgml
    doc/src/sgml/typeconv.sgml
    doc/src/sgml/user-manag.sgml
    doc/src/sgml/user.sgml
    doc/src/sgml/version.sgml
    doc/src/sgml/wal.sgml
    doc/src/sgml/xaggr.sgml
    doc/src/sgml/xfunc.sgml
    doc/src/sgml/xindex.sgml
    doc/src/sgml/xoper.sgml
    doc/src/sgml/xplang.sgml
    doc/src/sgml/xtypes.sgml
    doc/src/sgml/y2k.sgml
    register.txt
    src/DEVELOPERS
    src/Makefile
    src/Makefile.global.in
    src/Makefile.shlib
    src/backend/Makefile
    src/backend/access/Makefile
    src/backend/access/common/Makefile
    src/backend/access/common/heaptuple.c
    src/backend/access/common/indextuple.c
    src/backend/access/common/indexvalid.c
    src/backend/access/common/printtup.c
    src/backend/access/common/scankey.c
    src/backend/access/common/tupdesc.c
    src/backend/access/gist/Makefile
    src/backend/access/gist/gist.c
    src/backend/access/gist/gistget.c
    src/backend/access/gist/gistscan.c
    src/backend/access/gist/giststrat.c
    src/backend/access/hash/Makefile
    src/backend/access/hash/hash.c
    src/backend/access/hash/hashfunc.c
    src/backend/access/hash/hashinsert.c
    src/backend/access/hash/hashovfl.c
    src/backend/access/hash/hashpage.c
    src/backend/access/hash/hashscan.c
    src/backend/access/hash/hashsearch.c
    src/backend/access/hash/hashstrat.c
    src/backend/access/hash/hashutil.c
    src/backend/access/heap/Makefile
    src/backend/access/heap/heapam.c
    src/backend/access/heap/hio.c
    src/backend/access/heap/tuptoaster.c
    src/backend/access/index/Makefile
    src/backend/access/index/genam.c
    src/backend/access/index/indexam.c
    src/backend/access/index/istrat.c
    src/backend/access/nbtree/Makefile
    src/backend/access/nbtree/README
    src/backend/access/nbtree/nbtcompare.c
    src/backend/access/nbtree/nbtinsert.c
    src/backend/access/nbtree/nbtpage.c
    src/backend/access/nbtree/nbtree.c
    src/backend/access/nbtree/nbtsearch.c
    src/backend/access/nbtree/nbtsort.c
    src/backend/access/nbtree/nbtstrat.c
    src/backend/access/nbtree/nbtutils.c
    src/backend/access/rtree/Makefile
    src/backend/access/rtree/rtget.c
    src/backend/access/rtree/rtproc.c
    src/backend/access/rtree/rtree.c
    src/backend/access/rtree/rtscan.c
    src/backend/access/rtree/rtstrat.c
    src/backend/access/transam/Makefile
    src/backend/access/transam/clog.c
    src/backend/access/transam/rmgr.c
    src/backend/access/transam/transam.c
    src/backend/access/transam/varsup.c
    src/backend/access/transam/xact.c
    src/backend/access/transam/xid.c
    src/backend/access/transam/xlog.c
    src/backend/access/transam/xlogutils.c
    src/backend/bootstrap/.cvsignore
    src/backend/bootstrap/Makefile
    src/backend/bootstrap/bootparse.y
    src/backend/bootstrap/bootscanner.l
    src/backend/bootstrap/bootstrap.c
    src/backend/catalog/Makefile
    src/backend/catalog/README
    src/backend/catalog/aclchk.c
    src/backend/catalog/catalog.c
    src/backend/catalog/genbki.sh
    src/backend/catalog/heap.c
    src/backend/catalog/index.c
    src/backend/catalog/indexing.c
    src/backend/catalog/namespace.c
    src/backend/catalog/pg_aggregate.c
    src/backend/catalog/pg_largeobject.c
    src/backend/catalog/pg_namespace.c
    src/backend/catalog/pg_operator.c
    src/backend/catalog/pg_proc.c
    src/backend/catalog/pg_type.c
    src/backend/commands/Makefile
    src/backend/commands/_deadcode/recipe.c
    src/backend/commands/_deadcode/recipe.h
    src/backend/commands/_deadcode/version.c
    src/backend/commands/aggregatecmds.c
    src/backend/commands/analyze.c
    src/backend/commands/async.c
    src/backend/commands/cluster.c
    src/backend/commands/comment.c
    src/backend/commands/copy.c
    src/backend/commands/dbcommands.c
    src/backend/commands/define.c
    src/backend/commands/explain.c
    src/backend/commands/functioncmds.c
    src/backend/commands/indexcmds.c
    src/backend/commands/lockcmds.c
    src/backend/commands/operatorcmds.c
    src/backend/commands/portalcmds.c
    src/backend/commands/proclang.c
    src/backend/commands/schemacmds.c
    src/backend/commands/sequence.c
    src/backend/commands/tablecmds.c
    src/backend/commands/trigger.c
    src/backend/commands/typecmds.c
    src/backend/commands/user.c
    src/backend/commands/vacuum.c
    src/backend/commands/vacuumlazy.c
    src/backend/commands/variable.c
    src/backend/commands/view.c
    src/backend/executor/Makefile
    src/backend/executor/README
    src/backend/executor/_deadcode/nodeTee.c
    src/backend/executor/execAmi.c
    src/backend/executor/execJunk.c
    src/backend/executor/execMain.c
    src/backend/executor/execProcnode.c
    src/backend/executor/execQual.c
    src/backend/executor/execScan.c
    src/backend/executor/execTuples.c
    src/backend/executor/execUtils.c
    src/backend/executor/functions.c
    src/backend/executor/instrument.c
    src/backend/executor/nodeAgg.c
    src/backend/executor/nodeAppend.c
    src/backend/executor/nodeFunctionscan.c
    src/backend/executor/nodeGroup.c
    src/backend/executor/nodeHash.c
    src/backend/executor/nodeHashjoin.c
    src/backend/executor/nodeIndexscan.c
    src/backend/executor/nodeLimit.c
    src/backend/executor/nodeMaterial.c
    src/backend/executor/nodeMergejoin.c
    src/backend/executor/nodeNestloop.c
    src/backend/executor/nodeResult.c
    src/backend/executor/nodeSeqscan.c
    src/backend/executor/nodeSetOp.c
    src/backend/executor/nodeSort.c
    src/backend/executor/nodeSubplan.c
    src/backend/executor/nodeSubqueryscan.c
    src/backend/executor/nodeTidscan.c
    src/backend/executor/nodeUnique.c
    src/backend/executor/spi.c
    src/backend/lib/Makefile
    src/backend/lib/bit.c
    src/backend/lib/dllist.c
    src/backend/lib/lispsort.c
    src/backend/lib/stringinfo.c
    src/backend/libpq/Makefile
    src/backend/libpq/README.SSL
    src/backend/libpq/auth.c
    src/backend/libpq/be-fsstubs.c
    src/backend/libpq/be-secure.c
    src/backend/libpq/crypt.c
    src/backend/libpq/hba.c
    src/backend/libpq/md5.c
    src/backend/libpq/pg_hba.conf.sample
    src/backend/libpq/pg_ident.conf.sample
    src/backend/libpq/pqcomm.c
    src/backend/libpq/pqformat.c
    src/backend/libpq/pqsignal.c
    src/backend/main/Makefile
    src/backend/main/main.c
    src/backend/nodes/Makefile
    src/backend/nodes/README
    src/backend/nodes/copyfuncs.c
    src/backend/nodes/equalfuncs.c
    src/backend/nodes/list.c
    src/backend/nodes/makefuncs.c
    src/backend/nodes/nodeFuncs.c
    src/backend/nodes/nodes.c
    src/backend/nodes/outfuncs.c
    src/backend/nodes/print.c
    src/backend/nodes/read.c
    src/backend/nodes/readfuncs.c
    src/backend/optimizer/Makefile
    src/backend/optimizer/README
    src/backend/optimizer/geqo/Makefile
    src/backend/optimizer/geqo/geqo_copy.c
    src/backend/optimizer/geqo/geqo_cx.c
    src/backend/optimizer/geqo/geqo_erx.c
    src/backend/optimizer/geqo/geqo_eval.c
    src/backend/optimizer/geqo/geqo_main.c
    src/backend/optimizer/geqo/geqo_misc.c
    src/backend/optimizer/geqo/geqo_mutation.c
    src/backend/optimizer/geqo/geqo_ox1.c
    src/backend/optimizer/geqo/geqo_ox2.c
    src/backend/optimizer/geqo/geqo_pmx.c
    src/backend/optimizer/geqo/geqo_pool.c
    src/backend/optimizer/geqo/geqo_px.c
    src/backend/optimizer/geqo/geqo_recombination.c
    src/backend/optimizer/geqo/geqo_selection.c
    src/backend/optimizer/path/Makefile
    src/backend/optimizer/path/_deadcode/predmig.c
    src/backend/optimizer/path/_deadcode/xfunc.c
    src/backend/optimizer/path/allpaths.c
    src/backend/optimizer/path/clausesel.c
    src/backend/optimizer/path/costsize.c
    src/backend/optimizer/path/indxpath.c
    src/backend/optimizer/path/joinpath.c
    src/backend/optimizer/path/joinrels.c
    src/backend/optimizer/path/orindxpath.c
    src/backend/optimizer/path/pathkeys.c
    src/backend/optimizer/path/tidpath.c
    src/backend/optimizer/plan/Makefile
    src/backend/optimizer/plan/README
    src/backend/optimizer/plan/createplan.c
    src/backend/optimizer/plan/initsplan.c
    src/backend/optimizer/plan/planmain.c
    src/backend/optimizer/plan/planner.c
    src/backend/optimizer/plan/setrefs.c
    src/backend/optimizer/plan/subselect.c
    src/backend/optimizer/prep/Makefile
    src/backend/optimizer/prep/_deadcode/prepkeyset.c
    src/backend/optimizer/prep/prepqual.c
    src/backend/optimizer/prep/preptlist.c
    src/backend/optimizer/prep/prepunion.c
    src/backend/optimizer/util/Makefile
    src/backend/optimizer/util/clauses.c
    src/backend/optimizer/util/joininfo.c
    src/backend/optimizer/util/pathnode.c
    src/backend/optimizer/util/plancat.c
    src/backend/optimizer/util/relnode.c
    src/backend/optimizer/util/restrictinfo.c
    src/backend/optimizer/util/tlist.c
    src/backend/optimizer/util/var.c
    src/backend/parser/.cvsignore
    src/backend/parser/Makefile
    src/backend/parser/README
    src/backend/parser/analyze.c
    src/backend/parser/gram.y
    src/backend/parser/keywords.c
    src/backend/parser/parse_agg.c
    src/backend/parser/parse_clause.c
    src/backend/parser/parse_coerce.c
    src/backend/parser/parse_expr.c
    src/backend/parser/parse_func.c
    src/backend/parser/parse_node.c
    src/backend/parser/parse_oper.c
    src/backend/parser/parse_relation.c
    src/backend/parser/parse_target.c
    src/backend/parser/parse_type.c
    src/backend/parser/parser.c
    src/backend/parser/scan.l
    src/backend/parser/scansup.c
    src/backend/po/Makefile
    src/backend/po/cs.po
    src/backend/po/de.po
    src/backend/po/hu.po
    src/backend/po/nls.mk
    src/backend/po/ru.po
    src/backend/po/zh_CN.po
    src/backend/po/zh_TW.po
    src/backend/port/Makefile
    src/backend/port/aix/mkldexport.sh
    src/backend/port/beos/Makefile
    src/backend/port/beos/sem.c
    src/backend/port/beos/shm.c
    src/backend/port/beos/support.c
    src/backend/port/darwin/Makefile
    src/backend/port/darwin/README
    src/backend/port/darwin/system.c
    src/backend/port/dynloader/README.dlfcn.aix
    src/backend/port/dynloader/aix.c
    src/backend/port/dynloader/aix.h
    src/backend/port/dynloader/beos.c
    src/backend/port/dynloader/beos.h
    src/backend/port/dynloader/bsdi.c
    src/backend/port/dynloader/bsdi.h
    src/backend/port/dynloader/darwin.c
    src/backend/port/dynloader/darwin.h
    src/backend/port/dynloader/dgux.c
    src/backend/port/dynloader/dgux.h
    src/backend/port/dynloader/freebsd.c
    src/backend/port/dynloader/freebsd.h
    src/backend/port/dynloader/hpux.c
    src/backend/port/dynloader/hpux.h
    src/backend/port/dynloader/irix5.c
    src/backend/port/dynloader/irix5.h
    src/backend/port/dynloader/linux.c
    src/backend/port/dynloader/linux.h
    src/backend/port/dynloader/netbsd.c
    src/backend/port/dynloader/netbsd.h
    src/backend/port/dynloader/nextstep.c
    src/backend/port/dynloader/nextstep.h
    src/backend/port/dynloader/openbsd.c
    src/backend/port/dynloader/openbsd.h
    src/backend/port/dynloader/osf.c
    src/backend/port/dynloader/osf.h
    src/backend/port/dynloader/qnx4.c
    src/backend/port/dynloader/qnx4.h
    src/backend/port/dynloader/sco.c
    src/backend/port/dynloader/sco.h
    src/backend/port/dynloader/solaris.c
    src/backend/port/dynloader/solaris.h
    src/backend/port/dynloader/sunos4.c
    src/backend/port/dynloader/sunos4.h
    src/backend/port/dynloader/svr4.c
    src/backend/port/dynloader/svr4.h
    src/backend/port/dynloader/ultrix4.c
    src/backend/port/dynloader/ultrix4.h
    src/backend/port/dynloader/univel.c
    src/backend/port/dynloader/univel.h
    src/backend/port/dynloader/unixware.c
    src/backend/port/dynloader/unixware.h
    src/backend/port/dynloader/win.c
    src/backend/port/dynloader/win.h
    src/backend/port/gethostname.c
    src/backend/port/getrusage.c
    src/backend/port/hpux/tas.c.template
    src/backend/port/inet_aton.c
    src/backend/port/inet_aton.h
    src/backend/port/ipc_test.c
    src/backend/port/isinf.c
    src/backend/port/memcmp.c
    src/backend/port/nextstep/Makefile
    src/backend/port/nextstep/port.c
    src/backend/port/posix_sema.c
    src/backend/port/qnx4/Makefile
    src/backend/port/qnx4/ipc.h
    src/backend/port/qnx4/isnan.c
    src/backend/port/qnx4/rint.c
    src/backend/port/qnx4/sem.c
    src/backend/port/qnx4/sem.h
    src/backend/port/qnx4/shm.c
    src/backend/port/qnx4/shm.h
    src/backend/port/qnx4/tstrint.c
    src/backend/port/qnx4/tstsem.c
    src/backend/port/qnx4/tstshm.c
    src/backend/port/random.c
    src/backend/port/snprintf.c
    src/backend/port/srandom.c
    src/backend/port/strcasecmp.c
    src/backend/port/strerror.c
    src/backend/port/strtol.c
    src/backend/port/strtoul.c
    src/backend/port/sunos4/Makefile
    src/backend/port/sunos4/float.h
    src/backend/port/sysv_sema.c
    src/backend/port/sysv_shmem.c
    src/backend/port/tas/dummy.s
    src/backend/port/tas/hpux.s
    src/backend/port/tas/solaris_i386.s
    src/backend/port/tas/solaris_sparc.s
    src/backend/postmaster/Makefile
    src/backend/postmaster/pgstat.c
    src/backend/postmaster/postmaster.c
    src/backend/regex/COPYRIGHT
    src/backend/regex/Makefile
    src/backend/regex/WHATSNEW
    src/backend/regex/engine.c
    src/backend/regex/re_format.7
    src/backend/regex/regcomp.c
    src/backend/regex/regerror.c
    src/backend/regex/regex.3
    src/backend/regex/regexec.c
    src/backend/regex/regfree.c
    src/backend/regex/retest.c
    src/backend/rewrite/Makefile
    src/backend/rewrite/rewriteDefine.c
    src/backend/rewrite/rewriteHandler.c
    src/backend/rewrite/rewriteManip.c
    src/backend/rewrite/rewriteRemove.c
    src/backend/rewrite/rewriteSupport.c
    src/backend/storage/Makefile
    src/backend/storage/buffer/Makefile
    src/backend/storage/buffer/README
    src/backend/storage/buffer/buf_init.c
    src/backend/storage/buffer/buf_table.c
    src/backend/storage/buffer/bufmgr.c
    src/backend/storage/buffer/freelist.c
    src/backend/storage/buffer/localbuf.c
    src/backend/storage/file/Makefile
    src/backend/storage/file/buffile.c
    src/backend/storage/file/fd.c
    src/backend/storage/freespace/Makefile
    src/backend/storage/freespace/freespace.c
    src/backend/storage/ipc/Makefile
    src/backend/storage/ipc/README
    src/backend/storage/ipc/ipc.c
    src/backend/storage/ipc/ipci.c
    src/backend/storage/ipc/pmsignal.c
    src/backend/storage/ipc/shmem.c
    src/backend/storage/ipc/shmqueue.c
    src/backend/storage/ipc/sinval.c
    src/backend/storage/ipc/sinvaladt.c
    src/backend/storage/large_object/Makefile
    src/backend/storage/large_object/inv_api.c
    src/backend/storage/lmgr/Makefile
    src/backend/storage/lmgr/README
    src/backend/storage/lmgr/deadlock.c
    src/backend/storage/lmgr/lmgr.c
    src/backend/storage/lmgr/lock.c
    src/backend/storage/lmgr/lwlock.c
    src/backend/storage/lmgr/proc.c
    src/backend/storage/lmgr/s_lock.c
    src/backend/storage/lmgr/spin.c
    src/backend/storage/page/Makefile
    src/backend/storage/page/bufpage.c
    src/backend/storage/page/itemptr.c
    src/backend/storage/smgr/Makefile
    src/backend/storage/smgr/README
    src/backend/storage/smgr/md.c
    src/backend/storage/smgr/mm.c
    src/backend/storage/smgr/smgr.c
    src/backend/storage/smgr/smgrtype.c
    src/backend/tcop/Makefile
    src/backend/tcop/dest.c
    src/backend/tcop/fastpath.c
    src/backend/tcop/postgres.c
    src/backend/tcop/pquery.c
    src/backend/tcop/utility.c
    src/backend/tioga/Arr_TgRecipe.h
    src/backend/tioga/Makefile
    src/backend/tioga/Varray.c
    src/backend/tioga/Varray.h
    src/backend/tioga/tgRecipe.c
    src/backend/tioga/tgRecipe.h
    src/backend/utils/.cvsignore
    src/backend/utils/Gen_fmgrtab.sh
    src/backend/utils/Makefile
    src/backend/utils/adt/Makefile
    src/backend/utils/adt/acl.c
    src/backend/utils/adt/arrayfuncs.c
    src/backend/utils/adt/arrayutils.c
    src/backend/utils/adt/ascii.c
    src/backend/utils/adt/bool.c
    src/backend/utils/adt/cash.c
    src/backend/utils/adt/char.c
    src/backend/utils/adt/date.c
    src/backend/utils/adt/datetime.c
    src/backend/utils/adt/datum.c
    src/backend/utils/adt/encode.c
    src/backend/utils/adt/float.c
    src/backend/utils/adt/format_type.c
    src/backend/utils/adt/formatting.c
    src/backend/utils/adt/geo_ops.c
    src/backend/utils/adt/geo_selfuncs.c
    src/backend/utils/adt/inet_net_ntop.c
    src/backend/utils/adt/inet_net_pton.c
    src/backend/utils/adt/int.c
    src/backend/utils/adt/int8.c
    src/backend/utils/adt/like.c
    src/backend/utils/adt/like_match.c
    src/backend/utils/adt/mac.c
    src/backend/utils/adt/misc.c
    src/backend/utils/adt/nabstime.c
    src/backend/utils/adt/name.c
    src/backend/utils/adt/network.c
    src/backend/utils/adt/not_in.c
    src/backend/utils/adt/numeric.c
    src/backend/utils/adt/numutils.c
    src/backend/utils/adt/oid.c
    src/backend/utils/adt/oracle_compat.c
    src/backend/utils/adt/pg_locale.c
    src/backend/utils/adt/pg_lzcompress.c
    src/backend/utils/adt/pgstatfuncs.c
    src/backend/utils/adt/quote.c
    src/backend/utils/adt/regexp.c
    src/backend/utils/adt/regproc.c
    src/backend/utils/adt/ri_triggers.c
    src/backend/utils/adt/ruleutils.c
    src/backend/utils/adt/selfuncs.c
    src/backend/utils/adt/sets.c
    src/backend/utils/adt/tid.c
    src/backend/utils/adt/timestamp.c
    src/backend/utils/adt/varbit.c
    src/backend/utils/adt/varchar.c
    src/backend/utils/adt/varlena.c
    src/backend/utils/adt/version.c
    src/backend/utils/cache/Makefile
    src/backend/utils/cache/catcache.c
    src/backend/utils/cache/fcache.c
    src/backend/utils/cache/inval.c
    src/backend/utils/cache/lsyscache.c
    src/backend/utils/cache/relcache.c
    src/backend/utils/cache/syscache.c
    src/backend/utils/error/Makefile
    src/backend/utils/error/assert.c
    src/backend/utils/error/elog.c
    src/backend/utils/error/exc.c
    src/backend/utils/error/excabort.c
    src/backend/utils/error/excid.c
    src/backend/utils/error/format.c
    src/backend/utils/fmgr/Makefile
    src/backend/utils/fmgr/README
    src/backend/utils/fmgr/dfmgr.c
    src/backend/utils/fmgr/fmgr.c
    src/backend/utils/hash/Makefile
    src/backend/utils/hash/dynahash.c
    src/backend/utils/hash/hashfn.c
    src/backend/utils/hash/pg_crc.c
    src/backend/utils/init/Makefile
    src/backend/utils/init/findbe.c
    src/backend/utils/init/globals.c
    src/backend/utils/init/miscinit.c
    src/backend/utils/init/postinit.c
    src/backend/utils/mb/Makefile
    src/backend/utils/mb/README
    src/backend/utils/mb/Unicode/ISO10646-GB18030.TXT
    src/backend/utils/mb/Unicode/Makefile
    src/backend/utils/mb/Unicode/UCS_to_8859.pl
    src/backend/utils/mb/Unicode/UCS_to_BIG5.pl
    src/backend/utils/mb/Unicode/UCS_to_EUC_CN.pl
    src/backend/utils/mb/Unicode/UCS_to_EUC_JP.pl
    src/backend/utils/mb/Unicode/UCS_to_EUC_KR.pl
    src/backend/utils/mb/Unicode/UCS_to_EUC_TW.pl
    src/backend/utils/mb/Unicode/UCS_to_GB18030.pl
    src/backend/utils/mb/Unicode/UCS_to_GBK.pl
    src/backend/utils/mb/Unicode/UCS_to_JOHAB.pl
    src/backend/utils/mb/Unicode/UCS_to_SJIS.pl
    src/backend/utils/mb/Unicode/UCS_to_UHC.pl
    src/backend/utils/mb/Unicode/UCS_to_WIN874.pl
    src/backend/utils/mb/Unicode/UCS_to_WINX.pl
    src/backend/utils/mb/Unicode/UCS_to_cyrillic.pl
    src/backend/utils/mb/Unicode/alt_to_utf8.map
    src/backend/utils/mb/Unicode/big5_to_utf8.map
    src/backend/utils/mb/Unicode/euc_cn_to_utf8.map
    src/backend/utils/mb/Unicode/euc_jp_to_utf8.map
    src/backend/utils/mb/Unicode/euc_kr_to_utf8.map
    src/backend/utils/mb/Unicode/euc_tw_to_utf8.map
    src/backend/utils/mb/Unicode/gb18030_to_utf8.map
    src/backend/utils/mb/Unicode/gbk_to_utf8.map
    src/backend/utils/mb/Unicode/iso8859_10_to_utf8.map
    src/backend/utils/mb/Unicode/iso8859_13_to_utf8.map
    src/backend/utils/mb/Unicode/iso8859_14_to_utf8.map
    src/backend/utils/mb/Unicode/iso8859_15_to_utf8.map
    src/backend/utils/mb/Unicode/iso8859_16_to_utf8.map
    src/backend/utils/mb/Unicode/iso8859_2_to_utf8.map
    src/backend/utils/mb/Unicode/iso8859_3_to_utf8.map
    src/backend/utils/mb/Unicode/iso8859_4_to_utf8.map
    src/backend/utils/mb/Unicode/iso8859_5_to_utf8.map
    src/backend/utils/mb/Unicode/iso8859_6_to_utf8.map
    src/backend/utils/mb/Unicode/iso8859_7_to_utf8.map
    src/backend/utils/mb/Unicode/iso8859_8_to_utf8.map
    src/backend/utils/mb/Unicode/iso8859_9_to_utf8.map
    src/backend/utils/mb/Unicode/johab_to_utf8.map
    src/backend/utils/mb/Unicode/koi8r_to_utf8.map
    src/backend/utils/mb/Unicode/sjis_to_utf8.map
    src/backend/utils/mb/Unicode/tcvn_to_utf8.map
    src/backend/utils/mb/Unicode/ucs2utf.pl
    src/backend/utils/mb/Unicode/uhc_to_utf8.map
    src/backend/utils/mb/Unicode/utf8_to_alt.map
    src/backend/utils/mb/Unicode/utf8_to_big5.map
    src/backend/utils/mb/Unicode/utf8_to_euc_cn.map
    src/backend/utils/mb/Unicode/utf8_to_euc_jp.map
    src/backend/utils/mb/Unicode/utf8_to_euc_kr.map
    src/backend/utils/mb/Unicode/utf8_to_euc_tw.map
    src/backend/utils/mb/Unicode/utf8_to_gb18030.map
    src/backend/utils/mb/Unicode/utf8_to_gbk.map
    src/backend/utils/mb/Unicode/utf8_to_iso8859_10.map
    src/backend/utils/mb/Unicode/utf8_to_iso8859_13.map
    src/backend/utils/mb/Unicode/utf8_to_iso8859_14.map
    src/backend/utils/mb/Unicode/utf8_to_iso8859_15.map
    src/backend/utils/mb/Unicode/utf8_to_iso8859_16.map
    src/backend/utils/mb/Unicode/utf8_to_iso8859_2.map
    src/backend/utils/mb/Unicode/utf8_to_iso8859_3.map
    src/backend/utils/mb/Unicode/utf8_to_iso8859_4.map
    src/backend/utils/mb/Unicode/utf8_to_iso8859_5.map
    src/backend/utils/mb/Unicode/utf8_to_iso8859_6.map
    src/backend/utils/mb/Unicode/utf8_to_iso8859_7.map
    src/backend/utils/mb/Unicode/utf8_to_iso8859_8.map
    src/backend/utils/mb/Unicode/utf8_to_iso8859_9.map
    src/backend/utils/mb/Unicode/utf8_to_johab.map
    src/backend/utils/mb/Unicode/utf8_to_koi8r.map
    src/backend/utils/mb/Unicode/utf8_to_sjis.map
    src/backend/utils/mb/Unicode/utf8_to_tcvn.map
    src/backend/utils/mb/Unicode/utf8_to_uhc.map
    src/backend/utils/mb/Unicode/utf8_to_win1250.map
    src/backend/utils/mb/Unicode/utf8_to_win1251.map
    src/backend/utils/mb/Unicode/utf8_to_win1256.map
    src/backend/utils/mb/Unicode/utf8_to_win874.map
    src/backend/utils/mb/Unicode/win1250_to_utf8.map
    src/backend/utils/mb/Unicode/win1251_to_utf8.map
    src/backend/utils/mb/Unicode/win1256_to_utf8.map
    src/backend/utils/mb/Unicode/win874_to_utf8.map
    src/backend/utils/mb/alt.c
    src/backend/utils/mb/big5.c
    src/backend/utils/mb/conv.c
    src/backend/utils/mb/encnames.c
    src/backend/utils/mb/iso.c
    src/backend/utils/mb/mbutils.c
    src/backend/utils/mb/sjis.map
    src/backend/utils/mb/wchar.c
    src/backend/utils/mb/win.c
    src/backend/utils/mb/win1251.c
    src/backend/utils/mb/wstrcmp.c
    src/backend/utils/mb/wstrncmp.c
    src/backend/utils/misc/.cvsignore
    src/backend/utils/misc/Makefile
    src/backend/utils/misc/README
    src/backend/utils/misc/database.c
    src/backend/utils/misc/guc-file.l
    src/backend/utils/misc/guc.c
    src/backend/utils/misc/postgresql.conf.sample
    src/backend/utils/misc/ps_status.c
    src/backend/utils/misc/superuser.c
    src/backend/utils/mmgr/Makefile
    src/backend/utils/mmgr/README
    src/backend/utils/mmgr/aset.c
    src/backend/utils/mmgr/mcxt.c
    src/backend/utils/mmgr/portalmem.c
    src/backend/utils/sort/Makefile
    src/backend/utils/sort/logtape.c
    src/backend/utils/sort/tuplesort.c
    src/backend/utils/sort/tuplestore.c
    src/backend/utils/time/Makefile
    src/backend/utils/time/tqual.c
    src/bin/Makefile
    src/bin/initdb/Makefile
    src/bin/initdb/initdb.sh
    src/bin/initlocation/Makefile
    src/bin/initlocation/initlocation.sh
    src/bin/ipcclean/Makefile
    src/bin/ipcclean/ipcclean.sh
    src/bin/pg_config/Makefile
    src/bin/pg_config/pg_config.sh
    src/bin/pg_ctl/Makefile
    src/bin/pg_ctl/pg_ctl.sh
    src/bin/pg_dump/Makefile
    src/bin/pg_dump/README
    src/bin/pg_dump/common.c
    src/bin/pg_dump/cs.po
    src/bin/pg_dump/de.po
    src/bin/pg_dump/nls.mk
    src/bin/pg_dump/pg_backup.h
    src/bin/pg_dump/pg_backup_archiver.c
    src/bin/pg_dump/pg_backup_archiver.h
    src/bin/pg_dump/pg_backup_custom.c
    src/bin/pg_dump/pg_backup_db.c
    src/bin/pg_dump/pg_backup_db.h
    src/bin/pg_dump/pg_backup_files.c
    src/bin/pg_dump/pg_backup_null.c
    src/bin/pg_dump/pg_backup_tar.c
    src/bin/pg_dump/pg_backup_tar.h
    src/bin/pg_dump/pg_dump.c
    src/bin/pg_dump/pg_dump.h
    src/bin/pg_dump/pg_dumpall.sh
    src/bin/pg_dump/pg_restore.c
    src/bin/pg_dump/ru.po
    src/bin/pg_dump/sv.po
    src/bin/pg_dump/zh_CN.po
    src/bin/pg_dump/zh_TW.po
    src/bin/pg_encoding/Makefile
    src/bin/pg_encoding/pg_encoding.c
    src/bin/pg_id/Makefile
    src/bin/pg_id/pg_id.c
    src/bin/pgaccess/Makefile
    src/bin/pgaccess/README
    src/bin/pgaccess/copyright.html
    src/bin/pgaccess/demo/formdemo.sql
    src/bin/pgaccess/doc/html/a_right.gif
    src/bin/pgaccess/doc/html/addindex.gif
    src/bin/pgaccess/doc/html/api.html
    src/bin/pgaccess/doc/html/ball.gif
    src/bin/pgaccess/doc/html/contents.html
    src/bin/pgaccess/doc/html/copyright.html
    src/bin/pgaccess/doc/html/documentation.html
    src/bin/pgaccess/doc/html/download.html
    src/bin/pgaccess/doc/html/faq.html
    src/bin/pgaccess/doc/html/features.html
    src/bin/pgaccess/doc/html/formdemo.sql
    src/bin/pgaccess/doc/html/forms.gif
    src/bin/pgaccess/doc/html/forms.html
    src/bin/pgaccess/doc/html/function.gif
    src/bin/pgaccess/doc/html/help.gif
    src/bin/pgaccess/doc/html/index.html
    src/bin/pgaccess/doc/html/irix.html
    src/bin/pgaccess/doc/html/linux1.gif
    src/bin/pgaccess/doc/html/maillist.html
    src/bin/pgaccess/doc/html/main.html
    src/bin/pgaccess/doc/html/mainwindow.gif
    src/bin/pgaccess/doc/html/newtable.gif
    src/bin/pgaccess/doc/html/newuser.gif
    src/bin/pgaccess/doc/html/old_index.html
    src/bin/pgaccess/doc/html/permissions.gif
    src/bin/pgaccess/doc/html/pg93patch.html
    src/bin/pgaccess/doc/html/pga-rad.html
    src/bin/pgaccess/doc/html/qbtclet.html
    src/bin/pgaccess/doc/html/qbtclet.tcl
    src/bin/pgaccess/doc/html/screenshots.html
    src/bin/pgaccess/doc/html/specialchars.html
    src/bin/pgaccess/doc/html/todo.html
    src/bin/pgaccess/doc/html/tutorial/addref.jpg
    src/bin/pgaccess/doc/html/tutorial/altern_q.jpg
    src/bin/pgaccess/doc/html/tutorial/altern_v.jpg
    src/bin/pgaccess/doc/html/tutorial/copyright.html
    src/bin/pgaccess/doc/html/tutorial/index.html
    src/bin/pgaccess/doc/html/tutorial/intro.html
    src/bin/pgaccess/doc/html/tutorial/irix.html
    src/bin/pgaccess/doc/html/tutorial/newref.txt
    src/bin/pgaccess/doc/html/tutorial/newtable.jpg
    src/bin/pgaccess/doc/html/tutorial/newtable.tga
    src/bin/pgaccess/doc/html/tutorial/problems.html
    src/bin/pgaccess/doc/html/tutorial/screen1.jpg
    src/bin/pgaccess/doc/html/tutorial/sel_tbl.jpg
    src/bin/pgaccess/doc/html/tutorial/start.html
    src/bin/pgaccess/doc/html/tutorial/tut.html
    src/bin/pgaccess/doc/html/tutorial/tut_edit.html
    src/bin/pgaccess/doc/html/tutorial/tut_new.html
    src/bin/pgaccess/doc/html/tutorial/tut_sel1.html
    src/bin/pgaccess/doc/html/tutorial/tut_user.html
    src/bin/pgaccess/doc/html/vdesigner.gif
    src/bin/pgaccess/doc/html/whatsnew.html
    src/bin/pgaccess/doc/html/win32.html
    src/bin/pgaccess/images/icon_button.gif
    src/bin/pgaccess/images/icon_checkbutton.gif
    src/bin/pgaccess/images/icon_entry.gif
    src/bin/pgaccess/images/icon_frame.gif
    src/bin/pgaccess/images/icon_label.gif
    src/bin/pgaccess/images/icon_listbox.gif
    src/bin/pgaccess/images/icon_query.gif
    src/bin/pgaccess/images/icon_radiobutton.gif
    src/bin/pgaccess/images/icon_text.gif
    src/bin/pgaccess/lib/database.tcl
    src/bin/pgaccess/lib/forms.tcl
    src/bin/pgaccess/lib/functions.tcl
    src/bin/pgaccess/lib/help/abort.hlp
    src/bin/pgaccess/lib/help/add_records.hlp
    src/bin/pgaccess/lib/help/alter_table.hlp
    src/bin/pgaccess/lib/help/alter_user.hlp
    src/bin/pgaccess/lib/help/author.hlp
    src/bin/pgaccess/lib/help/begin.hlp
    src/bin/pgaccess/lib/help/close.hlp
    src/bin/pgaccess/lib/help/cluster.hlp
    src/bin/pgaccess/lib/help/commit.hlp
    src/bin/pgaccess/lib/help/copy.hlp
    src/bin/pgaccess/lib/help/copyrights.hlp
    src/bin/pgaccess/lib/help/create_aggregate.hlp
    src/bin/pgaccess/lib/help/create_database.hlp
    src/bin/pgaccess/lib/help/create_function.hlp
    src/bin/pgaccess/lib/help/create_index.hlp
    src/bin/pgaccess/lib/help/create_language.hlp
    src/bin/pgaccess/lib/help/create_operator.hlp
    src/bin/pgaccess/lib/help/create_rule.hlp
    src/bin/pgaccess/lib/help/create_sequence.hlp
    src/bin/pgaccess/lib/help/create_table.hlp
    src/bin/pgaccess/lib/help/create_table_as.hlp
    src/bin/pgaccess/lib/help/create_trigger.hlp
    src/bin/pgaccess/lib/help/create_type.hlp
    src/bin/pgaccess/lib/help/create_user.hlp
    src/bin/pgaccess/lib/help/create_view.hlp
    src/bin/pgaccess/lib/help/data_types.hlp
    src/bin/pgaccess/lib/help/datefunc.hlp
    src/bin/pgaccess/lib/help/declare.hlp
    src/bin/pgaccess/lib/help/delete.hlp
    src/bin/pgaccess/lib/help/drop_aggregate.hlp
    src/bin/pgaccess/lib/help/drop_database.hlp
    src/bin/pgaccess/lib/help/drop_function.hlp
    src/bin/pgaccess/lib/help/drop_index.hlp
    src/bin/pgaccess/lib/help/drop_language.hlp
    src/bin/pgaccess/lib/help/drop_operator.hlp
    src/bin/pgaccess/lib/help/drop_rule.hlp
    src/bin/pgaccess/lib/help/drop_sequence.hlp
    src/bin/pgaccess/lib/help/drop_table.hlp
    src/bin/pgaccess/lib/help/drop_trigger.hlp
    src/bin/pgaccess/lib/help/drop_type.hlp
    src/bin/pgaccess/lib/help/drop_user.hlp
    src/bin/pgaccess/lib/help/drop_view.hlp
    src/bin/pgaccess/lib/help/explain.hlp
    src/bin/pgaccess/lib/help/fetch.hlp
    src/bin/pgaccess/lib/help/form_design.hlp
    src/bin/pgaccess/lib/help/forms.hlp
    src/bin/pgaccess/lib/help/functions.hlp
    src/bin/pgaccess/lib/help/geomfunc.hlp
    src/bin/pgaccess/lib/help/grant.hlp
    src/bin/pgaccess/lib/help/history.hlp
    src/bin/pgaccess/lib/help/index.hlp
    src/bin/pgaccess/lib/help/inheritance.hlp
    src/bin/pgaccess/lib/help/insert.hlp
    src/bin/pgaccess/lib/help/ipv4func.hlp
    src/bin/pgaccess/lib/help/isolation.hlp
    src/bin/pgaccess/lib/help/keywords.hlp
    src/bin/pgaccess/lib/help/listen.hlp
    src/bin/pgaccess/lib/help/load.hlp
    src/bin/pgaccess/lib/help/lock.hlp
    src/bin/pgaccess/lib/help/mathfunc.hlp
    src/bin/pgaccess/lib/help/move.hlp
    src/bin/pgaccess/lib/help/mvcc.hlp
    src/bin/pgaccess/lib/help/new_query.hlp
    src/bin/pgaccess/lib/help/new_table.hlp
    src/bin/pgaccess/lib/help/notify.hlp
    src/bin/pgaccess/lib/help/open_query.hlp
    src/bin/pgaccess/lib/help/open_table.hlp
    src/bin/pgaccess/lib/help/pgfunctions.hlp
    src/bin/pgaccess/lib/help/postgresql.hlp
    src/bin/pgaccess/lib/help/queries.hlp
    src/bin/pgaccess/lib/help/reports.hlp
    src/bin/pgaccess/lib/help/reset.hlp
    src/bin/pgaccess/lib/help/revoke.hlp
    src/bin/pgaccess/lib/help/rollback.hlp
    src/bin/pgaccess/lib/help/schema.hlp
    src/bin/pgaccess/lib/help/scripts.hlp
    src/bin/pgaccess/lib/help/select.hlp
    src/bin/pgaccess/lib/help/select_into.hlp
    src/bin/pgaccess/lib/help/sequences.hlp
    src/bin/pgaccess/lib/help/set.hlp
    src/bin/pgaccess/lib/help/show.hlp
    src/bin/pgaccess/lib/help/sql_guide.hlp
    src/bin/pgaccess/lib/help/sqlfunc.hlp
    src/bin/pgaccess/lib/help/stringfunc.hlp
    src/bin/pgaccess/lib/help/tables.hlp
    src/bin/pgaccess/lib/help/unlisten.hlp
    src/bin/pgaccess/lib/help/update.hlp
    src/bin/pgaccess/lib/help/users.hlp
    src/bin/pgaccess/lib/help/vacuum.hlp
    src/bin/pgaccess/lib/help/view_table_structure.hlp
    src/bin/pgaccess/lib/help/views.hlp
    src/bin/pgaccess/lib/help/visual_designer.hlp
    src/bin/pgaccess/lib/help/y2k.hlp
    src/bin/pgaccess/lib/help.tcl
    src/bin/pgaccess/lib/languages/chinese_big5
    src/bin/pgaccess/lib/languages/chinese_gb
    src/bin/pgaccess/lib/languages/czech
    src/bin/pgaccess/lib/languages/deutsch
    src/bin/pgaccess/lib/languages/euskara
    src/bin/pgaccess/lib/languages/francais
    src/bin/pgaccess/lib/languages/italiano
    src/bin/pgaccess/lib/languages/japanese
    src/bin/pgaccess/lib/languages/magyar
    src/bin/pgaccess/lib/languages/nederlands
    src/bin/pgaccess/lib/languages/portugues
    src/bin/pgaccess/lib/languages/romana
    src/bin/pgaccess/lib/languages/russian.koi8r
    src/bin/pgaccess/lib/languages/russian_win
    src/bin/pgaccess/lib/languages/spanish
    src/bin/pgaccess/lib/mainlib.tcl
    src/bin/pgaccess/lib/preferences.tcl
    src/bin/pgaccess/lib/queries.tcl
    src/bin/pgaccess/lib/reports.tcl
    src/bin/pgaccess/lib/schema.tcl
    src/bin/pgaccess/lib/scripts.tcl
    src/bin/pgaccess/lib/sequences.tcl
    src/bin/pgaccess/lib/tables.tcl
    src/bin/pgaccess/lib/users.tcl
    src/bin/pgaccess/lib/views.tcl
    src/bin/pgaccess/lib/visualqb.tcl
    src/bin/pgaccess/main.tcl
    src/bin/pgaccess/pgaccess.sh
    src/bin/pgtclsh/Makefile
    src/bin/pgtclsh/README
    src/bin/pgtclsh/pgtclAppInit.c
    src/bin/pgtclsh/pgtclUtils.tcl
    src/bin/pgtclsh/pgtkAppInit.c
    src/bin/pgtclsh/updateStats.tcl
    src/bin/psql/.cvsignore
    src/bin/psql/Makefile
    src/bin/psql/command.c
    src/bin/psql/command.h
    src/bin/psql/common.c
    src/bin/psql/common.h
    src/bin/psql/copy.c
    src/bin/psql/copy.h
    src/bin/psql/create_help.pl
    src/bin/psql/cs.po
    src/bin/psql/de.po
    src/bin/psql/describe.c
    src/bin/psql/describe.h
    src/bin/psql/fr.po
    src/bin/psql/help.c
    src/bin/psql/help.h
    src/bin/psql/input.c
    src/bin/psql/input.h
    src/bin/psql/large_obj.c
    src/bin/psql/large_obj.h
    src/bin/psql/mainloop.c
    src/bin/psql/mainloop.h
    src/bin/psql/mbprint.c
    src/bin/psql/mbprint.h
    src/bin/psql/nls.mk
    src/bin/psql/print.c
    src/bin/psql/print.h
    src/bin/psql/prompt.c
    src/bin/psql/prompt.h
    src/bin/psql/ru.po
    src/bin/psql/settings.h
    src/bin/psql/startup.c
    src/bin/psql/stringutils.c
    src/bin/psql/stringutils.h
    src/bin/psql/sv.po
    src/bin/psql/tab-complete.c
    src/bin/psql/tab-complete.h
    src/bin/psql/variables.c
    src/bin/psql/variables.h
    src/bin/psql/win32.mak
    src/bin/psql/zh_CN.po
    src/bin/psql/zh_TW.po
    src/bin/scripts/Makefile
    src/bin/scripts/createdb
    src/bin/scripts/createlang.sh
    src/bin/scripts/createuser
    src/bin/scripts/dropdb
    src/bin/scripts/droplang
    src/bin/scripts/dropuser
    src/bin/scripts/vacuumdb
    src/corba/CosQuery.idl
    src/corba/CosQueryCollection.idl
    src/corba/pgsql.idl
    src/corba/pgsql_int.idl
    src/corba/server.cc
    src/data/charset.conf
    src/data/isocz-wincz.tab
    src/data/koi-alt.tab
    src/data/koi-iso.tab
    src/data/koi-koi.tab
    src/data/koi-mac.tab
    src/data/koi-win.tab
    src/include/Makefile
    src/include/access/attnum.h
    src/include/access/clog.h
    src/include/access/genam.h
    src/include/access/gist.h
    src/include/access/gistscan.h
    src/include/access/hash.h
    src/include/access/heapam.h
    src/include/access/hio.h
    src/include/access/htup.h
    src/include/access/ibit.h
    src/include/access/iqual.h
    src/include/access/istrat.h
    src/include/access/itup.h
    src/include/access/nbtree.h
    src/include/access/printtup.h
    src/include/access/relscan.h
    src/include/access/rmgr.h
    src/include/access/rtree.h
    src/include/access/rtscan.h
    src/include/access/sdir.h
    src/include/access/skey.h
    src/include/access/strat.h
    src/include/access/transam.h
    src/include/access/tupdesc.h
    src/include/access/tupmacs.h
    src/include/access/tuptoaster.h
    src/include/access/valid.h
    src/include/access/xact.h
    src/include/access/xlog.h
    src/include/access/xlogdefs.h
    src/include/access/xlogutils.h
    src/include/bootstrap/bootstrap.h
    src/include/c.h
    src/include/catalog/catalog.h
    src/include/catalog/catname.h
    src/include/catalog/catversion.h
    src/include/catalog/duplicate_oids
    src/include/catalog/heap.h
    src/include/catalog/index.h
    src/include/catalog/indexing.h
    src/include/catalog/namespace.h
    src/include/catalog/pg_aggregate.h
    src/include/catalog/pg_am.h
    src/include/catalog/pg_amop.h
    src/include/catalog/pg_amproc.h
    src/include/catalog/pg_attrdef.h
    src/include/catalog/pg_attribute.h
    src/include/catalog/pg_class.h
    src/include/catalog/pg_control.h
    src/include/catalog/pg_database.h
    src/include/catalog/pg_description.h
    src/include/catalog/pg_group.h
    src/include/catalog/pg_index.h
    src/include/catalog/pg_inherits.h
    src/include/catalog/pg_language.h
    src/include/catalog/pg_largeobject.h
    src/include/catalog/pg_listener.h
    src/include/catalog/pg_namespace.h
    src/include/catalog/pg_opclass.h
    src/include/catalog/pg_operator.h
    src/include/catalog/pg_proc.h
    src/include/catalog/pg_relcheck.h
    src/include/catalog/pg_rewrite.h
    src/include/catalog/pg_shadow.h
    src/include/catalog/pg_statistic.h
    src/include/catalog/pg_trigger.h
    src/include/catalog/pg_type.h
    src/include/catalog/pg_version.h
    src/include/catalog/unused_oids
    src/include/commands/async.h
    src/include/commands/cluster.h
    src/include/commands/comment.h
    src/include/commands/copy.h
    src/include/commands/dbcommands.h
    src/include/commands/defrem.h
    src/include/commands/explain.h
    src/include/commands/lockcmds.h
    src/include/commands/portalcmds.h
    src/include/commands/proclang.h
    src/include/commands/schemacmds.h
    src/include/commands/sequence.h
    src/include/commands/tablecmds.h
    src/include/commands/trigger.h
    src/include/commands/user.h
    src/include/commands/vacuum.h
    src/include/commands/variable.h
    src/include/commands/version.h
    src/include/commands/view.h
    src/include/executor/execdebug.h
    src/include/executor/execdefs.h
    src/include/executor/execdesc.h
    src/include/executor/executor.h
    src/include/executor/functions.h
    src/include/executor/hashjoin.h
    src/include/executor/instrument.h
    src/include/executor/nodeAgg.h
    src/include/executor/nodeAppend.h
    src/include/executor/nodeFunctionscan.h
    src/include/executor/nodeGroup.h
    src/include/executor/nodeHash.h
    src/include/executor/nodeHashjoin.h
    src/include/executor/nodeIndexscan.h
    src/include/executor/nodeLimit.h
    src/include/executor/nodeMaterial.h
    src/include/executor/nodeMergejoin.h
    src/include/executor/nodeNestloop.h
    src/include/executor/nodeResult.h
    src/include/executor/nodeSeqscan.h
    src/include/executor/nodeSetOp.h
    src/include/executor/nodeSort.h
    src/include/executor/nodeSubplan.h
    src/include/executor/nodeSubqueryscan.h
    src/include/executor/nodeTidscan.h
    src/include/executor/nodeUnique.h
    src/include/executor/spi.h
    src/include/executor/spi_priv.h
    src/include/executor/tuptable.h
    src/include/fmgr.h
    src/include/lib/dllist.h
    src/include/lib/lispsort.h
    src/include/lib/stringinfo.h
    src/include/libpq/auth.h
    src/include/libpq/be-fsstubs.h
    src/include/libpq/crypt.h
    src/include/libpq/hba.h
    src/include/libpq/libpq-be.h
    src/include/libpq/libpq-fs.h
    src/include/libpq/libpq.h
    src/include/libpq/password.h
    src/include/libpq/pqcomm.h
    src/include/libpq/pqformat.h
    src/include/libpq/pqsignal.h
    src/include/mb/pg_wchar.h
    src/include/miscadmin.h
    src/include/nodes/execnodes.h
    src/include/nodes/makefuncs.h
    src/include/nodes/memnodes.h
    src/include/nodes/nodeFuncs.h
    src/include/nodes/nodes.h
    src/include/nodes/params.h
    src/include/nodes/parsenodes.h
    src/include/nodes/pg_list.h
    src/include/nodes/plannodes.h
    src/include/nodes/primnodes.h
    src/include/nodes/print.h
    src/include/nodes/readfuncs.h
    src/include/nodes/relation.h
    src/include/optimizer/_deadcode/xfunc.h
    src/include/optimizer/clauses.h
    src/include/optimizer/cost.h
    src/include/optimizer/geqo.h
    src/include/optimizer/geqo_copy.h
    src/include/optimizer/geqo_gene.h
    src/include/optimizer/geqo_misc.h
    src/include/optimizer/geqo_mutation.h
    src/include/optimizer/geqo_pool.h
    src/include/optimizer/geqo_random.h
    src/include/optimizer/geqo_recombination.h
    src/include/optimizer/geqo_selection.h
    src/include/optimizer/joininfo.h
    src/include/optimizer/pathnode.h
    src/include/optimizer/paths.h
    src/include/optimizer/plancat.h
    src/include/optimizer/planmain.h
    src/include/optimizer/planner.h
    src/include/optimizer/prep.h
    src/include/optimizer/restrictinfo.h
    src/include/optimizer/subselect.h
    src/include/optimizer/tlist.h
    src/include/optimizer/var.h
    src/include/parser/analyze.h
    src/include/parser/gramparse.h
    src/include/parser/keywords.h
    src/include/parser/parse_agg.h
    src/include/parser/parse_clause.h
    src/include/parser/parse_coerce.h
    src/include/parser/parse_expr.h
    src/include/parser/parse_func.h
    src/include/parser/parse_node.h
    src/include/parser/parse_oper.h
    src/include/parser/parse_relation.h
    src/include/parser/parse_target.h
    src/include/parser/parse_type.h
    src/include/parser/parser.h
    src/include/parser/parsetree.h
    src/include/parser/scansup.h
    src/include/pg_config.h.in
    src/include/pg_config.h.win32
    src/include/pgstat.h
    src/include/port/aix.h
    src/include/port/beos.h
    src/include/port/bsdi.h
    src/include/port/darwin.h
    src/include/port/dgux.h
    src/include/port/freebsd.h
    src/include/port/hpux.h
    src/include/port/irix5.h
    src/include/port/linux.h
    src/include/port/netbsd.h
    src/include/port/nextstep.h
    src/include/port/openbsd.h
    src/include/port/osf.h
    src/include/port/qnx4.h
    src/include/port/sco.h
    src/include/port/solaris.h
    src/include/port/sunos4.h
    src/include/port/svr4.h
    src/include/port/ultrix4.h
    src/include/port/univel.h
    src/include/port/unixware.h
    src/include/port/win.h
    src/include/port/win32.h
    src/include/postgres.h
    src/include/postgres_ext.h
    src/include/postgres_fe.h
    src/include/regex/cclass.h
    src/include/regex/cname.h
    src/include/regex/regex.h
    src/include/regex/regex2.h
    src/include/regex/utils.h
    src/include/rewrite/prs2lock.h
    src/include/rewrite/rewriteDefine.h
    src/include/rewrite/rewriteHandler.h
    src/include/rewrite/rewriteManip.h
    src/include/rewrite/rewriteRemove.h
    src/include/rewrite/rewriteSupport.h
    src/include/rusagestub.h
    src/include/storage/backendid.h
    src/include/storage/block.h
    src/include/storage/buf.h
    src/include/storage/buf_internals.h
    src/include/storage/buffile.h
    src/include/storage/bufmgr.h
    src/include/storage/bufpage.h
    src/include/storage/fd.h
    src/include/storage/freespace.h
    src/include/storage/ipc.h
    src/include/storage/item.h
    src/include/storage/itemid.h
    src/include/storage/itempos.h
    src/include/storage/itemptr.h
    src/include/storage/large_object.h
    src/include/storage/lmgr.h
    src/include/storage/lock.h
    src/include/storage/lwlock.h
    src/include/storage/off.h
    src/include/storage/page.h
    src/include/storage/pg_sema.h
    src/include/storage/pg_shmem.h
    src/include/storage/pmsignal.h
    src/include/storage/pos.h
    src/include/storage/proc.h
    src/include/storage/relfilenode.h
    src/include/storage/s_lock.h
    src/include/storage/shmem.h
    src/include/storage/sinval.h
    src/include/storage/sinvaladt.h
    src/include/storage/smgr.h
    src/include/storage/spin.h
    src/include/strdup.h
    src/include/tcop/dest.h
    src/include/tcop/fastpath.h
    src/include/tcop/pquery.h
    src/include/tcop/tcopdebug.h
    src/include/tcop/tcopprot.h
    src/include/tcop/utility.h
    src/include/utils/acl.h
    src/include/utils/array.h
    src/include/utils/ascii.h
    src/include/utils/bit.h
    src/include/utils/builtins.h
    src/include/utils/cash.h
    src/include/utils/catcache.h
    src/include/utils/date.h
    src/include/utils/datetime.h
    src/include/utils/datum.h
    src/include/utils/dynahash.h
    src/include/utils/dynamic_loader.h
    src/include/utils/elog.h
    src/include/utils/exc.h
    src/include/utils/excid.h
    src/include/utils/fcache.h
    src/include/utils/fmgrtab.h
    src/include/utils/formatting.h
    src/include/utils/geo_decls.h
    src/include/utils/guc.h
    src/include/utils/hsearch.h
    src/include/utils/inet.h
    src/include/utils/int8.h
    src/include/utils/inval.h
    src/include/utils/logtape.h
    src/include/utils/lsyscache.h
    src/include/utils/memutils.h
    src/include/utils/nabstime.h
    src/include/utils/numeric.h
    src/include/utils/palloc.h
    src/include/utils/pg_crc.h
    src/include/utils/pg_locale.h
    src/include/utils/pg_lzcompress.h
    src/include/utils/portal.h
    src/include/utils/ps_status.h
    src/include/utils/rel.h
    src/include/utils/relcache.h
    src/include/utils/selfuncs.h
    src/include/utils/sets.h
    src/include/utils/syscache.h
    src/include/utils/timestamp.h
    src/include/utils/tqual.h
    src/include/utils/tuplesort.h
    src/include/utils/tuplestore.h
    src/include/utils/varbit.h
    src/interfaces/Makefile
    src/interfaces/cli/example1.c
    src/interfaces/cli/example2.c
    src/interfaces/cli/sqlcli.h
    src/interfaces/jdbc/CHANGELOG
    src/interfaces/jdbc/Implementation
    src/interfaces/jdbc/Makefile
    src/interfaces/jdbc/README
    src/interfaces/jdbc/build.xml
    src/interfaces/jdbc/example/ImageViewer.java
    src/interfaces/jdbc/example/Unicode.java
    src/interfaces/jdbc/example/basic.java
    src/interfaces/jdbc/example/blobtest.java
    src/interfaces/jdbc/example/corba/StockClient.java
    src/interfaces/jdbc/example/corba/StockDB.java
    src/interfaces/jdbc/example/corba/StockDispenserImpl.java
    src/interfaces/jdbc/example/corba/StockItemImpl.java
    src/interfaces/jdbc/example/corba/StockServer.java
    src/interfaces/jdbc/example/corba/readme
    src/interfaces/jdbc/example/corba/stock.idl
    src/interfaces/jdbc/example/corba/stock.sql
    src/interfaces/jdbc/example/datestyle.java
    src/interfaces/jdbc/example/metadata.java
    src/interfaces/jdbc/example/psql.java
    src/interfaces/jdbc/example/threadsafe.java
    src/interfaces/jdbc/jdbc.jpx
    src/interfaces/jdbc/org/postgresql/Connection.java
    src/interfaces/jdbc/org/postgresql/Driver.java.in
    src/interfaces/jdbc/org/postgresql/Field.java
    src/interfaces/jdbc/org/postgresql/PG_Stream.java
    src/interfaces/jdbc/org/postgresql/PostgresqlDataSource.java
    src/interfaces/jdbc/org/postgresql/ResultSet.java
    src/interfaces/jdbc/org/postgresql/Statement.java
    src/interfaces/jdbc/org/postgresql/core/BytePoolDim1.java
    src/interfaces/jdbc/org/postgresql/core/BytePoolDim2.java
    src/interfaces/jdbc/org/postgresql/core/Encoding.java
    src/interfaces/jdbc/org/postgresql/core/MemoryPool.java
    src/interfaces/jdbc/org/postgresql/core/ObjectPool.java
    src/interfaces/jdbc/org/postgresql/core/QueryExecutor.java
    src/interfaces/jdbc/org/postgresql/core/SimpleObjectPool.java
    src/interfaces/jdbc/org/postgresql/core/StartupPacket.java
    src/interfaces/jdbc/org/postgresql/errors.properties
    src/interfaces/jdbc/org/postgresql/errors_de.properties
    src/interfaces/jdbc/org/postgresql/errors_fr.properties
    src/interfaces/jdbc/org/postgresql/errors_it.properties
    src/interfaces/jdbc/org/postgresql/errors_nl.properties
    src/interfaces/jdbc/org/postgresql/errors_zh_TW.properties
    src/interfaces/jdbc/org/postgresql/fastpath/Fastpath.java
    src/interfaces/jdbc/org/postgresql/fastpath/FastpathArg.java
    src/interfaces/jdbc/org/postgresql/geometric/PGbox.java
    src/interfaces/jdbc/org/postgresql/geometric/PGcircle.java
    src/interfaces/jdbc/org/postgresql/geometric/PGline.java
    src/interfaces/jdbc/org/postgresql/geometric/PGlseg.java
    src/interfaces/jdbc/org/postgresql/geometric/PGpath.java
    src/interfaces/jdbc/org/postgresql/geometric/PGpoint.java
    src/interfaces/jdbc/org/postgresql/geometric/PGpolygon.java
    src/interfaces/jdbc/org/postgresql/jdbc1/CallableStatement.java
    src/interfaces/jdbc/org/postgresql/jdbc1/Connection.java
    src/interfaces/jdbc/org/postgresql/jdbc1/DatabaseMetaData.java
    src/interfaces/jdbc/org/postgresql/jdbc1/PreparedStatement.java
    src/interfaces/jdbc/org/postgresql/jdbc1/ResultSet.java
    src/interfaces/jdbc/org/postgresql/jdbc1/ResultSetMetaData.java
    src/interfaces/jdbc/org/postgresql/jdbc1/Statement.java
    src/interfaces/jdbc/org/postgresql/jdbc2/Array.java
    src/interfaces/jdbc/org/postgresql/jdbc2/CallableStatement.java
    src/interfaces/jdbc/org/postgresql/jdbc2/Connection.java
    src/interfaces/jdbc/org/postgresql/jdbc2/DatabaseMetaData.java
    src/interfaces/jdbc/org/postgresql/jdbc2/PBatchUpdateException.java
    src/interfaces/jdbc/org/postgresql/jdbc2/PreparedStatement.java
    src/interfaces/jdbc/org/postgresql/jdbc2/ResultSet.java
    src/interfaces/jdbc/org/postgresql/jdbc2/ResultSetMetaData.java
    src/interfaces/jdbc/org/postgresql/jdbc2/Statement.java
    src/interfaces/jdbc/org/postgresql/jdbc2/UpdateableResultSet.java
    src/interfaces/jdbc/org/postgresql/largeobject/BlobInputStream.java
    src/interfaces/jdbc/org/postgresql/largeobject/BlobOutputStream.java
    src/interfaces/jdbc/org/postgresql/largeobject/LargeObject.java
    src/interfaces/jdbc/org/postgresql/largeobject/LargeObjectManager.java
    src/interfaces/jdbc/org/postgresql/largeobject/PGblob.java
    src/interfaces/jdbc/org/postgresql/largeobject/PGclob.java
    src/interfaces/jdbc/org/postgresql/test/JDBC2Tests.java
    src/interfaces/jdbc/org/postgresql/test/README
    src/interfaces/jdbc/org/postgresql/test/jdbc2/ANTTest.java
    src/interfaces/jdbc/org/postgresql/test/jdbc2/BatchExecuteTest.java
    src/interfaces/jdbc/org/postgresql/test/jdbc2/BlobTest.java
    src/interfaces/jdbc/org/postgresql/test/jdbc2/ConnectionTest.java
    src/interfaces/jdbc/org/postgresql/test/jdbc2/DatabaseMetaDataTest.java
    src/interfaces/jdbc/org/postgresql/test/jdbc2/DateTest.java
    src/interfaces/jdbc/org/postgresql/test/jdbc2/DriverTest.java
    src/interfaces/jdbc/org/postgresql/test/jdbc2/EncodingTest.java
    src/interfaces/jdbc/org/postgresql/test/jdbc2/JBuilderTest.java
    src/interfaces/jdbc/org/postgresql/test/jdbc2/MiscTest.java
    src/interfaces/jdbc/org/postgresql/test/jdbc2/ResultSetTest.java
    src/interfaces/jdbc/org/postgresql/test/jdbc2/TimeTest.java
    src/interfaces/jdbc/org/postgresql/test/jdbc2/TimestampTest.java
    src/interfaces/jdbc/org/postgresql/test/jdbc2/UpdateableResultTest.java
    src/interfaces/jdbc/org/postgresql/util/MD5Digest.java
    src/interfaces/jdbc/org/postgresql/util/MessageTranslator.java
    src/interfaces/jdbc/org/postgresql/util/PGbytea.java
    src/interfaces/jdbc/org/postgresql/util/PGmoney.java
    src/interfaces/jdbc/org/postgresql/util/PGobject.java
    src/interfaces/jdbc/org/postgresql/util/PGtokenizer.java
    src/interfaces/jdbc/org/postgresql/util/PSQLException.java
    src/interfaces/jdbc/org/postgresql/util/Serialize.java
    src/interfaces/jdbc/org/postgresql/util/UnixCrypt.java
    src/interfaces/jdbc/org/postgresql/xa/ClientConnection.java
    src/interfaces/jdbc/org/postgresql/xa/TwoPhaseConnection.java
    src/interfaces/jdbc/org/postgresql/xa/TxConnection.java
    src/interfaces/jdbc/org/postgresql/xa/XAConnectionImpl.java
    src/interfaces/jdbc/org/postgresql/xa/XADataSourceImpl.java
    src/interfaces/jdbc/utils/CheckVersion.java
    src/interfaces/jdbc/utils/buildDriver
    src/interfaces/jdbc/utils/changelog.pl
    src/interfaces/libpgeasy/Makefile
    src/interfaces/libpgeasy/README
    src/interfaces/libpgeasy/examples/Makefile
    src/interfaces/libpgeasy/examples/pginsert.c
    src/interfaces/libpgeasy/examples/pgmultiresult.c
    src/interfaces/libpgeasy/examples/pgnulltest.c
    src/interfaces/libpgeasy/examples/pgwordcount.c
    src/interfaces/libpgeasy/halt.c
    src/interfaces/libpgeasy/halt.h
    src/interfaces/libpgeasy/libpgeasy.c
    src/interfaces/libpgeasy/libpgeasy.h
    src/interfaces/libpgtcl/Makefile
    src/interfaces/libpgtcl/README
    src/interfaces/libpgtcl/libpgtcl.def
    src/interfaces/libpgtcl/libpgtcl.h
    src/interfaces/libpgtcl/pgtcl.c
    src/interfaces/libpgtcl/pgtclCmds.c
    src/interfaces/libpgtcl/pgtclCmds.h
    src/interfaces/libpgtcl/pgtclId.c
    src/interfaces/libpgtcl/pgtclId.h
    src/interfaces/libpgtcl/win32.mak
    src/interfaces/libpq/Makefile
    src/interfaces/libpq/README
    src/interfaces/libpq/cs.po
    src/interfaces/libpq/de.po
    src/interfaces/libpq/fe-auth.c
    src/interfaces/libpq/fe-auth.h
    src/interfaces/libpq/fe-connect.c
    src/interfaces/libpq/fe-exec.c
    src/interfaces/libpq/fe-lobj.c
    src/interfaces/libpq/fe-misc.c
    src/interfaces/libpq/fe-print.c
    src/interfaces/libpq/fe-secure.c
    src/interfaces/libpq/fr.po
    src/interfaces/libpq/libpq-fe.h
    src/interfaces/libpq/libpq-int.h
    src/interfaces/libpq/libpq.rc
    src/interfaces/libpq/libpqdll.c
    src/interfaces/libpq/libpqdll.def
    src/interfaces/libpq/nls.mk
    src/interfaces/libpq/pqexpbuffer.c
    src/interfaces/libpq/pqexpbuffer.h
    src/interfaces/libpq/pqsignal.c
    src/interfaces/libpq/pqsignal.h
    src/interfaces/libpq/ru.po
    src/interfaces/libpq/sv.po
    src/interfaces/libpq/win32.c
    src/interfaces/libpq/win32.h
    src/interfaces/libpq/win32.mak
    src/interfaces/libpq/zh_CN.po
    src/interfaces/libpq/zh_TW.po
    src/interfaces/libpq++/CHANGES
    src/interfaces/libpq++/Makefile
    src/interfaces/libpq++/README
    src/interfaces/libpq++/TODO
    src/interfaces/libpq++/examples/Makefile
    src/interfaces/libpq++/examples/testlibpq0.cc
    src/interfaces/libpq++/examples/testlibpq1.cc
    src/interfaces/libpq++/examples/testlibpq2.cc
    src/interfaces/libpq++/examples/testlibpq2.sql
    src/interfaces/libpq++/examples/testlibpq3.cc
    src/interfaces/libpq++/examples/testlibpq3.sql
    src/interfaces/libpq++/examples/testlibpq4.cc
    src/interfaces/libpq++/examples/testlibpq4.sql
    src/interfaces/libpq++/examples/testlibpq5.cc
    src/interfaces/libpq++/examples/testlibpq5.sql
    src/interfaces/libpq++/examples/testlibpq6.cc
    src/interfaces/libpq++/examples/testlo.cc
    src/interfaces/libpq++/libpq++.h
    src/interfaces/libpq++/libpq++dll.rc
    src/interfaces/libpq++/pgconnection.cc
    src/interfaces/libpq++/pgconnection.h
    src/interfaces/libpq++/pgcursordb.cc
    src/interfaces/libpq++/pgcursordb.h
    src/interfaces/libpq++/pgdatabase.cc
    src/interfaces/libpq++/pgdatabase.h
    src/interfaces/libpq++/pglobject.cc
    src/interfaces/libpq++/pglobject.h
    src/interfaces/libpq++/pgtransdb.cc
    src/interfaces/libpq++/pgtransdb.h
    src/interfaces/libpq++/win32.mak
    src/interfaces/odbc/GNUmakefile
    src/interfaces/odbc/bind.c
    src/interfaces/odbc/bind.h
    src/interfaces/odbc/columninfo.c
    src/interfaces/odbc/columninfo.h
    src/interfaces/odbc/connection.c
    src/interfaces/odbc/connection.h
    src/interfaces/odbc/convert.c
    src/interfaces/odbc/convert.h
    src/interfaces/odbc/descriptor.h
    src/interfaces/odbc/dlg_specific.c
    src/interfaces/odbc/dlg_specific.h
    src/interfaces/odbc/dlg_wingui.c
    src/interfaces/odbc/drvconn.c
    src/interfaces/odbc/environ.c
    src/interfaces/odbc/environ.h
    src/interfaces/odbc/execute.c
    src/interfaces/odbc/gpps.c
    src/interfaces/odbc/gpps.h
    src/interfaces/odbc/info.c
    src/interfaces/odbc/info30.c
    src/interfaces/odbc/iodbc.h
    src/interfaces/odbc/isql.h
    src/interfaces/odbc/isqlext.h
    src/interfaces/odbc/license.txt
    src/interfaces/odbc/lobj.c
    src/interfaces/odbc/lobj.h
    src/interfaces/odbc/md5.c
    src/interfaces/odbc/md5.h
    src/interfaces/odbc/misc.c
    src/interfaces/odbc/misc.h
    src/interfaces/odbc/multibyte.c
    src/interfaces/odbc/multibyte.h
    src/interfaces/odbc/notice.txt
    src/interfaces/odbc/odbc.sql
    src/interfaces/odbc/odbcapi.c
    src/interfaces/odbc/odbcapi25w.c
    src/interfaces/odbc/odbcapi30.c
    src/interfaces/odbc/odbcapi30w.c
    src/interfaces/odbc/odbcapiw.c
    src/interfaces/odbc/odbcinst.ini
    src/interfaces/odbc/options.c
    src/interfaces/odbc/parse.c
    src/interfaces/odbc/pgapi30.c
    src/interfaces/odbc/pgapifunc.h
    src/interfaces/odbc/pgtypes.c
    src/interfaces/odbc/pgtypes.h
    src/interfaces/odbc/psqlodbc.c
    src/interfaces/odbc/psqlodbc.h
    src/interfaces/odbc/psqlodbc.rc
    src/interfaces/odbc/psqlodbc.reg
    src/interfaces/odbc/psqlodbc30.reg
    src/interfaces/odbc/psqlodbc30w.reg
    src/interfaces/odbc/psqlodbc_api30.def
    src/interfaces/odbc/psqlodbc_api30w.def
    src/interfaces/odbc/psqlodbc_apiw.def
    src/interfaces/odbc/psqlodbc_win32.def
    src/interfaces/odbc/qresult.c
    src/interfaces/odbc/qresult.h
    src/interfaces/odbc/readme.txt
    src/interfaces/odbc/resource.h
    src/interfaces/odbc/results.c
    src/interfaces/odbc/setup.c
    src/interfaces/odbc/setup.rul
    src/interfaces/odbc/socket.c
    src/interfaces/odbc/socket.h
    src/interfaces/odbc/statement.c
    src/interfaces/odbc/statement.h
    src/interfaces/odbc/tuple.c
    src/interfaces/odbc/tuple.h
    src/interfaces/odbc/tuplelist.c
    src/interfaces/odbc/tuplelist.h
    src/interfaces/odbc/version.h
    src/interfaces/odbc/win32.mak
    src/interfaces/odbc/win32_30.mak
    src/interfaces/odbc/win32_30w.mak
    src/interfaces/odbc/win32w.mak
    src/interfaces/odbc/win_md5.c
    src/interfaces/odbc/win_setup.h
    src/interfaces/odbc/win_unicode.c
    src/interfaces/perl5/Changes
    src/interfaces/perl5/GNUmakefile
    src/interfaces/perl5/MANIFEST
    src/interfaces/perl5/Makefile.PL
    src/interfaces/perl5/Pg.pm
    src/interfaces/perl5/Pg.xs
    src/interfaces/perl5/README
    src/interfaces/perl5/examples/ApachePg.pl
    src/interfaces/perl5/examples/example.newstyle
    src/interfaces/perl5/examples/example.oldstyle
    src/interfaces/perl5/ppport.h
    src/interfaces/perl5/test.pl
    src/interfaces/perl5/typemap
    src/interfaces/python/Announce
    src/interfaces/python/ChangeLog
    src/interfaces/python/GNUmakefile
    src/interfaces/python/PyGreSQL.spec
    src/interfaces/python/README
    src/interfaces/python/README.linux
    src/interfaces/python/Setup.in.raw
    src/interfaces/python/pg.py
    src/interfaces/python/pgdb.py
    src/interfaces/python/pgmodule.c
    src/interfaces/python/setup.py
    src/interfaces/python/tutorial/advanced.py
    src/interfaces/python/tutorial/basics.py
    src/interfaces/python/tutorial/func.py
    src/interfaces/python/tutorial/syscat.py
    src/interfaces/ssl/client.conf
    src/interfaces/ssl/mkcert.sh
    src/interfaces/ssl/pgkeygen.sh
    src/interfaces/ssl/root.conf
    src/interfaces/ssl/server.conf
    src/makefiles/Makefile.aix
    src/makefiles/Makefile.beos
    src/makefiles/Makefile.bsdi
    src/makefiles/Makefile.darwin
    src/makefiles/Makefile.dgux
    src/makefiles/Makefile.freebsd
    src/makefiles/Makefile.hpux
    src/makefiles/Makefile.irix5
    src/makefiles/Makefile.linux
    src/makefiles/Makefile.netbsd
    src/makefiles/Makefile.openbsd
    src/makefiles/Makefile.osf
    src/makefiles/Makefile.qnx4
    src/makefiles/Makefile.sco
    src/makefiles/Makefile.solaris
    src/makefiles/Makefile.sunos4
    src/makefiles/Makefile.svr4
    src/makefiles/Makefile.ultrix4
    src/makefiles/Makefile.univel
    src/makefiles/Makefile.unixware
    src/makefiles/Makefile.win
    src/nls-global.mk
    src/pl/Makefile
    src/pl/plperl/GNUmakefile
    src/pl/plperl/README
    src/pl/plperl/SPI.xs
    src/pl/plperl/eloglvl.c
    src/pl/plperl/eloglvl.h
    src/pl/plperl/plperl.c
    src/pl/plperl/ppport.h
    src/pl/plpgsql/Makefile
    src/pl/plpgsql/src/.cvsignore
    src/pl/plpgsql/src/INSTALL
    src/pl/plpgsql/src/Makefile
    src/pl/plpgsql/src/gram.y
    src/pl/plpgsql/src/pl_comp.c
    src/pl/plpgsql/src/pl_exec.c
    src/pl/plpgsql/src/pl_funcs.c
    src/pl/plpgsql/src/pl_handler.c
    src/pl/plpgsql/src/plpgsql.h
    src/pl/plpgsql/src/scan.l
    src/pl/plpgsql/test/README
    src/pl/plpgsql/test/expected/tables.out
    src/pl/plpgsql/test/expected/test.out
    src/pl/plpgsql/test/expected/triggers.out
    src/pl/plpgsql/test/expected/views.out
    src/pl/plpgsql/test/runtest
    src/pl/plpgsql/test/tables.sql
    src/pl/plpgsql/test/test.sql
    src/pl/plpgsql/test/triggers.sql
    src/pl/plpgsql/test/views.sql
    src/pl/plpython/Makefile
    src/pl/plpython/README
    src/pl/plpython/TODO
    src/pl/plpython/error.expected
    src/pl/plpython/feature.expected
    src/pl/plpython/plpython.c
    src/pl/plpython/plpython.h
    src/pl/plpython/plpython_depopulate.sql
    src/pl/plpython/plpython_deschema.sql
    src/pl/plpython/plpython_drop.sql
    src/pl/plpython/plpython_error.sql
    src/pl/plpython/plpython_function.sql
    src/pl/plpython/plpython_populate.sql
    src/pl/plpython/plpython_schema.sql
    src/pl/plpython/plpython_setof.sql
    src/pl/plpython/plpython_test.sql
    src/pl/plpython/test.sh
    src/pl/tcl/Makefile
    src/pl/tcl/license.terms
    src/pl/tcl/modules/Makefile
    src/pl/tcl/modules/README
    src/pl/tcl/modules/pltcl_delmod.in
    src/pl/tcl/modules/pltcl_listmod.in
    src/pl/tcl/modules/pltcl_loadmod.in
    src/pl/tcl/modules/unknown.pltcl
    src/pl/tcl/pltcl.c
    src/pl/tcl/test/README
    src/pl/tcl/test/runtest
    src/pl/tcl/test/test.expected
    src/pl/tcl/test/test_queries.sql
    src/pl/tcl/test/test_setup.sql
    src/template/aix
    src/template/beos
    src/template/bsdi
    src/template/darwin
    src/template/dgux
    src/template/freebsd
    src/template/hpux
    src/template/irix5
    src/template/linux
    src/template/netbsd
    src/template/nextstep
    src/template/openbsd
    src/template/osf
    src/template/qnx4
    src/template/sco
    src/template/solaris
    src/template/sunos4
    src/template/svr4
    src/template/ultrix4
    src/template/univel
    src/template/unixware
    src/template/win
    src/test/Makefile
    src/test/bench/Makefile
    src/test/bench/WISC-README
    src/test/bench/create.sh
    src/test/bench/create.source
    src/test/bench/perquery
    src/test/bench/query01
    src/test/bench/query02
    src/test/bench/query03
    src/test/bench/query04
    src/test/bench/query05
    src/test/bench/query06
    src/test/bench/query07
    src/test/bench/query08
    src/test/bench/query09
    src/test/bench/query10
    src/test/bench/query11
    src/test/bench/query12
    src/test/bench/query13
    src/test/bench/query14
    src/test/bench/query15
    src/test/bench/query16
    src/test/bench/query17
    src/test/bench/query18
    src/test/bench/query19
    src/test/bench/query20
    src/test/bench/query21
    src/test/bench/query22
    src/test/bench/query23
    src/test/bench/query24
    src/test/bench/query25
    src/test/bench/query26
    src/test/bench/query27
    src/test/bench/query28
    src/test/bench/query29
    src/test/bench/query30
    src/test/bench/query31
    src/test/bench/query32
    src/test/bench/runwisc.sh
    src/test/bench/wholebench.sh
    src/test/examples/Makefile
    src/test/examples/testlibpq.c
    src/test/examples/testlibpq2.c
    src/test/examples/testlibpq2.sql
    src/test/examples/testlibpq3.c
    src/test/examples/testlibpq3.sql
    src/test/examples/testlibpq4.c
    src/test/examples/testlo.c
    src/test/locale/Makefile
    src/test/locale/README
    src/test/locale/de_DE.ISO8859-1/Makefile
    src/test/locale/de_DE.ISO8859-1/README
    src/test/locale/de_DE.ISO8859-1/expected/de-ctype.out
    src/test/locale/de_DE.ISO8859-1/expected/test-de-char.sql.out
    src/test/locale/de_DE.ISO8859-1/expected/test-de-select.sql.out
    src/test/locale/de_DE.ISO8859-1/expected/test-de-sort.out
    src/test/locale/de_DE.ISO8859-1/expected/test-de-text.sql.out
    src/test/locale/de_DE.ISO8859-1/expected/test-de-upper-char.sql.out
    src/test/locale/de_DE.ISO8859-1/expected/test-de-upper-text.sql.out
    src/test/locale/de_DE.ISO8859-1/expected/test-de-upper-varchar.sql.out
    src/test/locale/de_DE.ISO8859-1/expected/test-de-varchar.sql.out
    src/test/locale/de_DE.ISO8859-1/runall
    src/test/locale/de_DE.ISO8859-1/test-de-select.sql.in
    src/test/locale/de_DE.ISO8859-1/test-de-sort.in
    src/test/locale/de_DE.ISO8859-1/test-de-upper.sql.in
    src/test/locale/de_DE.ISO8859-1/test-de.sql.in
    src/test/locale/gr_GR.ISO8859-7/Makefile
    src/test/locale/gr_GR.ISO8859-7/README
    src/test/locale/gr_GR.ISO8859-7/expected/gr-ctype.out
    src/test/locale/gr_GR.ISO8859-7/expected/test-gr-char.sql.out
    src/test/locale/gr_GR.ISO8859-7/expected/test-gr-select.sql.out
    src/test/locale/gr_GR.ISO8859-7/expected/test-gr-sort.out
    src/test/locale/gr_GR.ISO8859-7/expected/test-gr-text.sql.out
    src/test/locale/gr_GR.ISO8859-7/expected/test-gr-varchar.sql.out
    src/test/locale/gr_GR.ISO8859-7/runall
    src/test/locale/gr_GR.ISO8859-7/test-gr-select.sql.in
    src/test/locale/gr_GR.ISO8859-7/test-gr-sort.in
    src/test/locale/gr_GR.ISO8859-7/test-gr.sql.in
    src/test/locale/koi8-r/Makefile
    src/test/locale/koi8-r/expected/koi8-ctype.out
    src/test/locale/koi8-r/expected/test-koi8-char.sql.out
    src/test/locale/koi8-r/expected/test-koi8-select.sql.out
    src/test/locale/koi8-r/expected/test-koi8-sort.out
    src/test/locale/koi8-r/expected/test-koi8-text.sql.out
    src/test/locale/koi8-r/expected/test-koi8-varchar.sql.out
    src/test/locale/koi8-r/runall
    src/test/locale/koi8-r/test-koi8-select.sql.in
    src/test/locale/koi8-r/test-koi8-sort.in
    src/test/locale/koi8-r/test-koi8.sql.in
    src/test/locale/koi8-to-win1251/Makefile
    src/test/locale/koi8-to-win1251/README
    src/test/locale/koi8-to-win1251/expected/test-koi8-char.sql.out
    src/test/locale/koi8-to-win1251/expected/test-koi8-select.sql.out
    src/test/locale/koi8-to-win1251/expected/test-koi8-sort.out
    src/test/locale/koi8-to-win1251/expected/test-koi8-text.sql.out
    src/test/locale/koi8-to-win1251/expected/test-koi8-varchar.sql.out
    src/test/locale/koi8-to-win1251/runall
    src/test/locale/koi8-to-win1251/test-koi8-select.sql.in
    src/test/locale/koi8-to-win1251/test-koi8-sort.in
    src/test/locale/koi8-to-win1251/test-koi8.sql.in
    src/test/locale/sort-test.pl
    src/test/locale/sort-test.py
    src/test/locale/test-ctype.c
    src/test/locale/test-pgsql-locale.c
    src/test/mb/README
    src/test/mb/expected/big5.out
    src/test/mb/expected/euc_cn.out
    src/test/mb/expected/euc_jp.out
    src/test/mb/expected/euc_kr.out
    src/test/mb/expected/euc_tw.out
    src/test/mb/expected/mule_internal.out
    src/test/mb/expected/sjis.out
    src/test/mb/expected/unicode.out
    src/test/mb/mbregress.sh
    src/test/mb/sql/big5.sql
    src/test/mb/sql/euc_cn.sql
    src/test/mb/sql/euc_jp.sql
    src/test/mb/sql/euc_kr.sql
    src/test/mb/sql/euc_tw.sql
    src/test/mb/sql/mule_internal.sql
    src/test/mb/sql/sjis.sql
    src/test/mb/sql/unicode.sql
    src/test/performance/results/PgSQL.970926
    src/test/performance/runtests.pl
    src/test/performance/sqls/connection
    src/test/performance/sqls/crtsimple
    src/test/performance/sqls/crtsimpleidx
    src/test/performance/sqls/drpsimple
    src/test/performance/sqls/inssimple
    src/test/performance/sqls/inssimple.data
    src/test/performance/sqls/orbsimple
    src/test/performance/sqls/slcsimple
    src/test/performance/sqls/slcsimple.data
    src/test/performance/sqls/vacuum
    src/test/performance/start-pgsql.sh
    src/test/regress/GNUmakefile
    src/test/regress/Makefile
    src/test/regress/README
    src/test/regress/data/agg.data
    src/test/regress/data/constrf.data
    src/test/regress/data/constro.data
    src/test/regress/data/dept.data
    src/test/regress/data/desc.data
    src/test/regress/data/emp.data
    src/test/regress/data/hash.data
    src/test/regress/data/onek.data
    src/test/regress/data/person.data
    src/test/regress/data/real_city.data
    src/test/regress/data/rect.data
    src/test/regress/data/streets.data
    src/test/regress/data/stud_emp.data
    src/test/regress/data/student.data
    src/test/regress/data/tenk.data
    src/test/regress/expected/abstime-solaris-1947.out
    src/test/regress/expected/abstime.out
    src/test/regress/expected/aggregates.out
    src/test/regress/expected/alter_table.out
    src/test/regress/expected/arrays.out
    src/test/regress/expected/bit.out
    src/test/regress/expected/boolean.out
    src/test/regress/expected/box.out
    src/test/regress/expected/btree_index.out
    src/test/regress/expected/case.out
    src/test/regress/expected/char.out
    src/test/regress/expected/char_1.out
    src/test/regress/expected/circle.out
    src/test/regress/expected/comments.out
    src/test/regress/expected/create_aggregate.out
    src/test/regress/expected/create_index.out
    src/test/regress/expected/create_misc.out
    src/test/regress/expected/create_operator.out
    src/test/regress/expected/create_table.out
    src/test/regress/expected/create_type.out
    src/test/regress/expected/create_view.out
    src/test/regress/expected/date.out
    src/test/regress/expected/domain.out
    src/test/regress/expected/errors.out
    src/test/regress/expected/euc_cn.out
    src/test/regress/expected/euc_jp.out
    src/test/regress/expected/euc_kr.out
    src/test/regress/expected/euc_tw.out
    src/test/regress/expected/float4-exp-three-digits.out
    src/test/regress/expected/float4.out
    src/test/regress/expected/float8-exp-three-digits.out
    src/test/regress/expected/float8-fp-exception.out
    src/test/regress/expected/float8-small-is-zero.out
    src/test/regress/expected/float8.out
    src/test/regress/expected/foreign_key.out
    src/test/regress/expected/geometry-alpha-precision.out
    src/test/regress/expected/geometry-bsdi-precision.out
    src/test/regress/expected/geometry-i86-gnulibc.out
    src/test/regress/expected/geometry-intel-beos.out
    src/test/regress/expected/geometry-irix.out
    src/test/regress/expected/geometry-positive-zeros-bsd.out
    src/test/regress/expected/geometry-positive-zeros.out
    src/test/regress/expected/geometry-powerpc-aix4.out
    src/test/regress/expected/geometry-powerpc-darwin.out
    src/test/regress/expected/geometry-powerpc-linux-gnulibc1.out
    src/test/regress/expected/geometry-solaris-i386-pc.out
    src/test/regress/expected/geometry-solaris-precision.out
    src/test/regress/expected/geometry-uw7-cc.out
    src/test/regress/expected/geometry-uw7-gcc.out
    src/test/regress/expected/geometry.out
    src/test/regress/expected/hash_index.out
    src/test/regress/expected/horology-no-DST-before-1970.out
    src/test/regress/expected/horology-solaris-1947.out
    src/test/regress/expected/horology.out
    src/test/regress/expected/inet.out
    src/test/regress/expected/inherit.out
    src/test/regress/expected/insert.out
    src/test/regress/expected/int2.out
    src/test/regress/expected/int4.out
    src/test/regress/expected/int8-exp-three-digits.out
    src/test/regress/expected/int8.out
    src/test/regress/expected/interval.out
    src/test/regress/expected/join.out
    src/test/regress/expected/limit.out
    src/test/regress/expected/lseg.out
    src/test/regress/expected/mule_internal.out
    src/test/regress/expected/name.out
    src/test/regress/expected/numeric.out
    src/test/regress/expected/numeric_big.out
    src/test/regress/expected/numerology.out
    src/test/regress/expected/oid.out
    src/test/regress/expected/oidjoins.out
    src/test/regress/expected/opr_sanity.out
    src/test/regress/expected/path.out
    src/test/regress/expected/plpgsql.out
    src/test/regress/expected/point.out
    src/test/regress/expected/polygon.out
    src/test/regress/expected/portals.out
    src/test/regress/expected/portals_p2.out
    src/test/regress/expected/privileges.out
    src/test/regress/expected/random.out
    src/test/regress/expected/reltime.out
    src/test/regress/expected/rules.out
    src/test/regress/expected/sanity_check.out
    src/test/regress/expected/select.out
    src/test/regress/expected/select_distinct.out
    src/test/regress/expected/select_distinct_on.out
    src/test/regress/expected/select_having.out
    src/test/regress/expected/select_having_1.out
    src/test/regress/expected/select_implicit.out
    src/test/regress/expected/select_implicit_1.out
    src/test/regress/expected/select_into.out
    src/test/regress/expected/select_views.out
    src/test/regress/expected/select_views_1.out
    src/test/regress/expected/sql_ascii.out
    src/test/regress/expected/strings.out
    src/test/regress/expected/subselect.out
    src/test/regress/expected/temp.out
    src/test/regress/expected/text.out
    src/test/regress/expected/time.out
    src/test/regress/expected/timestamp.out
    src/test/regress/expected/timestamptz.out
    src/test/regress/expected/timetz.out
    src/test/regress/expected/tinterval-solaris-1947.out
    src/test/regress/expected/tinterval.out
    src/test/regress/expected/transactions.out
    src/test/regress/expected/triggers.out
    src/test/regress/expected/type_sanity.out
    src/test/regress/expected/union.out
    src/test/regress/expected/varchar.out
    src/test/regress/expected/varchar_1.out
    src/test/regress/input/constraints.source
    src/test/regress/input/copy.source
    src/test/regress/input/create_function_1.source
    src/test/regress/input/create_function_2.source
    src/test/regress/input/misc.source
    src/test/regress/output/constraints.source
    src/test/regress/output/copy.source
    src/test/regress/output/create_function_1.source
    src/test/regress/output/create_function_2.source
    src/test/regress/output/misc.source
    src/test/regress/parallel_schedule
    src/test/regress/pg_regress.sh
    src/test/regress/regress.c
    src/test/regress/regressplans.sh
    src/test/regress/resultmap
    src/test/regress/serial_schedule
    src/test/regress/sql/abstime.sql
    src/test/regress/sql/aggregates.sql
    src/test/regress/sql/alter_table.sql
    src/test/regress/sql/arrays.sql
    src/test/regress/sql/bit.sql
    src/test/regress/sql/boolean.sql
    src/test/regress/sql/box.sql
    src/test/regress/sql/btree_index.sql
    src/test/regress/sql/case.sql
    src/test/regress/sql/char.sql
    src/test/regress/sql/circle.sql
    src/test/regress/sql/comments.sql
    src/test/regress/sql/create_aggregate.sql
    src/test/regress/sql/create_index.sql
    src/test/regress/sql/create_misc.sql
    src/test/regress/sql/create_operator.sql
    src/test/regress/sql/create_table.sql
    src/test/regress/sql/create_type.sql
    src/test/regress/sql/create_view.sql
    src/test/regress/sql/date.sql
    src/test/regress/sql/domain.sql
    src/test/regress/sql/drop.sql
    src/test/regress/sql/errors.sql
    src/test/regress/sql/euc_cn.sql
    src/test/regress/sql/euc_jp.sql
    src/test/regress/sql/euc_kr.sql
    src/test/regress/sql/euc_tw.sql
    src/test/regress/sql/float4.sql
    src/test/regress/sql/float8.sql
    src/test/regress/sql/foreign_key.sql
    src/test/regress/sql/geometry.sql
    src/test/regress/sql/hash_index.sql
    src/test/regress/sql/horology.sql
    src/test/regress/sql/inet.sql
    src/test/regress/sql/inherit.sql
    src/test/regress/sql/insert.sql
    src/test/regress/sql/int2.sql
    src/test/regress/sql/int4.sql
    src/test/regress/sql/int8.sql
    src/test/regress/sql/interval.sql
    src/test/regress/sql/join.sql
    src/test/regress/sql/limit.sql
    src/test/regress/sql/lseg.sql
    src/test/regress/sql/mule_internal.sql
    src/test/regress/sql/name.sql
    src/test/regress/sql/numeric.sql
    src/test/regress/sql/numeric_big.sql
    src/test/regress/sql/numerology.sql
    src/test/regress/sql/oid.sql
    src/test/regress/sql/oidjoins.sql
    src/test/regress/sql/opr_sanity.sql
    src/test/regress/sql/path.sql
    src/test/regress/sql/plpgsql.sql
    src/test/regress/sql/point.sql
    src/test/regress/sql/polygon.sql
    src/test/regress/sql/portals.sql
    src/test/regress/sql/portals_p2.sql
    src/test/regress/sql/privileges.sql
    src/test/regress/sql/random.sql
    src/test/regress/sql/reltime.sql
    src/test/regress/sql/rules.sql
    src/test/regress/sql/sanity_check.sql
    src/test/regress/sql/select.sql
    src/test/regress/sql/select_distinct.sql
    src/test/regress/sql/select_distinct_on.sql
    src/test/regress/sql/select_having.sql
    src/test/regress/sql/select_implicit.sql
    src/test/regress/sql/select_into.sql
    src/test/regress/sql/select_views.sql
    src/test/regress/sql/sql_ascii.sql
    src/test/regress/sql/strings.sql
    src/test/regress/sql/subselect.sql
    src/test/regress/sql/temp.sql
    src/test/regress/sql/text.sql
    src/test/regress/sql/time.sql
    src/test/regress/sql/timestamp.sql
    src/test/regress/sql/timestamptz.sql
    src/test/regress/sql/timetz.sql
    src/test/regress/sql/tinterval.sql
    src/test/regress/sql/transactions.sql
    src/test/regress/sql/triggers.sql
    src/test/regress/sql/type_sanity.sql
    src/test/regress/sql/union.sql
    src/test/regress/sql/varchar.sql
    src/tools/RELEASE_CHANGES
    src/tools/backend/README
    src/tools/backend/backend_dirs.html
    src/tools/backend/flow.fig
    src/tools/backend/flow.gif
    src/tools/backend/index.html
    src/tools/ccsym
    src/tools/copyright
    src/tools/entab/Makefile
    src/tools/entab/entab.c
    src/tools/entab/entab.man
    src/tools/entab/halt.c
    src/tools/find_badmacros
    src/tools/find_static
    src/tools/find_typedef
    src/tools/make_ctags
    src/tools/make_diff/README
    src/tools/make_diff/cporig
    src/tools/make_diff/difforig
    src/tools/make_diff/rmorig
    src/tools/make_etags
    src/tools/make_keywords
    src/tools/make_mkid
    src/tools/pgcvslog
    src/tools/pginclude/README
    src/tools/pginclude/pgcompinclude
    src/tools/pginclude/pgdefine
    src/tools/pginclude/pgfixinclude
    src/tools/pginclude/pgrminclude
    src/tools/pgindent/README
    src/tools/pgindent/indent.bsd.patch
    src/tools/pgindent/pgcppindent
    src/tools/pgindent/pgindent
    src/tools/pgindent/pgjindent
    src/tutorial/Makefile
    src/tutorial/README
    src/tutorial/advanced.source
    src/tutorial/basics.source
    src/tutorial/beard.c
    src/tutorial/complex.c
    src/tutorial/complex.source
    src/tutorial/funcs.c
    src/tutorial/funcs.source
    src/tutorial/funcs_new.c
    src/tutorial/syscat.source
    src/utils/Makefile
    src/utils/README
    src/utils/dllinit.c
    src/utils/getopt.c
    src/utils/strdup.c
    src/win32.mak
This commit is contained in:
CVS to git conversion script 2002-06-20 20:29:55 +00:00
parent d84fe82230
commit 05dedace84
2695 changed files with 0 additions and 1480784 deletions

View File

@ -1,23 +0,0 @@
PostgreSQL Database Management System
(formerly known as Postgres, then as Postgres95)
Portions Copyright (c) 1996-2002, The PostgreSQL Global Development Group
Portions Copyright (c) 1994, The Regents of the University of California
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose, without fee, and without a written agreement
is hereby granted, provided that the above copyright notice and this
paragraph and the following two paragraphs appear in all copies.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

View File

@ -1,127 +0,0 @@
#
# PostgreSQL top level makefile
#
# $Header: /cvsroot/pgsql/GNUmakefile.in,v 1.24 2002/03/29 17:32:48 petere Exp $
#
subdir =
top_builddir = .
include $(top_builddir)/src/Makefile.global
all:
$(MAKE) -C doc all
$(MAKE) -C src all
@echo "All of PostgreSQL successfully made. Ready to install."
install:
$(MAKE) -C doc install
$(MAKE) -C src install
@cat $(srcdir)/register.txt
installdirs uninstall distprep:
$(MAKE) -C doc $@
$(MAKE) -C src $@
install-all-headers:
$(MAKE) -C src $@
# clean, distclean, etc should apply to contrib too, even though
# it's not built by default
clean:
$(MAKE) -C doc $@
$(MAKE) -C contrib $@
$(MAKE) -C src $@
# Garbage from autoconf:
@rm -rf autom4te.cache/
# Important: distclean `src' last, otherwise Makefile.global
# will be gone too soon.
distclean maintainer-clean:
-$(MAKE) -C doc $@
-$(MAKE) -C contrib $@
-$(MAKE) -C src $@
-rm -f config.cache config.log config.status GNUmakefile
# Garbage from autoconf:
@rm -rf autom4te.cache/
check: all
check installcheck:
$(MAKE) -C src/test $@
GNUmakefile: GNUmakefile.in $(top_builddir)/config.status
./config.status $@
##########################################################################
distdir := postgresql-$(VERSION)
dummy := =install=
garbage := =* "#"* ."#"* *~* *.orig *.rej core postgresql-*
dist: $(distdir).tar.gz
ifeq ($(split-dist), yes)
dist: postgresql-base-$(VERSION).tar.gz postgresql-docs-$(VERSION).tar.gz postgresql-opt-$(VERSION).tar.gz postgresql-test-$(VERSION).tar.gz
endif
dist:
-rm -rf $(distdir)
$(distdir).tar: distdir
$(TAR) chf $@ $(distdir)
opt_files := src/backend/utils/mb contrib/retep/build.xml \
src/tools src/corba src/data src/tutorial \
$(addprefix src/bin/, pgaccess pgtclsh pg_encoding) \
$(addprefix src/interfaces/, odbc libpq++ libpgtcl perl5 python jdbc) \
$(addprefix src/pl/, plperl tcl)
docs_files := doc/postgres.tar.gz doc/src doc/TODO.detail
postgresql-base-$(VERSION).tar: distdir
$(TAR) -c $(addprefix --exclude $(distdir)/, $(docs_files) $(opt_files) src/test) \
-f $@ $(distdir)
postgresql-docs-$(VERSION).tar: distdir
$(TAR) cf $@ $(addprefix $(distdir)/, $(docs_files))
postgresql-opt-$(VERSION).tar: distdir
$(TAR) cf $@ $(addprefix $(distdir)/, $(opt_files))
postgresql-test-$(VERSION).tar: distdir
$(TAR) cf $@ $(distdir)/src/test
distdir:
-rm -rf $(distdir)* $(dummy)
for x in `cd $(top_srcdir) && find . -name CVS -prune -o -print`; do \
file=`expr X$$x : 'X\./\(.*\)'`; \
if test -d "$(top_srcdir)/$$file" ; then \
mkdir "$(distdir)/$$file" && chmod 777 "$(distdir)/$$file"; \
else \
ln "$(top_srcdir)/$$file" "$(distdir)/$$file" >/dev/null 2>&1 \
|| cp "$(top_srcdir)/$$file" "$(distdir)/$$file"; \
fi || exit; \
done
$(MAKE) -C $(distdir) distprep
$(MAKE) -C $(distdir) distclean
distcheck: $(distdir).tar.gz
-rm -rf $(dummy)
mkdir $(dummy)
$(GZIP) -d -c $< | $(TAR) xf -
install_prefix=`cd $(dummy) && pwd`; \
cd $(distdir) \
&& ./configure --prefix="$$install_prefix"
$(MAKE) -C $(distdir) -q distprep
$(MAKE) -C $(distdir)
$(MAKE) -C $(distdir) install
$(MAKE) -C $(distdir) uninstall
@echo "checking whether \`$(MAKE) uninstall' works"
test `find $(dummy) ! -type d | wc -l` -eq 0
$(MAKE) -C $(distdir) dist
# Room for improvement: Check here whether this distribution tarball
# is sufficiently similar to the original one.
-rm -rf $(distdir) $(dummy)
@echo "Distribution integrity checks out."
.PHONY: dist distdir distcheck
unexport split-dist

3390
HISTORY

File diff suppressed because it is too large Load Diff

871
INSTALL
View File

@ -1,871 +0,0 @@
PostgreSQL Installation Instructions
------------------------------------------------------------------------
Short Version
./configure
gmake
su
gmake install
adduser postgres
mkdir /usr/local/pgsql/data
chown postgres /usr/local/pgsql/data
su - postgres
/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
/usr/local/pgsql/bin/postmaster -D /usr/local/pgsql/data >logfile 2>&1 &
/usr/local/pgsql/bin/createdb test
/usr/local/pgsql/bin/psql test
The long version is the rest of this document.
------------------------------------------------------------------------
Requirements
In general, a modern Unix-compatible platform should be able to run
PostgreSQL. The platforms that had received specific testing at the time of
release are listed in the Section called Supported Platforms below. In the
"doc" subdirectory of the distribution there are several platform-specific
FAQ documents you might wish to consult if you are having trouble.
The following prerequisites exist for building PostgreSQL:
* GNU make is required; other make programs will *not* work. GNU make is
often installed under the name "gmake"; this document will always refer
to it by that name. (On some systems GNU make is the default tool with
the name "make".) To test for GNU make enter
gmake --version
It is recommended to use version 3.76.1 or later.
* You need an ISO/ANSI C compiler. Recent versions of GCC are
recommendable, but PostgreSQL is known to build with a wide variety of
compilers from different vendors.
* gzip is needed to unpack the distribution in the first place. If you
are reading this, you probably already got past that hurdle.
* The GNU Readline library (for comfortable line editing and command
history retrieval) will automatically be used if found. You might wish
to install it before proceeding, but it is not essential. (On NetBSD,
the "libedit" library is readline-compatible and is used if
"libreadline" is not found.)
* GNU Flex and Bison are needed to build from scratch, but they are *not*
required when building from a released source package because
pre-generated output files are included in released packages. You will
need these programs only when building from a CVS tree or if you
changed the actual scanner and parser definition files. If you need
them, be sure to get Flex 2.5.4 or later and Bison 1.28 or later. Other
yacc programs can sometimes be used, but doing so requires extra effort
and is not recommended. Other lex programs will definitely not work.
* To build on Windows NT or Windows 2000 you need the Cygwin and cygipc
packages. See the file "doc/FAQ_MSWIN" for details.
If you need to get a GNU package, you can find it at your local GNU mirror
site (see http://www.gnu.org/order/ftp.html for a list) or at
ftp://ftp.gnu.org/gnu/.
Also check that you have sufficient disk space. You will need about 30 MB
for the source tree during compilation and about 10 MB for the installation
directory. An empty database cluster takes about 20 MB, databases take about
five times the amount of space that a flat text file with the same data
would take. If you are going to run the regression tests you will
temporarily need an extra 20 MB. Use the "df" command to check for disk
space.
------------------------------------------------------------------------
If You Are Upgrading
The internal data storage format changes with new releases of PostgreSQL.
Therefore, if you are upgrading an existing installation that does not have
a version number "7.2.x", you must back up and restore your data as shown
here. These instructions assume that your existing installation is under the
"/usr/local/pgsql" directory, and that the data area is in
"/usr/local/pgsql/data". Substitute your paths appropriately.
1. Make sure that your database is not updated during or after the backup.
This does not affect the integrity of the backup, but the changed data
would of course not be included. If necessary, edit the permissions in
the file "/usr/local/pgsql/data/pg_hba.conf" (or equivalent) to
disallow access from everyone except you.
2. To dump your database installation, type:
pg_dumpall > outputfile
If you need to preserve OIDs (such as when using them as foreign keys),
then use the "-o" option when running "pg_dumpall".
"pg_dumpall" does not save large objects. Check the Administrator's
Guide if you need to do this.
Make sure that you use the "pg_dumpall" command from the version you
are currently running. 7.2's "pg_dumpall" should not be used on older
databases.
3. If you are installing the new version at the same location as the old
one then shut down the old server, at the latest before you install the
new files:
kill -INT `cat /usr/local/pgsql/data/postmaster.pid`
Versions prior to 7.0 do not have this "postmaster.pid" file. If you
are using such a version you must find out the process id of the server
yourself, for example by typing "ps ax | grep postmaster", and supply
it to the "kill" command.
On systems that have PostgreSQL started at boot time, there is probably
a start-up file that will accomplish the same thing. For example, on a
Red Hat Linux system one might find that
/etc/rc.d/init.d/postgresql stop
works. Another possibility is "pg_ctl stop".
4. If you are installing in the same place as the old version then it is
also a good idea to move the old installation out of the way, in case
you have trouble and need to revert to it. Use a command like this:
mv /usr/local/pgsql /usr/local/pgsql.old
After you have installed PostgreSQL 7.2, create a new database directory and
start the new server. Remember that you must execute these commands while
logged in to the special database user account (which you already have if
you are upgrading).
/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
/usr/local/pgsql/bin/postmaster -D /usr/local/pgsql/data
Finally, restore your data with
/usr/local/pgsql/bin/psql -d template1 -f outputfile
using the *new* psql.
You can also install the new version in parallel with the old one to
decrease the downtime. These topics are discussed at length in the
Administrator's Guide, which you are encouraged to read in any case.
------------------------------------------------------------------------
Installation Procedure
1. Configuration
The first step of the installation procedure is to configure the source
tree for your system and choose the options you would like. This is
done by running the "configure" script. For a default installation
simply enter
./configure
This script will run a number of tests to guess values for various
system dependent variables and detect some quirks of your operating
system, and finally will create several files in the build tree to
record what it found.
The default configuration will build the server and utilities, as well
as all client applications and interfaces that require only a C
compiler. All files will be installed under "/usr/local/pgsql" by
default.
You can customize the build and installation process by supplying one
or more of the following command line options to "configure":
--prefix=PREFIX
Install all files under the directory "PREFIX" instead of
"/usr/local/pgsql". The actual files will be installed into
various subdirectories; no files will ever be installed directly
into the "PREFIX" directory.
If you have special needs, you can also customize the individual
subdirectories with the following options.
--exec-prefix=EXEC-PREFIX
You can install architecture-dependent files under a different
prefix, "EXEC-PREFIX", than what "PREFIX" was set to. This can be
useful to share architecture-independent files between hosts. If
you omit this, then "EXEC-PREFIX" is set equal to "PREFIX" and
both architecture-dependent and independent files will be
installed under the same tree, which is probably what you want.
--bindir=DIRECTORY
Specifies the directory for executable programs. The default is
"EXEC-PREFIX/bin", which normally means "/usr/local/pgsql/bin".
--datadir=DIRECTORY
Sets the directory for read-only data files used by the installed
programs. The default is "PREFIX/share". Note that this has
nothing to do with where your database files will be placed.
--sysconfdir=DIRECTORY
The directory for various configuration files, "PREFIX/etc" by
default.
--libdir=DIRECTORY
The location to install libraries and dynamically loadable
modules. The default is "EXEC-PREFIX/lib".
--includedir=DIRECTORY
The directory for installing C and C++ header files. The default
is "PREFIX/include".
--docdir=DIRECTORY
Documentation files, except "man" pages, will be installed into
this directory. The default is "PREFIX/doc".
--mandir=DIRECTORY
The man pages that come with PostgreSQL will be installed under
this directory, in their respective "manx" subdirectories. The
default is "PREFIX/man".
Note: Care has been taken to make it possible to install
PostgreSQL into shared installation locations (such as
"/usr/local/include") without interfering with the namespace
of the rest of the system. First, the string "/postgresql" is
automatically appended to datadir, sysconfdir, and docdir,
unless the fully expanded directory name already contains the
string "postgres" or "pgsql". For example, if you choose
"/usr/local" as prefix, the documentation will be installed
in "/usr/local/doc/postgresql", but if the prefix is
"/opt/postgres", then it will be in "/opt/postgres/doc".
Second, the installation layout of the C and C++ header files
has been reorganized in the 7.2 release. The public header
files of the client interfaces are installed into includedir
and are namespace-clean. The internal header files and the
server header files are installed into private directories
under includedir. See the Programmer's Guide for information
about how to get at the header files for each interface.
Finally, a private subdirectory will also be created, if
appropriate, under libdir for dynamically loadable modules.
--with-includes=DIRECTORIES
"DIRECTORIES" is a colon-separated list of directories that will
be added to the list the compiler searches for header files. If
you have optional packages (such as GNU Readline) installed in a
non-standard location, you have to use this option and probably
also the corresponding "--with-libraries" option.
Example: --with-includes=/opt/gnu/include:/usr/sup/include.
--with-libraries=DIRECTORIES
"DIRECTORIES" is a colon-separated list of directories to search
for libraries. You will probably have to use this option (and the
corresponding "--with-includes" option) if you have packages
installed in non-standard locations.
Example: --with-libraries=/opt/gnu/lib:/usr/sup/lib.
--enable-locale
Enables locale support. There is a performance penalty associated
with locale support, but if you are not in an English-speaking
environment you will most likely need this.
--enable-recode
Enables single-byte character set recode support. See the
Administrator's Guide about this feature.
--enable-multibyte
Allows the use of multibyte character encodings (including
Unicode) and character set encoding conversion. Read the
Administrator's Guide for details.
Note that some interfaces (such as Tcl or Java) expect all
character strings to be in Unicode, so this option will be
required to correctly support these interfaces.
--enable-nls[=LANGUAGES]
Enables Native Language Support (NLS), that is, the ability to
display a program's messages in a language other than English.
"LANGUAGES" is a space separated list of codes of the languages
that you want supported, for example --enable-nls='de fr'. (The
intersection between your list and the set of actually provided
translations will be computed automatically.) If you do not
specify a list, then all available translations are installed.
To use this option, you will need an implementation of the gettext
API. Some operating systems have this built-in (e.g., Linux,
NetBSD, Solaris), for other systems you can download an add-on
package from here: http://www.postgresql.org/~petere/gettext.html.
If you are using the gettext implementation in the GNU C library
then you will additionally need the GNU gettext package for some
utility programs. For any of the other implementations you will
not need it.
--with-pgport=NUMBER
Set "NUMBER" as the default port number for server and clients.
The default is 5432. The port can always be changed later on, but
if you specify it here then both server and clients will have the
same default compiled in, which can be very convenient. Usually
the only good reason to select a non-default value is if you
intend to run multiple PostgreSQL servers on the same machine.
--with-CXX
Build the C++ interface library.
--with-perl
Build the Perl interface module. The Perl interface will be
installed at the usual place for Perl modules (typically under
"/usr/lib/perl"), so you must have root access to perform the
installation step (see step 4). You need to have Perl 5 installed
to use this option.
--with-python
Build the Python interface module. You need to have root access to
be able to install the Python module at its default place
("/usr/lib/pythonx.y"). To be able to use this option, you must
have Python installed and your system needs to support shared
libraries. If you instead want to build a new complete interpreter
binary, you will have to do it manually.
--with-tcl
Builds components that require Tcl/Tk, which are libpgtcl,
pgtclsh, pgtksh, PgAccess, and PL/Tcl. But see below about
"--without-tk".
--without-tk
If you specify "--with-tcl" and this option, then programs that
require Tk (pgtksh and PgAccess) will be excluded.
--with-tclconfig=DIRECTORY, --with-tkconfig=DIRECTORY
Tcl/Tk installs the files "tclConfig.sh" and "tkConfig.sh", which
contain configuration information needed to build modules
interfacing to Tcl or Tk. These files are normally found
automatically at their well-known locations, but if you want to
use a different version of Tcl or Tk you can specify the directory
in which to find them.
--enable-odbc
Build the ODBC driver. By default, the driver will be independent
of a driver manager. To work better with a driver manager already
installed on your system, use one of the following options in
addition to this one. More information can be found in the
Programmer's Guide.
--with-iodbc
Build the ODBC driver for use with iODBC.
--with-unixodbc
Build the ODBC driver for use with unixODBC.
--with-odbcinst=DIRECTORY
Specifies the directory where the ODBC driver will expect its
"odbcinst.ini" configuration file. The default is
"/usr/local/pgsql/etc" or whatever you specified as
"--sysconfdir". It should be arranged that the driver reads the
same file as the driver manager.
If either the option "--with-iodbc" or the option
"--with-unixodbc" is used, this option will be ignored because in
that case the driver manager handles the location of the
configuration file.
--with-java
Build the JDBC driver and associated Java packages. This option
requires Ant to be installed (as well as a JDK, of course). Refer
to the JDBC driver documentation in the Programmer's Guide for
more information.
--with-krb4[=DIRECTORY], --with-krb5[=DIRECTORY]
Build with support for Kerberos authentication. You can use either
Kerberos version 4 or 5, but not both. The "DIRECTORY" argument
specifies the root directory of the Kerberos installation;
"/usr/athena" is assumed as default. If the relevant header files
and libraries are not under a common parent directory, then you
must use the "--with-includes" and "--with-libraries" options in
addition to this option. If, on the other hand, the required files
are in a location that is searched by default (e.g., "/usr/lib"),
then you can leave off the argument.
"configure" will check for the required header files and libraries
to make sure that your Kerberos installation is sufficient before
proceeding.
--with-krb-srvnam=NAME
The name of the Kerberos service principal. postgres is the
default. There's probably no reason to change this.
--with-openssl[=DIRECTORY]
Build with support for SSL (encrypted) connections. This requires
the OpenSSL package to be installed. The "DIRECTORY" argument
specifies the root directory of the OpenSSL installation; the
default is "/usr/local/ssl".
"configure" will check for the required header files and libraries
to make sure that your OpenSSL installation is sufficient before
proceeding.
--with-pam
Build with PAM (Pluggable Authentication Modules) support.
--enable-syslog
Enables the PostgreSQL server to use the syslog logging facility.
(Using this option does not mean that you must log with syslog or
even that it will be done by default, it simply makes it possible
to turn that option on at run time.)
--enable-debug
Compiles all programs and libraries with debugging symbols. This
means that you can run the programs through a debugger to analyze
problems. This enlarges the size of the installed executables
considerably, and on non-GCC compilers it usually also disables
compiler optimization, causing slowdowns. However, having the
symbols available is extremely helpful for dealing with any
problems that may arise. Currently, this option is recommended for
production installations only if you use GCC. But you should
always have it on if you are doing development work or running a
beta version.
--enable-cassert
Enables assertion checks in the server, which test for many "can't
happen" conditions. This is invaluable for code development
purposes, but the tests slow things down a little. Also, having
the tests turned on won't necessarily enhance the stability of
your server! The assertion checks are not categorized for
severity, and so what might be a relatively harmless bug will
still lead to server restarts if it triggers an assertion failure.
Currently, this option is not recommended for production use, but
you should have it on for development work or when running a beta
version.
--enable-depend
Enables automatic dependency tracking. With this option, the
makefiles are set up so that all affected object files will be
rebuilt when any header file is changed. This is useful if you are
doing development work, but is just wasted overhead if you intend
only to compile once and install. At present, this option will
work only if you use GCC.
If you prefer a C or C++ compiler different from the one "configure"
picks then you can set the environment variables CC or CXX,
respectively, to the program of your choice. Similarly, you can
override the default compiler flags with the CFLAGS and CXXFLAGS
variables. For example:
env CC=/opt/bin/gcc CFLAGS='-O2 -pipe' ./configure
2. Build
To start the build, type
gmake
(Remember to use GNU make.) The build may take anywhere from 5 minutes
to half an hour depending on your hardware. The last line displayed
should be
All of PostgreSQL is successfully made. Ready to install.
3. Regression Tests
If you want to test the newly built server before you install it, you
can run the regression tests at this point. The regression tests are a
test suite to verify that PostgreSQL runs on your machine in the way
the developers expected it to. Type
gmake check
(This won't work as root; do it as an unprivileged user.) It is
possible that some tests fail, due to differences in error message
wording or floating point results. The file "src/test/regress/README"
and the Administrator's Guide contain detailed information about
interpreting the test results. You can repeat this test at any later
time by issuing the same command.
4. Installing The Files
Note: If you are upgrading an existing system and are going
to install the new files over the old ones, then you should
have backed up your data and shut down the old server by now,
as explained in the Section called If You Are Upgrading
above.
To install PostgreSQL enter
gmake install
This will install files into the directories that were specified in
step 1. Make sure that you have appropriate permissions to write into
that area. Normally you need to do this step as root. Alternatively,
you could create the target directories in advance and arrange for
appropriate permissions to be granted.
If you built the Perl or Python interfaces and you were not the root
user when you executed the above command then that part of the
installation probably failed. In that case you should become the root
user and then do
gmake -C src/interfaces/perl5 install
gmake -C src/interfaces/python install
If you do not have superuser access you are on your own: you can still
take the required files and place them in other directories where Perl
or Python can find them, but how to do that is left as an exercise.
The standard installation provides only the header files needed for
client application development. If you plan to do any server-side
program development (such as custom functions or data types written in
C), then you may want to install the entire PostgreSQL include tree
into your target include directory. To do that, enter
gmake install-all-headers
This adds a megabyte or two to the installation footprint, and is only
useful if you don't plan to keep the whole source tree around for
reference. (If you do, you can just use the source's include directory
when building server-side software.)
Client-only installation: If you want to install only the client
applications and interface libraries, then you can use these commands:
gmake -C src/bin install
gmake -C src/include install
gmake -C src/interfaces install
gmake -C doc install
To undo the installation use the command "gmake uninstall". However,
this will not remove any created directories.
After the installation you can make room by removing the built files from
the source tree with the "gmake clean" command. This will preserve the files
made by the configure program, so that you can rebuild everything with
"gmake" later on. To reset the source tree to the state in which it was
distributed, use "gmake distclean". If you are going to build for several
platforms from the same source tree you must do this and re-configure for
each build.
If you perform a build and then discover that your configure options were
wrong, or if you change anything that configure investigates (for example,
you install GNU Readline), then it's a good idea to do "gmake distclean"
before reconfiguring and rebuilding. Without this, your changes in
configuration choices may not propagate everywhere they need to.
------------------------------------------------------------------------
Post-Installation Setup
Shared Libraries
On some systems that have shared libraries (which most systems do) you need
to tell your system how to find the newly installed shared libraries. The
systems on which this is *not* necessary include BSD/OS, FreeBSD, HP-UX,
IRIX, Linux, NetBSD, OpenBSD, Tru64 UNIX (formerly Digital UNIX), and
Solaris.
The method to set the shared library search path varies between platforms,
but the most widely usable method is to set the environment variable
LD_LIBRARY_PATH like so: In Bourne shells ("sh", "ksh", "bash", "zsh")
LD_LIBRARY_PATH=/usr/local/pgsql/lib
export LD_LIBRARY_PATH
or in "csh" or "tcsh"
setenv LD_LIBRARY_PATH /usr/local/pgsql/lib
Replace /usr/local/pgsql/lib with whatever you set "--libdir" to in step 1.
You should put these commands into a shell start-up file such as
"/etc/profile" or "~/.bash_profile". Some good information about the caveats
associated with this method can be found at
http://www.visi.com/~barr/ldpath.html.
On some systems it might be preferable to set the environment variable
LD_RUN_PATH *before* building.
If in doubt, refer to the manual pages of your system (perhaps "ld.so" or
"rld"). If you later on get a message like
psql: error in loading shared libraries
libpq.so.2.1: cannot open shared object file: No such file or directory
then this step was necessary. Simply take care of it then.
If you are on BSD/OS, Linux, or SunOS 4 and you have root access you can run
/sbin/ldconfig /usr/local/pgsql/lib
(or equivalent directory) after installation to enable the run-time linker
to find the shared libraries faster. Refer to the manual page of "ldconfig"
for more information. On FreeBSD, NetBSD, and OpenBSD the command is
/sbin/ldconfig -m /usr/local/pgsql/lib
instead. Other systems are not known to have an equivalent command.
------------------------------------------------------------------------
Environment Variables
If you installed into "/usr/local/pgsql" or some other location that is not
searched for programs by default, you need to add "/usr/local/pgsql/bin" (or
whatever you set "--bindir" to in step 1) into your PATH. To do this, add
the following to your shell start-up file, such as "~/.bash_profile" (or
"/etc/profile", if you want it to affect every user):
PATH=/usr/local/pgsql/bin:$PATH
If you are using "csh" or "tcsh", then use this command:
set path = ( /usr/local/pgsql/bin $path )
To enable your system to find the man documentation, you need to add a line
like the following to a shell start-up file:
MANPATH=/usr/local/pgsql/man:$MANPATH
The environment variables PGHOST and PGPORT specify to client applications
the host and port of the database server, overriding the compiled-in
defaults. If you are going to run client applications remotely then it is
convenient if every user that plans to use the database sets PGHOST. This is
not required, however: the settings can be communicated via command line
options to most client programs.
------------------------------------------------------------------------
Getting Started
The following is a quick summary of how to get PostgreSQL up and running
once installed. The Administrator's Guide contains more information.
1. Create a user account for the PostgreSQL server. This is the user the
server will run as. For production use you should create a separate,
unprivileged account ("postgres" is commonly used). If you do not have
root access or just want to play around, your own user account is
enough, but running the server as root is a security risk and will not
work.
adduser postgres
2. Create a database installation with the "initdb" command. To run
"initdb" you must be logged in to your PostgreSQL server account. It
will not work as root.
root# mkdir /usr/local/pgsql/data
root# chown postgres /usr/local/pgsql/data
root# su - postgres
postgres$ /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
The "-D" option specifies the location where the data will be stored.
You can use any path you want, it does not have to be under the
installation directory. Just make sure that the server account can
write to the directory (or create it, if it doesn't already exist)
before starting "initdb", as illustrated here.
3. The previous step should have told you how to start up the database
server. Do so now. The command should look something like
/usr/local/pgsql/bin/postmaster -D /usr/local/pgsql/data
This will start the server in the foreground. To put the server in the
background use something like
nohup /usr/local/pgsql/bin/postmaster -D /usr/local/pgsql/data \
</dev/null >>server.log 2>&1 </dev/null &
To stop a server running in the background you can type
kill `cat /usr/local/pgsql/data/postmaster.pid`
In order to allow TCP/IP connections (rather than only Unix domain
socket ones) you need to pass the "-i" option to "postmaster".
4. Create a database:
createdb testdb
Then enter
psql testdb
to connect to that database. At the prompt you can enter SQL commands
and start experimenting.
------------------------------------------------------------------------
What Now?
* The PostgreSQL distribution contains a comprehensive documentation set,
which you should read sometime. After installation, the documentation
can be accessed by pointing your browser to
"/usr/local/pgsql/doc/html/index.html", unless you changed the
installation directories.
The Tutorial should be your first reading if you are completely new to
SQL databases. If you are familiar with database concepts then you want
to proceed with the Administrator's Guide, which contains information
about how to set up the database server, database users, and
authentication.
* Usually, you will want to modify your computer so that it will
automatically start the database server whenever it boots. Some
suggestions for this are in the Administrator's Guide.
* Run the regression tests against the installed server (using the
sequential test method). If you didn't run the tests before
installation, you should definitely do it now. This is also explained
in the Administrator's Guide.
------------------------------------------------------------------------
Supported Platforms
PostgreSQL has been verified by the developer community to work on the
platforms listed below. A supported platform generally means that PostgreSQL
builds and installs according to these instructions and that the regression
tests pass.
Note: If you are having problems with the installation on a
supported platform, please write to <pgsql-bugs@postgresql.org> or
<pgsql-ports@postgresql.org>, not to the people listed here.
OS Processor Version Reported Remarks
AIX RS6000 7.2 2001-12-19, Andreas Zeugswetter see also
(<ZeugswetterA@spardat.at>), doc/FAQ_AIX
Tatsuo Ishii
(<t-ishii@sra.co.jp>)
BeOS x86 7.2 2001-11-29, Cyril Velter 5.0.4
(<cyril.velter@libertysurf.fr>)
BSD/OS x86 7.2 2001-11-27, Bruce Momjian 4.2
(<pgman@candle.pha.pa.us>)
FreeBSDAlpha 7.2 2001-12-18, Chris Kings-Lynne
(<chriskl@familyhealth.com.au>)
FreeBSDx86 7.2 2001-11-14, Chris Kings-Lynne
(<chriskl@familyhealth.com.au>)
HP-UX PA-RISC 7.2 2001-11-29, Joseph Conway 11.00 and 10.20;
(<Joseph.Conway@home.com>), Tom see also
Lane (<tgl@sss.pgh.pa.us>) doc/FAQ_HPUX
IRIX MIPS 7.2 2001-11-28, Luis Amigo 6.5.13, MIPSPro
(<lamigo@atc.unican.es>) 7.30
Linux Alpha 7.2 2001-11-16, Tom Lane 2.2.18; tested at
(<tgl@sss.pgh.pa.us>) SourceForge
Linux armv4l 7.2 2001-12-10, Mark Knox 2.2.x
(<segfault@hardline.org>)
Linux MIPS 7.2 2001-11-15, Hisao Shibuya 2.0.x; Cobalt
(<shibuya@alpha.or.jp>) Qube2
Linux PlayStation 7.2 2001-12-12, Permaine Cheung #undef
2 <pcheung@redhat.com>) HAS_TEST_AND_SET,
slock_t
Linux PPC74xx 7.2 2001-11-16, Tom Lane 2.2.18; Apple G3
(<tgl@sss.pgh.pa.us>)
Linux S/390 7.2 2001-12-12, Permaine Cheung
<pcheung@redhat.com>)
Linux Sparc 7.2 2001-11-28, Doug McNaught 2.2.19
(<doug@wireboard.com>)
Linux x86 7.2 2001-11-15, Thomas Lockhart 2.0.x, 2.2.x,
(<lockhart@fourpalms.org>) 2.4.x
MacOS XPPC 7.2 2001-11-28, Gavin Sherry 10.1.x
(<swm@linuxworld.com.au>)
NetBSD Alpha 7.2 2001-11-20, Thomas Thai 1.5W
(<tom@minnesota.com>)
NetBSD arm32 7.1 2001-03-21, Patrick Welche 1.5E
(<prlw1@cam.ac.uk>)
NetBSD m68k 7.0 2000-04-10, Henry B. Hotz Mac 8xx
(<hotz@jpl.nasa.gov>)
NetBSD PPC 7.2 2001-11-28, Bill Studenmund 1.5
(<wrstuden@netbsd.org>)
NetBSD Sparc 7.2 2001-12-03, Matthew Green 32- and 64-bit
(<mrg@eterna.com.au>) builds
NetBSD VAX 7.1 2001-03-30, Tom I. Helbekkmo 1.5
(<tih@kpnQwest.no>)
NetBSD x86 7.2 2001-11-28, Bill Studenmund 1.5
(<wrstuden@netbsd.org>)
OpenBSDSparc 7.2 2001-11-27, Brandon Palmer 3.0
(<bpalmer@crimelabs.net>)
OpenBSDx86 7.2 2001-11-26, Brandon Palmer 3.0
(<bpalmer@crimelabs.net>)
Open x86 7.2 2001-11-28, OU-8 Larry Rosenman see also
UNIX (<ler@lerctr.org>), UW-7 Olivier doc/FAQ_SCO
Prenant (<ohp@pyrenet.fr>)
QNX 4 x86 7.2 2001-12-10, Bernd Tegge 4.25; see also
RTOS (<tegge@repas-aeg.de>) doc/FAQ_QNX4
SolarisSparc 7.2 2001-11-12, Andrew Sullivan 2.6-8; see also
(<andrew@libertyrms.com>) doc/FAQ_Solaris
Solarisx86 7.2 2001-11-28, Martin Renters 2.8; see also
(<martin@datafax.com>) doc/FAQ_Solaris
SunOS 4Sparc 7.2 2001-12-04, Tatsuo Ishii
(<t-ishii@sra.co.jp>)
Tru64 Alpha 7.2 2001-11-26, Alessio Bragadini 5.0; 4.0g with cc
UNIX (<alessio@albourne.com>), Bernd and gcc
Tegge (<tegge@repas-aeg.de>)
Windowsx86 7.2 2001-12-13, Dave Page with Cygwin; see
(<dpage@vale-housing.co.uk>), doc/FAQ_MSWIN
Jason Tishler
(<jason@tishler.net>)
Windowsx86 7.2 2001-12-10, Dave Page native is
(<dpage@vale-housing.co.uk>) client-side only;
see
Administrator's
Guide
Unsupported Platforms: The following platforms are either known not to work,
or they used to work in a previous release and we did not receive explicit
confirmation of a successful test with version 7.2 at the time this list was
compiled. We include these here to let you know that these platforms *could*
be supported if given some attention.
OS Processor Version Reported Remarks
DG/UX m88k 6.3 1998-03-01, Brian E Gallew no recent
5.4R4.11 (<geek+@cmu.edu>) reports
MkLinux DR1PPC750 7.0 2001-04-03, Tatsuo Ishii 7.1 needs OS
(<t-ishii@sra.co.jp>) update?
NeXTSTEP x86 6.x 1998-03-01, David Wetzel bit rot
(<dave@turbocat.de>) suspected
QNX RTOS v6x86 7.2 2001-11-20, Igor Kovalenko patches
(<Igor.Kovalenko@motorola.com>) available in
archives,
but too late
for 7.2
SCO x86 6.5 1999-05-25, Andrew Merrill 7.2 should
OpenServer (<andrew@compclass.com>) work, but no
5 reports; see
also
doc/FAQ_SCO
System V R4m88k 6.2.1 1998-03-01, Doug Winterburn needs new
(<dlw@seavme.xroads.com>) TAS spinlock
code
System V R4MIPS 6.4 1998-10-28, Frank Ridderbusch no recent
(<ridderbusch.pad@sni.de>) reports
Ultrix MIPS 7.1 2001-03-26 TAS spinlock
code not
detected
Ultrix VAX 6.x 1998-03-01

View File

@ -1,36 +0,0 @@
# The PostgreSQL make files exploit features of GNU make that other
# makes do not have. Because it is a common mistake for users to try
# to build Postgres with a different make, we have this make file
# that, as a service, will look for a GNU make and invoke it, or show
# an error message if none could be found.
# If the user were using GNU make now, this file would not get used
# because GNU make uses a make file named "GNUmakefile" in preference
# to "Makefile" if it exists. PostgreSQL is shipped with a
# "GNUmakefile". If the user hasn't run the configure script yet, the
# GNUmakefile won't exist yet, so we catch that case as well.
all check install installdirs install-all-headers installcheck uninstall dep depend clean distclean maintainer-clean:
@if [ ! -f GNUmakefile ] ; then \
echo "You need to run the 'configure' program first. See the file"; \
echo "'INSTALL' for installation instructions." ; \
false ; \
fi
@IFS=':' ; \
for dir in $$PATH; do \
for prog in gmake gnumake make; do \
if [ -f $$dir/$$prog ] && ( $$dir/$$prog -f /dev/null --version 2>/dev/null | grep GNU >/dev/null 2>&1 ) ; then \
GMAKE=$$dir/$$prog; \
break 2; \
fi; \
done; \
done; \
\
if [ x"$${GMAKE+set}" = xset ]; then \
echo "Using GNU make found at $${GMAKE}"; \
$${GMAKE} $@ ; \
else \
echo "You must use GNU make to build PostgreSQL." ; \
false; \
fi

26
README
View File

@ -1,26 +0,0 @@
PostgreSQL Database Management System
=====================================
This directory contains the source code distribution of the PostgreSQL
database management system.
PostgreSQL is an advanced object-relational database management system
that supports an extended subset of the SQL standard, including
transactions, foreign keys, subqueries, triggers, user-defined types
and functions. This distribution also contains several language
bindings, including C, C++, Perl, Python, and Tcl, as well as drivers
for JDBC and ODBC.
See the file INSTALL for instructions on how to build and install
PostgreSQL. That file also lists supported operating systems and
hardware platforms and contains information regarding any other
software packages that are required to build or run the PostgreSQL
system. Changes between all PostgreSQL releases are recorded in the
file HISTORY. Copyright and license information can be found in the
file COPYRIGHT. A comprehensive documentation set is included in this
distribution; it can be read as described in the installation
instructions.
The latest version of this software may be obtained at
ftp://ftp.postgresql.org/pub/. For more information look at our web
site located at http://www.postgresql.org/.

13
aclocal.m4 vendored
View File

@ -1,13 +0,0 @@
dnl $Header: /cvsroot/pgsql/aclocal.m4,v 1.14 2002/03/29 17:32:48 petere Exp $
m4_include([config/ac_func_accept_argtypes.m4])
m4_include([config/c-compiler.m4])
m4_include([config/c-library.m4])
m4_include([config/cxx.m4])
m4_include([config/docbook.m4])
m4_include([config/general.m4])
m4_include([config/java.m4])
m4_include([config/libtool.m4])
m4_include([config/perl.m4])
m4_include([config/programs.m4])
m4_include([config/python.m4])
m4_include([config/tcl.m4])

View File

@ -1,76 +0,0 @@
# $Header: /cvsroot/pgsql/config/ac_func_accept_argtypes.m4,v 1.4 2002/03/29 17:32:53 petere Exp $
# This comes from the official Autoconf macro archive at
# <http://research.cys.de/autoconf-archive/>
# (I removed the $ before the Id CVS keyword below.)
dnl @synopsis AC_FUNC_ACCEPT_ARGTYPES
dnl
dnl Checks the data types of the three arguments to accept(). Results are
dnl placed into the symbols ACCEPT_TYPE_ARG[123], consistent with the
dnl following example:
dnl
dnl #define ACCEPT_TYPE_ARG1 int
dnl #define ACCEPT_TYPE_ARG2 struct sockaddr *
dnl #define ACCEPT_TYPE_ARG3 socklen_t
dnl
dnl This macro requires AC_CHECK_HEADERS to have already verified the
dnl presence or absence of sys/types.h and sys/socket.h.
dnl
dnl NOTE: This is just a modified version of the AC_FUNC_SELECT_ARGTYPES
dnl macro. Credit for that one goes to David MacKenzie et. al.
dnl
dnl @version Id: ac_func_accept_argtypes.m4,v 1.1 1999/12/03 11:29:29 simons Exp $
dnl @author Daniel Richard G. <skunk@mit.edu>
dnl
# PostgreSQL local changes: In the original version ACCEPT_TYPE_ARG3
# is a pointer type. That's kind of useless because then you can't
# use the macro to define a corresponding variable. We also make the
# reasonable(?) assumption that you can use arg3 for getsocktype etc.
# as well (i.e., anywhere POSIX.2 has socklen_t).
#
# arg2 can also be `const' (e.g., RH 4.2). Change the order of tests
# for arg3 so that `int' is first, in case there is no prototype at all.
#
# Solaris 7 and 8 have arg3 as 'void *' (disguised as 'Psocklen_t'
# which is *not* 'socklen_t *'). If we detect that, then we assume
# 'int' as the result, because that ought to work best.
AC_DEFUN([AC_FUNC_ACCEPT_ARGTYPES],
[AC_MSG_CHECKING([types of arguments for accept()])
AC_CACHE_VAL(ac_cv_func_accept_arg1,dnl
[AC_CACHE_VAL(ac_cv_func_accept_arg2,dnl
[AC_CACHE_VAL(ac_cv_func_accept_arg3,dnl
[for ac_cv_func_accept_arg1 in 'int' 'unsigned int'; do
for ac_cv_func_accept_arg2 in 'struct sockaddr *' 'const struct sockaddr *' 'void *'; do
for ac_cv_func_accept_arg3 in 'int' 'size_t' 'socklen_t' 'unsigned int' 'void'; do
AC_TRY_COMPILE(
[#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
extern int accept ($ac_cv_func_accept_arg1, $ac_cv_func_accept_arg2, $ac_cv_func_accept_arg3 *);],
[], [ac_not_found=no; break 3], [ac_not_found=yes])
done
done
done
if test "$ac_not_found" = yes; then
AC_MSG_ERROR([could not determine argument types])
fi
if test "$ac_cv_func_accept_arg3" = "void"; then
ac_cv_func_accept_arg3=int
fi
])dnl AC_CACHE_VAL
])dnl AC_CACHE_VAL
])dnl AC_CACHE_VAL
AC_MSG_RESULT([$ac_cv_func_accept_arg1, $ac_cv_func_accept_arg2, $ac_cv_func_accept_arg3 *])
AC_DEFINE_UNQUOTED(ACCEPT_TYPE_ARG1, $ac_cv_func_accept_arg1,
[Define to the type of arg 1 of 'accept'])
AC_DEFINE_UNQUOTED(ACCEPT_TYPE_ARG2, $ac_cv_func_accept_arg2,
[Define to the type of arg 2 of 'accept'])
AC_DEFINE_UNQUOTED(ACCEPT_TYPE_ARG3, $ac_cv_func_accept_arg3,
[Define to the type of arg 3 of 'accept'])
])

View File

@ -1,94 +0,0 @@
# Macros to detect C compiler features
# $Header: /cvsroot/pgsql/config/c-compiler.m4,v 1.5 2002/03/29 17:32:53 petere Exp $
# PGAC_C_SIGNED
# -------------
# Check if the C compiler understands signed types.
AC_DEFUN([PGAC_C_SIGNED],
[AC_CACHE_CHECK(for signed types, pgac_cv_c_signed,
[AC_TRY_COMPILE([],
[signed char c; signed short s; signed int i;],
[pgac_cv_c_signed=yes],
[pgac_cv_c_signed=no])])
if test x"$pgac_cv_c_signed" = xno ; then
AC_DEFINE(signed,, [Define empty if the C compiler does not understand signed types])
fi])# PGAC_C_SIGNED
# PGAC_TYPE_64BIT_INT(TYPE)
# -------------------------
# Check if TYPE is a working 64 bit integer type. Set HAVE_TYPE_64 to
# yes or no respectively, and define HAVE_TYPE_64 if yes.
AC_DEFUN([PGAC_TYPE_64BIT_INT],
[define([Ac_define], [translit([have_$1_64], [a-z *], [A-Z_P])])dnl
define([Ac_cachevar], [translit([pgac_cv_type_$1_64], [ *], [_p])])dnl
AC_CACHE_CHECK([whether $1 is 64 bits], [Ac_cachevar],
[AC_TRY_RUN(
[typedef $1 int64;
/*
* These are globals to discourage the compiler from folding all the
* arithmetic tests down to compile-time constants.
*/
int64 a = 20000001;
int64 b = 40000005;
int does_int64_work()
{
int64 c,d;
if (sizeof(int64) != 8)
return 0; /* definitely not the right size */
/* Do perfunctory checks to see if 64-bit arithmetic seems to work */
c = a * b;
d = (c + b) / b;
if (d != a+1)
return 0;
return 1;
}
main() {
exit(! does_int64_work());
}],
[Ac_cachevar=yes],
[Ac_cachevar=no],
[Ac_cachevar=no
dnl We will do better here with Autoconf 2.50
AC_MSG_WARN([64 bit arithmetic disabled when cross-compiling])])])
Ac_define=$Ac_cachevar
if test x"$Ac_cachevar" = xyes ; then
AC_DEFINE(Ac_define,, [Set to 1 if `]$1[' is 64 bits])
fi
undefine([Ac_define])dnl
undefine([Ac_cachevar])dnl
])# PGAC_TYPE_64BIT_INT
# PGAC_CHECK_ALIGNOF(TYPE, [INCLUDES = DEFAULT-INCLUDES])
# -----------------------------------------------------
# Find the alignment requirement of the given type. Define the result
# as ALIGNOF_TYPE. This macro works even when cross compiling.
# (Modelled after AC_CHECK_SIZEOF.)
AC_DEFUN([PGAC_CHECK_ALIGNOF],
[AS_LITERAL_IF([$1], [],
[AC_FATAL([$0: requires literal arguments])])dnl
AC_CHECK_TYPE([$1], [], [], [$2])
AC_CACHE_CHECK([alignment of $1], [AS_TR_SH([pgac_cv_alignof_$1])],
[if test "$AS_TR_SH([ac_cv_type_$1])" = yes; then
_AC_COMPUTE_INT([((char*) & pgac_struct.field) - ((char*) & pgac_struct)],
[AS_TR_SH([pgac_cv_alignof_$1])],
[AC_INCLUDES_DEFAULT([$2])
struct { char filler; $1 field; } pgac_struct;],
[AC_MSG_ERROR([cannot compute alignment of $1, 77])])
else
AS_TR_SH([pgac_cv_alignof_$1])=0
fi])dnl
AC_DEFINE_UNQUOTED(AS_TR_CPP(alignof_$1),
[$AS_TR_SH([pgac_cv_alignof_$1])],
[The alignment requirement of a `$1'])
])# PGAC_CHECK_ALIGNOF

View File

@ -1,112 +0,0 @@
# Macros that test various C library quirks
# $Header: /cvsroot/pgsql/config/c-library.m4,v 1.13 2002/03/30 00:59:52 petere Exp $
# PGAC_VAR_INT_TIMEZONE
# ---------------------
# Check if the global variable `timezone' exists. If so, define
# HAVE_INT_TIMEZONE.
AC_DEFUN([PGAC_VAR_INT_TIMEZONE],
[AC_CACHE_CHECK(for int timezone, pgac_cv_var_int_timezone,
[AC_TRY_LINK([#include <time.h>
int res;],
[res = timezone / 60;],
[pgac_cv_var_int_timezone=yes],
[pgac_cv_var_int_timezone=no])])
if test x"$pgac_cv_var_int_timezone" = xyes ; then
AC_DEFINE(HAVE_INT_TIMEZONE,, [Set to 1 if you have the global variable timezone])
fi])# PGAC_VAR_INT_TIMEZONE
# PGAC_FUNC_GETTIMEOFDAY_1ARG
# ---------------------------
# Check if gettimeofday() has only one arguments. (Normal is two.)
# If so, define GETTIMEOFDAY_1ARG.
AC_DEFUN([PGAC_FUNC_GETTIMEOFDAY_1ARG],
[AC_CACHE_CHECK(whether gettimeofday takes only one argument,
pgac_cv_func_gettimeofday_1arg,
[AC_TRY_COMPILE([#include <sys/time.h>],
[struct timeval *tp;
struct timezone *tzp;
gettimeofday(tp,tzp);],
[pgac_cv_func_gettimeofday_1arg=no],
[pgac_cv_func_gettimeofday_1arg=yes])])
if test x"$pgac_cv_func_gettimeofday_1arg" = xyes ; then
AC_DEFINE(GETTIMEOFDAY_1ARG,, [Set to 1 if gettimeofday() takes only 1 argument])
fi])# PGAC_FUNC_GETTIMEOFDAY_1ARG
# PGAC_FUNC_MEMCMP
# ----------------
# Check if memcmp() properly handles negative bytes and returns +/-.
# SunOS does not.
# AC_FUNC_MEMCMP
AC_DEFUN([PGAC_FUNC_MEMCMP],
[AC_CACHE_CHECK(for 8-bit clean memcmp, pgac_cv_func_memcmp_clean,
[AC_TRY_RUN([
main()
{
char c0 = 0x40, c1 = 0x80, c2 = 0x81;
exit(memcmp(&c0, &c2, 1) < 0 && memcmp(&c1, &c2, 1) < 0 ? 0 : 1);
}
], pgac_cv_func_memcmp_clean=yes, pgac_cv_func_memcmp_clean=no,
pgac_cv_func_memcmp_clean=no)])
if test $pgac_cv_func_memcmp_clean = no ; then
MEMCMP=memcmp.o
else
MEMCMP=
fi
AC_SUBST(MEMCMP)dnl
])
# PGAC_UNION_SEMUN
# ----------------
# Check if `union semun' exists. Define HAVE_UNION_SEMUN if so.
# If it doesn't then one could define it as
# union semun { int val; struct semid_ds *buf; unsigned short *array; }
AC_DEFUN([PGAC_UNION_SEMUN],
[AC_CHECK_TYPES([union semun], [], [],
[#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>])])# PGAC_UNION_SEMUN
# PGAC_STRUCT_SOCKADDR_UN
# -----------------------
# If `struct sockaddr_un' exists, define HAVE_STRUCT_SOCKADDR_UN. If
# it is missing then one could define it as { short int sun_family;
# char sun_path[108]; }. (Requires test for <sys/un.h>!)
AC_DEFUN([PGAC_STRUCT_SOCKADDR_UN],
[AC_CHECK_TYPES([struct sockaddr_un], [], [],
[#include <sys/types.h>
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
#endif
])])# PGAC_STRUCT_SOCKADDR_UN
# PGAC_FUNC_POSIX_SIGNALS
# -----------------------
# Check to see if the machine has the POSIX signal interface. Define
# HAVE_POSIX_SIGNALS if so. Also set the output variable HAVE_POSIX_SIGNALS
# to yes or no.
#
# Note that this test only compiles a test program, it doesn't check
# whether the routines actually work. If that becomes a problem, make
# a fancier check.
AC_DEFUN([PGAC_FUNC_POSIX_SIGNALS],
[AC_CACHE_CHECK(for POSIX signal interface, pgac_cv_func_posix_signals,
[AC_TRY_LINK([#include <signal.h>
],
[struct sigaction act, oact;
sigemptyset(&act.sa_mask);
act.sa_flags = SA_RESTART;
sigaction(0, &act, &oact);],
[pgac_cv_func_posix_signals=yes],
[pgac_cv_func_posix_signals=no])])
if test x"$pgac_cv_func_posix_signals" = xyes ; then
AC_DEFINE(HAVE_POSIX_SIGNALS,, [Set to 1 if you have the POSIX signal interface])
fi
HAVE_POSIX_SIGNALS=$pgac_cv_func_posix_signals
AC_SUBST(HAVE_POSIX_SIGNALS)])# PGAC_FUNC_POSIX_SIGNALS

1308
config/config.guess vendored

File diff suppressed because it is too large Load Diff

1409
config/config.sub vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,64 +0,0 @@
# Macros to detect certain C++ features
# $Header: /cvsroot/pgsql/config/Attic/cxx.m4,v 1.3 2002/03/29 20:54:33 petere Exp $
# PGAC_CLASS_STRING
# -----------------
# Look for class `string'. First look for the <string> header. If this
# is found a <string> header then it's probably safe to assume that
# class string exists. If not, check to make sure that <string.h>
# defines class `string'.
AC_DEFUN([PGAC_CLASS_STRING],
[AC_LANG_PUSH(C++)
AC_CHECK_HEADER(string,
[AC_DEFINE(HAVE_CXX_STRING_HEADER, 1,
[Define to 1 if you have the C++ <string> header])],
[AC_CACHE_CHECK([for class string in <string.h>],
[pgac_cv_class_string_in_string_h],
[AC_TRY_COMPILE([#include <stdio.h>
#include <stdlib.h>
#include <string.h>
],
[string foo = "test"],
[pgac_cv_class_string_in_string_h=yes],
[pgac_cv_class_string_in_string_h=no])])
if test x"$pgac_cv_class_string_in_string_h" != xyes ; then
AC_MSG_ERROR([neither <string> nor <string.h> seem to define the C++ class 'string'])
fi
])
AC_LANG_POP(C++)])# PGAC_CLASS_STRING
# PGAC_CXX_NAMESPACE_STD
# ----------------------
# Check whether the C++ compiler understands `using namespace std'.
#
# Note 1: On at least some compilers, it will not work until you've
# included a header that mentions namespace std. Thus, include the
# usual suspects before trying it.
#
# Note 2: This test does not actually reveal whether the C++ compiler
# properly understands namespaces in all generality. (GNU C++ 2.8.1
# is one that doesn't.) However, we don't care.
AC_DEFUN([PGAC_CXX_NAMESPACE_STD],
[AC_REQUIRE([PGAC_CLASS_STRING])
AC_CACHE_CHECK([for namespace std in C++],
pgac_cv_cxx_namespace_std,
[
AC_LANG_PUSH(C++)
AC_TRY_COMPILE(
[#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_CXX_STRING_HEADER
#include <string>
#endif
using namespace std;
], [],
[pgac_cv_cxx_namespace_std=yes],
[pgac_cv_cxx_namespace_std=no])
AC_LANG_POP(C++)])
if test $pgac_cv_cxx_namespace_std = yes ; then
AC_DEFINE(HAVE_NAMESPACE_STD, 1, [Define to 1 if the C++ compiler understands 'using namespace std'])
fi])# PGAC_CXX_NAMESPACE_STD

View File

@ -1,93 +0,0 @@
# $Header: /cvsroot/pgsql/config/docbook.m4,v 1.3 2002/04/14 17:23:20 petere Exp $
# PGAC_PROG_JADE
# --------------
AC_DEFUN([PGAC_PROG_JADE],
[AC_CHECK_PROGS([JADE], [openjade jade])])
# PGAC_PROG_NSGMLS
# ----------------
AC_DEFUN([PGAC_PROG_NSGMLS],
[AC_CHECK_PROGS([NSGMLS], [onsgmls nsgmls])])
# PGAC_CHECK_DOCBOOK(VERSION)
# ---------------------------
AC_DEFUN([PGAC_CHECK_DOCBOOK],
[AC_REQUIRE([PGAC_PROG_NSGMLS])
AC_CACHE_CHECK([for DocBook V$1], [pgac_cv_check_docbook],
[cat >conftest.sgml <<EOF
<!doctype book PUBLIC "-//OASIS//DTD DocBook V$1//EN">
<book>
<title>test</title>
<chapter>
<title>random</title>
<sect1>
<title>testsect</title>
<para>text</para>
</sect1>
</chapter>
</book>
EOF
${NSGMLS-false} -s conftest.sgml 1>&AS_MESSAGE_LOG_FD 2>&1
if test $? -eq 0; then
pgac_cv_check_docbook=yes
else
pgac_cv_check_docbook=no
fi
rm -f conftest.sgml])
have_docbook=$pgac_cv_check_docbook
AC_SUBST([have_docbook])
])# PGAC_CHECK_DOCBOOK
# PGAC_PATH_DOCBOOK_STYLESHEETS
# -----------------------------
AC_DEFUN([PGAC_PATH_DOCBOOK_STYLESHEETS],
[AC_ARG_VAR(DOCBOOKSTYLE, [location of DocBook stylesheets])dnl
AC_MSG_CHECKING([for DocBook stylesheets])
AC_CACHE_VAL([pgac_cv_path_stylesheets],
[if test -n "$DOCBOOKSTYLE"; then
pgac_cv_path_stylesheets=$DOCBOOKSTYLE
else
for pgac_prefix in /usr /usr/local /opt; do
for pgac_infix in share lib; do
for pgac_postfix in \
sgml/stylesheets/nwalsh-modular \
sgml/stylesheets/docbook \
sgml/docbook/dsssl/modular \
sgml/docbook/dsssl-stylesheets
do
pgac_candidate=$pgac_prefix/$pgac_infix/$pgac_postfix
if test -r "$pgac_candidate/html/docbook.dsl" \
&& test -r "$pgac_candidate/print/docbook.dsl"
then
pgac_cv_path_stylesheets=$pgac_candidate
break 3
fi
done
done
done
fi])
DOCBOOKSTYLE=$pgac_cv_path_stylesheets
AC_SUBST([DOCBOOKSTYLE])
if test -n "$DOCBOOKSTYLE"; then
AC_MSG_RESULT([$DOCBOOKSTYLE])
else
AC_MSG_RESULT(no)
fi])# PGAC_PATH_DOCBOOK_STYLESHEETS
# PGAC_PATH_COLLATEINDEX
# ----------------------
AC_DEFUN([PGAC_PATH_COLLATEINDEX],
[AC_REQUIRE([PGAC_PATH_DOCBOOK_STYLESHEETS])dnl
if test -n "$DOCBOOKSTYLE"; then
AC_PATH_PROGS(COLLATEINDEX, collateindex.pl, [],
[$DOCBOOKSTYLE/bin $PATH])
else
AC_PATH_PROGS(COLLATEINDEX, collateindex.pl)
fi])# PGAC_PATH_COLLATEINDEX

View File

@ -1,135 +0,0 @@
# $Header: /cvsroot/pgsql/config/general.m4,v 1.2 2002/03/29 17:32:53 petere Exp $
# This file defines new macros to process configure command line
# arguments, to replace the brain-dead AC_ARG_WITH and AC_ARG_ENABLE.
# The flaw in these is particularly that they only differentiate
# between "given" and "not given" and do not provide enough help to
# process arguments that only accept "yes/no", that require an
# argument (other than "yes/no"), etc.
#
# The point of this implementation is to reduce code size and
# redundancy in configure.in and to improve robustness and consistency
# in the option evaluation code.
# Convert type and name to shell variable name (e.g., "enable_long_strings")
m4_define([pgac_arg_to_variable],
[$1[]_[]patsubst($2, -, _)])
# PGAC_ARG(TYPE, NAME, HELP-STRING,
# [ACTION-IF-YES], [ACTION-IF-NO], [ACTION-IF-ARG],
# [ACTION-IF-OMITTED])
# ----------------------------------------------------------
# This is the base layer. TYPE is either "with" or "enable", depending
# on what you like. NAME is the rest of the option name, HELP-STRING
# as usual. ACTION-IF-YES is executed if the option is given without
# and argument (or "yes", which is the same); similar for ACTION-IF-NO.
AC_DEFUN([PGAC_ARG],
[
m4_case([$1],
enable, [
AC_ARG_ENABLE([$2], [$3], [
case [$]enableval in
yes)
m4_default([$4], :)
;;
no)
m4_default([$5], :)
;;
*)
$6
;;
esac
],
[$7])[]dnl AC_ARG_ENABLE
],
with, [
AC_ARG_WITH([$2], [$3], [
case [$]withval in
yes)
m4_default([$4], :)
;;
no)
m4_default([$5], :)
;;
*)
$6
;;
esac
],
[$7])[]dnl AC_ARG_WITH
],
[m4_fatal([first argument of $0 must be 'enable' or 'with', not '$1'])]
)
])# PGAC_ARG
# PGAC_ARG_BOOL(TYPE, NAME, DEFAULT, HELP-STRING,
# [ACTION-IF-YES], [ACTION-IF-NO])
# -----------------------------------------------
# Accept a boolean option, that is, one that only takes yes or no.
# ("no" is equivalent to "disable" or "without"). DEFAULT is what
# should be done if the option is omitted; it should be "yes" or "no".
# (Consequently, one of ACTION-IF-YES and ACTION-IF-NO will always
# execute.)
AC_DEFUN([PGAC_ARG_BOOL],
[PGAC_ARG([$1], [$2], [$4], [$5], [$6],
[AC_MSG_ERROR([no argument expected for --$1-$2 option])],
[m4_case([$3],
yes, [pgac_arg_to_variable([$1], [$2])=yes
$5],
no, [pgac_arg_to_variable([$1], [$2])=no
$6],
[m4_fatal([third argument of $0 must be 'yes' or 'no', not '$3'])])])[]dnl
])# PGAC_ARG_BOOL
# PGAC_ARG_REQ(TYPE, NAME, HELP-STRING, [ACTION-IF-GIVEN], [ACTION-IF-NOT-GIVEN])
# -------------------------------------------------------------------------------
# This option will require an argument; "yes" or "no" will not be
# accepted.
AC_DEFUN([PGAC_ARG_REQ],
[PGAC_ARG([$1], [$2], [$3],
[AC_MSG_ERROR([argument required for --$1-$2 option])],
[AC_MSG_ERROR([argument required for --$1-$2 option])],
[$4],
[$5])])# PGAC_ARG_REQ
# PGAC_ARG_OPTARG(TYPE, NAME, HELP-STRING, [DEFAULT-ACTION], [ARG-ACTION]
# [ACTION-ENABLED], [ACTION-DISABLED])
# -----------------------------------------------------------------------
# This will create an option that behaves as follows: If omitted, or
# called with "no", then set the enable_variable to "no" and do
# nothing else. If called with "yes", then execute DEFAULT-ACTION. If
# called with argument, set enable_variable to "yes" and execute
# ARG-ACTION. Additionally, execute ACTION-ENABLED if we ended up with
# "yes" either way, else ACTION-DISABLED.
#
# The intent is to allow enabling a feature, and optionally pass an
# additional piece of information.
AC_DEFUN([PGAC_ARG_OPTARG],
[PGAC_ARG([$1], [$2], [$3], [$4], [],
[pgac_arg_to_variable([$1], [$2])=yes
$5],
[pgac_arg_to_variable([$1], [$2])=no])
dnl Add this code only if there's a ACTION-ENABLED or ACTION-DISABLED.
m4_ifval([$6[]$7],
[
if test "[$]pgac_arg_to_variable([$1], [$2])" = yes; then
m4_default([$6], :)
m4_ifval([$7],
[else
$7
])[]dnl
fi
])[]dnl
])# PGAC_ARG_OPTARG

View File

@ -1,250 +0,0 @@
#! /bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

View File

@ -1,61 +0,0 @@
#
# Autoconf macros for configuring the build of Java JDBC Tools
#
# $Header: /cvsroot/pgsql/config/Attic/java.m4,v 1.4 2002/03/29 17:32:54 petere Exp $
#
# _PGAC_PROG_ANT_WORKS
# --------------------
AC_DEFUN([_PGAC_PROG_ANT_WORKS],
[
AC_CACHE_CHECK([whether $ANT works], [pgac_cv_prog_ant_works],
[
cat > conftest.java << EOF
public class conftest {
int testmethod(int a, int b) {
return a + b;
}
}
EOF
cat > conftest.xml << EOF
<project name="conftest" default="conftest">
<target name="conftest">
<javac srcdir="." includes="conftest.java">
</javac>
</target>
</project>
EOF
pgac_cmd='$ANT -buildfile conftest.xml 1>&2'
AC_TRY_EVAL(pgac_cmd)
pgac_save_status=$?
if test $? = 0 && test -f ./conftest.class ; then
pgac_cv_prog_ant_works=yes
else
echo "configure: failed java program was:" >&AS_MESSAGE_LOG_FD
cat conftest.java >&AS_MESSAGE_LOG_FD
echo "configure: failed build file was:" >&AS_MESSAGE_LOG_FD
cat conftest.xml >&AS_MESSAGE_LOG_FD
pgac_cv_prog_ant_works=no
fi
rm -f conftest* core core.* *.core
])
if test "$pgac_cv_prog_ant_works" != yes; then
AC_MSG_ERROR([ant does not work])
fi
])
# PGAC_PATH_ANT
# -------------
# Look for the ANT tool and set the output variable 'ANT' to 'ant'
# if found, empty otherwise
AC_DEFUN([PGAC_PATH_ANT],
[
AC_PATH_PROGS(ANT, [jakarta-ant ant ant.sh ant.bat])
_PGAC_PROG_ANT_WORKS
])

119
config/libtool.m4 vendored
View File

@ -1,119 +0,0 @@
## libtool.m4 - Configure libtool for the host system. -*-Shell-script-*-
## Copyright (C) 1996-1999,2000 Free Software Foundation, Inc.
## Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## 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 GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
##
## As a special exception to the GNU General Public License, if you
## distribute this file as part of a program that contains a
## configuration script generated by Autoconf, you may include it under
## the same distribution terms that you use for the rest of that program.
# No, PostgreSQL doesn't use libtool (yet), we just borrow stuff from it.
# This file was taken on 2000-10-20 from the multi-language branch (since
# that is the branch that PostgreSQL would most likely adopt anyway).
# --petere
# ... bunch of stuff removed here ...
# AC_PROG_LD - find the path to the GNU or non-GNU linker
AC_DEFUN([AC_PROG_LD],
[AC_ARG_WITH(gnu-ld,
[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
dnl ###not for PostgreSQL### AC_REQUIRE([AC_CANONICAL_BUILD])dnl
ac_prog=ld
if test "$GCC" = yes; then
# Check if gcc -print-prog-name=ld gives a path.
AC_MSG_CHECKING([for ld used by GCC])
case $host in
*-*-mingw*)
# gcc leaves a trailing carriage return which upsets mingw
ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
*)
ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
esac
case "$ac_prog" in
# Accept absolute paths.
changequote(,)dnl
[\\/]* | [A-Za-z]:[\\/]*)
re_direlt='/[^/][^/]*/\.\./'
changequote([,])dnl
# Canonicalize the path of ld
ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
done
test -z "$LD" && LD="$ac_prog"
;;
"")
# If it fails, then pretend we aren't using GCC.
ac_prog=ld
;;
*)
# If it is relative, then search for the first ld in PATH.
with_gnu_ld=unknown
;;
esac
elif test "$with_gnu_ld" = yes; then
AC_MSG_CHECKING([for GNU ld])
else
AC_MSG_CHECKING([for non-GNU ld])
fi
AC_CACHE_VAL(ac_cv_path_LD,
[if test -z "$LD"; then
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
for ac_dir in $PATH; do
test -z "$ac_dir" && ac_dir=.
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
ac_cv_path_LD="$ac_dir/$ac_prog"
# Check to see if the program is GNU ld. I'd rather use --version,
# but apparently some GNU ld's only accept -v.
# Break only if it was the GNU/non-GNU ld that we prefer.
if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
test "$with_gnu_ld" != no && break
else
test "$with_gnu_ld" != yes && break
fi
fi
done
IFS="$ac_save_ifs"
else
ac_cv_path_LD="$LD" # Let the user override the test with a path.
fi])
LD="$ac_cv_path_LD"
if test -n "$LD"; then
AC_MSG_RESULT($LD)
else
AC_MSG_RESULT(no)
fi
test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
AC_PROG_LD_GNU
])
AC_DEFUN([AC_PROG_LD_GNU],
[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
ac_cv_prog_gnu_ld=yes
else
ac_cv_prog_gnu_ld=no
fi])
with_gnu_ld=$ac_cv_prog_gnu_ld
])
# ... more stuff removed ...

View File

@ -1,33 +0,0 @@
#! /bin/sh
# This is *not* the GNU `missing' script, although it is similar in
# concept. You can call it from the makefiles to get consistent
# behavior when certain utility programs are missing.
case $1 in
flex|bison)
# `missing flex|bison <input> <output>'
input=$2
output=$3
if test -f "$output"; then
echo "\
***
WARNING: \`$1' is missing on your system. You should only need it
if you changed the file \`$input'; these changes will not take effect.
You can get $1 from a GNU mirror site.
***"
echo "touch $output"
touch "$output"
exit 0
else # ! test -f $output
echo "\
***
ERROR: \`$1' is missing on your system. It is needed to create the
file \`$output'. You can either get $1 from a GNU mirror site
or download an official distribution of PostgreSQL, which contains
pre-packaged $1 output.
***"
exit 1
fi
;;
esac

View File

@ -1,36 +0,0 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Last modified: 1994-03-25
# Public domain
errstatus=0
for file in ${1+"$@"} ; do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d in ${1+"$@"} ; do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp" 1>&2
mkdir "$pathcomp" > /dev/null 2>&1 || lasterr=$?
fi
if test ! -d "$pathcomp"; then
errstatus=$lasterr
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# mkinstalldirs ends here

View File

@ -1,35 +0,0 @@
# $Header: /cvsroot/pgsql/config/perl.m4,v 1.2 2002/05/28 16:57:53 petere Exp $
# PGAC_PATH_PERL
# --------------
AC_DEFUN([PGAC_PATH_PERL],
[AC_PATH_PROG(PERL, perl)])
# PGAC_CHECK_PERL_CONFIG(NAME)
# ----------------------------
AC_DEFUN([PGAC_CHECK_PERL_CONFIG],
[AC_REQUIRE([PGAC_PATH_PERL])
AC_MSG_CHECKING([for Perl $1])
perl_$1=`$PERL -MConfig -e 'print $Config{$1}'`
AC_SUBST(perl_$1)dnl
AC_MSG_RESULT([$perl_$1])])
# PGAC_CHECK_PERL_CONFIGS(NAMES)
# ------------------------------
AC_DEFUN([PGAC_CHECK_PERL_CONFIGS],
[m4_foreach([pgac_item], [$1], [PGAC_CHECK_PERL_CONFIG(pgac_item)])])
# PGAC_CHECK_PERL_EMBED_LDFLAGS
# -----------------------------
AC_DEFUN([PGAC_CHECK_PERL_EMBED_LDFLAGS],
[AC_REQUIRE([PGAC_PATH_PERL])
AC_MSG_CHECKING(for flags to link embedded Perl)
pgac_tmp1=`$PERL -MExtUtils::Embed -e ldopts`
pgac_tmp2=`$PERL -MConfig -e 'print $Config{ccdlflags}'`
perl_embed_ldflags=`echo X"$pgac_tmp1" | sed "s/^X//;s%$pgac_tmp2%%"`
AC_SUBST(perl_embed_ldflags)dnl
AC_MSG_RESULT([$perl_embed_ldflags])])

View File

@ -1,41 +0,0 @@
#! /bin/sh
# This script prepares a PostgreSQL build tree. It is intended
# to be run by the configure script.
me=`basename $0`
help="\
Usage: $me sourcetree [buildtree]"
if test -z "$1"; then
echo "$help" 1>&2
exit 1
elif test x"$1" = x"--help"; then
echo "$help"
exit 0
fi
unset CDPATH
sourcetree=`cd $1 && pwd`
buildtree=`cd ${2:-'.'} && pwd`
for item in `find "$sourcetree" -type d \( -name CVS -prune -o -print \)`; do
subdir=`expr "$item" : "$sourcetree\(.*\)"`
if test ! -d "$buildtree/$subdir"; then
mkdir -p "$buildtree/$subdir" || exit 1
fi
done
for item in `find "$sourcetree" -name Makefile -print -o -name GNUmakefile -print`; do
filename=`expr "$item" : "$sourcetree\(.*\)"`
if test ! -f "${item}.in"; then
if cmp "$item" "$buildtree/$filename" >/dev/null 2>&1; then : ; else
ln -fs "$item" "$buildtree/$filename" || exit 1
fi
fi
done
exit 0

View File

@ -1,192 +0,0 @@
# $Header: /cvsroot/pgsql/config/programs.m4,v 1.10 2002/04/10 22:46:33 petere Exp $
# PGAC_PATH_FLEX
# --------------
# Look for Flex, set the output variable FLEX to its path if found.
# Avoid the buggy version 2.5.3. Also find Flex if its installed
# under `lex', but do not accept other Lex programs.
AC_DEFUN([PGAC_PATH_FLEX],
[AC_CACHE_CHECK([for flex], pgac_cv_path_flex,
[# Let the user override the test
if test -n "$FLEX"; then
pgac_cv_path_flex=$FLEX
else
pgac_save_IFS=$IFS
IFS=:
for pgac_dir in $PATH; do
if test -z "$pgac_dir" || test x"$pgac_dir" = x"."; then
pgac_dir=`pwd`
fi
for pgac_prog in flex lex; do
pgac_candidate="$pgac_dir/$pgac_prog"
if test -f "$pgac_candidate" \
&& $pgac_candidate --version </dev/null >/dev/null 2>&1
then
echo '%%' > conftest.l
if $pgac_candidate -t conftest.l 2>/dev/null | grep FLEX_SCANNER >/dev/null 2>&1; then
if $pgac_candidate --version | grep '2\.5\.3' >/dev/null 2>&1; then
pgac_broken_flex=$pgac_candidate
continue
fi
pgac_cv_path_flex=$pgac_candidate
break 2
fi
fi
done
done
IFS=$pgac_save_IFS
rm -f conftest.l
: ${pgac_cv_path_flex=no}
fi
])[]dnl AC_CACHE_CHECK
if test x"$pgac_cv_path_flex" = x"no"; then
if test -n "$pgac_broken_flex"; then
AC_MSG_WARN([
*** The Flex version 2.5.3 you have at $pgac_broken_flex contains a bug. You
*** should get version 2.5.4 or later.])
fi
AC_MSG_WARN([
*** Without Flex you will not be able to build PostgreSQL from CVS or
*** change any of the scanner definition files. You can obtain Flex from
*** a GNU mirror site. (If you are using the official distribution of
*** PostgreSQL then you do not need to worry about this because the Flex
*** output is pre-generated.)])
fi
if test x"$pgac_cv_path_flex" = x"no"; then
FLEX=
else
FLEX=$pgac_cv_path_flex
fi
AC_SUBST(FLEX)
AC_SUBST(FLEXFLAGS)
])# PGAC_PATH_FLEX
# PGAC_CHECK_READLINE
# -------------------
# Check for the readline library and dependent libraries, either
# termcap or curses. Also try libedit, since NetBSD's is compatible.
# Add the required flags to LIBS, define HAVE_LIBREADLINE.
AC_DEFUN([PGAC_CHECK_READLINE],
[AC_REQUIRE([AC_CANONICAL_HOST])
AC_MSG_CHECKING([for readline])
AC_CACHE_VAL([pgac_cv_check_readline],
[pgac_cv_check_readline=no
for pgac_lib in "" " -ltermcap" " -lncurses" " -lcurses" ; do
for pgac_rllib in -lreadline -ledit ; do
pgac_save_LIBS=$LIBS
LIBS="${pgac_rllib}${pgac_lib} $LIBS"
AC_TRY_LINK_FUNC([readline], [[
# NetBSD and OpenBSD have a broken linker that does not
# recognize dependent libraries
case $host_os in netbsd* | openbsd* )
case $pgac_lib in
*curses*) ;;
*) pgac_lib=" -lcurses" ;;
esac
esac
pgac_cv_check_readline="${pgac_rllib}${pgac_lib}"
break 2
]])
LIBS=$pgac_save_LIBS
done
done
LIBS=$pgac_save_LIBS
])[]dnl AC_CACHE_VAL
if test "$pgac_cv_check_readline" != no ; then
AC_DEFINE(HAVE_LIBREADLINE, 1, [Define if you have a function readline library])
LIBS="$pgac_cv_check_readline $LIBS"
AC_MSG_RESULT([yes ($pgac_cv_check_readline)])
else
AC_MSG_RESULT(no)
fi])# PGAC_CHECK_READLINE
# PGAC_VAR_RL_COMPLETION_APPEND_CHARACTER
# ---------------------------------------
# Readline versions < 2.1 don't have rl_completion_append_character
AC_DEFUN([PGAC_VAR_RL_COMPLETION_APPEND_CHARACTER],
[AC_MSG_CHECKING([for rl_completion_append_character])
AC_TRY_LINK([#include <stdio.h>
#ifdef HAVE_READLINE_READLINE_H
# include <readline/readline.h>
#elif defined(HAVE_READLINE_H)
# include <readline.h>
#endif
],
[rl_completion_append_character = 'x';],
[AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_RL_COMPLETION_APPEND_CHARACTER, 1,
[Define if you have rl_completion_append_character])],
[AC_MSG_RESULT(no)])])# PGAC_VAR_RL_COMPLETION_APPEND_CHARACTER
# PGAC_CHECK_GETTEXT
# ------------------
AC_DEFUN([PGAC_CHECK_GETTEXT],
[
AC_SEARCH_LIBS(gettext, intl, [],
[AC_MSG_ERROR([a gettext implementation is required for NLS])])
AC_CHECK_HEADER([libintl.h], [],
[AC_MSG_ERROR([header file <libintl.h> is required for NLS])])
AC_CHECK_PROGS(MSGFMT, msgfmt)
if test -z "$MSGFMT"; then
AC_MSG_ERROR([msgfmt is required for NLS])
fi
AC_CHECK_PROGS(MSGMERGE, msgmerge)
dnl FIXME: We should probably check for version >=0.10.36.
AC_CHECK_PROGS(XGETTEXT, xgettext)
# Note: share/locale is always the default, independent of $datadir
localedir='${prefix}/share/locale'
if test x"$prefix" = x"NONE"; then
exp_localedir="$ac_default_prefix/share/locale"
else
exp_localedir="$prefix/share/locale"
fi
AC_SUBST(localedir)
AC_DEFINE_UNQUOTED(LOCALEDIR, ["$exp_localedir"],
[location of locale files])
])# PGAC_CHECK_GETTEXT
# PGAC_CHECK_STRIP
# ----------------
# Check for a 'strip' program, and figure out if that program can
# strip libraries.
AC_DEFUN([PGAC_CHECK_STRIP],
[
AC_CHECK_TOOL(STRIP, strip, :)
AC_MSG_CHECKING([whether it is possible to strip libraries])
if test x"$STRIP" != x"" && "$STRIP" -V 2>&1 | grep "GNU strip" >/dev/null; then
STRIP_STATIC_LIB="$STRIP -x"
STRIP_SHARED_LIB="$STRIP --strip-unneeded"
AC_MSG_RESULT(yes)
else
STRIP_STATIC_LIB=:
STRIP_SHARED_LIB=:
AC_MSG_RESULT(no)
fi
AC_SUBST(STRIP_STATIC_LIB)
AC_SUBST(STRIP_SHARED_LIB)
])# PGAC_CHECK_STRIP

View File

@ -1,84 +0,0 @@
#
# Autoconf macros for configuring the build of Python extension modules
#
# $Header: /cvsroot/pgsql/config/python.m4,v 1.4 2002/03/29 17:32:54 petere Exp $
#
# PGAC_PATH_PYTHON
# ----------------
# Look for Python and set the output variable 'PYTHON'
# to 'python' if found, empty otherwise.
AC_DEFUN([PGAC_PATH_PYTHON],
[AC_PATH_PROG(PYTHON, python)
if test x"$PYTHON" = x""; then
AC_MSG_ERROR([Python not found])
fi
])
# _PGAC_CHECK_PYTHON_DIRS
# -----------------------
# Determine the name of various directory of a given Python installation.
AC_DEFUN([_PGAC_CHECK_PYTHON_DIRS],
[AC_REQUIRE([PGAC_PATH_PYTHON])
AC_MSG_CHECKING([Python installation directories])
python_version=`${PYTHON} -c "import sys; print sys.version[[:3]]"`
python_prefix=`${PYTHON} -c "import sys; print sys.prefix"`
python_execprefix=`${PYTHON} -c "import sys; print sys.exec_prefix"`
python_configdir="${python_execprefix}/lib/python${python_version}/config"
python_moduledir="${python_prefix}/lib/python${python_version}/site-packages"
python_moduleexecdir="${python_execprefix}/lib/python${python_version}/site-packages"
python_includespec="-I${python_prefix}/include/python${python_version}"
if test "$python_prefix" != "$python_execprefix"; then
python_includespec="-I${python_execprefix}/include/python${python_version} $python_includespec"
fi
AC_SUBST(python_version)[]dnl
AC_SUBST(python_prefix)[]dnl
AC_SUBST(python_execprefix)[]dnl
AC_SUBST(python_configdir)[]dnl
AC_SUBST(python_moduledir)[]dnl
AC_SUBST(python_moduleexecdir)[]dnl
AC_SUBST(python_includespec)[]dnl
# This should be enough of a message.
if test "$python_prefix" != "$python_execprefix"; then
AC_MSG_RESULT([$python_prefix/lib/python${python_version} and $python_execprefix/lib/python${python_version}])
else
AC_MSG_RESULT([$python_prefix/lib/python${python_version}])
fi
])# _PGAC_CHECK_PYTHON_DIRS
# PGAC_CHECK_PYTHON_MODULE_SETUP
# ------------------------------
# Finds things required to build a Python extension module.
# This used to do more, that's why it's separate.
#
# It would be nice if we could check whether the current setup allows
# the build of the shared module. Future project.
AC_DEFUN([PGAC_CHECK_PYTHON_MODULE_SETUP],
[
AC_REQUIRE([_PGAC_CHECK_PYTHON_DIRS])
])# PGAC_CHECK_PYTHON_MODULE_SETUP
# PGAC_CHECK_PYTHON_EMBED_SETUP
# -----------------------------
# Courtesy of the INN 2.3.1 package...
AC_DEFUN([PGAC_CHECK_PYTHON_EMBED_SETUP],
[AC_REQUIRE([_PGAC_CHECK_PYTHON_DIRS])
AC_MSG_CHECKING([how to link an embedded Python application])
_python_libs=`grep '^LIBS=' $python_configdir/Makefile | sed 's/^.*=//'`
_python_libc=`grep '^LIBC=' $python_configdir/Makefile | sed 's/^.*=//'`
_python_libm=`grep '^LIBM=' $python_configdir/Makefile | sed 's/^.*=//'`
_python_liblocalmod=`grep '^LOCALMODLIBS=' $python_configdir/Makefile | sed 's/^.*=//'`
_python_libbasemod=`grep '^BASEMODLIBS=' $python_configdir/Makefile | sed 's/^.*=//'`
pgac_tab=" " # tab character
python_libspec=`echo X"-L$python_configdir $_python_libs $_python_libc $_python_libm -lpython$python_version $_python_liblocalmod $_python_libbasemod" | sed -e 's/^X//' -e "s/[[ $pgac_tab]][[ $pgac_tab]]*/ /g"`
AC_MSG_RESULT([${python_libspec}])
AC_SUBST(python_libspec)[]dnl
])# PGAC_CHECK_PYTHON_EMBED_SETUP

View File

@ -1,89 +0,0 @@
# $Header: /cvsroot/pgsql/config/tcl.m4,v 1.4 2002/05/24 18:10:17 petere Exp $
# Autoconf macros to check for Tcl related things
AC_DEFUN([PGAC_PATH_TCLSH],
[AC_PATH_PROGS(TCLSH, [tclsh tcl])])
# PGAC_PATH_TCLCONFIGSH([SEARCH-PATH])
# ------------------------------------
AC_DEFUN([PGAC_PATH_TCLCONFIGSH],
[AC_REQUIRE([PGAC_PATH_TCLSH])[]dnl
AC_BEFORE([$0], [PGAC_PATH_TKCONFIGSH])[]dnl
AC_MSG_CHECKING([for tclConfig.sh])
# Let user override test
if test -z "$TCL_CONFIG_SH"; then
pgac_test_dirs="$1"
set X $pgac_test_dirs; shift
if test $[#] -eq 0; then
test -z "$TCLSH" && AC_MSG_ERROR([unable to locate tclConfig.sh because no Tcl shell was found])
set X `echo 'puts $auto_path' | $TCLSH`; shift
fi
for pgac_dir do
if test -r "$pgac_dir/tclConfig.sh"; then
TCL_CONFIG_SH=$pgac_dir/tclConfig.sh
break
fi
done
fi
if test -z "$TCL_CONFIG_SH"; then
AC_MSG_RESULT(no)
AC_MSG_ERROR([file 'tclConfig.sh' is required for Tcl])
else
AC_MSG_RESULT([$TCL_CONFIG_SH])
fi
AC_SUBST([TCL_CONFIG_SH])
])# PGAC_PATH_TCLCONFIGSH
# PGAC_PATH_TKCONFIGSH([SEARCH-PATH])
# ------------------------------------
AC_DEFUN([PGAC_PATH_TKCONFIGSH],
[AC_REQUIRE([PGAC_PATH_TCLSH])[]dnl
AC_MSG_CHECKING([for tkConfig.sh])
# Let user override test
if test -z "$TK_CONFIG_SH"; then
pgac_test_dirs="$1"
set X $pgac_test_dirs; shift
if test $[#] -eq 0; then
test -z "$TCLSH" && AC_MSG_ERROR([unable to locate tkConfig.sh because no Tcl shell was found])
set X `echo 'puts $auto_path' | $TCLSH`; shift
fi
for pgac_dir do
if test -r "$pgac_dir/tkConfig.sh"; then
TK_CONFIG_SH=$pgac_dir/tkConfig.sh
break
fi
done
fi
if test -z "$TK_CONFIG_SH"; then
AC_MSG_RESULT(no)
AC_MSG_ERROR([file 'tkConfig.sh' is required for Tk])
else
AC_MSG_RESULT([$TK_CONFIG_SH])
fi
AC_SUBST([TK_CONFIG_SH])
])# PGAC_PATH_TKCONFIGSH
# PGAC_EVAL_TCLCONFIGSH(FILE, WANTED-VARS)
# ----------------------------------------
# Assigns variables listed in WANTED-VARS by reading FILE and
# evaluating it according to the quoting scheme of tclConfig.sh and
# tkConfig.sh. Calls AC_SUBST for each variable.
AC_DEFUN([PGAC_EVAL_TCLCONFIGSH],
[. "$1"
m4_foreach([pgac_item], [$2],
[eval pgac_item=\"[$]pgac_item\"
AC_SUBST(pgac_item)])])

18038
configure vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,60 +0,0 @@
# $Header: /cvsroot/pgsql/contrib/Makefile,v 1.31 2002/02/22 23:05:34 momjian Exp $
subdir = contrib
top_builddir = ..
include $(top_builddir)/src/Makefile.global
WANTED_DIRS = \
array \
btree_gist \
chkpass \
cube \
dbase \
dblink \
dbsize \
earthdistance \
findoidjoins \
fulltextindex \
fuzzystrmatch \
intarray \
isbn_issn \
lo \
miscutil \
noupdate \
oid2name \
pg_controldata \
pg_dumplo \
pg_logger \
pg_resetxlog \
pgbench \
pgcrypto \
pgstattuple \
rserv \
rtree_gist \
seg \
spi \
string \
tips \
tsearch \
userlock \
vacuumlo
ifeq ($(with_java),yes)
WANTED_DIRS += retep
endif
# Missing:
# ipc_check \ (does not have a makefile)
# mSQL-interface \ (requires msql installed)
# mac \ (does not have a makefile)
# mysql \ (does not have a makefile)
# oracle \ (does not have a makefile)
# start-scripts \ (does not have a makefile)
# tools \ (does not have a makefile)
# xml \ (non-standard makefile)
all install installdirs uninstall clean distclean maintainer-clean check installcheck:
@for dir in $(WANTED_DIRS); do \
$(MAKE) -C $$dir $@ || exit; \
done

View File

@ -1,205 +0,0 @@
The PostgreSQL contrib tree
---------------------------
This subtree contains porting tools, analysis utilities, and plug-in
features that are not part of the core PostgreSQL system, mainly because
they address a limited audience or are too experimental to be part of
the main source tree. This does not preclude their usefulness.
Each subdirectory contains a README file with information about the
module. Most items can be built with `gmake all' and installed with
`gmake install' in the usual fashion, after you have run the `configure'
script in the top-level directory. Some directories supply new
user-defined functions, operators, or types. After you have installed
the files you need to register the new entities in the database system
by running the commands in the supplied .sql file. For example,
$ psql -d dbname -f module.sql
See the PostgreSQL documentation for more information about this
procedure.
Index:
------
array -
Array iterator functions
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@stack.net>
chkpass -
An auto-encrypted password datatype
by D'Arcy J.M. Cain <darcy@druid.net>
cube -
Multidimensional-cube datatype (GiST indexing example)
by Gene Selkov, Jr. <selkovjr@mcs.anl.gov>
dbase -
Converts from dbase/xbase to PostgreSQL
by Maarten.Boekhold <Maarten.Boekhold@reuters.com>,
Frank Koormann <fkoorman@usf.uni-osnabrueck.de>,
Ivan Baldo <lubaldo@adinet.com.uy>
dblink -
Allows remote query execution
by Joe Conway <joe.conway@mail.com>
dbsize -
Reports database and table disk space
by Peter Eisentraut <peter_e@gmx.net>
earthdistance -
Operator for computing earth distance for two points
by Hal Snyder <hal@vailsys.com>
findoidjoins -
Finds the joins used by oid columns by examining the actual
values in the oid columns and row oids.
by Bruce Momjian <pgman@candle.pha.pa.us>
fulltextindex -
Full text indexing using triggers
by Maarten Boekhold <maartenb@dutepp0.et.tudelft.nl>
fuzzystrmatch -
Levenshtein, metaphone, and soundex fuzzy string matching
by Joe Conway <joseph.conway@home.com>, Joel Burton <jburton@scw.org>
intagg -
Integer aggregator
by mlw <markw@mohawksoft.com>
intarray -
Index support for arrays of int4, using GiST
by Teodor Sigaev <teodor@stack.net> 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>
lo -
Large Object maintenance
by Peter Mount <peter@retep.org.uk>
mSQL-interface -
mSQL API translation library
by Aldrin Leal <aldrin@americasnet.com>
mac -
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>
oracle -
converts Oracle database schema to PostgreSQL
by Gilles Darold <gilles@darold.net>
pg_controldata -
Dump contents of pg_control (database master file)
by Oliver Elphick <olly@lfix.co.uk>
pg_dumplo -
Dump large objects
by Karel Zak <zakkr@zf.jcu.cz>
pg_logger -
Stdin-to-syslog gateway for PostgreSQL
by Nathan Myers <ncm@nospam.cantrip.org>
pg_resetxlog -
Reset the WAL log (pg_xlog) to recover from crash or format change
by Tom Lane <tgl@sss.pgh.pa.us>
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>
pgcrypto -
Cryptographic functions
by Marko Kreen <marko@l-t.ee>
pgstattuple -
A function returns the percentage of "dead" tuples in a table
by Tatsuo Ishii <t-ishii@sra.co.jp>
retep -
tools to build retep tools packages
by Peter T Mount <peter@retep.org.uk>
rserv -
replication server
by Vadim B. Mikheev <vadim4o@email.com>
rtree_gist -
Support for emulating RTREE indexing in GiST
by Oleg Bartunov <oleg@sai.msu.su> and Teodor Sigaev <teodor@stack.net>
seg -
Confidence-interval datatype (GiST indexing example)
by Gene Selkov, Jr. <selkovjr@mcs.anl.gov>
spi -
Various trigger functions, examples for using SPI.
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>
tips/apache_logging -
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
by Teodor Sigaev <teodor@stack.net> and Oleg Bartunov
<oleg@sai.msu.su>.
userlock -
User locks
by Massimo Dal Zotto <dz@cs.unitn.it>
vacuumlo -
Remove orphaned large objects
by Peter T Mount <peter@retep.org.uk>
xml -
Storing XML in PostgreSQL
by John Gray <jgray@azuli.co.uk>

View File

@ -1,11 +0,0 @@
# $Header: /cvsroot/pgsql/contrib/array/Attic/Makefile,v 1.16 2001/09/06 10:49:29 petere Exp $
subdir = contrib/array
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
MODULES = array_iterator
DATA_built = array_iterator.sql
DOCS = README.array_iterator
include $(top_srcdir)/contrib/contrib-global.mk

View File

@ -1,49 +0,0 @@
Array iterator functions, by Massimo Dal Zotto <dz@cs.unitn.it>
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.
This loadable module defines a new class of functions which take
an array and a scalar value, iterate a scalar operator over the
elements of the array and the value, and compute a result as
the logical OR or AND of the iteration results.
For example array_int4eq returns true if some of the elements
of an array of int4 is equal to the given value:
array_int4eq({1,2,3}, 1) --> true
array_int4eq({1,2,3}, 4) --> false
If we have defined T array types and O scalar operators we can
define T x O x 2 array functions, each of them has a name like
"array_[all_]<basetype><operation>" and takes an array of type T
iterating the operator O over all the elements. Note however
that some of the possible combination are invalid, for example
the array_int4_like because there is no like operator for int4.
We can then define new operators based on these functions and use
them to write queries with qualification clauses based on the
values of some of the elements of an array.
For example to select rows having some or all element of an array
attribute equal to a given value or matching a regular expression:
create table t(id int4[], txt text[]);
-- select tuples with some id element equal to 123
select * from t where t.id *= 123;
-- select tuples with some txt element matching '[a-z]'
select * from t where t.txt *~ '[a-z]';
-- select tuples with all txt elements matching '^[A-Z]'
select * from t where t.txt[1:3] **~ '^[A-Z]';
The scheme is quite general, each operator which operates on a base type
can be iterated over the elements of an array. It seem to work well but
defining each new operators requires writing a different C function.
Furthermore in each function there are two hardcoded OIDs which reference
a base type and a procedure. Not very portable. Can anyone suggest a
better and more portable way to do it ?
See also array_iterator.sql for an example on how to use this module.

View File

@ -1,372 +0,0 @@
/*
* array_iterator.c --
*
* This file defines a new class of operators which take an
* array and a scalar value, iterate a scalar operator over the
* elements of the array and the value and compute a result as
* the logical OR or AND of the iteration results.
*
* Copyright (C) 1999, Massimo Dal Zotto <dz@cs.unitn.it>
* ported to postgreSQL 6.3.2,added oid_functions, 18.1.1999,
* Tobias Gabele <gabele@wiz.uni-kassel.de>
*
* This software is distributed under the GNU General Public License
* either version 2, or (at your option) any later version.
*/
#include "postgres.h"
#include <ctype.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include "access/tupmacs.h"
#include "access/xact.h"
#include "fmgr.h"
#include "miscadmin.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
#include "utils/lsyscache.h"
#include "array_iterator.h"
static int32
array_iterator(Oid elemtype, Oid proc, int and, ArrayType *array, Datum value)
{
int16 typlen;
bool typbyval;
int nitems,
i;
Datum result;
int ndim,
*dim;
char *p;
FmgrInfo finfo;
/* Sanity checks */
if (array == (ArrayType *) NULL)
{
/* elog(WARNING, "array_iterator: array is null"); */
return (0);
}
/* detoast input if necessary */
array = DatumGetArrayTypeP(PointerGetDatum(array));
ndim = ARR_NDIM(array);
dim = ARR_DIMS(array);
nitems = ArrayGetNItems(ndim, dim);
if (nitems == 0)
return (0);
/* Lookup element type information */
get_typlenbyval(elemtype, &typlen, &typbyval);
/* Lookup the function entry point */
fmgr_info(proc, &finfo);
if (finfo.fn_nargs != 2)
{
elog(ERROR, "array_iterator: proc %u does not take 2 args", proc);
return (0);
}
/* Scan the array and apply the operator to each element */
result = BoolGetDatum(false);
p = ARR_DATA_PTR(array);
for (i = 0; i < nitems; i++)
{
Datum itemvalue;
itemvalue = fetch_att(p, typbyval, typlen);
if (typlen > 0)
p += typlen;
else
p += INTALIGN(*(int32 *) p);
result = FunctionCall2(&finfo, itemvalue, value);
if (DatumGetBool(result))
{
if (!and)
return (1);
}
else
{
if (and)
return (0);
}
}
if (and && DatumGetBool(result))
return (1);
else
return (0);
}
/*
* Iterator functions for type _text
*/
int32
array_texteq(ArrayType *array, char *value)
{
return array_iterator((Oid) 25, /* text */
(Oid) 67, /* texteq */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_texteq(ArrayType *array, char *value)
{
return array_iterator((Oid) 25, /* text */
(Oid) 67, /* texteq */
1, /* logical and */
array, (Datum) value);
}
int32
array_textregexeq(ArrayType *array, char *value)
{
return array_iterator((Oid) 25, /* text */
(Oid) 1254, /* textregexeq */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_textregexeq(ArrayType *array, char *value)
{
return array_iterator((Oid) 25, /* text */
(Oid) 1254, /* textregexeq */
1, /* logical and */
array, (Datum) value);
}
/*
* Iterator functions for type _varchar. Note that the regexp
* operators take the second argument of type text.
*/
int32
array_varchareq(ArrayType *array, char *value)
{
return array_iterator((Oid) 1043, /* varchar */
(Oid) 1070, /* varchareq */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_varchareq(ArrayType *array, char *value)
{
return array_iterator((Oid) 1043, /* varchar */
(Oid) 1070, /* varchareq */
1, /* logical and */
array, (Datum) value);
}
int32
array_varcharregexeq(ArrayType *array, char *value)
{
return array_iterator((Oid) 1043, /* varchar */
(Oid) 1254, /* textregexeq */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_varcharregexeq(ArrayType *array, char *value)
{
return array_iterator((Oid) 1043, /* varchar */
(Oid) 1254, /* textregexeq */
1, /* logical and */
array, (Datum) value);
}
/*
* Iterator functions for type _bpchar. Note that the regexp
* operators take the second argument of type text.
*/
int32
array_bpchareq(ArrayType *array, char *value)
{
return array_iterator((Oid) 1042, /* bpchar */
(Oid) 1048, /* bpchareq */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_bpchareq(ArrayType *array, char *value)
{
return array_iterator((Oid) 1042, /* bpchar */
(Oid) 1048, /* bpchareq */
1, /* logical and */
array, (Datum) value);
}
int32
array_bpcharregexeq(ArrayType *array, char *value)
{
return array_iterator((Oid) 1042, /* bpchar */
(Oid) 1254, /* textregexeq */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_bpcharregexeq(ArrayType *array, char *value)
{
return array_iterator((Oid) 1042, /* bpchar */
(Oid) 1254, /* textregexeq */
1, /* logical and */
array, (Datum) value);
}
/*
* Iterator functions for type _int4
*/
int32
array_int4eq(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 65, /* int4eq */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_int4eq(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 65, /* int4eq */
1, /* logical and */
array, (Datum) value);
}
int32
array_int4ne(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 144, /* int4ne */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_int4ne(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 144, /* int4ne */
1, /* logical and */
array, (Datum) value);
}
int32
array_int4gt(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 147, /* int4gt */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_int4gt(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 147, /* int4gt */
1, /* logical and */
array, (Datum) value);
}
int32
array_int4ge(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 150, /* int4ge */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_int4ge(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 150, /* int4ge */
1, /* logical and */
array, (Datum) value);
}
int32
array_int4lt(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 66, /* int4lt */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_int4lt(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 66, /* int4lt */
1, /* logical and */
array, (Datum) value);
}
int32
array_int4le(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 149, /* int4le */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_int4le(ArrayType *array, int4 value)
{
return array_iterator((Oid) 23, /* int4 */
(Oid) 149, /* int4le */
1, /* logical and */
array, (Datum) value);
}
/* new tobias gabele 1999 */
int32
array_oideq(ArrayType *array, Oid value)
{
return array_iterator((Oid) 26, /* oid */
(Oid) 184, /* oideq */
0, /* logical or */
array, (Datum) value);
}
int32
array_all_oidne(ArrayType *array, Oid value)
{
return array_iterator((Oid) 26, /* int4 */
(Oid) 185, /* oidne */
1, /* logical and */
array, (Datum) value);
}
/* end of file */
/*
* Local Variables:
* tab-width: 4
* c-indent-level: 4
* c-basic-offset: 4
* End:
*/

View File

@ -1,45 +0,0 @@
#ifndef ARRAY_ITERATOR_H
#define ARRAY_ITERATOR_H
static int32 array_iterator(Oid elemtype, Oid proc, int and,
ArrayType *array, Datum value);
int32 array_texteq(ArrayType *array, char *value);
int32 array_all_texteq(ArrayType *array, char *value);
int32 array_textregexeq(ArrayType *array, char *value);
int32 array_all_textregexeq(ArrayType *array, char *value);
int32 array_varchareq(ArrayType *array, char *value);
int32 array_all_varchareq(ArrayType *array, char *value);
int32 array_varcharregexeq(ArrayType *array, char *value);
int32 array_all_varcharregexeq(ArrayType *array, char *value);
int32 array_bpchareq(ArrayType *array, char *value);
int32 array_all_bpchareq(ArrayType *array, char *value);
int32 array_bpcharregexeq(ArrayType *array, char *value);
int32 array_all_bpcharregexeq(ArrayType *array, char *value);
int32 array_int4eq(ArrayType *array, int4 value);
int32 array_all_int4eq(ArrayType *array, int4 value);
int32 array_int4ne(ArrayType *array, int4 value);
int32 array_all_int4ne(ArrayType *array, int4 value);
int32 array_int4gt(ArrayType *array, int4 value);
int32 array_all_int4gt(ArrayType *array, int4 value);
int32 array_int4ge(ArrayType *array, int4 value);
int32 array_all_int4ge(ArrayType *array, int4 value);
int32 array_int4lt(ArrayType *array, int4 value);
int32 array_all_int4lt(ArrayType *array, int4 value);
int32 array_int4le(ArrayType *array, int4 value);
int32 array_all_int4le(ArrayType *array, int4 value);
int32 array_oideq(ArrayType *array, Oid value);
int32 array_all_oidne(ArrayType *array, Oid value);
#endif
/*
* Local Variables:
* tab-width: 4
* c-indent-level: 4
* c-basic-offset: 4
* End:
*/

View File

@ -1,253 +0,0 @@
-- SQL code to define the new array iterator functions and operators
-- define the array operators *=, **=, *~ and **~ for type _text
--
create function array_texteq(_text, text) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_all_texteq(_text, text) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_textregexeq(_text, text) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_all_textregexeq(_text, text) returns bool
as 'MODULE_PATHNAME'
language 'c';
create operator *= (
leftarg=_text,
rightarg=text,
procedure=array_texteq);
create operator **= (
leftarg=_text,
rightarg=text,
procedure=array_all_texteq);
create operator *~ (
leftarg=_text,
rightarg=text,
procedure=array_textregexeq);
create operator **~ (
leftarg=_text,
rightarg=text,
procedure=array_all_textregexeq);
-- define the array operators *=, **=, *~ and **~ for type _varchar
--
-- NOTE: "varchar" is also a reserved word and must be quoted.
--
create function array_varchareq(_varchar, varchar) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_all_varchareq(_varchar, varchar) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_varcharregexeq(_varchar, varchar) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_all_varcharregexeq(_varchar, varchar) returns bool
as 'MODULE_PATHNAME'
language 'c';
create operator *= (
leftarg=_varchar,
rightarg="varchar",
procedure=array_varchareq);
create operator **= (
leftarg=_varchar,
rightarg="varchar",
procedure=array_all_varchareq);
create operator *~ (
leftarg=_varchar,
rightarg="varchar",
procedure=array_varcharregexeq);
create operator **~ (
leftarg=_varchar,
rightarg="varchar",
procedure=array_all_varcharregexeq);
-- define the array operators *=, **=, *~ and **~ for type _bpchar
--
create function array_bpchareq(_bpchar, bpchar) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_all_bpchareq(_bpchar, bpchar) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_bpcharregexeq(_bpchar, bpchar) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_all_bpcharregexeq(_bpchar, bpchar) returns bool
as 'MODULE_PATHNAME'
language 'c';
create operator *= (
leftarg=_bpchar,
rightarg=bpchar,
procedure=array_bpchareq);
create operator **= (
leftarg=_bpchar,
rightarg=bpchar,
procedure=array_all_bpchareq);
create operator *~ (
leftarg=_bpchar,
rightarg=bpchar,
procedure=array_bpcharregexeq);
create operator **~ (
leftarg=_bpchar,
rightarg=bpchar,
procedure=array_all_bpcharregexeq);
-- define the array operators *=, **=, *> and **> for type _int4
--
create function array_int4eq(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_all_int4eq(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_int4ne(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_all_int4ne(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_int4gt(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_all_int4gt(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_int4ge(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_all_int4ge(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_int4lt(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_all_int4lt(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_int4le(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_all_int4le(_int4, int4) returns bool
as 'MODULE_PATHNAME'
language 'c';
create operator *= (
leftarg=_int4,
rightarg=int4,
procedure=array_int4eq);
create operator **= (
leftarg=_int4,
rightarg=int4,
procedure=array_all_int4eq);
create operator *<> (
leftarg=_int4,
rightarg=int4,
procedure=array_int4ne);
create operator **<> (
leftarg=_int4,
rightarg=int4,
procedure=array_all_int4ne);
create operator *> (
leftarg=_int4,
rightarg=int4,
procedure=array_int4gt);
create operator **> (
leftarg=_int4,
rightarg=int4,
procedure=array_all_int4gt);
create operator *>= (
leftarg=_int4,
rightarg=int4,
procedure=array_int4ge);
create operator **>= (
leftarg=_int4,
rightarg=int4,
procedure=array_all_int4ge);
create operator *< (
leftarg=_int4,
rightarg=int4,
procedure=array_int4lt);
create operator **< (
leftarg=_int4,
rightarg=int4,
procedure=array_all_int4lt);
create operator *<= (
leftarg=_int4,
rightarg=int4,
procedure=array_int4le);
create operator **<= (
leftarg=_int4,
rightarg=int4,
procedure=array_all_int4le);
-- define the array operators *=, **<> for type _oid (added tobias 1. 1999)
--
create function array_oideq(_oid, oid) returns bool
as 'MODULE_PATHNAME'
language 'c';
create function array_all_oidne(_oid, oid) returns bool
as 'MODULE_PATHNAME'
language 'c';
create operator *= (
leftarg=_oid,
rightarg=oid,
procedure=array_oideq);
create operator **<> (
leftarg=_oid,
rightarg=oid,
procedure=array_all_oidne);
-- end of file

View File

@ -1,12 +0,0 @@
# $Header: /cvsroot/pgsql/contrib/btree_gist/Makefile,v 1.3 2001/09/06 10:49:29 petere Exp $
subdir = contrib/btree_gist
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
MODULES = btree_gist
DATA_built = btree_gist.sql
DOCS = README.btree_gist
REGRESS = btree_gist
include $(top_srcdir)/contrib/contrib-global.mk

View File

@ -1,31 +0,0 @@
This is B-Tree implementation using GiST for int4 and
timestamp types.
All work was done by Teodor Sigaev (teodor@stack.net) and Oleg Bartunov
(oleg@sai.msu.su). See http://www.sai.msu.su/~megera/postgres/gist
for additional information.
NOTICE:
This version will works only with postgresql version 7.2 and above
because of changes in interface of function calling and in system
tables.
INSTALLATION:
gmake
gmake install
-- load functions
psql <database> < btree_gist.sql
REGRESSION TEST:
gmake installcheck
EXAMPLE USAGE:
create table test (a int4);
-- create index
create index testidx on test using gist (a);
-- query
select * from test where a < 10;

View File

@ -1,583 +0,0 @@
#include "postgres.h"
#include "access/gist.h"
#include "access/itup.h"
#include "access/nbtree.h"
#include "utils/palloc.h"
#include "utils/geo_decls.h"
#include "utils/elog.h"
typedef int (*CMPFUNC) (const void *a, const void *b);
typedef void (*BINARY_UNION) (Datum *, char *);
typedef struct intkey
{
int4 lower;
int4 upper;
} INT4KEY;
typedef struct tskey
{
Timestamp lower;
Timestamp upper;
} TSKEY;
/* used for sorting */
typedef struct rix
{
int index;
char *r;
} RIX;
/*
** int4key in/out
*/
PG_FUNCTION_INFO_V1(int4key_in);
PG_FUNCTION_INFO_V1(int4key_out);
Datum int4key_in(PG_FUNCTION_ARGS);
Datum int4key_out(PG_FUNCTION_ARGS);
/*
** tskey in/out
*/
PG_FUNCTION_INFO_V1(tskey_in);
PG_FUNCTION_INFO_V1(tskey_out);
Datum tskey_in(PG_FUNCTION_ARGS);
Datum tskey_out(PG_FUNCTION_ARGS);
/*
** int4 ops
*/
PG_FUNCTION_INFO_V1(gint4_compress);
PG_FUNCTION_INFO_V1(gint4_union);
PG_FUNCTION_INFO_V1(gint4_picksplit);
PG_FUNCTION_INFO_V1(gint4_consistent);
PG_FUNCTION_INFO_V1(gint4_penalty);
PG_FUNCTION_INFO_V1(gint4_same);
Datum gint4_compress(PG_FUNCTION_ARGS);
Datum gint4_union(PG_FUNCTION_ARGS);
Datum gint4_picksplit(PG_FUNCTION_ARGS);
Datum gint4_consistent(PG_FUNCTION_ARGS);
Datum gint4_penalty(PG_FUNCTION_ARGS);
Datum gint4_same(PG_FUNCTION_ARGS);
static void gint4_binary_union(Datum *r1, char *r2);
static int int4key_cmp(const void *a, const void *b);
/*
** timestamp ops
*/
PG_FUNCTION_INFO_V1(gts_compress);
PG_FUNCTION_INFO_V1(gts_union);
PG_FUNCTION_INFO_V1(gts_picksplit);
PG_FUNCTION_INFO_V1(gts_consistent);
PG_FUNCTION_INFO_V1(gts_penalty);
PG_FUNCTION_INFO_V1(gts_same);
Datum gts_compress(PG_FUNCTION_ARGS);
Datum gts_union(PG_FUNCTION_ARGS);
Datum gts_picksplit(PG_FUNCTION_ARGS);
Datum gts_consistent(PG_FUNCTION_ARGS);
Datum gts_penalty(PG_FUNCTION_ARGS);
Datum gts_same(PG_FUNCTION_ARGS);
static void gts_binary_union(Datum *r1, char *r2);
static int tskey_cmp(const void *a, const void *b);
#define TimestampGetDatumFast(X) Float8GetDatumFast(X)
/* define for comparison */
#define TSGE( ts1, ts2 ) (DatumGetBool(DirectFunctionCall2( \
timestamp_ge, \
PointerGetDatum( ts1 ), \
PointerGetDatum( ts2 ) \
)))
#define TSGT( ts1, ts2 ) (DatumGetBool(DirectFunctionCall2( \
timestamp_gt, \
PointerGetDatum( ts1 ), \
PointerGetDatum( ts2 ) \
)))
#define TSEQ( ts1, ts2 ) (DatumGetBool(DirectFunctionCall2( \
timestamp_eq, \
PointerGetDatum( ts1 ), \
PointerGetDatum( ts2 ) \
)))
#define TSLT( ts1, ts2 ) (DatumGetBool(DirectFunctionCall2( \
timestamp_lt, \
PointerGetDatum( ts1 ), \
PointerGetDatum( ts2 ) \
)))
#define TSLE( ts1, ts2 ) (DatumGetBool(DirectFunctionCall2( \
timestamp_le, \
PointerGetDatum( ts1 ), \
PointerGetDatum( ts2 ) \
)))
/*
** Common btree-function (for all ops)
*/
static GIST_SPLITVEC *btree_picksplit(bytea *entryvec, GIST_SPLITVEC *v,
BINARY_UNION bu, CMPFUNC cmp);
PG_FUNCTION_INFO_V1(btree_decompress);
Datum btree_decompress(PG_FUNCTION_ARGS);
/**************************************************
* int4 ops
**************************************************/
Datum
gint4_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval;
if (entry->leafkey)
{
INT4KEY *r = palloc(sizeof(INT4KEY));
retval = palloc(sizeof(GISTENTRY));
r->lower = r->upper = (entry->key);
gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page,
entry->offset, sizeof(INT4KEY), FALSE);
}
else
retval = entry;
PG_RETURN_POINTER(retval);
}
Datum
gint4_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
int4 query = PG_GETARG_INT32(1);
INT4KEY *kkk = (INT4KEY *) DatumGetPointer(entry->key);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
bool retval;
switch (strategy)
{
case BTLessEqualStrategyNumber:
retval = (query >= kkk->lower);
break;
case BTLessStrategyNumber:
if (GIST_LEAF(entry))
retval = (query > kkk->lower);
else
retval = (query >= kkk->lower);
break;
case BTEqualStrategyNumber:
/* in leaf page kkk->lower always = kkk->upper */
if (GIST_LEAF(entry))
retval = (query == kkk->lower);
else
retval = (kkk->lower <= query && query <= kkk->upper);
break;
case BTGreaterStrategyNumber:
if (GIST_LEAF(entry))
retval = (query < kkk->upper);
else
retval = (query <= kkk->upper);
break;
case BTGreaterEqualStrategyNumber:
retval = (query <= kkk->upper);
break;
default:
retval = FALSE;
}
PG_RETURN_BOOL(retval);
}
Datum
gint4_union(PG_FUNCTION_ARGS)
{
bytea *entryvec = (bytea *) PG_GETARG_POINTER(0);
int i,
numranges;
INT4KEY *cur,
*out = palloc(sizeof(INT4KEY));
numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY);
*(int *) PG_GETARG_POINTER(1) = sizeof(INT4KEY);
cur = (INT4KEY *) DatumGetPointer((((GISTENTRY *) (VARDATA(entryvec)))[0].key));
out->lower = cur->lower;
out->upper = cur->upper;
for (i = 1; i < numranges; i++)
{
cur = (INT4KEY *) DatumGetPointer((((GISTENTRY *) (VARDATA(entryvec)))[i].key));
if (out->lower > cur->lower)
out->lower = cur->lower;
if (out->upper < cur->upper)
out->upper = cur->upper;
}
PG_RETURN_POINTER(out);
}
Datum
gint4_penalty(PG_FUNCTION_ARGS)
{
INT4KEY *origentry = (INT4KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
INT4KEY *newentry = (INT4KEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *result = (float *) PG_GETARG_POINTER(2);
*result = Max(newentry->upper - origentry->upper, 0) +
Max(origentry->lower - newentry->lower, 0);
PG_RETURN_POINTER(result);
}
Datum
gint4_picksplit(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(btree_picksplit(
(bytea *) PG_GETARG_POINTER(0),
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
gint4_binary_union,
int4key_cmp
));
}
Datum
gint4_same(PG_FUNCTION_ARGS)
{
INT4KEY *b1 = (INT4KEY *) PG_GETARG_POINTER(0);
INT4KEY *b2 = (INT4KEY *) PG_GETARG_POINTER(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
*result = (b1->lower == b2->lower && b1->upper == b2->upper) ? TRUE : FALSE;
PG_RETURN_POINTER(result);
}
static void
gint4_binary_union(Datum *r1, char *r2)
{
INT4KEY *b1;
INT4KEY *b2 = (INT4KEY *) r2;
if (!DatumGetPointer(*r1))
{
*r1 = PointerGetDatum(palloc(sizeof(INT4KEY)));
b1 = (INT4KEY *) DatumGetPointer(*r1);
b1->upper = b2->upper;
b1->lower = b2->lower;
}
else
{
b1 = (INT4KEY *) DatumGetPointer(*r1);
b1->lower = (b1->lower > b2->lower) ?
b2->lower : b1->lower;
b1->upper = (b1->upper > b2->upper) ?
b1->upper : b2->upper;
}
}
static int
int4key_cmp(const void *a, const void *b)
{
return (((INT4KEY *) (((RIX *) a)->r))->lower - ((INT4KEY *) (((RIX *) b)->r))->lower);
}
/**************************************************
* timestamp ops
**************************************************/
Datum
gts_compress(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
GISTENTRY *retval;
if (entry->leafkey)
{
TSKEY *r = (TSKEY *) palloc(sizeof(TSKEY));
retval = palloc(sizeof(GISTENTRY));
r->lower = r->upper = *(Timestamp *) (entry->key);
gistentryinit(*retval, PointerGetDatum(r),
entry->rel, entry->page,
entry->offset, sizeof(TSKEY), FALSE);
}
else
retval = entry;
PG_RETURN_POINTER(retval);
}
Datum
gts_consistent(PG_FUNCTION_ARGS)
{
GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
Timestamp *query = (Timestamp *) PG_GETARG_POINTER(1);
StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
bool retval;
TSKEY *key;
/*
* * if entry is not leaf, use gbox_internal_consistent, * else use
* gbox_leaf_consistent
*/
if (!entry->key)
return FALSE;
key = (TSKEY *) DatumGetPointer(entry->key);
switch (strategy)
{
case BTLessEqualStrategyNumber:
retval = TSGE(query, &(key->lower));
break;
case BTLessStrategyNumber:
if (GIST_LEAF(entry))
retval = TSGT(query, &(key->lower));
else
retval = TSGE(query, &(key->lower));
break;
case BTEqualStrategyNumber:
/* in leaf page key->lower always = key->upper */
if (GIST_LEAF(entry))
retval = TSEQ(query, &(key->lower));
else
retval = (TSLE(&(key->lower), query) && TSLE(query, &(key->upper)));
break;
case BTGreaterStrategyNumber:
if (GIST_LEAF(entry))
retval = TSLT(query, &(key->upper));
else
retval = TSLE(query, &(key->upper));
break;
case BTGreaterEqualStrategyNumber:
retval = TSLE(query, &(key->upper));
break;
default:
retval = FALSE;
}
PG_RETURN_BOOL(retval);
}
Datum
gts_union(PG_FUNCTION_ARGS)
{
bytea *entryvec = (bytea *) PG_GETARG_POINTER(0);
int i,
numranges;
TSKEY *cur,
*out = palloc(sizeof(TSKEY));
numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY);
*(int *) PG_GETARG_POINTER(1) = sizeof(TSKEY);
cur = (TSKEY *) DatumGetPointer((((GISTENTRY *) (VARDATA(entryvec)))[0].key));
out->lower = cur->lower;
out->upper = cur->upper;
for (i = 1; i < numranges; i++)
{
cur = (TSKEY *) DatumGetPointer((((GISTENTRY *) (VARDATA(entryvec)))[i].key));
if (TSGT(&out->lower, &cur->lower))
out->lower = cur->lower;
if (TSLT(&out->upper, &cur->upper))
out->upper = cur->upper;
}
PG_RETURN_POINTER(out);
}
Datum
gts_penalty(PG_FUNCTION_ARGS)
{
TSKEY *origentry = (TSKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(0))->key);
TSKEY *newentry = (TSKEY *) DatumGetPointer(((GISTENTRY *) PG_GETARG_POINTER(1))->key);
float *result = (float *) PG_GETARG_POINTER(2);
Interval *intr;
intr = DatumGetIntervalP(DirectFunctionCall2(
timestamp_mi,
TimestampGetDatumFast(newentry->upper),
TimestampGetDatumFast(origentry->upper)));
/* see interval_larger */
*result = Max(intr->time + intr->month * (30.0 * 86400), 0);
pfree(intr);
intr = DatumGetIntervalP(DirectFunctionCall2(
timestamp_mi,
TimestampGetDatumFast(origentry->lower),
TimestampGetDatumFast(newentry->lower)));
/* see interval_larger */
*result += Max(intr->time + intr->month * (30.0 * 86400), 0);
pfree(intr);
PG_RETURN_POINTER(result);
}
Datum
gts_picksplit(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(btree_picksplit(
(bytea *) PG_GETARG_POINTER(0),
(GIST_SPLITVEC *) PG_GETARG_POINTER(1),
gts_binary_union,
tskey_cmp
));
}
Datum
gts_same(PG_FUNCTION_ARGS)
{
TSKEY *b1 = (TSKEY *) PG_GETARG_POINTER(0);
TSKEY *b2 = (TSKEY *) PG_GETARG_POINTER(1);
bool *result = (bool *) PG_GETARG_POINTER(2);
if (b1 && b2)
*result = (TSEQ(&(b1->lower), &(b2->lower)) && TSEQ(&(b1->upper), &(b2->upper))) ? TRUE : FALSE;
else
*result = (b1 == NULL && b2 == NULL) ? TRUE : FALSE;
PG_RETURN_POINTER(result);
}
static void
gts_binary_union(Datum *r1, char *r2)
{
TSKEY *b1;
TSKEY *b2 = (TSKEY *) r2;
if (!DatumGetPointer(*r1))
{
*r1 = PointerGetDatum(palloc(sizeof(TSKEY)));
b1 = (TSKEY *) DatumGetPointer(*r1);
b1->upper = b2->upper;
b1->lower = b2->lower;
}
else
{
b1 = (TSKEY *) DatumGetPointer(*r1);
b1->lower = (TSGT(&b1->lower, &b2->lower)) ?
b2->lower : b1->lower;
b1->upper = (TSGT(&b1->upper, &b2->upper)) ?
b1->upper : b2->upper;
}
}
static int
tskey_cmp(const void *a, const void *b)
{
return DatumGetInt32(
DirectFunctionCall2(
timestamp_cmp,
TimestampGetDatumFast(((TSKEY *) (((RIX *) a)->r))->lower),
TimestampGetDatumFast(((TSKEY *) (((RIX *) b)->r))->lower)
)
);
}
/**************************************************
* Common btree-function (for all ops)
**************************************************/
/*
** The GiST PickSplit method
*/
static GIST_SPLITVEC *
btree_picksplit(bytea *entryvec, GIST_SPLITVEC *v, BINARY_UNION bu, CMPFUNC cmp)
{
OffsetNumber i;
RIX *array;
OffsetNumber maxoff;
int nbytes;
maxoff = ((VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY)) - 1;
nbytes = (maxoff + 2) * sizeof(OffsetNumber);
v->spl_left = (OffsetNumber *) palloc(nbytes);
v->spl_right = (OffsetNumber *) palloc(nbytes);
v->spl_nleft = 0;
v->spl_nright = 0;
v->spl_ldatum = PointerGetDatum(0);
v->spl_rdatum = PointerGetDatum(0);
array = (RIX *) palloc(sizeof(RIX) * (maxoff + 1));
/* copy the data into RIXes, and sort the RIXes */
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
{
array[i].index = i;
array[i].r = (char *) DatumGetPointer((((GISTENTRY *) (VARDATA(entryvec)))[i].key));
}
qsort((void *) &array[FirstOffsetNumber], maxoff - FirstOffsetNumber + 1,
sizeof(RIX), cmp);
for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i))
{
if (i <= (maxoff - FirstOffsetNumber + 1) / 2)
{
v->spl_left[v->spl_nleft] = array[i].index;
v->spl_nleft++;
(*bu) (&v->spl_ldatum, array[i].r);
}
else
{
v->spl_right[v->spl_nright] = array[i].index;
v->spl_nright++;
(*bu) (&v->spl_rdatum, array[i].r);
}
}
pfree(array);
return (v);
}
/*
** GiST DeCompress methods
** do not do anything.
*/
Datum
btree_decompress(PG_FUNCTION_ARGS)
{
PG_RETURN_POINTER(PG_GETARG_POINTER(0));
}
/**************************************************
* In/Out for keys, not really needed
**************************************************/
Datum
int4key_in(PG_FUNCTION_ARGS)
{
INT4KEY *key = palloc(sizeof(INT4KEY));
if (sscanf(PG_GETARG_POINTER(0), "%d|%d", &(key->lower), &(key->upper)) != 2)
elog(ERROR, "Error in input format");
PG_RETURN_POINTER(key);
}
Datum
int4key_out(PG_FUNCTION_ARGS)
{
INT4KEY *key = (INT4KEY *) PG_GETARG_POINTER(0);
char *str = palloc(sizeof(char) * 22);
sprintf(str, "%d|%d", key->lower, key->upper);
PG_RETURN_POINTER(str);
}
Datum
tskey_in(PG_FUNCTION_ARGS)
{
elog(ERROR, "Not implemented");
PG_RETURN_POINTER(NULL);
}
Datum
tskey_out(PG_FUNCTION_ARGS)
{
elog(ERROR, "Not implemented");
PG_RETURN_POINTER(NULL);
}

View File

@ -1,270 +0,0 @@
begin transaction;
-- create type of int4 key
CREATE FUNCTION int4key_in(opaque)
RETURNS opaque
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);
CREATE FUNCTION int4key_out(opaque)
RETURNS opaque
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);
CREATE TYPE int4key (
internallength = 8,
input = int4key_in,
output = int4key_out
);
--
--
--
-- int4 ops
--
--
--
-- define the GiST support methods
create function gint4_consistent(opaque,int4,int2) returns bool as 'MODULE_PATHNAME' language 'C';
create function gint4_compress(opaque) returns opaque as 'MODULE_PATHNAME' language 'C';
create function btree_decompress(opaque) returns opaque as 'MODULE_PATHNAME' language 'C';
create function gint4_penalty(opaque,opaque,opaque) returns opaque as 'MODULE_PATHNAME' language 'C' with(isstrict);
create function gint4_picksplit(opaque, opaque) returns opaque as 'MODULE_PATHNAME' language 'C';
create function gint4_union(bytea, opaque) returns int4 as 'MODULE_PATHNAME' language 'C';
create function gint4_same(opaque, opaque, opaque) returns opaque as 'MODULE_PATHNAME' language 'C';
-- add a new opclass
INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype)
VALUES (
(SELECT oid FROM pg_am WHERE amname = 'gist'),
'gist_int4_ops',
(SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'),
1, -- UID of superuser is hardwired to 1 as of PG 7.3
(SELECT oid FROM pg_type WHERE typname = 'int4'),
true,
(SELECT oid FROM pg_type WHERE typname = 'int4key'));
SELECT o.oid AS opoid, o.oprname
INTO TABLE int_ops_tmp
FROM pg_operator o, pg_type t
WHERE o.oprleft = t.oid and o.oprright = t.oid
and t.typname = 'int4';
-- get the comparators for int4es and store them in a tmp table
INSERT INTO pg_amop (amopclaid, amopopr, amopstrategy, amopreqcheck)
SELECT opcl.oid, c.opoid, 1, 'f'
FROM pg_opclass opcl, int_ops_tmp c
WHERE opcname = 'gist_int4_ops'
and c.oprname = '<';
INSERT INTO pg_amop (amopclaid, amopopr, amopstrategy, amopreqcheck)
SELECT opcl.oid, c.opoid, 2, 'f'
FROM pg_opclass opcl, int_ops_tmp c
WHERE opcname = 'gist_int4_ops'
and c.oprname = '<=';
INSERT INTO pg_amop (amopclaid, amopopr, amopstrategy, amopreqcheck)
SELECT opcl.oid, c.opoid, 3, 'f'
FROM pg_opclass opcl, int_ops_tmp c
WHERE opcname = 'gist_int4_ops'
and c.oprname = '=';
INSERT INTO pg_amop (amopclaid, amopopr, amopstrategy, amopreqcheck)
SELECT opcl.oid, c.opoid, 4, 'f'
FROM pg_opclass opcl, int_ops_tmp c
WHERE opcname = 'gist_int4_ops'
and c.oprname = '>=';
INSERT INTO pg_amop (amopclaid, amopopr, amopstrategy, amopreqcheck)
SELECT opcl.oid, c.opoid, 5, 'f'
FROM pg_opclass opcl, int_ops_tmp c
WHERE opcname = 'gist_int4_ops'
and c.oprname = '>';
DROP table int_ops_tmp;
-- add the entries to amproc for the support methods
-- note the amprocnum numbers associated with each are specific!
INSERT INTO pg_amproc (amopclaid, amproc, amprocnum)
SELECT opcl.oid, pro.oid, 1
FROM pg_opclass opcl, pg_proc pro
WHERE opcname = 'gist_int4_ops'
and proname = 'gint4_consistent';
INSERT INTO pg_amproc (amopclaid, amproc, amprocnum)
SELECT opcl.oid, pro.oid, 2
FROM pg_opclass opcl, pg_proc pro
WHERE opcname = 'gist_int4_ops'
and proname = 'gint4_union';
INSERT INTO pg_amproc (amopclaid, amproc, amprocnum)
SELECT opcl.oid, pro.oid, 3
FROM pg_opclass opcl, pg_proc pro
WHERE opcname = 'gist_int4_ops'
and proname = 'gint4_compress';
INSERT INTO pg_amproc (amopclaid, amproc, amprocnum)
SELECT opcl.oid, pro.oid, 4
FROM pg_opclass opcl, pg_proc pro
WHERE opcname = 'gist_int4_ops'
and proname = 'btree_decompress';
INSERT INTO pg_amproc (amopclaid, amproc, amprocnum)
SELECT opcl.oid, pro.oid, 5
FROM pg_opclass opcl, pg_proc pro
WHERE opcname = 'gist_int4_ops'
and proname = 'gint4_penalty';
INSERT INTO pg_amproc (amopclaid, amproc, amprocnum)
SELECT opcl.oid, pro.oid, 6
FROM pg_opclass opcl, pg_proc pro
WHERE opcname = 'gist_int4_ops'
and proname = 'gint4_picksplit';
INSERT INTO pg_amproc (amopclaid, amproc, amprocnum)
SELECT opcl.oid, pro.oid, 7
FROM pg_opclass opcl, pg_proc pro
WHERE opcname = 'gist_int4_ops'
and proname = 'gint4_same';
--
--
--
-- timestamp ops
--
--
--
-- create type of timestamp key
CREATE FUNCTION tskey_in(opaque)
RETURNS opaque
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);
CREATE FUNCTION tskey_out(opaque)
RETURNS opaque
AS 'MODULE_PATHNAME'
LANGUAGE 'c' with (isstrict);
CREATE TYPE tskey (
internallength = 16,
input = tskey_in,
output = tskey_out
);
create function gts_consistent(opaque,timestamp,int2) returns bool as 'MODULE_PATHNAME' language 'C';
create function gts_compress(opaque) returns opaque as 'MODULE_PATHNAME' language 'C';
create function gts_penalty(opaque,opaque,opaque) returns opaque as 'MODULE_PATHNAME' language 'C' with(isstrict);
create function gts_picksplit(opaque, opaque) returns opaque as 'MODULE_PATHNAME' language 'C';
create function gts_union(bytea, opaque) returns int4 as 'MODULE_PATHNAME' language 'C';
create function gts_same(opaque, opaque, opaque) returns opaque as 'MODULE_PATHNAME' language 'C';
-- add a new opclass
INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype)
VALUES (
(SELECT oid FROM pg_am WHERE amname = 'gist'),
'gist_timestamp_ops',
(SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'),
1, -- UID of superuser is hardwired to 1 as of PG 7.3
(SELECT oid FROM pg_type WHERE typname = 'timestamp'),
true,
(SELECT oid FROM pg_type WHERE typname = 'tskey'));
SELECT o.oid AS opoid, o.oprname
INTO TABLE timestamp_ops_tmp
FROM pg_operator o, pg_type t
WHERE o.oprleft = t.oid and o.oprright = t.oid
and t.typname = 'timestamp';
INSERT INTO pg_amop (amopclaid, amopopr, amopstrategy, amopreqcheck)
SELECT opcl.oid, c.opoid, 1, 'f'
FROM pg_opclass opcl, timestamp_ops_tmp c
WHERE opcname = 'gist_timestamp_ops'
and c.oprname = '<';
INSERT INTO pg_amop (amopclaid, amopopr, amopstrategy, amopreqcheck)
SELECT opcl.oid, c.opoid, 2, 'f'
FROM pg_opclass opcl, timestamp_ops_tmp c
WHERE opcname = 'gist_timestamp_ops'
and c.oprname = '<=';
INSERT INTO pg_amop (amopclaid, amopopr, amopstrategy, amopreqcheck)
SELECT opcl.oid, c.opoid, 3, 'f'
FROM pg_opclass opcl, timestamp_ops_tmp c
WHERE opcname = 'gist_timestamp_ops'
and c.oprname = '=';
INSERT INTO pg_amop (amopclaid, amopopr, amopstrategy, amopreqcheck)
SELECT opcl.oid, c.opoid, 4, 'f'
FROM pg_opclass opcl, timestamp_ops_tmp c
WHERE opcname = 'gist_timestamp_ops'
and c.oprname = '>=';
INSERT INTO pg_amop (amopclaid, amopopr, amopstrategy, amopreqcheck)
SELECT opcl.oid, c.opoid, 5, 'f'
FROM pg_opclass opcl, timestamp_ops_tmp c
WHERE opcname = 'gist_timestamp_ops'
and c.oprname = '>';
DROP table timestamp_ops_tmp;
-- add the entries to amproc for the support methods
-- note the amprocnum numbers associated with each are specific!
INSERT INTO pg_amproc (amopclaid, amproc, amprocnum)
SELECT opcl.oid, pro.oid, 1
FROM pg_opclass opcl, pg_proc pro
WHERE opcname = 'gist_timestamp_ops'
and proname = 'gts_consistent';
INSERT INTO pg_amproc (amopclaid, amproc, amprocnum)
SELECT opcl.oid, pro.oid, 2
FROM pg_opclass opcl, pg_proc pro
WHERE opcname = 'gist_timestamp_ops'
and proname = 'gts_union';
INSERT INTO pg_amproc (amopclaid, amproc, amprocnum)
SELECT opcl.oid, pro.oid, 3
FROM pg_opclass opcl, pg_proc pro
WHERE opcname = 'gist_timestamp_ops'
and proname = 'gts_compress';
INSERT INTO pg_amproc (amopclaid, amproc, amprocnum)
SELECT opcl.oid, pro.oid, 4
FROM pg_opclass opcl, pg_proc pro
WHERE opcname = 'gist_timestamp_ops'
and proname = 'btree_decompress';
INSERT INTO pg_amproc (amopclaid, amproc, amprocnum)
SELECT opcl.oid, pro.oid, 5
FROM pg_opclass opcl, pg_proc pro
WHERE opcname = 'gist_timestamp_ops'
and proname = 'gts_penalty';
INSERT INTO pg_amproc (amopclaid, amproc, amprocnum)
SELECT opcl.oid, pro.oid, 6
FROM pg_opclass opcl, pg_proc pro
WHERE opcname = 'gist_timestamp_ops'
and proname = 'gts_picksplit';
INSERT INTO pg_amproc (amopclaid, amproc, amprocnum)
SELECT opcl.oid, pro.oid, 7
FROM pg_opclass opcl, pg_proc pro
WHERE opcname = 'gist_timestamp_ops'
and proname = 'gts_same';
end transaction;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,39 +0,0 @@
--
-- first, define the datatype. Turn off echoing so that expected file
-- does not depend on contents of seg.sql.
--
\set ECHO none
create table inttmp (b int4);
\copy inttmp from 'data/test_btree.data'
create table tstmp ( t timestamp without time zone );
\copy tstmp from 'data/test_btree_ts.data'
-- without idx
select count(*) from inttmp where b <=10;
count
-------
11
(1 row)
select count(*) from tstmp where t < '2001-05-29 08:33:09';
count
-------
66
(1 row)
-- create idx
create index aaaidx on inttmp using gist ( b );
create index tsidx on tstmp using gist ( t );
--with idx
set enable_seqscan=off;
select count(*) from inttmp where b <=10;
count
-------
11
(1 row)
select count(*) from tstmp where t < '2001-05-29 08:33:09';
count
-------
66
(1 row)

View File

@ -1,36 +0,0 @@
--
-- first, define the datatype. Turn off echoing so that expected file
-- does not depend on contents of seg.sql.
--
\set ECHO none
\i btree_gist.sql
\set ECHO all
create table inttmp (b int4);
\copy inttmp from 'data/test_btree.data'
create table tstmp ( t timestamp without time zone );
\copy tstmp from 'data/test_btree_ts.data'
-- without idx
select count(*) from inttmp where b <=10;
select count(*) from tstmp where t < '2001-05-29 08:33:09';
-- create idx
create index aaaidx on inttmp using gist ( b );
create index tsidx on tstmp using gist ( t );
--with idx
set enable_seqscan=off;
select count(*) from inttmp where b <=10;
select count(*) from tstmp where t < '2001-05-29 08:33:09';

View File

@ -1,11 +0,0 @@
# $Header: /cvsroot/pgsql/contrib/chkpass/Makefile,v 1.3 2001/09/06 10:49:29 petere Exp $
subdir = contrib/chkpass
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
MODULES = chkpass
DATA_built = chkpass.sql
DOCS = README.chkpass
include $(top_srcdir)/contrib/contrib-global.mk

View File

@ -1,22 +0,0 @@
$Header: /cvsroot/pgsql/contrib/chkpass/Attic/README.chkpass,v 1.1 2001/05/03 12:32:13 darcy Exp $
Chkpass is a password type that is automatically checked and converted upon
entry. It is stored encrypted. To compare, simply compare agains a clear
text password and the comparison function will encrypt it before comparing.
It also returns an error if the code determines that the password is easily
crackable. This is currently a stub that does nothing.
I haven't worried about making this type indexable. I doubt that anyone
would ever need to sort a file in order of encrypted password.
If you precede the string with a colon, the encryption and checking are
skipped so that you can enter existing passwords into the field.
On output, a colon is prepended. This makes it possible to dump and reload
passwords without re-encrypting them. If you want the password (encrypted)
without the colon then use the raw() function. This allows you to use the
type with things like Apache's Auth_PostgreSQL module.
D'Arcy J.M. Cain
darcy@druid.net

View File

@ -1,196 +0,0 @@
/*
* PostgreSQL type definitions for chkpass
* Written by D'Arcy J.M. Cain
* darcy@druid.net
* http://www.druid.net/darcy/
*
* $Id: chkpass.c,v 1.7 2001/12/19 18:49:24 petere Exp $
* best viewed with tabs set to 4
*/
#include "postgres.h"
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif
#include "fmgr.h"
/*
* This type encrypts it's input unless the first character is a colon.
* The output is the encrypted form with a leading colon. The output
* format is designed to allow dump and reload operations to work as
* expected without doing special tricks.
*/
/*
* This is the internal storage format for CHKPASSs.
* 15 is all I need but add a little buffer
*/
typedef struct chkpass
{
char password[16];
} chkpass;
/*
* Various forward declarations:
*/
Datum chkpass_in(PG_FUNCTION_ARGS);
Datum chkpass_out(PG_FUNCTION_ARGS);
Datum chkpass_rout(PG_FUNCTION_ARGS);
/* Only equal or not equal make sense */
Datum chkpass_eq(PG_FUNCTION_ARGS);
Datum chkpass_ne(PG_FUNCTION_ARGS);
/* This function checks that the password is a good one
* It's just a placeholder for now */
static int
verify_pass(const char *str)
{
return 0;
}
/*
* CHKPASS reader.
*/
PG_FUNCTION_INFO_V1(chkpass_in)
Datum
chkpass_in(PG_FUNCTION_ARGS)
{
char *str = PG_GETARG_CSTRING(0);
chkpass *result;
char mysalt[4];
static bool random_initialized = false;
static char salt_chars[] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
/* special case to let us enter encrypted passwords */
if (*str == ':')
{
result = (chkpass *) palloc(sizeof(chkpass));
strncpy(result->password, str + 1, 13);
result->password[13] = 0;
PG_RETURN_POINTER(result);
}
if (verify_pass(str) != 0)
{
elog(ERROR, "chkpass_in: purported CHKPASS \"%s\" is a weak password",
str);
PG_RETURN_POINTER(NULL);
}
result = (chkpass *) palloc(sizeof(chkpass));
if (!random_initialized)
{
srandom((unsigned int) time(NULL));
random_initialized = true;
}
mysalt[0] = salt_chars[random() & 0x3f];
mysalt[1] = salt_chars[random() & 0x3f];
mysalt[2] = 0; /* technically the terminator is not
* necessary but I like to play safe */
strcpy(result->password, crypt(str, mysalt));
PG_RETURN_POINTER(result);
}
/*
* CHKPASS output function.
* Just like any string but we know it is max 15 (13 plus colon and terminator.)
*/
PG_FUNCTION_INFO_V1(chkpass_out)
Datum
chkpass_out(PG_FUNCTION_ARGS)
{
chkpass *password = (chkpass *) PG_GETARG_POINTER(0);
char *result;
if (password == NULL)
PG_RETURN_POINTER(NULL);
if ((result = (char *) palloc(16)) != NULL)
{
result[0] = ':';
strcpy(result + 1, password->password);
}
PG_RETURN_CSTRING(result);
}
/*
* special output function that doesn't output the colon
*/
PG_FUNCTION_INFO_V1(chkpass_rout)
Datum
chkpass_rout(PG_FUNCTION_ARGS)
{
chkpass *password = (chkpass *) PG_GETARG_POINTER(0);
text *result = NULL;
if (password == NULL)
PG_RETURN_POINTER(NULL);
if ((result = (text *) palloc(VARHDRSZ + 16)) != NULL)
{
result->vl_len = VARHDRSZ + strlen(password->password);
memcpy(result->vl_dat, password->password, strlen(password->password));
}
PG_RETURN_CSTRING(result);
}
/*
* Boolean tests
*/
PG_FUNCTION_INFO_V1(chkpass_eq)
Datum
chkpass_eq(PG_FUNCTION_ARGS)
{
chkpass *a1 = (chkpass *) PG_GETARG_POINTER(0);
text *a2 = (text *) PG_GETARG_TEXT_P(1);
char str[10];
int sz = 8;
if (!a1 || !a2)
PG_RETURN_BOOL(0);
if (a2->vl_len < 12)
sz = a2->vl_len - 4;
strncpy(str, a2->vl_dat, sz);
str[sz] = 0;
PG_RETURN_BOOL(strcmp(a1->password, crypt(str, a1->password)) == 0);
}
PG_FUNCTION_INFO_V1(chkpass_ne)
Datum
chkpass_ne(PG_FUNCTION_ARGS)
{
chkpass *a1 = (chkpass *) PG_GETARG_POINTER(0);
text *a2 = (text *) PG_GETARG_TEXT_P(1);
char str[10];
int sz = 8;
if (!a1 || !a2)
PG_RETURN_BOOL(0);
if (a2->vl_len < 12)
sz = a2->vl_len - 4;
strncpy(str, a2->vl_dat, sz);
str[sz] = 0;
PG_RETURN_BOOL(strcmp(a1->password, crypt(str, a1->password)) != 0);
}

View File

@ -1,78 +0,0 @@
--
-- PostgreSQL code for CHKPASS.
-- Written by D'Arcy J.M. Cain
-- darcy@druid.net
-- http://www.druid.net/darcy/
--
-- $Header: /cvsroot/pgsql/contrib/chkpass/chkpass.sql.in,v 1.1 2001/08/23 16:50:33 tgl Exp $
--
-- best viewed with tabs set to 4
--
--
-- Input and output functions and the type itself:
--
create function chkpass_in(opaque)
returns opaque
as 'MODULE_PATHNAME'
language 'c';
create function chkpass_out(opaque)
returns opaque
as 'MODULE_PATHNAME'
language 'c';
create type chkpass (
internallength = 16,
externallength = 13,
input = chkpass_in,
output = chkpass_out
);
create function raw(chkpass)
returns text
as 'MODULE_PATHNAME', 'chkpass_rout'
language 'c';
--
-- The various boolean tests:
--
create function eq(chkpass, text)
returns bool
as 'MODULE_PATHNAME', 'chkpass_eq'
language 'c';
create function ne(chkpass, text)
returns bool
as 'MODULE_PATHNAME', 'chkpass_ne'
language 'c';
--
-- Now the operators. Note how some of the parameters to some
-- of the 'create operator' commands are commented out. This
-- is because they reference as yet undefined operators, and
-- will be implicitly defined when those are, further down.
--
create operator = (
leftarg = chkpass,
rightarg = text,
commutator = =,
-- negator = <>,
procedure = eq
);
create operator <> (
leftarg = chkpass,
rightarg = text,
negator = =,
procedure = ne
);
COMMENT ON TYPE chkpass IS 'password type with checks';
--
-- eof
--

View File

@ -1,202 +0,0 @@
# $Header: /cvsroot/pgsql/contrib/contrib-global.mk,v 1.2 2001/09/16 16:11:08 petere Exp $
# This file contains generic rules to build many kinds of simple
# contrib modules. You only need to set a few variables and include
# this file, the rest will be done here.
#
# Use the following layout for your Makefile:
#
# subdir = contrib/xxx
# top_builddir = ../..
# include $(top_builddir)/src/Makefile.global
#
# [variable assignments, see below]
# [custom rules, rarely necessary]
#
# include $(top_srcdir)/contrib/contrib-global.mk
#
# The following variables can be set:
#
# MODULES -- list of shared objects to be build from source file with
# same stem (do not include suffix in this list)
# DATA -- random files to install into $PREFIX/share/contrib
# DATA_built -- random files to install into $PREFIX/share/contrib,
# which need to be built first
# DOCS -- random files to install under $PREFIX/doc/contrib
# SCRIPTS -- script files (not binaries) to install into $PREFIX/bin
# REGRESS -- list of regression test cases (without suffix)
#
# or at most one of these two:
#
# PROGRAM -- a binary program to build (list objects files in OBJS)
# MODULE_big -- a shared object to build (list object files in OBJS)
#
# The following can also be set:
#
# EXTRA_CLEAN -- extra files to remove in 'make clean'
# PG_CPPFLAGS -- will be added to CPPFLAGS
# PG_LIBS -- will be added to PROGRAM link line
# SHLIB_LINK -- will be added to MODULE_big link line
#
# Better look at some of the existing uses for examples...
override CPPFLAGS := -I$(srcdir) $(CPPFLAGS)
ifdef MODULES
override CFLAGS += $(CFLAGS_SL)
override DLLLIBS := $(BE_DLLLIBS) $(DLLLIBS)
endif
ifdef PG_CPPFLAGS
override CPPFLAGS := $(PG_CPPFLAGS) $(CPPFLAGS)
endif
all: $(PROGRAM) $(DATA_built) $(addsuffix $(DLSUFFIX), $(MODULES))
ifdef MODULE_big
# shared library parameters
NAME = $(MODULE_big)
SO_MAJOR_VERSION= 0
SO_MINOR_VERSION= 0
rpath =
override DLLLIBS := $(BE_DLLLIBS) $(DLLLIBS)
include $(top_srcdir)/src/Makefile.shlib
all: all-lib
endif # MODULE_big
install: all installdirs
ifneq (,$(DATA)$(DATA_built))
@for file in $(addprefix $(srcdir)/, $(DATA)) $(DATA_built); do \
echo "$(INSTALL_DATA) $$file $(DESTDIR)$(datadir)/contrib"; \
$(INSTALL_DATA) $$file $(DESTDIR)$(datadir)/contrib; \
done
endif # DATA
ifdef MODULES
@for file in $(addsuffix $(DLSUFFIX), $(MODULES)); do \
echo "$(INSTALL_SHLIB) $$file $(DESTDIR)$(pkglibdir)"; \
$(INSTALL_SHLIB) $$file $(DESTDIR)$(pkglibdir); \
done
endif # MODULES
ifdef DOCS
@for file in $(addprefix $(srcdir)/, $(DOCS)); do \
echo "$(INSTALL_DATA) $$file $(DESTDIR)$(docdir)/contrib"; \
$(INSTALL_DATA) $$file $(DESTDIR)$(docdir)/contrib; \
done
endif # DOCS
ifdef PROGRAM
$(INSTALL_PROGRAM) $(PROGRAM)$(X) $(DESTDIR)$(bindir)
endif # PROGRAM
ifdef MODULE_big
$(INSTALL_SHLIB) $(shlib) $(DESTDIR)$(pkglibdir)/$(MODULE_big)$(DLSUFFIX)
endif # MODULE_big
ifdef SCRIPTS
@for file in $(addprefix $(srcdir)/, $(SCRIPTS)); do \
echo "$(INSTALL_SCRIPT) $$file $(DESTDIR)$(bindir)"; \
$(INSTALL_SCRIPT) $$file $(DESTDIR)$(bindir); \
done
endif # SCRIPTS
installdirs:
ifneq (,$(DATA)$(DATA_built))
$(mkinstalldirs) $(DESTDIR)$(datadir)/contrib
endif
ifneq (,$(MODULES)$(MODULE_big))
$(mkinstalldirs) $(DESTDIR)$(pkglibdir)
endif
ifdef DOCS
$(mkinstalldirs) $(DESTDIR)$(docdir)/contrib
endif
ifneq (,$(PROGRAM)$(SCRIPTS))
$(mkinstalldirs) $(DESTDIR)$(bindir)
endif
uninstall:
ifneq (,$(DATA)$(DATA_built))
rm -f $(addprefix $(DESTDIR)$(datadir)/contrib/, $(DATA) $(DATA_built))
endif
ifdef MODULES
rm -f $(addprefix $(DESTDIR)$(pkglibdir)/, $(addsuffix $(DLSUFFIX), $(MODULES)))
endif
ifdef DOCS
rm -f $(addprefix $(DESTDIR)$(docdir)/contrib/, $(DOCS))
endif
ifdef PROGRAM
rm -f $(DESTDIR)$(bindir)/$(PROGRAM)$(X)
endif
ifdef MODULE_big
rm -f $(DESTDIR)$(pkglibdir)/$(MODULE_big)$(DLSUFFIX)
endif
ifdef SCRIPTS
rm -f $(addprefix $(DESTDIR)$(bindir)/, $(SCRIPTS))
endif
clean:
ifdef MODULES
rm -f $(addsuffix $(DLSUFFIX), $(MODULES)) $(addsuffix .o, $(MODULES))
endif
ifdef DATA_built
rm -f $(DATA_built)
endif
ifdef PROGRAM
rm -f $(PROGRAM)$(X)
endif
ifdef OBJS
rm -f $(OBJS)
endif
ifdef EXTRA_CLEAN
rm -f $(EXTRA_CLEAN)
endif
ifdef REGRESS
# things created by various check targets
rm -rf results tmp_check log
rm -f regression.diffs regression.out regress.out run_check.out
ifeq ($(PORTNAME), win)
rm -f regress.def
endif
endif # REGRESS
ifdef MODULE_big
clean: clean-lib
endif
distclean maintainer-clean: clean
ifdef REGRESS
.PHONY: submake
submake:
$(MAKE) -C $(top_builddir)/src/test/regress pg_regress
# against installed postmaster
installcheck: submake
$(top_builddir)/src/test/regress/pg_regress $(REGRESS)
# in-tree test doesn't work yet (no way to install my shared library)
#check: all submake
# $(top_builddir)/src/test/regress/pg_regress --temp-install \
# --top-builddir=$(top_builddir) $(REGRESS)
check:
@echo "'make check' is not supported."
@echo "Do 'make install', then 'make installcheck' instead."
endif # REGRESS
# STANDARD RULES
ifneq (,$(MODULES)$(MODULE_big))
%.sql: %.sql.in
sed 's,MODULE_PATHNAME,$$libdir/$*,g' $< >$@
endif
ifdef PROGRAM
$(PROGRAM): $(OBJS)
$(CC) $(CFLAGS) $(OBJS) $(PG_LIBS) $(LDFLAGS) $(LIBS) -o $@
endif

View File

@ -1,36 +0,0 @@
# $Header: /cvsroot/pgsql/contrib/cube/Makefile,v 1.6 2001/11/16 16:32:33 petere Exp $
subdir = contrib/cube
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
MODULE_big = cube
OBJS= cube.o cubeparse.o cubescan.o buffer.o
DATA_built = cube.sql
DOCS = README.cube
REGRESS = cube
cubeparse.c: cubeparse.h ;
cubeparse.h: cubeparse.y
ifdef YACC
$(YACC) -d $(YFLAGS) -p cube_yy $<
mv -f y.tab.c cubeparse.c
mv -f y.tab.h cubeparse.h
else
@$(missing) bison $< $@
endif
cubescan.c: cubescan.l
ifdef FLEX
$(FLEX) $(FLEXFLAGS) -Pcube_yy -o'$@' $<
else
@$(missing) flex $< $@
endif
EXTRA_CLEAN = cubeparse.c cubeparse.h cubescan.c y.tab.c y.tab.h
include $(top_srcdir)/contrib/contrib-global.mk

View File

@ -1,289 +0,0 @@
This directory contains the code for the user-defined type,
CUBE, representing multidimensional cubes.
FILES
-----
Makefile building instructions for the shared library
README.cube the file you are now reading
buffer.c globals and buffer access utilities shared between
the parser (cubeparse.y) and the scanner (cubescan.l)
buffer.h function prototypes for buffer.c
cube.c the implementation of this data type in c
cube.sql.in SQL code needed to register this type with postgres
(transformed to cube.sql by make)
cubedata.h the data structure used to store the cubes
cubeparse.y the grammar file for the parser (used by cube_in() in cube.c)
cubescan.l scanner rules (used by cube_yyparse() in cubeparse.y)
INSTALLATION
============
To install the type, run
make
make install
For this to work, make sure that:
. the cube source directory is in the postgres contrib directory
. the user running "make install" has postgres administrative authority
. this user's environment defines the PGLIB and PGDATA variables and has
postgres binaries in the PATH.
This only installs the type implementation and documentation. To make the
type available in any particular database, do
psql -d databasename < cube.sql
If you install the type in the template1 database, all subsequently created
databases will inherit it.
To test the new type, after "make install" do
make installcheck
If it fails, examine the file regression.diffs to find out the reason (the
test code is a direct adaptation of the regression tests from the main
source tree).
SYNTAX
======
The following are valid external representations for the CUBE type:
'x' A floating point value representing
a one-dimensional point or one-dimensional
zero length cubement
'(x)' Same as above
'x1,x2,x3,...,xn' A point in n-dimensional space,
represented internally as a zero volume box
'(x1,x2,x3,...,xn)' Same as above
'(x),(y)' 1-D cubement starting at x and ending at y
or vice versa; the order does not matter
'(x1,...,xn),(y1,...,yn)' n-dimensional box represented by
a pair of its opposite corners, no matter which.
Functions take care of swapping to achieve
"lower left -- upper right" representation
before computing any values
Grammar
-------
rule 1 box -> O_BRACKET paren_list COMMA paren_list C_BRACKET
rule 2 box -> paren_list COMMA paren_list
rule 3 box -> paren_list
rule 4 box -> list
rule 5 paren_list -> O_PAREN list C_PAREN
rule 6 list -> FLOAT
rule 7 list -> list COMMA FLOAT
Tokens
------
n [0-9]+
integer [+-]?{n}
real [+-]?({n}\.{n}?)|(\.{n})
FLOAT ({integer}|{real})([eE]{integer})?
O_BRACKET \[
C_BRACKET \]
O_PAREN \(
C_PAREN \)
COMMA \,
Examples of valid CUBE representations:
--------------------------------------
'x' A floating point value representing
a one-dimensional point (or, zero-length
one-dimensional interval)
'(x)' Same as above
'x1,x2,x3,...,xn' A point in n-dimensional space,
represented internally as a zero volume cube
'(x1,x2,x3,...,xn)' Same as above
'(x),(y)' A 1-D interval starting at x and ending at y
or vice versa; the order does not matter
'[(x),(y)]' Same as above
'(x1,...,xn),(y1,...,yn)' An n-dimensional box represented by
a pair of its diagonally opposite corners,
regardless of order. Swapping is provided
by all comarison routines to ensure the
"lower left -- upper right" representation
before actaul comparison takes place.
'[(x1,...,xn),(y1,...,yn)]' Same as above
White space is ignored, so '[(x),(y)]' can be: '[ ( x ), ( y ) ]'
DEFAULTS
========
I believe this union:
select cube_union('(0,5,2),(2,3,1)','0');
cube_union
-------------------
(0, 0, 0),(2, 5, 2)
(1 row)
does not contradict to the common sense, neither does the intersection
select cube_inter('(0,-1),(1,1)','(-2),(2)');
cube_inter
-------------
(0, 0),(1, 0)
(1 row)
In all binary operations on differently sized boxes, I assume the smaller
one to be a cartesian projection, i. e., having zeroes in place of coordinates
omitted in the string representation. The above examples are equivalent to:
cube_union('(0,5,2),(2,3,1)','(0,0,0),(0,0,0)');
cube_inter('(0,-1),(1,1)','(-2,0),(2,0)');
The following containment predicate uses the point syntax,
while in fact the second argument is internally represented by a box.
This syntax makes it unnecessary to define the special Point type
and functions for (box,point) predicates.
select cube_contains('(0,0),(1,1)', '0.5,0.5');
cube_contains
--------------
t
(1 row)
PRECISION
=========
Values are stored internally as 32-bit floating point numbers. This means that
numbers with more than 7 significant digits will be truncated.
USAGE
=====
The access method for CUBE is a GiST (gist_cube_ops), which is a
generalization of R-tree. GiSTs allow the postgres implementation of
R-tree, originally encoded to support 2-D geometric types such as
boxes and polygons, to be used with any data type whose data domain
can be partitioned using the concepts of containment, intersection and
equality. In other words, everything that can intersect or contain
its own kind can be indexed with a GiST. That includes, among other
things, all geometric data types, regardless of their dimensionality
(see also contrib/seg).
The operators supported by the GiST access method include:
[a, b] << [c, d] Is left of
The left operand, [a, b], occurs entirely to the left of the
right operand, [c, d], on the axis (-inf, inf). It means,
[a, b] << [c, d] is true if b < c and false otherwise
[a, b] >> [c, d] Is right of
[a, b] is occurs entirely to the right of [c, d].
[a, b] >> [c, d] is true if b > c and false otherwise
[a, b] &< [c, d] Over left
The cubement [a, b] overlaps the cubement [c, d] in such a way
that a <= c <= b and b <= d
[a, b] &> [c, d] Over right
The cubement [a, b] overlaps the cubement [c, d] in such a way
that a > c and b <= c <= d
[a, b] = [c, d] Same as
The cubements [a, b] and [c, d] are identical, that is, a == b
and c == d
[a, b] @ [c, d] Contains
The cubement [a, b] contains the cubement [c, d], that is,
a <= c and b >= d
[a, b] @ [c, d] Contained in
The cubement [a, b] is contained in [c, d], that is,
a >= c and b <= d
Although the mnemonics of the following operators is questionable, I
preserved them to maintain visual consistency with other geometric
data types defined in Postgres.
Other operators:
[a, b] < [c, d] Less than
[a, b] > [c, d] Greater than
These operators do not make a lot of sense for any practical
purpose but sorting. These operators first compare (a) to (c),
and if these are equal, compare (b) to (d). That accounts for
reasonably good sorting in most cases, which is useful if
you want to use ORDER BY with this type
There are a few other potentially useful functions defined in cube.c
that vanished from the schema because I stopped using them. Some of
these were meant to support type casting. Let me know if I was wrong:
I will then add them back to the schema. I would also appreciate
other ideas that would enhance the type and make it more useful.
For examples of usage, see sql/cube.sql
CREDITS
=======
This code is essentially based on the example written for
Illustra, http://garcia.me.berkeley.edu/~adong/rtree
My thanks are primarily to Prof. Joe Hellerstein
(http://db.cs.berkeley.edu/~jmh/) for elucidating the gist of the GiST
(http://gist.cs.berkeley.edu/), and to his former student, Andy Dong
(http://best.me.berkeley.edu/~adong/), for his exemplar.
I am also grateful to all postgres developers, present and past, for enabling
myself to create my own world and live undisturbed in it. And I would like to
acknowledge my gratitude to Argonne Lab and to the U.S. Department of Energy
for the years of faithful support of my database research.
------------------------------------------------------------------------
Gene Selkov, Jr.
Computational Scientist
Mathematics and Computer Science Division
Argonne National Laboratory
9700 S Cass Ave.
Building 221
Argonne, IL 60439-4844
selkovjr@mcs.anl.gov

View File

@ -1,84 +0,0 @@
/* This module defines the parse buffer and routines for setting/reading it */
#include "postgres.h"
#include "utils/elog.h"
static char *PARSE_BUFFER;
static char *PARSE_BUFFER_PTR;
static unsigned int PARSE_BUFFER_SIZE;
static unsigned int SCANNER_POS;
void set_parse_buffer(char *s);
void reset_parse_buffer(void);
int read_parse_buffer(void);
char *parse_buffer(void);
char *parse_buffer_ptr(void);
unsigned int parse_buffer_curr_char(void);
unsigned int parse_buffer_size(void);
unsigned int parse_buffer_pos(void);
extern void cube_flush_scanner_buffer(void); /* defined in cubescan.l */
void
set_parse_buffer(char *s)
{
PARSE_BUFFER = s;
PARSE_BUFFER_SIZE = strlen(s);
if (PARSE_BUFFER_SIZE == 0)
elog(ERROR, "cube_in: can't parse an empty string");
PARSE_BUFFER_PTR = PARSE_BUFFER;
SCANNER_POS = 0;
}
void
reset_parse_buffer(void)
{
PARSE_BUFFER_PTR = PARSE_BUFFER;
SCANNER_POS = 0;
cube_flush_scanner_buffer();
}
int
read_parse_buffer(void)
{
int c;
/*
* c = *PARSE_BUFFER_PTR++; SCANNER_POS++;
*/
c = PARSE_BUFFER[SCANNER_POS];
if (SCANNER_POS < PARSE_BUFFER_SIZE)
SCANNER_POS++;
return c;
}
char *
parse_buffer(void)
{
return PARSE_BUFFER;
}
unsigned int
parse_buffer_curr_char(void)
{
return PARSE_BUFFER[SCANNER_POS];
}
char *
parse_buffer_ptr(void)
{
return PARSE_BUFFER_PTR;
}
unsigned int
parse_buffer_pos(void)
{
return SCANNER_POS;
}
unsigned int
parse_buffer_size(void)
{
return PARSE_BUFFER_SIZE;
}

View File

@ -1,8 +0,0 @@
extern void set_parse_buffer(char *s);
extern void reset_parse_buffer(void);
extern int read_parse_buffer(void);
extern char *parse_buffer(void);
extern char *parse_buffer_ptr(void);
extern unsigned int parse_buffer_curr_char(void);
extern unsigned int parse_buffer_pos(void);
extern unsigned int parse_buffer_size(void);

File diff suppressed because it is too large Load Diff

View File

@ -1,372 +0,0 @@
-- Create the user-defined type for N-dimensional boxes
--
BEGIN TRANSACTION;
CREATE FUNCTION cube_in(opaque)
RETURNS opaque
AS 'MODULE_PATHNAME'
LANGUAGE 'c';
CREATE FUNCTION cube_out(opaque)
RETURNS opaque
AS 'MODULE_PATHNAME'
LANGUAGE 'c';
CREATE TYPE cube (
internallength = variable,
input = cube_in,
output = cube_out
);
COMMENT ON TYPE cube IS
'multi-dimensional cube ''(FLOAT-1, FLOAT-2, ..., FLOAT-N), (FLOAT-1, FLOAT-2, ..., FLOAT-N)''';
--
-- External C-functions for R-tree methods
--
-- Left/Right methods
CREATE FUNCTION cube_over_left(cube, cube) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_over_left(cube, cube) IS
'is over and left of (NOT IMPLEMENTED)';
CREATE FUNCTION cube_over_right(cube, cube) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_over_right(cube, cube) IS
'is over and right of (NOT IMPLEMENTED)';
CREATE FUNCTION cube_left(cube, cube) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_left(cube, cube) IS
'is left of (NOT IMPLEMENTED)';
CREATE FUNCTION cube_right(cube, cube) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_right(cube, cube) IS
'is right of (NOT IMPLEMENTED)';
-- Comparison methods
CREATE FUNCTION cube_lt(cube, cube) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_lt(cube, cube) IS
'lower than';
CREATE FUNCTION cube_gt(cube, cube) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_gt(cube, cube) IS
'greater than';
CREATE FUNCTION cube_contains(cube, cube) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_contains(cube, cube) IS
'contains';
CREATE FUNCTION cube_contained(cube, cube) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_contained(cube, cube) IS
'contained in';
CREATE FUNCTION cube_overlap(cube, cube) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_overlap(cube, cube) IS
'overlaps';
CREATE FUNCTION cube_same(cube, cube) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_same(cube, cube) IS
'same as';
CREATE FUNCTION cube_different(cube, cube) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
COMMENT ON FUNCTION cube_different(cube, cube) IS
'different';
-- support routines for indexing
CREATE FUNCTION cube_union(cube, cube) RETURNS cube
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
CREATE FUNCTION cube_inter(cube, cube) RETURNS cube
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
CREATE FUNCTION cube_size(cube) RETURNS float4
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
-- Misc N-dimensional functions
-- proximity routines
CREATE FUNCTION cube_distance(cube, cube) RETURNS float4
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
--
-- OPERATORS
--
CREATE OPERATOR < (
LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_lt,
COMMUTATOR = '>',
RESTRICT = scalarltsel, JOIN = scalarltjoinsel
);
CREATE OPERATOR > (
LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_gt,
COMMUTATOR = '<',
RESTRICT = scalargtsel, JOIN = scalargtjoinsel
);
CREATE OPERATOR << (
LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_left,
COMMUTATOR = '>>',
RESTRICT = positionsel, JOIN = positionjoinsel
);
CREATE OPERATOR &< (
LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_over_left,
COMMUTATOR = '&>',
RESTRICT = positionsel, JOIN = positionjoinsel
);
CREATE OPERATOR && (
LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_overlap,
COMMUTATOR = '&&',
RESTRICT = positionsel, JOIN = positionjoinsel
);
CREATE OPERATOR &> (
LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_over_right,
COMMUTATOR = '&<',
RESTRICT = positionsel, JOIN = positionjoinsel
);
CREATE OPERATOR >> (
LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_right,
COMMUTATOR = '<<',
RESTRICT = positionsel, JOIN = positionjoinsel
);
CREATE OPERATOR = (
LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_same,
COMMUTATOR = '=', NEGATOR = '<>',
RESTRICT = eqsel, JOIN = eqjoinsel,
SORT1 = '<', SORT2 = '<'
);
CREATE OPERATOR <> (
LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_different,
COMMUTATOR = '<>', NEGATOR = '=',
RESTRICT = neqsel, JOIN = neqjoinsel
);
CREATE OPERATOR @ (
LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_contains,
COMMUTATOR = '~',
RESTRICT = contsel, JOIN = contjoinsel
);
CREATE OPERATOR ~ (
LEFTARG = cube, RIGHTARG = cube, PROCEDURE = cube_contained,
COMMUTATOR = '@',
RESTRICT = contsel, JOIN = contjoinsel
);
-- define the GiST support methods
CREATE FUNCTION g_cube_consistent(opaque,cube,int4) RETURNS bool
AS 'MODULE_PATHNAME' LANGUAGE 'c';
CREATE FUNCTION g_cube_compress(opaque) RETURNS opaque
AS 'MODULE_PATHNAME' LANGUAGE 'c';
CREATE FUNCTION g_cube_decompress(opaque) RETURNS opaque
AS 'MODULE_PATHNAME' LANGUAGE 'c';
CREATE FUNCTION g_cube_penalty(opaque,opaque,opaque) RETURNS opaque
AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict);
CREATE FUNCTION g_cube_picksplit(opaque, opaque) RETURNS opaque
AS 'MODULE_PATHNAME' LANGUAGE 'c';
CREATE FUNCTION g_cube_union(bytea, opaque) RETURNS cube
AS 'MODULE_PATHNAME' LANGUAGE 'c';
CREATE FUNCTION g_cube_same(cube, cube, opaque) RETURNS opaque
AS 'MODULE_PATHNAME' LANGUAGE 'c';
-- register the default opclass for indexing
INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype)
VALUES (
(SELECT oid FROM pg_am WHERE amname = 'gist'),
'gist_cube_ops',
(SELECT oid FROM pg_namespace WHERE nspname = 'pg_catalog'),
1, -- UID of superuser is hardwired to 1 as of PG 7.3
(SELECT oid FROM pg_type WHERE typname = 'cube'),
true,
0);
-- get the comparators for boxes and store them in a tmp table
SELECT o.oid AS opoid, o.oprname
INTO TEMP TABLE gist_cube_ops_tmp
FROM pg_operator o, pg_type t
WHERE o.oprleft = t.oid and o.oprright = t.oid
and t.typname = 'cube';
-- make sure we have the right operators
-- SELECT * from gist_cube_ops_tmp;
-- using the tmp table, generate the amop entries
-- cube_left
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 1, false, c.opoid
FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '<<';
-- cube_over_left
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 2, false, c.opoid
FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '&<';
-- cube_overlap
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 3, false, c.opoid
FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '&&';
-- cube_over_right
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 4, false, c.opoid
FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '&>';
-- cube_right
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 5, false, c.opoid
FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '>>';
-- cube_same
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 6, false, c.opoid
FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '=';
-- cube_contains
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 7, false, c.opoid
FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '@';
-- cube_contained
INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr)
SELECT opcl.oid, 8, false, c.opoid
FROM pg_opclass opcl, gist_cube_ops_tmp c
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and c.oprname = '~';
DROP TABLE gist_cube_ops_tmp;
-- add the entries to amproc for the support methods
-- note the amprocnum numbers associated with each are specific!
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 1, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_consistent';
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 2, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_union';
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 3, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_compress';
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 4, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_decompress';
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 5, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_penalty';
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 6, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_picksplit';
INSERT INTO pg_amproc (amopclaid, amprocnum, amproc)
SELECT opcl.oid, 7, pro.oid
FROM pg_opclass opcl, pg_proc pro
WHERE
opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist')
and opcname = 'gist_cube_ops'
and proname = 'g_cube_same';
END TRANSACTION;

View File

@ -1,6 +0,0 @@
typedef struct NDBOX
{
unsigned int size; /* required to be a Postgres varlena type */
unsigned int dim;
float x[1];
} NDBOX;

View File

@ -1,252 +0,0 @@
%{
/* NdBox = [(lowerleft),(upperright)] */
/* [(xLL(1)...xLL(N)),(xUR(1)...xUR(n))] */
#define YYERROR_VERBOSE
#define YYPARSE_PARAM result /* need this to pass a pointer (void *) to yyparse */
#define YYSTYPE char *
#define YYDEBUG 1
#include <string.h>
#include "cubedata.h"
#include "buffer.h"
#include "postgres.h"
#include "utils/palloc.h"
#include "utils/elog.h"
#undef yylex /* falure to redefine yylex will result in a call to the */
#define yylex cube_yylex /* wrong scanner when running inside the postgres backend */
extern int yylex(); /* defined as cube_yylex in cubescan.c */
extern int errno;
int cube_yyerror( char *msg );
int cube_yyparse(void *result);
static int delim_count(char *s, char delim);
static NDBOX * write_box(unsigned int dim, char *str1, char *str2);
static NDBOX * write_point_as_box(char *s);
%}
/* BISON Declarations */
%token FLOAT O_PAREN C_PAREN O_BRACKET C_BRACKET COMMA
%start box
/* Grammar follows */
%%
box:
O_BRACKET paren_list COMMA paren_list C_BRACKET {
int dim;
int c = parse_buffer_curr_char();
int pos = parse_buffer_pos();
/* We can't let the parser recognize more than one valid expression:
the job is done and memory is allocated. */
if ( c != '\0' ) {
/* Not at EOF */
reset_parse_buffer();
elog(ERROR, "(0) bad cube representation; garbage at or before char %d, ('%c', \\%03o)\n", pos, c, c );
YYERROR;
}
dim = delim_count($2, ',') + 1;
if ( (delim_count($4, ',') + 1) != dim ) {
reset_parse_buffer();
elog(ERROR, "(1) bad cube representation; different point dimensions in (%s) and (%s)\n", $2, $4);
YYABORT;
}
*((void **)result) = write_box( dim, $2, $4 );
}
|
paren_list COMMA paren_list {
int dim;
int c = parse_buffer_curr_char();
int pos = parse_buffer_pos();
if ( c != '\0' ) { /* Not at EOF */
reset_parse_buffer();
elog(ERROR, "(2) bad cube representation; garbage at or before char %d, ('%c', \\%03o)\n", pos, c, c );
YYABORT;
}
dim = delim_count($1, ',') + 1;
if ( (delim_count($3, ',') + 1) != dim ) {
reset_parse_buffer();
elog(ERROR, "(3) bad cube representation; different point dimensions in (%s) and (%s)\n", $1, $3);
YYABORT;
}
*((void **)result) = write_box( dim, $1, $3 );
}
|
paren_list {
int c = parse_buffer_curr_char();
int pos = parse_buffer_pos();
if ( c != '\0') { /* Not at EOF */
reset_parse_buffer();
elog(ERROR, "(4) bad cube representation; garbage at or before char %d, ('%c', \\%03o)\n", pos, c, c );
YYABORT;
}
if ( yychar != YYEOF) {
/* There's still a lookahead token to be parsed */
reset_parse_buffer();
elog(ERROR, "(5) bad cube representation; garbage at or before char %d, ('end of input', \\%03o)\n", pos, c);
YYABORT;
}
*((void **)result) = write_point_as_box($1);
}
|
list {
int c = parse_buffer_curr_char();
int pos = parse_buffer_pos();
if ( c != '\0') { /* Not at EOF */
reset_parse_buffer();
elog(ERROR, "(6) bad cube representation; garbage at or before char %d, ('%c', \\%03o)\n", pos, c, c);
YYABORT;
}
if ( yychar != YYEOF) {
/* There's still a lookahead token to be parsed */
reset_parse_buffer();
elog(ERROR, "(7) bad cube representation; garbage at or before char %d, ('end of input', \\%03o)\n", pos, c);
YYABORT;
}
*((void **)result) = write_point_as_box($1);
}
;
paren_list:
O_PAREN list C_PAREN {
$$ = $2;
}
;
list:
FLOAT {
$$ = palloc(strlen(parse_buffer()) + 1);
strcpy($$, $1);
}
|
list COMMA FLOAT {
$$ = $1;
strcat($$, ",");
strcat($$, $3);
}
;
%%
int cube_yyerror ( char *msg ) {
char *buf = (char *) palloc(256);
int position;
yyclearin;
if ( !strcmp(msg, "parse error, expecting `$'") ) {
msg = "expecting end of input";
}
position = parse_buffer_pos() > parse_buffer_size() ? parse_buffer_pos() - 1 : parse_buffer_pos();
sprintf(
buf,
"%s at or before position %d, character ('%c', \\%03o), input: '%s'\n",
msg,
position,
parse_buffer()[position - 1],
parse_buffer()[position - 1],
parse_buffer()
);
reset_parse_buffer();
elog(ERROR, buf);
return 0;
}
static int
delim_count(char *s, char delim)
{
int ndelim = 0;
while ((s = strchr(s, delim)) != NULL)
{
ndelim++;
s++;
}
return (ndelim);
}
static NDBOX *
write_box(unsigned int dim, char *str1, char *str2)
{
NDBOX * bp;
char * s;
int i;
int size = offsetof(NDBOX, x[0]) + sizeof(float) * dim * 2;
bp = palloc(size);
bp->size = size;
bp->dim = dim;
s = str1;
bp->x[i=0] = strtod(s, NULL);
while ((s = strchr(s, ',')) != NULL) {
s++; i++;
bp->x[i] = strtod(s, NULL);
}
s = str2;
bp->x[i=dim] = strtod(s, NULL);
while ((s = strchr(s, ',')) != NULL) {
s++; i++;
bp->x[i] = strtod(s, NULL);
}
return(bp);
}
static NDBOX * write_point_as_box(char *str)
{
NDBOX * bp;
int i, size;
double x;
int dim = delim_count(str, ',') + 1;
char * s = str;
size = offsetof(NDBOX, x[0]) + sizeof(float) * dim * 2;
bp = palloc(size);
bp->size = size;
bp->dim = dim;
i = 0;
x = strtod(s, NULL);
bp->x[0] = x;
bp->x[dim] = x;
while ((s = strchr(s, ',')) != NULL) {
s++; i++;
x = strtod(s, NULL);
bp->x[i] = x;
bp->x[i+dim] = x;
}
return(bp);
}

View File

@ -1,54 +0,0 @@
%{
/*
** A scanner for EMP-style numeric ranges
*/
#define YYSTYPE char *
#define yylval cube_yylval
#include <stdio.h>
#include "cubeparse.h"
#include "buffer.h"
#define YY_NO_UNPUT 1
#undef yywrap
/* flex screws a couple symbols when used with the -P otion; fix those */
#define YY_DECL int cube_yylex YY_PROTO(( void )); \
int cube_yylex YY_PROTO(( void ))
/* redefined YY_INPUT reads byte-wise from the memory area defined in buffer.c */
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) \
{ \
int c = read_parse_buffer(); \
result = (c == '\0') ? YY_NULL : (buf[0] = c, 1); \
}
void cube_flush_scanner_buffer(void);
%}
n [0-9]+
integer [+-]?{n}
real [+-]?({n}\.{n}?)|(\.{n})
float ({integer}|{real})([eE]{integer})?
%%
{float} yylval = yytext; return FLOAT;
\[ yylval = "("; return O_BRACKET;
\] yylval = ")"; return C_BRACKET;
\( yylval = "("; return O_PAREN;
\) yylval = ")"; return C_PAREN;
\, yylval = ")"; return COMMA;
[ ]+ /* discard spaces */
. return yytext[0]; /* alert parser of the garbage */
%%
int cube_yylex();
void cube_flush_scanner_buffer(void) {
fprintf(stderr, "cube_flush_scanner_buffer called\n");
YY_FLUSH_BUFFER;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,950 +0,0 @@
--
-- Test cube datatype
--
--
-- first, define the datatype. Turn off echoing so that expected file
-- does not depend on contents of cube.sql.
--
\set ECHO none
--
-- testing the input and output functions
--
-- Any number (a one-dimensional point)
SELECT '1'::cube AS cube;
cube
------
(1)
(1 row)
SELECT '-1'::cube AS cube;
cube
------
(-1)
(1 row)
SELECT '1.'::cube AS cube;
cube
------
(1)
(1 row)
SELECT '-1.'::cube AS cube;
cube
------
(-1)
(1 row)
SELECT '.1'::cube AS cube;
cube
-------
(0.1)
(1 row)
SELECT '-.1'::cube AS cube;
ERROR: parse error, expecting `FLOAT' or `O_PAREN' or `O_BRACKET' at or before position 2, character ('.', \056), input: '-.1'
SELECT '1.0'::cube AS cube;
cube
------
(1)
(1 row)
SELECT '-1.0'::cube AS cube;
cube
------
(-1)
(1 row)
SELECT '1e7'::cube AS cube;
cube
---------
(1e+07)
(1 row)
SELECT '-1e7'::cube AS cube;
cube
----------
(-1e+07)
(1 row)
SELECT '1.0e7'::cube AS cube;
cube
---------
(1e+07)
(1 row)
SELECT '-1.0e7'::cube AS cube;
cube
----------
(-1e+07)
(1 row)
SELECT '1e+7'::cube AS cube;
cube
---------
(1e+07)
(1 row)
SELECT '-1e+7'::cube AS cube;
cube
----------
(-1e+07)
(1 row)
SELECT '1.0e+7'::cube AS cube;
cube
---------
(1e+07)
(1 row)
SELECT '-1.0e+7'::cube AS cube;
cube
----------
(-1e+07)
(1 row)
SELECT '1e-7'::cube AS cube;
cube
---------
(1e-07)
(1 row)
SELECT '-1e-7'::cube AS cube;
cube
----------
(-1e-07)
(1 row)
SELECT '1.0e-7'::cube AS cube;
cube
---------
(1e-07)
(1 row)
SELECT '-1.0e-7'::cube AS cube;
cube
----------
(-1e-07)
(1 row)
SELECT '1e-700'::cube AS cube;
cube
------
(0)
(1 row)
SELECT '-1e-700'::cube AS cube;
cube
------
(0)
(1 row)
-- simple lists (points)
SELECT '1,2'::cube AS cube;
cube
--------
(1, 2)
(1 row)
SELECT '(1,2)'::cube AS cube;
cube
--------
(1, 2)
(1 row)
SELECT '1,2,3,4,5'::cube AS cube;
cube
-----------------
(1, 2, 3, 4, 5)
(1 row)
SELECT '(1,2,3,4,5)'::cube AS cube;
cube
-----------------
(1, 2, 3, 4, 5)
(1 row)
-- double lists (cubes)
SELECT '(0),(0)'::cube AS cube;
cube
------
(0)
(1 row)
SELECT '(0),(1)'::cube AS cube;
cube
---------
(0),(1)
(1 row)
SELECT '[(0),(0)]'::cube AS cube;
cube
------
(0)
(1 row)
SELECT '[(0),(1)]'::cube AS cube;
cube
---------
(0),(1)
(1 row)
SELECT '(0,0,0,0),(0,0,0,0)'::cube AS cube;
cube
--------------
(0, 0, 0, 0)
(1 row)
SELECT '(0,0,0,0),(1,0,0,0)'::cube AS cube;
cube
---------------------------
(0, 0, 0, 0),(1, 0, 0, 0)
(1 row)
SELECT '[(0,0,0,0),(0,0,0,0)]'::cube AS cube;
cube
--------------
(0, 0, 0, 0)
(1 row)
SELECT '[(0,0,0,0),(1,0,0,0)]'::cube AS cube;
cube
---------------------------
(0, 0, 0, 0),(1, 0, 0, 0)
(1 row)
-- invalid input: parse errors
SELECT ''::cube AS cube;
ERROR: cube_in: can't parse an empty string
SELECT 'ABC'::cube AS cube;
ERROR: parse error, expecting `FLOAT' or `O_PAREN' or `O_BRACKET' at or before position 1, character ('A', \101), input: 'ABC'
SELECT '()'::cube AS cube;
ERROR: parse error, expecting `FLOAT' at or before position 2, character (')', \051), input: '()'
SELECT '[]'::cube AS cube;
ERROR: parse error, expecting `O_PAREN' at or before position 2, character (']', \135), input: '[]'
SELECT '[()]'::cube AS cube;
ERROR: parse error, expecting `FLOAT' at or before position 3, character (')', \051), input: '[()]'
SELECT '[(1)]'::cube AS cube;
ERROR: parse error, expecting `COMMA' at or before position 5, character (']', \135), input: '[(1)]'
SELECT '[(1),]'::cube AS cube;
ERROR: parse error, expecting `O_PAREN' at or before position 6, character (']', \135), input: '[(1),]'
SELECT '[(1),2]'::cube AS cube;
ERROR: parse error, expecting `O_PAREN' at or before position 7, character (']', \135), input: '[(1),2]'
SELECT '[(1),(2),(3)]'::cube AS cube;
ERROR: parse error, expecting `C_BRACKET' at or before position 9, character (',', \054), input: '[(1),(2),(3)]'
SELECT '1,'::cube AS cube;
ERROR: parse error, expecting `FLOAT' at or before position 2, character (',', \054), input: '1,'
SELECT '1,2,'::cube AS cube;
ERROR: parse error, expecting `FLOAT' at or before position 4, character (',', \054), input: '1,2,'
SELECT '1,,2'::cube AS cube;
ERROR: parse error, expecting `FLOAT' at or before position 3, character (',', \054), input: '1,,2'
SELECT '(1,)'::cube AS cube;
ERROR: parse error, expecting `FLOAT' at or before position 4, character (')', \051), input: '(1,)'
SELECT '(1,2,)'::cube AS cube;
ERROR: parse error, expecting `FLOAT' at or before position 6, character (')', \051), input: '(1,2,)'
SELECT '(1,,2)'::cube AS cube;
ERROR: parse error, expecting `FLOAT' at or before position 4, character (',', \054), input: '(1,,2)'
-- invalid input: semantic errors and trailing garbage
SELECT '[(1),(2)],'::cube AS cube; -- 0
ERROR: (0) bad cube representation; garbage at or before char 9, (',', \054)
SELECT '[(1,2,3),(2,3)]'::cube AS cube; -- 1
ERROR: (1) bad cube representation; different point dimensions in (1,2,3) and (2,3)
SELECT '[(1,2),(1,2,3)]'::cube AS cube; -- 1
ERROR: (1) bad cube representation; different point dimensions in (1,2) and (1,2,3)
SELECT '(1),(2),'::cube AS cube; -- 2
ERROR: (2) bad cube representation; garbage at or before char 7, (',', \054)
SELECT '(1,2,3),(2,3)'::cube AS cube; -- 3
ERROR: (3) bad cube representation; different point dimensions in (1,2,3) and (2,3)
SELECT '(1,2),(1,2,3)'::cube AS cube; -- 3
ERROR: (3) bad cube representation; different point dimensions in (1,2) and (1,2,3)
SELECT '(1,2,3)ab'::cube AS cube; -- 4
ERROR: (4) bad cube representation; garbage at or before char 8, ('b', \142)
SELECT '(1,2,3)a'::cube AS cube; -- 5
ERROR: (5) bad cube representation; garbage at or before char 8, ('end of input', \000)
SELECT '(1,2)('::cube AS cube; -- 5
ERROR: (5) bad cube representation; garbage at or before char 6, ('end of input', \000)
SELECT '1,2ab'::cube AS cube; -- 6
ERROR: (6) bad cube representation; garbage at or before char 4, ('b', \142)
SELECT '1 e7'::cube AS cube; -- 6
ERROR: (6) bad cube representation; garbage at or before char 3, ('7', \067)
SELECT '1,2a'::cube AS cube; -- 7
ERROR: (7) bad cube representation; garbage at or before char 4, ('end of input', \000)
SELECT '1..2'::cube AS cube; -- 7
ERROR: (7) bad cube representation; garbage at or before char 4, ('end of input', \000)
--
-- testing the operators
--
-- equality/inequality:
--
SELECT '24, 33.20'::cube = '24, 33.20'::cube AS bool;
bool
------
t
(1 row)
SELECT '24, 33.20'::cube != '24, 33.20'::cube AS bool;
bool
------
f
(1 row)
SELECT '24, 33.20'::cube = '24, 33.21'::cube AS bool;
bool
------
f
(1 row)
SELECT '24, 33.20'::cube != '24, 33.21'::cube AS bool;
bool
------
t
(1 row)
SELECT '(2,0),(3,1)'::cube = '(2,0,0,0,0),(3,1,0,0,0)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(2,0),(3,1)'::cube = '(2,0,0,0,0),(3,1,0,0,1)'::cube AS bool;
bool
------
f
(1 row)
-- "lower than" / "greater than"
-- (these operators are not useful for anything but ordering)
--
SELECT '1'::cube > '2'::cube AS bool;
bool
------
f
(1 row)
SELECT '1'::cube < '2'::cube AS bool;
bool
------
t
(1 row)
SELECT '1,1'::cube > '1,2'::cube AS bool;
bool
------
f
(1 row)
SELECT '1,1'::cube < '1,2'::cube AS bool;
bool
------
t
(1 row)
SELECT '(2,0),(3,1)'::cube > '(2,0,0,0,0),(3,1,0,0,1)'::cube AS bool;
bool
------
f
(1 row)
SELECT '(2,0),(3,1)'::cube < '(2,0,0,0,0),(3,1,0,0,1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(2,0),(3,1)'::cube > '(2,0,0,0,1),(3,1,0,0,0)'::cube AS bool;
bool
------
f
(1 row)
SELECT '(2,0),(3,1)'::cube < '(2,0,0,0,1),(3,1,0,0,0)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(2,0),(3,1)'::cube > '(2,0,0,0,0),(3,1,0,0,0)'::cube AS bool;
bool
------
f
(1 row)
SELECT '(2,0),(3,1)'::cube < '(2,0,0,0,0),(3,1,0,0,0)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(2,0,0,0,0),(3,1,0,0,1)'::cube > '(2,0),(3,1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(2,0,0,0,0),(3,1,0,0,1)'::cube < '(2,0),(3,1)'::cube AS bool;
bool
------
f
(1 row)
SELECT '(2,0,0,0,1),(3,1,0,0,0)'::cube > '(2,0),(3,1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(2,0,0,0,1),(3,1,0,0,0)'::cube < '(2,0),(3,1)'::cube AS bool;
bool
------
f
(1 row)
SELECT '(2,0,0,0,0),(3,1,0,0,0)'::cube > '(2,0),(3,1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(2,0,0,0,0),(3,1,0,0,0)'::cube < '(2,0),(3,1)'::cube AS bool;
bool
------
f
(1 row)
-- "overlap"
--
SELECT '1'::cube && '1'::cube AS bool;
bool
------
t
(1 row)
SELECT '1'::cube && '2'::cube AS bool;
bool
------
f
(1 row)
SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '0'::cube AS bool;
bool
------
t
(1 row)
SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '1'::cube AS bool;
bool
------
t
(1 row)
SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '1,1,1'::cube AS bool;
bool
------
t
(1 row)
SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '[(1,1,1),(2,2,2)]'::cube AS bool;
bool
------
t
(1 row)
SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '[(1,1),(2,2)]'::cube AS bool;
bool
------
t
(1 row)
SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '[(2,1,1),(2,2,2)]'::cube AS bool;
bool
------
f
(1 row)
-- "overlap on the left" / "overlap on the right"
-- (these operators are not useful at all but R-tree seems to be
-- sensitive to their presence)
--
SELECT '1'::cube &< '0'::cube AS bool;
bool
------
f
(1 row)
SELECT '1'::cube &< '1'::cube AS bool;
bool
------
t
(1 row)
SELECT '1'::cube &< '2'::cube AS bool;
bool
------
f
(1 row)
SELECT '(0),(1)'::cube &< '0'::cube AS bool;
bool
------
t
(1 row)
SELECT '(0),(1)'::cube &< '1'::cube AS bool;
bool
------
f
(1 row)
SELECT '(0),(1)'::cube &< '(0),(0.5)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(0),(1)'::cube &< '(0),(1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(0),(1)'::cube &< '(0),(2)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(0),(1)'::cube &< '(1),(2)'::cube AS bool;
bool
------
f
(1 row)
SELECT '(0),(1)'::cube &< '(2),(3)'::cube AS bool;
bool
------
f
(1 row)
SELECT '0'::cube &> '1'::cube AS bool;
bool
------
f
(1 row)
SELECT '1'::cube &> '1'::cube AS bool;
bool
------
t
(1 row)
SELECT '2'::cube &> '1'::cube AS bool;
bool
------
f
(1 row)
SELECT '0'::cube &> '(0),(1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '1'::cube &> '(0),(1)'::cube AS bool;
bool
------
f
(1 row)
SELECT '(0),(0.5)' &> '(0),(1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(0),(1)'::cube &> '(0),(1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(0),(2)'::cube &> '(0),(1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(1),(2)'::cube &> '(0),(1)'::cube AS bool;
bool
------
f
(1 row)
SELECT '(2),(3)'::cube &> '(0),(1)'::cube AS bool;
bool
------
f
(1 row)
-- "left" / "right"
-- (these operators are not useful but for 1-D or 2-D cubes, but R-tree
-- seems to want them defined)
--
SELECT '1'::cube << '0'::cube AS bool;
bool
------
f
(1 row)
SELECT '1'::cube << '1'::cube AS bool;
bool
------
f
(1 row)
SELECT '1'::cube << '2'::cube AS bool;
bool
------
t
(1 row)
SELECT '(0),(1)'::cube << '0'::cube AS bool;
bool
------
f
(1 row)
SELECT '(0),(1)'::cube << '1'::cube AS bool;
bool
------
t
(1 row)
SELECT '(0),(1)'::cube << '(0),(0.5)'::cube AS bool;
bool
------
f
(1 row)
SELECT '(0),(1)'::cube << '(0),(1)'::cube AS bool;
bool
------
f
(1 row)
SELECT '(0),(1)'::cube << '(0),(2)'::cube AS bool;
bool
------
f
(1 row)
SELECT '(0),(1)'::cube << '(1),(2)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(0),(1)'::cube << '(2),(3)'::cube AS bool;
bool
------
t
(1 row)
SELECT '0'::cube >> '1'::cube AS bool;
bool
------
f
(1 row)
SELECT '1'::cube >> '1'::cube AS bool;
bool
------
f
(1 row)
SELECT '2'::cube >> '1'::cube AS bool;
bool
------
t
(1 row)
SELECT '0'::cube >> '(0),(1)'::cube AS bool;
bool
------
f
(1 row)
SELECT '1'::cube >> '(0),(1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(0),(0.5)' >> '(0),(1)'::cube AS bool;
bool
------
f
(1 row)
SELECT '(0),(1)'::cube >> '(0),(1)'::cube AS bool;
bool
------
f
(1 row)
SELECT '(0),(2)'::cube >> '(0),(1)'::cube AS bool;
bool
------
f
(1 row)
SELECT '(1),(2)'::cube >> '(0),(1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(2),(3)'::cube >> '(0),(1)'::cube AS bool;
bool
------
t
(1 row)
-- "contained in" (the left operand is the cube entirely enclosed by
-- the right operand):
--
SELECT '0'::cube ~ '0'::cube AS bool;
bool
------
t
(1 row)
SELECT '0,0,0'::cube ~ '0,0,0'::cube AS bool;
bool
------
t
(1 row)
SELECT '0,0'::cube ~ '0,0,1'::cube AS bool;
bool
------
t
(1 row)
SELECT '0,0,0'::cube ~ '0,0,1'::cube AS bool;
bool
------
f
(1 row)
SELECT '1,0,0'::cube ~ '0,0,1'::cube AS bool;
bool
------
f
(1 row)
SELECT '(1,0,0),(0,0,1)'::cube ~ '(1,0,0),(0,0,1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(1,0,0),(0,0,1)'::cube ~ '(-1,-1,-1),(1,1,1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(1,0,0),(0,0,1)'::cube ~ '(-1,-1,-1,-1),(1,1,1,1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '0'::cube ~ '(-1),(1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '1'::cube ~ '(-1),(1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '-1'::cube ~ '(-1),(1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(-1),(1)'::cube ~ '(-1),(1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(-1),(1)'::cube ~ '(-1,-1),(1,1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(-2),(1)'::cube ~ '(-1),(1)'::cube AS bool;
bool
------
f
(1 row)
SELECT '(-2),(1)'::cube ~ '(-1,-1),(1,1)'::cube AS bool;
bool
------
f
(1 row)
-- "contains" (the left operand is the cube that entirely encloses the
-- right operand)
--
SELECT '0'::cube @ '0'::cube AS bool;
bool
------
t
(1 row)
SELECT '0,0,0'::cube @ '0,0,0'::cube AS bool;
bool
------
t
(1 row)
SELECT '0,0,1'::cube @ '0,0'::cube AS bool;
bool
------
t
(1 row)
SELECT '0,0,1'::cube @ '0,0,0'::cube AS bool;
bool
------
f
(1 row)
SELECT '0,0,1'::cube @ '1,0,0'::cube AS bool;
bool
------
f
(1 row)
SELECT '(1,0,0),(0,0,1)'::cube @ '(1,0,0),(0,0,1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(-1,-1,-1),(1,1,1)'::cube @ '(1,0,0),(0,0,1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(-1,-1,-1,-1),(1,1,1,1)'::cube @ '(1,0,0),(0,0,1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(-1),(1)'::cube @ '0'::cube AS bool;
bool
------
t
(1 row)
SELECT '(-1),(1)'::cube @ '1'::cube AS bool;
bool
------
t
(1 row)
SELECT '(-1),(1)'::cube @ '-1'::cube AS bool;
bool
------
t
(1 row)
SELECT '(-1),(1)'::cube @ '(-1),(1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(-1,-1),(1,1)'::cube @ '(-1),(1)'::cube AS bool;
bool
------
t
(1 row)
SELECT '(-1),(1)'::cube @ '(-2),(1)'::cube AS bool;
bool
------
f
(1 row)
SELECT '(-1,-1),(1,1)'::cube @ '(-2),(1)'::cube AS bool;
bool
------
f
(1 row)
-- Load some example data and build the index
--
CREATE TABLE test_cube (c cube);
\copy test_cube from 'data/test_cube.data'
CREATE INDEX test_cube_ix ON test_cube USING gist (c);
SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)';
c
--------------------------
(2424, 160),(2424, 81)
(759, 187),(662, 163)
(1444, 403),(1346, 344)
(337, 455),(240, 359)
(1594, 1043),(1517, 971)
(5 rows)
-- Test sorting
SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)' GROUP BY c;
c
--------------------------
(337, 455),(240, 359)
(759, 187),(662, 163)
(1444, 403),(1346, 344)
(1594, 1043),(1517, 971)
(2424, 160),(2424, 81)
(5 rows)

View File

@ -1,244 +0,0 @@
--
-- Test cube datatype
--
--
-- first, define the datatype. Turn off echoing so that expected file
-- does not depend on contents of cube.sql.
--
\set ECHO none
\i cube.sql
\set ECHO all
--
-- testing the input and output functions
--
-- Any number (a one-dimensional point)
SELECT '1'::cube AS cube;
SELECT '-1'::cube AS cube;
SELECT '1.'::cube AS cube;
SELECT '-1.'::cube AS cube;
SELECT '.1'::cube AS cube;
SELECT '-.1'::cube AS cube;
SELECT '1.0'::cube AS cube;
SELECT '-1.0'::cube AS cube;
SELECT '1e7'::cube AS cube;
SELECT '-1e7'::cube AS cube;
SELECT '1.0e7'::cube AS cube;
SELECT '-1.0e7'::cube AS cube;
SELECT '1e+7'::cube AS cube;
SELECT '-1e+7'::cube AS cube;
SELECT '1.0e+7'::cube AS cube;
SELECT '-1.0e+7'::cube AS cube;
SELECT '1e-7'::cube AS cube;
SELECT '-1e-7'::cube AS cube;
SELECT '1.0e-7'::cube AS cube;
SELECT '-1.0e-7'::cube AS cube;
SELECT '1e-700'::cube AS cube;
SELECT '-1e-700'::cube AS cube;
-- simple lists (points)
SELECT '1,2'::cube AS cube;
SELECT '(1,2)'::cube AS cube;
SELECT '1,2,3,4,5'::cube AS cube;
SELECT '(1,2,3,4,5)'::cube AS cube;
-- double lists (cubes)
SELECT '(0),(0)'::cube AS cube;
SELECT '(0),(1)'::cube AS cube;
SELECT '[(0),(0)]'::cube AS cube;
SELECT '[(0),(1)]'::cube AS cube;
SELECT '(0,0,0,0),(0,0,0,0)'::cube AS cube;
SELECT '(0,0,0,0),(1,0,0,0)'::cube AS cube;
SELECT '[(0,0,0,0),(0,0,0,0)]'::cube AS cube;
SELECT '[(0,0,0,0),(1,0,0,0)]'::cube AS cube;
-- invalid input: parse errors
SELECT ''::cube AS cube;
SELECT 'ABC'::cube AS cube;
SELECT '()'::cube AS cube;
SELECT '[]'::cube AS cube;
SELECT '[()]'::cube AS cube;
SELECT '[(1)]'::cube AS cube;
SELECT '[(1),]'::cube AS cube;
SELECT '[(1),2]'::cube AS cube;
SELECT '[(1),(2),(3)]'::cube AS cube;
SELECT '1,'::cube AS cube;
SELECT '1,2,'::cube AS cube;
SELECT '1,,2'::cube AS cube;
SELECT '(1,)'::cube AS cube;
SELECT '(1,2,)'::cube AS cube;
SELECT '(1,,2)'::cube AS cube;
-- invalid input: semantic errors and trailing garbage
SELECT '[(1),(2)],'::cube AS cube; -- 0
SELECT '[(1,2,3),(2,3)]'::cube AS cube; -- 1
SELECT '[(1,2),(1,2,3)]'::cube AS cube; -- 1
SELECT '(1),(2),'::cube AS cube; -- 2
SELECT '(1,2,3),(2,3)'::cube AS cube; -- 3
SELECT '(1,2),(1,2,3)'::cube AS cube; -- 3
SELECT '(1,2,3)ab'::cube AS cube; -- 4
SELECT '(1,2,3)a'::cube AS cube; -- 5
SELECT '(1,2)('::cube AS cube; -- 5
SELECT '1,2ab'::cube AS cube; -- 6
SELECT '1 e7'::cube AS cube; -- 6
SELECT '1,2a'::cube AS cube; -- 7
SELECT '1..2'::cube AS cube; -- 7
--
-- testing the operators
--
-- equality/inequality:
--
SELECT '24, 33.20'::cube = '24, 33.20'::cube AS bool;
SELECT '24, 33.20'::cube != '24, 33.20'::cube AS bool;
SELECT '24, 33.20'::cube = '24, 33.21'::cube AS bool;
SELECT '24, 33.20'::cube != '24, 33.21'::cube AS bool;
SELECT '(2,0),(3,1)'::cube = '(2,0,0,0,0),(3,1,0,0,0)'::cube AS bool;
SELECT '(2,0),(3,1)'::cube = '(2,0,0,0,0),(3,1,0,0,1)'::cube AS bool;
-- "lower than" / "greater than"
-- (these operators are not useful for anything but ordering)
--
SELECT '1'::cube > '2'::cube AS bool;
SELECT '1'::cube < '2'::cube AS bool;
SELECT '1,1'::cube > '1,2'::cube AS bool;
SELECT '1,1'::cube < '1,2'::cube AS bool;
SELECT '(2,0),(3,1)'::cube > '(2,0,0,0,0),(3,1,0,0,1)'::cube AS bool;
SELECT '(2,0),(3,1)'::cube < '(2,0,0,0,0),(3,1,0,0,1)'::cube AS bool;
SELECT '(2,0),(3,1)'::cube > '(2,0,0,0,1),(3,1,0,0,0)'::cube AS bool;
SELECT '(2,0),(3,1)'::cube < '(2,0,0,0,1),(3,1,0,0,0)'::cube AS bool;
SELECT '(2,0),(3,1)'::cube > '(2,0,0,0,0),(3,1,0,0,0)'::cube AS bool;
SELECT '(2,0),(3,1)'::cube < '(2,0,0,0,0),(3,1,0,0,0)'::cube AS bool;
SELECT '(2,0,0,0,0),(3,1,0,0,1)'::cube > '(2,0),(3,1)'::cube AS bool;
SELECT '(2,0,0,0,0),(3,1,0,0,1)'::cube < '(2,0),(3,1)'::cube AS bool;
SELECT '(2,0,0,0,1),(3,1,0,0,0)'::cube > '(2,0),(3,1)'::cube AS bool;
SELECT '(2,0,0,0,1),(3,1,0,0,0)'::cube < '(2,0),(3,1)'::cube AS bool;
SELECT '(2,0,0,0,0),(3,1,0,0,0)'::cube > '(2,0),(3,1)'::cube AS bool;
SELECT '(2,0,0,0,0),(3,1,0,0,0)'::cube < '(2,0),(3,1)'::cube AS bool;
-- "overlap"
--
SELECT '1'::cube && '1'::cube AS bool;
SELECT '1'::cube && '2'::cube AS bool;
SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '0'::cube AS bool;
SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '1'::cube AS bool;
SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '1,1,1'::cube AS bool;
SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '[(1,1,1),(2,2,2)]'::cube AS bool;
SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '[(1,1),(2,2)]'::cube AS bool;
SELECT '[(-1,-1,-1),(1,1,1)]'::cube && '[(2,1,1),(2,2,2)]'::cube AS bool;
-- "overlap on the left" / "overlap on the right"
-- (these operators are not useful at all but R-tree seems to be
-- sensitive to their presence)
--
SELECT '1'::cube &< '0'::cube AS bool;
SELECT '1'::cube &< '1'::cube AS bool;
SELECT '1'::cube &< '2'::cube AS bool;
SELECT '(0),(1)'::cube &< '0'::cube AS bool;
SELECT '(0),(1)'::cube &< '1'::cube AS bool;
SELECT '(0),(1)'::cube &< '(0),(0.5)'::cube AS bool;
SELECT '(0),(1)'::cube &< '(0),(1)'::cube AS bool;
SELECT '(0),(1)'::cube &< '(0),(2)'::cube AS bool;
SELECT '(0),(1)'::cube &< '(1),(2)'::cube AS bool;
SELECT '(0),(1)'::cube &< '(2),(3)'::cube AS bool;
SELECT '0'::cube &> '1'::cube AS bool;
SELECT '1'::cube &> '1'::cube AS bool;
SELECT '2'::cube &> '1'::cube AS bool;
SELECT '0'::cube &> '(0),(1)'::cube AS bool;
SELECT '1'::cube &> '(0),(1)'::cube AS bool;
SELECT '(0),(0.5)' &> '(0),(1)'::cube AS bool;
SELECT '(0),(1)'::cube &> '(0),(1)'::cube AS bool;
SELECT '(0),(2)'::cube &> '(0),(1)'::cube AS bool;
SELECT '(1),(2)'::cube &> '(0),(1)'::cube AS bool;
SELECT '(2),(3)'::cube &> '(0),(1)'::cube AS bool;
-- "left" / "right"
-- (these operators are not useful but for 1-D or 2-D cubes, but R-tree
-- seems to want them defined)
--
SELECT '1'::cube << '0'::cube AS bool;
SELECT '1'::cube << '1'::cube AS bool;
SELECT '1'::cube << '2'::cube AS bool;
SELECT '(0),(1)'::cube << '0'::cube AS bool;
SELECT '(0),(1)'::cube << '1'::cube AS bool;
SELECT '(0),(1)'::cube << '(0),(0.5)'::cube AS bool;
SELECT '(0),(1)'::cube << '(0),(1)'::cube AS bool;
SELECT '(0),(1)'::cube << '(0),(2)'::cube AS bool;
SELECT '(0),(1)'::cube << '(1),(2)'::cube AS bool;
SELECT '(0),(1)'::cube << '(2),(3)'::cube AS bool;
SELECT '0'::cube >> '1'::cube AS bool;
SELECT '1'::cube >> '1'::cube AS bool;
SELECT '2'::cube >> '1'::cube AS bool;
SELECT '0'::cube >> '(0),(1)'::cube AS bool;
SELECT '1'::cube >> '(0),(1)'::cube AS bool;
SELECT '(0),(0.5)' >> '(0),(1)'::cube AS bool;
SELECT '(0),(1)'::cube >> '(0),(1)'::cube AS bool;
SELECT '(0),(2)'::cube >> '(0),(1)'::cube AS bool;
SELECT '(1),(2)'::cube >> '(0),(1)'::cube AS bool;
SELECT '(2),(3)'::cube >> '(0),(1)'::cube AS bool;
-- "contained in" (the left operand is the cube entirely enclosed by
-- the right operand):
--
SELECT '0'::cube ~ '0'::cube AS bool;
SELECT '0,0,0'::cube ~ '0,0,0'::cube AS bool;
SELECT '0,0'::cube ~ '0,0,1'::cube AS bool;
SELECT '0,0,0'::cube ~ '0,0,1'::cube AS bool;
SELECT '1,0,0'::cube ~ '0,0,1'::cube AS bool;
SELECT '(1,0,0),(0,0,1)'::cube ~ '(1,0,0),(0,0,1)'::cube AS bool;
SELECT '(1,0,0),(0,0,1)'::cube ~ '(-1,-1,-1),(1,1,1)'::cube AS bool;
SELECT '(1,0,0),(0,0,1)'::cube ~ '(-1,-1,-1,-1),(1,1,1,1)'::cube AS bool;
SELECT '0'::cube ~ '(-1),(1)'::cube AS bool;
SELECT '1'::cube ~ '(-1),(1)'::cube AS bool;
SELECT '-1'::cube ~ '(-1),(1)'::cube AS bool;
SELECT '(-1),(1)'::cube ~ '(-1),(1)'::cube AS bool;
SELECT '(-1),(1)'::cube ~ '(-1,-1),(1,1)'::cube AS bool;
SELECT '(-2),(1)'::cube ~ '(-1),(1)'::cube AS bool;
SELECT '(-2),(1)'::cube ~ '(-1,-1),(1,1)'::cube AS bool;
-- "contains" (the left operand is the cube that entirely encloses the
-- right operand)
--
SELECT '0'::cube @ '0'::cube AS bool;
SELECT '0,0,0'::cube @ '0,0,0'::cube AS bool;
SELECT '0,0,1'::cube @ '0,0'::cube AS bool;
SELECT '0,0,1'::cube @ '0,0,0'::cube AS bool;
SELECT '0,0,1'::cube @ '1,0,0'::cube AS bool;
SELECT '(1,0,0),(0,0,1)'::cube @ '(1,0,0),(0,0,1)'::cube AS bool;
SELECT '(-1,-1,-1),(1,1,1)'::cube @ '(1,0,0),(0,0,1)'::cube AS bool;
SELECT '(-1,-1,-1,-1),(1,1,1,1)'::cube @ '(1,0,0),(0,0,1)'::cube AS bool;
SELECT '(-1),(1)'::cube @ '0'::cube AS bool;
SELECT '(-1),(1)'::cube @ '1'::cube AS bool;
SELECT '(-1),(1)'::cube @ '-1'::cube AS bool;
SELECT '(-1),(1)'::cube @ '(-1),(1)'::cube AS bool;
SELECT '(-1,-1),(1,1)'::cube @ '(-1),(1)'::cube AS bool;
SELECT '(-1),(1)'::cube @ '(-2),(1)'::cube AS bool;
SELECT '(-1,-1),(1,1)'::cube @ '(-2),(1)'::cube AS bool;
-- Load some example data and build the index
--
CREATE TABLE test_cube (c cube);
\copy test_cube from 'data/test_cube.data'
CREATE INDEX test_cube_ix ON test_cube USING gist (c);
SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)';
-- Test sorting
SELECT * FROM test_cube WHERE c && '(3000,1000),(0,0)' GROUP BY c;

View File

@ -1,21 +0,0 @@
# $Header: /cvsroot/pgsql/contrib/dbase/Attic/Makefile,v 1.4 2001/12/21 05:29:46 momjian Exp $
subdir = contrib/dbase
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
PROGRAM = dbf2pg
OBJS = dbf.o dbf2pg.o endian.o
PG_CPPFLAGS = -I$(libpq_srcdir)
PG_LIBS = $(libpq)
# Uncomment this to provide charset translation
#PG_CPPFLAGS += -DHAVE_ICONV_H
# You might need to uncomment this too, if libiconv is a separate
# library on your platform
#PG_LIBS += -liconv
DOCS = README.dbf2pg
MAN = dbf2pg.1 # XXX not implemented
include $(top_srcdir)/contrib/contrib-global.mk

View File

@ -1,135 +0,0 @@
dbf2sql(1L) dbf2sql(1L)
NAME
dbf2sql - Insert xBase-style .dbf-files into a Post-
greSQL-table
SYNOPSIS
"dbf2pg [options] dbf-file"
Options:
[-v[v]] [-f] [-u | -l] [-c | -D] [-d database] [-t table]
[-h host] [-s oldname=newname[,oldname=newname]] [-s
start] [-e end] [-W] [-U username] [-B transaction_size]
[-F charset_from [-T charset_to]]
DESCRIPTION
This manual page documents the program dbf2pg. It takes
an xBase-style .dbf-file, and inserts it into the speci-
fied database and table.
OPTIONS
-v Display some status-messages.
-vv Also display progress.
-f Convert all field-names from the .dbf-file to low-
ercase.
-u Convert the contents of all fields to uppercase.
-l Convert the contents of all fields to lowercase.
-c Create the table specified with -t. If this table
already exists, first DROP it.
-D Delete the contents of the table specified with -t.
Note that this table has to exists. An error is
returned if this is not the case.
-W Ask for password.
-d database
Specify the database to use. An error is returned
if this database does not exists. Default is
"test".
-t table
Specify the table to insert in. An error is
returned if this table does not exists. Default is
"test".
-h host
Specify the host to which to connect. Default is
"localhost".
1
dbf2sql(1L) dbf2sql(1L)
-s oldname=newname[,oldname=newname]
Change the name of a field from oldname to newname.
This is mainly used to avoid using reserved SQL-
keywords. Example:
-s SELECT=SEL,COMMIT=doit
This is done before the -f operator has taken
effect!
-s start
Specify the first record-number in the xBase-file
we will insert.
-e end Specify the last record-number in the xBase-file we
will insert.
-B transaction_size
Specify the number of records per transaction,
default is all records.
-U username
Log as the specified user in the database.
-F charset_from
If specified, it converts the data from the speci-
fied charset. Example:
-F IBM437
Consult your system documentation to see the con-
versions available. This requires iconv to be enabled
in the compile.
-T charset_to
Together with -F charset_from , it converts the
data to the specified charset. Default is
"ISO-8859-1". This requires iconv to be enabled
in the compile.
ENVIRONMENT
This program is affected by the environment-variables as
used by "PostgresSQL." See the documentation of Post-
gresSQL for more info. This program can optionally use iconv
character set conversion routines.
BUGS
Fields larger than 8192 characters are not supported and
could break the program.
Some charset convertions could cause the output to be
larger than the input and could break the program.
2

View File

@ -1,520 +0,0 @@
/* Routines to read and write xBase-files (.dbf)
By Maarten Boekhold, 29th of oktober 1995
Modified by Frank Koormann (fkoorman@usf.uni-osnabrueck.de), Jun 10 1996
prepare dataarea with memset
get systemtime and set filedate
set formatstring for real numbers
*/
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#include <time.h>
#include "dbf.h"
/* open a dbf-file, get it's field-info and store this information */
dbhead *
dbf_open(u_char *file, int flags)
{
int file_no;
dbhead *dbh;
f_descr *fields;
dbf_header *head;
dbf_field *fieldc;
int t;
if ((dbh = (dbhead *) malloc(sizeof(dbhead))) == NULL)
return (dbhead *) DBF_ERROR;
if ((head = (dbf_header *) malloc(sizeof(dbf_header))) == NULL)
{
free(dbh);
return (dbhead *) DBF_ERROR;
}
if ((fieldc = (dbf_field *) malloc(sizeof(dbf_field))) == NULL)
{
free(head);
free(dbh);
return (dbhead *) DBF_ERROR;
}
if ((file_no = open(file, flags)) == -1)
{
free(fieldc);
free(head);
free(dbh);
return (dbhead *) DBF_ERROR;
}
/* read in the disk-header */
if (read(file_no, head, sizeof(dbf_header)) == -1)
{
close(file_no);
free(fieldc);
free(head);
free(dbh);
return (dbhead *) DBF_ERROR;
}
if (!(head->dbh_dbt & DBH_NORMAL))
{
close(file_no);
free(fieldc);
free(head);
free(dbh);
return (dbhead *) DBF_ERROR;
}
dbh->db_fd = file_no;
if (head->dbh_dbt & DBH_MEMO)
dbh->db_memo = 1;
else
dbh->db_memo = 0;
dbh->db_year = head->dbh_year;
dbh->db_month = head->dbh_month;
dbh->db_day = head->dbh_day;
dbh->db_hlen = get_short((u_char *) &head->dbh_hlen);
dbh->db_records = get_long((u_char *) &head->dbh_records);
dbh->db_currec = 0;
dbh->db_rlen = get_short((u_char *) &head->dbh_rlen);
dbh->db_nfields = (dbh->db_hlen - sizeof(dbf_header)) / sizeof(dbf_field);
/*
* dbh->db_hlen - sizeof(dbf_header) isn't the correct size, cos
* dbh->hlen is in fact a little more cos of the 0x0D (and possibly
* another byte, 0x4E, I have seen this somewhere). Because of
* rounding everything turns out right :)
*/
if ((fields = (f_descr *) calloc(dbh->db_nfields, sizeof(f_descr)))
== NULL)
{
close(file_no);
free(fieldc);
free(head);
free(dbh);
return (dbhead *) DBF_ERROR;
}
for (t = 0; t < dbh->db_nfields; t++)
{
/* Maybe I have calculated the number of fields incorrectly. This can happen
when programs reserve lots of space at the end of the header for future
expansion. This will catch this situation */
if (fields[t].db_name[0] == 0x0D)
{
dbh->db_nfields = t;
break;
}
read(file_no, fieldc, sizeof(dbf_field));
strncpy(fields[t].db_name, fieldc->dbf_name, DBF_NAMELEN);
fields[t].db_type = fieldc->dbf_type;
fields[t].db_flen = fieldc->dbf_flen;
fields[t].db_dec = fieldc->dbf_dec;
}
dbh->db_offset = dbh->db_hlen;
dbh->db_fields = fields;
if ((dbh->db_buff = (u_char *) malloc(dbh->db_rlen)) == NULL)
return (dbhead *) DBF_ERROR;
free(fieldc);
free(head);
return dbh;
}
int
dbf_write_head(dbhead * dbh)
{
dbf_header head;
time_t now;
struct tm *dbf_time;
if (lseek(dbh->db_fd, 0, SEEK_SET) == -1)
return DBF_ERROR;
/* fill up the diskheader */
/* Set dataarea of head to '\0' */
memset(&head, '\0', sizeof(dbf_header));
head.dbh_dbt = DBH_NORMAL;
if (dbh->db_memo)
head.dbh_dbt = DBH_MEMO;
now = time((time_t *) NULL);
dbf_time = localtime(&now);
head.dbh_year = dbf_time->tm_year;
head.dbh_month = dbf_time->tm_mon + 1; /* Months since January +
* 1 */
head.dbh_day = dbf_time->tm_mday;
put_long(head.dbh_records, dbh->db_records);
put_short(head.dbh_hlen, dbh->db_hlen);
put_short(head.dbh_rlen, dbh->db_rlen);
if (write(dbh->db_fd, &head, sizeof(dbf_header)) != sizeof(dbf_header))
return DBF_ERROR;
return 0;
}
int
dbf_put_fields(dbhead * dbh)
{
dbf_field field;
u_long t;
u_char end = 0x0D;
if (lseek(dbh->db_fd, sizeof(dbf_header), SEEK_SET) == -1)
return DBF_ERROR;
/* Set dataarea of field to '\0' */
memset(&field, '\0', sizeof(dbf_field));
for (t = 0; t < dbh->db_nfields; t++)
{
strncpy(field.dbf_name, dbh->db_fields[t].db_name, DBF_NAMELEN - 1);
field.dbf_type = dbh->db_fields[t].db_type;
field.dbf_flen = dbh->db_fields[t].db_flen;
field.dbf_dec = dbh->db_fields[t].db_dec;
if (write(dbh->db_fd, &field, sizeof(dbf_field)) != sizeof(dbf_field))
return DBF_ERROR;
}
if (write(dbh->db_fd, &end, 1) != 1)
return DBF_ERROR;
return 0;
}
int
dbf_add_field(dbhead * dbh, u_char *name, u_char type,
u_char length, u_char dec)
{
f_descr *ptr;
u_char *foo;
u_long size,
field_no;
size = (dbh->db_nfields + 1) * sizeof(f_descr);
if (!(ptr = (f_descr *) realloc(dbh->db_fields, size)))
return DBF_ERROR;
dbh->db_fields = ptr;
field_no = dbh->db_nfields;
strncpy(dbh->db_fields[field_no].db_name, name, DBF_NAMELEN);
dbh->db_fields[field_no].db_type = type;
dbh->db_fields[field_no].db_flen = length;
dbh->db_fields[field_no].db_dec = dec;
dbh->db_nfields++;
dbh->db_hlen += sizeof(dbf_field);
dbh->db_rlen += length;
if (!(foo = (u_char *) realloc(dbh->db_buff, dbh->db_rlen)))
return DBF_ERROR;
dbh->db_buff = foo;
return 0;
}
dbhead *
dbf_open_new(u_char *name, int flags)
{
dbhead *dbh;
if (!(dbh = (dbhead *) malloc(sizeof(dbhead))))
return (dbhead *) DBF_ERROR;
if (flags & O_CREAT)
{
if ((dbh->db_fd = open(name, flags, DBF_FILE_MODE)) == -1)
{
free(dbh);
return (dbhead *) DBF_ERROR;
}
}
else
{
if ((dbh->db_fd = open(name, flags)) == -1)
{
free(dbh);
return (dbhead *) DBF_ERROR;
}
}
dbh->db_offset = 0;
dbh->db_memo = 0;
dbh->db_year = 0;
dbh->db_month = 0;
dbh->db_day = 0;
dbh->db_hlen = sizeof(dbf_header) + 1;
dbh->db_records = 0;
dbh->db_currec = 0;
dbh->db_rlen = 1;
dbh->db_nfields = 0;
dbh->db_buff = NULL;
dbh->db_fields = (f_descr *) NULL;
return dbh;
}
void
dbf_close(dbhead * dbh)
{
int t;
close(dbh->db_fd);
for (t = 0; t < dbh->db_nfields; t++)
free(&dbh->db_fields[t]);
if (dbh->db_buff != NULL)
free(dbh->db_buff);
free(dbh);
}
int
dbf_get_record(dbhead * dbh, field * fields, u_long rec)
{
u_char *data;
int t,
i,
offset;
u_char *dbffield,
*end;
/* calculate at which offset we have to read. *DON'T* forget the
0x0D which seperates field-descriptions from records!
Note (april 5 1996): This turns out to be included in db_hlen
*/
offset = dbh->db_hlen + (rec * dbh->db_rlen);
if (lseek(dbh->db_fd, offset, SEEK_SET) == -1)
{
lseek(dbh->db_fd, 0, SEEK_SET);
dbh->db_offset = 0;
return DBF_ERROR;
}
dbh->db_offset = offset;
dbh->db_currec = rec;
data = dbh->db_buff;
read(dbh->db_fd, data, dbh->db_rlen);
if (data[0] == DBF_DELETED)
return DBF_DELETED;
dbffield = &data[1];
for (t = 0; t < dbh->db_nfields; t++)
{
strncpy(fields[t].db_name, dbh->db_fields[t].db_name, DBF_NAMELEN);
fields[t].db_type = dbh->db_fields[t].db_type;
fields[t].db_flen = dbh->db_fields[t].db_flen;
fields[t].db_dec = dbh->db_fields[t].db_dec;
if (fields[t].db_type == 'C')
{
end = &dbffield[fields[t].db_flen - 1];
i = fields[t].db_flen;
while ((i > 0) && ((*end < 0x21) || (*end > 0x7E)))
{
end--;
i--;
}
strncpy(fields[t].db_contents, dbffield, i);
fields[t].db_contents[i] = '\0';
}
else
{
end = dbffield;
i = fields[t].db_flen;
while ((i > 0) && ((*end < 0x21) || (*end > 0x7E)))
{
end++;
i--;
}
strncpy(fields[t].db_contents, end, i);
fields[t].db_contents[i] = '\0';
}
dbffield += fields[t].db_flen;
}
dbh->db_offset += dbh->db_rlen;
return DBF_VALID;
}
field *
dbf_build_record(dbhead * dbh)
{
int t;
field *fields;
if (!(fields = (field *) calloc(dbh->db_nfields, sizeof(field))))
return (field *) DBF_ERROR;
for (t = 0; t < dbh->db_nfields; t++)
{
if (!(fields[t].db_contents =
(u_char *) malloc(dbh->db_fields[t].db_flen + 1)))
{
for (t = 0; t < dbh->db_nfields; t++)
{
if (fields[t].db_contents != 0)
{
free(fields[t].db_contents);
free(fields);
}
return (field *) DBF_ERROR;
}
}
strncpy(fields[t].db_name, dbh->db_fields[t].db_name, DBF_NAMELEN);
fields[t].db_type = dbh->db_fields[t].db_type;
fields[t].db_flen = dbh->db_fields[t].db_flen;
fields[t].db_dec = dbh->db_fields[t].db_dec;
}
return fields;
}
void
dbf_free_record(dbhead * dbh, field * rec)
{
int t;
for (t = 0; t < dbh->db_nfields; t++)
free(rec[t].db_contents);
free(rec);
}
int
dbf_put_record(dbhead * dbh, field * rec, u_long where)
{
u_long offset,
new,
idx,
t,
h,
length;
u_char *data,
end = 0x1a;
double fl;
u_char foo[128],
format[32];
/* offset: offset in file for this record
new: real offset after lseek
idx: index to which place we are inside the 'hardcore'-data for this
record
t: field-counter
data: the hardcore-data that is put on disk
h: index into the field-part in the hardcore-data
length: length of the data to copy
fl: a float used to get the right precision with real numbers
foo: copy of db_contents when field is not 'C'
format: sprintf format-string to get the right precision with real numbers
NOTE: this declaration of 'foo' can cause overflow when the contents-field
is longer the 127 chars (which is highly unlikely, cos it is not used
in text-fields).
*/
/* REMEMBER THAT THERE'S A 0x1A AT THE END OF THE FILE, SO DON'T
DO A SEEK_END WITH 0!!!!!! USE -1 !!!!!!!!!!
*/
if (where > dbh->db_records)
{
if ((new = lseek(dbh->db_fd, -1, SEEK_END)) == -1)
return DBF_ERROR;
dbh->db_records++;
}
else
{
offset = dbh->db_hlen + (where * dbh->db_rlen);
if ((new = lseek(dbh->db_fd, offset, SEEK_SET)) == -1)
return DBF_ERROR;
}
dbh->db_offset = new;
data = dbh->db_buff;
/* Set dataarea of data to ' ' (space) */
memset(data, ' ', dbh->db_rlen);
/* data[0] = DBF_VALID; */
idx = 1;
for (t = 0; t < dbh->db_nfields; t++)
{
/* if field is empty, don't do a thing */
if (rec[t].db_contents[0] != '\0')
{
/* Handle text */
if (rec[t].db_type == 'C')
{
if (strlen(rec[t].db_contents) > rec[t].db_flen)
length = rec[t].db_flen;
else
length = strlen(rec[t].db_contents);
strncpy(data + idx, rec[t].db_contents, length);
}
else
{
/* Handle the rest */
/* Numeric is special, because of real numbers */
if ((rec[t].db_type == 'N') && (rec[t].db_dec != 0))
{
fl = atof(rec[t].db_contents);
sprintf(format, "%%.%df", rec[t].db_dec);
sprintf(foo, format, fl);
}
else
strcpy(foo, rec[t].db_contents);
if (strlen(foo) > rec[t].db_flen)
length = rec[t].db_flen;
else
length = strlen(foo);
h = rec[t].db_flen - length;
strncpy(data + idx + h, foo, length);
}
}
idx += rec[t].db_flen;
}
if (write(dbh->db_fd, data, dbh->db_rlen) != dbh->db_rlen)
return DBF_ERROR;
/* There's a 0x1A at the end of a dbf-file */
if (where == dbh->db_records)
{
if (write(dbh->db_fd, &end, 1) != 1)
return DBF_ERROR;
}
dbh->db_offset += dbh->db_rlen;
return 0;
}

View File

@ -1,139 +0,0 @@
/* header-file for dbf.c
declares routines for reading and writing xBase-files (.dbf), and
associated structures
Maarten Boekhold (maarten.boekhold@reuters.com) 29 oktober 1995
*/
#ifndef _DBF_H
#define _DBF_H
#include <sys/types.h>
/**********************************************************************
The DBF-part
***********************************************************************/
#define DBF_FILE_MODE 0644
/* byte offsets for date in dbh_date */
#define DBH_DATE_YEAR 0
#define DBH_DATE_MONTH 1
#define DBH_DATE_DAY 2
/* maximum fieldname-length */
#define DBF_NAMELEN 11
/* magic-cookies for the file */
#define DBH_NORMAL 0x03
#define DBH_MEMO 0x83
/* magic-cookies for the fields */
#define DBF_ERROR -1
#define DBF_VALID 0x20
#define DBF_DELETED 0x2A
/* diskheader */
typedef struct
{
u_char dbh_dbt; /* indentification field */
u_char dbh_year; /* last modification-date */
u_char dbh_month;
u_char dbh_day;
u_char dbh_records[4]; /* number of records */
u_char dbh_hlen[2]; /* length of this header */
u_char dbh_rlen[2]; /* length of a record */
u_char dbh_stub[20]; /* misc stuff we don't need */
} dbf_header;
/* disk field-description */
typedef struct
{
u_char dbf_name[DBF_NAMELEN]; /* field-name terminated with \0 */
u_char dbf_type; /* field-type */
u_char dbf_reserved[4]; /* some reserved stuff */
u_char dbf_flen; /* field-length */
u_char dbf_dec; /* number of decimal positions if type is
* 'N' */
u_char dbf_stub[14]; /* stuff we don't need */
} dbf_field;
/* memory field-description */
typedef struct
{
u_char db_name[DBF_NAMELEN]; /* field-name terminated with \0 */
u_char db_type; /* field-type */
u_char db_flen; /* field-length */
u_char db_dec; /* number of decimal positions */
} f_descr;
/* memory dfb-header */
typedef struct
{
int db_fd; /* file-descriptor */
u_long db_offset; /* current offset in file */
u_char db_memo; /* memo-file present */
u_char db_year; /* last update as YYMMDD */
u_char db_month;
u_char db_day;
u_long db_hlen; /* length of the diskheader, for
* calculating the offsets */
u_long db_records; /* number of records */
u_long db_currec; /* current record-number starting at 0 */
u_short db_rlen; /* length of the record */
u_char db_nfields; /* number of fields */
u_char *db_buff; /* record-buffer to save malloc()'s */
f_descr *db_fields; /* pointer to an array of field-
* descriptions */
} dbhead;
/* structure that contains everything a user wants from a field, including
the contents (in ASCII). Warning! db_flen may be bigger than the actual
length of db_name! This is because a field doesn't have to be completely
filled */
typedef struct
{
u_char db_name[DBF_NAMELEN]; /* field-name terminated with \0 */
u_char db_type; /* field-type */
u_char db_flen; /* field-length */
u_char db_dec; /* number of decimal positions */
u_char *db_contents; /* contents of the field in ASCII */
} field;
/* prototypes for functions */
extern dbhead *dbf_open(u_char *file, int flags);
extern int dbf_write_head(dbhead * dbh);
extern int dbf_put_fields(dbhead * dbh);
extern int dbf_add_field(dbhead * dbh, u_char *name, u_char type,
u_char length, u_char dec);
extern dbhead *dbf_open_new(u_char *name, int flags);
extern void dbf_close(dbhead * dbh);
extern int dbf_get_record(dbhead * dbh, field * fields, u_long rec);
extern field *dbf_build_record(dbhead * dbh);
extern void dbf_free_record(dbhead * dbh, field * fields);
extern int dbf_put_record(dbhead * dbh, field * rec, u_long where);
/*********************************************************************
The endian-part
***********************************************************************/
extern long get_long(u_char *cp);
extern void put_long(u_char *cp, long lval);
extern short get_short(u_char *cp);
extern void put_short(u_char *cp, short lval);
#endif /* _DBF_H */

View File

@ -1,116 +0,0 @@
.TH dbf2sql 1L \" -*- nroff -*-
.SH NAME
dbf2sql \- Insert xBase\-style .dbf\-files into a PostgreSQL\-table
.SH SYNOPSIS
.B dbf2pg [options] dbf-file
.br
.br
Options:
.br
[-v[v]] [-f] [-u | -l] [-c | -D] [-d database] [-t table]
[-h host] [-s oldname=newname[,oldname=newname]]
[-s start] [-e end] [-W] [-U username] [-B transaction_size]
[-F charset_from [-T charset_to]]
.SH DESCRIPTION
This manual page documents the program
.BR dbf2pg.
It takes an xBase-style .dbf-file, and inserts it into the specified
database and table.
.SS OPTIONS
.TP
.I "\-v"
Display some status-messages.
.TP
.I "-vv"
Also display progress.
.TP
.I "-f"
Convert all field-names from the .dbf-file to lowercase.
.TP
.I "-u"
Convert the contents of all fields to uppercase.
.TP
.I "-l"
Convert the contents of all fields to lowercase.
.TP
.I "-c"
Create the table specified with
.IR \-t .
If this table already exists, first
.BR DROP
it.
.TP
.I "-D"
Delete the contents of the table specified with
.IR \-t .
Note that this table has to exists. An error is returned if this is not the
case.
.TP
.I "-W"
Ask for password.
.TP
.I "-d database"
Specify the database to use. An error is returned if this database does not
exists. Default is "test".
.TP
.I "-t table"
Specify the table to insert in. An error is returned if this table does not
exists. Default is "test".
.TP
.I "-h host"
Specify the host to which to connect. Default is "localhost".
.TP
.I "-s oldname=newname[,oldname=newname]"
Change the name of a field from
.BR oldname
to
.BR newname .
This is mainly used to avoid using reserved SQL-keywords. Example:
.br
.br
-s SELECT=SEL,COMMIT=doit
.br
.br
This is done
.BR before
the
.IR -f
operator has taken effect!
.TP
.I "-s start"
Specify the first record-number in the xBase-file we will insert.
.TP
.I "-e end"
Specify the last record-number in the xBase-file we will insert.
.TP
.I "-B transaction_size"
Specify the number of records per transaction, default is all records.
.TP
.I "-U username"
Log as the specified user in the database.
.TP
.I "-F charset_from"
If specified, it converts the data from the specified charset. Example:
.br
.br
-F IBM437
.br
.br
Consult your system documentation to see the convertions available.
.TP
.I "-T charset_to"
Together with
.I "-F charset_from"
, it converts the data to the specified charset. Default is "ISO-8859-1".
.SH ENVIRONMENT
This program is affected by the environment-variables as used
by
.B PostgresSQL.
See the documentation of PostgresSQL for more info.
.SH BUGS
Fields larger than 8192 characters are not supported and could break the
program.
.br
Some charset convertions could cause the output to be larger than the input
and could break the program.

View File

@ -1,954 +0,0 @@
/* This program reads in an xbase-dbf file and sends 'inserts' to an
PostgreSQL-server with the records in the xbase-file
M. Boekhold (maarten.boekhold@reuters.com) okt. 1995
oktober 1996: merged sources of dbf2msql.c and dbf2pg.c
oktober 1997: removed msql support
*/
#include "postgres_fe.h"
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#ifdef HAVE_ICONV_H
#include <iconv.h>
#endif
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#include "libpq-fe.h"
#include "dbf.h"
int verbose = 0,
upper = 0,
lower = 0,
create = 0,
fieldlow = 0;
int del = 0;
unsigned int begin = 0,
end = 0;
unsigned int t_block = 0;
#ifdef HAVE_ICONV_H
char *charset_from = NULL;
char *charset_to = "ISO-8859-1";
iconv_t iconv_d;
char convert_charset_buff[8192];
#endif
char *host = NULL;
char *dbase = "test";
char *table = "test";
char *username = NULL;
char *password = NULL;
char *subarg = NULL;
char escape_buff[8192];
void do_substitute(char *subarg, dbhead * dbh);
inline void strtoupper(char *string);
inline void strtolower(char *string);
void do_create(PGconn *, char *, dbhead *);
void do_inserts(PGconn *, char *, dbhead *);
int check_table(PGconn *, char *);
char *Escape(char *);
#ifdef HAVE_ICONV_H
char *convert_charset(char *string);
#endif
void usage(void);
unsigned int isinteger(char *);
char *simple_prompt(const char *prompt, int maxlen, bool echo);
unsigned int
isinteger(char *buff)
{
char *i = buff;
while (*i != '\0')
{
if (i == buff)
if ((*i == '-') ||
(*i == '+'))
{
i++;
continue;
}
if (!isdigit((unsigned char) *i))
return 0;
i++;
}
return 1;
}
inline void
strtoupper(char *string)
{
while (*string != '\0')
{
*string = toupper((unsigned char) *string);
string++;
}
}
inline void
strtolower(char *string)
{
while (*string != '\0')
{
*string = tolower((unsigned char) *string);
string++;
}
}
/* FIXME: should this check for overflow? */
char *
Escape(char *string)
{
char *foo,
*bar;
foo = escape_buff;
bar = string;
while (*bar != '\0')
{
if ((*bar == '\t') ||
(*bar == '\n') ||
(*bar == '\\'))
*foo++ = '\\';
*foo++ = *bar++;
}
*foo = '\0';
return escape_buff;
}
#ifdef HAVE_ICONV_H
char *
convert_charset(char *string)
{
size_t in_size,
out_size,
nconv;
char *in_ptr,
*out_ptr;
in_size = strlen(string) + 1;
out_size = sizeof(convert_charset_buff);
in_ptr = string;
out_ptr = convert_charset_buff;
iconv(iconv_d, NULL, &in_size, &out_ptr, &out_size); /* necessary to reset
* state information */
while (in_size > 0)
{
nconv = iconv(iconv_d, &in_ptr, &in_size, &out_ptr, &out_size);
if (nconv == (size_t) -1)
{
printf("WARNING: cannot convert charset of string \"%s\".\n",
string);
strcpy(convert_charset_buff, string);
return convert_charset_buff;
}
}
*out_ptr = 0; /* terminate output string */
return convert_charset_buff;
}
#endif
int
check_table(PGconn *conn, char *table)
{
char *q = "select relname from pg_class where "
"relkind='r' and relname !~* '^pg'";
PGresult *res;
int i = 0;
if (!(res = PQexec(conn, q)))
{
printf("%s\n", PQerrorMessage(conn));
return 0;
}
for (i = 0; i < PQntuples(res); i++)
{
if (!strcmp(table, PQgetvalue(res, i, PQfnumber(res, "relname"))))
return 1;
}
return 0;
}
void
usage(void)
{
printf("dbf2pg\n"
"usage: dbf2pg [-u | -l] [-h hostname] [-W] [-U username]\n"
" [-B transaction_size] [-F charset_from [-T charset_to]]\n"
" [-s oldname=newname[,oldname=newname[...]]] [-d dbase]\n"
" [-t table] [-c | -D] [-f] [-v[v]] dbf-file\n");
}
/* patch submitted by Jeffrey Y. Sue <jysue@aloha.net> */
/* Provides functionallity for substituting dBase-fieldnames for others */
/* Mainly for avoiding conflicts between fieldnames and SQL-reserved */
/* keywords */
void
do_substitute(char *subarg, dbhead * dbh)
{
/* NOTE: subarg is modified in this function */
int i,
bad;
char *p,
*oldname,
*newname;
if (!subarg)
return;
if (verbose > 1)
printf("Substituting new field names\n");
/* use strstr instead of strtok because of possible empty tokens */
oldname = subarg;
while (oldname && strlen(oldname) && (p = strstr(oldname, "=")))
{
*p = '\0'; /* mark end of oldname */
newname = ++p; /* point past \0 of oldname */
if (strlen(newname))
{ /* if not an empty string */
p = strstr(newname, ",");
if (p)
{
*p = '\0'; /* mark end of newname */
p++; /* point past where the comma was */
}
}
if (strlen(newname) >= DBF_NAMELEN)
{
printf("Truncating new field name %s to %d chars\n",
newname, DBF_NAMELEN - 1);
newname[DBF_NAMELEN - 1] = '\0';
}
bad = 1;
for (i = 0; i < dbh->db_nfields; i++)
{
if (strcmp(dbh->db_fields[i].db_name, oldname) == 0)
{
bad = 0;
strcpy(dbh->db_fields[i].db_name, newname);
if (verbose > 1)
{
printf("Substitute old:%s new:%s\n",
oldname, newname);
}
break;
}
}
if (bad)
{
printf("Warning: old field name %s not found\n",
oldname);
}
oldname = p;
}
} /* do_substitute */
void
do_create(PGconn *conn, char *table, dbhead * dbh)
{
char *query;
char t[20];
int i,
length;
PGresult *res;
if (verbose > 1)
printf("Building CREATE-clause\n");
if (!(query = (char *) malloc(
(dbh->db_nfields * 40) + 29 + strlen(table))))
{
fprintf(stderr, "Memory allocation error in function do_create\n");
PQfinish(conn);
close(dbh->db_fd);
free(dbh);
exit(1);
}
sprintf(query, "CREATE TABLE %s (", table);
length = strlen(query);
for (i = 0; i < dbh->db_nfields; i++)
{
if (!strlen(dbh->db_fields[i].db_name))
{
continue;
/* skip field if length of name == 0 */
}
if ((strlen(query) != length))
strcat(query, ",");
if (fieldlow)
strtolower(dbh->db_fields[i].db_name);
strcat(query, dbh->db_fields[i].db_name);
switch (dbh->db_fields[i].db_type)
{
case 'D':
strcat(query, " date");
break;
case 'C':
if (dbh->db_fields[i].db_flen > 1)
{
strcat(query, " varchar");
sprintf(t, "(%d)",
dbh->db_fields[i].db_flen);
strcat(query, t);
}
else
strcat(query, " char");
break;
case 'N':
if (dbh->db_fields[i].db_dec != 0)
strcat(query, " real");
else
strcat(query, " int");
break;
case 'L':
strcat(query, " char");
break;
}
}
strcat(query, ")");
if (verbose > 1)
{
printf("Sending create-clause\n");
printf("%s\n", query);
}
if ((res = PQexec(conn, query)) == NULL)
{
fprintf(stderr, "Error creating table!\n");
fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn));
close(dbh->db_fd);
free(dbh);
free(query);
PQfinish(conn);
exit(1);
}
PQclear(res);
free(query);
}
/* FIXME: can be optimized to not use strcat, but it is worth the effort? */
void
do_inserts(PGconn *conn, char *table, dbhead * dbh)
{
PGresult *res;
field *fields;
int i,
h,
result;
char *query,
*foo;
char pgdate[10];
if (verbose > 1)
printf("Inserting records\n");
h = 2; /* 2 because of terminating \n\0 */
for (i = 0; i < dbh->db_nfields; i++)
{
h += dbh->db_fields[i].db_flen > 2 ?
dbh->db_fields[i].db_flen :
2; /* account for possible NULL values (\N) */
h += 1; /* the delimiter */
}
/*
* make sure we can build the COPY query, note that we don't need to
* just add this value, since the COPY query is a separate query (see
* below)
*/
if (h < 17 + strlen(table))
h = 17 + strlen(table);
if (!(query = (char *) malloc(h)))
{
PQfinish(conn);
fprintf(stderr,
"Memory allocation error in function do_inserts (query)\n");
close(dbh->db_fd);
free(dbh);
exit(1);
}
if ((fields = dbf_build_record(dbh)) == (field *) DBF_ERROR)
{
fprintf(stderr,
"Couldn't allocate memory for record in do_insert\n");
PQfinish(conn);
free(query);
dbf_close(dbh);
exit(1);
}
if (end == 0) /* "end" is a user option, if not
* specified, */
end = dbh->db_records; /* then all records are processed. */
if (t_block == 0) /* user not specified transaction block
* size */
t_block = end - begin; /* then we set it to be the full data */
for (i = begin; i < end; i++)
{
/* we need to start a new transaction and COPY statement */
if (((i - begin) % t_block) == 0)
{
if (verbose > 1)
fprintf(stderr, "Transaction: START\n");
res = PQexec(conn, "BEGIN");
if (res == NULL)
{
fprintf(stderr, "Error starting transaction!\n");
fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn));
exit(1);
}
sprintf(query, "COPY %s FROM stdin", table);
res = PQexec(conn, query);
if (res == NULL)
{
fprintf(stderr, "Error starting COPY!\n");
fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn));
exit(1);
}
}
/* build line and submit */
result = dbf_get_record(dbh, fields, i);
if (result == DBF_VALID)
{
query[0] = '\0';
for (h = 0; h < dbh->db_nfields; h++)
{
if (!strlen(fields[h].db_name))
continue;
if (h != 0) /* not for the first field! */
strcat(query, "\t"); /* COPY statement field
* separator */
if (upper)
strtoupper(fields[h].db_contents);
if (lower)
strtolower(fields[h].db_contents);
foo = fields[h].db_contents;
#ifdef HAVE_ICONV_H
if (charset_from)
foo = convert_charset(foo);
#endif
foo = Escape(foo);
/* handle the date first - liuk */
if (fields[h].db_type == 'D')
{
if ((strlen(foo) == 8) && isinteger(foo))
{
sprintf(pgdate, "%c%c%c%c-%c%c-%c%c",
foo[0], foo[1], foo[2], foo[3],
foo[4], foo[5], foo[6], foo[7]);
strcat(query, pgdate);
}
else
{
/*
* empty field must be inserted as NULL value in
* this way
*/
strcat(query, "\\N");
}
}
else if ((fields[h].db_type == 'N') &&
(fields[h].db_dec == 0))
{
if (isinteger(foo))
strcat(query, foo);
else
{
strcat(query, "\\N");
if (verbose)
fprintf(stderr, "Illegal numeric value found "
"in record %d, field \"%s\"\n",
i, fields[h].db_name);
}
}
else
{
strcat(query, foo); /* must be character */
}
}
strcat(query, "\n");
if ((verbose > 1) && ((i % 100) == 0))
{ /* Only show every 100 */
printf("Inserting record %d\n", i); /* records. */
}
PQputline(conn, query);
}
/* we need to end this copy and transaction */
if (((i - begin) % t_block) == t_block - 1)
{
if (verbose > 1)
fprintf(stderr, "Transaction: END\n");
PQputline(conn, "\\.\n");
if (PQendcopy(conn) != 0)
{
fprintf(stderr, "Something went wrong while copying. Check "
"your tables!\n");
exit(1);
}
res = PQexec(conn, "END");
if (res == NULL)
{
fprintf(stderr, "Error committing work!\n");
fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn));
exit(1);
}
}
}
/* last row copied in, end copy and transaction */
/* remember, i is now 1 greater then when we left the loop */
if (((i - begin) % t_block) != 0)
{
if (verbose > 1)
fprintf(stderr, "Transaction: END\n");
PQputline(conn, "\\.\n");
if (PQendcopy(conn) != 0)
{
fprintf(stderr, "Something went wrong while copying. Check "
"your tables!\n");
}
res = PQexec(conn, "END");
if (res == NULL)
{
fprintf(stderr, "Error committing work!\n");
fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn));
exit(1);
}
}
dbf_free_record(dbh, fields);
free(query);
}
/*
* simple_prompt --- borrowed from psql
*
* Generalized function especially intended for reading in usernames and
* password interactively. Reads from /dev/tty or stdin/stderr.
*
* prompt: The prompt to print
* maxlen: How many characters to accept
* echo: Set to false if you want to hide what is entered (for passwords)
*
* Returns a malloc()'ed string with the input (w/o trailing newline).
*/
static bool prompt_state = false;
char *
simple_prompt(const char *prompt, int maxlen, bool echo)
{
int length;
char *destination;
FILE *termin,
*termout;
#ifdef HAVE_TERMIOS_H
struct termios t_orig,
t;
#endif
destination = (char *) malloc(maxlen + 2);
if (!destination)
return NULL;
prompt_state = true; /* disable SIGINT */
/*
* Do not try to collapse these into one "w+" mode file. Doesn't work
* on some platforms (eg, HPUX 10.20).
*/
termin = fopen("/dev/tty", "r");
termout = fopen("/dev/tty", "w");
if (!termin || !termout)
{
if (termin)
fclose(termin);
if (termout)
fclose(termout);
termin = stdin;
termout = stderr;
}
#ifdef HAVE_TERMIOS_H
if (!echo)
{
tcgetattr(fileno(termin), &t);
t_orig = t;
t.c_lflag &= ~ECHO;
tcsetattr(fileno(termin), TCSAFLUSH, &t);
}
#endif
if (prompt)
{
fputs(gettext(prompt), termout);
fflush(termout);
}
if (fgets(destination, maxlen, termin) == NULL)
destination[0] = '\0';
length = strlen(destination);
if (length > 0 && destination[length - 1] != '\n')
{
/* eat rest of the line */
char buf[128];
int buflen;
do
{
if (fgets(buf, sizeof(buf), termin) == NULL)
break;
buflen = strlen(buf);
} while (buflen > 0 && buf[buflen - 1] != '\n');
}
if (length > 0 && destination[length - 1] == '\n')
/* remove trailing newline */
destination[length - 1] = '\0';
#ifdef HAVE_TERMIOS_H
if (!echo)
{
tcsetattr(fileno(termin), TCSAFLUSH, &t_orig);
fputs("\n", termout);
fflush(termout);
}
#endif
if (termin != stdin)
{
fclose(termin);
fclose(termout);
}
prompt_state = false; /* SIGINT okay again */
return destination;
}
int
main(int argc, char **argv)
{
PGconn *conn;
int i;
extern int optind;
extern char *optarg;
char *query;
dbhead *dbh;
while ((i = getopt(argc, argv, "DWflucvh:b:e:d:t:s:B:U:F:T:")) != -1)
{
switch (i)
{
case 'D':
if (create)
{
usage();
printf("Can't use -c and -D at the same time!\n");
exit(1);
}
del = 1;
break;
case 'W':
password = simple_prompt("Password: ", 100, 0);
break;
case 'f':
fieldlow = 1;
break;
case 'v':
verbose++;
break;
case 'c':
if (del)
{
usage();
printf("Can't use -c and -D at the same time!\n");
exit(1);
}
create = 1;
break;
case 'l':
lower = 1;
break;
case 'u':
if (lower)
{
usage();
printf("Can't use -u and -l at the same time!\n");
exit(1);
}
upper = 1;
break;
case 'b':
begin = atoi(optarg);
break;
case 'e':
end = atoi(optarg);
break;
case 'h':
host = (char *) strdup(optarg);
break;
case 'd':
dbase = (char *) strdup(optarg);
break;
case 't':
table = (char *) strdup(optarg);
break;
case 's':
subarg = (char *) strdup(optarg);
break;
case 'B':
t_block = atoi(optarg);
break;
case 'U':
username = (char *) strdup(optarg);
break;
#ifdef HAVE_ICONV_H
case 'F':
charset_from = (char *) strdup(optarg);
break;
case 'T':
charset_to = (char *) strdup(optarg);
break;
#endif
case ':':
usage();
printf("missing argument!\n");
exit(1);
break;
case '?':
usage();
/*
* FIXME: Ivan thinks this is bad: printf("unknown
* argument: %s\n", argv[0]);
*/
exit(1);
break;
default:
break;
}
}
argc -= optind;
argv = &argv[optind];
if (argc != 1)
{
usage();
if (username)
free(username);
if (password)
free(password);
exit(1);
}
#ifdef HAVE_ICONV_H
if (charset_from)
{
if (verbose > 1)
printf("Setting conversion from charset \"%s\" to \"%s\".\n",
charset_from, charset_to);
iconv_d = iconv_open(charset_to, charset_from);
if (iconv_d == (iconv_t) - 1)
{
printf("Cannot convert from charset \"%s\" to charset \"%s\".\n",
charset_from, charset_to);
exit(1);
}
}
#endif
if (verbose > 1)
printf("Opening dbf-file\n");
if ((dbh = dbf_open(argv[0], O_RDONLY)) == (dbhead *) - 1)
{
fprintf(stderr, "Couldn't open xbase-file %s\n", argv[0]);
if (username)
free(username);
if (password)
free(password);
#ifdef HAVE_ICONV_H
if (charset_from)
iconv_close(iconv_d);
#endif
exit(1);
}
if (fieldlow)
for (i = 0; i < dbh->db_nfields; i++)
strtolower(dbh->db_fields[i].db_name);
if (verbose)
{
printf("dbf-file: %s, PG-dbase: %s, PG-table: %s\n", argv[0],
dbase,
table);
printf("Number of records: %ld\n", dbh->db_records);
printf("NAME:\t\tLENGTH:\t\tTYPE:\n");
printf("-------------------------------------\n");
for (i = 0; i < dbh->db_nfields; i++)
{
printf("%-12s\t%7d\t\t%5c\n", dbh->db_fields[i].db_name,
dbh->db_fields[i].db_flen,
dbh->db_fields[i].db_type);
}
}
if (verbose > 1)
printf("Making connection to PG-server\n");
conn = PQsetdbLogin(host, NULL, NULL, NULL, dbase, username, password);
if (PQstatus(conn) != CONNECTION_OK)
{
fprintf(stderr, "Couldn't get a connection with the ");
fprintf(stderr, "designated host!\n");
fprintf(stderr, "Detailed report: %s\n", PQerrorMessage(conn));
close(dbh->db_fd);
free(dbh);
if (username)
free(username);
if (password)
free(password);
#ifdef HAVE_ICONV_H
if (charset_from)
iconv_close(iconv_d);
#endif
exit(1);
}
/* Substitute field names */
do_substitute(subarg, dbh);
/* create table if specified, else check if target table exists */
if (!create)
{
if (!check_table(conn, table))
{
printf("Table does not exist!\n");
if (username)
free(username);
if (password)
free(password);
#ifdef HAVE_ICONV_H
if (charset_from)
iconv_close(iconv_d);
#endif
exit(1);
}
if (del)
{
if (!(query = (char *) malloc(13 + strlen(table))))
{
printf("Memory-allocation error in main (delete)!\n");
close(dbh->db_fd);
free(dbh);
PQfinish(conn);
if (username)
free(username);
if (password)
free(password);
#ifdef HAVE_ICONV_H
if (charset_from)
iconv_close(iconv_d);
#endif
exit(1);
}
if (verbose > 1)
printf("Deleting from original table\n");
sprintf(query, "DELETE FROM %s", table);
PQexec(conn, query);
free(query);
}
}
else
{
if (!(query = (char *) malloc(12 + strlen(table))))
{
printf("Memory-allocation error in main (drop)!\n");
close(dbh->db_fd);
free(dbh);
PQfinish(conn);
if (username)
free(username);
if (password)
free(password);
#ifdef HAVE_ICONV_H
if (charset_from)
iconv_close(iconv_d);
#endif
exit(1);
}
if (verbose > 1)
printf("Dropping original table (if one exists)\n");
sprintf(query, "DROP TABLE %s", table);
PQexec(conn, query);
free(query);
/* Build a CREATE-clause
*/
do_create(conn, table, dbh);
}
/* Build an INSERT-clause
*/
PQexec(conn, "SET DATESTYLE TO 'ISO';");
do_inserts(conn, table, dbh);
if (verbose > 1)
printf("Closing up....\n");
close(dbh->db_fd);
free(dbh);
PQfinish(conn);
if (username)
free(username);
if (password)
free(password);
#ifdef HAVE_ICONV_H
if (charset_from)
iconv_close(iconv_d);
#endif
exit(0);
}

View File

@ -1,49 +0,0 @@
/* Maarten Boekhold (maarten.boekhold@reuters.com) oktober 1995 */
#include <sys/types.h>
#include "dbf.h"
/*
* routine to change little endian long to host long
*/
long
get_long(u_char *cp)
{
long ret;
ret = *cp++;
ret += ((*cp++) << 8);
ret += ((*cp++) << 16);
ret += ((*cp++) << 24);
return ret;
}
void
put_long(u_char *cp, long lval)
{
cp[0] = lval & 0xff;
cp[1] = (lval >> 8) & 0xff;
cp[2] = (lval >> 16) & 0xff;
cp[3] = (lval >> 24) & 0xff;
}
/*
* routine to change little endian short to host short
*/
short
get_short(u_char *cp)
{
short ret;
ret = *cp++;
ret += ((*cp++) << 8);
return ret;
}
void
put_short(u_char *cp, short sval)
{
cp[0] = sval & 0xff;
cp[1] = (sval >> 8) & 0xff;
}

View File

@ -1,15 +0,0 @@
# $Header: /cvsroot/pgsql/contrib/dblink/Makefile,v 1.4 2001/09/06 10:49:29 petere Exp $
subdir = contrib/dblink
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
MODULE_big = dblink
PG_CPPFLAGS = -I$(libpq_srcdir)
OBJS = dblink.o
SHLIB_LINK = $(libpq)
DATA_built = dblink.sql
DOCS = README.dblink
include $(top_srcdir)/contrib/contrib-global.mk

View File

@ -1,415 +0,0 @@
/*
* dblink
*
* Functions returning results from a remote database
*
* Copyright (c) Joseph Conway <mail@joeconway.com>, 2001, 2002,
* ALL RIGHTS RESERVED;
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without a written agreement
* is hereby granted, provided that the above copyright notice and this
* paragraph and the following two paragraphs appear in all copies.
*
* IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
* LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
* DOCUMENTATION, EVEN IF THE AUTHOR OR DISTRIBUTORS HAVE BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAS NO OBLIGATIONS TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
Version 0.4 (7 April, 2002):
Functions allowing remote database INSERT/UPDATE/DELETE/SELECT, and
various utility functions.
Tested under Linux (Red Hat 7.2) and PostgreSQL 7.2 and 7.3devel
Release Notes:
Version 0.4
- removed cursor wrap around input sql to allow for remote
execution of INSERT/UPDATE/DELETE
- dblink now returns a resource id instead of a real pointer
- added several utility functions -- see below
Version 0.3
- fixed dblink invalid pointer causing corrupt elog message
- fixed dblink_tok improper handling of null results
- fixed examples in README.dblink
Version 0.2
- initial release
Installation:
Place these files in a directory called 'dblink' under 'contrib' in the PostgreSQL source tree. Then run:
make
make install
You can use dblink.sql to create the functions in your database of choice, e.g.
psql -U postgres template1 < dblink.sql
installs following functions into database template1:
dblink(text,text) RETURNS setof int
- returns a resource id for results from remote query
dblink_tok(int,int) RETURNS text
- extracts and returns individual field results
dblink_strtok(text,text,int) RETURNS text
- extracts and returns individual token from delimited text
dblink_get_pkey(text) RETURNS setof text
- returns the field names of a relation's primary key fields
dblink_last_oid(int) RETURNS oid
- returns the last inserted oid
dblink_build_sql_insert(text,int2vector,int2,_text,_text) RETURNS text
- builds an insert statement using a local tuple, replacing the
selection key field values with alternate supplied values
dblink_build_sql_delete(text,int2vector,int2,_text) RETURNS text
- builds a delete statement using supplied values for selection
key field values
dblink_build_sql_update(text,int2vector,int2,_text,_text) RETURNS text
- builds an update statement using a local tuple, replacing the
selection key field values with alternate supplied values
dblink_current_query() RETURNS text
- returns the current query string
dblink_replace(text,text,text) RETURNS text
- replace all occurences of substring-a in the input-string
with substring-b
Documentation
==================================================================
Name
dblink -- Returns a resource id for a data set from a remote database
Synopsis
dblink(text connstr, text sql)
Inputs
connstr
standard libpq format connection srting,
e.g. "hostaddr=127.0.0.1 port=5432 dbname=mydb user=postgres password=mypasswd"
sql
sql statement that you wish to execute on the remote host
e.g. "select * from pg_class"
Outputs
Returns setof int (res_id)
Example usage
select dblink('hostaddr=127.0.0.1 port=5432 dbname=mydb user=postgres password=mypasswd'
,'select f1, f2 from mytable');
==================================================================
Name
dblink_tok -- Returns individual select field results from a dblink remote query
Synopsis
dblink_tok(int res_id, int fnumber)
Inputs
res_id
a resource id returned by a call to dblink()
fnumber
the ordinal position (zero based) of the field to be returned from the dblink result set
Outputs
Returns text
Example usage
select dblink_tok(t1.dblink_p,0) as f1, dblink_tok(t1.dblink_p,1) as f2
from (select dblink('hostaddr=127.0.0.1 port=5432 dbname=mydb user=postgres password=mypasswd'
,'select f1, f2 from mytable') as dblink_p) as t1;
==================================================================
A more convenient way to use dblink may be to create a view:
create view myremotetable as
select dblink_tok(t1.dblink_p,0) as f1, dblink_tok(t1.dblink_p,1) as f2
from (select dblink('hostaddr=127.0.0.1 port=5432 dbname=template1 user=postgres password=postgres'
,'select proname, prosrc from pg_proc') as dblink_p) as t1;
Then you can simply write:
select f1, f2 from myremotetable where f1 like 'bytea%';
==================================================================
Name
dblink_strtok -- Extracts and returns individual token from delimited text
Synopsis
dblink_strtok(text inputstring, text delimiter, int posn) RETURNS text
Inputs
inputstring
any string you want to parse a token out of;
e.g. 'f=1&g=3&h=4'
delimiter
a single character to use as the delimiter;
e.g. '&' or '='
posn
the position of the token of interest, 0 based;
e.g. 1
Outputs
Returns text
Example usage
test=# select dblink_strtok(dblink_strtok('f=1&g=3&h=4','&',1),'=',1);
dblink_strtok
---------------
3
(1 row)
==================================================================
Name
dblink_get_pkey -- returns the field names of a relation's primary
key fields
Synopsis
dblink_get_pkey(text relname) RETURNS setof text
Inputs
relname
any relation name;
e.g. 'foobar'
Outputs
Returns setof text -- one row for each primary key field, in order of
precedence
Example usage
test=# select dblink_get_pkey('foobar');
dblink_get_pkey
-----------------
f1
f2
f3
f4
f5
(5 rows)
==================================================================
Name
dblink_last_oid -- Returns last inserted oid
Synopsis
dblink_last_oid(int res_id) RETURNS oid
Inputs
res_id
any resource id returned by dblink function;
Outputs
Returns oid of last inserted tuple
Example usage
test=# select dblink_last_oid(dblink('hostaddr=127.0.0.1 port=5432 dbname=mydb user=postgres password=mypasswd'
,'insert into mytable (f1, f2) values (1,2)'));
dblink_last_oid
----------------
16553
(1 row)
==================================================================
Name
dblink_build_sql_insert -- builds an insert statement using a local
tuple, replacing the selection key field
values with alternate supplied values
dblink_build_sql_delete -- builds a delete statement using supplied
values for selection key field values
dblink_build_sql_update -- builds an update statement using a local
tuple, replacing the selection key field
values with alternate supplied values
Synopsis
dblink_build_sql_insert(text relname
,int2vector primary_key_attnums
,int2 num_primary_key_atts
,_text src_pk_att_vals_array
,_text tgt_pk_att_vals_array) RETURNS text
dblink_build_sql_delete(text relname
,int2vector primary_key_attnums
,int2 num_primary_key_atts
,_text tgt_pk_att_vals_array) RETURNS text
dblink_build_sql_update(text relname
,int2vector primary_key_attnums
,int2 num_primary_key_atts
,_text src_pk_att_vals_array
,_text tgt_pk_att_vals_array) RETURNS text
Inputs
relname
any relation name;
e.g. 'foobar'
primary_key_attnums
vector of primary key attnums (1 based, see pg_index.indkey);
e.g. '1 2'
num_primary_key_atts
number of primary key attnums in the vector; e.g. 2
src_pk_att_vals_array
array of primary key values, used to look up the local matching
tuple, the values of which are then used to construct the SQL
statement
tgt_pk_att_vals_array
array of primary key values, used to replace the local tuple
values in the SQL statement
Outputs
Returns text -- requested SQL statement
Example usage
test=# select dblink_build_sql_insert('foo','1 2',2,'{"1", "a"}','{"1", "b''a"}');
dblink_build_sql_insert
--------------------------------------------------
INSERT INTO foo(f1,f2,f3) VALUES('1','b''a','1')
(1 row)
test=# select dblink_build_sql_delete('MyFoo','1 2',2,'{"1", "b"}');
dblink_build_sql_delete
---------------------------------------------
DELETE FROM "MyFoo" WHERE f1='1' AND f2='b'
(1 row)
test=# select dblink_build_sql_update('foo','1 2',2,'{"1", "a"}','{"1", "b"}');
dblink_build_sql_update
-------------------------------------------------------------
UPDATE foo SET f1='1',f2='b',f3='1' WHERE f1='1' AND f2='b'
(1 row)
==================================================================
Name
dblink_current_query -- returns the current query string
Synopsis
dblink_current_query () RETURNS text
Inputs
None
Outputs
Returns text -- a copy of the currently executing query
Example usage
test=# select dblink_current_query() from (select dblink('dbname=template1','select oid, proname from pg_proc where proname = ''byteacat''') as f1) as t1;
dblink_current_query
-----------------------------------------------------------------------------------------------------------------------------------------------------
select dblink_current_query() from (select dblink('dbname=template1','select oid, proname from pg_proc where proname = ''byteacat''') as f1) as t1;
(1 row)
==================================================================
Name
dblink_replace -- replace all occurences of substring-a in the
input-string with substring-b
Synopsis
dblink_replace(text input-string, text substring-a, text substring-b) RETURNS text
Inputs
input-string
the starting string, before replacement of substring-a
substring-a
the substring to find and replace
substring-b
the substring to be substituted in place of substring-a
Outputs
Returns text -- a copy of the starting string, but with all occurences of
substring-a replaced with substring-b
Example usage
test=# select dblink_replace('12345678901234567890','56','hello');
dblink_replace
----------------------------
1234hello78901234hello7890
(1 row)
==================================================================
-- Joe Conway

File diff suppressed because it is too large Load Diff

View File

@ -1,125 +0,0 @@
/*
* dblink.h
*
* Functions returning results from a remote database
*
* Copyright (c) Joseph Conway <mail@joeconway.com>, 2001, 2002,
* ALL RIGHTS RESERVED;
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without a written agreement
* is hereby granted, provided that the above copyright notice and this
* paragraph and the following two paragraphs appear in all copies.
*
* IN NO EVENT SHALL THE AUTHOR OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
* LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
* DOCUMENTATION, EVEN IF THE AUTHOR OR DISTRIBUTORS HAVE BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* THE AUTHOR AND DISTRIBUTORS SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAS NO OBLIGATIONS TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
#ifndef DBLINK_H
#define DBLINK_H
#include <string.h>
#include "postgres.h"
#include "libpq-fe.h"
#include "libpq-int.h"
#include "fmgr.h"
#include "access/tupdesc.h"
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/pg_index.h"
#include "catalog/pg_type.h"
#include "executor/executor.h"
#include "executor/spi.h"
#include "lib/stringinfo.h"
#include "nodes/nodes.h"
#include "nodes/execnodes.h"
#include "nodes/pg_list.h"
#include "parser/parse_type.h"
#include "tcop/tcopprot.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/array.h"
#include "utils/syscache.h"
#ifdef NamespaceRelationName
#include "catalog/namespace.h"
#endif /* NamespaceRelationName */
/*
* Max SQL statement size
*/
#define DBLINK_MAX_SQLSTATE_SIZE 16384
/*
* This struct holds the results of the remote query.
* Use fn_extra to hold a pointer to it across calls
*/
typedef struct
{
/*
* last tuple number accessed
*/
int tup_num;
/*
* resource index number for this context
*/
int res_id_index;
/*
* the actual query results
*/
PGresult *res;
} dblink_results;
/*
* This struct holds results in the form of an array.
* Use fn_extra to hold a pointer to it across calls
*/
typedef struct
{
/*
* elem being accessed
*/
int elem_num;
/*
* number of elems
*/
int num_elems;
/*
* the actual array
*/
void *res;
} dblink_array_results;
/*
* External declarations
*/
extern Datum dblink(PG_FUNCTION_ARGS);
extern Datum dblink_tok(PG_FUNCTION_ARGS);
extern Datum dblink_strtok(PG_FUNCTION_ARGS);
extern Datum dblink_get_pkey(PG_FUNCTION_ARGS);
extern Datum dblink_last_oid(PG_FUNCTION_ARGS);
extern Datum dblink_build_sql_insert(PG_FUNCTION_ARGS);
extern Datum dblink_build_sql_delete(PG_FUNCTION_ARGS);
extern Datum dblink_build_sql_update(PG_FUNCTION_ARGS);
extern Datum dblink_current_query(PG_FUNCTION_ARGS);
extern Datum dblink_replace_text(PG_FUNCTION_ARGS);
extern char *debug_query_string;
#endif /* DBLINK_H */

View File

@ -1,38 +0,0 @@
CREATE OR REPLACE FUNCTION dblink (text,text) RETURNS setof int
AS 'MODULE_PATHNAME','dblink' LANGUAGE 'c'
WITH (isstrict);
CREATE OR REPLACE FUNCTION dblink_tok (int,int) RETURNS text
AS 'MODULE_PATHNAME','dblink_tok' LANGUAGE 'c'
WITH (isstrict);
CREATE OR REPLACE FUNCTION dblink_strtok (text,text,int) RETURNS text
AS 'MODULE_PATHNAME','dblink_strtok' LANGUAGE 'c'
WITH (iscachable, isstrict);
CREATE OR REPLACE FUNCTION dblink_get_pkey (text) RETURNS setof text
AS 'MODULE_PATHNAME','dblink_get_pkey' LANGUAGE 'c'
WITH (isstrict);
CREATE OR REPLACE FUNCTION dblink_last_oid (int) RETURNS oid
AS 'MODULE_PATHNAME','dblink_last_oid' LANGUAGE 'c'
WITH (isstrict);
CREATE OR REPLACE FUNCTION dblink_build_sql_insert (text, int2vector, int2, _text, _text) RETURNS text
AS 'MODULE_PATHNAME','dblink_build_sql_insert' LANGUAGE 'c'
WITH (isstrict);
CREATE OR REPLACE FUNCTION dblink_build_sql_delete (text, int2vector, int2, _text) RETURNS text
AS 'MODULE_PATHNAME','dblink_build_sql_delete' LANGUAGE 'c'
WITH (isstrict);
CREATE OR REPLACE FUNCTION dblink_build_sql_update (text, int2vector, int2, _text, _text) RETURNS text
AS 'MODULE_PATHNAME','dblink_build_sql_update' LANGUAGE 'c'
WITH (isstrict);
CREATE OR REPLACE FUNCTION dblink_current_query () RETURNS text
AS 'MODULE_PATHNAME','dblink_current_query' LANGUAGE 'c';
CREATE OR REPLACE FUNCTION dblink_replace (text,text,text) RETURNS text
AS 'MODULE_PATHNAME','dblink_replace_text' LANGUAGE 'c'
WITH (iscachable, isstrict);

View File

@ -1,9 +0,0 @@
subdir = contrib/dbsize
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
MODULES = dbsize
DATA_built = dbsize.sql
DOCS = README.dbsize
include $(top_srcdir)/contrib/contrib-global.mk

View File

@ -1,11 +0,0 @@
This module contains two functions that report the size of a given
database or relation. E.g.,
SELECT database_size('template1');
SELECT relation_size('pg_class');
These functions report the actual file system space. Thus, users can
avoid digging through the details of the database directories.
Copy this directory to contrib/dbsize in your PostgreSQL source tree.
Then just run make; make install.

View File

@ -1,164 +0,0 @@
#include "postgres.h"
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include "access/heapam.h"
#include "catalog/catalog.h"
#include "catalog/catname.h"
#include "catalog/namespace.h"
#include "catalog/pg_database.h"
#include "fmgr.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
static char *
psnprintf(size_t len, const char *fmt,...)
{
va_list ap;
char *buf;
buf = palloc(len);
va_start(ap, fmt);
vsnprintf(buf, len, fmt, ap);
va_end(ap);
return buf;
}
/*
* SQL function: database_size(name) returns bigint
*/
PG_FUNCTION_INFO_V1(database_size);
Datum database_size(PG_FUNCTION_ARGS);
Datum
database_size(PG_FUNCTION_ARGS)
{
Name dbname = PG_GETARG_NAME(0);
HeapTuple tuple;
Relation relation;
ScanKeyData scanKey;
HeapScanDesc scan;
Oid dbid;
char *dbpath;
DIR *dirdesc;
struct dirent *direntry;
int64 totalsize;
relation = heap_openr(DatabaseRelationName, AccessShareLock);
ScanKeyEntryInitialize(&scanKey, 0, Anum_pg_database_datname,
F_NAMEEQ, NameGetDatum(dbname));
scan = heap_beginscan(relation, SnapshotNow, 1, &scanKey);
tuple = heap_getnext(scan, ForwardScanDirection);
if (!HeapTupleIsValid(tuple))
elog(ERROR, "database %s does not exist", NameStr(*dbname));
dbid = tuple->t_data->t_oid;
if (dbid == InvalidOid)
elog(ERROR, "invalid database id");
heap_endscan(scan);
heap_close(relation, NoLock);
dbpath = GetDatabasePath(dbid);
dirdesc = opendir(dbpath);
if (!dirdesc)
elog(ERROR, "could not open directory %s: %s", dbpath, strerror(errno));
totalsize = 0;
for (;;)
{
char *fullname;
struct stat statbuf;
errno = 0;
direntry = readdir(dirdesc);
if (!direntry)
{
if (errno)
elog(ERROR, "error reading directory: %s", strerror(errno));
else
break;
}
fullname = psnprintf(strlen(dbpath) + 1 + strlen(direntry->d_name) + 1,
"%s/%s", dbpath, direntry->d_name);
if (stat(fullname, &statbuf) == -1)
elog(ERROR, "could not stat %s: %s", fullname, strerror(errno));
totalsize += statbuf.st_size;
pfree(fullname);
}
closedir(dirdesc);
PG_RETURN_INT64(totalsize);
}
/*
* SQL function: relation_size(text) returns bigint
*/
PG_FUNCTION_INFO_V1(relation_size);
Datum relation_size(PG_FUNCTION_ARGS);
Datum
relation_size(PG_FUNCTION_ARGS)
{
text *relname = PG_GETARG_TEXT_P(0);
RangeVar *relrv;
Relation relation;
Oid relnode;
int64 totalsize;
unsigned int segcount;
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname,
"relation_size"));
relation = relation_openrv(relrv, AccessShareLock);
relnode = relation->rd_rel->relfilenode;
totalsize = 0;
segcount = 0;
for (;;)
{
char *fullname;
struct stat statbuf;
if (segcount == 0)
fullname = psnprintf(25, "%u", (unsigned) relnode);
else
fullname = psnprintf(50, "%u.%u", (unsigned) relnode, segcount);
if (stat(fullname, &statbuf) == -1)
{
if (errno == ENOENT)
break;
else
elog(ERROR, "could not stat %s: %m", fullname);
}
totalsize += statbuf.st_size;
pfree(fullname);
segcount++;
}
relation_close(relation, AccessShareLock);
PG_RETURN_INT64(totalsize);
}

View File

@ -1,7 +0,0 @@
CREATE FUNCTION database_size (name) RETURNS bigint
AS 'MODULE_PATHNAME', 'database_size'
LANGUAGE C WITH (isstrict);
CREATE FUNCTION relation_size (text) RETURNS bigint
AS 'MODULE_PATHNAME', 'relation_size'
LANGUAGE C WITH (isstrict);

View File

@ -1,11 +0,0 @@
# $Header: /cvsroot/pgsql/contrib/earthdistance/Makefile,v 1.11 2001/09/06 10:49:29 petere Exp $
subdir = contrib/earthdistance
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
MODULES = earthdistance
DATA_built = earthdistance.sql
DOCS = README.earthdistance
include $(top_srcdir)/contrib/contrib-global.mk

View File

@ -1,31 +0,0 @@
Date: Wed, 1 Apr 1998 15:19:32 -0600 (CST)
From: Hal Snyder <hal@vailsys.com>
To: vmehr@ctp.com
Subject: [QUESTIONS] Re: Spatial data, R-Trees
> From: Vivek Mehra <vmehr@ctp.com>
> Date: Wed, 1 Apr 1998 10:06:50 -0500
> Am just starting out with PostgreSQL and would like to learn more about
> the spatial data handling ablilities of postgreSQL - in terms of using
> R-tree indexes, user defined types, operators and functions.
>
> Would you be able to suggest where I could find some code and SQL to
> look at to create these?
Here's the setup for adding an operator '<@>' to give distance in
statute miles between two points on the earth's surface. Coordinates
are in degrees. Points are taken as (longitude, latitude) and not vice
versa as longitude is closer to the intuitive idea of x-axis and
latitude to y-axis.
There's C source, Makefile for FreeBSD, and SQL for installing and
testing the function.
Let me know if anything looks fishy!
A note on testing C extensions - it seems not enough to drop a function
and re-create it - if I change a function, I have to stop and restart
the backend for the new version to be seen. I guess it would be too
messy to track which functions are added from a .so and do a dlclose
when the last one is dropped.

View File

@ -1,72 +0,0 @@
#include "postgres.h"
#include <math.h>
#include "utils/geo_decls.h" /* for Pt */
/* Earth's radius is in statute miles. */
const int EARTH_RADIUS = 3958.747716;
const int TWO_PI = 2.0 * M_PI;
double *geo_distance(Point *pt1, Point *pt2);
/******************************************************
*
* degtorad - convert degrees to radians
*
* arg: double, angle in degrees
*
* returns: double, same angle in radians
******************************************************/
static double
degtorad(double degrees)
{
return (degrees / 360.0) * TWO_PI;
}
/******************************************************
*
* geo_distance - distance between points
*
* args:
* a pair of points - for each point,
* x-coordinate is longitude in degrees west of Greenwich
* y-coordinate is latitude in degrees above equator
*
* returns: double
* distance between the points in miles on earth's surface
******************************************************/
double *
geo_distance(Point *pt1, Point *pt2)
{
double long1,
lat1,
long2,
lat2;
double longdiff;
double *resultp = palloc(sizeof(double));
/* convert degrees to radians */
long1 = degtorad(pt1->x);
lat1 = degtorad(pt1->y);
long2 = degtorad(pt2->x);
lat2 = degtorad(pt2->y);
/* compute difference in longitudes - want < 180 degrees */
longdiff = fabs(long1 - long2);
if (longdiff > M_PI)
longdiff = TWO_PI - longdiff;
*resultp = EARTH_RADIUS * acos
(sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(longdiff));
return resultp;
}

View File

@ -1,24 +0,0 @@
--------------- geo_distance
DROP FUNCTION geo_distance (point, point);
CREATE FUNCTION geo_distance (point, point) RETURNS float8
AS 'MODULE_PATHNAME' LANGUAGE 'c'
WITH (isstrict);
SELECT geo_distance ('(1,2)'::point, '(3,4)'::point);
--------------- geo_distance as operator <@>
DROP OPERATOR <@> (point, point);
CREATE OPERATOR <@> (
leftarg = point,
rightarg = point,
procedure = geo_distance,
commutator = <@>
);
-- ( 87.6, 41.8) is in Chicago
-- (106.7, 35.1) is in Albuquerque
-- The cities are about 1100 miles apart
SELECT '(87.6,41.8)'::point <@> '(106.7,35.1)'::point;

View File

@ -1,19 +0,0 @@
# $Header: /cvsroot/pgsql/contrib/findoidjoins/Attic/Makefile,v 1.13 2001/09/06 10:49:29 petere Exp $
subdir = contrib/findoidjoins
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
PROGRAM = findoidjoins
OBJS = findoidjoins.o
libpgeasy_srcdir = $(top_srcdir)/src/interfaces/libpgeasy
libpgeasy_builddir = $(top_builddir)/src/interfaces/libpgeasy
PG_CPPFLAGS = -I$(libpgeasy_srcdir) -I$(libpq_srcdir)
PG_LIBS = -L$(libpgeasy_builddir) -lpgeasy $(libpq)
SCRIPTS = make_oidjoins_check
DOCS = README.findoidjoins
include $(top_srcdir)/contrib/contrib-global.mk

View File

@ -1,94 +0,0 @@
findoidjoins
This program scans a database, and prints oid fields (also regproc, regclass
and regtype fields) and the tables they join to. CAUTION: it is ver-r-r-y
slow on a large database, or even a not-so-large one. We don't really
recommend running it on anything but an empty database, such as template1.
Uses pgeasy library.
Run on an empty database, it returns the system join relationships (shown
below for 7.2). Note that unexpected matches may indicate bogus entries
in system tables --- don't accept a peculiar match without question.
In particular, a field shown as joining to more than one target table is
probably messed up. In 7.2, the *only* field that should join to more
than one target is pg_description.objoid. (Running make_oidjoins_check
is an easy way to spot fields joining to more than one table, BTW.)
The shell script make_oidjoins_check converts findoidjoins' output
into an SQL script that checks for dangling links (entries in an
OID or REGPROC column that don't match any row in the expected table).
Note that fields joining to more than one table are NOT processed.
The result of make_oidjoins_check should be installed as the "oidjoins"
regression test. The oidjoins test should be updated after any
revision in the patterns of cross-links between system tables.
(Ideally we'd just regenerate the script as part of the regression
tests themselves, but that seems too slow...)
NOTE: in 7.2, make_oidjoins_check produces one bogus join check, for
pg_class.relfilenode => pg_class.oid. This is an artifact and should not
be added to the oidjoins regress test.
---------------------------------------------------------------------------
Join pg_aggregate.aggtransfn => pg_proc.oid
Join pg_aggregate.aggfinalfn => pg_proc.oid
Join pg_aggregate.aggbasetype => pg_type.oid
Join pg_aggregate.aggtranstype => pg_type.oid
Join pg_aggregate.aggfinaltype => pg_type.oid
Join pg_am.amgettuple => pg_proc.oid
Join pg_am.aminsert => pg_proc.oid
Join pg_am.ambeginscan => pg_proc.oid
Join pg_am.amrescan => pg_proc.oid
Join pg_am.amendscan => pg_proc.oid
Join pg_am.ammarkpos => pg_proc.oid
Join pg_am.amrestrpos => pg_proc.oid
Join pg_am.ambuild => pg_proc.oid
Join pg_am.ambulkdelete => pg_proc.oid
Join pg_am.amcostestimate => pg_proc.oid
Join pg_amop.amopclaid => pg_opclass.oid
Join pg_amop.amopopr => pg_operator.oid
Join pg_amproc.amopclaid => pg_opclass.oid
Join pg_amproc.amproc => pg_proc.oid
Join pg_attribute.attrelid => pg_class.oid
Join pg_attribute.atttypid => pg_type.oid
Join pg_class.reltype => pg_type.oid
Join pg_class.relam => pg_am.oid
Join pg_class.reltoastrelid => pg_class.oid
Join pg_class.reltoastidxid => pg_class.oid
Join pg_description.classoid => pg_class.oid
Join pg_index.indexrelid => pg_class.oid
Join pg_index.indrelid => pg_class.oid
Join pg_opclass.opcamid => pg_am.oid
Join pg_opclass.opcintype => pg_type.oid
Join pg_operator.oprleft => pg_type.oid
Join pg_operator.oprright => pg_type.oid
Join pg_operator.oprresult => pg_type.oid
Join pg_operator.oprcom => pg_operator.oid
Join pg_operator.oprnegate => pg_operator.oid
Join pg_operator.oprlsortop => pg_operator.oid
Join pg_operator.oprrsortop => pg_operator.oid
Join pg_operator.oprcode => pg_proc.oid
Join pg_operator.oprrest => pg_proc.oid
Join pg_operator.oprjoin => pg_proc.oid
Join pg_proc.prolang => pg_language.oid
Join pg_proc.prorettype => pg_type.oid
Join pg_rewrite.ev_class => pg_class.oid
Join pg_statistic.starelid => pg_class.oid
Join pg_statistic.staop1 => pg_operator.oid
Join pg_statistic.staop2 => pg_operator.oid
Join pg_statistic.staop3 => pg_operator.oid
Join pg_trigger.tgrelid => pg_class.oid
Join pg_trigger.tgfoid => pg_proc.oid
Join pg_type.typrelid => pg_class.oid
Join pg_type.typelem => pg_type.oid
Join pg_type.typinput => pg_proc.oid
Join pg_type.typoutput => pg_proc.oid
Join pg_type.typreceive => pg_proc.oid
Join pg_type.typsend => pg_proc.oid
---------------------------------------------------------------------------
Bruce Momjian (root@candle.pha.pa.us)

View File

@ -1,109 +0,0 @@
/*
* findoidjoins.c, requires src/interfaces/libpgeasy
*
*/
#include "postgres_fe.h"
#include "libpq-fe.h"
#include "halt.h"
#include "libpgeasy.h"
PGresult *attres,
*relres;
int
main(int argc, char **argv)
{
char query[4000];
char relname[256];
char relname2[256];
char attname[256];
char typname[256];
int count;
char optstr[256];
if (argc != 2)
halt("Usage: %s database\n", argv[0]);
snprintf(optstr, 256, "dbname=%s", argv[1]);
connectdb(optstr);
on_error_continue();
on_error_stop();
doquery("BEGIN WORK");
doquery("\
DECLARE c_attributes BINARY CURSOR FOR \
SELECT typname, relname, a.attname \
FROM pg_class c, pg_attribute a, pg_type t \
WHERE a.attnum > 0 AND \
relkind = 'r' AND \
(typname = 'oid' OR \
typname = 'regproc' OR \
typname = 'regclass' OR \
typname = 'regtype') AND \
a.attrelid = c.oid AND \
a.atttypid = t.oid \
ORDER BY 2, a.attnum ; \
");
doquery("FETCH ALL IN c_attributes");
attres = get_result();
doquery("\
DECLARE c_relations BINARY CURSOR FOR \
SELECT relname \
FROM pg_class c \
WHERE relkind = 'r' AND relhasoids \
ORDER BY 1; \
");
doquery("FETCH ALL IN c_relations");
relres = get_result();
set_result(attres);
while (fetch(typname, relname, attname) != END_OF_TUPLES)
{
set_result(relres);
reset_fetch();
while (fetch(relname2) != END_OF_TUPLES)
{
unset_result(relres);
if (strcmp(typname, "oid") == 0)
sprintf(query, "\
DECLARE c_matches BINARY CURSOR FOR \
SELECT count(*)::int4 \
FROM \"%s\" t1, \"%s\" t2 \
WHERE t1.\"%s\" = t2.oid ",
relname, relname2, attname);
else
sprintf(query, "\
DECLARE c_matches BINARY CURSOR FOR \
SELECT count(*)::int4 \
FROM \"%s\" t1, \"%s\" t2 \
WHERE t1.\"%s\"::oid = t2.oid ",
relname, relname2, attname);
doquery(query);
doquery("FETCH ALL IN c_matches");
fetch(&count);
if (count != 0)
printf("Join %s.%s => %s.oid\n", relname, attname, relname2);
doquery("CLOSE c_matches");
set_result(relres);
}
set_result(attres);
}
set_result(relres);
doquery("CLOSE c_relations");
PQclear(relres);
set_result(attres);
doquery("CLOSE c_attributes");
PQclear(attres);
unset_result(attres);
doquery("COMMIT WORK");
disconnectdb();
return 0;
}

View File

@ -1,53 +0,0 @@
#! /bin/sh
# You first run findoidjoins on the template1 database, and send that
# output into this script to generate a list of SQL statements.
# NOTE: any field that findoidjoins thinks joins to more than one table
# will NOT be checked by the output of this script. You should be
# suspicious of multiple entries in findoidjoins' output.
# Caution: you may need to use GNU awk.
AWK=${AWK:-awk}
trap "rm -f /tmp/$$ /tmp/$$a /tmp/$$b" 0 1 2 3 15
# Read input
cat "$@" >/tmp/$$
# Look for fields with multiple references.
cat /tmp/$$ | cut -d' ' -f2 | sort | uniq -d >/tmp/$$a
if [ -s /tmp/$$a ] ; then
echo "Ignoring these fields that link to multiple tables:" 1>&2
cat /tmp/$$a 1>&2
fi
# Get the non-multiply-referenced fields.
cat /tmp/$$ | while read LINE
do
set -- $LINE
grep "$2" /tmp/$$a >/dev/null 2>&1 || echo $LINE
done >/tmp/$$b
# Generate the output.
cat /tmp/$$b |
$AWK -F'[ \.]' '\
BEGIN \
{
printf "\
--\n\
-- This is created by pgsql/contrib/findoidjoins/make_oidjoin_check\n\
--\n";
}
{
printf "\
SELECT ctid, %s.%s \n\
FROM %s \n\
WHERE %s.%s != 0 AND \n\
NOT EXISTS(SELECT * FROM %s AS t1 WHERE t1.oid = %s.%s);\n",
$2, $3, $2,
$2, $3,
$5, $2, $3;
}'
exit 0

View File

@ -1,12 +0,0 @@
# $Header: /cvsroot/pgsql/contrib/fulltextindex/Attic/Makefile,v 1.11 2001/09/06 10:49:29 petere Exp $
subdir = contrib/fulltextindex
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
MODULES = fti
DATA_built = fti.sql
DOCS = README.fti
SCRIPTS = fti.pl
include $(top_srcdir)/contrib/contrib-global.mk

View File

@ -1,201 +0,0 @@
An attempt at some sort of Full Text Indexing for PostgreSQL.
The included software is an attempt to add some sort of Full Text Indexing
support to PostgreSQL. I mean by this that we can ask questions like:
Give me all rows that have 'still' and 'nash' in the 'artist' or 'title'
fields.
Ofcourse we can write this as:
select * from cds where (artist ~* 'stills' or title ~* 'stills') and
(artist ~* 'nash' or title ~* 'nash');
But this does not use any indices, and therefore, if your database
gets very large, it will not have very high performance (the above query
requires at least one sequential scan, it probably takes 2 due to the
self-join).
The approach used by this add-on is to define a trigger on the table and
columns you want to do this queries on. On every insert in the table, it
takes the value in the specified columns, breaks the text in these columns
up into pieces, and stores all sub-strings into another table, together
with a reference to the row in the original table that contained this
sub-string (it uses the oid of that row).
By now creating an index over the 'fti-table', we can search for
substrings that occur in the original table. By making a join between
the fti-table and the orig-table, we can get the actual rows we want
(this can also be done by using subselects - but subselects are currently
inefficient in Postgres, and maybe there're other ways too).
The trigger code also allows an array called StopWords, that prevents
certain words from being indexed.
As an example we take the previous query, where we assume we have all
sub-strings in the table 'cds-fti':
select c.*
from cds c, cds-fti f1, cds-fti f2
where f1.string ~ '^stills' and
f2.string ~ '^nash' and
f1.id = c.oid and
f2.id = c.oid ;
We can use the ~ (case-sensitive regular expression) here, because of
the way sub-strings are built: from right to left, ie. house -> 'se' +
'use' + 'ouse' + 'house'. If a ~ search starts with a ^ (match start of
string), btree indices can be used by PostgreSQL.
Now, how do we create the trigger that maintains the fti-table? First: the
fti-table should have the following schema:
create cds-fti ( string varchar(N), id oid );
Don't change the *names* of the columns, the varchar() can in fact also
be of text-type. If you do use varchar, make sure the largest possible
sub-string will fit.
The create the function that contains the trigger::
create function fti() returns opaque as
'/path/to/fti.so' language 'C';
And finally define the trigger on the 'cds' table:
create trigger cds-fti-trigger after update or insert or delete on cds
for each row execute procedure fti(cds-fti, artist, title);
Here, the trigger will be defined on table 'cds', it will create
sub-strings from the fields 'artist' and 'title', and it will place
those sub-strings in the table 'cds-fti'.
Now populate the table 'cds'. This will also populate the table 'cds-fti'.
It's fastest to populate the table *before* you create the indices. Use the
supplied 'fti.pl' to assist you with this.
Before you start using the system, you should at least have the following
indices:
create index cds-fti-idx on cds-fti (string); -- String matching
create index cds-fti-idx on cds-fti (id); -- For deleting a cds row
create index cds-oid-idx on cds (oid); -- For joining cds to cds-fti
To get the most performance out of this, you should have 'cds-fti'
clustered on disk, ie. all rows with the same sub-strings should be
close to each other. There are 3 ways of doing this:
1. After you have created the indices, execute 'cluster cds-fti-idx on cds-fti'.
2. Do a 'select * into tmp-table from cds-fti order by string' *before*
you create the indices, then 'drop table cds-fti' and
'alter table tmp-table rename to cds-fti'
3. *Before* creating indices, dump the contents of the cds-fti table using
'pg_dump -a -t cds-fti dbase-name', remove the \connect
from the beginning and the \. from the end, and sort it using the
UNIX 'sort' program, and reload the data.
Method 1 is very slow, 2 a lot faster, and for very large tables, 3 is
preferred.
BENCH:
~~~~~
Maarten Boekhold <maartenb@dutepp0.et.tudelft.nl>
The following data was generated by the 'timings.sh' script included
in this directory. It uses a very large table with music-related
articles as a source for the fti-table. The tables used are:
product : contains product information : 540.429 rows
artist_fti : fti table for product : 4.501.321 rows
clustered : same as above, only clustered : 4.501.321 rows
A sequential scan of the artist_fti table (and thus also the clustered table)
takes around 6:16 minutes....
Unfortunately I cannot provide anybody else with this test-data, since I
am not allowed to redistribute the data (it's a database being sold by
a couple of wholesale companies). Anyways, it's megabytes, so you probably
wouldn't want it in this distribution anyways.
I haven't tested this with less data.
The test-machine is a Pentium 133, 64 MB, Linux 2.0.32 with the database
on a 'QUANTUM BIGFOOT_CY4320A, 4134MB w/67kB Cache, CHS=8960/15/63'. This
is a very slow disk.
The postmaster was running with:
postmaster -i -b /usr/local/pgsql/bin/postgres -S 1024 -B 256 \
-o -o /usr/local/pgsql/debug-output -F -d 1
('trashing' means a 'select count(*) from artist_fti' to completely trash
any disk-caches and buffers....)
TESTING ON UNCLUSTERED FTI
trashing
1: ^lapton and ^ric : 0.050u 0.000s 5m37.484s 0.01%
2: ^lapton and ^ric : 0.050u 0.030s 5m32.447s 0.02%
3: ^lapton and ^ric : 0.030u 0.020s 5m28.822s 0.01%
trashing
1: ^lling and ^tones : 0.020u 0.030s 0m54.313s 0.09%
2: ^lling and ^tones : 0.040u 0.030s 0m5.057s 1.38%
3: ^lling and ^tones : 0.010u 0.050s 0m2.072s 2.89%
trashing
1: ^aughan and ^evie : 0.020u 0.030s 0m26.241s 0.19%
2: ^aughan and ^evie : 0.050u 0.010s 0m1.316s 4.55%
3: ^aughan and ^evie : 0.030u 0.020s 0m1.029s 4.85%
trashing
1: ^lling : 0.040u 0.010s 0m55.104s 0.09%
2: ^lling : 0.030u 0.030s 0m4.716s 1.27%
3: ^lling : 0.040u 0.010s 0m2.157s 2.31%
trashing
1: ^stev and ^ray and ^vaugh : 0.040u 0.000s 1m5.630s 0.06%
2: ^stev and ^ray and ^vaugh : 0.050u 0.020s 1m3.561s 0.11%
3: ^stev and ^ray and ^vaugh : 0.050u 0.010s 1m5.923s 0.09%
trashing
1: ^lling (no join) : 0.050u 0.020s 0m24.139s 0.28%
2: ^lling (no join) : 0.040u 0.040s 0m1.087s 7.35%
3: ^lling (no join) : 0.020u 0.030s 0m0.772s 6.48%
trashing
1: ^vaughan (no join) : 0.040u 0.030s 0m9.075s 0.77%
2: ^vaughan (no join) : 0.030u 0.010s 0m0.609s 6.56%
3: ^vaughan (no join) : 0.040u 0.010s 0m0.503s 9.94%
trashing
1: ^rol (no join) : 0.020u 0.030s 0m49.898s 0.10%
2: ^rol (no join) : 0.030u 0.020s 0m3.136s 1.59%
3: ^rol (no join) : 0.030u 0.020s 0m1.231s 4.06%
TESTING ON CLUSTERED FTI
trashing
1: ^lapton and ^ric : 0.020u 0.020s 2m17.120s 0.02%
2: ^lapton and ^ric : 0.030u 0.020s 2m11.767s 0.03%
3: ^lapton and ^ric : 0.040u 0.010s 2m8.128s 0.03%
trashing
1: ^lling and ^tones : 0.020u 0.030s 0m18.179s 0.27%
2: ^lling and ^tones : 0.030u 0.010s 0m1.897s 2.10%
3: ^lling and ^tones : 0.040u 0.010s 0m1.619s 3.08%
trashing
1: ^aughan and ^evie : 0.070u 0.010s 0m11.765s 0.67%
2: ^aughan and ^evie : 0.040u 0.010s 0m1.198s 4.17%
3: ^aughan and ^evie : 0.030u 0.020s 0m0.872s 5.73%
trashing
1: ^lling : 0.040u 0.000s 0m28.623s 0.13%
2: ^lling : 0.030u 0.010s 0m2.339s 1.70%
3: ^lling : 0.030u 0.010s 0m1.975s 2.02%
trashing
1: ^stev and ^ray and ^vaugh : 0.020u 0.010s 0m17.667s 0.16%
2: ^stev and ^ray and ^vaugh : 0.030u 0.010s 0m3.745s 1.06%
3: ^stev and ^ray and ^vaugh : 0.030u 0.020s 0m3.439s 1.45%
trashing
1: ^lling (no join) : 0.020u 0.040s 0m2.218s 2.70%
2: ^lling (no join) : 0.020u 0.020s 0m0.506s 7.90%
3: ^lling (no join) : 0.030u 0.030s 0m0.510s 11.76%
trashing
1: ^vaughan (no join) : 0.040u 0.050s 0m2.048s 4.39%
2: ^vaughan (no join) : 0.030u 0.020s 0m0.332s 15.04%
3: ^vaughan (no join) : 0.040u 0.010s 0m0.318s 15.72%
trashing
1: ^rol (no join) : 0.020u 0.030s 0m2.384s 2.09%
2: ^rol (no join) : 0.020u 0.030s 0m0.676s 7.39%
3: ^rol (no join) : 0.020u 0.030s 0m0.697s 7.17%

View File

@ -1 +0,0 @@
Place "stop" words in lookup table

View File

@ -1,443 +0,0 @@
#include "postgres.h"
#include <ctype.h>
#include "executor/spi.h"
#include "commands/trigger.h"
/*
* Trigger function accepts variable number of arguments:
*
* 1. relation in which to store the substrings
* 2. fields to extract substrings from
*
* The relation in which to insert *must* have the following layout:
*
* string varchar(#)
* id oid
*
* where # is the largest size of the varchar columns being indexed
*
* Example:
*
* -- Create the SQL function based on the compiled shared object
* create function fti() returns opaque as
* '/usr/local/pgsql/lib/contrib/fti.so' language 'C';
*
* -- Create the FTI table
* create table product_fti (string varchar(255), id oid);
*
* -- Create an index to assist string matches
* create index product_fti_string_idx on product_fti (string);
*
* -- Create an index to assist trigger'd deletes
* create index product_fti_id_idx on product_fti (id);
*
* -- Create an index on the product oid column to assist joins
* -- between the fti table and the product table
* create index product_oid_idx on product (oid);
*
* -- Create the trigger to perform incremental changes to the full text index.
* create trigger product_fti_trig after update or insert or delete on product
* for each row execute procedure fti(product_fti, title, artist);
* ^^^^^^^^^^^
* table where full text index is stored
* ^^^^^^^^^^^^^
* columns to index in the base table
*
* After populating 'product', try something like:
*
* SELECT DISTINCT(p.*) FROM product p, product_fti f1, product_fti f2 WHERE
* f1.string ~ '^slippery' AND f2.string ~ '^wet' AND p.oid=f1.id AND p.oid=f2.id;
*
* To check that your indicies are being used correctly, make sure you
* EXPLAIN SELECT ... your test query above.
*
* CHANGELOG
* ---------
*
* august 3 2001
* Extended fti function to accept more than one column as a
* parameter and all specified columns are indexed. Changed
* all uses of sprintf to snprintf. Made error messages more
* consistent.
*
* march 4 1998 Changed breakup() to return less substrings. Only breakup
* in word parts which are in turn shortened from the start
* of the word (ie. word, ord, rd)
* Did allocation of substring buffer outside of breakup()
*
* oct. 5 1997, fixed a bug in string breakup (where there are more nonalpha
* characters between words then 1).
*
* oct 4-5 1997 implemented the thing, at least the basic functionallity
* of it all....
*
* TODO
* ----
*
* prevent generating duplicate words for an oid in the fti table
* save a plan for deletes
* create a function that will make the index *after* we have populated
* the main table (probably first delete all contents to be sure there's
* nothing in it, then re-populate the fti-table)
*
* can we do something with operator overloading or a seperate function
* that can build the final query automatigally?
*/
#define MAX_FTI_QUERY_LENGTH 8192
extern Datum fti(PG_FUNCTION_ARGS);
static char *breakup(char *, char *);
static bool is_stopword(char *);
static bool new_tuple = false;
#ifdef USE_STOP_WORDS
/* THIS LIST MUST BE IN SORTED ORDER, A BINARY SEARCH IS USED!!!! */
char *StopWords[] = { /* list of words to skip in indexing */
"no",
"the",
"yes"
};
#endif /* USE_STOP_WORDS */
/* stuff for caching query-plans, stolen from contrib/spi/\*.c */
typedef struct
{
char *ident;
int nplans;
void **splan;
} EPlan;
static EPlan *InsertPlans = NULL;
static EPlan *DeletePlans = NULL;
static int nInsertPlans = 0;
static int nDeletePlans = 0;
static EPlan *find_plan(char *ident, EPlan ** eplan, int *nplans);
/***********************************************************************/
PG_FUNCTION_INFO_V1(fti);
Datum
fti(PG_FUNCTION_ARGS)
{
TriggerData *trigdata;
Trigger *trigger; /* to get trigger name */
int nargs; /* # of arguments */
char **args; /* arguments */
char *relname; /* triggered relation name */
Relation rel; /* triggered relation */
char *indexname; /* name of table for substrings */
HeapTuple rettuple = NULL;
TupleDesc tupdesc; /* tuple description */
bool isinsert = false;
bool isdelete = false;
int ret;
char query[MAX_FTI_QUERY_LENGTH];
Oid oid;
/*
* FILE *debug;
*/
/*
* debug = fopen("/dev/xconsole", "w"); fprintf(debug, "FTI: entered
* function\n"); fflush(debug);
*/
if (!CALLED_AS_TRIGGER(fcinfo))
elog(ERROR, "Full Text Indexing: Not fired by trigger manager");
/* It's safe to cast now that we've checked */
trigdata = (TriggerData *) fcinfo->context;
if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
elog(ERROR, "Full Text Indexing: Can't process STATEMENT events");
if (TRIGGER_FIRED_BEFORE(trigdata->tg_event))
elog(ERROR, "Full Text Indexing: Must be fired AFTER event");
if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
isinsert = true;
if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
{
isdelete = true;
isinsert = true;
}
if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
isdelete = true;
trigger = trigdata->tg_trigger;
rel = trigdata->tg_relation;
relname = SPI_getrelname(rel);
rettuple = trigdata->tg_trigtuple;
if (isdelete && isinsert) /* is an UPDATE */
rettuple = trigdata->tg_newtuple;
if ((ret = SPI_connect()) < 0)
elog(ERROR, "Full Text Indexing: SPI_connect: Failed, returned %d\n", ret);
nargs = trigger->tgnargs;
if (nargs < 2)
elog(ERROR, "Full Text Indexing: Trigger must have at least 2 arguments\n");
args = trigger->tgargs;
indexname = args[0];
tupdesc = rel->rd_att; /* what the tuple looks like (?) */
/* get oid of current tuple, needed by all, so place here */
oid = rettuple->t_data->t_oid;
if (!OidIsValid(oid))
elog(ERROR, "Full Text Indexing: Oid of current tuple is invalid");
if (isdelete)
{
void *pplan;
Oid *argtypes;
Datum values[1];
EPlan *plan;
int i;
snprintf(query, MAX_FTI_QUERY_LENGTH, "D%s", indexname);
for (i = 1; i < nargs; i++)
snprintf(query, MAX_FTI_QUERY_LENGTH, "%s$%s", query, args[i]);
plan = find_plan(query, &DeletePlans, &nDeletePlans);
if (plan->nplans <= 0)
{
argtypes = (Oid *) palloc(sizeof(Oid));
argtypes[0] = OIDOID;
snprintf(query, MAX_FTI_QUERY_LENGTH, "DELETE FROM %s WHERE id = $1", indexname);
pplan = SPI_prepare(query, 1, argtypes);
if (!pplan)
elog(ERROR, "Full Text Indexing: SPI_prepare: Returned NULL in delete");
pplan = SPI_saveplan(pplan);
if (pplan == NULL)
elog(ERROR, "Full Text Indexing: SPI_saveplan: Returned NULL in delete");
plan->splan = (void **) malloc(sizeof(void *));
*(plan->splan) = pplan;
plan->nplans = 1;
}
values[0] = oid;
ret = SPI_execp(*(plan->splan), values, NULL, 0);
if (ret != SPI_OK_DELETE)
elog(ERROR, "Full Text Indexing: SPI_execp: Error executing plan in delete");
}
if (isinsert)
{
char *substring;
char *column;
void *pplan;
Oid *argtypes;
Datum values[2];
int colnum;
struct varlena *data;
EPlan *plan;
int i;
char *buff;
char *string;
snprintf(query, MAX_FTI_QUERY_LENGTH, "I%s", indexname);
for (i = 1; i < nargs; i++)
snprintf(query, MAX_FTI_QUERY_LENGTH, "%s$%s", query, args[i]);
plan = find_plan(query, &InsertPlans, &nInsertPlans);
/* no plan yet, so allocate mem for argtypes */
if (plan->nplans <= 0)
{
argtypes = (Oid *) palloc(2 * sizeof(Oid));
argtypes[0] = VARCHAROID; /* create table t_name (string
* varchar, */
argtypes[1] = OIDOID; /* id oid); */
/* prepare plan to gain speed */
snprintf(query, MAX_FTI_QUERY_LENGTH, "INSERT INTO %s (string, id) VALUES ($1, $2)",
indexname);
pplan = SPI_prepare(query, 2, argtypes);
if (!pplan)
elog(ERROR, "Full Text Indexing: SPI_prepare: Returned NULL in insert");
pplan = SPI_saveplan(pplan);
if (pplan == NULL)
elog(ERROR, "Full Text Indexing: SPI_saveplan: Returned NULL in insert");
plan->splan = (void **) malloc(sizeof(void *));
*(plan->splan) = pplan;
plan->nplans = 1;
}
/* prepare plan for query */
for (i = 0; i < nargs - 1; i++)
{
colnum = SPI_fnumber(tupdesc, args[i + 1]);
if (colnum == SPI_ERROR_NOATTRIBUTE)
elog(ERROR, "Full Text Indexing: SPI_fnumber: Column '%s' of '%s' not found", args[i + 1], indexname);
/* Get the char* representation of the column */
column = SPI_getvalue(rettuple, tupdesc, colnum);
/* make sure we don't try to index NULL's */
if (column)
{
string = column;
while (*string != '\0')
{
*string = tolower((unsigned char) *string);
string++;
}
data = (struct varlena *) palloc(sizeof(int32) + strlen(column) +1);
buff = palloc(strlen(column) + 1);
/* saves lots of calls in while-loop and in breakup() */
new_tuple = true;
while ((substring = breakup(column, buff)))
{
int l;
l = strlen(substring);
data->vl_len = l + sizeof(int32);
memcpy(VARDATA(data), substring, l);
values[0] = PointerGetDatum(data);
values[1] = oid;
ret = SPI_execp(*(plan->splan), values, NULL, 0);
if (ret != SPI_OK_INSERT)
elog(ERROR, "Full Text Indexing: SPI_execp: Error executing plan in insert");
}
pfree(buff);
pfree(data);
}
}
}
SPI_finish();
return PointerGetDatum(rettuple);
}
static char *
breakup(char *string, char *substring)
{
static char *last_start;
static char *cur_pos;
if (new_tuple)
{
cur_pos = last_start = &string[strlen(string) - 1];
new_tuple = false; /* don't initialize this next time */
}
while (cur_pos > string) /* don't read before start of 'string' */
{
/*
* skip pieces at the end of a string that are not alfa-numeric
* (ie. 'string$%^&', last_start first points to '&', and after
* this to 'g'
*/
if (!isalnum((unsigned char) *last_start))
{
while (!isalnum((unsigned char) *last_start) &&
last_start > string)
last_start--;
cur_pos = last_start;
}
cur_pos--; /* substrings are at minimum 2 characters
* long */
if (isalnum((unsigned char) *cur_pos))
{
/* Houston, we have a substring! :) */
memcpy(substring, cur_pos, last_start - cur_pos + 1);
substring[last_start - cur_pos + 1] = '\0';
if (!is_stopword(substring))
return substring;
}
else
{
last_start = cur_pos - 1;
cur_pos = last_start;
}
}
return NULL; /* we've processed all of 'string' */
}
/* copied from src/backend/parser/keywords.c and adjusted for our situation*/
static bool
is_stopword(char *text)
{
#ifdef USE_STOP_WORDS
char **StopLow; /* for list of stop-words */
char **StopHigh;
char **StopMiddle;
int difference;
StopLow = &StopWords[0]; /* initialize stuff for binary search */
StopHigh = endof(StopWords);
/* Loop invariant: *StopLow <= text < *StopHigh */
while (StopLow < StopHigh)
{
StopMiddle = StopLow + (StopHigh - StopLow) / 2;
difference = strcmp(*StopMiddle, text);
if (difference == 0)
return (true);
else if (difference < 0)
StopLow = StopMiddle + 1;
else
StopHigh = StopMiddle;
}
#endif /* USE_STOP_WORDS */
return (false);
}
/* for caching of query plans, stolen from contrib/spi/\*.c */
static EPlan *
find_plan(char *ident, EPlan ** eplan, int *nplans)
{
EPlan *newp;
int i;
if (*nplans > 0)
{
for (i = 0; i < *nplans; i++)
{
if (strcmp((*eplan)[i].ident, ident) == 0)
break;
}
if (i != *nplans)
return (*eplan + i);
*eplan = (EPlan *) realloc(*eplan, (i + 1) * sizeof(EPlan));
newp = *eplan + i;
}
else
{
newp = *eplan = (EPlan *) malloc(sizeof(EPlan));
(*nplans) = i = 0;
}
newp->ident = (char *) malloc(strlen(ident) + 1);
strcpy(newp->ident, ident);
newp->nplans = 0;
newp->splan = NULL;
(*nplans)++;
return (newp);
}

View File

@ -1,209 +0,0 @@
#!/usr/bin/perl
#
# This script substracts all suffixes of all words in a specific column in a table
# and generates output that can be loaded into a new table with the
# psql '\copy' command. The new table should have the following structure:
#
# create table tab (
# string text,
# id oid
# );
#
# Note that you cannot use 'copy' (the SQL-command) directly, because
# there's no '\.' included at the end of the output.
#
# The output can be fed through the UNIX commands 'uniq' and 'sort'
# to generate the smallest and sorted output to populate the fti-table.
#
# Example:
#
# fti.pl -u -d mydb -t mytable -c mycolumn,mycolumn2 -f myfile
# sort -o myoutfile myfile
# uniq myoutfile sorted-file
#
# psql -u mydb
#
# \copy my_fti_table from myfile
#
# create index fti_idx on my_fti_table (string,id);
#
# create function fti() returns opaque as
# '/path/to/fti/file/fti.so'
# language 'C';
#
# create trigger my_fti_trigger after update or insert or delete
# on mytable
# for each row execute procedure fti(my_fti_table, mycolumn);
#
# Make sure you have an index on mytable(oid) to be able to do somewhat
# efficient substring searches.
#use lib '/usr/local/pgsql/lib/perl5/';
use lib '/mnt/web/guide/postgres/lib/perl5/site_perl';
use Pg;
use Getopt::Std;
$PGRES_EMPTY_QUERY = 0 ;
$PGRES_COMMAND_OK = 1 ;
$PGRES_TUPLES_OK = 2 ;
$PGRES_COPY_OUT = 3 ;
$PGRES_COPY_IN = 4 ;
$PGRES_BAD_RESPONSE = 5 ;
$PGRES_NONFATAL_ERROR = 6 ;
$PGRES_FATAL_ERROR = 7 ;
# the minimum length of word to include in the full text index
$MIN_WORD_LENGTH = 2;
# the minimum length of the substrings in the full text index
$MIN_SUBSTRING_LENGTH = 2;
$[ = 0; # make sure string offsets start at 0
sub break_up {
my $string = pop @_;
# convert strings to lower case
$string = lc($string);
@strings = split(/\W+/, $string);
@subs = ();
foreach $s (@strings) {
$len = length($s);
next if ($len <= $MIN_WORD_LENGTH);
for ($i = 0; $i <= $len - $MIN_SUBSTRING_LENGTH; $i++) {
$tmp = substr($s, $i);
push(@subs, $tmp);
}
}
return @subs;
}
sub connect_db {
my $dbname = shift @_;
my $user = shift @_;
my $passwd = shift @_;
if (!defined($dbname) || $dbname eq "") {
return 1;
}
$connect_string = "dbname=$dbname";
if ($user ne "") {
if ($passwd eq "") {
return 0;
}
$connect_string = "$connect_string user=$user password=$passwd ".
"authtype=password";
}
$PG_CONN = PQconnectdb($connect_string);
if (PQstatus($PG_CONN)) {
print STDERR "Couldn't make connection with database!\n";
print STDERR PQerrorMessage($PG_CONN), "\n";
return 0;
}
return 1;
}
sub quit_prog {
close(OUT);
unlink $opt_f;
if (defined($PG_CONN)) {
PQfinish($PG_CONN);
}
exit 1;
}
sub get_username {
print "Username: ";
chop($n = <STDIN>);
return $n;;
}
sub get_password {
print "Password: ";
system("stty -echo < /dev/tty");
chop($pwd = <STDIN>);
print "\n";
system("stty echo < /dev/tty");
return $pwd;
}
sub main {
getopts('d:t:c:f:u');
if (!$opt_d || !$opt_t || !$opt_c || !$opt_f) {
print STDERR "usage: $0 [-u] -d database -t table -c column[,column...] ".
"-f output-file\n";
return 1;
}
@cols = split(/,/, $opt_c);
if (defined($opt_u)) {
$uname = get_username();
$pwd = get_password();
} else {
$uname = "";
$pwd = "";
}
$SIG{'INT'} = 'quit_prog';
if (!connect_db($opt_d, $uname, $pwd)) {
print STDERR "Connecting to database failed!\n";
return 1;
}
if (!open(OUT, ">$opt_f")) {
print STDERR "Couldnt' open file '$opt_f' for output!\n";
return 1;
}
PQexec($PG_CONN, "begin");
$query = "declare C cursor for select (\"";
$query .= join("\" || ' ' || \"", @cols);
$query .= "\") as string, oid from $opt_t";
$res = PQexec($PG_CONN, $query);
if (!$res || (PQresultStatus($res) != $PGRES_COMMAND_OK)) {
print STDERR "Error declaring cursor!\n";
print STDERR PQerrorMessage($PG_CONN), "\n";
PQfinish($PG_CONN);
return 1;
}
PQclear($res);
$query = "fetch in C";
while (($res = PQexec($PG_CONN, $query)) &&
(PQresultStatus($res) == $PGRES_TUPLES_OK) &&
(PQntuples($res) == 1)) {
$col = PQgetvalue($res, 0, 0);
$oid = PQgetvalue($res, 0, 1);
@subs = break_up($col);
foreach $i (@subs) {
print OUT "$i\t$oid\n";
}
}
if (!$res || (PQresultStatus($res) != PGRES_TUPLES_OK)) {
print STDERR "Error retrieving data from backend!\n";
print STDERR PQerrorMEssage($PG_CONN), "\n";
PQfinish($PG_CONN);
return 1;
}
PQclear($res);
PQfinish($PG_CONN);
return 0;
}
exit main();

View File

@ -1,3 +0,0 @@
create function fti() returns opaque as
'MODULE_PATHNAME'
language 'C';

View File

@ -1,350 +0,0 @@
#!/bin/sh
PATH=${PATH}:/usr/local/pgsql/bin
TIMEFORMAT="%3Uu %3Ss %lR %P%%"
export PATH TIMEFORMAT
case "$1" in
-n)
trashing=0
;;
*)
trashing=1
;;
esac
echo "TESTING ON UNCLUSTERED FTI"
# trash disk
if [ $trashing = 1 ]
then
echo "trashing"
psql -q -n -o /dev/null -c "select count(*) from product;" test
else
echo
fi
Q="select count(p.oid) from product p, artist_fti f1, artist_fti f2
where
f1.string ~ '^lapton' and f2.string ~ '^ric' and
f1.id=p.oid and f2.id=p.oid;"
echo -n "1: ^lapton and ^ric : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "2: ^lapton and ^ric : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "3: ^lapton and ^ric : "
time psql -q -n -o /dev/null -c "$Q" test
# trash disk
if [ $trashing = 1 ]
then
echo "trashing"
psql -q -n -o /dev/null -c "select count(*) from product;" test
else
echo
fi
Q="select count(p.oid) from product p, artist_fti f1, artist_fti f2
where
f1.string ~ '^lling' and f2.string ~ '^tones' and
f1.id=p.oid and f2.id=p.oid;"
echo -n "1: ^lling and ^tones : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "2: ^lling and ^tones : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "3: ^lling and ^tones : "
time psql -q -n -o /dev/null -c "$Q" test
# trash disk
if [ $trashing = 1 ]
then
echo "trashing"
psql -q -n -o /dev/null -c "select count(*) from product;" test
else
echo
fi
Q="select count(p.oid) from product p, artist_fti f1, artist_fti f2
where
f1.string ~ '^aughan' and f2.string ~ '^evie' and
f1.id=p.oid and f2.id=p.oid;"
echo -n "1: ^aughan and ^evie : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "2: ^aughan and ^evie : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "3: ^aughan and ^evie : "
time psql -q -n -o /dev/null -c "$Q" test
# trash disk
if [ $trashing = 1 ]
then
echo "trashing"
psql -q -n -o /dev/null -c "select count(*) from product;" test
else
echo
fi
Q="select count(p.oid) from product p, artist_fti f1
where
f1.string ~ '^lling' and
p.oid=f1.id;"
echo -n "1: ^lling : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "2: ^lling : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "3: ^lling : "
time psql -q -n -o /dev/null -c "$Q" test
# trash disk
if [ $trashing = 1 ]
then
echo "trashing"
psql -q -n -o /dev/null -c "select count(*) from product;" test
else
echo
fi
Q="select count(p.oid) from product p, artist_fti f1, artist_fti f2, artist_fti f3
where
f1.string ~ '^stev' and
f2.string ~ '^ray' and
f3.string ~ '^vaugh' and
p.oid=f1.id and p.oid=f2.id and p.oid=f3.id;"
echo -n "1: ^stev and ^ray and ^vaugh : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "2: ^stev and ^ray and ^vaugh : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "3: ^stev and ^ray and ^vaugh : "
time psql -q -n -o /dev/null -c "$Q" test
# trash disk
if [ $trashing = 1 ]
then
echo "trashing"
psql -q -n -o /dev/null -c "select count(*) from product;" test
else
echo
fi
Q="select count(*) from artist_fti where string ~ '^lling';"
echo -n "1: ^lling (no join) : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "2: ^lling (no join) : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "3: ^lling (no join) : "
time psql -q -n -o /dev/null -c "$Q" test
# trash disk
if [ $trashing = 1 ]
then
echo "trashing"
psql -q -n -o /dev/null -c "select count(*) from product;" test
else
echo
fi
Q="select count(*) from artist_fti where string ~ '^vaughan';"
echo -n "1: ^vaughan (no join) : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "2: ^vaughan (no join) : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "3: ^vaughan (no join) : "
time psql -q -n -o /dev/null -c "$Q" test
# trash disk
if [ $trashing = 1 ]
then
echo "trashing"
psql -q -n -o /dev/null -c "select count(*) from product;" test
else
echo
fi
Q="select count(*) from artist_fti where string ~ '^rol';"
echo -n "1: ^rol (no join) : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "2: ^rol (no join) : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "3: ^rol (no join) : "
time psql -q -n -o /dev/null -c "$Q" test
echo
echo "TESTING ON CLUSTERED FTI"
# trash disk
if [ $trashing = 1 ]
then
echo "trashing"
psql -q -n -o /dev/null -c "select count(*) from product;" test
else
echo
fi
Q="select count(p.oid) from product p, clustered f1, clustered f2
where
f1.string ~ '^lapton' and f2.string ~ '^ric' and
f1.id=p.oid and f2.id=p.oid;"
echo -n "1: ^lapton and ^ric : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "2: ^lapton and ^ric : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "3: ^lapton and ^ric : "
time psql -q -n -o /dev/null -c "$Q" test
# trash disk
if [ $trashing = 1 ]
then
echo "trashing"
psql -q -n -o /dev/null -c "select count(*) from product;" test
else
echo
fi
Q="select count(p.oid) from product p, clustered f1, clustered f2
where
f1.string ~ '^lling' and f2.string ~ '^tones' and
f1.id=p.oid and f2.id=p.oid;"
echo -n "1: ^lling and ^tones : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "2: ^lling and ^tones : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "3: ^lling and ^tones : "
time psql -q -n -o /dev/null -c "$Q" test
# trash disk
if [ $trashing = 1 ]
then
echo "trashing"
psql -q -n -o /dev/null -c "select count(*) from product;" test
else
echo
fi
Q="select count(p.oid) from product p, clustered f1, clustered f2
where
f1.string ~ '^aughan' and f2.string ~ '^evie' and
f1.id=p.oid and f2.id=p.oid;"
echo -n "1: ^aughan and ^evie : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "2: ^aughan and ^evie : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "3: ^aughan and ^evie : "
time psql -q -n -o /dev/null -c "$Q" test
# trash disk
if [ $trashing = 1 ]
then
echo "trashing"
psql -q -n -o /dev/null -c "select count(*) from product;" test
else
echo
fi
Q="select count(p.oid) from product p, clustered f1
where
f1.string ~ '^lling' and
p.oid=f1.id;"
echo -n "1: ^lling : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "2: ^lling : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "3: ^lling : "
time psql -q -n -o /dev/null -c "$Q" test
# trash disk
if [ $trashing = 1 ]
then
echo "trashing"
psql -q -n -o /dev/null -c "select count(*) from product;" test
else
echo
fi
Q="select count(p.oid) from product p, clustered f1, clustered f2, clustered f3
where
f1.string ~ '^stev' and
f2.string ~ '^ray' and
f3.string ~ '^vaugh' and
p.oid=f1.id and p.oid=f2.id and p.oid=f3.id;"
echo -n "1: ^stev and ^ray and ^vaugh : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "2: ^stev and ^ray and ^vaugh : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "3: ^stev and ^ray and ^vaugh : "
time psql -q -n -o /dev/null -c "$Q" test
# trash disk
if [ $trashing = 1 ]
then
echo "trashing"
psql -q -n -o /dev/null -c "select count(*) from product;" test
else
echo
fi
Q="select count(*) from clustered where string ~ '^lling';"
echo -n "1: ^lling (no join) : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "2: ^lling (no join) : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "3: ^lling (no join) : "
time psql -q -n -o /dev/null -c "$Q" test
# trash disk
if [ $trashing = 1 ]
then
echo "trashing"
psql -q -n -o /dev/null -c "select count(*) from product;" test
else
echo
fi
Q="select count(*) from clustered where string ~ '^vaughan';"
echo -n "1: ^vaughan (no join) : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "2: ^vaughan (no join) : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "3: ^vaughan (no join) : "
time psql -q -n -o /dev/null -c "$Q" test
# trash disk
if [ $trashing = 1 ]
then
echo "trashing"
psql -q -n -o /dev/null -c "select count(*) from product;" test
else
echo
fi
Q="select count(*) from clustered where string ~ '^rol';"
echo -n "1: ^rol (no join) : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "2: ^rol (no join) : "
time psql -q -n -o /dev/null -c "$Q" test
echo -n "3: ^rol (no join) : "
time psql -q -n -o /dev/null -c "$Q" test

View File

@ -1,11 +0,0 @@
# $Header: /cvsroot/pgsql/contrib/fuzzystrmatch/Makefile,v 1.2 2001/09/06 10:49:29 petere Exp $
subdir = contrib/fuzzystrmatch
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
MODULES = fuzzystrmatch
DATA_built = fuzzystrmatch.sql
DOCS = README.fuzzystrmatch README.soundex
include $(top_srcdir)/contrib/contrib-global.mk

View File

@ -1,129 +0,0 @@
/*
* fuzzystrmatch.c
*
* Functions for "fuzzy" comparison of strings
*
* Copyright (c) Joseph Conway <joseph.conway@home.com>, 2001;
*
* levenshtein()
* -------------
* Written based on a description of the algorithm by Michael Gilleland
* found at http://www.merriampark.com/ld.htm
* Also looked at levenshtein.c in the PHP 4.0.6 distribution for
* inspiration.
*
* metaphone()
* -----------
* Modified for PostgreSQL by Joe Conway.
* Based on CPAN's "Text-Metaphone-1.96" by Michael G Schwern <schwern@pobox.com>
* Code slightly modified for use as PostgreSQL function (palloc, elog, etc).
* Metaphone was originally created by Lawrence Philips and presented in article
* in "Computer Language" December 1990 issue.
*
* soundex()
* -----------
* Folded existing soundex contrib into this one. Renamed text_soundex() (C function)
* to soundex() for consistency.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without a written agreement
* is hereby granted, provided that the above copyright notice and this
* paragraph and the following two paragraphs appear in all copies.
*
* IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
* LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
* DOCUMENTATION, EVEN IF THE AUTHOR OR DISTRIBUTORS HAVE BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAS NO OBLIGATIONS TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
Version 0.2 (7 August, 2001):
Functions to calculate the degree to which two strings match in a "fuzzy" way
Tested under Linux (Red Hat 6.2 and 7.0) and PostgreSQL 7.2devel
Release Notes:
Version 0.2
- folded soundex contrib into this one
Version 0.1
- initial release
Installation:
Place these files in a directory called 'fuzzystrmatch' under 'contrib' in the PostgreSQL source tree. Then run:
make
make install
You can use fuzzystrmatch.sql to create the functions in your database of choice, e.g.
psql -U postgres template1 < fuzzystrmatch.sql
installs following functions into database template1:
levenshtein() - calculates the levenshtein distance between two strings
metaphone() - calculates the metaphone code of an input string
Documentation
==================================================================
Name
levenshtein -- calculates the levenshtein distance between two strings
Synopsis
levenshtein(text source, text target)
Inputs
source
any text string, 255 characters max, NOT NULL
target
any text string, 255 characters max, NOT NULL
Outputs
Returns int
Example usage
select levenshtein('GUMBO','GAMBOL');
==================================================================
Name
metaphone -- calculates the metaphone code of an input string
Synopsis
metaphone(text source, int max_output_length)
Inputs
source
any text string, 255 characters max, NOT NULL
max_output_length
maximum length of the output metaphone code; if longer, the output
is truncated to this length
Outputs
Returns text
Example usage
select metaphone('GUMBO',4);
==================================================================
-- Joe Conway

View File

@ -1,62 +0,0 @@
NOTE: Modified August 07, 2001 by Joe Conway. Updated for accuracy
after combining soundex code into the fuzzystrmatch contrib
---------------------------------------------------------------------
The Soundex system is a method of matching similar sounding names
(or any words) to the same code. It was initially used by the
United States Census in 1880, 1900, and 1910, but it has little use
beyond English names (or the English pronunciation of names), and
it is not a linguistic tool.
The following are some usage examples:
SELECT soundex('hello world!');
CREATE TABLE s (nm text)\g
insert into s values ('john')\g
insert into s values ('joan')\g
insert into s values ('wobbly')\g
select * from s
where soundex(nm) = soundex('john')\g
select nm from s a, s b
where soundex(a.nm) = soundex(b.nm)
and a.oid <> b.oid\g
CREATE FUNCTION text_sx_eq(text, text) RETURNS bool AS
'select soundex($1) = soundex($2)'
LANGUAGE 'sql'\g
CREATE FUNCTION text_sx_lt(text,text) RETURNS bool AS
'select soundex($1) < soundex($2)'
LANGUAGE 'sql'\g
CREATE FUNCTION text_sx_gt(text,text) RETURNS bool AS
'select soundex($1) > soundex($2)'
LANGUAGE 'sql';
CREATE FUNCTION text_sx_le(text,text) RETURNS bool AS
'select soundex($1) <= soundex($2)'
LANGUAGE 'sql';
CREATE FUNCTION text_sx_ge(text,text) RETURNS bool AS
'select soundex($1) >= soundex($2)'
LANGUAGE 'sql';
CREATE FUNCTION text_sx_ne(text,text) RETURNS bool AS
'select soundex($1) <> soundex($2)'
LANGUAGE 'sql';
DROP OPERATOR #= (text,text)\g
CREATE OPERATOR #= (leftarg=text, rightarg=text, procedure=text_sx_eq,
commutator=text_sx_eq)\g
SELECT *
FROM s
WHERE text_sx_eq(nm,'john')\g
SELECT *
from s
where s.nm #= 'john';

View File

@ -1,731 +0,0 @@
/*
* fuzzystrmatch.c
*
* Functions for "fuzzy" comparison of strings
*
* Copyright (c) Joseph Conway <joseph.conway@home.com>, 2001;
*
* levenshtein()
* -------------
* Written based on a description of the algorithm by Michael Gilleland
* found at http://www.merriampark.com/ld.htm
* Also looked at levenshtein.c in the PHP 4.0.6 distribution for
* inspiration.
*
* metaphone()
* -----------
* Modified for PostgreSQL by Joe Conway.
* Based on CPAN's "Text-Metaphone-1.96" by Michael G Schwern <schwern@pobox.com>
* Code slightly modified for use as PostgreSQL function (palloc, elog, etc).
* Metaphone was originally created by Lawrence Philips and presented in article
* in "Computer Language" December 1990 issue.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without a written agreement
* is hereby granted, provided that the above copyright notice and this
* paragraph and the following two paragraphs appear in all copies.
*
* IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
* LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
* DOCUMENTATION, EVEN IF THE AUTHOR OR DISTRIBUTORS HAVE BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAS NO OBLIGATIONS TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
#include "fuzzystrmatch.h"
/*
* Calculates Levenshtein Distance between two strings.
* Uses simplest and fastest cost model only, i.e. assumes a cost of 1 for
* each deletion, substitution, or insertion.
*/
PG_FUNCTION_INFO_V1(levenshtein);
Datum
levenshtein(PG_FUNCTION_ARGS)
{
char *str_s;
char *str_s0;
char *str_t;
int cols = 0;
int rows = 0;
int *u_cells;
int *l_cells;
int *tmp;
int i;
int j;
/*
* Fetch the arguments. str_s is referred to as the "source" cols =
* length of source + 1 to allow for the initialization column str_t
* is referred to as the "target", rows = length of target + 1 rows =
* length of target + 1 to allow for the initialization row
*/
str_s = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0))));
str_t = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(1))));
cols = strlen(str_s) + 1;
rows = strlen(str_t) + 1;
/*
* Restrict the length of the strings being compared to something
* reasonable because we will have to perform rows * cols
* calcualtions. If longer strings need to be compared, increase
* MAX_LEVENSHTEIN_STRLEN to suit (but within your tolerance for speed
* and memory usage).
*/
if ((cols > MAX_LEVENSHTEIN_STRLEN + 1) || (rows > MAX_LEVENSHTEIN_STRLEN + 1))
elog(ERROR, "levenshtein: Arguments may not exceed %d characters in length", MAX_LEVENSHTEIN_STRLEN);
/*
* If either rows or cols is 0, the answer is the other value. This
* makes sense since it would take that many insertions the build a
* matching string
*/
if (cols == 0)
PG_RETURN_INT32(rows);
if (rows == 0)
PG_RETURN_INT32(cols);
/*
* Allocate two vectors of integers. One will be used for the "upper"
* row, the other for the "lower" row. Initialize the "upper" row to
* 0..cols
*/
u_cells = palloc(sizeof(int) * cols);
for (i = 0; i < cols; i++)
u_cells[i] = i;
l_cells = palloc(sizeof(int) * cols);
/*
* Use str_s0 to "rewind" the pointer to str_s in the nested for loop
* below
*/
str_s0 = str_s;
/*
* Loop throught the rows, starting at row 1. Row 0 is used for the
* initial "upper" row.
*/
for (j = 1; j < rows; j++)
{
/*
* We'll always start with col 1, and initialize lower row col 0
* to j
*/
l_cells[0] = j;
for (i = 1; i < cols; i++)
{
int c = 0;
int c1 = 0;
int c2 = 0;
int c3 = 0;
/*
* The "cost" value is 0 if the character at the current col
* position in the source string, matches the character at the
* current row position in the target string; cost is 1
* otherwise.
*/
c = ((CHAREQ(str_s, str_t)) ? 0 : 1);
/*
* c1 is upper right cell plus 1
*/
c1 = u_cells[i] + 1;
/*
* c2 is lower left cell plus 1
*/
c2 = l_cells[i - 1] + 1;
/*
* c3 is cell diagonally above to the left plus "cost"
*/
c3 = u_cells[i - 1] + c;
/*
* The lower right cell is set to the minimum of c1, c2, c3
*/
l_cells[i] = (c1 < c2 ? c1 : c2) < c3 ? (c1 < c2 ? c1 : c2) : c3;
/*
* Increment the pointer to str_s
*/
NextChar(str_s);
}
/*
* Lower row now becomes the upper row, and the upper row gets
* reused as the new lower row.
*/
tmp = u_cells;
u_cells = l_cells;
l_cells = tmp;
/*
* Increment the pointer to str_t
*/
NextChar(str_t);
/*
* Rewind the pointer to str_s
*/
str_s = str_s0;
}
/*
* Because the final value (at position row, col) was swapped from the
* lower row to the upper row, that's where we'll find it.
*/
PG_RETURN_INT32(u_cells[cols - 1]);
}
/*
* Calculates the metaphone of an input string.
* Returns number of characters requested
* (suggested value is 4)
*/
PG_FUNCTION_INFO_V1(metaphone);
Datum
metaphone(PG_FUNCTION_ARGS)
{
int reqlen;
char *str_i;
size_t str_i_len;
char *metaph;
text *result_text;
int retval;
str_i = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0))));
str_i_len = strlen(str_i);
if (str_i_len > MAX_METAPHONE_STRLEN)
elog(ERROR, "metaphone: Input string must not exceed %d characters", MAX_METAPHONE_STRLEN);
if (!(str_i_len > 0))
elog(ERROR, "metaphone: Input string length must be > 0");
reqlen = PG_GETARG_INT32(1);
if (reqlen > MAX_METAPHONE_STRLEN)
elog(ERROR, "metaphone: Requested Metaphone output length must not exceed %d characters", MAX_METAPHONE_STRLEN);
if (!(reqlen > 0))
elog(ERROR, "metaphone: Requested Metaphone output length must be > 0");
metaph = palloc(reqlen);
memset(metaph, '\0', reqlen);
retval = _metaphone(str_i, reqlen, &metaph);
if (retval == META_SUCCESS)
{
result_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(metaph)));
PG_RETURN_TEXT_P(result_text);
}
else
{
elog(ERROR, "metaphone: failure");
/*
* Keep the compiler quiet
*/
PG_RETURN_NULL();
}
}
/*
* Original code by Michael G Schwern starts here.
* Code slightly modified for use as PostgreSQL
* function (palloc, etc). Original includes
* are rolled into fuzzystrmatch.h
*------------------------------------------------------------------*/
/* I suppose I could have been using a character pointer instead of
* accesssing the array directly... */
/* Look at the next letter in the word */
#define Next_Letter (toupper((unsigned char) word[w_idx+1]))
/* Look at the current letter in the word */
#define Curr_Letter (toupper((unsigned char) word[w_idx]))
/* Go N letters back. */
#define Look_Back_Letter(n) \
(w_idx >= (n) ? toupper((unsigned char) word[w_idx-(n)]) : '\0')
/* Previous letter. I dunno, should this return null on failure? */
#define Prev_Letter (Look_Back_Letter(1))
/* Look two letters down. It makes sure you don't walk off the string. */
#define After_Next_Letter \
(Next_Letter != '\0' ? toupper((unsigned char) word[w_idx+2]) : '\0')
#define Look_Ahead_Letter(n) toupper((unsigned char) Lookahead(word+w_idx, n))
/* Allows us to safely look ahead an arbitrary # of letters */
/* I probably could have just used strlen... */
char
Lookahead(char *word, int how_far)
{
char letter_ahead = '\0'; /* null by default */
int idx;
for (idx = 0; word[idx] != '\0' && idx < how_far; idx++);
/* Edge forward in the string... */
letter_ahead = word[idx]; /* idx will be either == to how_far or at
* the end of the string */
return letter_ahead;
}
/* phonize one letter */
#define Phonize(c) do {(*phoned_word)[p_idx++] = c;} while (0)
/* Slap a null character on the end of the phoned word */
#define End_Phoned_Word do {(*phoned_word)[p_idx] = '\0';} while (0)
/* How long is the phoned word? */
#define Phone_Len (p_idx)
/* Note is a letter is a 'break' in the word */
#define Isbreak(c) (!isalpha((unsigned char) (c)))
int
_metaphone(
/* IN */
char *word,
int max_phonemes,
/* OUT */
char **phoned_word
)
{
int w_idx = 0; /* point in the phonization we're at. */
int p_idx = 0; /* end of the phoned phrase */
/*-- Parameter checks --*/
/*
* Shouldn't be necessary, but left these here anyway jec Aug 3, 2001
*/
/* Negative phoneme length is meaningless */
if (!(max_phonemes > 0))
elog(ERROR, "metaphone: Requested output length must be > 0");
/* Empty/null string is meaningless */
if ((word == NULL) || !(strlen(word) > 0))
elog(ERROR, "metaphone: Input string length must be > 0");
/*-- Allocate memory for our phoned_phrase --*/
if (max_phonemes == 0)
{ /* Assume largest possible */
*phoned_word = palloc(sizeof(char) * strlen(word) +1);
if (!*phoned_word)
return META_ERROR;
}
else
{
*phoned_word = palloc(sizeof(char) * max_phonemes + 1);
if (!*phoned_word)
return META_ERROR;
}
/*-- The first phoneme has to be processed specially. --*/
/* Find our first letter */
for (; !isalpha((unsigned char) (Curr_Letter)); w_idx++)
{
/* On the off chance we were given nothing but crap... */
if (Curr_Letter == '\0')
{
End_Phoned_Word;
return META_SUCCESS; /* For testing */
}
}
switch (Curr_Letter)
{
/* AE becomes E */
case 'A':
if (Next_Letter == 'E')
{
Phonize('E');
w_idx += 2;
}
/* Remember, preserve vowels at the beginning */
else
{
Phonize('A');
w_idx++;
}
break;
/* [GKP]N becomes N */
case 'G':
case 'K':
case 'P':
if (Next_Letter == 'N')
{
Phonize('N');
w_idx += 2;
}
break;
/*
* WH becomes H, WR becomes R W if followed by a vowel
*/
case 'W':
if (Next_Letter == 'H' ||
Next_Letter == 'R')
{
Phonize(Next_Letter);
w_idx += 2;
}
else if (isvowel(Next_Letter))
{
Phonize('W');
w_idx += 2;
}
/* else ignore */
break;
/* X becomes S */
case 'X':
Phonize('S');
w_idx++;
break;
/* Vowels are kept */
/*
* We did A already case 'A': case 'a':
*/
case 'E':
case 'I':
case 'O':
case 'U':
Phonize(Curr_Letter);
w_idx++;
break;
default:
/* do nothing */
break;
}
/* On to the metaphoning */
for (; Curr_Letter != '\0' &&
(max_phonemes == 0 || Phone_Len < max_phonemes);
w_idx++)
{
/*
* How many letters to skip because an eariler encoding handled
* multiple letters
*/
unsigned short int skip_letter = 0;
/*
* THOUGHT: It would be nice if, rather than having things
* like... well, SCI. For SCI you encode the S, then have to
* remember to skip the C. So the phonome SCI invades both S and
* C. It would be better, IMHO, to skip the C from the S part of
* the encoding. Hell, I'm trying it.
*/
/* Ignore non-alphas */
if (!isalpha((unsigned char) (Curr_Letter)))
continue;
/* Drop duplicates, except CC */
if (Curr_Letter == Prev_Letter &&
Curr_Letter != 'C')
continue;
switch (Curr_Letter)
{
/* B -> B unless in MB */
case 'B':
if (Prev_Letter != 'M')
Phonize('B');
break;
/*
* 'sh' if -CIA- or -CH, but not SCH, except SCHW. (SCHW
* is handled in S) S if -CI-, -CE- or -CY- dropped if
* -SCI-, SCE-, -SCY- (handed in S) else K
*/
case 'C':
if (MAKESOFT(Next_Letter))
{ /* C[IEY] */
if (After_Next_Letter == 'A' &&
Next_Letter == 'I')
{ /* CIA */
Phonize(SH);
}
/* SC[IEY] */
else if (Prev_Letter == 'S')
{
/* Dropped */
}
else
Phonize('S');
}
else if (Next_Letter == 'H')
{
#ifndef USE_TRADITIONAL_METAPHONE
if (After_Next_Letter == 'R' ||
Prev_Letter == 'S')
{ /* Christ, School */
Phonize('K');
}
else
Phonize(SH);
#else
Phonize(SH);
#endif
skip_letter++;
}
else
Phonize('K');
break;
/*
* J if in -DGE-, -DGI- or -DGY- else T
*/
case 'D':
if (Next_Letter == 'G' &&
MAKESOFT(After_Next_Letter))
{
Phonize('J');
skip_letter++;
}
else
Phonize('T');
break;
/*
* F if in -GH and not B--GH, D--GH, -H--GH, -H---GH else
* dropped if -GNED, -GN, else dropped if -DGE-, -DGI- or
* -DGY- (handled in D) else J if in -GE-, -GI, -GY and
* not GG else K
*/
case 'G':
if (Next_Letter == 'H')
{
if (!(NOGHTOF(Look_Back_Letter(3)) ||
Look_Back_Letter(4) == 'H'))
{
Phonize('F');
skip_letter++;
}
else
{
/* silent */
}
}
else if (Next_Letter == 'N')
{
if (Isbreak(After_Next_Letter) ||
(After_Next_Letter == 'E' &&
Look_Ahead_Letter(3) == 'D'))
{
/* dropped */
}
else
Phonize('K');
}
else if (MAKESOFT(Next_Letter) &&
Prev_Letter != 'G')
Phonize('J');
else
Phonize('K');
break;
/* H if before a vowel and not after C,G,P,S,T */
case 'H':
if (isvowel(Next_Letter) &&
!AFFECTH(Prev_Letter))
Phonize('H');
break;
/*
* dropped if after C else K
*/
case 'K':
if (Prev_Letter != 'C')
Phonize('K');
break;
/*
* F if before H else P
*/
case 'P':
if (Next_Letter == 'H')
Phonize('F');
else
Phonize('P');
break;
/*
* K
*/
case 'Q':
Phonize('K');
break;
/*
* 'sh' in -SH-, -SIO- or -SIA- or -SCHW- else S
*/
case 'S':
if (Next_Letter == 'I' &&
(After_Next_Letter == 'O' ||
After_Next_Letter == 'A'))
Phonize(SH);
else if (Next_Letter == 'H')
{
Phonize(SH);
skip_letter++;
}
#ifndef USE_TRADITIONAL_METAPHONE
else if (Next_Letter == 'C' &&
Look_Ahead_Letter(2) == 'H' &&
Look_Ahead_Letter(3) == 'W')
{
Phonize(SH);
skip_letter += 2;
}
#endif
else
Phonize('S');
break;
/*
* 'sh' in -TIA- or -TIO- else 'th' before H else T
*/
case 'T':
if (Next_Letter == 'I' &&
(After_Next_Letter == 'O' ||
After_Next_Letter == 'A'))
Phonize(SH);
else if (Next_Letter == 'H')
{
Phonize(TH);
skip_letter++;
}
else
Phonize('T');
break;
/* F */
case 'V':
Phonize('F');
break;
/* W before a vowel, else dropped */
case 'W':
if (isvowel(Next_Letter))
Phonize('W');
break;
/* KS */
case 'X':
Phonize('K');
Phonize('S');
break;
/* Y if followed by a vowel */
case 'Y':
if (isvowel(Next_Letter))
Phonize('Y');
break;
/* S */
case 'Z':
Phonize('S');
break;
/* No transformation */
case 'F':
case 'J':
case 'L':
case 'M':
case 'N':
case 'R':
Phonize(Curr_Letter);
break;
default:
/* nothing */
break;
} /* END SWITCH */
w_idx += skip_letter;
} /* END FOR */
End_Phoned_Word;
return (META_SUCCESS);
} /* END metaphone */
/*
* SQL function: soundex(text) returns text
*/
PG_FUNCTION_INFO_V1(soundex);
Datum
soundex(PG_FUNCTION_ARGS)
{
char outstr[SOUNDEX_LEN + 1];
char *arg;
arg = _textout(PG_GETARG_TEXT_P(0));
_soundex(arg, outstr);
PG_RETURN_TEXT_P(_textin(outstr));
}
static void
_soundex(const char *instr, char *outstr)
{
int count;
AssertArg(instr);
AssertArg(outstr);
outstr[SOUNDEX_LEN] = '\0';
/* Skip leading non-alphabetic characters */
while (!isalpha((unsigned char) instr[0]) && instr[0])
++instr;
/* No string left */
if (!instr[0])
{
outstr[0] = (char) 0;
return;
}
/* Take the first letter as is */
*outstr++ = (char) toupper((unsigned char) *instr++);
count = 1;
while (*instr && count < SOUNDEX_LEN)
{
if (isalpha((unsigned char) *instr) &&
soundex_code(*instr) != soundex_code(*(instr - 1)))
{
*outstr = soundex_code(instr[0]);
if (*outstr != '0')
{
++outstr;
++count;
}
}
++instr;
}
/* Fill with 0's */
while (count < SOUNDEX_LEN)
{
*outstr = '0';
++outstr;
++count;
}
}

View File

@ -1,172 +0,0 @@
/*
* fuzzystrmatch.h
*
* Functions for "fuzzy" comparison of strings
*
* Copyright (c) Joseph Conway <joseph.conway@home.com>, 2001;
*
* levenshtein()
* -------------
* Written based on a description of the algorithm by Michael Gilleland
* found at http://www.merriampark.com/ld.htm
* Also looked at levenshtein.c in the PHP 4.0.6 distribution for
* inspiration.
*
* metaphone()
* -----------
* Modified for PostgreSQL by Joe Conway.
* Based on CPAN's "Text-Metaphone-1.96" by Michael G Schwern <schwern@pobox.com>
* Code slightly modified for use as PostgreSQL function (palloc, elog, etc).
* Metaphone was originally created by Lawrence Philips and presented in article
* in "Computer Language" December 1990 issue.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without a written agreement
* is hereby granted, provided that the above copyright notice and this
* paragraph and the following two paragraphs appear in all copies.
*
* IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
* LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
* DOCUMENTATION, EVEN IF THE AUTHOR OR DISTRIBUTORS HAVE BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE AUTHOR AND DISTRIBUTORS HAS NO OBLIGATIONS TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
#ifndef FUZZYSTRMATCH_H
#define FUZZYSTRMATCH_H
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "postgres.h"
#include "fmgr.h"
#include "utils/builtins.h"
/*
* External declarations
*/
extern Datum levenshtein(PG_FUNCTION_ARGS);
extern Datum metaphone(PG_FUNCTION_ARGS);
extern Datum soundex(PG_FUNCTION_ARGS);
/*
* Soundex
*/
static void _soundex(const char *instr, char *outstr);
#define SOUNDEX_LEN 4
#define _textin(str) DirectFunctionCall1(textin, CStringGetDatum(str))
#define _textout(str) DatumGetPointer(DirectFunctionCall1(textout, PointerGetDatum(str)))
/* ABCDEFGHIJKLMNOPQRSTUVWXYZ */
static const char *soundex_table = "01230120022455012623010202";
#define soundex_code(letter) soundex_table[toupper((unsigned char) (letter)) - 'A']
/*
* Levenshtein
*/
#define STRLEN(p) strlen(p)
#define CHAREQ(p1, p2) (*(p1) == *(p2))
#define NextChar(p) ((p)++)
#define MAX_LEVENSHTEIN_STRLEN 255
/*
* Metaphone
*/
#define MAX_METAPHONE_STRLEN 255
/*
* Original code by Michael G Schwern starts here.
* Code slightly modified for use as PostgreSQL
* function (combined *.h into here).
*------------------------------------------------------------------*/
/**************************************************************************
metaphone -- Breaks english phrases down into their phonemes.
Input
word -- An english word to be phonized
max_phonemes -- How many phonemes to calculate. If 0, then it
will phonize the entire phrase.
phoned_word -- The final phonized word. (We'll allocate the
memory.)
Output
error -- A simple error flag, returns TRUE or FALSE
NOTES: ALL non-alpha characters are ignored, this includes whitespace,
although non-alpha characters will break up phonemes.
****************************************************************************/
/**************************************************************************
my constants -- constants I like
Probably redundant.
***************************************************************************/
#define META_ERROR FALSE
#define META_SUCCESS TRUE
#define META_FAILURE FALSE
/* I add modifications to the traditional metaphone algorithm that you
might find in books. Define this if you want metaphone to behave
traditionally */
#undef USE_TRADITIONAL_METAPHONE
/* Special encodings */
#define SH 'X'
#define TH '0'
char Lookahead(char *word, int how_far);
int
_metaphone(
/* IN */
char *word,
int max_phonemes,
/* OUT */
char **phoned_word
);
/* Metachar.h ... little bits about characters for metaphone */
/*-- Character encoding array & accessing macros --*/
/* Stolen directly out of the book... */
char _codes[26] = {
1, 16, 4, 16, 9, 2, 4, 16, 9, 2, 0, 2, 2, 2, 1, 4, 0, 2, 4, 4, 1, 0, 0, 0, 8, 0
/* a b c d e f g h i j k l m n o p q r s t u v w x y z */
};
#define ENCODE(c) (isalpha((unsigned char) (c)) ? _codes[((toupper((unsigned char) (c))) - 'A')] : 0)
#define isvowel(c) (ENCODE(c) & 1) /* AEIOU */
/* These letters are passed through unchanged */
#define NOCHANGE(c) (ENCODE(c) & 2) /* FJMNR */
/* These form dipthongs when preceding H */
#define AFFECTH(c) (ENCODE(c) & 4) /* CGPST */
/* These make C and G soft */
#define MAKESOFT(c) (ENCODE(c) & 8) /* EIY */
/* These prevent GH from becoming F */
#define NOGHTOF(c) (ENCODE(c) & 16) /* BDH */
#endif /* FUZZYSTRMATCH_H */

View File

@ -1,11 +0,0 @@
CREATE FUNCTION levenshtein (text,text) RETURNS int
AS 'MODULE_PATHNAME','levenshtein' LANGUAGE 'c' with (iscachable, isstrict);
CREATE FUNCTION metaphone (text,int) RETURNS text
AS 'MODULE_PATHNAME','metaphone' LANGUAGE 'c' with (iscachable, isstrict);
CREATE FUNCTION soundex(text) RETURNS text
AS 'MODULE_PATHNAME', 'soundex' LANGUAGE 'c' with (iscachable, isstrict);
CREATE FUNCTION text_soundex(text) RETURNS text
AS 'MODULE_PATHNAME', 'soundex' LANGUAGE 'c';

View File

@ -1,15 +0,0 @@
#############################################
# Makefile for integer aggregator
# Copyright (C) 2001 Digital Music Network.
# by Mark L. Woodward
# $Header: /cvsroot/pgsql/contrib/intagg/Makefile,v 1.3 2002/02/25 04:16:58 tgl Exp $
subdir = contrib/intagg
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
MODULES = int_aggregate
DATA_built = int_aggregate.sql
DOCS = README.int_aggregate
include $(top_srcdir)/contrib/contrib-global.mk

View File

@ -1,55 +0,0 @@
Integer aggregator/enumerator.
Many database systems have the notion of a one to many table.
A one to many table usually sits between two indexed tables,
as:
create table one_to_many(left int, right int) ;
And it is used like this:
SELECT right.* from right JOIN one_to_many ON (right.id = one_to_many.right)
WHERE one_to_many.left = item;
This will return all the items in the right hand table for an entry
in the left hand table. This is a very common construct in SQL.
Now, this methodology can be cumbersome with a very large number of
entries in the one_to_many table. Depending on the order in which
data was entered, a join like this could result in an index scan
and a fetch for each right hand entry in the table for a particular
left hand entry.
If you have a very dynamic system, there is not much you can do.
However, if you have some data which is fairly static, you can
create a summary table with the aggregator.
CREATE TABLE summary as SELECT left, int_array_aggregate(right)
AS right FROM one_to_many GROUP BY left;
This will create a table with one row per left item, and an array
of right items. Now this is pretty useless without some way of using
the array, thats why there is an array enumerator.
SELECT left, int_array_enum(right) FROM summary WHERE left = item;
The above query using int_array_enum, produces the same results as:
SELECT left, right FROM one_to_many WHERE left = item;
The difference is that the query against the summary table has to get
only one row from the table, where as the query against "one_to_many"
must index scan and fetch a row for each entry.
On our system, an EXPLAIN shows a query with a cost of 8488 gets reduced
to a cost of 329. The query is a join between the one_to_many table,
select right, count(right) from
(
select left, int_array_enum(right) as right from summary join
(select left from left_table where left = item) as lefts
ON (summary.left = lefts.left )
) as list group by right order by count desc ;

View File

@ -1,271 +0,0 @@
/*
* Integer array aggregator / enumerator
*
* Mark L. Woodward
* DMN Digital Music Network.
* www.dmn.com
*
* Copyright (C) Digital Music Network
* December 20, 2001
*
* This file is the property of the Digital Music Network (DMN).
* It is being made available to users of the PostgreSQL system
* under the BSD license.
*
*/
#include "postgres.h"
#include <ctype.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include "postgres.h"
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/indexing.h"
#include "catalog/pg_proc.h"
#include "executor/executor.h"
#include "utils/fcache.h"
#include "utils/sets.h"
#include "utils/syscache.h"
#include "access/tupmacs.h"
#include "access/xact.h"
#include "fmgr.h"
#include "miscadmin.h"
#include "utils/array.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
#include "utils/lsyscache.h"
/* This is actually a postgres version of a one dimentional array */
typedef struct agg
{
ArrayType a;
int items;
int lower;
int4 array[1];
}PGARRAY;
/* This is used to keep track of our position during enumeration */
typedef struct callContext
{
PGARRAY *p;
int num;
int flags;
}CTX;
#define TOASTED 1
#define START_NUM 8
#define PGARRAY_SIZE(n) (sizeof(PGARRAY) + ((n-1)*sizeof(int4)))
static PGARRAY * GetPGArray(int4 state, int fAdd);
static PGARRAY *ShrinkPGArray(PGARRAY *p);
Datum int_agg_state(PG_FUNCTION_ARGS);
Datum int_agg_final_count(PG_FUNCTION_ARGS);
Datum int_agg_final_array(PG_FUNCTION_ARGS);
Datum int_enum(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(int_agg_state);
PG_FUNCTION_INFO_V1(int_agg_final_count);
PG_FUNCTION_INFO_V1(int_agg_final_array);
PG_FUNCTION_INFO_V1(int_enum);
/*
* Manage the aggregation state of the array
* You need to specify the correct memory context, or it will vanish!
*/
static PGARRAY * GetPGArray(int4 state, int fAdd)
{
PGARRAY *p = (PGARRAY *) state;
if(!state)
{
/* New array */
int cb = PGARRAY_SIZE(START_NUM);
p = (PGARRAY *) MemoryContextAlloc(TopTransactionContext, cb);
if(!p)
{
elog(ERROR,"Integer aggregator, cant allocate TopTransactionContext memory");
return 0;
}
p->a.size = cb;
p->a.ndim= 0;
p->a.flags = 0;
p->items = 0;
p->lower= START_NUM;
}
else if(fAdd)
{ /* Ensure array has space */
if(p->items >= p->lower)
{
PGARRAY *pn;
int n = p->lower + p->lower;
int cbNew = PGARRAY_SIZE(n);
pn = (PGARRAY *) repalloc(p, cbNew);
if(!pn)
{ /* Realloc failed! Reallocate new block. */
pn = (PGARRAY *) MemoryContextAlloc(TopTransactionContext, cbNew);
if(!pn)
{
elog(ERROR, "Integer aggregator, REALLY REALLY can't alloc memory");
return (PGARRAY *) NULL;
}
memcpy(pn, p, p->a.size);
pfree(p);
}
pn->a.size = cbNew;
pn->lower = n;
return pn;
}
}
return p;
}
/* Shrinks the array to its actual size and moves it into the standard
* memory allocation context, frees working memory */
static PGARRAY *ShrinkPGArray(PGARRAY *p)
{
PGARRAY *pnew=NULL;
if(p)
{
/* get target size */
int cb = PGARRAY_SIZE(p->items);
/* use current transaction context */
pnew = palloc(cb);
if(pnew)
{
/* Fix up the fields in the new structure, so Postgres understands */
memcpy(pnew, p, cb);
pnew->a.size = cb;
pnew->a.ndim=1;
pnew->a.flags = 0;
pnew->lower = 0;
}
else
{
elog(ERROR, "Integer aggregator, can't allocate memory");
}
pfree(p);
}
return pnew;
}
/* Called for each iteration during an aggregate function */
Datum int_agg_state(PG_FUNCTION_ARGS)
{
int4 state = PG_GETARG_INT32(0);
int4 value = PG_GETARG_INT32(1);
PGARRAY *p = GetPGArray(state, 1);
if(!p)
{
elog(ERROR,"No aggregate storage\n");
}
else if(p->items >= p->lower)
{
elog(ERROR,"aggregate storage too small\n");
}
else
{
p->array[p->items++]= value;
}
PG_RETURN_INT32(p);
}
/* This is the final function used for the integer aggregator. It returns all the integers
* collected as a one dimentional integer array */
Datum int_agg_final_array(PG_FUNCTION_ARGS)
{
PGARRAY *pnew = ShrinkPGArray(GetPGArray(PG_GETARG_INT32(0),0));
if(pnew)
{
PG_RETURN_POINTER(pnew);
}
else
{
PG_RETURN_NULL();
}
}
/* This function accepts an array, and returns one item for each entry in the array */
Datum int_enum(PG_FUNCTION_ARGS)
{
CTX *pc;
PGARRAY *p = (PGARRAY *) PG_GETARG_POINTER(0);
ReturnSetInfo *rsi = (ReturnSetInfo *)fcinfo->resultinfo;
if(!p)
{
elog(WARNING, "No data sent\n");
return 0;
}
if(!rsi)
{
elog(ERROR, "No ReturnSetInfo sent! function must be declared returning a 'setof' integer");
PG_RETURN_NULL();
}
if(!fcinfo->context)
{
/* Allocate a working context */
pc = (CTX *) palloc(sizeof(CTX));
if(!pc)
{
elog(ERROR, "CTX Alocation failed\n");
PG_RETURN_NULL();
}
/* Don't copy atribute if you don't need too */
if(VARATT_IS_EXTENDED(p) )
{
/* Toasted!!! */
pc->p = (PGARRAY *) PG_DETOAST_DATUM_COPY(p);
pc->flags = TOASTED;
if(!pc->p)
{
elog(ERROR, "Error in toaster!!! no detoasting\n");
PG_RETURN_NULL();
}
}
else
{
/* Untoasted */
pc->p = p;
pc->flags = 0;
}
fcinfo->context = (Node *) pc;
pc->num=0;
}
else /* use an existing one */
{
pc = (CTX *) fcinfo->context;
}
/* Are we done yet? */
if(pc->num >= pc->p->items)
{
/* We are done */
if(pc->flags & TOASTED)
pfree(pc->p);
pfree(fcinfo->context);
fcinfo->context = NULL;
rsi->isDone = ExprEndResult ;
}
else /* nope, return the next value */
{
int val = pc->p->array[pc->num++];
rsi->isDone = ExprMultipleResult;
PG_RETURN_INT32(val);
}
PG_RETURN_NULL();
}

View File

@ -1,40 +0,0 @@
-- Drop functions
drop function int_agg_state (int4, int4);
drop function int_agg_final_array (int4);
drop aggregate int_array_aggregate(int4);
drop function int_array_enum (int4[]);
-- Internal function for the aggregate
-- Is called for each item in an aggregation
create function int_agg_state (int4, int4)
returns int4
as 'MODULE_FILENAME','int_agg_state'
language 'c';
-- Internal function for the aggregate
-- Is called at the end of the aggregation, and returns an array.
create function int_agg_final_array (int4)
returns int4[]
as 'MODULE_FILENAME','int_agg_final_array'
language 'c';
-- The aggration funcion.
-- uses the above functions to create an array of integers from an aggregation.
create aggregate int_array_aggregate
(
BASETYPE = int4,
SFUNC = int_agg_state,
STYPE = int4,
FINALFUNC = int_agg_final_array,
INITCOND = 0
);
-- The enumeration function
-- returns each element in a one dimentional integer array
-- as a row.
create function int_array_enum(int4[])
returns setof integer
as 'MODULE_FILENAME','int_enum'
language 'c';

Some files were not shown because too many files have changed in this diff Show More