mirror of
https://github.com/zebrajr/postgres.git
synced 2025-12-07 00:20:24 +01:00
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:
parent
d84fe82230
commit
05dedace84
23
COPYRIGHT
23
COPYRIGHT
|
|
@ -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.
|
||||
127
GNUmakefile.in
127
GNUmakefile.in
|
|
@ -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
|
||||
871
INSTALL
871
INSTALL
|
|
@ -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
|
||||
36
Makefile
36
Makefile
|
|
@ -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
26
README
|
|
@ -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
13
aclocal.m4
vendored
|
|
@ -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])
|
||||
|
|
@ -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'])
|
||||
])
|
||||
|
|
@ -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
|
||||
|
|
@ -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
1308
config/config.guess
vendored
File diff suppressed because it is too large
Load Diff
1409
config/config.sub
vendored
1409
config/config.sub
vendored
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
119
config/libtool.m4
vendored
|
|
@ -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 ...
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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])])
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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)])])
|
||||
1266
configure.in
1266
configure.in
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
||||
205
contrib/README
205
contrib/README
|
|
@ -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>
|
||||
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
|
@ -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:
|
||||
*/
|
||||
|
|
@ -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:
|
||||
*/
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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)
|
||||
|
||||
|
|
@ -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';
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
--
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
1174
contrib/cube/cube.c
1174
contrib/cube/cube.c
File diff suppressed because it is too large
Load Diff
|
|
@ -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;
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
typedef struct NDBOX
|
||||
{
|
||||
unsigned int size; /* required to be a Postgres varlena type */
|
||||
unsigned int dim;
|
||||
float x[1];
|
||||
} NDBOX;
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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
|
|
@ -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)
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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.
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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 */
|
||||
|
|
@ -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);
|
||||
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -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
|
||||
|
|
@ -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)
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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%
|
||||
|
|
@ -1 +0,0 @@
|
|||
Place "stop" words in lookup table
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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();
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
create function fti() returns opaque as
|
||||
'MODULE_PATHNAME'
|
||||
language 'C';
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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';
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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';
|
||||
|
|
@ -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
|
||||
|
|
@ -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 ;
|
||||
|
||||
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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
Loading…
Reference in New Issue
Block a user