From: CVS to git conversion script Date: Thu, 20 Jun 2002 20:29:55 +0000 (+0000) Subject: This commit was manufactured by cvs2git to create branch 'ecpg_big_bison'. X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=05dedace84ef8c93fea5309c3ac55f889011429b;p=users%2Fkgrittn%2Fpostgres.git This commit was manufactured by cvs2git to create branch 'ecpg_big_bison'. Sprout from master 2002-06-20 20:29:54 UTC Bruce Momjian '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 --- diff --git a/COPYRIGHT b/COPYRIGHT deleted file mode 100644 index c93355e396..0000000000 --- a/COPYRIGHT +++ /dev/null @@ -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. diff --git a/GNUmakefile.in b/GNUmakefile.in deleted file mode 100644 index 56cb1e3574..0000000000 --- a/GNUmakefile.in +++ /dev/null @@ -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 diff --git a/HISTORY b/HISTORY deleted file mode 100644 index 2d267df499..0000000000 --- a/HISTORY +++ /dev/null @@ -1,3390 +0,0 @@ - Release Notes - - Release 7.2.1 - - Release date: 2002-03-21 - - This has a variety of fixes from 7.2. - - ---------------------------------------------------------------------- - -Migration to version 7.2.1 - - A dump/restore is *not* required for those running 7.2. - - ---------------------------------------------------------------------- - -Changes - - Ensure that sequence counters do not go backwards after a crash (Tom) - Fix pgaccess kanji-coversion key binding (Tatsuo) - Optimizer improvements (Tom) - cash I/O improvements (Tom) - New Russian FAQ - Compile fix for missing AuthBlockSig (Heiko) - Additional time zones and time zone fixes (Thomas) - Allow psql \connect to handle mixed case database and user names (Tom) - Return proper OID on command completion even with ON INSERT rules (Tom) - Allow COPY FROM to use 8-bit DELIMITERS (Tatsuo) - Fix bug in extract/date_part for milliseconds/microseconds (Tatsuo) - Improve handling of multiple UNIONs with different lengths (Tom) - contrib/btree_gist improvements (Teodor Sigaev) - contrib/tsearch dictionary improvements, see README.tsearch for - an additional installation step (Thomas T. Thai, Teodor Sigaev) - Fix for array subscripts handling (Tom) - Allow EXECUTE of "CREATE TABLE AS ... SELECT" in PL/PgSQL (Tom) - - - ---------------------------------------------------------------------- - - Release 7.2 - - Release date: 2002-02-04 - -Overview - - This release improves PostgreSQL for use in high-volume applications. - - Major changes in this release: - - VACUUM - - Vacuuming no longer locks tables, thus allowing normal user access - during the vacuum. A new "VACUUM FULL" command does old-style - vacuum by locking the table and shrinking the on-disk copy of the - table. - - Transactions - - There is no longer a problem with installations that exceed four - billion transactions. - - OID's - - OID's are now optional. Users can now create tables without OID's - for cases where OID usage is excessive. - - Optimizer - - The system now computes histogram column statistics during - "ANALYZE", allowing much better optimizer choices. - - Security - - A new MD5 encryption option allows more secure storage and - transfer of passwords. A new Unix-domain socket authentication - option is available on Linux and BSD systems. - - Statistics - - Administrators can use the new table access statistics module to - get fine-grained information about table and index usage. - - Internationalization - - Program and library messages can now be displayed in several - languages. - - ---------------------------------------------------------------------- - -Migration to version 7.2 - - A dump/restore using "pg_dump" is required for those wishing to migrate - data from any previous release. - - Observe the following incompatibilities: - - * The semantics of the "VACUUM" command have changed in this release. - You may wish to update your maintenance procedures accordingly. - - * In this release, comparisons using = NULL will always return false (or - NULL, more precisely). Previous releases automatically transformed - this syntax to IS NULL. The old behavior can be re-enabled using a - "postgresql.conf" parameter. - - * The "pg_hba.conf" and "pg_ident.conf" configuration is now only - reloaded after receiving a SIGHUP signal, not with each connection. - - * The function "octet_length()" now returns the uncompressed data - length. - - * The date/time value 'current' is no longer available. You will need to - rewrite your applications. - - * The timestamp() function is no longer available. Use timestamp - 'string' instead, or CAST. - - The SELECT ... LIMIT #,# syntax will be removed in the next release. You - should change your queries to use separate LIMIT and OFFSET clauses, e.g. - LIMIT 10 OFFSET 20. - - ---------------------------------------------------------------------- - -Changes - - Server Operation - - Create temporary files in a separate directory (Bruce) - Delete orphanded temporary files on postmaster startup (Bruce) - Added unique indexes to some system tables (Tom) - System table operator reorganization (Oleg Bartunov, Teodor Sigaev, Tom) - Renamed pg_log to pg_clog (Tom) - Enable SIGTERM, SIGQUIT to kill backends (Jan) - Removed compile-time limit on number of backends (Tom) - Better cleanup for semaphore resource failure (Tatsuo, Tom) - Allow safe transaction ID wraparound (Tom) - Removed OID's from some system tables (Tom) - Removed "triggered data change violation" error check (Tom) - SPI portal creation of prepared/saved plans (Jan) - Allow SPI column functions to work for system columns (Tom) - Long value compression improvement (Tom) - Statistics collector for table, index access (Jan) - Truncate extra-long sequence names to a reasonable value (Tom) - Measure transaction times in milliseconds (Thomas) - Fix TID sequential scans (Hiroshi) - Superuser ID now fixed at 1 (Peter E) - New pg_ctl "reload" option (Tom) - - ---------------------------------------------------------------------- - - Performance - - Optimizer improvements (Tom) - New histogram column statistics for optimizer (Tom) - Reuse write-ahead log files rather than discarding them (Tom) - Cache improvements (Tom) - IS NULL, IS NOT NULL optimizer improvement (Tom) - Improve lock manager to reduce lock contention (Tom) - Keep relcache entries for index access support functions (Tom) - Allow better selectivity with NaN and infinities in NUMERIC (Tom) - R-tree performance improvements (Kenneth Been) - B-tree splits more efficient (Tom) - - ---------------------------------------------------------------------- - - Privileges - - Change UPDATE, DELETE permissions to be distinct (Peter E) - New REFERENCES, TRIGGER privileges (Peter E) - Allow GRANT/REVOKE to/from more than one user at a time (Peter E) - New has_table_privilege() function (Joe Conway) - Allow non-superuser to vacuum database (Tom) - New SET SESSION AUTHORIZATION command (Peter E) - Fix bug in privilege modifications on newly created tables (Tom) - Disallow access to pg_statistic for non-superuser, add user-accessible views (Tom) - - ---------------------------------------------------------------------- - - Client Authentication - - Fork postmaster before doing authentication to prevent hangs (Peter E) - Add ident authentication over Unix domain sockets on Linux, *BSD (Helge Bahmann, Oliver Elphick, Teodor Sigaev, Bruce) - Add a password authentication method that uses MD5 encryption (Bruce) - Allow encryption of stored passwords using MD5 (Bruce) - PAM authentication (Dominic J. Eidson) - Load pg_hba.conf and pg_ident.conf only on startup and SIGHUP (Bruce) - - ---------------------------------------------------------------------- - - Server Configuration - - Interpretation of some time zone abbreviations as Australian rather than North American now settable at run time (Bruce) - New parameter to set default transaction isolation level (Peter E) - New parameter to enable conversion of "expr = NULL" into "expr IS NULL", off by default (Peter E) - New parameter to control memory usage by VACUUM (Tom) - New parameter to set client authentication timeout (Tom) - New parameter to set maximum number of open files (Tom) - - ---------------------------------------------------------------------- - - Queries - - Statements added by INSERT rules now execute after the INSERT (Jan) - Prevent unadorned relation names in target list (Bruce) - NULLs now sort after all normal values in ORDER BY (Tom) - New IS UNKNOWN, IS NOT UNKNOWN Boolean tests (Tom) - New SHARE UPDATE EXCLUSIVE lock mode (Tom) - New EXPLAIN ANALYZE command that shows run times and row counts (Martijn van Oosterhout) - Fix problem with LIMIT and subqueries (Tom) - Fix for LIMIT, DISTINCT ON pushed into subqueryies (Tom) - Fix nested EXCEPT/INTERSECT (Tom) - - ---------------------------------------------------------------------- - - Schema Manipulation - - Fix SERIAL in temporary tables (Bruce) - Allow temporary sequences (Bruce) - Sequences now use int8 internally (Tom) - New SERIAL8 creates int8 columns with sequences, default still SERIAL4 (Tom) - Make OIDs optional using WITHOUT OIDS (Tom) - Add %TYPE syntax to CREATE TYPE (Ian Lance Taylor) - Add ALTER TABLE / DROP CONSTRAINT for CHECK constraints (Christopher Kings-Lynne) - New CREATE OR REPLACE FUNCTION to alter existing function (preserving the function OID) (Gavin Sherry) - Add ALTER TABLE / ADD [ UNIQUE | PRIMARY ] (Christopher Kings-Lynne) - Allow column renaming in views - Make ALTER TABLE / RENAME COLUMN update column names of indexes (Brent Verner) - Fix for ALTER TABLE / ADD CONSTRAINT ... CHECK with inherited tables (Stephan Szabo) - ALTER TABLE RENAME update foreign-key trigger arguments correctly (Brent Verner) - DROP AGGREGATE and COMMENT ON AGGREGATE now accept an aggtype (Tom) - Add automatic return type data casting for SQL functions (Tom) - Allow GiST indexes to handle NULLs and multikey indexes (Oleg Bartunov, Teodor Sigaev, Tom) - Enable partial indexes (Martijn van Oosterhout) - - ---------------------------------------------------------------------- - - Utility Commands - - Add RESET ALL, SHOW ALL (Marko Kreen) - CREATE/ALTER USER/GROUP now allow options in any order (Vince) - Add LOCK A, B, C functionality (Neil Padgett) - New ENCRYPTED/UNENCRYPTED option to CREATE/ALTER USER (Bruce) - New light-weight VACUUM does not lock table; old semantics are available as VACUUM FULL (Tom) - Disable COPY TO/FROM on views (Bruce) - COPY DELIMITERS string must be exactly one character (Tom) - VACUUM warning about index tuples fewer than heap now only appears when appropriate (Martijn van Oosterhout) - Fix permission checks for CREATE INDEX (Tom) - Disallow inappropriate use of CREATE/DROP INDEX/TRIGGER/VIEW (Tom) - - ---------------------------------------------------------------------- - - Data Types and Functions - - SUM(), AVG(), COUNT() now uses int8 internally for speed (Tom) - Add convert(), convert2() (Tatsuo) - New function bit_length() (Peter E) - Make the "n" in CHAR(n)/VARCHAR(n) represents letters, not bytes (Tatsuo) - CHAR(), VARCHAR() now reject strings that are too long (Peter E) - BIT VARYING now rejects bit strings that are too long (Peter E) - BIT now rejects bit strings that do not match declared size (Peter E) - INET, CIDR text conversion functions (Alex Pilosov) - INET, CIDR operators << and <<= indexable (Alex Pilosov) - Bytea \### now requires valid three digit octal number - Bytea comparison improvements, now supports =, <>, >, >=, <, and <= - Bytea now supports B-tree indexes - Bytea now supports LIKE, LIKE...ESCAPE, NOT LIKE, NOT LIKE...ESCAPE - Bytea now supports concatenation - New bytea functions: position, substring, trim, btrim, and length - New encode() function mode, "escaped", converts minimally escaped bytea to/from text - Add pg_database_encoding_max_length() (Tatsuo) - Add pg_client_encoding() function (Tatsuo) - now() returns time with millisecond precision (Thomas) - New TIMESTAMP WITHOUT TIMEZONE data type (Thomas) - Add ISO date/time specification with "T", yyyy-mm-ddThh:mm:ss (Thomas) - New xid/int comparison functions (Hiroshi) - Add precision to TIME, TIMESTAMP, and INVERVAL data types (Thomas) - Modify type coersion logic to attempt binary-compatible functions first (Tom) - New encode() function installed by default (Marko Kreen) - Improved to_*() conversion functions (Karel Zak) - Optimize LIKE/ILIKE when using single-byte encodings (Tatsuo) - New functions in contrib/pgcrypto: crypt(), hmac(), encrypt(), gen_salt() (Marko Kreen) - Correct description of translate() function (Bruce) - Add INTERVAL argument for SET TIME ZONE (Thomas) - Add INTERVAL YEAR TO MONTH (etc.) syntax (Thomas) - Optimize length functions when using single-byte encodings (Tatsuo) - Fix path_inter, path_distance, path_length, dist_ppath to handle closed paths (Curtis Barrett, Tom) - octet_length(text) now returns non-compressed length (Tatsuo, Bruce) - Handle "July" full name in date/time literals (Greg Sabino Mullane) - Some datatype() function calls now evaluated differently - Add support for Julian and ISO time specifications (Thomas) - - ---------------------------------------------------------------------- - - Internationalization - - National language support in psql, pg_dump, libpq, and server (Peter E) - Message translations in Chinese (simplified, traditional), Czech, French, German, Hungarian, Russian, Swedish (Peter E, Serguei A. Mokhov, Karel Zak, Weiping He, Zhenbang Wei, Kovacs Zoltan) - Make trim, ltrim, rtrim, btrim, lpad, rpad, translate multibyte aware (Tatsuo) - Add LATIN5,6,7,8,9,10 support (Tatsuo) - Add ISO 8859-5,6,7,8 support (Tatsuo) - Correct LATIN5 to mean ISO-8859-9, not ISO-8859-5 (Tatsuo) - Make mic2ascii() non-ASCII aware (Tatsuo) - Reject invalid multibyte character sequences (Tatsuo) - - ---------------------------------------------------------------------- - - PL/pgSQL - - Now uses portals for SELECT loops, allowing huge result sets (Jan) - CURSOR and REFCURSOR support (Jan) - Can now return open cursors (Jan) - Add ELSEIF (Klaus Reger) - Improve PL/pgSQL error reporting, including location of error (Tom) - Allow IS or FOR key words in cursor declaration, for compatibility (Bruce) - Fix for SELECT ... FOR UPDATE (Tom) - Fix for PERFORM returning multiple rows (Tom) - Make PL/pgSQL use the server's type coercion code (Tom) - Memory leak fix (Jan, Tom) - Make trailing semicolon optional (Tom) - - ---------------------------------------------------------------------- - - PL/Perl - - New untrusted PL/Perl (Alex Pilosov) - PL/Perl is now built on some platforms even if libperl is not shared (Peter E) - - ---------------------------------------------------------------------- - - PL/Tcl - - Now reports errorInfo (Vsevolod Lobko) - Add spi_lastoid function (bob@redivi.com) - - ---------------------------------------------------------------------- - - PL/Python - - ...is new (Andrew Bosma) - - ---------------------------------------------------------------------- - - Psql - - \d displays indexes in unique, primary groupings (Christopher Kings-Lynne) - Allow trailing semicolons in backslash commands (Greg Sabino Mullane) - Read password from /dev/tty if possible - Force new password prompt when changing user and database (Tatsuo, Tom) - Format the correct number of columns for Unicode (Patrice) - - ---------------------------------------------------------------------- - - Libpq - - New function PQescapeString() to escape quotes in command strings (Florian Weimer) - New function PQescapeBytea() escapes binary strings for use as SQL string literals - - ---------------------------------------------------------------------- - - JDBC - - Return OID of INSERT (Ken K) - Handle more data types (Ken K) - Handle single quotes and newlines in strings (Ken K) - Handle NULL variables (Ken K) - Fix for time zone handling (Barry Lind) - Improved Druid support - Allow eight-bit characters with non-multibyte server (Barry Lind) - Support BIT, BINARY types (Ned Wolpert) - Reduce memory usage (Michael Stephens, Dave Cramer) - Update DatabaseMetaData (Peter E) - Add DatabaseMetaData.getCatalogs() (Peter E) - Encoding fixes (Anders Bengtsson) - Get/setCatalog methods (Jason Davies) - DatabaseMetaData.getColumns() now returns column defaults (Jason Davies) - DatabaseMetaData.getColumns() performance improvement (Jeroen van Vianen) - Some JDBC1 and JDBC2 merging (Anders Bengtsson) - Transaction performance improvements (Barry Lind) - Array fixes (Greg Zoller) - Serialize addition - Fix batch processing (Rene Pijlman) - ExecSQL method reorganization (Anders Bengtsson) - GetColumn() fixes (Jeroen van Vianen) - Fix isWriteable() function (Rene Pijlman) - Improved passage of JDBC2 conformance tests (Rene Pijlman) - Add bytea type capability (Barry Lind) - Add isNullable() (Rene Pijlman) - JDBC date/time test suite fixes (Liam Stewart) - Fix for SELECT 'id' AS xxx FROM table (Dave Cramer) - Fix DatabaseMetaData to show precision properly (Mark Lillywhite) - New getImported/getExported keys (Jason Davies) - MD5 password encryption support (Jeremy Wohl) - Fix to actually use type cache (Ned Wolpert) - - ---------------------------------------------------------------------- - - ODBC - - Remove query size limit (Hiroshi) - Remove text field size limit (Hiroshi) - Fix for SQLPrimaryKeys in multibyte mode (Hiroshi) - Allow ODBC procedure calls (Hiroshi) - Improve boolean handing (Aidan Mountford) - Most configuration options on setable via DSN (Hiroshi) - Multibyte, performance fixes (Hiroshi) - Allow driver to be used with iODBC or unixODBC (Peter E) - MD5 password encryption support (Bruce) - Add more compatibility functions to odbc.sql (Peter E) - - ---------------------------------------------------------------------- - - ECPG - - EXECUTE ... INTO implemented (Christof Petig) - Multiple row descriptor support (e.g. CARDINALITY) (Christof Petig) - Fix for GRANT parameters (Lee Kindness) - Fix INITIALLY DEFERRED bug - Various bug fixes (Michael, Christof Petig) - Auto allocation for indicator variable arrays (int *ind_p=NULL) - Auto allocation for string arrays (char **foo_pp=NULL) - ECPGfree_auto_mem fixed - All function names with external linkage are now prefixed by ECPG - Fixes for arrays of structures (Michael) - - ---------------------------------------------------------------------- - - Misc. Interfaces - - Python fix fetchone() (Gerhard Haring) - Use UTF, Unicode in Tcl where appropriate (Vsevolod Lobko, Reinhard Max) - Add Tcl COPY TO/FROM (ljb) - Prevent output of default index op class in pg_dump (Tom) - Fix libpgeasy memory leak (Bruce) - - ---------------------------------------------------------------------- - - Build and Install - - Configure, dynamic loader, and shared library fixes (Peter E) - Fixes in QNX 4 port (Bernd Tegge) - Fixes in Cygwin and Win32 ports (Jason Tishler, Gerhard Haring, Dmitry Yurtaev, Darko Prenosil, Mikhail Terekhov) - Fix for Win32 socket communication failures (Magnus, Mikhail Terekhov) - Hurd compile fix (Oliver Elphick) - BeOS fixes (Cyril Velter) - Remove configure --enable-unicode-conversion, now enabled by multibyte (Tatsuo) - AIX fixes (Tatsuo, Andreas) - Fix parallel make (Peter E) - Install SQL language manual pages into OS-specific directories (Peter E) - Rename config.h to pg_config.h (Peter E) - Reorganize installation layout of header files (Peter E) - - ---------------------------------------------------------------------- - - Source Code - - Remove SEP_CHAR (Bruce) - New GUC hooks (Tom) - Merge GUC and command line handling (Marko Kreen) - Remove EXTEND INDEX (Martijn van Oosterhout, Tom) - New pgjindent utility to indent java code (Bruce) - Remove define of true/false when compiling under C++ (Leandro Fanzone, Tom) - pgindent fixes (Bruce, Tom) - Replace strcasecmp() with strcmp() where appropriate (Peter E) - Dynahash portability improvements (Tom) - Add 'volatile' usage in spinlock structures - Improve signal handling logic (Tom) - - ---------------------------------------------------------------------- - - Contrib - - New contrib/rtree_gist (Oleg Bartunov, Teodor Sigaev) - New contrib/tsearch full-text indexing (Oleg, Teodor Sigaev) - Add contrib/dblink for remote database access (Joe Conway) - contrib/ora2pg Oracle conversion utility (Gilles Darold) - contrib/xml XML conversion utility (John Gray) - contrib/fulltextindex fixes (Christopher Kings-Lynne) - New contrib/fuzzystrmatch with levenshtein and metaphone, soundex merged (Joe Conway) - Add contrib/intarray boolean queries, binary search, fixes (Oleg Bartunov) - New pg_upgrade utility (Bruce) - Add new pg_resetxlog options (Bruce, Tom) - ---------------------------------------------------------------------- - - Release 7.1.3 - - Release date: 2001-08-15 - - ---------------------------------------------------------------------- - -Migration to version 7.1.3 - - A dump/restore is *not* required for those running 7.1.X. - - ---------------------------------------------------------------------- - -Changes - - Remove unused WAL segements of large transactions (Tom) - Multiaction rule fix (Tom) - PL/pgSQL memory allocation fix (Jan) - VACUUM buffer fix (Tom) - Regression test fixes (Tom) - pg_dump fixes for GRANT/REVOKE/comments on views, user-defined types (Tom) - Fix subselects with DISTINCT ON or LIMIT (Tom) - BEOS fix - Disable COPY TO/FROM a view (Tom) - Cygwin build (Jason Tishler) - - - ---------------------------------------------------------------------- - - Release 7.1.2 - - Release date: 2001-05-11 - - This has one fix from 7.1.1. - - ---------------------------------------------------------------------- - -Migration to version 7.1.2 - - A dump/restore is *not* required for those running 7.1.X. - - ---------------------------------------------------------------------- - -Changes - - Fix PL/pgSQL SELECTs when returning no rows - Fix for psql backslash core dump - Referential integrity permission fix - Optimizer fixes - pg_dump cleanups - - - ---------------------------------------------------------------------- - - Release 7.1.1 - - Release date: 2001-05-05 - - This has a variety of fixes from 7.1. - - ---------------------------------------------------------------------- - -Migration to version 7.1.1 - - A dump/restore is *not* required for those running 7.1. - - ---------------------------------------------------------------------- - -Changes - - Fix for numeric MODULO operator (Tom) - pg_dump fixes (Philip) - pg_dump can dump 7.0 databases (Philip) - readline 4.2 fixes (Peter E) - JOIN fixes (Tom) - AIX, MSWIN, VAX,N32K fixes (Tom) - Multibytes fixes (Tom) - Unicode fixes (Tatsuo) - Optimizer improvements (Tom) - Fix for whole tuples in functions (Tom) - Fix for pg_ctl and option strings with spaces (Peter E) - ODBC fixes (Hiroshi) - EXTRACT can now take string argument (Thomas) - Python fixes (Darcy) - - - ---------------------------------------------------------------------- - - Release 7.1 - - Release date: 2001-04-13 - - This release focuses on removing limitations that have existed in the - PostgreSQL code for many years. - - Major changes in this release: - - Write-ahead Log (WAL) - - To maintain database consistency in case of an operating system - crash, previous releases of PostgreSQL have forced all data - modifications to disk before each transaction commit. With WAL, - only one log file must be flushed to disk, greatly improving - performance. If you have been using -F in previous releases to - disable disk flushes, you may want to consider discontinuing its - use. - - TOAST - - TOAST - Previous releases had a compiled-in row length limit, - typically 8k - 32k. This limit made storage of long text fields - difficult. With TOAST, long rows of any length can be stored with - good performance. - - Outer Joins - - We now support outer joins. The UNION/NOT IN workaround for outer - joins is no longer required. We use the SQL92 outer join syntax. - - Function Manager - - The previous C function manager did not handle NULLs properly, nor - did it support 64-bit CPU's (Alpha). The new function manager - does. You can continue using your old custom functions, but you - may want to rewrite them in the future to use the new function - manager call interface. - - Complex Queries - - A large number of complex queries that were unsupported in - previous releases now work. Many combinations of views, - aggregates, UNION, LIMIT, cursors, subqueries, and inherited - tables now work properly. Inherited tables are now accessed by - default. Subqueries in FROM are now supported. - - ---------------------------------------------------------------------- - -Migration to version 7.1 - - A dump/restore using pg_dump is required for those wishing to migrate data - from any previous release. - - ---------------------------------------------------------------------- - -Changes - - Bug Fixes - --------- - Many multi-byte/Unicode/locale fixes (Tatsuo and others) - More reliable ALTER TABLE RENAME (Tom) - Kerberos V fixes (David Wragg) - Fix for INSERT INTO...SELECT where targetlist has subqueries (Tom) - Prompt username/password on standard error (Bruce) - Large objects inv_read/inv_write fixes (Tom) - Fixes for to_char(), to_date(), to_ascii(), and to_timestamp() (Karel, - Daniel Baldoni) - Prevent query expressions from leaking memory (Tom) - Allow UPDATE of arrays elements (Tom) - Wake up lock waiters during cancel (Hiroshi) - Fix rare cursor crash when using hash join (Tom) - Fix for DROP TABLE/INDEX in rolled-back transaction (Hiroshi) - Fix psql crash from \l+ if MULTIBYTE enabled (Peter E) - Fix truncation of rule names during CREATE VIEW (Ross Reedstrom) - Fix PL/perl (Alex Kapranoff) - Disallow LOCK on views (Mark Hollomon) - Disallow INSERT/UPDATE/DELETE on views (Mark Hollomon) - Disallow DROP RULE, CREATE INDEX, TRUNCATE on views (Mark Hollomon) - Allow PL/pgSQL accept non-ASCII identifiers (Tatsuo) - Allow views to proper handle GROUP BY, aggregates, DISTINCT (Tom) - Fix rare failure with TRUNCATE command (Tom) - Allow UNION/INTERSECT/EXCEPT to be used with ALL, subqueries, views, - DISTINCT, ORDER BY, SELECT...INTO (Tom) - Fix parser failures during aborted transactions (Tom) - Allow temporary relations to properly clean up indexes (Bruce) - Fix VACUUM problem with moving rows in same page (Tom) - Modify pg_dump to better handle user-defined items in template1 (Philip) - Allow LIMIT in VIEW (Tom) - Require cursor FETCH to honor LIMIT (Tom) - Allow PRIMARY/FOREIGN Key definitions on inherited columns (Stephan) - Allow ORDER BY, LIMIT in sub-selects (Tom) - Allow UNION in CREATE RULE (Tom) - Make ALTER/DROP TABLE rollback-able (Vadim, Tom) - Store initdb collation in pg_control so collation cannot be changed (Tom) - Fix INSERT...SELECT with rules (Tom) - Fix FOR UPDATE inside views and subselects (Tom) - Fix OVERLAPS operators conform to SQL92 spec regarding NULLs (Tom) - Fix lpad() and rpad() to handle length less than input string (Tom) - Fix use of NOTIFY in some rules (Tom) - Overhaul btree code (Tom) - Fix NOT NULL use in Pl/pgSQL variables (Tom) - Overhaul GIST code (Oleg) - Fix CLUSTER to preserve constraints and column default (Tom) - Improved deadlock detection handling (Tom) - Allow multiple SERIAL columns in a table (Tom) - Prevent occasional index corruption (Vadim) - - Enhancements - ------------ - Add OUTER JOINs (Tom) - Function manager overhaul (Tom) - Allow ALTER TABLE RENAME on indexes (Tom) - Improve CLUSTER (Tom) - Improve ps status display for more platforms (Peter E, Marc) - Improve CREATE FUNCTION failure message (Ross) - JDBC improvements (Peter, Travis Bauer, Christopher Cain, William Webber, - Gunnar) - Grand Unified Configuration scheme/GUC. Many options can now be set in - data/postgresql.conf, postmaster/postgres flags, or SET commands (Peter E) - Improved handling of file descriptor cache (Tom) - New warning code about auto-created table alias entries (Bruce) - Overhaul initdb process (Tom, Peter E) - Overhaul of inherited tables; inherited tables now accessed by default; - new ONLY keyword prevents it (Chris Bitmead, Tom) - ODBC cleanups/improvements (Nick Gorham, Stephan Szabo, Zoltan Kovacs, - Michael Fork) - Allow renaming of temp tables (Tom) - Overhaul memory manager contexts (Tom) - pg_dumpall uses CREATE USER or CREATE GROUP rather using COPY (Peter E) - Overhaul pg_dump (Philip Warner) - Allow pg_hba.conf secondary password file to specify only username (Peter E) - Allow TEMPORARY or TEMP keyword when creating temporary tables (Bruce) - New memory leak checker (Karel) - New SET SESSION CHARACTERISTICS (Thomas) - Allow nested block comments (Thomas) - Add WITHOUT TIME ZONE type qualifier (Thomas) - New ALTER TABLE ADD CONSTRAINT (Stephan) - Use NUMERIC accumulators for INTEGER aggregates (Tom) - Overhaul aggregate code (Tom) - New VARIANCE and STDDEV() aggregates - Improve dependency ordering of pg_dump (Philip) - New pg_restore command (Philip) - New pg_dump tar output option (Philip) - New pg_dump of large objects (Philip) - New ESCAPE option to LIKE (Thomas) - New case-insensitive LIKE - ILIKE (Thomas) - Allow functional indexes to use binary-compatible type (Tom) - Allow SQL functions to be used in more contexts (Tom) - New pg_config utility (Peter E) - New PL/pgSQL EXECUTE command which allows dynamic SQL and utility statements - (Jan) - New PL/pgSQL GET DIAGNOSTICS statement for SPI value access (Jan) - New quote_identifiers() and quote_literal() functions (Jan) - New ALTER TABLE table OWNER TO user command (Mark Hollomon) - Allow subselects in FROM, i.e. FROM (SELECT ...) [AS] alias (Tom) - Update PyGreSQL to version 3.1 (D'Arcy) - Store tables as files named by OID (Vadim) - New SQL function setval(seq,val,bool) for use in pg_dump (Philip) - Require DROP VIEW to remove views, no DROP TABLE (Mark) - Allow DROP VIEW view1, view2 (Mark) - Allow multiple objects in DROP INDEX, DROP RULE, and DROP TYPE (Tom) - Allow automatic conversion to/from Unicode (Tatsuo, Eiji) - New /contrib/pgcrypto hashing functions (Marko Kreen) - New pg_dumpall --globals-only option (Peter E) - New CHECKPOINT command for WAL which creates new WAL log file (Vadim) - New AT TIME ZONE syntax (Thomas) - Allow location of Unix domain socket to be configurable (David J. MacKenzie) - Allow postmaster to listen on a specific IP address (David J. MacKenzie) - Allow socket path name to be specified in hostname by using leading slash - (David J. MacKenzie) - Allow CREATE DATABASE to specify template database (Tom) - New utility to convert MySQL schema dumps to SQL92 and PostgreSQL (Thomas) - New /contrib/rserv replication toolkit (Vadim) - New file format for COPY BINARY (Tom) - New /contrib/oid2name to map numeric files to table names (B Palmer) - New "idle in transaction" ps status message (Marc) - Update to pgaccess 0.98.7 (Constantin Teodorescu) - pg_ctl now defaults to -w (wait) on shutdown, new -l (log) option - Add rudimentary dependency checking to pg_dump (Philip) - - Types - ----- - Fix INET/CIDR type ordering and add new functions (Tom) - Make OID behave as an unsigned type (Tom) - Allow BIGINT as synonym for INT8 (Peter E) - New int2 and int8 comparison operators (Tom) - New BIT and BIT VARYING types (Adriaan Joubert, Tom, Peter E) - CHAR() no longer faster than VARCHAR() because of TOAST (Tom) - New GIST seg/cube examples (Gene Selkov) - Improved round(numeric) handling (Tom) - Fix CIDR output formatting (Tom) - New CIDR abbrev() function (Tom) - - Performance - ----------- - Write-Ahead Log (WAL) to provide crash recovery with less performance - overhead (Vadim) - ANALYZE stage of VACUUM no longer exclusively locks table (Bruce) - Reduced file seeks (Denis Perchine) - Improve BTREE code for duplicate keys (Tom) - Store all large objects in a single table (Denis Perchine, Tom) - Improve memory allocation performance (Karel, Tom) - - Source Code - ----------- - New function manager call conventions (Tom) - SGI portability fixes (David Kaelbling) - New configure --enable-syslog option (Peter E) - New BSDI README (Bruce) - configure script moved to top level, not /src (Peter E) - Makefile/configuration/compilation overhaul (Peter E) - New configure --with-python option (Peter E) - Solaris cleanups (Peter E) - Overhaul /contrib Makefiles (Karel) - New OpenSSL configuration option (Magnus, Peter E) - AIX fixes (Andreas) - QNX fixes (Maurizio) - New heap_open(), heap_openr() API (Tom) - Remove colon and semi-colon operators (Thomas) - New pg_class.relkind value for views (Mark Hollomon) - Rename ichar() to chr() (Karel) - New documentation for btrim(), ascii(), chr(), repeat() (Karel) - Fixes for NT/Cygwin (Pete Forman) - AIX port fixes (Andreas) - New BeOS port (David Reid, Cyril Velter) - Add proofreader's changes to docs (Addison-Wesley, Bruce) - New Alpha spinlock code (Adriaan Joubert, Compaq) - Unixware port overhaul (Peter E) - New Darwin/Mac OSX port (Peter Bierman, Bruce Hartzler) - New FreeBSD Alpha port (Alfred) - Overhaul shared memory segments (Tom) - Add IBM S/390 support (Neale Ferguson) - Moved macmanuf to /contrib (Larry Rosenman) - Syslog improvements (Larry Rosenman) - New template0 database that contains no user additions (Tom) - New /contrib/cube and /contrib/seg GIST sample code (Gene Selkov) - Allow NetBSD's libedit instead of readline (Peter) - Improved assembly language source code format (Bruce) - New contrib/pg_logger - New --template option to createdb - New contrib/pg_control utility (Oliver) - New FreeBSD tools ipc_check, start-scripts/freebsd - - - ---------------------------------------------------------------------- - - Release 7.0.3 - - Release date: 2000-11-11 - - This has a variety of fixes from 7.0.2. - - ---------------------------------------------------------------------- - -Migration to version 7.0.3 - - A dump/restore is *not* required for those running 7.0.*. - - ---------------------------------------------------------------------- - -Changes - - Jdbc fixes (Peter) - Large object fix (Tom) - Fix lean in COPY WITH OIDS leak (Tom) - Fix backwards-index-scan (Tom) - Fix SELECT ... FOR UPDATE so it checks for duplicate keys (Hiroshi) - Add --enable-syslog to configure (Marc) - Fix abort transaction at backend exit in rare cases (Tom) - Fix for psql \l+ when multi-byte enabled (Tatsuo) - Allow PL/pgSQL to accept non ascii identifiers (Tatsuo) - Make vacuum always flush buffers (Tom) - Fix to allow cancel while waiting for a lock (Hiroshi) - Fix for memory aloocation problem in user authentication code (Tom) - Remove bogus use of int4out() (Tom) - Fixes for multiple subqueries in COALESCE or BETWEEN (Tom) - Fix for failure of triggers on heap open in certain cases (Jeroen van - Vianen) - Fix for erroneous selectivity of not-equals (Tom) - Fix for erroneous use of strcmp() (Tom) - Fix for bug where storage manager accesses items beyond end of file - (Tom) - Fix to include kernel errno message in all smgr elog messages (Tom) - Fix for '.' not in PATH at build time (SL Baur) - Fix for out-of-file-descriptors error (Tom) - Fix to make pg_dump dump 'iscachable' flag for functions (Tom) - Fix for subselect in targetlist of Append node (Tom) - Fix for mergejoin plans (Tom) - Fix TRUNCATE failure on relations with indexes (Tom) - Avoid database-wide restart on write error (Hiroshi) - Fix nodeMaterial to honor chgParam by recomputing its output (Tom) - Fix VACUUM problem with moving chain of update tuples when source and - destination of a tuple lie on the same page (Tom) - Fix user.c CommandCounterIncrement (Tom) - Fix for AM/PM boundary problem in to_char() (Karel Zak) - Fix TIME aggregate handling (Tom) - Fix to_char() to avoid coredump on NULL input (Tom) - Buffer fix (Tom) - Fix for inserting/copying longer multibyte strings into char() data - types (Tatsuo) - Fix for crash of backend, on abort (Tom) - - - ---------------------------------------------------------------------- - - Release 7.0.2 - - Release date: 2000-06-05 - - This is a repackaging of 7.0.1 with added documentation. - - ---------------------------------------------------------------------- - -Migration to version 7.0.2 - - A dump/restore is *not* required for those running 7.*. - - ---------------------------------------------------------------------- - -Changes - - Added documentation to tarball. - - - ---------------------------------------------------------------------- - - Release 7.0.1 - - Release date: 2000-06-01 - - This is a cleanup release for 7.0. - - ---------------------------------------------------------------------- - -Migration to version 7.0.1 - - A dump/restore is *not* required for those running 7.0. - - ---------------------------------------------------------------------- - -Changes - - Fix many CLUSTER failures (Tom) - Allow ALTER TABLE RENAME works on indexes (Tom) - Fix plpgsql to handle datetime->timestamp and timespan->interval (Bruce) - New configure --with-setproctitle switch to use setproctitle() (Marc, Bruce) - Fix the off by one errors in ResultSet from 6.5.3, and more. - jdbc ResultSet fixes (Joseph Shraibman) - optimizer tunings (Tom) - Fix create user for pgaccess - Fix for UNLISTEN failure - IRIX fixes (David Kaelbling) - QNX fixes (Andreas Kardos) - Reduce COPY IN lock level (Tom) - Change libpqeasy to use PQconnectdb() style parameters (Bruce) - Fix pg_dump to handle OID indexes (Tom) - Fix small memory leak (Tom) - Solaris fix for createdb/dropdb (Tatsuo) - Fix for non-blocking connections (Alfred Perlstein) - Fix improper recovery after RENAME TABLE failures (Tom) - Copy pg_ident.conf.sample into /lib directory in install (Bruce) - Add SJIS UDC (NEC selection IBM kanji) support (Eiji Tokuya) - Fix too long syslog message (Tatsuo) - Fix problem with quoted indexes that are too long (Tom) - JDBC ResultSet.getTimestamp() fix (Gregory Krasnow & Floyd Marinescu) - ecpg changes (Michael) - - - ---------------------------------------------------------------------- - - Release 7.0 - - Release date: 2000-05-08 - - This release contains improvements in many areas, demonstrating the - continued growth of PostgreSQL. There are more improvements and fixes in - 7.0 than in any previous release. The developers have confidence that this - is the best release yet; we do our best to put out only solid releases, - and this one is no exception. - - Major changes in this release: - - Foreign Keys - - Foreign keys are now implemented, with the exception of PARTIAL - MATCH foreign keys. Many users have been asking for this feature, - and we are pleased to offer it. - - Optimizer Overhaul - - Continuing on work started a year ago, the optimizer has been - improved, allowing better query plan selection and faster - performance with less memory usage. - - Updated psql - - psql, our interactive terminal monitor, has been updated with a - variety of new features. See the psql manual page for details. - - Join Syntax - - SQL92 join syntax is now supported, though only as INNER JOINs for - this release. JOIN, NATURAL JOIN, JOIN/USING, JOIN/ON are - available, as are column correlation names. - - ---------------------------------------------------------------------- - -Migration to version 7.0 - - A dump/restore using pg_dump is required for those wishing to migrate data - from any previous release of PostgreSQL. For those upgrading from 6.5.*, - you may instead use pg_upgrade to upgrade to this release; however, a full - dump/reload installation is always the most robust method for upgrades. - - Interface and compatibility issues to consider for the new release - include: - - * The date/time types datetime and timespan have been superseded by the - SQL92-defined types timestamp and interval. Although there has been - some effort to ease the transition by allowing PostgreSQL to recognize - the deprecated type names and translate them to the new type names, - this mechanism may not be completely transparent to your existing - application. - - * The optimizer has been substantially improved in the area of query - cost estimation. In some cases, this will result in decreased query - times as the optimizer makes a better choice for the preferred plan. - However, in a small number of cases, usually involving pathological - distributions of data, your query times may go up. If you are dealing - with large amounts of data, you may want to check your queries to - verify performance. - - * The JDBC and ODBC interfaces have been upgraded and extended. - - * The string function CHAR_LENGTH is now a native function. Previous - versions translated this into a call to LENGTH, which could result in - ambiguity with other types implementing LENGTH such as the geometric - types. - - ---------------------------------------------------------------------- - -Changes - - Bug Fixes - --------- - Prevent function calls exceeding maximum number of arguments (Tom) - Improve CASE construct (Tom) - Fix SELECT coalesce(f1,0) FROM int4_tbl GROUP BY f1 (Tom) - Fix SELECT sentence.words[0] FROM sentence GROUP BY sentence.words[0] (Tom) - Fix GROUP BY scan bug (Tom) - Improvements in SQL grammar processing (Tom) - Fix for views involved in INSERT ... SELECT ... (Tom) - Fix for SELECT a/2, a/2 FROM test_missing_target GROUP BY a/2 (Tom) - Fix for subselects in INSERT ... SELECT (Tom) - Prevent INSERT ... SELECT ... ORDER BY (Tom) - Fixes for relations greater than 2GB, including vacuum - Improve propagating system table changes to other backends (Tom) - Improve propagating user table changes to other backends (Tom) - Fix handling of temp tables in complex situations (Bruce, Tom) - Allow table locking at table open, improving concurrent reliability (Tom) - Properly quote sequence names in pg_dump (Ross J. Reedstrom) - Prevent DROP DATABASE while others accessing - Prevent any rows from being returned by GROUP BY if no rows processed (Tom) - Fix SELECT COUNT(1) FROM table WHERE ...' if no rows matching WHERE (Tom) - Fix pg_upgrade so it works for MVCC (Tom) - Fix for SELECT ... WHERE x IN (SELECT ... HAVING SUM(x) > 1) (Tom) - Fix for "f1 datetime DEFAULT 'now'" (Tom) - Fix problems with CURRENT_DATE used in DEFAULT (Tom) - Allow comment-only lines, and ;;; lines too. (Tom) - Improve recovery after failed disk writes, disk full (Hiroshi) - Fix cases where table is mentioned in FROM but not joined (Tom) - Allow HAVING clause without aggregate functions (Tom) - Fix for "--" comment and no trailing newline, as seen in perl interface - Improve pg_dump failure error reports (Bruce) - Allow sorts and hashes to exceed 2GB file sizes (Tom) - Fix for pg_dump dumping of inherited rules (Tom) - Fix for NULL handling comparisons (Tom) - Fix inconsistent state caused by failed CREATE/DROP commands (Hiroshi) - Fix for dbname with dash - Prevent DROP INDEX from interfering with other backends (Tom) - Fix file descriptor leak in verify_password() - Fix for "Unable to identify an operator =$" problem - Fix ODBC so no segfault if CommLog and Debug enabled (Dirk Niggemann) - Fix for recursive exit call (Massimo) - Fix for extra-long timezones (Jeroen van Vianen) - Make pg_dump preserve primary key information (Peter E) - Prevent databases with single quotes (Peter E) - Prevent DROP DATABASE inside transaction (Peter E) - ecpg memory leak fixes (Stephen Birch) - Fix for SELECT null::text, SELECT int4fac(null) and SELECT 2 + (null) (Tom) - Y2K timestamp fix (Massimo) - Fix for VACUUM 'HEAP_MOVED_IN was not expected' errors (Tom) - Fix for views with tables/columns containing spaces (Tom) - Prevent permissions on indexes (Peter E) - Fix for spinlock stuck problem when error is generated (Hiroshi) - Fix ipcclean on Linux - Fix handling of NULL constraint conditions (Tom) - Fix memory leak in odbc driver (Nick Gorham) - Fix for permission check on UNION tables (Tom) - Fix to allow SELECT 'a' LIKE 'a' (Tom) - Fix for SELECT 1 + NULL (Tom) - Fixes to CHAR - Fix log() on numeric type (Tom) - Deprecate ':' and ';' operators - Allow vacuum of temporary tables - Disallow inherited columns with the same name as new columns - Recover or force failure when disk space is exhausted (Hiroshi) - Fix INSERT INTO ... SELECT with AS columns matching result columns - Fix INSERT ... SELECT ... GROUP BY groups by target columns not source columns (Tom) - Fix CREATE TABLE test (a char(5) DEFAULT text '', b int4) with INSERT (Tom) - Fix UNION with LIMIT - Fix CREATE TABLE x AS SELECT 1 UNION SELECT 2 - Fix CREATE TABLE test(col char(2) DEFAULT user) - Fix mismatched types in CREATE TABLE ... DEFAULT - Fix SELECT * FROM pg_class where oid in (0,-1) - Fix SELECT COUNT('asdf') FROM pg_class WHERE oid=12 - Prevent user who can create databases can modifying pg_database table (Peter E) - Fix btree to give a useful elog when key > 1/2 (page - overhead) (Tom) - Fix INSERT of 0.0 into DECIMAL(4,4) field (Tom) - - Enhancements - ------------ - New CLI interface include file sqlcli.h, based on SQL3/SQL98 - Remove all limits on query length, row length limit still exists (Tom) - Update jdbc protocol to 2.0 (Jens Glaser ) - Add TRUNCATE command to quickly truncate relation (Mike Mascari) - Fix to give super user and createdb user proper update catalog rights (Peter E) - Allow ecpg bool variables to have NULL values (Christof) - Issue ecpg error if NULL value for variable with no NULL indicator (Christof) - Allow ^C to cancel COPY command (Massimo) - Add SET FSYNC and SHOW PG_OPTIONS commands(Massimo) - Function name overloading for dynamically-loaded C functions (Frankpitt) - Add CmdTuples() to libpq++(Vince) - New CREATE CONSTRAINT TRIGGER and SET CONSTRAINTS commands(Jan) - Allow CREATE FUNCTION/WITH clause to be used for all language types - configure --enable-debug adds -g (Peter E) - configure --disable-debug removes -g (Peter E) - Allow more complex default expressions (Tom) - First real FOREIGN KEY constraint trigger functionality (Jan) - Add FOREIGN KEY ... MATCH FULL ... ON DELETE CASCADE (Jan) - Add FOREIGN KEY ... MATCH referential actions (Don Baccus) - Allow WHERE restriction on ctid (physical heap location) (Hiroshi) - Move pginterface from contrib to interface directory, rename to pgeasy (Bruce) - Change pgeasy connectdb() parameter ordering (Bruce) - Require SELECT DISTINCT target list to have all ORDER BY columns (Tom) - Add Oracle's COMMENT ON command (Mike Mascari ) - libpq's PQsetNoticeProcessor function now returns previous hook(Peter E) - Prevent PQsetNoticeProcessor from being set to NULL (Peter E) - Make USING in COPY optional (Bruce) - Allow subselects in the target list (Tom) - Allow subselects on the left side of comparison operators (Tom) - New parallel regression test (Jan) - Change backend-side COPY to write files with permissions 644 not 666 (Tom) - Force permissions on PGDATA directory to be secure, even if it exists (Tom) - Added psql LASTOID variable to return last inserted oid (Peter E) - Allow concurrent vacuum and remove pg_vlock vacuum lock file (Tom) - Add permissions check for vacuum (Peter E) - New libpq functions to allow asynchronous connections: PQconnectStart(), - PQconnectPoll(), PQresetStart(), PQresetPoll(), PQsetenvStart(), - PQsetenvPoll(), PQsetenvAbort (Ewan Mellor) - New libpq PQsetenv() function (Ewan Mellor) - create/alter user extension (Peter E) - New postmaster.pid and postmaster.opts under $PGDATA (Tatsuo) - New scripts for create/drop user/db (Peter E) - Major psql overhaul (Peter E) - Add const to libpq interface (Peter E) - New libpq function PQoidValue (Peter E) - Show specific non-aggregate causing problem with GROUP BY (Tom) - Make changes to pg_shadow recreate pg_pwd file (Peter E) - Add aggregate(DISTINCT ...) (Tom) - Allow flag to control COPY input/output of NULLs (Peter E) - Make postgres user have a password by default (Peter E) - Add CREATE/ALTER/DROP GROUP (Peter E) - All administration scripts now support --long options (Peter E, Karel) - Vacuumdb script now supports --all option (Peter E) - ecpg new portable FETCH syntax - Add ecpg EXEC SQL IFDEF, EXEC SQL IFNDEF, EXEC SQL ELSE, EXEC SQL ELIF - and EXEC SQL ENDIF directives - Add pg_ctl script to control backend start-up (Tatsuo) - Add postmaster.opts.default file to store start-up flags (Tatsuo) - Allow --with-mb=SQL_ASCII - Increase maximum number of index keys to 16 (Bruce) - Increase maximum number of function arguments to 16 (Bruce) - Allow configuration of maximum number of index keys and arguments (Bruce) - Allow unprivileged users to change their passwords (Peter E) - Password authentication enabled; required for new users (Peter E) - Disallow dropping a user who owns a database (Peter E) - Change initdb option --with-mb to --enable-multibyte - Add option for initdb to prompts for superuser password (Peter E) - Allow complex type casts like col::numeric(9,2) and col::int2::float8 (Tom) - Updated user interfaces on initdb, initlocation, pg_dump, ipcclean (Peter E) - New pg_char_to_encoding() and pg_encoding_to_char() functions (Tatsuo) - Libpq non-blocking mode (Alfred Perlstein) - Improve conversion of types in casts that don't specify a length - New plperl internal programming language (Mark Hollomon) - Allow COPY IN to read file that do not end with a newline (Tom) - Indicate when long identifiers are truncated (Tom) - Allow aggregates to use type equivalency (Peter E) - Add Oracle's to_char(), to_date(), to_datetime(), to_timestamp(), to_number() - conversion functions (Karel Zak ) - Add SELECT DISTINCT ON (expr [, expr ...]) targetlist ... (Tom) - Check to be sure ORDER BY is compatible with the DISTINCT operation (Tom) - Add NUMERIC and int8 types to ODBC - Improve EXPLAIN results for Append, Group, Agg, Unique (Tom) - Add ALTER TABLE ... ADD FOREIGN KEY (Stephan Szabo) - Allow SELECT .. FOR UPDATE in PL/pgSQL (Hiroshi) - Enable backward sequential scan even after reaching EOF (Hiroshi) - Add btree indexing of boolean values, >= and <= (Don Baccus) - Print current line number when COPY FROM fails (Massimo) - Recognize POSIX time zone e.g. "PST+8" and "GMT-8" (Thomas) - Add DEC as synonym for DECIMAL (Thomas) - Add SESSION_USER as SQL92 keyword, same as CURRENT_USER (Thomas) - Implement SQL92 column aliases (aka correlation names) (Thomas) - Implement SQL92 join syntax (Thomas) - Make INTERVAL reserved word allowed as a column identifier (Thomas) - Implement REINDEX command (Hiroshi) - Accept ALL in aggregate function SUM(ALL col) (Tom) - Prevent GROUP BY from using column aliases (Tom) - New psql \encoding option (Tatsuo) - Allow PQrequestCancel() to terminate when in waiting-for-lock state (Hiroshi) - Allow negation of a negative number in all cases - Add ecpg descriptors (Christof, Michael) - Allow CREATE VIEW v AS SELECT f1::char(8) FROM tbl - Allow casts with length, like foo::char(8) - New libpq functions PQsetClientEncoding(), PQclientEncoding() (Tatsuo) - Add support for SJIS user defined characters (Tatsuo) - Larger views/rules supported - Make libpq's PQconndefaults() thread-safe (Tom) - Disable // as comment to be ANSI conforming, should use -- (Tom) - Allow column aliases on views CREATE VIEW name (collist) - Fixes for views with subqueries (Tom) - Allow UPDATE table SET fld = (SELECT ...) (Tom) - SET command options no longer require quotes - Update pgaccess to 0.98.6 - New SET SEED command - New pg_options.sample file - New SET FSYNC command (Massimo) - Allow pg_descriptions when creating tables - Allow pg_descriptions when creating types, columns, and functions - Allow psql \copy to allow delimiters (Peter E) - Allow psql to print nulls as distinct from "" [null] (Peter E) - - Types - ----- - Many array fixes (Tom) - Allow bare column names to be subscripted as arrays (Tom) - Improve type casting of int and float constants (Tom) - Cleanups for int8 inputs, range checking, and type conversion (Tom) - Fix for SELECT timespan('21:11:26'::time) (Tom) - netmask('x.x.x.x/0') is 255.255.255.255 instead of 0.0.0.0 (Oleg Sharoiko) - Add btree index on NUMERIC (Jan) - Perl fix for large objects containing NUL characters (Douglas Thomson) - ODBC fix for for large objects (free) - Fix indexing of cidr data type - Fix for Ethernet MAC addresses (macaddr type) comparisons - Fix for date/time types when overflows happened in computations (Tom) - Allow array on int8 (Peter E) - Fix for rounding/overflow of NUMERIC type, like NUMERIC(4,4) (Tom) - Allow NUMERIC arrays - Fix bugs in NUMERIC ceil() and floor() functions (Tom) - Make char_length()/octet_length including trailing blanks (Tom) - Made abstime/reltime use int4 instead of time_t (Peter E) - New lztext data type for compressed text fields - Revise code to handle coercion of int and float constants (Tom) - Start at new code to implement a BIT and BIT VARYING type (Adriaan Joubert) - NUMERIC now accepts scientific notation (Tom) - NUMERIC to int4 rounds (Tom) - Convert float4/8 to NUMERIC properly (Tom) - Allow type conversion with NUMERIC (Thomas) - Make ISO date style (2000-02-16 09:33) the default (Thomas) - Add NATIONAL CHAR [ VARYING ] (Thomas) - Allow NUMERIC round and trunc to accept negative scales (Tom) - New TIME WITH TIME ZONE type (Thomas) - Add MAX()/MIN() on time type (Thomas) - Add abs(), mod(), fac() for int8 (Thomas) - Rename functions to round(), sqrt(), cbrt(), pow() for float8 (Thomas) - Add transcendental math functions (e.g. sin(), acos()) for float8 (Thomas) - Add exp() and ln() for NUMERIC type - Rename NUMERIC power() to pow() (Thomas) - Improved TRANSLATE() function (Edwin Ramirez, Tom) - Allow X=-Y operators (Tom) - Allow SELECT float8(COUNT(*))/(SELECT COUNT(*) FROM t) FROM t GROUP BY f1; (Tom) - Allow LOCALE to use indexes in regular expression searches (Tom) - Allow creation of functional indexes to use default types - - Performance - ----------- - Prevent exponential space consumption with many AND's and OR's (Tom) - Collect attribute selectivity values for system columns (Tom) - Reduce memory usage of aggregates (Tom) - Fix for LIKE optimization to use indexes with multibyte encodings (Tom) - Fix r-tree index optimizer selectivity (Thomas) - Improve optimizer selectivity computations and functions (Tom) - Optimize btree searching for cases where many equal keys exist (Tom) - Enable fast LIKE index processing only if index present (Tom) - Re-use free space on index pages with duplicates (Tom) - Improve hash join processing (Tom) - Prevent descending sort if result is already sorted(Hiroshi) - Allow commuting of index scan query qualifications (Tom) - Prefer index scans in cases where ORDER BY/GROUP BY is required (Tom) - Allocate large memory requests in fix-sized chunks for performance (Tom) - Fix vacuum's performance by reducing memory allocation requests (Tom) - Implement constant-expression simplification (Bernard Frankpitt, Tom) - Use secondary columns to be used to determine start of index scan (Hiroshi) - Prevent quadruple use of disk space when doing internal sorting (Tom) - Faster sorting by calling fewer functions (Tom) - Create system indexes to match all system caches (Bruce, Hiroshi) - Make system caches use system indexes (Bruce) - Make all system indexes unique (Bruce) - Improve pg_statistics management for VACUUM speed improvement (Tom) - Flush backend cache less frequently (Tom, Hiroshi) - COPY now reuses previous memory allocation, improving performance (Tom) - Improve optimization cost estimation (Tom) - Improve optimizer estimate of range queries x > lowbound AND x < highbound (Tom) - Use DNF instead of CNF where appropriate (Tom, Taral) - Further cleanup for OR-of-AND WHERE-clauses (Tom) - Make use of index in OR clauses (x = 1 AND y = 2) OR (x = 2 AND y = 4) (Tom) - Smarter optimizer computations for random index page access (Tom) - New SET variable to control optimizer costs (Tom) - Optimizer queries based on LIMIT, OFFSET, and EXISTS qualifications (Tom) - Reduce optimizer internal housekeeping of join paths for speedup (Tom) - Major subquery speedup (Tom) - Fewer fsync writes when fsync is not disabled (Tom) - Improved LIKE optimizer estimates (Tom) - Prevent fsync in SELECT-only queries (Vadim) - Make index creation use psort code, because it is now faster (Tom) - Allow creation of sort temp tables > 1 Gig - - Source Tree Changes - ------------------- - Fix for linux PPC compile - New generic expression-tree-walker subroutine (Tom) - Change form() to varargform() to prevent portability problems - Improved range checking for large integers on Alphas - Clean up #include in /include directory (Bruce) - Add scripts for checking includes (Bruce) - Remove un-needed #include's from *.c files (Bruce) - Change #include's to use <> and "" as appropriate (Bruce) - Enable WIN32 compilation of libpq - Alpha spinlock fix from Uncle George - Overhaul of optimizer data structures (Tom) - Fix to cygipc library (Yutaka Tanida) - Allow pgsql to work on newer Cygwin snapshots (Dan) - New catalog version number (Tom) - Add Linux ARM - Rename heap_replace to heap_update - Update for QNX (Dr. Andreas Kardos) - New platform-specific regression handling (Tom) - Rename oid8 -> oidvector and int28 -> int2vector (Bruce) - Included all yacc and lex files into the distribution (Peter E.) - Remove lextest, no longer needed (Peter E) - Fix for libpq and psql on Win32 (Magnus) - Internally change datetime and timespan into timestamp and interval (Thomas) - Fix for plpgsql on BSDI - Add SQL_ASCII test case to the regression test (Tatsuo) - configure --with-mb now deprecated (Tatsuo) - NT fixes - NetBSD fixes (Johnny C. Lam ) - Fixes for Alpha compiles - New multibyte encodings - - - ---------------------------------------------------------------------- - - Release 6.5.3 - - Release date: 1999-10-13 - - This is basically a cleanup release for 6.5.2. We have added a new - PgAccess that was missing in 6.5.2, and installed an NT-specific fix. - - ---------------------------------------------------------------------- - -Migration to version 6.5.3 - - A dump/restore is *not* required for those running 6.5.*. - - ---------------------------------------------------------------------- - -Changes - - Updated version of pgaccess 0.98 - NT-specific patch - Fix dumping rules on inherited tables - - - ---------------------------------------------------------------------- - - Release 6.5.2 - - Release date: 1999-09-15 - - This is basically a cleanup release for 6.5.1. We have fixed a variety of - problems reported by 6.5.1 users. - - ---------------------------------------------------------------------- - -Migration to version 6.5.2 - - A dump/restore is *not* required for those running 6.5.*. - - ---------------------------------------------------------------------- - -Changes - - subselect+CASE fixes(Tom) - Add SHLIB_LINK setting for solaris_i386 and solaris_sparc ports(Daren Sefcik) - Fixes for CASE in WHERE join clauses(Tom) - Fix BTScan abort(Tom) - Repair the check for redundant UNIQUE and PRIMARY KEY indexes(Thomas) - Improve it so that it checks for multi-column constraints(Thomas) - Fix for Win32 making problem with MB enabled(Hiroki Kataoka) - Allow BSD yacc and bison to compile pl code(Bruce) - Fix SET NAMES working - int8 fixes(Thomas) - Fix vacuum's memory consumption(Hiroshi,Tatsuo) - Reduce the total memory consumption of vacuum(Tom) - Fix for timestamp(datetime) - Rule deparsing bugfixes(Tom) - Fix quoting problems in mkMakefile.tcldefs.sh.in and mkMakefile.tkdefs.sh.in(Tom) - This is to re-use space on index pages freed by vacuum(Vadim) - document -x for pg_dump(Bruce) - Fix for unary operators in rule deparser(Tom) - Comment out FileUnlink of excess segments during mdtruncate()(Tom) - Irix linking fix from Yu Cao >yucao@falcon.kla-tencor.com< - Repair logic error in LIKE: should not return LIKE_ABORT - when reach end of pattern before end of text(Tom) - Repair incorrect cleanup of heap memory allocation during transaction abort(Tom) - Updated version of pgaccess 0.98 - - - ---------------------------------------------------------------------- - - Release 6.5.1 - - Release date: 1999-07-15 - - This is basically a cleanup release for 6.5. We have fixed a variety of - problems reported by 6.5 users. - - ---------------------------------------------------------------------- - -Migration to version 6.5.1 - - A dump/restore is *not* required for those running 6.5. - - ---------------------------------------------------------------------- - -Changes - - Add NT README file - Portability fixes for linux_ppc, Irix, linux_alpha, OpenBSD, alpha - Remove QUERY_LIMIT, use SELECT...LIMIT - Fix for EXPLAIN on inheritance(Tom) - Patch to allow vacuum on multi-segment tables(Hiroshi) - R-Tree optimizer selectivity fix(Tom) - ACL file descriptor leak fix(Atsushi Ogawa) - New expresssion subtree code(Tom) - Avoid disk writes for read-only transactions(Vadim) - Fix for removal of temp tables if last transaction was aborted(Bruce) - Fix to prevent too large tuple from being created(Bruce) - plpgsql fixes - Allow port numbers 32k - 64k(Bruce) - Add ^ precidence(Bruce) - Rename sort files called pg_temp to pg_sorttemp(Bruce) - Fix for microseconds in time values(Tom) - Tutorial source cleanup - New linux_m68k port - Fix for sorting of NULL's in some cases(Tom) - Shared library dependencies fixed (Tom) - Fixed glitches affecting GROUP BY in subselects(Tom) - Fix some compiler warnings (Tomoaki Nishiyama) - Add Win1250 (Czech) support (Pavel Behal) - - - ---------------------------------------------------------------------- - - Release 6.5 - - Release date: 1999-06-09 - - This release marks a major step in the development team's mastery of the - source code we inherited from Berkeley. You will see we are now easily - adding major features, thanks to the increasing size and experience of our - world-wide development team. - - Here is a brief summary of the more notable changes: - - Multi-version concurrency control(MVCC) - - This removes our old table-level locking, and replaces it with a - locking system that is superior to most commercial database - systems. In a traditional system, each row that is modified is - locked until committed, preventing reads by other users. MVCC uses - the natural multi-version nature of PostgreSQL to allow readers to - continue reading consistent data during writer activity. Writers - continue to use the compact pg_log transaction system. This is all - performed without having to allocate a lock for every row like - traditional database systems. So, basically, we no longer are - restricted by simple table-level locking; we have something better - than row-level locking. - - Hot backups from pg_dump - - pg_dump takes advantage of the new MVCC features to give a - consistent database dump/backup while the database stays online - and available for queries. - - Numeric data type - - We now have a true numeric data type, with user-specified - precision. - - Temporary tables - - Temporary tables are guaranteed to have unique names within a - database session, and are destroyed on session exit. - - New SQL features - - We now have CASE, INTERSECT, and EXCEPT statement support. We have - new LIMIT/OFFSET, SET TRANSACTION ISOLATION LEVEL, SELECT ... FOR - UPDATE, and an improved LOCK TABLE command. - - Speedups - - We continue to speed up PostgreSQL, thanks to the variety of - talents within our team. We have sped up memory allocation, - optimization, table joins, and row transfer routines. - - Ports - - We continue to expand our port list, this time including Windows - NT/ix86 and NetBSD/arm32. - - Interfaces - - Most interfaces have new versions, and existing functionality has - been improved. - - Documentation - - New and updated material is present throughout the documentation. - New FAQs have been contributed for SGI and AIX platforms. The - Tutorial has introductory information on SQL from Stefan - Simkovics. For the User's Guide, there are reference pages - covering the postmaster and more utility programs, and a new - appendix contains details on date/time behavior. The - Administrator's Guide has a new chapter on troubleshooting from - Tom Lane. And the Programmer's Guide has a description of query - processing, also from Stefan, and details on obtaining the - PostgreSQL source tree via anonymous CVS and CVSup. - - ---------------------------------------------------------------------- - -Migration to version 6.5 - - A dump/restore using pg_dump is required for those wishing to migrate data - from any previous release of PostgreSQL. pg_upgrade can *not* be used to - upgrade to this release because the on-disk structure of the tables has - changed compared to previous releases. - - The new Multi-Version Concurrency Control (MVCC) features can give - somewhat different behaviors in multi-user environments. *Read and - understand the following section to ensure that your existing applications - will give you the behavior you need.* - - ---------------------------------------------------------------------- - - Multi-Version Concurrency Control - - Because readers in 6.5 don't lock data, regardless of transaction - isolation level, data read by one transaction can be overwritten by - another. In other words, if a row is returned by "SELECT" it doesn't mean - that this row really exists at the time it is returned (i.e. sometime - after the statement or transaction began) nor that the row is protected - from being deleted or updated by concurrent transactions before the - current transaction does a commit or rollback. - - To ensure the actual existence of a row and protect it against concurrent - updates one must use "SELECT FOR UPDATE" or an appropriate "LOCK TABLE" - statement. This should be taken into account when porting applications - from previous releases of PostgreSQL and other environments. - - Keep the above in mind if you are using "contrib/refint.*" triggers for - referential integrity. Additional techniques are required now. One way is - to use "LOCK parent_table IN SHARE ROW EXCLUSIVE MODE" command if a - transaction is going to update/delete a primary key and use "LOCK - parent_table IN SHARE MODE" command if a transaction is going to - update/insert a foreign key. - - Note: Note that if you run a transaction in SERIALIZABLE mode then you - must execute the "LOCK" commands above before execution of any DML - statement ("SELECT/INSERT/DELETE/UPDATE/FETCH/COPY_TO") in the - transaction. - - These inconveniences will disappear in the future when the ability to read - dirty (uncommitted) data (regardless of isolation level) and true - referential integrity will be implemented. - - ---------------------------------------------------------------------- - -Changes - - Bug Fixes - --------- - Fix text<->float8 and text<->float4 conversion functions(Thomas) - Fix for creating tables with mixed-case constraints(Billy) - Change exp()/pow() behavior to generate error on underflow/overflow(Jan) - Fix bug in pg_dump -z - Memory overrun cleanups(Tatsuo) - Fix for lo_import crash(Tatsuo) - Adjust handling of data type names to suppress double quotes(Thomas) - Use type coercion for matching columns and DEFAULT(Thomas) - Fix deadlock so it only checks once after one second of sleep(Bruce) - Fixes for aggregates and PL/pgsql(Hiroshi) - Fix for subquery crash(Vadim) - Fix for libpq function PQfnumber and case-insensitive names(Bahman Rafatjoo) - Fix for large object write-in-middle, no extra block, memory consumption(Tatsuo) - Fix for pg_dump -d or -D and quote special characters in INSERT - Repair serious problems with dynahash(Tom) - Fix INET/CIDR portability problems - Fix problem with selectivity error in ALTER TABLE ADD COLUMN(Bruce) - Fix executor so mergejoin of different column types works(Tom) - Fix for Alpha OR selectivity bug - Fix OR index selectivity problem(Bruce) - Fix so \d shows proper length for char()/varchar()(Ryan) - Fix tutorial code(Clark) - Improve destroyuser checking(Oliver) - Fix for Kerberos(Rodney McDuff) - Fix for dropping database while dirty buffers(Bruce) - Fix so sequence nextval() can be case-sensitive(Bruce) - Fix !!= operator - Drop buffers before destroying database files(Bruce) - Fix case where executor evaluates functions twice(Tatsuo) - Allow sequence nextval actions to be case-sensitive(Bruce) - Fix optimizer indexing not working for negative numbers(Bruce) - Fix for memory leak in executor with fjIsNull - Fix for aggregate memory leaks(Erik Riedel) - Allow username containing a dash GRANT permissions - Cleanup of NULL in inet types - Clean up system table bugs(Tom) - Fix problems of PAGER and \? command(Masaaki Sakaida) - Reduce default multi-segment file size limit to 1GB(Peter) - Fix for dumping of CREATE OPERATOR(Tom) - Fix for backward scanning of cursors(Hiroshi Inoue) - Fix for COPY FROM STDIN when using \i(Tom) - Fix for subselect is compared inside an expression(Jan) - Fix handling of error reporting while returning rows(Tom) - Fix problems with reference to array types(Tom,Jan) - Prevent UPDATE SET oid(Jan) - Fix pg_dump so -t option can handle case-sensitive tablenames - Fixes for GROUP BY in special cases(Tom, Jan) - Fix for memory leak in failed queries(Tom) - DEFAULT now supports mixed-case identifiers(Tom) - Fix for multi-segment uses of DROP/RENAME table, indexes(Ole Gjerde) - Disable use of pg_dump with both -o and -d options(Bruce) - Allow pg_dump to properly dump GROUP permissions(Bruce) - Fix GROUP BY in INSERT INTO table SELECT * FROM table2(Jan) - Fix for computations in views(Jan) - Fix for aggregates on array indexes(Tom) - Fix for DEFAULT handles single quotes in value requiring too many quotes - Fix security problem with non-super users importing/exporting large objects(Tom) - Rollback of transaction that creates table cleaned up properly(Tom) - Fix to allow long table and column names to generate proper serial names(Tom) - - Enhancements - ------------ - Add "vacuumdb" utility - Speed up libpq by allocating memory better(Tom) - EXPLAIN all indexes used(Tom) - Implement CASE, COALESCE, NULLIF expression(Thomas) - New pg_dump table output format(Constantin) - Add string min()/max() functions(Thomas) - Extend new type coercion techniques to aggregates(Thomas) - New moddatetime contrib(Terry) - Update to pgaccess 0.96(Constantin) - Add routines for single-byte "char" type(Thomas) - Improved substr() function(Thomas) - Improved multibyte handling(Tatsuo) - Multi-version concurrency control/MVCC(Vadim) - New Serialized mode(Vadim) - Fix for tables over 2gigs(Peter) - New SET TRANSACTION ISOLATION LEVEL(Vadim) - New LOCK TABLE IN ... MODE(Vadim) - Update ODBC driver(Byron) - New NUMERIC data type(Jan) - New SELECT FOR UPDATE(Vadim) - Handle "NaN" and "Infinity" for input values(Jan) - Improved date/year handling(Thomas) - Improved handling of backend connections(Magnus) - New options ELOG_TIMESTAMPS and USE_SYSLOG options for log files(Massimo) - New TCL_ARRAYS option(Massimo) - New INTERSECT and EXCEPT(Stefan) - New pg_index.indisprimary for primary key tracking(D'Arcy) - New pg_dump option to allow dropping of tables before creation(Brook) - Speedup of row output routines(Tom) - New READ COMMITTED isolation level(Vadim) - New TEMP tables/indexes(Bruce) - Prevent sorting if result is already sorted(Jan) - New memory allocation optimization(Jan) - Allow psql to do \p\g(Bruce) - Allow multiple rule actions(Jan) - Added LIMIT/OFFSET functionality(Jan) - Improve optimizer when joining a large number of tables(Bruce) - New intro to SQL from S. Simkovics' Master's Thesis (Stefan, Thomas) - New intro to backend processing from S. Simkovics' Master's Thesis (Stefan) - Improved int8 support(Ryan Bradetich, Thomas, Tom) - New routines to convert between int8 and text/varchar types(Thomas) - New bushy plans, where meta-tables are joined(Bruce) - Enable right-hand queries by default(Bruce) - Allow reliable maximum number of backends to be set at configure time - (--with-maxbackends and postmaster switch (-N backends))(Tom) - GEQO default now 10 tables because of optimizer speedups(Tom) - Allow NULL=Var for MS-SQL portability(Michael, Bruce) - Modify contrib check_primary_key() so either "automatic" or "dependent"(Anand) - Allow psql \d on a view show query(Ryan) - Speedup for LIKE(Bruce) - Ecpg fixes/features, see src/interfaces/ecpg/ChangeLog file(Michael) - JDBC fixes/features, see src/interfaces/jdbc/CHANGELOG(Peter) - Make % operator have precedence like /(Bruce) - Add new postgres -O option to allow system table structure changes(Bruce) - Update contrib/pginterface/findoidjoins script(Tom) - Major speedup in vacuum of deleted rows with indexes(Vadim) - Allow non-SQL functions to run different versions based on arguments(Tom) - Add -E option that shows actual queries sent by \dt and friends(Masaaki Sakaida) - Add version number in start-up banners for psql(Masaaki Sakaida) - New contrib/vacuumlo removes large objects not referenced(Peter) - New initialization for table sizes so non-vacuumed tables perform better(Tom) - Improve error messages when a connection is rejected(Tom) - Support for arrays of char() and varchar() fields(Massimo) - Overhaul of hash code to increase reliability and performance(Tom) - Update to PyGreSQL 2.4(D'Arcy) - Changed debug options so -d4 and -d5 produce different node displays(Jan) - New pg_options: pretty_plan, pretty_parse, pretty_rewritten(Jan) - Better optimization statistics for system table access(Tom) - Better handling of non-default block sizes(Massimo) - Improve GEQO optimizer memory consumption(Tom) - UNION now suppports ORDER BY of columns not in target list(Jan) - Major libpq++ improvements(Vince Vielhaber) - pg_dump now uses -z(ACL's) as default(Bruce) - backend cache, memory speedups(Tom) - have pg_dump do everything in one snapshot transaction(Vadim) - fix for large object memory leakage, fix for pg_dumping(Tom) - INET type now respects netmask for comparisons - Make VACUUM ANALYZE only use a readlock(Vadim) - Allow VIEWs on UNIONS(Jan) - pg_dump now can generate consistent snapshots on active databases(Vadim) - - Source Tree Changes - ------------------- - Improve port matching(Tom) - Portability fixes for SunOS - Add NT/Win32 backend port and enable dynamic loading(Magnus and Daniel Horak) - New port to Cobalt Qube(Mips) running Linux(Tatsuo) - Port to NetBSD/m68k(Mr. Mutsuki Nakajima) - Port to NetBSD/sun3(Mr. Mutsuki Nakajima) - Port to NetBSD/macppc(Toshimi Aoki) - Fix for tcl/tk configuration(Vince) - Removed CURRENT keyword for rule queries(Jan) - NT dynamic loading now works(Daniel Horak) - Add ARM32 support(Andrew McMurry) - Better support for HPUX 11 and Unixware - Improve file handling to be more uniform, prevent file descriptor leak(Tom) - New install commands for plpgsql(Jan) - - - ---------------------------------------------------------------------- - - Release 6.4.2 - - Release date: 1998-12-20 - - The 6.4.1 release was improperly packaged. This also has one additional - bug fix. - - ---------------------------------------------------------------------- - -Migration to version 6.4.2 - - A dump/restore is *not* required for those running 6.4.*. - - ---------------------------------------------------------------------- - -Changes - - Fix for datetime constant problem on some platforms(Thomas) - - ---------------------------------------------------------------------- - - Release 6.4.1 - - Release date: 1998-12-18 - - This is basically a cleanup release for 6.4. We have fixed a variety of - problems reported by 6.4 users. - - ---------------------------------------------------------------------- - -Migration to version 6.4.1 - - A dump/restore is *not* required for those running 6.4. - - ---------------------------------------------------------------------- - -Changes - - Add pg_dump -N flag to force double quotes around identifiers. This is - the default(Thomas) - Fix for NOT in where clause causing crash(Bruce) - EXPLAIN VERBOSE coredump fix(Vadim) - Fix shared-library problems on Linux - Fix test for table existance to allow mixed-case and whitespace in - the table name(Thomas) - Fix a couple of pg_dump bugs - Configure matches template/.similar entries better(Tom) - Change builtin function names from SPI_* to spi_* - OR WHERE clause fix(Vadim) - Fixes for mixed-case table names(Billy) - contrib/linux/postgres.init.csh/sh fix(Thomas) - libpq memory overrun fix - SunOS fixes(Tom) - Change exp() behavior to generate error on underflow(Thomas) - pg_dump fixes for memory leak, inheritance constraints, layout change - update pgaccess to 0.93 - Fix prototype for 64-bit platforms - Multibyte fixes(Tatsuo) - New ecpg man page - Fix memory overruns(Tatsuo) - Fix for lo_import() crash(Bruce) - Better search for install program(Tom) - Timezone fixes(Tom) - HPUX fixes(Tom) - Use implicit type coercion for matching DEFAULT values(Thomas) - Add routines to help with single-byte (internal) character type(Thomas) - Compilation of libpq for Win32 fixes(Magnus) - Upgrade to PyGreSQL 2.2(D'Arcy) - - ---------------------------------------------------------------------- - - Release 6.4 - - Release date: 1998-10-30 - - There are *many* new features and improvements in this release. Thanks to - our developers and maintainers, nearly every aspect of the system has - received some attention since the previous release. Here is a brief, - incomplete summary: - - * Views and rules are now functional thanks to extensive new code in the - rewrite rules system from Jan Wieck. He also wrote a chapter on it for - the Programmer's Guide. - - * Jan also contributed a second procedural language, PL/pgSQL, to go - with the original PL/pgTCL procedural language he contributed last - release. - - * We have optional multiple-byte character set support from Tatsuo Iishi - to complement our existing locale support. - - * Client/server communications has been cleaned up, with better support - for asynchronous messages and interrupts thanks to Tom Lane. - - * The parser will now perform automatic type coercion to match arguments - to available operators and functions, and to match columns and - expressions with target columns. This uses a generic mechanism which - supports the type extensibility features of PostgreSQL. There is a new - chapter in the User's Guide which covers this topic. - - * Three new data types have been added. Two types, inet and cidr, - support various forms of IP network, subnet, and machine addressing. - There is now an 8-byte integer type available on some platforms. See - the chapter on data types in the User's Guide for details. A fourth - type, serial, is now supported by the parser as an amalgam of the int4 - type, a sequence, and a unique index. - - * Several more SQL92-compatible syntax features have been added, - including "INSERT DEFAULT VALUES" - - * The automatic configuration and installation system has received some - attention, and should be more robust for more platforms than it has - ever been. - - ---------------------------------------------------------------------- - -Migration to version 6.4 - - A dump/restore using pg_dump or pg_dumpall is required for those wishing - to migrate data from any previous release of PostgreSQL. - - ---------------------------------------------------------------------- - -Changes - - Bug Fixes - --------- - Fix for a tiny memory leak in PQsetdb/PQfinish(Bryan) - Remove char2-16 data types, use char/varchar(Darren) - Pqfn not handles a NOTICE message(Anders) - Reduced busywaiting overhead for spinlocks with many backends (dg) - Stuck spinlock detection (dg) - Fix up "ISO-style" timespan decoding and encoding(Thomas) - Fix problem with table drop after rollback of transaction(Vadim) - Change error message and remove non-functional update message(Vadim) - Fix for COPY array checking - Fix for SELECT 1 UNION SELECT NULL - Fix for buffer leaks in large object calls(Pascal) - Change owner from oid to int4 type(Bruce) - Fix a bug in the oracle compatibility functions btrim() ltrim() and rtrim() - Fix for shared invalidation cache overflow(Massimo) - Prevent file descriptor leaks in failed COPY's(Bruce) - Fix memory leak in libpgtcl's pg_select(Constantin) - Fix problems with username/passwords over 8 characters(Tom) - Fix problems with handling of asynchronous NOTIFY in backend(Tom) - Fix of many bad system table entries(Tom) - - Enhancements - ------------ - Upgrade ecpg and ecpglib,see src/interfaces/ecpc/ChangeLog(Michael) - Show the index used in an EXPLAIN(Zeugswetter) - EXPLAIN invokes rule system and shows plan(s) for rewritten queries(Jan) - Multibyte awareness of many data types and functions, via configure(Tatsuo) - New configure --with-mb option(Tatsuo) - New initdb --pgencoding option(Tatsuo) - New createdb -E multibyte option(Tatsuo) - Select version(); now returns PostgreSQL version(Jeroen) - Libpq now allows asynchronous clients(Tom) - Allow cancel from client of backend query(Tom) - Psql now cancels query with Control-C(Tom) - Libpq users need not issue dummy queries to get NOTIFY messages(Tom) - NOTIFY now sends sender's PID, so you can tell whether it was your own(Tom) - PGresult struct now includes associated error message, if any(Tom) - Define "tz_hour" and "tz_minute" arguments to date_part()(Thomas) - Add routines to convert between varchar and bpchar(Thomas) - Add routines to allow sizing of varchar and bpchar into target columns(Thomas) - Add bit flags to support timezonehour and minute in data retrieval(Thomas) - Allow more variations on valid floating point numbers (e.g. ".1", "1e6")(Thomas) - Fixes for unary minus parsing with leading spaces(Thomas) - Implement TIMEZONE_HOUR, TIMEZONE_MINUTE per SQL92 specs(Thomas) - Check for and properly ignore FOREIGN KEY column constraints(Thomas) - Define USER as synonym for CURRENT_USER per SQL92 specs(Thomas) - Enable HAVING clause but no fixes elsewhere yet. - Make "char" type a synonym for "char(1)" (actually implemented as bpchar)(Thomas) - Save string type if specified for DEFAULT clause handling(Thomas) - Coerce operations involving different data types(Thomas) - Allow some index use for columns of different types(Thomas) - Add capabilities for automatic type conversion(Thomas) - Cleanups for large objects, so file is truncated on open(Peter) - Readline cleanups(Tom) - Allow psql \f \ to make spaces as delimiter(Bruce) - Pass pg_attribute.atttypmod to the frontend for column field lengths(Tom,Bruce) - Msql compatibility library in /contrib(Aldrin) - Remove the requirement that ORDER/GROUP BY clause identifiers be - included in the target list(David) - Convert columns to match columns in UNION clauses(Thomas) - Remove fork()/exec() and only do fork()(Bruce) - Jdbc cleanups(Peter) - Show backend status on ps command line(only works on some platforms)(Bruce) - Pg_hba.conf now has a sameuser option in the database field - Make lo_unlink take oid param, not int4 - New DISABLE_COMPLEX_MACRO for compilers that can't handle our macros(Bruce) - Libpgtcl now handles NOTIFY as a Tcl event, need not send dummy queries(Tom) - libpgtcl cleanups(Tom) - Add -error option to libpgtcl's pg_result command(Tom) - New locale patch, see docs/README/locale(Oleg) - Fix for pg_dump so CONSTRAINT and CHECK syntax is correct(ccb) - New contrib/lo code for large object orphan removal(Peter) - New psql command "SET CLIENT_ENCODING TO 'encoding'" for multibytes - feature, see /doc/README.mb(Tatsuo) - /contrib/noupdate code to revoke update permission on a column - Libpq can now be compiled on win32(Magnus) - Add PQsetdbLogin() in libpq - New 8-byte integer type, checked by configure for OS support(Thomas) - Better support for quoted table/column names(Thomas) - Surround table and column names with double-quotes in pg_dump(Thomas) - PQreset() now works with passwords(Tom) - Handle case of GROUP BY target list column number out of range(David) - Allow UNION in subselects - Add auto-size to screen to \d? commands(Bruce) - Use UNION to show all \d? results in one query(Bruce) - Add \d? field search feature(Bruce) - Pg_dump issues fewer \connect requests(Tom) - Make pg_dump -z flag work better, document it in manual page(Tom) - Add HAVING clause with full support for subselects and unions(Stephan) - Full text indexing routines in contrib/fulltextindex(Maarten) - Transaction ids now stored in shared memory(Vadim) - New PGCLIENTENCODING when issuing COPY command(Tatsuo) - Support for SQL92 syntax "SET NAMES"(Tatsuo) - Support for LATIN2-5(Tatsuo) - Add UNICODE regression test case(Tatsuo) - Lock manager cleanup, new locking modes for LLL(Vadim) - Allow index use with OR clauses(Bruce) - Allows "SELECT NULL ORDER BY 1;" - Explain VERBOSE prints the plan, and now pretty-prints the plan to - the postmaster log file(Bruce) - Add indexes display to \d command(Bruce) - Allow GROUP BY on functions(David) - New pg_class.relkind for large objects(Bruce) - New way to send libpq NOTICE messages to a different location(Tom) - New \w write command to psql(Bruce) - New /contrib/findoidjoins scans oid columns to find join relationships(Bruce) - Allow binary-compatible indexes to be considered when checking for valid - Indexes for restriction clauses containing a constant(Thomas) - New ISBN/ISSN code in /contrib/isbn_issn - Allow NOT LIKE, IN, NOT IN, BETWEEN, and NOT BETWEEN constraint(Thomas) - New rewrite system fixes many problems with rules and views(Jan) - * Rules on relations work - * Event qualifications on insert/update/delete work - * New OLD variable to reference CURRENT, CURRENT will be remove in future - * Update rules can reference NEW and OLD in rule qualifications/actions - * Insert/update/delete rules on views work - * Multiple rule actions are now supported, surrounded by parentheses - * Regular users can create views/rules on tables they have RULE permits - * Rules and views inherit the permissions on the creator - * No rules at the column level - * No UPDATE NEW/OLD rules - * New pg_tables, pg_indexes, pg_rules and pg_views system views - * Only a single action on SELECT rules - * Total rewrite overhaul, perhaps for 6.5 - * handle subselects - * handle aggregates on views - * handle insert into select from view works - System indexes are now multi-key(Bruce) - Oidint2, oidint4, and oidname types are removed(Bruce) - Use system cache for more system table lookups(Bruce) - New backend programming language PL/pgSQL in backend/pl(Jan) - New SERIAL data type, auto-creates sequence/index(Thomas) - Enable assert checking without a recompile(Massimo) - User lock enhancements(Massimo) - New setval() command to set sequence value(Massimo) - Auto-remove unix socket file on start-up if no postmaster running(Massimo) - Conditional trace package(Massimo) - New UNLISTEN command(Massimo) - Psql and libpq now compile under win32 using win32.mak(Magnus) - Lo_read no longer stores trailing NULL(Bruce) - Identifiers are now truncated to 31 characters internally(Bruce) - Createuser options now availble on the command line - Code for 64-bit integer supported added, configure tested, int8 type(Thomas) - Prevent file descriptor leaf from failed COPY(Bruce) - New pg_upgrade command(Bruce) - Updated /contrib directories(Massimo) - New CREATE TABLE DEFAULT VALUES statement available(Thomas) - New INSERT INTO TABLE DEFAULT VALUES statement available(Thomas) - New DECLARE and FETCH feature(Thomas) - libpq's internal structures now not exported(Tom) - Allow up to 8 key indexes(Bruce) - Remove ARCHIVE keyword, that is no longer used(Thomas) - pg_dump -n flag to supress quotes around indentifiers - disable system columns for views(Jan) - new INET and CIDR types for network addresses(TomH, Paul) - no more double quotes in psql output - pg_dump now dumps views(Terry) - new SET QUERY_LIMIT(Tatsuo,Jan) - - Source Tree Changes - ------------------- - /contrib cleanup(Jun) - Inline some small functions called for every row(Bruce) - Alpha/linux fixes - Hp/UX cleanups(Tom) - Multibyte regression tests(Soonmyung.) - Remove --disabled options from configure - Define PGDOC to use POSTGRESDIR by default - Make regression optional - Remove extra braces code to pgindent(Bruce) - Add bsdi shared library support(Bruce) - New --without-CXX support configure option(Brook) - New FAQ_CVS - Update backend flowchart in tools/backend(Bruce) - Change atttypmod from int16 to int32(Bruce, Tom) - Getrusage() fix for platforms that do not have it(Tom) - Add PQconnectdb, PGUSER, PGPASSWORD to libpq man page - NS32K platform fixes(Phil Nelson, John Buller) - Sco 7/UnixWare 2.x fixes(Billy,others) - Sparc/Solaris 2.5 fixes(Ryan) - Pgbuiltin.3 is obsolete, move to doc files(Thomas) - Even more documention(Thomas) - Nextstep support(Jacek) - Aix support(David) - pginterface manual page(Bruce) - shared libraries all have version numbers - merged all OS-specific shared library defines into one file - smarter TCL/TK configuration checking(Billy) - smarter perl configuration(Brook) - configure uses supplied install-sh if no install script found(Tom) - new Makefile.shlib for shared library configuration(Tom) - - ---------------------------------------------------------------------- - - Release 6.3.2 - - Release date: 1998-04-07 - - This is a bug-fix release for 6.3.x. Refer to the release notes for - version 6.3 for a more complete summary of new features. - - Summary: - - * Repairs automatic configuration support for some platforms, including - Linux, from breakage inadvertently introduced in version 6.3.1. - - * Correctly handles function calls on the left side of BETWEEN and LIKE - clauses. - - A dump/restore is NOT required for those running 6.3 or 6.3.1. A make - distclean, make, and make install is all that is required. This last step - should be performed while the postmaster is not running. You should - re-link any custom applications that use PostgreSQL libraries. - - For upgrades from pre-6.3 installations, refer to the installation and - migration instructions for version 6.3. - - ---------------------------------------------------------------------- - -Changes - - Configure detection improvements for tcl/tk(Brook Milligan, Alvin) - Manual page improvements(Bruce) - BETWEEN and LIKE fix(Thomas) - fix for psql \connect used by pg_dump(Oliver Elphick) - New odbc driver - pgaccess, version 0.86 - qsort removed, now uses libc version, cleanups(Jeroen) - fix for buffer over-runs detected(Maurice Gittens) - fix for buffer overrun in libpgtcl(Randy Kunkee) - fix for UNION with DISTINCT or ORDER BY(Bruce) - gettimeofday configure check(Doug Winterburn) - Fix "indexes not used" bug(Vadim) - docs additions(Thomas) - Fix for backend memory leak(Bruce) - libreadline cleanup(Erwan MAS) - Remove DISTDIR(Bruce) - Makefile dependency cleanup(Jeroen van Vianen) - ASSERT fixes(Bruce) - - - ---------------------------------------------------------------------- - - Release 6.3.1 - - Release date: 1998-03-23 - - Summary: - - * Additional support for multibyte character sets. - - * Repair byte ordering for mixed-endian clients and servers. - - * Minor updates to allowed SQL syntax. - - * Improvements to the configuration autodetection for installation. - - A dump/restore is NOT required for those running 6.3. A make distclean, - make, and make install is all that is required. This last step should be - performed while the postmaster is not running. You should re-link any - custom applications that use PostgreSQL libraries. - - For upgrades from pre-6.3 installations, refer to the installation and - migration instructions for version 6.3. - - ---------------------------------------------------------------------- - -Changes - - ecpg cleanup/fixes, now version 1.1(Michael Meskes) - pg_user cleanup(Bruce) - large object fix for pg_dump and tclsh (alvin) - LIKE fix for multiple adjacent underscores - fix for redefining builtin functions(Thomas) - ultrix4 cleanup - upgrade to pg_access 0.83 - updated CLUSTER manual page - multibyte character set support, see doc/README.mb(Tatsuo) - configure --with-pgport fix - pg_ident fix - big-endian fix for backend communications(Kataoka) - SUBSTR() and substring() fix(Jan) - several jdbc fixes(Peter) - libpgtcl improvements, see libptcl/README(Randy Kunkee) - Fix for "Datasize = 0" error(Vadim) - Prevent \do from wrapping(Bruce) - Remove duplicate Russian character set entries - Sunos4 cleanup - Allow optional TABLE keyword in LOCK and SELECT INTO(Thomas) - CREATE SEQUENCE options to allow a negative integer(Thomas) - Add "PASSWORD" as an allowed column identifier(Thomas) - Add checks for UNION target fields(Bruce) - Fix Alpha port(Dwayne Bailey) - Fix for text arrays containing quotes(Doug Gibson) - Solaris compile fix(Albert Chin-A-Young) - Better identify tcl and tk libs and includes(Bruce) - - - ---------------------------------------------------------------------- - - Release 6.3 - - Release date: 1998-03-01 - - There are *many* new features and improvements in this release. Here is a - brief, incomplete summary: - - * Many new SQL features, including full SQL92 subselect capability - (everything is here but target-list subselects). - - * Support for client-side environment variables to specify time zone and - date style. - - * Socket interface for client/server connection. This is the default now - so you may need to start postmaster with the "-i" flag. - - * Better password authorization mechanisms. Default table permissions - have changed. - - * Old-style time travel has been removed. Performance has been improved. - - Note: Bruce Momjian wrote the following notes to introduce the new - release. - - There are some general 6.3 issues that I want to mention. These are only - the big items that can not be described in one sentence. A review of the - detailed changes list is still needed. - - First, we now have subselects. Now that we have them, I would like to - mention that without subselects, SQL is a very limited language. - Subselects are a major feature, and you should review your code for places - where subselects provide a better solution for your queries. I think you - will find that there are more uses for subselects than you may think. - Vadim has put us on the big SQL map with subselects, and fully functional - ones too. The only thing you can't do with subselects is to use them in - the target list. - - Second, 6.3 uses Unix domain sockets rather than TCP/IP by default. To - enable connections from other machines, you have to use the new postmaster - -i option, and of course edit "pg_hba.conf". Also, for this reason, the - format of "pg_hba.conf" has changed. - - Third, char() fields will now allow faster access than varchar() or text. - Specifically, the text and varchar() have a penalty for access to any - columns after the first column of this type. char() used to also have this - access penalty, but it no longer does. This may suggest that you redesign - some of your tables, especially if you have short character columns that - you have defined as varchar() or text. This and other changes make 6.3 - even faster than earlier releases. - - We now have passwords definable independent of any Unix file. There are - new SQL USER commands. See the Administrator's Guide for more information. - There is a new table, pg_shadow, which is used to store user information - and user passwords, and it by default only SELECT-able by the postgres - super-user. pg_user is now a view of pg_shadow, and is SELECT-able by - PUBLIC. You should keep using pg_user in your application without changes. - - User-created tables now no longer have SELECT permission to PUBLIC by - default. This was done because the ANSI standard requires it. You can of - course GRANT any permissions you want after the table is created. System - tables continue to be SELECT-able by PUBLIC. - - We also have real deadlock detection code. No more sixty-second timeouts. - And the new locking code implements a FIFO better, so there should be less - resource starvation during heavy use. - - Many complaints have been made about inadequate documentation in previous - releases. Thomas has put much effort into many new manuals for this - release. Check out the doc/ directory. - - For performance reasons, time travel is gone, but can be implemented using - triggers (see "pgsql/contrib/spi/README"). Please check out the new \d - command for types, operators, etc. Also, views have their own permissions - now, not based on the underlying tables, so permissions on them have to be - set separately. Check "/pgsql/interfaces" for some new ways to talk to - PostgreSQL. - - This is the first release that really required an explanation for existing - users. In many ways, this was necessary because the new release removes - many limitations, and the work-arounds people were using are no longer - needed. - - ---------------------------------------------------------------------- - -Migration to version 6.3 - - A dump/restore using pg_dump or pg_dumpall is required for those wishing - to migrate data from any previous release of PostgreSQL. - - ---------------------------------------------------------------------- - -Changes - - Bug Fixes - --------- - Fix binary cursors broken by MOVE implementation(Vadim) - Fix for tcl library crash(Jan) - Fix for array handling, from Gerhard Hintermayer - Fix acl error, and remove duplicate pqtrace(Bruce) - Fix psql \e for empty file(Bruce) - Fix for textcat on varchar() fields(Bruce) - Fix for DBT Sendproc (Zeugswetter Andres) - Fix vacuum analyze syntax problem(Bruce) - Fix for international identifiers(Tatsuo) - Fix aggregates on inherited tables(Bruce) - Fix substr() for out-of-bounds data - Fix for select 1=1 or 2=2, select 1=1 and 2=2, and select sum(2+2)(Bruce) - Fix notty output to show status result. -q option still turns it off(Bruce) - Fix for count(*), aggs with views and multiple tables and sum(3)(Bruce) - Fix cluster(Bruce) - Fix for PQtrace start/stop several times(Bruce) - Fix a variety of locking problems like newer lock waiters getting - lock before older waiters, and having readlock people not share - locks if a writer is waiting for a lock, and waiting writers not - getting priority over waiting readers(Bruce) - Fix crashes in psql when executing queries from external files(James) - Fix problem with multiple order by columns, with the first one having - NULL values(Jeroen) - Use correct hash table support functions for float8 and int4(Thomas) - Re-enable JOIN= option in CREATE OPERATOR statement (Thomas) - Change precedence for boolean operators to match expected behavior(Thomas) - Generate elog(ERROR) on over-large integer(Bruce) - Allow multiple-argument functions in constraint clauses(Thomas) - Check boolean input literals for 'true','false','yes','no','1','0' - and throw elog(ERROR) if unrecognized(Thomas) - Major large objects fix - Fix for GROUP BY showing duplicates(Vadim) - Fix for index scans in MergeJion(Vadim) - - Enhancements - ------------ - Subselects with EXISTS, IN, ALL, ANY keywords (Vadim, Bruce, Thomas) - New User Manual(Thomas, others) - Speedup by inlining some frequently-called functions - Real deadlock detection, no more timeouts(Bruce) - Add SQL92 "constants" CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP, - CURRENT_USER(Thomas) - Modify constraint syntax to be SQL92-compliant(Thomas) - Implement SQL92 PRIMARY KEY and UNIQUE clauses using indexes(Thomas) - Recognize SQL92 syntax for FOREIGN KEY. Throw elog notice(Thomas) - Allow NOT NULL UNIQUE constraint clause (each allowed separately before)(Thomas) - Allow PostgreSQL-style casting ("::") of non-constants(Thomas) - Add support for SQL3 TRUE and FALSE boolean constants(Thomas) - Support SQL92 syntax for IS TRUE/IS FALSE/IS NOT TRUE/IS NOT FALSE(Thomas) - Allow shorter strings for boolean literals (e.g. "t", "tr", "tru")(Thomas) - Allow SQL92 delimited identifiers(Thomas) - Implement SQL92 binary and hexadecimal string decoding (b'10' and x'1F')(Thomas) - Support SQL92 syntax for type coercion of literal strings - (e.g. "DATETIME 'now'")(Thomas) - Add conversions for int2, int4, and OID types to and from text(Thomas) - Use shared lock when building indexes(Vadim) - Free memory allocated for an user query inside transaction block after - this query is done, was turned off in <= 6.2.1(Vadim) - New SQL statement CREATE PROCEDURAL LANGUAGE(Jan) - New PostgreSQL Procedural Language (PL) backend interface(Jan) - Rename pg_dump -H option to -h(Bruce) - Add Java support for passwords, European dates(Peter) - Use indexes for LIKE and ~, !~ operations(Bruce) - Add hash functions for datetime and timespan(Thomas) - Time Travel removed(Vadim, Bruce) - Add paging for \d and \z, and fix \i(Bruce) - Add Unix domain socket support to backend and to frontend library(Goran) - Implement CREATE DATABASE/WITH LOCATION and initlocation utility(Thomas) - Allow more SQL92 and/or PostgreSQL reserved words as column identifiers(Thomas) - Augment support for SQL92 SET TIME ZONE...(Thomas) - SET/SHOW/RESET TIME ZONE uses TZ backend environment variable(Thomas) - Implement SET keyword = DEFAULT and SET TIME ZONE DEFAULT(Thomas) - Enable SET TIME ZONE using TZ environment variable(Thomas) - Add PGDATESTYLE environment variable to frontend and backend initialization(Thomas) - Add PGTZ, PGCOSTHEAP, PGCOSTINDEX, PGRPLANS, PGGEQO - frontend library initialization environment variables(Thomas) - Regression tests time zone automatically set with "setenv PGTZ PST8PDT"(Thomas) - Add pg_description table for info on tables, columns, operators, types, and - aggregates(Bruce) - Increase 16 char limit on system table/index names to 32 characters(Bruce) - Rename system indexes(Bruce) - Add 'GERMAN' option to SET DATESTYLE(Thomas) - Define an "ISO-style" timespan output format with "hh:mm:ss" fields(Thomas) - Allow fractional values for delta times (e.g. '2.5 days')(Thomas) - Validate numeric input more carefully for delta times(Thomas) - Implement day of year as possible input to date_part()(Thomas) - Define timespan_finite() and text_timespan() functions(Thomas) - Remove archive stuff(Bruce) - Allow for a pg_password authentication database that is separate from - the system password file(Todd) - Dump ACLs, GRANT, REVOKE permissions(Matt) - Define text, varchar, and bpchar string length functions(Thomas) - Fix Query handling for inheritance, and cost computations(Bruce) - Implement CREATE TABLE/AS SELECT (alternative to SELECT/INTO)(Thomas) - Allow NOT, IS NULL, IS NOT NULL in constraints(Thomas) - Implement UNIONs for SELECT(Bruce) - Add UNION, GROUP, DISTINCT to INSERT(Bruce) - varchar() stores only necessary bytes on disk(Bruce) - Fix for BLOBs(Peter) - Mega-Patch for JDBC...see README_6.3 for list of changes(Peter) - Remove unused "option" from PQconnectdb() - New LOCK command and lock manual page describing deadlocks(Bruce) - Add new psql \da, \dd, \df, \do, \dS, and \dT commands(Bruce) - Enhance psql \z to show sequences(Bruce) - Show NOT NULL and DEFAULT in psql \d table(Bruce) - New psql .psqlrc file start-up(Andrew) - Modify sample start-up script in contrib/linux to show syslog(Thomas) - New types for IP and MAC addresses in contrib/ip_and_mac(TomH) - Unix system time conversions with date/time types in contrib/unixdate(Thomas) - Update of contrib stuff(Massimo) - Add Unix socket support to DBD::Pg(Goran) - New python interface (PyGreSQL 2.0)(D'Arcy) - New frontend/backend protocol has a version number, network byte order(Phil) - Security features in pg_hba.conf enhanced and documented, many cleanups(Phil) - CHAR() now faster access than VARCHAR() or TEXT - ecpg embedded SQL preprocessor - Reduce system column overhead(Vadmin) - Remove pg_time table(Vadim) - Add pg_type attribute to identify types that need length (bpchar, varchar) - Add report of offending line when COPY command fails - Allow VIEW permissions to be set separately from the underlying tables. - For security, use GRANT/REVOKE on views as appropriate(Jan) - Tables now have no default GRANT SELECT TO PUBLIC. You must - explicitly grant such permissions. - Clean up tutorial examples(Darren) - - Source Tree Changes - ------------------- - Add new html development tools, and flow chart in /tools/backend - Fix for SCO compiles - Stratus computer port Robert Gillies - Added support for shlib for BSD44_derived & i386_solaris - Make configure more automated(Brook) - Add script to check regression test results - Break parser functions into smaller files, group together(Bruce) - Rename heap_create to heap_create_and_catalog, rename heap_creatr - to heap_create()(Bruce) - Sparc/Linux patch for locking(TomS) - Remove PORTNAME and reorganize port-specific stuff(Marc) - Add optimizer README file(Bruce) - Remove some recursion in optimizer and clean up some code there(Bruce) - Fix for NetBSD locking(Henry) - Fix for libptcl make(Tatsuo) - AIX patch(Darren) - Change IS TRUE, IS FALSE, ... to expressions using "=" rather than - function calls to istrue() or isfalse() to allow optimization(Thomas) - Various fixes NetBSD/Sparc related(TomH) - Alpha linux locking(Travis,Ryan) - Change elog(WARN) to elog(ERROR)(Bruce) - FAQ for FreeBSD(Marc) - Bring in the PostODBC source tree as part of our standard distribution(Marc) - A minor patch for HP/UX 10 vs 9(Stan) - New pg_attribute.atttypmod for type-specific info like varchar length(Bruce) - Unixware patches(Billy) - New i386 'lock' for spin lock asm(Billy) - Support for multiplexed backends is removed - Start an OpenBSD port - Start an AUX port - Start a Cygnus port - Add string functions to regression suite(Thomas) - Expand a few function names formerly truncated to 16 characters(Thomas) - Remove un-needed malloc() calls and replace with palloc()(Bruce) - - ---------------------------------------------------------------------- - - Release 6.2.1 - - Release date: 1997-10-17 - - 6.2.1 is a bug-fix and usability release on 6.2. - - Summary: - - * Allow strings to span lines, per SQL92. - - * Include example trigger function for inserting user names on table - updates. - - This is a minor bug-fix release on 6.2. For upgrades from pre-6.2 systems, - a full dump/reload is required. Refer to the 6.2 release notes for - instructions. - - ---------------------------------------------------------------------- - -Migration from version 6.2 to version 6.2.1 - - This is a minor bug-fix release. A dump/reload is not required from - version 6.2, but is required from any release prior to 6.2. - - In upgrading from version 6.2, if you choose to dump/reload you will find - that avg(money) is now calculated correctly. All other bug fixes take - effect upon updating the executables. - - Another way to avoid dump/reload is to use the following SQL command from - "psql" to update the existing system table: - - update pg_aggregate set aggfinalfn = 'cash_div_flt8' - where aggname = 'avg' and aggbasetype = 790; - - This will need to be done to every existing database, including template1. - - ---------------------------------------------------------------------- - -Changes - - Allow TIME and TYPE column names(Thomas) - Allow larger range of true/false as boolean values(Thomas) - Support output of "now" and "current"(Thomas) - Handle DEFAULT with INSERT of NULL properly(Vadim) - Fix for relation reference counts problem in buffer manager(Vadim) - Allow strings to span lines, like ANSI(Thomas) - Fix for backward cursor with ORDER BY(Vadim) - Fix avg(cash) computation(Thomas) - Fix for specifying a column twice in ORDER/GROUP BY(Vadim) - Documented new libpq function to return affected rows, PQcmdTuples(Bruce) - Trigger function for inserting user names for INSERT/UPDATE(Brook Milligan) - - - ---------------------------------------------------------------------- - - Release 6.2 - - Release date: 1997-10-02 - - A dump/restore is required for those wishing to migrate data from previous - releases of PostgreSQL. - - ---------------------------------------------------------------------- - -Migration from version 6.1 to version 6.2 - - This migration requires a complete dump of the 6.1 database and a restore - of the database in 6.2. - - Note that the "pg_dump" and "pg_dumpall" utility from 6.2 should be used - to dump the 6.1 database. - - ---------------------------------------------------------------------- - -Migration from version 1.x to version 6.2 - - Those migrating from earlier 1.* releases should first upgrade to 1.09 - because the COPY output format was improved from the 1.02 release. - - ---------------------------------------------------------------------- - -Changes - - Bug Fixes - --------- - Fix problems with pg_dump for inheritance, sequences, archive tables(Bruce) - Fix compile errors on overflow due to shifts, unsigned, and bad prototypes - from Solaris(Diab Jerius) - Fix bugs in geometric line arithmetic (bad intersection calculations)(Thomas) - Check for geometric intersections at endpoints to avoid rounding ugliness(Thomas) - Catch non-functional delete attempts(Vadim) - Change time function names to be more consistent(Michael Reifenberg) - Check for zero divides(Michael Reifenberg) - Fix very old bug which made tuples changed/inserted by a commnd - visible to the command itself (so we had multiple update of - updated tuples, etc)(Vadim) - Fix for SELECT null, 'fail' FROM pg_am (Patrick) - SELECT NULL as EMPTY_FIELD now allowed(Patrick) - Remove un-needed signal stuff from contrib/pginterface - Fix OR (where x != 1 or x isnull didn't return tuples with x NULL) (Vadim) - Fix time_cmp function (Vadim) - Fix handling of functions with non-attribute first argument in - WHERE clauses (Vadim) - Fix GROUP BY when order of entries is different from order - in target list (Vadim) - Fix pg_dump for aggregates without sfunc1 (Vadim) - - Enhancements - ------------ - Default genetic optimizer GEQO parameter is now 8(Bruce) - Allow use parameters in target list having aggregates in functions(Vadim) - Added JDBC driver as an interface(Adrian & Peter) - pg_password utility - Return number of tuples inserted/affected by INSERT/UPDATE/DELETE etc.(Vadim) - Triggers implemented with CREATE TRIGGER (SQL3)(Vadim) - SPI (Server Programming Interface) allows execution of queries inside - C-functions (Vadim) - NOT NULL implemented (SQL92)(Robson Paniago de Miranda) - Include reserved words for string handling, outer joins, and unions(Thomas) - Implement extended comments ("/* ... */") using exclusive states(Thomas) - Add "//" single-line comments(Bruce) - Remove some restrictions on characters in operator names(Thomas) - DEFAULT and CONSTRAINT for tables implemented (SQL92)(Vadim & Thomas) - Add text concatenation operator and function (SQL92)(Thomas) - Support WITH TIME ZONE syntax (SQL92)(Thomas) - Support INTERVAL unit TO unit syntax (SQL92)(Thomas) - Define types DOUBLE PRECISION, INTERVAL, CHARACTER, - and CHARACTER VARYING (SQL92)(Thomas) - Define type FLOAT(p) and rudimentary DECIMAL(p,s), NUMERIC(p,s) (SQL92)(Thomas) - Define EXTRACT(), POSITION(), SUBSTRING(), and TRIM() (SQL92)(Thomas) - Define CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP (SQL92)(Thomas) - Add syntax and warnings for UNION, HAVING, INNER and OUTER JOIN (SQL92)(Thomas) - Add more reserved words, mostly for SQL92 compliance(Thomas) - Allow hh:mm:ss time entry for timespan/reltime types(Thomas) - Add center() routines for lseg, path, polygon(Thomas) - Add distance() routines for circle-polygon, polygon-polygon(Thomas) - Check explicitly for points and polygons contained within polygons - using an axis-crossing algorithm(Thomas) - Add routine to convert circle-box(Thomas) - Merge conflicting operators for different geometric data types(Thomas) - Replace distance operator "<===>" with "<->"(Thomas) - Replace "above" operator "!^" with ">^" and "below" operator "!|" with "<^"(Thomas) - Add routines for text trimming on both ends, substring, and string position(Thomas) - Added conversion routines circle(box) and poly(circle)(Thomas) - Allow internal sorts to be stored in memory rather than in files(Bruce & Vadim) - Allow functions and operators on internally-identical types to succeed(Bruce) - Speed up backend start-up after profiling analysis(Bruce) - Inline frequently called functions for performance(Bruce) - Reduce open() calls(Bruce) - psql: Add PAGER for \h and \?,\C fix - Fix for psql pager when no tty(Bruce) - New entab utility(Bruce) - General trigger functions for referential integrity (Vadim) - General trigger functions for time travel (Vadim) - General trigger functions for AUTOINCREMENT/IDENTITY feature (Vadim) - MOVE implementation (Vadim) - - Source Tree Changes - ------------------- - HPUX 10 patches (Vladimir Turin) - Added SCO support, (Daniel Harris) - mkLinux patches (Tatsuo Ishii) - Change geometric box terminology from "length" to "width"(Thomas) - Deprecate temporary unstored slope fields in geometric code(Thomas) - Remove restart instructions from INSTALL(Bruce) - Look in /usr/ucb first for install(Bruce) - Fix c++ copy example code(Thomas) - Add -o to psql manual page(Bruce) - Prevent relname unallocated string length from being copied into database(Bruce) - Cleanup for NAMEDATALEN use(Bruce) - Fix pg_proc names over 15 chars in output(Bruce) - Add strNcpy() function(Bruce) - remove some (void) casts that are unnecessary(Bruce) - new interfaces directory(Marc) - Replace fopen() calls with calls to fd.c functions(Bruce) - Make functions static where possible(Bruce) - enclose unused functions in #ifdef NOT_USED(Bruce) - Remove call to difftime() in timestamp support to fix SunOS(Bruce & Thomas) - Changes for Digital Unix - Portability fix for pg_dumpall(Bruce) - Rename pg_attribute.attnvals to attdispersion(Bruce) - "intro/unix" manual page now "pgintro"(Bruce) - "built-in" manual page now "pgbuiltin"(Bruce) - "drop" manual page now "drop_table"(Bruce) - Add "create_trigger", "drop_trigger" manual pages(Thomas) - Add constraints regression test(Vadim & Thomas) - Add comments syntax regression test(Thomas) - Add PGINDENT and support program(Bruce) - Massive commit to run PGINDENT on all *.c and *.h files(Bruce) - Files moved to /src/tools directory(Bruce) - SPI and Trigger programming guides (Vadim & D'Arcy) - - ---------------------------------------------------------------------- - - Release 6.1.1 - - Release date: 1997-07-22 - - ---------------------------------------------------------------------- - -Migration from version 6.1 to version 6.1.1 - - This is a minor bug-fix release. A dump/reload is not required from - version 6.1, but is required from any release prior to 6.1. Refer to the - release notes for 6.1 for more details. - - ---------------------------------------------------------------------- - -Changes - - fix for SET with options (Thomas) - allow pg_dump/pg_dumpall to preserve ownership of all tables/objects(Bruce) - new psql \connect option allows changing usernames without changing databases - fix for initdb --debug option(Yoshihiko Ichikawa)) - lextest cleanup(Bruce) - hash fixes(Vadim) - fix date/time month boundary arithmetic(Thomas) - fix timezone daylight handling for some ports(Thomas, Bruce, Tatsuo) - timestamp overhauled to use standard functions(Thomas) - other code cleanup in date/time routines(Thomas) - psql's \d now case-insensitive(Bruce) - psql's backslash commands can now have trailing semicolon(Bruce) - fix memory leak in psql when using \g(Bruce) - major fix for endian handling of communication to server(Thomas, Tatsuo) - Fix for Solaris assembler and include files(Yoshihiko Ichikawa) - allow underscores in usernames(Bruce) - pg_dumpall now returns proper status, portability fix(Bruce) - - - ---------------------------------------------------------------------- - - Release 6.1 - - Release date: 1997-06-08 - - The regression tests have been adapted and extensively modified for the - 6.1 release of PostgreSQL. - - Three new data types (datetime, timespan, and circle) have been added to - the native set of PostgreSQL types. Points, boxes, paths, and polygons - have had their output formats made consistent across the data types. The - polygon output in misc.out has only been spot-checked for correctness - relative to the original regression output. - - PostgreSQL 6.1 introduces a new, alternate optimizer which uses genetic - algorithms. These algorithms introduce a random behavior in the ordering - of query results when the query contains multiple qualifiers or multiple - tables (giving the optimizer a choice on order of evaluation). Several - regression tests have been modified to explicitly order the results, and - hence are insensitive to optimizer choices. A few regression tests are for - data types which are inherently unordered (e.g. points and time intervals) - and tests involving those types are explicitly bracketed with "set geqo to - 'off'" and "reset geqo". - - The interpretation of array specifiers (the curly braces around atomic - values) appears to have changed sometime after the original regression - tests were generated. The current "./expected/*.out" files reflect this - new interpretation, which may not be correct! - - The float8 regression test fails on at least some platforms. This is due - to differences in implementations of pow() and exp() and the signaling - mechanisms used for overflow and underflow conditions. - - The "random" results in the random test should cause the "random" test to - be "failed", since the regression tests are evaluated using a simple diff. - However, "random" does not seem to produce random results on my test - machine (Linux/gcc/i686). - - ---------------------------------------------------------------------- - -Migration to version 6.1 - - This migration requires a complete dump of the 6.0 database and a restore - of the database in 6.1. - - Those migrating from earlier 1.* releases should first upgrade to 1.09 - because the COPY output format was improved from the 1.02 release. - - ---------------------------------------------------------------------- - -Changes - - Bug Fixes - --------- - packet length checking in library routines - lock manager priority patch - check for under/over flow of float8(Bruce) - multi-table join fix(Vadim) - SIGPIPE crash fix(Darren) - large object fixes(Sven) - allow btree indexes to handle NULLs(Vadim) - timezone fixes(D'Arcy) - select SUM(x) can return NULL on no rows(Thomas) - internal optimizer, executor bug fixes(Vadim) - fix problem where inner loop in < or <= has no rows(Vadim) - prevent re-commuting join index clauses(Vadim) - fix join clauses for multiple tables(Vadim) - fix hash, hashjoin for arrays(Vadim) - fix btree for abstime type(Vadim) - large object fixes(Raymond) - fix buffer leak in hash indexes (Vadim) - fix rtree for use in inner scan (Vadim) - fix gist for use in inner scan, cleanups (Vadim, Andrea) - avoid unnecessary local buffers allocation (Vadim, Massimo) - fix local buffers leak in transaction aborts (Vadim) - fix file manager memmory leaks, cleanups (Vadim, Massimo) - fix storage manager memmory leaks (Vadim) - fix btree duplicates handling (Vadim) - fix deleted tuples re-incarnation caused by vacuum (Vadim) - fix SELECT varchar()/char() INTO TABLE made zero-length fields(Bruce) - many psql, pg_dump, and libpq memory leaks fixed using Purify (Igor) - - Enhancements - ------------ - attribute optimization statistics(Bruce) - much faster new btree bulk load code(Paul) - BTREE UNIQUE added to bulk load code(Vadim) - new lock debug code(Massimo) - massive changes to libpg++(Leo) - new GEQO optimizer speeds table multi-table optimization(Martin) - new WARN message for non-unique insert into unique key(Marc) - update x=-3, no spaces, now valid(Bruce) - remove case-sensitive identifier handling(Bruce,Thomas,Dan) - debug backend now pretty-prints tree(Darren) - new Oracle character functions(Edmund) - new plaintext password functions(Dan) - no such class or insufficient privilege changed to distinct messages(Dan) - new ANSI timestamp function(Dan) - new ANSI Time and Date types (Thomas) - move large chunks of data in backend(Martin) - multi-column btree indexes(Vadim) - new SET var TO value command(Martin) - update transaction status on reads(Dan) - new locale settings for character types(Oleg) - new SEQUENCE serial number generator(Vadim) - GROUP BY function now possible(Vadim) - re-organize regression test(Thomas,Marc) - new optimizer operation weights(Vadim) - new psql \z grant/permit option(Marc) - new MONEY data type(D'Arcy,Thomas) - tcp socket communication speed improved(Vadim) - new VACUUM option for attribute statistics, and for certain columns (Vadim) - many geometric type improvements(Thomas,Keith) - additional regression tests(Thomas) - new datestyle variable(Thomas,Vadim,Martin) - more comparison operators for sorting types(Thomas) - new conversion functions(Thomas) - new more compact btree format(Vadim) - allow pg_dumpall to preserve database ownership(Bruce) - new SET GEQO=# and R_PLANS variable(Vadim) - old (!GEQO) optimizer can use right-sided plans (Vadim) - typechecking improvement in SQL parser(Bruce) - new SET, SHOW, RESET commands(Thomas,Vadim) - new \connect database USER option - new destroydb -i option (Igor) - new \dt and \di psql commands (Darren) - SELECT "\n" now escapes newline (A. Duursma) - new geometry conversion functions from old format (Thomas) - - Source tree changes - ------------------- - new configuration script(Marc) - readline configuration option added(Marc) - OS-specific configuration options removed(Marc) - new OS-specific template files(Marc) - no more need to edit Makefile.global(Marc) - re-arrange include files(Marc) - nextstep patches (Gregor Hoffleit) - removed WIN32-specific code(Bruce) - removed postmaster -e option, now only postgres -e option (Bruce) - merge duplicate library code in front/backends(Martin) - now works with eBones, international Kerberos(Jun) - more shared library support - c++ include file cleanup(Bruce) - warn about buggy flex(Bruce) - DG-UX, Ultrix, Irix, AIX portability fixes - - ---------------------------------------------------------------------- - - Release 6.0 - - Release date: 1997-01-29 - - A dump/restore is required for those wishing to migrate data from previous - releases of PostgreSQL. - - ---------------------------------------------------------------------- - -Migration from version 1.09 to version 6.0 - - This migration requires a complete dump of the 1.09 database and a restore - of the database in 6.0. - - ---------------------------------------------------------------------- - -Migration from pre-1.09 to version 6.0 - - Those migrating from earlier 1.* releases should first upgrade to 1.09 - because the COPY output format was improved from the 1.02 release. - - ---------------------------------------------------------------------- - -Changes - - Bug Fixes - --------- - ALTER TABLE bug - running postgress process needs to re-read table definition - Allow vacuum to be run on one table or entire database(Bruce) - Array fixes - Fix array over-runs of memory writes(Kurt) - Fix elusive btree range/non-range bug(Dan) - Fix for hash indexes on some types like time and date - Fix for pg_log size explosion - Fix permissions on lo_export()(Bruce) - Fix unitialized reads of memory(Kurt) - Fixed ALTER TABLE ... char(3) bug(Bruce) - Fixed a few small memory leaks - Fixed EXPLAIN handling of options and changed full_path option name - Fixed output of group acl permissions - Memory leaks (hunt and destroy with tools like Purify(Kurt) - Minor improvements to rules system - NOTIFY fixes - New asserts for run-checking - Overhauled parser/analyze code to properly report errors and increase speed - Pg_dump -d now handles NULL's properly(Bruce) - Prevent SELECT NULL from crashing server (Bruce) - Properly report errors when INSERT ... SELECT columns did not match - Properly report errors when insert column names were not correct - Psql \g filename now works(Bruce) - Psql fixed problem with multiple statements on one line with multiple outputs - Removed duplicate system oid's - SELECT * INTO TABLE . GROUP/ORDER BY gives unlink error if table exists(Bruce) - Several fixes for queries that crashed the backend - Starting quote in insert string errors(Bruce) - Submitting an empty query now returns empty status, not just " " query(Bruce) - - Enhancements - ------------ - Add EXPLAIN manual page(Bruce) - Add UNIQUE index capability(Dan) - Add hostname/user level access control rather than just hostname and user - Add synonym of != for <>(Bruce) - Allow "select oid,* from table" - Allow BY,ORDER BY to specify columns by number, or by non-alias table.column(Bruce) - Allow COPY from the frontend(Bryan) - Allow GROUP BY to use alias column name(Bruce) - Allow actual compression, not just reuse on the same page(Vadim) - Allow installation-configuration option to auto-add all local users(Bryan) - Allow libpq to distinguish between text value '' and null(Bruce) - Allow non-postgres users with createdb privs to destroydb's - Allow restriction on who can create C functions(Bryan) - Allow restriction on who can do backend COPY(Bryan) - Can shrink tables, pg_time and pg_log(Vadim & Erich) - Change debug level 2 to print queries only, changed debug heading layout(Bruce) - Change default decimal constant representation from float4 to float8(Bruce) - European date format now set when postmaster is started - Execute lowercase function names if not found with exact case - Fixes for aggregate/GROUP processing, allow 'select sum(func(x),sum(x+y) from z' - Gist now included in the distrubution(Marc) - Idend authentication of local users(Bryan) - Implement BETWEEN qualifier(Bruce) - Implement IN qualifier(Bruce) - Libpq has PQgetisnull()(Bruce) - Libpq++ improvements - New options to initdb(Bryan) - Pg_dump allow dump of oid's(Bruce) - Pg_dump create indexes after tables are loaded for speed(Bruce) - Pg_dumpall dumps all databases, and the user table - Pginterface additions for NULL values(Bruce) - Prevent postmaster from being run as root - Psql \h and \? is now readable(Bruce) - Psql allow backslashed, semicolons anywhere on the line(Bruce) - Psql changed command prompt for lines in query or in quotes(Bruce) - Psql char(3) now displays as (bp)char in \d output(Bruce) - Psql return code now more accurate(Bryan?) - Psql updated help syntax(Bruce) - Re-visit and fix vacuum(Vadim) - Reduce size of regression diffs, remove timezone name difference(Bruce) - Remove compile-time parameters to enable binary distributions(Bryan) - Reverse meaning of HBA masks(Bryan) - Secure Authentication of local users(Bryan) - Speed up vacuum(Vadim) - Vacuum now had VERBOSE option(Bruce) - - Source tree changes - ------------------- - All functions now have prototypes that are compared against the calls - Allow asserts to be disabled easly from Makefile.global(Bruce) - Change oid constants used in code to #define names - Decoupled sparc and solaris defines(Kurt) - Gcc -Wall compiles cleanly with warnings only from unfixable constructs - Major include file reorganization/reduction(Marc) - Make now stops on compile failure(Bryan) - Makefile restructuring(Bryan, Marc) - Merge bsdi_2_1 to bsdi(Bruce) - Monitor program removed - Name change from Postgres95 to PostgreSQL - New config.h file(Marc, Bryan) - PG_VERSION now set to 6.0 and used by postmaster - Portability additions, including Ultrix, DG/UX, AIX, and Solaris - Reduced the number of #define's, centeralized #define's - Remove duplicate OIDS in system tables(Dan) - Remove duplicate system catalog info or report mismatches(Dan) - Removed many os-specific #define's - Restructured object file generation/location(Bryan, Marc) - Restructured port-specific file locations(Bryan, Marc) - Unused/uninialized variables corrected - - ---------------------------------------------------------------------- - - Release 1.09 - - Release date: 1996-11-04 - - Sorry, we didn't keep track of changes from 1.02 to 1.09. Some of the - changes listed in 6.0 were actually included in the 1.02.1 to 1.09 - releases. - - ---------------------------------------------------------------------- - - Release 1.02 - - Release date: 1996-08-01 - - ---------------------------------------------------------------------- - -Migration from version 1.02 to version 1.02.1 - - Here is a new migration file for 1.02.1. It includes the 'copy' change and - a script to convert old ASCII files. - - Note: The following notes are for the benefit of users who want to - migrate databases from Postgres95 1.01 and 1.02 to Postgres95 1.02.1. - - If you are starting afresh with Postgres95 1.02.1 and do not need to - migrate old databases, you do not need to read any further. - - In order to upgrade older Postgres95 version 1.01 or 1.02 databases to - version 1.02.1, the following steps are required: - - - - - databases. This is done by running the new 1.02.1 server against your - own 1.01 or 1.02 database and applying the queries attached at the end - of the file. This can be done easily through "psql". If your 1.01 or - 1.02 database is named testdb and you have cut the commands from the - end of this file and saved them in "addfunc.sql": - - % psql testdb -f addfunc.sql - - Those upgrading 1.02 databases will get a warning when executing the - last two statements in the file because they are already present in - 1.02. This is not a cause for concern. - - ---------------------------------------------------------------------- - -Dump/Reload Procedure - - If you are trying to reload a pg_dump or text-mode, copy tablename to - stdout generated with a previous version, you will need to run the - attached "sed" script on the ASCII file before loading it into the - database. The old format used '.' as end-of-data, while '\.' is now the - end-of-data marker. Also, empty strings are now loaded in as '' rather - than NULL. See the copy manual page for full details. - - sed 's/^\.$/\\./g' out_file - - If you are loading an older binary copy or non-stdout copy, there is no - end-of-data character, and hence no conversion necessary. - - -- following lines added by agc to reflect the case-insensitive - -- regexp searching for varchar (in 1.02), and bpchar (in 1.02.1) - create operator ~* (leftarg = bpchar, rightarg = text, procedure = texticregexeq); - create operator !~* (leftarg = bpchar, rightarg = text, procedure = texticregexne); - create operator ~* (leftarg = varchar, rightarg = text, procedure = texticregexeq); - create operator !~* (leftarg = varchar, rightarg = text, procedure = texticregexne); - - ---------------------------------------------------------------------- - -Changes - - Source code maintenance and development - * worldwide team of volunteers - * the source tree now in CVS at ftp.ki.net - - Enhancements - * psql (and underlying libpq library) now has many more options for - formatting output, including HTML - * pg_dump now output the schema and/or the data, with many fixes to - enhance completeness. - * psql used in place of monitor in administration shell scripts. - monitor to be depreciated in next release. - * date/time functions enhanced - * NULL insert/update/comparison fixed/enhanced - * TCL/TK lib and shell fixed to work with both tck7.4/tk4.0 and tcl7.5/tk4.1 - - Bug Fixes (almost too numerous to mention) - * indexes - * storage management - * check for NULL pointer before dereferencing - * Makefile fixes - - New Ports - * added SolarisX86 port - * added BSDI 2.1 port - * added DGUX port - - ---------------------------------------------------------------------- - - Release 1.01 - - Release date: 1996-02-23 - - ---------------------------------------------------------------------- - -Migration from version 1.0 to version 1.01 - - The following notes are for the benefit of users who want to migrate - databases from Postgres95 1.0 to Postgres95 1.01. - - If you are starting afresh with Postgres95 1.01 and do not need to migrate - old databases, you do not need to read any further. - - In order to Postgres95 version 1.01 with databases created with Postgres95 - version 1.0, the following steps are required: - - - OIDNAMELEN to 20. - - - - - data directory (typically the value of your $PGDATA). - "src/libpq/pg_hba" shows an example syntax. - - - the line - - HBA = 1 - - in "src/Makefile.global" - - Note that host-based authentication is turned on by default, and - if you do not take steps A or B above, the out-of-the-box 1.01 - will not allow you to connect to 1.0 databases. - - - - - your existing $PGDATA directory. - - - path up so that 1.01 binaries are being used. - - - - - - - This is done by running the new 1.01 server against your own 1.0 - database and applying the queries attached and saving in the file - 1.0_to_1.01.sql. This can be done easily through "psql". If your 1.0 - database is name testdb: - - % psql testdb -f 1.0_to_1.01.sql - - and then execute the following commands (cut and paste from here): - - -- add builtin functions that are new to 1.01 - - create function int4eqoid (int4, oid) returns bool as 'foo' - language 'internal'; - create function oideqint4 (oid, int4) returns bool as 'foo' - language 'internal'; - create function char2icregexeq (char2, text) returns bool as 'foo' - language 'internal'; - create function char2icregexne (char2, text) returns bool as 'foo' - language 'internal'; - create function char4icregexeq (char4, text) returns bool as 'foo' - language 'internal'; - create function char4icregexne (char4, text) returns bool as 'foo' - language 'internal'; - create function char8icregexeq (char8, text) returns bool as 'foo' - language 'internal'; - create function char8icregexne (char8, text) returns bool as 'foo' - language 'internal'; - create function char16icregexeq (char16, text) returns bool as 'foo' - language 'internal'; - create function char16icregexne (char16, text) returns bool as 'foo' - language 'internal'; - create function texticregexeq (text, text) returns bool as 'foo' - language 'internal'; - create function texticregexne (text, text) returns bool as 'foo' - language 'internal'; - - -- add builtin functions that are new to 1.01 - - create operator = (leftarg = int4, rightarg = oid, procedure = int4eqoid); - create operator = (leftarg = oid, rightarg = int4, procedure = oideqint4); - create operator ~* (leftarg = char2, rightarg = text, procedure = char2icregexeq); - create operator !~* (leftarg = char2, rightarg = text, procedure = char2icregexne); - create operator ~* (leftarg = char4, rightarg = text, procedure = char4icregexeq); - create operator !~* (leftarg = char4, rightarg = text, procedure = char4icregexne); - create operator ~* (leftarg = char8, rightarg = text, procedure = char8icregexeq); - create operator !~* (leftarg = char8, rightarg = text, procedure = char8icregexne); - create operator ~* (leftarg = char16, rightarg = text, procedure = char16icregexeq); - create operator !~* (leftarg = char16, rightarg = text, procedure = char16icregexne); - create operator ~* (leftarg = text, rightarg = text, procedure = texticregexeq); - create operator !~* (leftarg = text, rightarg = text, procedure = texticregexne); - - ---------------------------------------------------------------------- - -Changes - - Incompatibilities: - * 1.01 is backwards compatible with 1.0 database provided the user - follow the steps outlined in the MIGRATION_from_1.0_to_1.01 file. - If those steps are not taken, 1.01 is not compatible with 1.0 database. - - Enhancements: - * added PQdisplayTuples() to libpq and changed monitor and psql to use it - * added NeXT port (requires SysVIPC implementation) - * added CAST .. AS ... syntax - * added ASC and DESC keywords - * added 'internal' as a possible language for CREATE FUNCTION - internal functions are C functions which have been statically linked - into the postgres backend. - * a new type "name" has been added for system identifiers (table names, - attribute names, etc.) This replaces the old char16 type. The - of name is set by the NAMEDATALEN #define in src/Makefile.global - * a readable reference manual that describes the query language. - * added host-based access control. A configuration file ($PGDATA/pg_hba) - is used to hold the configuration data. If host-based access control - is not desired, comment out HBA=1 in src/Makefile.global. - * changed regex handling to be uniform use of Henry Spencer's regex code - regardless of platform. The regex code is included in the distribution - * added functions and operators for case-insensitive regular expressions. - The operators are ~* and !~*. - * pg_dump uses COPY instead of SELECT loop for better performance - - Bug fixes: - * fixed an optimizer bug that was causing core dumps when - functions calls were used in comparisons in the WHERE clause - * changed all uses of getuid to geteuid so that effective uids are used - * psql now returns non-zero status on errors when using -c - * applied public patches 1-14 - - ---------------------------------------------------------------------- - - Release 1.0 - - Release date: 1995-09-05 - - ---------------------------------------------------------------------- - -Changes - - Copyright change: - * The copyright of Postgres 1.0 has been loosened to be freely modifiable - and modifiable for any purpose. Please read the COPYRIGHT file. - Thanks to Professor Michael Stonebraker for making this possible. - - Incompatibilities: - * date formats have to be MM-DD-YYYY (or DD-MM-YYYY if you're using - EUROPEAN STYLE). This follows SQL-92 specs. - * "delimiters" is now a keyword - - Enhancements: - * sql LIKE syntax has been added - * copy command now takes an optional USING DELIMITER specification. - delimiters can be any single-character string. - * IRIX 5.3 port has been added. - Thanks to Paul Walmsley and others. - * updated pg_dump to work with new libpq - * \d has been added psql - Thanks to Keith Parks - * regexp performance for architectures that use POSIX regex has been - improved due to caching of precompiled patterns. - Thanks to Alistair Crooks - * a new version of libpq++ - Thanks to William Wanders - - Bug fixes: - * arbitrary userids can be specified in the createuser script - * \c to connect to other databases in psql now works. - * bad pg_proc entry for float4inc() is fixed - * users with usecreatedb field set can now create databases without - having to be usesuper - * remove access control entries when the entry no longer has any - permissions - * fixed non-portable datetimes implementation - * added kerberos flags to the src/backend/Makefile - * libpq now works with kerberos - * typographic errors in the user manual have been corrected. - * btrees with multiple index never worked, now we tell you they don't - work when you try to use them - - ---------------------------------------------------------------------- - - Postgres95 Release 0.03 - - Release date: 1995-07-21 - - ---------------------------------------------------------------------- - -Changes - - Incompatible changes: - * BETA-0.3 IS INCOMPATIBLE WITH DATABASES CREATED WITH PREVIOUS VERSIONS - (due to system catalog changes and indexing structure changes). - * double-quote (") is deprecated as a quoting character for string literals; - you need to convert them to single quotes ('). - * name of aggregates (eg. int4sum) are renamed in accordance with the - SQL standard (eg. sum). - * CHANGE ACL syntax is replaced by GRANT/REVOKE syntax. - * float literals (eg. 3.14) are now of type float4 (instead of float8 in - previous releases); you might have to do typecasting if you depend on it - being of type float8. If you neglect to do the typecasting and you assign - a float literal to a field of type float8, you may get incorrect values - stored! - * LIBPQ has been totally revamped so that frontend applications - can connect to multiple backends - * the usesysid field in pg_user has been changed from int2 to int4 to - allow wider range of Unix user ids. - * the netbsd/freebsd/bsd o/s ports have been consolidated into a - single BSD44_derived port. (thanks to Alistair Crooks) - - SQL standard-compliance (the following details changes that makes postgres95 - more compliant to the SQL-92 standard): - * the following SQL types are now built-in: smallint, int(eger), float, real, - char(N), varchar(N), date and time. - - The following are aliases to existing postgres types: - smallint -> int2 - integer, int -> int4 - float, real -> float4 - char(N) and varchar(N) are implemented as truncated text types. In - addition, char(N) does blank-padding. - * single-quote (') is used for quoting string literals; '' (in addition to - \') is supported as means of inserting a single quote in a string - * SQL standard aggregate names (MAX, MIN, AVG, SUM, COUNT) are used - (Also, aggregates can now be overloaded, i.e. you can define your - own MAX aggregate to take in a user-defined type.) - * CHANGE ACL removed. GRANT/REVOKE syntax added. - - Privileges can be given to a group using the "GROUP" keyword. - For example: - GRANT SELECT ON foobar TO GROUP my_group; - The keyword 'PUBLIC' is also supported to mean all users. - - Privileges can only be granted or revoked to one user or group - at a time. - - "WITH GRANT OPTION" is not supported. Only class owners can change - access control - - The default access control is to to grant users readonly access. - You must explicitly grant insert/update access to users. To change - this, modify the line in - src/backend/utils/acl.h - that defines ACL_WORLD_DEFAULT - - Bug fixes: - * the bug where aggregates of empty tables were not run has been fixed. Now, - aggregates run on empty tables will return the initial conditions of the - aggregates. Thus, COUNT of an empty table will now properly return 0. - MAX/MIN of an empty table will return a tuple of value NULL. - * allow the use of \; inside the monitor - * the LISTEN/NOTIFY asynchronous notification mechanism now work - * NOTIFY in rule action bodies now work - * hash indexes work, and access methods in general should perform better. - creation of large btree indexes should be much faster. (thanks to Paul - Aoki) - - Other changes and enhancements: - * addition of an EXPLAIN statement used for explaining the query execution - plan (eg. "EXPLAIN SELECT * FROM EMP" prints out the execution plan for - the query). - * WARN and NOTICE messages no longer have timestamps on them. To turn on - timestamps of error messages, uncomment the line in - src/backend/utils/elog.h: - /* define ELOG_TIMESTAMPS */ - * On an access control violation, the message - "Either no such class or insufficient privilege" - will be given. This is the same message that is returned when - a class is not found. This dissuades non-privileged users from - guessing the existence of privileged classes. - * some additional system catalog changes have been made that are not - visible to the user. - - libpgtcl changes: - * The -oid option has been added to the "pg_result" tcl command. - pg_result -oid returns oid of the last tuple inserted. If the - last command was not an INSERT, then pg_result -oid returns "". - * the large object interface is available as pg_lo* tcl commands: - pg_lo_open, pg_lo_close, pg_lo_creat, etc. - - Portability enhancements and New Ports: - * flex/lex problems have been cleared up. Now, you should be able to use - flex instead of lex on any platforms. We no longer make assumptions of - what lexer you use based on the platform you use. - * The Linux-ELF port is now supported. Various configuration have been - tested: The following configuration is known to work: - kernel 1.2.10, gcc 2.6.3, libc 4.7.2, flex 2.5.2, bison 1.24 - with everything in ELF format, - - New utilities: - * ipcclean added to the distribution - ipcclean usually does not need to be run, but if your backend crashes - and leaves shared memory segments hanging around, ipcclean will - clean them up for you. - - New documentation: - * the user manual has been revised and libpq documentation added. - - ---------------------------------------------------------------------- - - Postgres95 Release 0.02 - - Release date: 1995-05-25 - - ---------------------------------------------------------------------- - -Changes - - Incompatible changes: - * The SQL statement for creating a database is 'CREATE DATABASE' instead - of 'CREATEDB'. Similarly, dropping a database is 'DROP DATABASE' instead - of 'DESTROYDB'. However, the names of the executables 'createdb' and - 'destroydb' remain the same. - - New tools: - * pgperl - a Perl (4.036) interface to Postgres95 - * pg_dump - a utility for dumping out a postgres database into a - script file containing query commands. The script files are in a ASCII - format and can be used to reconstruct the database, even on other - machines and other architectures. (Also good for converting - a Postgres 4.2 database to Postgres95 database.) - - The following ports have been incorporated into postgres95-beta-0.02: - * the NetBSD port by Alistair Crooks - * the AIX port by Mike Tung - * the Windows NT port by Jon Forrest (more stuff but not done yet) - * the Linux ELF port by Brian Gallew - - The following bugs have been fixed in postgres95-beta-0.02: - * new lines not escaped in COPY OUT and problem with COPY OUT when first - attribute is a '.' - * cannot type return to use the default user id in createuser - * SELECT DISTINCT on big tables crashes - * Linux installation problems - * monitor doesn't allow use of 'localhost' as PGHOST - * psql core dumps when doing \c or \l - * the "pgtclsh" target missing from src/bin/pgtclsh/Makefile - * libpgtcl has a hard-wired default port number - * SELECT DISTINCT INTO TABLE hangs - * CREATE TYPE doesn't accept 'variable' as the internallength - * wrong result using more than 1 aggregate in a SELECT - - ---------------------------------------------------------------------- - - Postgres95 Release 0.01 - - Release date: 1995-05-01 - - Initial release. diff --git a/INSTALL b/INSTALL deleted file mode 100644 index 1288a9da4a..0000000000 --- a/INSTALL +++ /dev/null @@ -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 \ - >server.log 2>&1 or - , not to the people listed here. - - OS Processor Version Reported Remarks - AIX RS6000 7.2 2001-12-19, Andreas Zeugswetter see also - (), doc/FAQ_AIX - Tatsuo Ishii - () - BeOS x86 7.2 2001-11-29, Cyril Velter 5.0.4 - () - BSD/OS x86 7.2 2001-11-27, Bruce Momjian 4.2 - () - FreeBSDAlpha 7.2 2001-12-18, Chris Kings-Lynne - () - FreeBSDx86 7.2 2001-11-14, Chris Kings-Lynne - () - HP-UX PA-RISC 7.2 2001-11-29, Joseph Conway 11.00 and 10.20; - (), Tom see also - Lane () doc/FAQ_HPUX - IRIX MIPS 7.2 2001-11-28, Luis Amigo 6.5.13, MIPSPro - () 7.30 - Linux Alpha 7.2 2001-11-16, Tom Lane 2.2.18; tested at - () SourceForge - Linux armv4l 7.2 2001-12-10, Mark Knox 2.2.x - () - Linux MIPS 7.2 2001-11-15, Hisao Shibuya 2.0.x; Cobalt - () Qube2 - Linux PlayStation 7.2 2001-12-12, Permaine Cheung #undef - 2 ) HAS_TEST_AND_SET, - slock_t - Linux PPC74xx 7.2 2001-11-16, Tom Lane 2.2.18; Apple G3 - () - Linux S/390 7.2 2001-12-12, Permaine Cheung - ) - Linux Sparc 7.2 2001-11-28, Doug McNaught 2.2.19 - () - Linux x86 7.2 2001-11-15, Thomas Lockhart 2.0.x, 2.2.x, - () 2.4.x - MacOS XPPC 7.2 2001-11-28, Gavin Sherry 10.1.x - () - NetBSD Alpha 7.2 2001-11-20, Thomas Thai 1.5W - () - NetBSD arm32 7.1 2001-03-21, Patrick Welche 1.5E - () - NetBSD m68k 7.0 2000-04-10, Henry B. Hotz Mac 8xx - () - NetBSD PPC 7.2 2001-11-28, Bill Studenmund 1.5 - () - NetBSD Sparc 7.2 2001-12-03, Matthew Green 32- and 64-bit - () builds - NetBSD VAX 7.1 2001-03-30, Tom I. Helbekkmo 1.5 - () - NetBSD x86 7.2 2001-11-28, Bill Studenmund 1.5 - () - OpenBSDSparc 7.2 2001-11-27, Brandon Palmer 3.0 - () - OpenBSDx86 7.2 2001-11-26, Brandon Palmer 3.0 - () - Open x86 7.2 2001-11-28, OU-8 Larry Rosenman see also - UNIX (), UW-7 Olivier doc/FAQ_SCO - Prenant () - QNX 4 x86 7.2 2001-12-10, Bernd Tegge 4.25; see also - RTOS () doc/FAQ_QNX4 - SolarisSparc 7.2 2001-11-12, Andrew Sullivan 2.6-8; see also - () doc/FAQ_Solaris - Solarisx86 7.2 2001-11-28, Martin Renters 2.8; see also - () doc/FAQ_Solaris - SunOS 4Sparc 7.2 2001-12-04, Tatsuo Ishii - () - Tru64 Alpha 7.2 2001-11-26, Alessio Bragadini 5.0; 4.0g with cc - UNIX (), Bernd and gcc - Tegge () - Windowsx86 7.2 2001-12-13, Dave Page with Cygwin; see - (), doc/FAQ_MSWIN - Jason Tishler - () - Windowsx86 7.2 2001-12-10, Dave Page native is - () 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 () reports - MkLinux DR1PPC750 7.0 2001-04-03, Tatsuo Ishii 7.1 needs OS - () update? - NeXTSTEP x86 6.x 1998-03-01, David Wetzel bit rot - () suspected - QNX RTOS v6x86 7.2 2001-11-20, Igor Kovalenko patches - () available in - archives, - but too late - for 7.2 - SCO x86 6.5 1999-05-25, Andrew Merrill 7.2 should - OpenServer () work, but no - 5 reports; see - also - doc/FAQ_SCO - System V R4m88k 6.2.1 1998-03-01, Doug Winterburn needs new - () TAS spinlock - code - System V R4MIPS 6.4 1998-10-28, Frank Ridderbusch no recent - () reports - Ultrix MIPS 7.1 2001-03-26 TAS spinlock - code not - detected - Ultrix VAX 6.x 1998-03-01 diff --git a/Makefile b/Makefile deleted file mode 100644 index 9de7cce180..0000000000 --- a/Makefile +++ /dev/null @@ -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 diff --git a/README b/README deleted file mode 100644 index a02403b8b8..0000000000 --- a/README +++ /dev/null @@ -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/. diff --git a/aclocal.m4 b/aclocal.m4 deleted file mode 100644 index 1edb7f9800..0000000000 --- a/aclocal.m4 +++ /dev/null @@ -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]) diff --git a/config/ac_func_accept_argtypes.m4 b/config/ac_func_accept_argtypes.m4 deleted file mode 100644 index f22d905659..0000000000 --- a/config/ac_func_accept_argtypes.m4 +++ /dev/null @@ -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 -# -# (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. -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 -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#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']) -]) diff --git a/config/c-compiler.m4 b/config/c-compiler.m4 deleted file mode 100644 index 5171e1e6d9..0000000000 --- a/config/c-compiler.m4 +++ /dev/null @@ -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 diff --git a/config/c-library.m4 b/config/c-library.m4 deleted file mode 100644 index 10a91d43b4..0000000000 --- a/config/c-library.m4 +++ /dev/null @@ -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 -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 ], -[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 -#include -#include ])])# 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 !) -AC_DEFUN([PGAC_STRUCT_SOCKADDR_UN], -[AC_CHECK_TYPES([struct sockaddr_un], [], [], -[#include -#ifdef HAVE_SYS_UN_H -#include -#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 -], -[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 diff --git a/config/config.guess b/config/config.guess deleted file mode 100755 index dc70191a98..0000000000 --- a/config/config.guess +++ /dev/null @@ -1,1308 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. - -timestamp='2001-08-04' - -# This file 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. - -# Written by Per Bothner . -# Please send patches to . -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; - --version | -v ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - - -dummy=dummy-$$ -trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int dummy(){}" > $dummy.c ; - for c in cc gcc c89 ; do - ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ; - if test $? = 0 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - rm -f $dummy.c $dummy.o $dummy.rel ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # Netbsd (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # Determine the machine/vendor (is the vendor relevant). - case "${UNAME_MACHINE}" in - amiga) machine=m68k-unknown ;; - arm32) machine=arm-unknown ;; - atari*) machine=m68k-atari ;; - sun3*) machine=m68k-sun ;; - mac68k) machine=m68k-apple ;; - macppc) machine=powerpc-apple ;; - hp3[0-9][05]) machine=m68k-hp ;; - ibmrt|romp-ibm) machine=romp-ibm ;; - *) machine=${UNAME_MACHINE}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE}" in - i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit 0 ;; - alpha:OSF1:*:*) - if test $UNAME_RELEASE = "V4.0"; then - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - fi - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - cat <$dummy.s - .data -\$Lformat: - .byte 37,100,45,37,120,10,0 # "%d-%x\n" - - .text - .globl main - .align 4 - .ent main -main: - .frame \$30,16,\$26,0 - ldgp \$29,0(\$27) - .prologue 1 - .long 0x47e03d80 # implver \$0 - lda \$2,-1 - .long 0x47e20c21 # amask \$2,\$1 - lda \$16,\$Lformat - mov \$0,\$17 - not \$1,\$18 - jsr \$26,printf - ldgp \$29,0(\$26) - mov 0,\$16 - jsr \$26,exit - .end main -EOF - eval $set_cc_for_build - $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null - if test "$?" = 0 ; then - case `./$dummy` in - 0-0) - UNAME_MACHINE="alpha" - ;; - 1-0) - UNAME_MACHINE="alphaev5" - ;; - 1-1) - UNAME_MACHINE="alphaev56" - ;; - 1-101) - UNAME_MACHINE="alphapca56" - ;; - 2-303) - UNAME_MACHINE="alphaev6" - ;; - 2-307) - UNAME_MACHINE="alphaev67" - ;; - esac - fi - rm -f $dummy.s $dummy - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit 0 ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit 0 ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit 0 ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit 0;; - amiga:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit 0 ;; - arc64:OpenBSD:*:*) - echo mips64el-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - arc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - hkmips:OpenBSD:*:*) - echo mips-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - pmax:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sgi:OpenBSD:*:*) - echo mips-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - wgrisc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit 0 ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit 0;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit 0;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit 0 ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit 0 ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit 0 ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit 0 ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit 0 ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit 0 ;; - atari*:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit 0 ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit 0 ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit 0 ;; - sun3*:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mac68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme88k:OpenBSD:*:*) - echo m88k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit 0 ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit 0 ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit 0 ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - eval $set_cc_for_build - $CC_FOR_BUILD $dummy.c -o $dummy \ - && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ - && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo mips-mips-riscos${UNAME_RELEASE} - exit 0 ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit 0 ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit 0 ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit 0 ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit 0 ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit 0 ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit 0 ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit 0 ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit 0 ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit 0 ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit 0 ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit 0 ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit 0 ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - eval $set_cc_for_build - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo rs6000-ibm-aix3.2.5 - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit 0 ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit 0 ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit 0 ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit 0 ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit 0 ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit 0 ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit 0 ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit 0 ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - case "${HPUX_REV}" in - 11.[0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - esac ;; - esac - fi ;; - esac - if [ "${HP_ARCH}" = "" ]; then - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - eval $set_cc_for_build - (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` - if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi - rm -f $dummy.c $dummy - fi ;; - esac - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit 0 ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit 0 ;; - 3050*:HI-UX:*:*) - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - eval $set_cc_for_build - $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - echo unknown-hitachi-hiuxwe2 - exit 0 ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit 0 ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit 0 ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit 0 ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit 0 ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit 0 ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit 0 ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit 0 ;; - hppa*:OpenBSD:*:*) - echo hppa-unknown-openbsd - exit 0 ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit 0 ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit 0 ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit 0 ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit 0 ;; - CRAY*X-MP:*:*:*) - echo xmp-cray-unicos - exit 0 ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3D:*:*:*) - echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY-2:*:*:*) - echo cray2-cray-unicos - exit 0 ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit 0 ;; - hp300:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit 0 ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit 0 ;; - *:OpenBSD:*:*) - echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - exit 0 ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit 0 ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit 0 ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit 0 ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i386-pc-interix - exit 0 ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit 0 ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit 0 ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - *:GNU:*:*) - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit 0 ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit 0 ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux - exit 0 ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - mips:Linux:*:*) - case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in - big) echo mips-unknown-linux-gnu && exit 0 ;; - little) echo mipsel-unknown-linux-gnu && exit 0 ;; - esac - ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit 0 ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit 0 ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev67 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit 0 ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit 0 ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit 0 ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit 0 ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit 0 ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - ld_supported_targets=`cd /; ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit 0 ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit 0 ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit 0 ;; - esac - # Determine whether the default compiler is a.out or elf - cat >$dummy.c < -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif -#ifdef __ELF__ -# ifdef __GLIBC__ -# if __GLIBC__ >= 2 - printf ("%s-pc-linux-gnu\n", argv[1]); -# else - printf ("%s-pc-linux-gnulibc1\n", argv[1]); -# endif -# else - printf ("%s-pc-linux-gnulibc1\n", argv[1]); -# endif -#else - printf ("%s-pc-linux-gnuaout\n", argv[1]); -#endif - return 0; -} -EOF - eval $set_cc_for_build - $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0 - rm -f $dummy.c $dummy - test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit 0 ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit 0 ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit 0 ;; - i*86:*:5:[78]*) - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit 0 ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` - (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit 0 ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit 0 ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit 0 ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit 0 ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit 0 ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit 0 ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit 0 ;; - M68*:*:R3V[567]*:*) - test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4.3${OS_REL} && exit 0 - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4 && exit 0 ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit 0 ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit 0 ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit 0 ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit 0 ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit 0 ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit 0 ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit 0 ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit 0 ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit 0 ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit 0 ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit 0 ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit 0 ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit 0 ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit 0 ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit 0 ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Darwin:*:*) - echo `uname -p`-apple-darwin${UNAME_RELEASE} - exit 0 ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - if test "${UNAME_MACHINE}" = "x86pc"; then - UNAME_MACHINE=pc - fi - echo `uname -p`-${UNAME_MACHINE}-nto-qnx - exit 0 ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit 0 ;; - NSR-[KW]:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit 0 ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit 0 ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit 0 ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit 0 ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit 0 ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit 0 ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit 0 ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit 0 ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit 0 ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit 0 ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit 0 ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit 0 ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit 0 ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -eval $set_cc_for_build -$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0 -rm -f $dummy.c $dummy - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit 0 ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - c34*) - echo c34-convex-bsd - exit 0 ;; - c38*) - echo c38-convex-bsd - exit 0 ;; - c4*) - echo c4-convex-bsd - exit 0 ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/config/config.sub b/config/config.sub deleted file mode 100755 index f87dc312cb..0000000000 --- a/config/config.sub +++ /dev/null @@ -1,1409 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. - -timestamp='2001-08-02' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file 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. - -# Please send patches to . -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; - --version | -v ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit 0;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis) - os= - basic_machine=$1 - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ - | c4x | clipper \ - | d10v | d30v | dsp16xx \ - | fr30 \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | m32r | m68000 | m68k | m88k | mcore \ - | mips16 | mips64 | mips64el | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el | mips64vr4300 \ - | mips64vr4300el | mips64vr5000 | mips64vr5000el \ - | mipsbe | mipsel | mipsle | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | ns16k | ns32k \ - | openrisc \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | s390 | s390x \ - | sh | sh[34] | sh[34]eb | shbe | shle \ - | sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \ - | strongarm \ - | tahoe | thumb | tic80 | tron \ - | v850 \ - | we32k \ - | x86 | xscale \ - | z8k) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alphapca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armv*-* \ - | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c54x-* \ - | clipper-* | cray2-* | cydra-* \ - | d10v-* | d30v-* \ - | f30[01]-* | f700-* | fr30-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | m32r-* \ - | m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | mcore-* \ - | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \ - | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipsel-* \ - | mipsle-* | mipstx39-* | mipstx39el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | s390-* | s390x-* \ - | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \ - | sparc-* | sparc64-* | sparc86x-* | sparclite-* \ - | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* \ - | t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \ - | v850-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xmp-* | xps100-* | xscale-* \ - | ymp-* \ - | z8k-*) - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | ymp) - basic_machine=ymp-cray - os=-unicos - ;; - cray2) - basic_machine=cray2-cray - os=-unicos - ;; - [cjt]90) - basic_machine=${basic_machine}-cray - os=-unicos - ;; - crds | unos) - basic_machine=m68k-crds - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mipsel*-linux*) - basic_machine=mipsel-unknown - os=-linux-gnu - ;; - mips*-linux*) - basic_machine=mips-unknown - os=-linux-gnu - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - mmix*) - basic_machine=mmix-knuth - os=-mmixware - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pentium | p5 | k5 | k6 | nexgen) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon) - basic_machine=i686-pc - ;; - pentiumii | pentium2) - basic_machine=i686-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sparclite-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=t3e-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - windows32) - basic_machine=i386-pc - os=-windows32-msvcrt - ;; - xmp) - basic_machine=xmp-cray - os=-unicos - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - mips) - if [ x$os = x-linux-gnu ]; then - basic_machine=mips-unknown - else - basic_machine=mips-mips - fi - ;; - romp) - basic_machine=romp-ibm - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh3 | sh4 | sh3eb | sh4eb) - basic_machine=sh-unknown - ;; - sparc | sparcv9 | sparcv9b) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - c4x*) - basic_machine=c4x-none - os=-coff - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ - | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto*) - os=-nto-qnx - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-ibm) - os=-aix - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -vxsim* | -vxworks*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit 0 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/config/cxx.m4 b/config/cxx.m4 deleted file mode 100644 index 5498db091a..0000000000 --- a/config/cxx.m4 +++ /dev/null @@ -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 header. If this -# is found a header then it's probably safe to assume that -# class string exists. If not, check to make sure that -# 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++ header])], - [AC_CACHE_CHECK([for class string in ], - [pgac_cv_class_string_in_string_h], -[AC_TRY_COMPILE([#include -#include -#include -], - [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 nor 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 -#include -#ifdef HAVE_CXX_STRING_HEADER -#include -#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 diff --git a/config/docbook.m4 b/config/docbook.m4 deleted file mode 100644 index b0b6ce0238..0000000000 --- a/config/docbook.m4 +++ /dev/null @@ -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 < - - test - - random - - testsect - text - - - -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 diff --git a/config/general.m4 b/config/general.m4 deleted file mode 100644 index 1a0a60dd60..0000000000 --- a/config/general.m4 +++ /dev/null @@ -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 diff --git a/config/install-sh b/config/install-sh deleted file mode 100755 index ebc66913e9..0000000000 --- a/config/install-sh +++ /dev/null @@ -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 diff --git a/config/java.m4 b/config/java.m4 deleted file mode 100644 index 2f7de3a42a..0000000000 --- a/config/java.m4 +++ /dev/null @@ -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 - - - - - - -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 -]) diff --git a/config/libtool.m4 b/config/libtool.m4 deleted file mode 100644 index 798420d5bc..0000000000 --- a/config/libtool.m4 +++ /dev/null @@ -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 , 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 &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 ... diff --git a/config/missing b/config/missing deleted file mode 100755 index 29865631d5..0000000000 --- a/config/missing +++ /dev/null @@ -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=$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 diff --git a/config/mkinstalldirs b/config/mkinstalldirs deleted file mode 100755 index cc8783edce..0000000000 --- a/config/mkinstalldirs +++ /dev/null @@ -1,36 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy -# Author: Noah Friedman -# 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 diff --git a/config/perl.m4 b/config/perl.m4 deleted file mode 100644 index dc134acc22..0000000000 --- a/config/perl.m4 +++ /dev/null @@ -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])]) diff --git a/config/prep_buildtree b/config/prep_buildtree deleted file mode 100644 index 57d7719673..0000000000 --- a/config/prep_buildtree +++ /dev/null @@ -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 diff --git a/config/programs.m4 b/config/programs.m4 deleted file mode 100644 index 371b21b918..0000000000 --- a/config/programs.m4 +++ /dev/null @@ -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 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 -#ifdef HAVE_READLINE_READLINE_H -# include -#elif defined(HAVE_READLINE_H) -# include -#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 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 diff --git a/config/python.m4 b/config/python.m4 deleted file mode 100644 index 6058ef3d2a..0000000000 --- a/config/python.m4 +++ /dev/null @@ -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 diff --git a/config/tcl.m4 b/config/tcl.m4 deleted file mode 100644 index d3407c924f..0000000000 --- a/config/tcl.m4 +++ /dev/null @@ -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)])]) diff --git a/configure b/configure deleted file mode 100755 index 19c0cd9faf..0000000000 --- a/configure +++ /dev/null @@ -1,18038 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.53 for PostgreSQL 7.3devel. -# -# Report bugs to . -# -# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -# -# Copyright 2002 PostgreSQL Global Development Group - -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - - -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix -fi - -# NLS nuisances. -# Support unset when possible. -if (FOO=FOO; unset FOO) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - -(set +x; test -n "`(LANG=C; export LANG) 2>&1`") && - { $as_unset LANG || test "${LANG+set}" != set; } || - { LANG=C; export LANG; } -(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") && - { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } || - { LC_ALL=C; export LC_ALL; } -(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") && - { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } || - { LC_TIME=C; export LC_TIME; } -(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") && - { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } || - { LC_CTYPE=C; export LC_CTYPE; } -(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") && - { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } || - { LANGUAGE=C; export LANGUAGE; } -(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") && - { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } || - { LC_COLLATE=C; export LC_COLLATE; } -(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") && - { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } || - { LC_NUMERIC=C; export LC_NUMERIC; } -(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") && - { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } || - { LC_MESSAGES=C; export LC_MESSAGES; } - - -# Name of the executable. -as_me=`(basename "$0") 2>/dev/null || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - -# PATH needs CR, and LINENO needs CR and PATH. -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conftest.sh - echo "exit 0" >>conftest.sh - chmod +x conftest.sh - if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conftest.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | - sed ' - N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, - t loop - s,-$,, - s,^['$as_cr_digits']*\n,, - ' >$as_me.lineno && - chmod +x $as_me.lineno || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno - # Exit status is that of the last command. - exit -} - - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; -esac - -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.file - -as_executable_p="test -f" - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" - - -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; } - - -# Name of the host. -# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -exec 6>&1 - -# -# Initializations. -# -ac_default_prefix=/usr/local -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} - -# Maximum number of lines to put in a shell here document. -# This variable seems obsolete. It should probably be removed, and -# only ac_max_sed_lines should be used. -: ${ac_max_here_lines=38} - -# Identity of this package. -PACKAGE_NAME='PostgreSQL' -PACKAGE_TARNAME='postgresql' -PACKAGE_VERSION='7.3devel' -PACKAGE_STRING='PostgreSQL 7.3devel' -PACKAGE_BUGREPORT='pgsql-bugs@postgresql.org' - -ac_unique_file="src/backend/access/common/heaptuple.c" -ac_default_prefix=/usr/local/pgsql -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#if HAVE_SYS_TYPES_H -# include -#endif -#if HAVE_SYS_STAT_H -# include -#endif -#if STDC_HEADERS -# include -# include -#else -# if HAVE_STDLIB_H -# include -# endif -#endif -#if HAVE_STRING_H -# if !STDC_HEADERS && HAVE_MEMORY_H -# include -# endif -# include -#endif -#if HAVE_STRINGS_H -# include -#endif -#if HAVE_INTTYPES_H -# include -#else -# if HAVE_STDINT_H -# include -# endif -#endif -#if HAVE_UNISTD_H -# include -#endif" - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${prefix}/doc' -mandir='${prefix}/man' - -ac_prev= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" - ac_prev= - continue - fi - - ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_option in - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) - datadir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - eval "enable_$ac_feature=no" ;; - - -enable-* | --enable-*) - ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 - { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "enable_$ac_feature='$ac_optarg'" ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -docdir | --docdir | --infodi | --infod | --doc | --inf) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --infodi=* | --infod=* | --doc=* | --inf=*) - docdir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package| sed 's/-/_/g'` - case $ac_option in - *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; - *) ac_optarg=yes ;; - esac - eval "with_$ac_package='$ac_optarg'" ;; - - -without-* | --without-*) - ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 - { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/-/_/g'` - eval "with_$ac_package=no" ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) { echo "$as_me: error: unrecognized option: $ac_option -Try \`$0 --help' for more information." >&2 - { (exit 1); exit 1; }; } - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 - { (exit 1); exit 1; }; } - ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` - eval "$ac_envvar='$ac_optarg'" - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - { echo "$as_me: error: missing argument to $ac_option" >&2 - { (exit 1); exit 1; }; } -fi - -# Be sure to have absolute paths. -for ac_var in exec_prefix prefix -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* | NONE | '' ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; - esac -done - -# Be sure to have absolute paths. -for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ - localstatedir libdir includedir oldincludedir docdir mandir -do - eval ac_val=$`echo $ac_var` - case $ac_val in - [\\/$]* | ?:[\\/]* ) ;; - *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 - { (exit 1); exit 1; }; };; - esac -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. - If a cross compiler is detected then cross compile mode will be used." >&2 - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_confdir=`(dirname "$0") 2>/dev/null || -$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$0" : 'X\(//\)[^/]' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$0" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 - { (exit 1); exit 1; }; } - else - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 - { (exit 1); exit 1; }; } - fi -fi -srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` -ac_env_build_alias_set=${build_alias+set} -ac_env_build_alias_value=$build_alias -ac_cv_env_build_alias_set=${build_alias+set} -ac_cv_env_build_alias_value=$build_alias -ac_env_host_alias_set=${host_alias+set} -ac_env_host_alias_value=$host_alias -ac_cv_env_host_alias_set=${host_alias+set} -ac_cv_env_host_alias_value=$host_alias -ac_env_target_alias_set=${target_alias+set} -ac_env_target_alias_value=$target_alias -ac_cv_env_target_alias_set=${target_alias+set} -ac_cv_env_target_alias_value=$target_alias -ac_env_CC_set=${CC+set} -ac_env_CC_value=$CC -ac_cv_env_CC_set=${CC+set} -ac_cv_env_CC_value=$CC -ac_env_CFLAGS_set=${CFLAGS+set} -ac_env_CFLAGS_value=$CFLAGS -ac_cv_env_CFLAGS_set=${CFLAGS+set} -ac_cv_env_CFLAGS_value=$CFLAGS -ac_env_LDFLAGS_set=${LDFLAGS+set} -ac_env_LDFLAGS_value=$LDFLAGS -ac_cv_env_LDFLAGS_set=${LDFLAGS+set} -ac_cv_env_LDFLAGS_value=$LDFLAGS -ac_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_env_CPPFLAGS_value=$CPPFLAGS -ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} -ac_cv_env_CPPFLAGS_value=$CPPFLAGS -ac_env_CPP_set=${CPP+set} -ac_env_CPP_value=$CPP -ac_cv_env_CPP_set=${CPP+set} -ac_cv_env_CPP_value=$CPP -ac_env_CXX_set=${CXX+set} -ac_env_CXX_value=$CXX -ac_cv_env_CXX_set=${CXX+set} -ac_cv_env_CXX_value=$CXX -ac_env_CXXFLAGS_set=${CXXFLAGS+set} -ac_env_CXXFLAGS_value=$CXXFLAGS -ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set} -ac_cv_env_CXXFLAGS_value=$CXXFLAGS -ac_env_CXXCPP_set=${CXXCPP+set} -ac_env_CXXCPP_value=$CXXCPP -ac_cv_env_CXXCPP_set=${CXXCPP+set} -ac_cv_env_CXXCPP_value=$CXXCPP -ac_env_DOCBOOKSTYLE_set=${DOCBOOKSTYLE+set} -ac_env_DOCBOOKSTYLE_value=$DOCBOOKSTYLE -ac_cv_env_DOCBOOKSTYLE_set=${DOCBOOKSTYLE+set} -ac_cv_env_DOCBOOKSTYLE_value=$DOCBOOKSTYLE - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures PostgreSQL 7.3devel to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -_ACEOF - - cat <<_ACEOF -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data [PREFIX/share] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --infodir=DIR info documentation [PREFIX/info] - --mandir=DIR man documentation [PREFIX/man] -_ACEOF - - cat <<\_ACEOF - -System types: - --build=BUILD configure for building on BUILD [guessed] - --host=HOST cross-compile to build programs to run on HOST [BUILD] -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of PostgreSQL 7.3devel:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-integer-datetimes enable 64-bit integer date/time support - --enable-recode enable character set recode support - --enable-nls[=LANGUAGES] enable Native Language Support - --disable-shared do not build shared libraries - --disable-rpath do not embed shared library search path in executables - --enable-debug build with debugging symbols (-g) - --enable-depend turn on automatic dependency tracking - --enable-cassert enable assertion checks (for debugging) - --enable-odbc build the ODBC driver package - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - - --with-includes=DIRS look for additional header files in DIRS - --with-libraries=DIRS look for additional libraries in DIRS - --with-libs=DIRS alternative spelling of --with-libraries - --with-pgport=PORTNUM change default port number 5432 - --with-maxbackends=N set default maximum number of connections 32 - --with-tcl build Tcl and Tk interfaces - --without-tk do not build Tk interfaces if Tcl is enabled - --with-tclconfig=DIR tclConfig.sh and tkConfig.sh are in DIR - --with-tkconfig=DIR tkConfig.sh is in DIR - --with-perl build Perl interface and PL/Perl - --with-python build Python interface module - --with-java build JDBC interface and Java tools - --with-krb4[=DIR] build with Kerberos 4 support [/usr/athena] - --with-krb5[=DIR] build with Kerberos 5 support [/usr/athena] - --with-krb-srvnam=NAME name of the service principal in Kerberos postgres - --with-pam build with PAM support - --with-openssl[=DIR] build with OpenSSL support [/usr/local/ssl] - --without-readline do not use Readline - --without-zlib do not use Zlib - --with-unixodbc build ODBC driver for unixODBC - --with-iodbc build ODBC driver for iODBC - --with-odbcinst=DIR default directory for odbcinst.ini sysconfdir - --with-CXX build C++ modules (libpq++) - --with-gnu-ld assume the C compiler uses GNU ld default=no - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have - headers in a nonstandard directory - CPP C preprocessor - CXX C++ compiler command - CXXFLAGS C++ compiler flags - CXXCPP C++ preprocessor - DOCBOOKSTYLE - location of DocBook stylesheets - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to . -_ACEOF -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - ac_popdir=`pwd` - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d $ac_dir || continue - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac -# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be -# absolute. -ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` -ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd` -ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` -ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` - - cd $ac_dir - # Check for guested configure; otherwise get Cygnus style configure. - if test -f $ac_srcdir/configure.gnu; then - echo - $SHELL $ac_srcdir/configure.gnu --help=recursive - elif test -f $ac_srcdir/configure; then - echo - $SHELL $ac_srcdir/configure --help=recursive - elif test -f $ac_srcdir/configure.ac || - test -f $ac_srcdir/configure.in; then - echo - $ac_configure --help - else - echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi - cd $ac_popdir - done -fi - -test -n "$ac_init_help" && exit 0 -if $ac_init_version; then - cat <<\_ACEOF -PostgreSQL configure 7.3devel -generated by GNU Autoconf 2.53 - -Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 -Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. - -Copyright 2002 PostgreSQL Global Development Group -_ACEOF - exit 0 -fi -exec 5>config.log -cat >&5 <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by PostgreSQL $as_me 7.3devel, which was -generated by GNU Autoconf 2.53. Invocation command line was - - $ $0 $@ - -_ACEOF -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -hostinfo = `(hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - echo "PATH: $as_dir" -done - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Also quote any args containing shell meta-characters. -ac_configure_args= -ac_sep= -for ac_arg -do - case $ac_arg in - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n ) continue ;; - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - continue ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" - ac_sep=" " ;; - esac - # Get rid of the leading space. -done - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Be sure not to use single quotes in there, as some shells, -# such as our DU 5.0 friend, will then `close' the trap. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - cat <<\_ASBOX -## ---------------- ## -## Cache variables. ## -## ---------------- ## -_ASBOX - echo - # The following way of writing the cache mishandles newlines in values, -{ - (set) 2>&1 | - case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in - *ac_space=\ *) - sed -n \ - "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" - ;; - *) - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" - ;; - esac; -} - echo - if test -s confdefs.h; then - cat <<\_ASBOX -## ----------- ## -## confdefs.h. ## -## ----------- ## -_ASBOX - echo - sed "/^$/d" confdefs.h - echo - fi - test "$ac_signal" != 0 && - echo "$as_me: caught signal $ac_signal" - echo "$as_me: exit $exit_status" - } >&5 - rm -f core core.* *.core && - rm -rf conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status - ' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo >confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi -fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 -echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special - # files actually), so we avoid doing that. - if test -f "$cache_file"; then - { echo "$as_me:$LINENO: loading cache $cache_file" >&5 -echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . $cache_file;; - *) . ./$cache_file;; - esac - fi -else - { echo "$as_me:$LINENO: creating cache $cache_file" >&5 -echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in `(set) 2>&1 | - sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val="\$ac_cv_env_${ac_var}_value" - eval ac_new_val="\$ac_env_${ac_var}_value" - case $ac_old_set,$ac_new_set in - set,) - { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 -echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 -echo "$as_me: former value: $ac_old_val" >&2;} - { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 -echo "$as_me: current value: $ac_new_val" >&2;} - ac_cache_corrupted=: - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) - ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 -echo "$as_me: error: changes in the environment can compromise the build" >&2;} - { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 -echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -ac_aux_dir= -for ac_dir in config $srcdir/config; do - if test -f $ac_dir/install-sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f $ac_dir/install.sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f $ac_dir/shtool; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in config $srcdir/config" >&5 -echo "$as_me: error: cannot find install-sh or install.sh in config $srcdir/config" >&2;} - { (exit 1); exit 1; }; } -fi -ac_config_guess="$SHELL $ac_aux_dir/config.guess" -ac_config_sub="$SHELL $ac_aux_dir/config.sub" -ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. - - -configure_args=$ac_configure_args - - - -cat >>confdefs.h <<_ACEOF -#define PG_VERSION "$PACKAGE_VERSION" -_ACEOF - - -# Make sure we can run config.sub. -$ac_config_sub sun4 >/dev/null 2>&1 || - { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5 -echo "$as_me: error: cannot run $ac_config_sub" >&2;} - { (exit 1); exit 1; }; } - -echo "$as_me:$LINENO: checking build system type" >&5 -echo $ECHO_N "checking build system type... $ECHO_C" >&6 -if test "${ac_cv_build+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_build_alias=$build_alias -test -z "$ac_cv_build_alias" && - ac_cv_build_alias=`$ac_config_guess` -test -z "$ac_cv_build_alias" && - { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 -echo "$as_me: error: cannot guess build type; you must specify one" >&2;} - { (exit 1); exit 1; }; } -ac_cv_build=`$ac_config_sub $ac_cv_build_alias` || - { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5 -echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;} - { (exit 1); exit 1; }; } - -fi -echo "$as_me:$LINENO: result: $ac_cv_build" >&5 -echo "${ECHO_T}$ac_cv_build" >&6 -build=$ac_cv_build -build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` - - -echo "$as_me:$LINENO: checking host system type" >&5 -echo $ECHO_N "checking host system type... $ECHO_C" >&6 -if test "${ac_cv_host+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_host_alias=$host_alias -test -z "$ac_cv_host_alias" && - ac_cv_host_alias=$ac_cv_build_alias -ac_cv_host=`$ac_config_sub $ac_cv_host_alias` || - { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5 -echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;} - { (exit 1); exit 1; }; } - -fi -echo "$as_me:$LINENO: result: $ac_cv_host" >&5 -echo "${ECHO_T}$ac_cv_host" >&6 -host=$ac_cv_host -host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` - - - -template= -echo "$as_me:$LINENO: checking which template to use" >&5 -echo $ECHO_N "checking which template to use... $ECHO_C" >&6 - - - - -# Check whether --with-template or --without-template was given. -if test "${with_template+set}" = set; then - withval="$with_template" - - case $withval in - yes) - { { echo "$as_me:$LINENO: error: argument required for --with-template option" >&5 -echo "$as_me: error: argument required for --with-template option" >&2;} - { (exit 1); exit 1; }; } - ;; - no) - { { echo "$as_me:$LINENO: error: argument required for --with-template option" >&5 -echo "$as_me: error: argument required for --with-template option" >&2;} - { (exit 1); exit 1; }; } - ;; - *) - - case $withval in - list) echo; ls "$srcdir/src/template"; exit;; - *) if test -f "$srcdir/src/template/$with_template" ; then - template=$withval - else - { { echo "$as_me:$LINENO: error: '$withval' is not a valid template name. Use 'list' for a list." >&5 -echo "$as_me: error: '$withval' is not a valid template name. Use 'list' for a list." >&2;} - { (exit 1); exit 1; }; } - fi;; - esac - - ;; - esac - -else - - # --with-template not given - -case $host_os in - aix*) template=aix ;; - beos*) template=beos ;; - bsdi*) template=bsdi ;; - cygwin*) template=win ;; - darwin*) template=darwin ;; - dgux*) template=dgux ;; - freebsd*) template=freebsd ;; - hpux*) template=hpux ;; - irix*) template=irix5 ;; - linux*) template=linux ;; - netbsd*) template=netbsd ;; -nextstep*) template=nextstep ;; - openbsd*) template=openbsd ;; - osf*) template=osf ;; - qnx*) template=qnx4 ;; - sco*) template=sco ;; - solaris*) template=solaris ;; - sunos*) template=sunos4 ;; - sysv4.2*) - case $host_vendor in - univel) template=univel ;; - esac ;; - sysv4*) template=svr4 ;; - sysv5*) template=unixware ;; - ultrix*) template=ultrix4 ;; -esac - - if test x"$template" = x"" ; then - { { echo "$as_me:$LINENO: error: -******************************************************************* -PostgreSQL has apparently not been ported to your platform yet. -To try a manual configuration, look into the src/template directory -for a similar platform and use the '--with-template=' option. - -Please also contact to see about -rectifying this. Include the above 'checking host system type...' -line. -******************************************************************* -" >&5 -echo "$as_me: error: -******************************************************************* -PostgreSQL has apparently not been ported to your platform yet. -To try a manual configuration, look into the src/template directory -for a similar platform and use the '--with-template=' option. - -Please also contact to see about -rectifying this. Include the above 'checking host system type...' -line. -******************************************************************* -" >&2;} - { (exit 1); exit 1; }; } - fi - - -fi; - - -echo "$as_me:$LINENO: result: $template" >&5 -echo "${ECHO_T}$template" >&6 - -PORTNAME=$template - - -# Pick right test-and-set (TAS) code. Most platforms have inline -# assembler code in src/include/storage/s_lock.h, so we just use -# a dummy file here. -case $host in - *-*-hpux*) need_tas=yes; tas_file=hpux.s ;; - sparc-*-solaris*) need_tas=yes; tas_file=solaris_sparc.s ;; - i?86-*-solaris*) need_tas=yes; tas_file=solaris_i386.s ;; - *) need_tas=no; tas_file=dummy.s ;; -esac -ac_config_links="$ac_config_links src/backend/port/tas.s:src/backend/port/tas/${tas_file}" - - -if test "$need_tas" = yes ; then - TAS=tas.o -fi - - - - -## -## Command line options -## - - -# -# Add non-standard directories to the include path -# - - - -# Check whether --with-includes or --without-includes was given. -if test "${with_includes+set}" = set; then - withval="$with_includes" - - case $withval in - yes) - { { echo "$as_me:$LINENO: error: argument required for --with-includes option" >&5 -echo "$as_me: error: argument required for --with-includes option" >&2;} - { (exit 1); exit 1; }; } - ;; - no) - { { echo "$as_me:$LINENO: error: argument required for --with-includes option" >&5 -echo "$as_me: error: argument required for --with-includes option" >&2;} - { (exit 1); exit 1; }; } - ;; - *) - - ;; - esac - -fi; - - - -# -# Add non-standard directories to the library search path -# - - - -# Check whether --with-libraries or --without-libraries was given. -if test "${with_libraries+set}" = set; then - withval="$with_libraries" - - case $withval in - yes) - { { echo "$as_me:$LINENO: error: argument required for --with-libraries option" >&5 -echo "$as_me: error: argument required for --with-libraries option" >&2;} - { (exit 1); exit 1; }; } - ;; - no) - { { echo "$as_me:$LINENO: error: argument required for --with-libraries option" >&5 -echo "$as_me: error: argument required for --with-libraries option" >&2;} - { (exit 1); exit 1; }; } - ;; - *) - LIBRARY_DIRS=$withval - ;; - esac - -fi; - - - - - -# Check whether --with-libs or --without-libs was given. -if test "${with_libs+set}" = set; then - withval="$with_libs" - - case $withval in - yes) - { { echo "$as_me:$LINENO: error: argument required for --with-libs option" >&5 -echo "$as_me: error: argument required for --with-libs option" >&2;} - { (exit 1); exit 1; }; } - ;; - no) - { { echo "$as_me:$LINENO: error: argument required for --with-libs option" >&5 -echo "$as_me: error: argument required for --with-libs option" >&2;} - { (exit 1); exit 1; }; } - ;; - *) - LIBRARY_DIRS=$withval - ;; - esac - -fi; - - - -# -# 64-bit integer date/time storage (--enable-integer-datetimes) -# -echo "$as_me:$LINENO: checking whether to build with 64-bit integer date/time support" >&5 -echo $ECHO_N "checking whether to build with 64-bit integer date/time support... $ECHO_C" >&6 - - -# Check whether --enable-integer-datetimes or --disable-integer-datetimes was given. -if test "${enable_integer_datetimes+set}" = set; then - enableval="$enable_integer_datetimes" - - case $enableval in - yes) - -cat >>confdefs.h <<\_ACEOF -#define USE_INTEGER_DATETIMES 1 -_ACEOF - - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --enable-integer-datetimes option" >&5 -echo "$as_me: error: no argument expected for --enable-integer-datetimes option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - enable_integer_datetimes=no - -fi; - -echo "$as_me:$LINENO: result: $enable_integer_datetimes" >&5 -echo "${ECHO_T}$enable_integer_datetimes" >&6 - - -# Character set recode (--enable-recode) -# -echo "$as_me:$LINENO: checking whether to build with recode support" >&5 -echo $ECHO_N "checking whether to build with recode support... $ECHO_C" >&6 - - -# Check whether --enable-recode or --disable-recode was given. -if test "${enable_recode+set}" = set; then - enableval="$enable_recode" - - case $enableval in - yes) - -cat >>confdefs.h <<\_ACEOF -#define CYR_RECODE 1 -_ACEOF - - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --enable-recode option" >&5 -echo "$as_me: error: no argument expected for --enable-recode option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - enable_recode=no - -fi; - -echo "$as_me:$LINENO: result: $enable_recode" >&5 -echo "${ECHO_T}$enable_recode" >&6 - - -# -# Multibyte support -# -MULTIBYTE=SQL_ASCII - -cat >>confdefs.h <<\_ACEOF -#define MULTIBYTE 1 -_ACEOF - - - -# -# NLS -# -echo "$as_me:$LINENO: checking whether NLS is wanted" >&5 -echo $ECHO_N "checking whether NLS is wanted... $ECHO_C" >&6 - - -# Check whether --enable-nls or --disable-nls was given. -if test "${enable_nls+set}" = set; then - enableval="$enable_nls" - - case $enableval in - yes) - : - ;; - no) - : - ;; - *) - enable_nls=yes -WANTED_LANGUAGES=$enableval - ;; - esac - -else - enable_nls=no -fi; - - -if test "$enable_nls" = yes; then - -cat >>confdefs.h <<\_ACEOF -#define ENABLE_NLS 1 -_ACEOF - -fi - -echo "$as_me:$LINENO: result: $enable_nls" >&5 -echo "${ECHO_T}$enable_nls" >&6 - - - -# -# Default port number (--with-pgport), default 5432 -# -echo "$as_me:$LINENO: checking for default port number" >&5 -echo $ECHO_N "checking for default port number... $ECHO_C" >&6 - - - -# Check whether --with-pgport or --without-pgport was given. -if test "${with_pgport+set}" = set; then - withval="$with_pgport" - - case $withval in - yes) - { { echo "$as_me:$LINENO: error: argument required for --with-pgport option" >&5 -echo "$as_me: error: argument required for --with-pgport option" >&2;} - { (exit 1); exit 1; }; } - ;; - no) - { { echo "$as_me:$LINENO: error: argument required for --with-pgport option" >&5 -echo "$as_me: error: argument required for --with-pgport option" >&2;} - { (exit 1); exit 1; }; } - ;; - *) - default_port=$withval - ;; - esac - -else - default_port=5432 -fi; - -echo "$as_me:$LINENO: result: $default_port" >&5 -echo "${ECHO_T}$default_port" >&6 -# Need both of these because some places want an integer and some a string - -cat >>confdefs.h <<_ACEOF -#define DEF_PGPORT ${default_port} -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define DEF_PGPORT_STR "${default_port}" -_ACEOF - - - -# -# Maximum number of allowed connections (--with-maxbackends), default 32 -# -echo "$as_me:$LINENO: checking for default soft limit on number of connections" >&5 -echo $ECHO_N "checking for default soft limit on number of connections... $ECHO_C" >&6 - - - -# Check whether --with-maxbackends or --without-maxbackends was given. -if test "${with_maxbackends+set}" = set; then - withval="$with_maxbackends" - - case $withval in - yes) - { { echo "$as_me:$LINENO: error: argument required for --with-maxbackends option" >&5 -echo "$as_me: error: argument required for --with-maxbackends option" >&2;} - { (exit 1); exit 1; }; } - ;; - no) - { { echo "$as_me:$LINENO: error: argument required for --with-maxbackends option" >&5 -echo "$as_me: error: argument required for --with-maxbackends option" >&2;} - { (exit 1); exit 1; }; } - ;; - *) - - ;; - esac - -else - with_maxbackends=32 -fi; - -echo "$as_me:$LINENO: result: $with_maxbackends" >&5 -echo "${ECHO_T}$with_maxbackends" >&6 - -cat >>confdefs.h <<_ACEOF -#define DEF_MAXBACKENDS $with_maxbackends -_ACEOF - - - -# -# Option to disable shared libraries -# - - -# Check whether --enable-shared or --disable-shared was given. -if test "${enable_shared+set}" = set; then - enableval="$enable_shared" - - case $enableval in - yes) - : - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --enable-shared option" >&5 -echo "$as_me: error: no argument expected for --enable-shared option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - enable_shared=yes - -fi; - - - -# -# '-rpath'-like feature can be disabled -# - - -# Check whether --enable-rpath or --disable-rpath was given. -if test "${enable_rpath+set}" = set; then - enableval="$enable_rpath" - - case $enableval in - yes) - : - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --enable-rpath option" >&5 -echo "$as_me: error: no argument expected for --enable-rpath option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - enable_rpath=yes - -fi; - - - - -# -# --enable-debug adds -g to compiler flags -# - - -# Check whether --enable-debug or --disable-debug was given. -if test "${enable_debug+set}" = set; then - enableval="$enable_debug" - - case $enableval in - yes) - : - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --enable-debug option" >&5 -echo "$as_me: error: no argument expected for --enable-debug option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - enable_debug=no - -fi; - - - -# -# C compiler -# - -# For historical reasons you can also use --with-CC to specify the C compiler -# to use, although the standard way to do this is to set the CC environment -# variable. - - - -# Check whether --with-CC or --without-CC was given. -if test "${with_CC+set}" = set; then - withval="$with_CC" - - case $withval in - yes) - { { echo "$as_me:$LINENO: error: argument required for --with-CC option" >&5 -echo "$as_me: error: argument required for --with-CC option" >&2;} - { (exit 1); exit 1; }; } - ;; - no) - { { echo "$as_me:$LINENO: error: argument required for --with-CC option" >&5 -echo "$as_me: error: argument required for --with-CC option" >&2;} - { (exit 1); exit 1; }; } - ;; - *) - CC=$with_CC - ;; - esac - -fi; - - -case $template in - aix) pgac_cc_list="gcc xlc";; - irix) pgac_cc_list="cc";; # no gcc - *) pgac_cc_list="gcc cc";; -esac - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - for ac_prog in $pgac_cc_list - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in $pgac_cc_list -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$ac_ct_CC" && break -done - - CC=$ac_ct_CC -fi - - -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH" >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH" >&2;} - { (exit 1); exit 1; }; } - -# Provide some information about the compiler. -echo "$as_me:$LINENO:" \ - "checking for C compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 - (eval $ac_compiler --version &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 - (eval $ac_compiler -v &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 - (eval $ac_compiler -V &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.exe" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -echo "$as_me:$LINENO: checking for C compiler default output" >&5 -echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 -ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 - (eval $ac_link_default) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # Find the output, starting from the most likely. This scheme is -# not robust to junk in `.', hence go to wildcards (a.*) only as a last -# resort. - -# Be careful to initialize this variable, since it used to be cached. -# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. -ac_cv_exeext= -for ac_file in `ls a_out.exe a.exe conftest.exe 2>/dev/null; - ls a.out conftest 2>/dev/null; - ls a.* conftest.* 2>/dev/null`; do - case $ac_file in - *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb | *.xSYM ) ;; - a.out ) # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - # FIXME: I believe we export ac_cv_exeext for Libtool --akim. - export ac_cv_exeext - break;; - * ) break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -{ { echo "$as_me:$LINENO: error: C compiler cannot create executables" >&5 -echo "$as_me: error: C compiler cannot create executables" >&2;} - { (exit 77); exit 77; }; } -fi - -ac_exeext=$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6 - -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 -# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 -# If not cross compiling, check that we can run a simple program. -if test "$cross_compiling" != yes; then - if { ac_try='./$ac_file' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { echo "$as_me:$LINENO: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'." >&5 -echo "$as_me: error: cannot run C compiled programs. -If you meant to cross compile, use \`--host'." >&2;} - { (exit 1); exit 1; }; } - fi - fi -fi -echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - -rm -f a.out a.exe conftest$ac_cv_exeext -ac_clean_files=$ac_clean_files_save -# Check the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 -echo "$as_me:$LINENO: result: $cross_compiling" >&5 -echo "${ECHO_T}$cross_compiling" >&6 - -echo "$as_me:$LINENO: checking for suffix of executables" >&5 -echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in `(ls conftest.exe; ls conftest; ls conftest.*) 2>/dev/null`; do - case $ac_file in - *.$ac_ext | *.o | *.obj | *.xcoff | *.tds | *.d | *.pdb ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - export ac_cv_exeext - break;; - * ) break;; - esac -done -else - { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link" >&5 -echo "$as_me: error: cannot compute suffix of executables: cannot compile and link" >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest$ac_cv_exeext -echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -echo "${ECHO_T}$ac_cv_exeext" >&6 - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -echo "$as_me:$LINENO: checking for suffix of object files" >&5 -echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 -if test "${ac_cv_objext+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then - for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile" >&5 -echo "$as_me: error: cannot compute suffix of object files: cannot compile" >&2;} - { (exit 1); exit 1; }; } -fi - -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -echo "${ECHO_T}$ac_cv_objext" >&6 -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 -if test "${ac_cv_c_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_compiler_gnu=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 -GCC=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -CFLAGS="-g" -echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 -if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cc_g=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_prog_cc_g=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -# Some people use a C++ compiler to compile C. Since we use `exit', -# in C++ we need to declare it. In case someone uses the same compiler -# for both compiling C and C++ we need to have the C++ compiler decide -# the declaration of exit, since it's the most demanding environment. -cat >conftest.$ac_ext <<_ACEOF -#ifndef __cplusplus - choke me -#endif -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - for ac_declaration in \ - ''\ - '#include ' \ - 'extern "C" void std::exit (int) throw (); using std::exit;' \ - 'extern "C" void std::exit (int); using std::exit;' \ - 'extern "C" void exit (int) throw ();' \ - 'extern "C" void exit (int);' \ - 'void exit (int);' -do - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -$ac_declaration -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -continue -fi -rm -f conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_declaration -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest.$ac_ext -done -rm -f conftest* -if test -n "$ac_declaration"; then - echo '#ifdef __cplusplus' >>confdefs.h - echo $ac_declaration >>confdefs.h - echo '#endif' >>confdefs.h -fi - -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest.$ac_ext -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -# Read the template -. "$srcdir/src/template/$template" || exit - -if test "$ac_env_CFLAGS_set" = set; then - CFLAGS=$ac_env_CFLAGS_value -fi -if test "$enable_debug" = yes && test "$ac_cv_prog_cc_g" = yes; then - CFLAGS="$CFLAGS -g" -fi -{ echo "$as_me:$LINENO: using CFLAGS=$CFLAGS" >&5 -echo "$as_me: using CFLAGS=$CFLAGS" >&6;} -# Check if the compiler still works with the template settings -echo "$as_me:$LINENO: checking whether the C compiler still works" >&5 -echo $ECHO_N "checking whether the C compiler still works... $ECHO_C" >&6 - -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - { { echo "$as_me:$LINENO: error: cannot proceed" >&5 -echo "$as_me: error: cannot proceed" >&2;} - { (exit 1); exit 1; }; } -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 -echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if test "${ac_cv_prog_CPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -echo "$as_me:$LINENO: result: $CPP" >&5 -echo "${ECHO_T}$CPP" >&6 -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : -else - { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check" >&5 -echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check" >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -# Create compiler version string -if test x"$GCC" = x"yes" ; then - cc_string="GCC `${CC} --version | sed q`" -else - cc_string=$CC -fi - -cat >>confdefs.h <<_ACEOF -#define PG_VERSION_STR "PostgreSQL $PACKAGE_VERSION on $host, compiled by $cc_string" -_ACEOF - - - -# -# Automatic dependency tracking -# - - -# Check whether --enable-depend or --disable-depend was given. -if test "${enable_depend+set}" = set; then - enableval="$enable_depend" - - case $enableval in - yes) - autodepend=yes - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --enable-depend option" >&5 -echo "$as_me: error: no argument expected for --enable-depend option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - enable_depend=no - -fi; - - - - -# -# Enable assert checks -# - - -# Check whether --enable-cassert or --disable-cassert was given. -if test "${enable_cassert+set}" = set; then - enableval="$enable_cassert" - - case $enableval in - yes) - -cat >>confdefs.h <<\_ACEOF -#define USE_ASSERT_CHECKING 1 -_ACEOF - - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --enable-cassert option" >&5 -echo "$as_me: error: no argument expected for --enable-cassert option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - enable_cassert=no - -fi; - - - -# -# Include directories -# -ac_save_IFS=$IFS -IFS="${IFS}:" -# SRCH_INC comes from the template file -for dir in $with_includes $SRCH_INC; do - if test -d "$dir"; then - INCLUDES="$INCLUDES -I$dir" - else - { echo "$as_me:$LINENO: WARNING: *** Include directory $dir does not exist." >&5 -echo "$as_me: WARNING: *** Include directory $dir does not exist." >&2;} - fi -done -IFS=$ac_save_IFS - - - -# -# Library directories -# -ac_save_IFS=$IFS -IFS="${IFS}:" -# LIBRARY_DIRS comes from command line, SRCH_LIB from template file. -for dir in $LIBRARY_DIRS $SRCH_LIB; do - if test -d "$dir"; then - LIBDIRS="$LIBDIRS -L$dir" - else - { echo "$as_me:$LINENO: WARNING: *** Library directory $dir does not exist." >&5 -echo "$as_me: WARNING: *** Library directory $dir does not exist." >&2;} - fi -done -IFS=$ac_save_IFS - - -# -# Tcl/Tk -# -echo "$as_me:$LINENO: checking whether to build with Tcl" >&5 -echo $ECHO_N "checking whether to build with Tcl... $ECHO_C" >&6 - - - -# Check whether --with-tcl or --without-tcl was given. -if test "${with_tcl+set}" = set; then - withval="$with_tcl" - - case $withval in - yes) - : - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --with-tcl option" >&5 -echo "$as_me: error: no argument expected for --with-tcl option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - with_tcl=no - -fi; - -echo "$as_me:$LINENO: result: $with_tcl" >&5 -echo "${ECHO_T}$with_tcl" >&6 - - -# If Tcl is enabled (above) then Tk is also, unless the user disables it using --without-tk -echo "$as_me:$LINENO: checking whether to build with Tk" >&5 -echo $ECHO_N "checking whether to build with Tk... $ECHO_C" >&6 -if test "$with_tcl" = yes; then - - - -# Check whether --with-tk or --without-tk was given. -if test "${with_tk+set}" = set; then - withval="$with_tk" - - case $withval in - yes) - : - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --with-tk option" >&5 -echo "$as_me: error: no argument expected for --with-tk option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - with_tk=yes - -fi; - -else - with_tk=no -fi -echo "$as_me:$LINENO: result: $with_tk" >&5 -echo "${ECHO_T}$with_tk" >&6 - - - -# We see if the path to the Tcl/Tk configuration scripts is specified. -# This will override the use of tclsh to find the paths to search. - - - - -# Check whether --with-tclconfig or --without-tclconfig was given. -if test "${with_tclconfig+set}" = set; then - withval="$with_tclconfig" - - case $withval in - yes) - { { echo "$as_me:$LINENO: error: argument required for --with-tclconfig option" >&5 -echo "$as_me: error: argument required for --with-tclconfig option" >&2;} - { (exit 1); exit 1; }; } - ;; - no) - { { echo "$as_me:$LINENO: error: argument required for --with-tclconfig option" >&5 -echo "$as_me: error: argument required for --with-tclconfig option" >&2;} - { (exit 1); exit 1; }; } - ;; - *) - - ;; - esac - -fi; - - -# We see if the path to the Tk configuration scripts is specified. -# This will override the use of tclsh to find the paths to search. - - - - -# Check whether --with-tkconfig or --without-tkconfig was given. -if test "${with_tkconfig+set}" = set; then - withval="$with_tkconfig" - - case $withval in - yes) - { { echo "$as_me:$LINENO: error: argument required for --with-tkconfig option" >&5 -echo "$as_me: error: argument required for --with-tkconfig option" >&2;} - { (exit 1); exit 1; }; } - ;; - no) - { { echo "$as_me:$LINENO: error: argument required for --with-tkconfig option" >&5 -echo "$as_me: error: argument required for --with-tkconfig option" >&2;} - { (exit 1); exit 1; }; } - ;; - *) - - ;; - esac - -fi; - - -# -# Optionally build Perl modules (Pg.pm and PL/Perl) -# -echo "$as_me:$LINENO: checking whether to build Perl modules" >&5 -echo $ECHO_N "checking whether to build Perl modules... $ECHO_C" >&6 - - - -# Check whether --with-perl or --without-perl was given. -if test "${with_perl+set}" = set; then - withval="$with_perl" - - case $withval in - yes) - : - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --with-perl option" >&5 -echo "$as_me: error: no argument expected for --with-perl option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - with_perl=no - -fi; - -echo "$as_me:$LINENO: result: $with_perl" >&5 -echo "${ECHO_T}$with_perl" >&6 - - -# -# Optionally build Python interface module -# -echo "$as_me:$LINENO: checking whether to build Python modules" >&5 -echo $ECHO_N "checking whether to build Python modules... $ECHO_C" >&6 - - - -# Check whether --with-python or --without-python was given. -if test "${with_python+set}" = set; then - withval="$with_python" - - case $withval in - yes) - : - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --with-python option" >&5 -echo "$as_me: error: no argument expected for --with-python option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - with_python=no - -fi; - -echo "$as_me:$LINENO: result: $with_python" >&5 -echo "${ECHO_T}$with_python" >&6 - - -# -# Optionally build the Java/JDBC tools -# -echo "$as_me:$LINENO: checking whether to build Java/JDBC tools" >&5 -echo $ECHO_N "checking whether to build Java/JDBC tools... $ECHO_C" >&6 - - - -# Check whether --with-java or --without-java was given. -if test "${with_java+set}" = set; then - withval="$with_java" - - case $withval in - yes) - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - - for ac_prog in jakarta-ant ant ant.sh ant.bat -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_path_ANT+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $ANT in - [\\/]* | ?:[\\/]*) - ac_cv_path_ANT="$ANT" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ANT="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - ;; -esac -fi -ANT=$ac_cv_path_ANT - -if test -n "$ANT"; then - echo "$as_me:$LINENO: result: $ANT" >&5 -echo "${ECHO_T}$ANT" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$ANT" && break -done - - - echo "$as_me:$LINENO: checking whether $ANT works" >&5 -echo $ECHO_N "checking whether $ANT works... $ECHO_C" >&6 -if test "${pgac_cv_prog_ant_works+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - cat > conftest.java << EOF -public class conftest { - int testmethod(int a, int b) { - return a + b; - } -} -EOF - - cat > conftest.xml << EOF - - - - - - -EOF - - pgac_cmd='$ANT -buildfile conftest.xml 1>&2' - { (eval echo "$as_me:$LINENO: \"$pgac_cmd\"") >&5 - (eval $pgac_cmd) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - pgac_save_status=$? - if test $? = 0 && test -f ./conftest.class ; then - pgac_cv_prog_ant_works=yes - else - echo "configure: failed java program was:" >&5 - cat conftest.java >&5 - echo "configure: failed build file was:" >&5 - cat conftest.xml >&5 - pgac_cv_prog_ant_works=no - fi - - rm -f conftest* core core.* *.core - -fi -echo "$as_me:$LINENO: result: $pgac_cv_prog_ant_works" >&5 -echo "${ECHO_T}$pgac_cv_prog_ant_works" >&6 - - if test "$pgac_cv_prog_ant_works" != yes; then - { { echo "$as_me:$LINENO: error: ant does not work" >&5 -echo "$as_me: error: ant does not work" >&2;} - { (exit 1); exit 1; }; } - fi - - -if test -z "$ANT"; then - { { echo "$as_me:$LINENO: error: Ant is required to build Java components" >&5 -echo "$as_me: error: Ant is required to build Java components" >&2;} - { (exit 1); exit 1; }; } -fi - ;; - no) - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --with-java option" >&5 -echo "$as_me: error: no argument expected for --with-java option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - with_java=no -echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi; - - - - -# -# Kerberos 4 -# -echo "$as_me:$LINENO: checking whether to build with Kerberos 4 support" >&5 -echo $ECHO_N "checking whether to build with Kerberos 4 support... $ECHO_C" >&6 - - - -# Check whether --with-krb4 or --without-krb4 was given. -if test "${with_krb4+set}" = set; then - withval="$with_krb4" - - case $withval in - yes) - krb4_prefix=/usr/athena - ;; - no) - : - ;; - *) - with_krb4=yes -krb4_prefix=$withval - ;; - esac - -else - with_krb4=no -fi; - - -if test "$with_krb4" = yes; then - - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - -cat >>confdefs.h <<\_ACEOF -#define KRB4 1 -_ACEOF - - - if test -d "$krb4_prefix/include"; then - INCLUDES="$INCLUDES -I$krb4_prefix/include" - fi - if test -d "$krb4_prefix/lib"; then - LIBDIRS="$LIBDIRS -L$krb4_prefix/lib" - fi - - krb_srvtab="/etc/srvtab" - -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - - - - -# -# Kerberos 5 -# -echo "$as_me:$LINENO: checking whether to build with Kerberos 5 support" >&5 -echo $ECHO_N "checking whether to build with Kerberos 5 support... $ECHO_C" >&6 - - - -# Check whether --with-krb5 or --without-krb5 was given. -if test "${with_krb5+set}" = set; then - withval="$with_krb5" - - case $withval in - yes) - krb5_prefix=/usr/athena - ;; - no) - : - ;; - *) - with_krb5=yes -krb5_prefix=$withval - ;; - esac - -else - with_krb5=no -fi; - - -if test "$with_krb5" = yes; then - - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - -cat >>confdefs.h <<\_ACEOF -#define KRB5 1 -_ACEOF - - - if test -d "$krb5_prefix/include"; then - INCLUDES="$INCLUDES -I$krb5_prefix/include" - fi - if test -d "$krb5_prefix/lib"; then - LIBDIRS="$LIBDIRS -L$krb5_prefix/lib" - fi - - krb_srvtab="FILE:\$(sysconfdir)/krb5.keytab" - -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - - - - -# Using both Kerberos 4 and Kerberos 5 at the same time isn't going to work. -if test "$with_krb4" = yes && test "$with_krb5" = yes ; then - { { echo "$as_me:$LINENO: error: Kerberos 4 and Kerberos 5 support cannot be combined" >&5 -echo "$as_me: error: Kerberos 4 and Kerberos 5 support cannot be combined" >&2;} - { (exit 1); exit 1; }; } -fi - - - - -# -# Kerberos configuration parameters -# - - - -# Check whether --with-krb-srvnam or --without-krb-srvnam was given. -if test "${with_krb_srvnam+set}" = set; then - withval="$with_krb_srvnam" - - case $withval in - yes) - { { echo "$as_me:$LINENO: error: argument required for --with-krb-srvnam option" >&5 -echo "$as_me: error: argument required for --with-krb-srvnam option" >&2;} - { (exit 1); exit 1; }; } - ;; - no) - { { echo "$as_me:$LINENO: error: argument required for --with-krb-srvnam option" >&5 -echo "$as_me: error: argument required for --with-krb-srvnam option" >&2;} - { (exit 1); exit 1; }; } - ;; - *) - - ;; - esac - -else - with_krb_srvnam="postgres" -fi; - - -cat >>confdefs.h <<_ACEOF -#define PG_KRB_SRVNAM "$with_krb_srvnam" -_ACEOF - - - -# -# PAM -# -echo "$as_me:$LINENO: checking whether to build with PAM support" >&5 -echo $ECHO_N "checking whether to build with PAM support... $ECHO_C" >&6 - - - -# Check whether --with-pam or --without-pam was given. -if test "${with_pam+set}" = set; then - withval="$with_pam" - - case $withval in - yes) - -cat >>confdefs.h <<\_ACEOF -#define USE_PAM 1 -_ACEOF - - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --with-pam option" >&5 -echo "$as_me: error: no argument expected for --with-pam option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - with_pam=no - -fi; - -echo "$as_me:$LINENO: result: $with_pam" >&5 -echo "${ECHO_T}$with_pam" >&6 - - - -# -# OpenSSL -# - - - -# Check whether --with-openssl or --without-openssl was given. -if test "${with_openssl+set}" = set; then - withval="$with_openssl" - - case $withval in - yes) - openssl_prefix=/usr/local/ssl - ;; - no) - : - ;; - *) - with_openssl=yes -openssl_prefix=$withval - ;; - esac - -else - with_openssl=no -fi; - - -if test "$with_openssl" = yes; then - - echo "$as_me:$LINENO: result: building with OpenSSL support" >&5 -echo "${ECHO_T}building with OpenSSL support" >&6 - -cat >>confdefs.h <<\_ACEOF -#define USE_SSL 1 -_ACEOF - - - if test -d "${openssl_prefix}/include" ; then - INCLUDES="$INCLUDES -I${openssl_prefix}/include" - fi - if test -d "${openssl_prefix}/lib" ; then - LIBDIRS="$LIBDIRS -L${openssl_prefix}/lib" - fi - -fi - - - - - -# -# Readline -# - - - -# Check whether --with-readline or --without-readline was given. -if test "${with_readline+set}" = set; then - withval="$with_readline" - - case $withval in - yes) - : - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --with-readline option" >&5 -echo "$as_me: error: no argument expected for --with-readline option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - with_readline=yes - -fi; - - -# -# Zlib -# - - - -# Check whether --with-zlib or --without-zlib was given. -if test "${with_zlib+set}" = set; then - withval="$with_zlib" - - case $withval in - yes) - : - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --with-zlib option" >&5 -echo "$as_me: error: no argument expected for --with-zlib option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - with_zlib=yes - -fi; - - - - -# -# Optionally enable the building of the ODBC driver -# - -# Old option name -if test "${with_odbc+set}" = set && test "${enable_odbc+set}" != set; then - enable_odbc=$with_odbc -fi - -echo "$as_me:$LINENO: checking whether to build the ODBC driver" >&5 -echo $ECHO_N "checking whether to build the ODBC driver... $ECHO_C" >&6 - - -# Check whether --enable-odbc or --disable-odbc was given. -if test "${enable_odbc+set}" = set; then - enableval="$enable_odbc" - - case $enableval in - yes) - : - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --enable-odbc option" >&5 -echo "$as_me: error: no argument expected for --enable-odbc option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - enable_odbc=no - -fi; - - - - -# Check whether --with-unixodbc or --without-unixodbc was given. -if test "${with_unixodbc+set}" = set; then - withval="$with_unixodbc" - - case $withval in - yes) - : - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --with-unixodbc option" >&5 -echo "$as_me: error: no argument expected for --with-unixodbc option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - with_unixodbc=no - -fi; - - - - -# Check whether --with-iodbc or --without-iodbc was given. -if test "${with_iodbc+set}" = set; then - withval="$with_iodbc" - - case $withval in - yes) - : - ;; - no) - : - ;; - *) - { { echo "$as_me:$LINENO: error: no argument expected for --with-iodbc option" >&5 -echo "$as_me: error: no argument expected for --with-iodbc option" >&2;} - { (exit 1); exit 1; }; } - ;; - esac - -else - with_iodbc=no - -fi; - -if test "$with_unixodbc" = yes && test "$with_iodbc" = yes; then - { { echo "$as_me:$LINENO: error: ODBC driver cannot be built for both unixODBC and iODBC" >&5 -echo "$as_me: error: ODBC driver cannot be built for both unixODBC and iODBC" >&2;} - { (exit 1); exit 1; }; } -fi -if test "$with_unixodbc" = yes || test "$with_iodbc" = yes; then - enable_odbc=yes -fi -case $enable_odbc:$with_unixodbc:$with_iodbc in - yes:no:no) echo "$as_me:$LINENO: result: yes (stand-alone)" >&5 -echo "${ECHO_T}yes (stand-alone)" >&6;; - yes:yes:no) echo "$as_me:$LINENO: result: yes (unixODBC)" >&5 -echo "${ECHO_T}yes (unixODBC)" >&6 - -cat >>confdefs.h <<\_ACEOF -#define WITH_UNIXODBC 1 -_ACEOF - - ;; - yes:no:yes) echo "$as_me:$LINENO: result: yes (iODBC)" >&5 -echo "${ECHO_T}yes (iODBC)" >&6 - -cat >>confdefs.h <<\_ACEOF -#define WITH_IODBC 1 -_ACEOF - - ;; - no:*) echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6;; -esac - - - - - -# Allow for overriding the default location of the odbcinst.ini -# file which is normally ${sysconfdir} (i.e., ${prefix}/etc). - - - -# Check whether --with-odbcinst or --without-odbcinst was given. -if test "${with_odbcinst+set}" = set; then - withval="$with_odbcinst" - - case $withval in - yes) - { { echo "$as_me:$LINENO: error: argument required for --with-odbcinst option" >&5 -echo "$as_me: error: argument required for --with-odbcinst option" >&2;} - { (exit 1); exit 1; }; } - ;; - no) - { { echo "$as_me:$LINENO: error: argument required for --with-odbcinst option" >&5 -echo "$as_me: error: argument required for --with-odbcinst option" >&2;} - { (exit 1); exit 1; }; } - ;; - *) - odbcinst_ini_dir=$withval - ;; - esac - -else - odbcinst_ini_dir="\${sysconfdir}" -fi; - - - - - -# Assume system is ELF if it predefines __ELF__ as 1, -# otherwise believe host_os based default. -case $host_os in - freebsd1*|freebsd2*) elf=no;; - freebsd3*|freebsd4*) elf=yes;; -esac - - -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#if __ELF__ - yes -#endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "yes" >/dev/null 2>&1; then - ELF_SYS=true -else - if test "X$elf" = "Xyes" ; then - ELF_SYS=true -else - ELF_SYS= -fi -fi -rm -f conftest* - - - - - -# -# Optionally build C++ code (i.e., libpq++) -# -echo "$as_me:$LINENO: checking whether to build C++ modules" >&5 -echo $ECHO_N "checking whether to build C++ modules... $ECHO_C" >&6 - - - -# Check whether --with-CXX or --without-CXX was given. -if test "${with_CXX+set}" = set; then - withval="$with_CXX" - - case $withval in - yes) - : - ;; - no) - : - ;; - *) - with_CXX=yes -CXX=$withval - ;; - esac - -else - with_CXX=no -fi; - - -if test "$with_CXX" = yes; then - - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - - # If the user has specified CXXFLAGS in the environment, leave it - # alone, else use a default. - - ac_ext=cc -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -if test -n "$ac_tool_prefix"; then - for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_CXX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$CXX"; then - ac_cv_prog_CXX="$CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -CXX=$ac_cv_prog_CXX -if test -n "$CXX"; then - echo "$as_me:$LINENO: result: $CXX" >&5 -echo "${ECHO_T}$CXX" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$CXX" && break - done -fi -if test -z "$CXX"; then - ac_ct_CXX=$CXX - for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_CXX"; then - ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CXX="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -ac_ct_CXX=$ac_cv_prog_ac_ct_CXX -if test -n "$ac_ct_CXX"; then - echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 -echo "${ECHO_T}$ac_ct_CXX" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$ac_ct_CXX" && break -done -test -n "$ac_ct_CXX" || ac_ct_CXX="g++" - - CXX=$ac_ct_CXX -fi - - -# Provide some information about the compiler. -echo "$as_me:$LINENO:" \ - "checking for C++ compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` -{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 - (eval $ac_compiler --version &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 - (eval $ac_compiler -v &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } -{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 - (eval $ac_compiler -V &5) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } - -echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6 -if test "${ac_cv_cxx_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_compiler_gnu=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_compiler_gnu=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -ac_cv_cxx_compiler_gnu=$ac_compiler_gnu - -fi -echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6 -GXX=`test $ac_compiler_gnu = yes && echo yes` -ac_test_CXXFLAGS=${CXXFLAGS+set} -ac_save_CXXFLAGS=$CXXFLAGS -CXXFLAGS="-g" -echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 -echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6 -if test "${ac_cv_prog_cxx_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_prog_cxx_g=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_prog_cxx_g=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6 -if test "$ac_test_CXXFLAGS" = set; then - CXXFLAGS=$ac_save_CXXFLAGS -elif test $ac_cv_prog_cxx_g = yes; then - if test "$GXX" = yes; then - CXXFLAGS="-g -O2" - else - CXXFLAGS="-g" - fi -else - if test "$GXX" = yes; then - CXXFLAGS="-O2" - else - CXXFLAGS= - fi -fi -for ac_declaration in \ - ''\ - '#include ' \ - 'extern "C" void std::exit (int) throw (); using std::exit;' \ - 'extern "C" void std::exit (int); using std::exit;' \ - 'extern "C" void exit (int) throw ();' \ - 'extern "C" void exit (int);' \ - 'void exit (int);' -do - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -$ac_declaration -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -continue -fi -rm -f conftest.$ac_objext conftest.$ac_ext - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_declaration -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -exit (42); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest.$ac_ext -done -rm -f conftest* -if test -n "$ac_declaration"; then - echo '#ifdef __cplusplus' >>confdefs.h - echo $ac_declaration >>confdefs.h - echo '#endif' >>confdefs.h -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - if test "$ac_env_CXXFLAGS" != set; then - if test "$GXX" = yes; then - CXXFLAGS=-O2 - else - case $template in - osf) CXXFLAGS='-O4 -Olimit 2000' ;; - unixware) CXXFLAGS='-O' ;; - *) CXXFLAGS= ;; - esac - fi - fi - if test "$enable_debug" = yes && test "$ac_cv_prog_cxx_g" = yes; then - CXXFLAGS="$CXXFLAGS -g" - fi - { echo "$as_me:$LINENO: using CXXFLAGS=$CXXFLAGS" >&5 -echo "$as_me: using CXXFLAGS=$CXXFLAGS" >&6;} - - ac_ext=cc -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 -echo $ECHO_N "checking how to run the C++ preprocessor... $ECHO_C" >&6 -if test -z "$CXXCPP"; then - if test "${ac_cv_prog_CXXCPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Double quotes because CXXCPP needs to be expanded - for CXXCPP in "$CXX -E" "/lib/cpp" - do - ac_preproc_ok=false -for ac_cxx_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_cxx_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_cxx_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - break -fi - - done - ac_cv_prog_CXXCPP=$CXXCPP - -fi - CXXCPP=$ac_cv_prog_CXXCPP -else - ac_cv_prog_CXXCPP=$CXXCPP -fi -echo "$as_me:$LINENO: result: $CXXCPP" >&5 -echo "${ECHO_T}$CXXCPP" >&6 -ac_preproc_ok=false -for ac_cxx_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include - Syntax error -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_cxx_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - : -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.$ac_ext - - # OK, works on sane cases. Now check whether non-existent headers - # can be detected and how. - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_cxx_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - # Broken: success on invalid input. -continue -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.err conftest.$ac_ext -if $ac_preproc_ok; then - : -else - { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check" >&5 -echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check" >&2;} - { (exit 1); exit 1; }; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - - - -CPPFLAGS="$CPPFLAGS $INCLUDES" -LDFLAGS="$LDFLAGS $LIBDIRS" - -{ echo "$as_me:$LINENO: using CPPFLAGS=$CPPFLAGS" >&5 -echo "$as_me: using CPPFLAGS=$CPPFLAGS" >&6;} -{ echo "$as_me:$LINENO: using LDFLAGS=$LDFLAGS" >&5 -echo "$as_me: using LDFLAGS=$LDFLAGS" >&6;} - - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_AWK+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AWK="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - echo "$as_me:$LINENO: result: $AWK" >&5 -echo "${ECHO_T}$AWK" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$AWK" && break -done - -echo "$as_me:$LINENO: checking for flex" >&5 -echo $ECHO_N "checking for flex... $ECHO_C" >&6 -if test "${pgac_cv_path_flex+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # 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 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 - -fi -echo "$as_me:$LINENO: result: $pgac_cv_path_flex" >&5 -echo "${ECHO_T}$pgac_cv_path_flex" >&6 -if test x"$pgac_cv_path_flex" = x"no"; then - if test -n "$pgac_broken_flex"; then - { echo "$as_me:$LINENO: WARNING: -*** The Flex version 2.5.3 you have at $pgac_broken_flex contains a bug. You -*** should get version 2.5.4 or later." >&5 -echo "$as_me: WARNING: -*** The Flex version 2.5.3 you have at $pgac_broken_flex contains a bug. You -*** should get version 2.5.4 or later." >&2;} - fi - - { echo "$as_me:$LINENO: WARNING: -*** 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.)" >&5 -echo "$as_me: WARNING: -*** 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.)" >&2;} -fi - -if test x"$pgac_cv_path_flex" = x"no"; then - FLEX= -else - FLEX=$pgac_cv_path_flex -fi - - - - -echo "$as_me:$LINENO: checking whether ln -s works" >&5 -echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6 -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else - echo "$as_me:$LINENO: result: no, using $LN_S" >&5 -echo "${ECHO_T}no, using $LN_S" >&6 -fi - - -# Check whether --with-gnu-ld or --without-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then - withval="$with_gnu_ld" - test "$withval" = no || with_gnu_ld=yes -else - with_gnu_ld=no -fi; -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - echo "$as_me:$LINENO: checking for ld used by GCC" >&5 -echo $ECHO_N "checking for ld used by GCC... $ECHO_C" >&6 - 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. - [\\/]* | [A-Za-z]:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # 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 - echo "$as_me:$LINENO: checking for GNU ld" >&5 -echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6 -else - echo "$as_me:$LINENO: checking for non-GNU ld" >&5 -echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6 -fi -if test "${ac_cv_path_LD+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - 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 -fi - -LD="$ac_cv_path_LD" -if test -n "$LD"; then - echo "$as_me:$LINENO: result: $LD" >&5 -echo "${ECHO_T}$LD" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi -test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5 -echo "$as_me: error: no acceptable ld found in \$PATH" >&2;} - { (exit 1); exit 1; }; } -echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5 -echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6 -if test "${ac_cv_prog_gnu_ld+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # I'd rather use --version here, but apparently some GNU ld's only accept -v. -if $LD -v 2>&1 &5; then - ac_cv_prog_gnu_ld=yes -else - ac_cv_prog_gnu_ld=no -fi -fi -echo "$as_me:$LINENO: result: $ac_cv_prog_gnu_ld" >&5 -echo "${ECHO_T}$ac_cv_prog_gnu_ld" >&6 -with_gnu_ld=$ac_cv_prog_gnu_ld - - - - -case $host_os in sysv5*) - echo "$as_me:$LINENO: checking whether ld -R works" >&5 -echo $ECHO_N "checking whether ld -R works... $ECHO_C" >&6 -if test "${pgac_cv_prog_ld_R+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - - pgac_save_LDFLAGS=$LDFLAGS; LDFLAGS="$LDFLAGS -Wl,-R/usr/lib" - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - pgac_cv_prog_ld_R=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -pgac_cv_prog_ld_R=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$pgac_save_LDFLAGS - -fi -echo "$as_me:$LINENO: result: $pgac_cv_prog_ld_R" >&5 -echo "${ECHO_T}$pgac_cv_prog_ld_R" >&6 - ld_R_works=$pgac_cv_prog_ld_R - -esac -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - echo "$as_me:$LINENO: result: $RANLIB" >&5 -echo "${ECHO_T}$RANLIB" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":" -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5 -echo "${ECHO_T}$ac_ct_RANLIB" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - RANLIB=$ac_ct_RANLIB -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -for ac_prog in lorder -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_LORDER+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$LORDER"; then - ac_cv_prog_LORDER="$LORDER" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_LORDER="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -LORDER=$ac_cv_prog_LORDER -if test -n "$LORDER"; then - echo "$as_me:$LINENO: result: $LORDER" >&5 -echo "${ECHO_T}$LORDER" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$LORDER" && break -done - -# Extract the first word of "tar", so it can be a program name with args. -set dummy tar; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_path_TAR+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $TAR in - [\\/]* | ?:[\\/]*) - ac_cv_path_TAR="$TAR" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_TAR="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - ;; -esac -fi -TAR=$ac_cv_path_TAR - -if test -n "$TAR"; then - echo "$as_me:$LINENO: result: $TAR" >&5 -echo "${ECHO_T}$TAR" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_STRIP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - echo "$as_me:$LINENO: result: $STRIP" >&5 -echo "${ECHO_T}$STRIP" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 -echo "${ECHO_T}$ac_ct_STRIP" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - STRIP=$ac_ct_STRIP -else - STRIP="$ac_cv_prog_STRIP" -fi - - - echo "$as_me:$LINENO: checking whether it is possible to strip libraries" >&5 -echo $ECHO_N "checking whether it is possible to strip libraries... $ECHO_C" >&6 - 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" - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - else - STRIP_STATIC_LIB=: - STRIP_SHARED_LIB=: - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - fi - - - - -for ac_prog in 'bison -y' -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_YACC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$YACC"; then - ac_cv_prog_YACC="$YACC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_YACC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -YACC=$ac_cv_prog_YACC -if test -n "$YACC"; then - echo "$as_me:$LINENO: result: $YACC" >&5 -echo "${ECHO_T}$YACC" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$YACC" && break -done - -if test -z "$YACC"; then - { echo "$as_me:$LINENO: WARNING: -*** Without Bison you will not be able to build PostgreSQL from CVS or -*** change any of the parser definition files. You can obtain Bison 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 Bison -*** output is pre-generated.) To use a different yacc program (possible, -*** but not recommended), set the environment variable YACC before running -*** 'configure'." >&5 -echo "$as_me: WARNING: -*** Without Bison you will not be able to build PostgreSQL from CVS or -*** change any of the parser definition files. You can obtain Bison 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 Bison -*** output is pre-generated.) To use a different yacc program (possible, -*** but not recommended), set the environment variable YACC before running -*** 'configure'." >&2;} -fi - - -if test "$with_tk" = yes; then - # Extract the first word of "wish", so it can be a program name with args. -set dummy wish; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_path_WISH+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $WISH in - [\\/]* | ?:[\\/]*) - ac_cv_path_WISH="$WISH" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_WISH="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - ;; -esac -fi -WISH=$ac_cv_path_WISH - -if test -n "$WISH"; then - echo "$as_me:$LINENO: result: $WISH" >&5 -echo "${ECHO_T}$WISH" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -z "$WISH" && { { echo "$as_me:$LINENO: error: 'wish' is required for Tk support" >&5 -echo "$as_me: error: 'wish' is required for Tk support" >&2;} - { (exit 1); exit 1; }; } -fi - -# Extract the first word of "perl", so it can be a program name with args. -set dummy perl; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_path_PERL+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $PERL in - [\\/]* | ?:[\\/]*) - ac_cv_path_PERL="$PERL" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - ;; -esac -fi -PERL=$ac_cv_path_PERL - -if test -n "$PERL"; then - echo "$as_me:$LINENO: result: $PERL" >&5 -echo "${ECHO_T}$PERL" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -if test "$with_perl" = yes; then - -echo "$as_me:$LINENO: checking for Perl installsitearch" >&5 -echo $ECHO_N "checking for Perl installsitearch... $ECHO_C" >&6 -perl_installsitearch=`$PERL -MConfig -e 'print $Config{installsitearch}'` -echo "$as_me:$LINENO: result: $perl_installsitearch" >&5 -echo "${ECHO_T}$perl_installsitearch" >&6 -echo "$as_me:$LINENO: checking for Perl installman3dir" >&5 -echo $ECHO_N "checking for Perl installman3dir... $ECHO_C" >&6 -perl_installman3dir=`$PERL -MConfig -e 'print $Config{installman3dir}'` -echo "$as_me:$LINENO: result: $perl_installman3dir" >&5 -echo "${ECHO_T}$perl_installman3dir" >&6 -echo "$as_me:$LINENO: checking for Perl archlibexp" >&5 -echo $ECHO_N "checking for Perl archlibexp... $ECHO_C" >&6 -perl_archlibexp=`$PERL -MConfig -e 'print $Config{archlibexp}'` -echo "$as_me:$LINENO: result: $perl_archlibexp" >&5 -echo "${ECHO_T}$perl_archlibexp" >&6 -echo "$as_me:$LINENO: checking for Perl privlibexp" >&5 -echo $ECHO_N "checking for Perl privlibexp... $ECHO_C" >&6 -perl_privlibexp=`$PERL -MConfig -e 'print $Config{privlibexp}'` -echo "$as_me:$LINENO: result: $perl_privlibexp" >&5 -echo "${ECHO_T}$perl_privlibexp" >&6 -echo "$as_me:$LINENO: checking for Perl useshrplib" >&5 -echo $ECHO_N "checking for Perl useshrplib... $ECHO_C" >&6 -perl_useshrplib=`$PERL -MConfig -e 'print $Config{useshrplib}'` -echo "$as_me:$LINENO: result: $perl_useshrplib" >&5 -echo "${ECHO_T}$perl_useshrplib" >&6 -echo "$as_me:$LINENO: checking for Perl man3ext" >&5 -echo $ECHO_N "checking for Perl man3ext... $ECHO_C" >&6 -perl_man3ext=`$PERL -MConfig -e 'print $Config{man3ext}'` -echo "$as_me:$LINENO: result: $perl_man3ext" >&5 -echo "${ECHO_T}$perl_man3ext" >&6 - -echo "$as_me:$LINENO: checking for flags to link embedded Perl" >&5 -echo $ECHO_N "checking for flags to link embedded Perl... $ECHO_C" >&6 -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%%"` -echo "$as_me:$LINENO: result: $perl_embed_ldflags" >&5 -echo "${ECHO_T}$perl_embed_ldflags" >&6 -fi - -if test "$with_python" = yes; then - # Extract the first word of "python", so it can be a program name with args. -set dummy python; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_path_PYTHON+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $PYTHON in - [\\/]* | ?:[\\/]*) - ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - ;; -esac -fi -PYTHON=$ac_cv_path_PYTHON - -if test -n "$PYTHON"; then - echo "$as_me:$LINENO: result: $PYTHON" >&5 -echo "${ECHO_T}$PYTHON" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - -if test x"$PYTHON" = x""; then - { { echo "$as_me:$LINENO: error: Python not found" >&5 -echo "$as_me: error: Python not found" >&2;} - { (exit 1); exit 1; }; } -fi - - -echo "$as_me:$LINENO: checking Python installation directories" >&5 -echo $ECHO_N "checking Python installation directories... $ECHO_C" >&6 -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 - -# This should be enough of a message. -if test "$python_prefix" != "$python_execprefix"; then - echo "$as_me:$LINENO: result: $python_prefix/lib/python${python_version} and $python_execprefix/lib/python${python_version}" >&5 -echo "${ECHO_T}$python_prefix/lib/python${python_version} and $python_execprefix/lib/python${python_version}" >&6 -else - echo "$as_me:$LINENO: result: $python_prefix/lib/python${python_version}" >&5 -echo "${ECHO_T}$python_prefix/lib/python${python_version}" >&6 -fi - - - - - -echo "$as_me:$LINENO: checking how to link an embedded Python application" >&5 -echo $ECHO_N "checking how to link an embedded Python application... $ECHO_C" >&6 - -_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"` - -echo "$as_me:$LINENO: result: ${python_libspec}" >&5 -echo "${ECHO_T}${python_libspec}" >&6 - - -fi - - -## -## Libraries -## - -if test "$PORTNAME" != "aix" -a "$PORTNAME" != "alpha" -then - -echo "$as_me:$LINENO: checking for main in -lbsd" >&5 -echo $ECHO_N "checking for main in -lbsd... $ECHO_C" >&6 -if test "${ac_cv_lib_bsd_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lbsd $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_bsd_main=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_bsd_main=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_bsd_main" >&5 -echo "${ECHO_T}$ac_cv_lib_bsd_main" >&6 -if test $ac_cv_lib_bsd_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBBSD 1 -_ACEOF - - LIBS="-lbsd $LIBS" - -fi - -fi - -echo "$as_me:$LINENO: checking for setproctitle in -lutil" >&5 -echo $ECHO_N "checking for setproctitle in -lutil... $ECHO_C" >&6 -if test "${ac_cv_lib_util_setproctitle+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lutil $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char setproctitle (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -setproctitle (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_util_setproctitle=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_util_setproctitle=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_util_setproctitle" >&5 -echo "${ECHO_T}$ac_cv_lib_util_setproctitle" >&6 -if test $ac_cv_lib_util_setproctitle = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBUTIL 1 -_ACEOF - - LIBS="-lutil $LIBS" - -fi - - -echo "$as_me:$LINENO: checking for main in -lm" >&5 -echo $ECHO_N "checking for main in -lm... $ECHO_C" >&6 -if test "${ac_cv_lib_m_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lm $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_m_main=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_m_main=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_m_main" >&5 -echo "${ECHO_T}$ac_cv_lib_m_main" >&6 -if test $ac_cv_lib_m_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBM 1 -_ACEOF - - LIBS="-lm $LIBS" - -fi - - -echo "$as_me:$LINENO: checking for main in -ldl" >&5 -echo $ECHO_N "checking for main in -ldl... $ECHO_C" >&6 -if test "${ac_cv_lib_dl_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dl_main=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_dl_main=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dl_main" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_main" >&6 -if test $ac_cv_lib_dl_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBDL 1 -_ACEOF - - LIBS="-ldl $LIBS" - -fi - - -echo "$as_me:$LINENO: checking for main in -lnsl" >&5 -echo $ECHO_N "checking for main in -lnsl... $ECHO_C" >&6 -if test "${ac_cv_lib_nsl_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lnsl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_nsl_main=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_nsl_main=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_main" >&5 -echo "${ECHO_T}$ac_cv_lib_nsl_main" >&6 -if test $ac_cv_lib_nsl_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBNSL 1 -_ACEOF - - LIBS="-lnsl $LIBS" - -fi - - -echo "$as_me:$LINENO: checking for main in -lsocket" >&5 -echo $ECHO_N "checking for main in -lsocket... $ECHO_C" >&6 -if test "${ac_cv_lib_socket_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsocket $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_socket_main=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_socket_main=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_socket_main" >&5 -echo "${ECHO_T}$ac_cv_lib_socket_main" >&6 -if test $ac_cv_lib_socket_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSOCKET 1 -_ACEOF - - LIBS="-lsocket $LIBS" - -fi - - -echo "$as_me:$LINENO: checking for main in -lipc" >&5 -echo $ECHO_N "checking for main in -lipc... $ECHO_C" >&6 -if test "${ac_cv_lib_ipc_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lipc $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_ipc_main=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_ipc_main=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_ipc_main" >&5 -echo "${ECHO_T}$ac_cv_lib_ipc_main" >&6 -if test $ac_cv_lib_ipc_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBIPC 1 -_ACEOF - - LIBS="-lipc $LIBS" - -fi - - -echo "$as_me:$LINENO: checking for main in -lIPC" >&5 -echo $ECHO_N "checking for main in -lIPC... $ECHO_C" >&6 -if test "${ac_cv_lib_IPC_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lIPC $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_IPC_main=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_IPC_main=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_IPC_main" >&5 -echo "${ECHO_T}$ac_cv_lib_IPC_main" >&6 -if test $ac_cv_lib_IPC_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBIPC 1 -_ACEOF - - LIBS="-lIPC $LIBS" - -fi - - -echo "$as_me:$LINENO: checking for main in -llc" >&5 -echo $ECHO_N "checking for main in -llc... $ECHO_C" >&6 -if test "${ac_cv_lib_lc_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-llc $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_lc_main=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_lc_main=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_lc_main" >&5 -echo "${ECHO_T}$ac_cv_lib_lc_main" >&6 -if test $ac_cv_lib_lc_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLC 1 -_ACEOF - - LIBS="-llc $LIBS" - -fi - - -echo "$as_me:$LINENO: checking for main in -ldld" >&5 -echo $ECHO_N "checking for main in -ldld... $ECHO_C" >&6 -if test "${ac_cv_lib_dld_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_dld_main=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_dld_main=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_dld_main" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_main" >&6 -if test $ac_cv_lib_dld_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBDLD 1 -_ACEOF - - LIBS="-ldld $LIBS" - -fi - - -echo "$as_me:$LINENO: checking for main in -lld" >&5 -echo $ECHO_N "checking for main in -lld... $ECHO_C" >&6 -if test "${ac_cv_lib_ld_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_ld_main=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_ld_main=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_ld_main" >&5 -echo "${ECHO_T}$ac_cv_lib_ld_main" >&6 -if test $ac_cv_lib_ld_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBLD 1 -_ACEOF - - LIBS="-lld $LIBS" - -fi - - -echo "$as_me:$LINENO: checking for main in -lcompat" >&5 -echo $ECHO_N "checking for main in -lcompat... $ECHO_C" >&6 -if test "${ac_cv_lib_compat_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lcompat $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_compat_main=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_compat_main=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_compat_main" >&5 -echo "${ECHO_T}$ac_cv_lib_compat_main" >&6 -if test $ac_cv_lib_compat_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBCOMPAT 1 -_ACEOF - - LIBS="-lcompat $LIBS" - -fi - - -echo "$as_me:$LINENO: checking for main in -lBSD" >&5 -echo $ECHO_N "checking for main in -lBSD... $ECHO_C" >&6 -if test "${ac_cv_lib_BSD_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lBSD $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_BSD_main=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_BSD_main=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_BSD_main" >&5 -echo "${ECHO_T}$ac_cv_lib_BSD_main" >&6 -if test $ac_cv_lib_BSD_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBBSD 1 -_ACEOF - - LIBS="-lBSD $LIBS" - -fi - - -echo "$as_me:$LINENO: checking for main in -lgen" >&5 -echo $ECHO_N "checking for main in -lgen... $ECHO_C" >&6 -if test "${ac_cv_lib_gen_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lgen $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_gen_main=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_gen_main=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_gen_main" >&5 -echo "${ECHO_T}$ac_cv_lib_gen_main" >&6 -if test $ac_cv_lib_gen_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBGEN 1 -_ACEOF - - LIBS="-lgen $LIBS" - -fi - - -echo "$as_me:$LINENO: checking for main in -lPW" >&5 -echo $ECHO_N "checking for main in -lPW... $ECHO_C" >&6 -if test "${ac_cv_lib_PW_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lPW $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_PW_main=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_PW_main=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_PW_main" >&5 -echo "${ECHO_T}$ac_cv_lib_PW_main" >&6 -if test $ac_cv_lib_PW_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBPW 1 -_ACEOF - - LIBS="-lPW $LIBS" - -fi - - -echo "$as_me:$LINENO: checking for main in -lresolv" >&5 -echo $ECHO_N "checking for main in -lresolv... $ECHO_C" >&6 -if test "${ac_cv_lib_resolv_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lresolv $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_resolv_main=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_resolv_main=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_main" >&5 -echo "${ECHO_T}$ac_cv_lib_resolv_main" >&6 -if test $ac_cv_lib_resolv_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBRESOLV 1 -_ACEOF - - LIBS="-lresolv $LIBS" - -fi - -# QNX: - -echo "$as_me:$LINENO: checking for main in -lunix" >&5 -echo $ECHO_N "checking for main in -lunix... $ECHO_C" >&6 -if test "${ac_cv_lib_unix_main+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lunix $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -main (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_unix_main=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_unix_main=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_unix_main" >&5 -echo "${ECHO_T}$ac_cv_lib_unix_main" >&6 -if test $ac_cv_lib_unix_main = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBUNIX 1 -_ACEOF - - LIBS="-lunix $LIBS" - -fi - -echo "$as_me:$LINENO: checking for library containing crypt" >&5 -echo $ECHO_N "checking for library containing crypt... $ECHO_C" >&6 -if test "${ac_cv_search_crypt+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -ac_cv_search_crypt=no -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char crypt (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -crypt (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_crypt="none required" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -if test "$ac_cv_search_crypt" = no; then - for ac_lib in crypt; do - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char crypt (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -crypt (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_crypt="-l$ac_lib" -break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - done -fi -LIBS=$ac_func_search_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_search_crypt" >&5 -echo "${ECHO_T}$ac_cv_search_crypt" >&6 -if test "$ac_cv_search_crypt" != no; then - test "$ac_cv_search_crypt" = "none required" || LIBS="$ac_cv_search_crypt $LIBS" - -fi - -# BeOS: - -echo "$as_me:$LINENO: checking for __inet_ntoa in -lbind" >&5 -echo $ECHO_N "checking for __inet_ntoa in -lbind... $ECHO_C" >&6 -if test "${ac_cv_lib_bind___inet_ntoa+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lbind $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char __inet_ntoa (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -__inet_ntoa (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_bind___inet_ntoa=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_bind___inet_ntoa=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_bind___inet_ntoa" >&5 -echo "${ECHO_T}$ac_cv_lib_bind___inet_ntoa" >&6 -if test $ac_cv_lib_bind___inet_ntoa = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBBIND 1 -_ACEOF - - LIBS="-lbind $LIBS" - -fi - -# Solaris: -echo "$as_me:$LINENO: checking for library containing fdatasync" >&5 -echo $ECHO_N "checking for library containing fdatasync... $ECHO_C" >&6 -if test "${ac_cv_search_fdatasync+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -ac_cv_search_fdatasync=no -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char fdatasync (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -fdatasync (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_fdatasync="none required" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -if test "$ac_cv_search_fdatasync" = no; then - for ac_lib in rt posix4; do - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char fdatasync (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -fdatasync (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_fdatasync="-l$ac_lib" -break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - done -fi -LIBS=$ac_func_search_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_search_fdatasync" >&5 -echo "${ECHO_T}$ac_cv_search_fdatasync" >&6 -if test "$ac_cv_search_fdatasync" != no; then - test "$ac_cv_search_fdatasync" = "none required" || LIBS="$ac_cv_search_fdatasync $LIBS" - -fi - - -if test "$with_readline" = yes; then - -echo "$as_me:$LINENO: checking for readline" >&5 -echo $ECHO_N "checking for readline... $ECHO_C" >&6 - -if test "${pgac_cv_check_readline+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - 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" - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char readline (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -readline (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - - # 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 - -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - LIBS=$pgac_save_LIBS - done -done -LIBS=$pgac_save_LIBS - -fi - -if test "$pgac_cv_check_readline" != no ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LIBREADLINE 1 -_ACEOF - - LIBS="$pgac_cv_check_readline $LIBS" - echo "$as_me:$LINENO: result: yes ($pgac_cv_check_readline)" >&5 -echo "${ECHO_T}yes ($pgac_cv_check_readline)" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - if test x"$pgac_cv_check_readline" = x"no"; then - { { echo "$as_me:$LINENO: error: readline library not found -Use --without-readline to disable readline support." >&5 -echo "$as_me: error: readline library not found -Use --without-readline to disable readline support." >&2;} - { (exit 1); exit 1; }; } - fi -fi - -if test "$with_zlib" = yes; then - -echo "$as_me:$LINENO: checking for inflate in -lz" >&5 -echo $ECHO_N "checking for inflate in -lz... $ECHO_C" >&6 -if test "${ac_cv_lib_z_inflate+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lz $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char inflate (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -inflate (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_z_inflate=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_z_inflate=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_z_inflate" >&5 -echo "${ECHO_T}$ac_cv_lib_z_inflate" >&6 -if test $ac_cv_lib_z_inflate = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBZ 1 -_ACEOF - - LIBS="-lz $LIBS" - -else - { { echo "$as_me:$LINENO: error: zlib library not found -Use --without-zlib to disable zlib support." >&5 -echo "$as_me: error: zlib library not found -Use --without-zlib to disable zlib support." >&2;} - { (exit 1); exit 1; }; } -fi - -fi - -if test "$with_krb4" = yes ; then - -echo "$as_me:$LINENO: checking for des_encrypt in -ldes" >&5 -echo $ECHO_N "checking for des_encrypt in -ldes... $ECHO_C" >&6 -if test "${ac_cv_lib_des_des_encrypt+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldes $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char des_encrypt (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -des_encrypt (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_des_des_encrypt=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_des_des_encrypt=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_des_des_encrypt" >&5 -echo "${ECHO_T}$ac_cv_lib_des_des_encrypt" >&6 -if test $ac_cv_lib_des_des_encrypt = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBDES 1 -_ACEOF - - LIBS="-ldes $LIBS" - -else - { { echo "$as_me:$LINENO: error: library 'des' is required for Kerberos 4" >&5 -echo "$as_me: error: library 'des' is required for Kerberos 4" >&2;} - { (exit 1); exit 1; }; } -fi - - -echo "$as_me:$LINENO: checking for krb_sendauth in -lkrb" >&5 -echo $ECHO_N "checking for krb_sendauth in -lkrb... $ECHO_C" >&6 -if test "${ac_cv_lib_krb_krb_sendauth+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lkrb $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char krb_sendauth (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -krb_sendauth (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_krb_krb_sendauth=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_krb_krb_sendauth=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_krb_krb_sendauth" >&5 -echo "${ECHO_T}$ac_cv_lib_krb_krb_sendauth" >&6 -if test $ac_cv_lib_krb_krb_sendauth = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBKRB 1 -_ACEOF - - LIBS="-lkrb $LIBS" - -else - { { echo "$as_me:$LINENO: error: library 'krb' is required for Kerberos 4" >&5 -echo "$as_me: error: library 'krb' is required for Kerberos 4" >&2;} - { (exit 1); exit 1; }; } -fi - -fi - -if test "$with_krb5" = yes ; then - echo "$as_me:$LINENO: checking for library containing com_err" >&5 -echo $ECHO_N "checking for library containing com_err... $ECHO_C" >&6 -if test "${ac_cv_search_com_err+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -ac_cv_search_com_err=no -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char com_err (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -com_err (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_com_err="none required" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -if test "$ac_cv_search_com_err" = no; then - for ac_lib in krb5 'krb5 -ldes -lasn1 -lroken' com_err; do - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char com_err (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -com_err (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_com_err="-l$ac_lib" -break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - done -fi -LIBS=$ac_func_search_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_search_com_err" >&5 -echo "${ECHO_T}$ac_cv_search_com_err" >&6 -if test "$ac_cv_search_com_err" != no; then - test "$ac_cv_search_com_err" = "none required" || LIBS="$ac_cv_search_com_err $LIBS" - -else - { { echo "$as_me:$LINENO: error: could not find function 'com_err' required for Kerberos 5" >&5 -echo "$as_me: error: could not find function 'com_err' required for Kerberos 5" >&2;} - { (exit 1); exit 1; }; } -fi - - echo "$as_me:$LINENO: checking for library containing krb5_encrypt" >&5 -echo $ECHO_N "checking for library containing krb5_encrypt... $ECHO_C" >&6 -if test "${ac_cv_search_krb5_encrypt+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -ac_cv_search_krb5_encrypt=no -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char krb5_encrypt (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -krb5_encrypt (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_krb5_encrypt="none required" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -if test "$ac_cv_search_krb5_encrypt" = no; then - for ac_lib in krb5 'krb5 -ldes -lasn1 -lroken' crypto k5crypto; do - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char krb5_encrypt (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -krb5_encrypt (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_krb5_encrypt="-l$ac_lib" -break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - done -fi -LIBS=$ac_func_search_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_search_krb5_encrypt" >&5 -echo "${ECHO_T}$ac_cv_search_krb5_encrypt" >&6 -if test "$ac_cv_search_krb5_encrypt" != no; then - test "$ac_cv_search_krb5_encrypt" = "none required" || LIBS="$ac_cv_search_krb5_encrypt $LIBS" - -else - { { echo "$as_me:$LINENO: error: could not find function 'krb5_encrypt' required for Kerberos 5" >&5 -echo "$as_me: error: could not find function 'krb5_encrypt' required for Kerberos 5" >&2;} - { (exit 1); exit 1; }; } -fi - - echo "$as_me:$LINENO: checking for library containing krb5_sendauth" >&5 -echo $ECHO_N "checking for library containing krb5_sendauth... $ECHO_C" >&6 -if test "${ac_cv_search_krb5_sendauth+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -ac_cv_search_krb5_sendauth=no -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char krb5_sendauth (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -krb5_sendauth (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_krb5_sendauth="none required" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -if test "$ac_cv_search_krb5_sendauth" = no; then - for ac_lib in krb5 'krb5 -ldes -lasn1 -lroken'; do - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char krb5_sendauth (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -krb5_sendauth (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_krb5_sendauth="-l$ac_lib" -break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - done -fi -LIBS=$ac_func_search_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_search_krb5_sendauth" >&5 -echo "${ECHO_T}$ac_cv_search_krb5_sendauth" >&6 -if test "$ac_cv_search_krb5_sendauth" != no; then - test "$ac_cv_search_krb5_sendauth" = "none required" || LIBS="$ac_cv_search_krb5_sendauth $LIBS" - -else - { { echo "$as_me:$LINENO: error: could not find function 'krb5_sendauth' required for Kerberos 5" >&5 -echo "$as_me: error: could not find function 'krb5_sendauth' required for Kerberos 5" >&2;} - { (exit 1); exit 1; }; } -fi - -fi - -if test "$with_openssl" = yes ; then - -echo "$as_me:$LINENO: checking for CRYPTO_new_ex_data in -lcrypto" >&5 -echo $ECHO_N "checking for CRYPTO_new_ex_data in -lcrypto... $ECHO_C" >&6 -if test "${ac_cv_lib_crypto_CRYPTO_new_ex_data+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lcrypto $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char CRYPTO_new_ex_data (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -CRYPTO_new_ex_data (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_crypto_CRYPTO_new_ex_data=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_crypto_CRYPTO_new_ex_data=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_CRYPTO_new_ex_data" >&5 -echo "${ECHO_T}$ac_cv_lib_crypto_CRYPTO_new_ex_data" >&6 -if test $ac_cv_lib_crypto_CRYPTO_new_ex_data = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBCRYPTO 1 -_ACEOF - - LIBS="-lcrypto $LIBS" - -else - { { echo "$as_me:$LINENO: error: library 'crypto' is required for OpenSSL" >&5 -echo "$as_me: error: library 'crypto' is required for OpenSSL" >&2;} - { (exit 1); exit 1; }; } -fi - - -echo "$as_me:$LINENO: checking for SSL_library_init in -lssl" >&5 -echo $ECHO_N "checking for SSL_library_init in -lssl... $ECHO_C" >&6 -if test "${ac_cv_lib_ssl_SSL_library_init+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lssl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char SSL_library_init (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -SSL_library_init (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_ssl_SSL_library_init=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_ssl_SSL_library_init=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_SSL_library_init" >&5 -echo "${ECHO_T}$ac_cv_lib_ssl_SSL_library_init" >&6 -if test $ac_cv_lib_ssl_SSL_library_init = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSSL 1 -_ACEOF - - LIBS="-lssl $LIBS" - -else - { { echo "$as_me:$LINENO: error: library 'ssl' is required for OpenSSL" >&5 -echo "$as_me: error: library 'ssl' is required for OpenSSL" >&2;} - { (exit 1); exit 1; }; } -fi - -fi - -if test "$with_pam" = yes ; then - -echo "$as_me:$LINENO: checking for pam_start in -lpam" >&5 -echo $ECHO_N "checking for pam_start in -lpam... $ECHO_C" >&6 -if test "${ac_cv_lib_pam_pam_start+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpam $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char pam_start (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -pam_start (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_pam_pam_start=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_pam_pam_start=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_pam_pam_start" >&5 -echo "${ECHO_T}$ac_cv_lib_pam_pam_start" >&6 -if test $ac_cv_lib_pam_pam_start = yes; then - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBPAM 1 -_ACEOF - - LIBS="-lpam $LIBS" - -else - { { echo "$as_me:$LINENO: error: library 'pam' is required for PAM" >&5 -echo "$as_me: error: library 'pam' is required for PAM" >&2;} - { (exit 1); exit 1; }; } -fi - -fi - - -## -## Header files -## -echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 -if test "${ac_cv_header_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#include -#include -#include - -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_cv_header_stdc=yes -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_cv_header_stdc=no -fi -rm -f conftest.err conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "memchr" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "free" >/dev/null 2>&1; then - : -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then - : -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - exit(2); - exit (0); -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - : -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -( exit $ac_status ) -ac_cv_header_stdc=no -fi -rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -fi -echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -echo "${ECHO_T}$ac_cv_header_stdc" >&6 -if test $ac_cv_header_stdc = yes; then - -cat >>confdefs.h <<\_ACEOF -#define STDC_HEADERS 1 -_ACEOF - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. - - - - - - - - - -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default - -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_Header=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_Header=no" -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - - - - - - - - - - - - - - - - - - -for ac_header in crypt.h dld.h endian.h fp_class.h getopt.h ieeefp.h pwd.h sys/ipc.h sys/pstat.h sys/select.h sys/sem.h sys/socket.h sys/shm.h sys/un.h termios.h kernel/OS.h kernel/image.h SupportDefs.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; - no:yes ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -# At least on IRIX, cpp test for netinet/tcp.h will fail unless -# netinet/in.h is included first. - -for ac_header in netinet/in.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; - no:yes ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -for ac_header in netinet/tcp.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#ifdef HAVE_NETINET_IN_H -#include -#endif - - -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_Header=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_Header=no" -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -if test "$with_readline" = yes; then - -for ac_header in readline/readline.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; - no:yes ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -else - -for ac_header in readline.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; - no:yes ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -else - { { echo "$as_me:$LINENO: error: readline header not found -Use --without-readline to disable readline support." >&5 -echo "$as_me: error: readline header not found -Use --without-readline to disable readline support." >&2;} - { (exit 1); exit 1; }; } -fi - -done - -fi - -done - - -for ac_header in readline/history.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; - no:yes ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -else - -for ac_header in history.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include <$ac_header> -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; - no:yes ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; -esac -echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 -if eval "test \"\${$as_ac_Header+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=$ac_header_preproc" -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -else - { { echo "$as_me:$LINENO: error: history header not found -Use --without-readline to disable readline support." >&5 -echo "$as_me: error: history header not found -Use --without-readline to disable readline support." >&2;} - { (exit 1); exit 1; }; } -fi - -done - -fi - -done - -fi - -if test "$with_zlib" = yes; then - if test "${ac_cv_header_zlib_h+set}" = set; then - echo "$as_me:$LINENO: checking for zlib.h" >&5 -echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6 -if test "${ac_cv_header_zlib_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5 -echo "${ECHO_T}$ac_cv_header_zlib_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking zlib.h usability" >&5 -echo $ECHO_N "checking zlib.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking zlib.h presence" >&5 -echo $ECHO_N "checking zlib.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: zlib.h: proceeding with the preprocessor's result" >&2;};; - no:yes ) - { echo "$as_me:$LINENO: WARNING: zlib.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: zlib.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: zlib.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: zlib.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: zlib.h: proceeding with the preprocessor's result" >&2;};; -esac -echo "$as_me:$LINENO: checking for zlib.h" >&5 -echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6 -if test "${ac_cv_header_zlib_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_zlib_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5 -echo "${ECHO_T}$ac_cv_header_zlib_h" >&6 - -fi -if test $ac_cv_header_zlib_h = yes; then - : -else - { { echo "$as_me:$LINENO: error: zlib header not found -Use --without-zlib to disable zlib support." >&5 -echo "$as_me: error: zlib header not found -Use --without-zlib to disable zlib support." >&2;} - { (exit 1); exit 1; }; } -fi - - -fi - -if test "$with_krb4" = yes ; then - if test "${ac_cv_header_krb_h+set}" = set; then - echo "$as_me:$LINENO: checking for krb.h" >&5 -echo $ECHO_N "checking for krb.h... $ECHO_C" >&6 -if test "${ac_cv_header_krb_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_krb_h" >&5 -echo "${ECHO_T}$ac_cv_header_krb_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking krb.h usability" >&5 -echo $ECHO_N "checking krb.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking krb.h presence" >&5 -echo $ECHO_N "checking krb.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: krb.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: krb.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: krb.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: krb.h: proceeding with the preprocessor's result" >&2;};; - no:yes ) - { echo "$as_me:$LINENO: WARNING: krb.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: krb.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: krb.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: krb.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: krb.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: krb.h: proceeding with the preprocessor's result" >&2;};; -esac -echo "$as_me:$LINENO: checking for krb.h" >&5 -echo $ECHO_N "checking for krb.h... $ECHO_C" >&6 -if test "${ac_cv_header_krb_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_krb_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_krb_h" >&5 -echo "${ECHO_T}$ac_cv_header_krb_h" >&6 - -fi -if test $ac_cv_header_krb_h = yes; then - : -else - { { echo "$as_me:$LINENO: error: header file is required for Kerberos 4" >&5 -echo "$as_me: error: header file is required for Kerberos 4" >&2;} - { (exit 1); exit 1; }; } -fi - - -fi - -if test "$with_krb5" = yes ; then - if test "${ac_cv_header_krb5_h+set}" = set; then - echo "$as_me:$LINENO: checking for krb5.h" >&5 -echo $ECHO_N "checking for krb5.h... $ECHO_C" >&6 -if test "${ac_cv_header_krb5_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_krb5_h" >&5 -echo "${ECHO_T}$ac_cv_header_krb5_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking krb5.h usability" >&5 -echo $ECHO_N "checking krb5.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking krb5.h presence" >&5 -echo $ECHO_N "checking krb5.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: krb5.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: krb5.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: krb5.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: krb5.h: proceeding with the preprocessor's result" >&2;};; - no:yes ) - { echo "$as_me:$LINENO: WARNING: krb5.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: krb5.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: krb5.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: krb5.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: krb5.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: krb5.h: proceeding with the preprocessor's result" >&2;};; -esac -echo "$as_me:$LINENO: checking for krb5.h" >&5 -echo $ECHO_N "checking for krb5.h... $ECHO_C" >&6 -if test "${ac_cv_header_krb5_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_krb5_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_krb5_h" >&5 -echo "${ECHO_T}$ac_cv_header_krb5_h" >&6 - -fi -if test $ac_cv_header_krb5_h = yes; then - : -else - { { echo "$as_me:$LINENO: error: header file is required for Kerberos 5" >&5 -echo "$as_me: error: header file is required for Kerberos 5" >&2;} - { (exit 1); exit 1; }; } -fi - - - if test "${ac_cv_header_com_err_h+set}" = set; then - echo "$as_me:$LINENO: checking for com_err.h" >&5 -echo $ECHO_N "checking for com_err.h... $ECHO_C" >&6 -if test "${ac_cv_header_com_err_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_com_err_h" >&5 -echo "${ECHO_T}$ac_cv_header_com_err_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking com_err.h usability" >&5 -echo $ECHO_N "checking com_err.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking com_err.h presence" >&5 -echo $ECHO_N "checking com_err.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: com_err.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: com_err.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: com_err.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: com_err.h: proceeding with the preprocessor's result" >&2;};; - no:yes ) - { echo "$as_me:$LINENO: WARNING: com_err.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: com_err.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: com_err.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: com_err.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: com_err.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: com_err.h: proceeding with the preprocessor's result" >&2;};; -esac -echo "$as_me:$LINENO: checking for com_err.h" >&5 -echo $ECHO_N "checking for com_err.h... $ECHO_C" >&6 -if test "${ac_cv_header_com_err_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_com_err_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_com_err_h" >&5 -echo "${ECHO_T}$ac_cv_header_com_err_h" >&6 - -fi -if test $ac_cv_header_com_err_h = yes; then - : -else - { { echo "$as_me:$LINENO: error: header file is required for Kerberos 5" >&5 -echo "$as_me: error: header file is required for Kerberos 5" >&2;} - { (exit 1); exit 1; }; } -fi - - -fi - -if test "$with_openssl" = yes ; then - if test "${ac_cv_header_openssl_ssl_h+set}" = set; then - echo "$as_me:$LINENO: checking for openssl/ssl.h" >&5 -echo $ECHO_N "checking for openssl/ssl.h... $ECHO_C" >&6 -if test "${ac_cv_header_openssl_ssl_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_openssl_ssl_h" >&5 -echo "${ECHO_T}$ac_cv_header_openssl_ssl_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking openssl/ssl.h usability" >&5 -echo $ECHO_N "checking openssl/ssl.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking openssl/ssl.h presence" >&5 -echo $ECHO_N "checking openssl/ssl.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: openssl/ssl.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: openssl/ssl.h: proceeding with the preprocessor's result" >&2;};; - no:yes ) - { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: openssl/ssl.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: openssl/ssl.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: openssl/ssl.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: openssl/ssl.h: proceeding with the preprocessor's result" >&2;};; -esac -echo "$as_me:$LINENO: checking for openssl/ssl.h" >&5 -echo $ECHO_N "checking for openssl/ssl.h... $ECHO_C" >&6 -if test "${ac_cv_header_openssl_ssl_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_openssl_ssl_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_openssl_ssl_h" >&5 -echo "${ECHO_T}$ac_cv_header_openssl_ssl_h" >&6 - -fi -if test $ac_cv_header_openssl_ssl_h = yes; then - : -else - { { echo "$as_me:$LINENO: error: header file is required for OpenSSL" >&5 -echo "$as_me: error: header file is required for OpenSSL" >&2;} - { (exit 1); exit 1; }; } -fi - - - if test "${ac_cv_header_openssl_err_h+set}" = set; then - echo "$as_me:$LINENO: checking for openssl/err.h" >&5 -echo $ECHO_N "checking for openssl/err.h... $ECHO_C" >&6 -if test "${ac_cv_header_openssl_err_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_openssl_err_h" >&5 -echo "${ECHO_T}$ac_cv_header_openssl_err_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking openssl/err.h usability" >&5 -echo $ECHO_N "checking openssl/err.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking openssl/err.h presence" >&5 -echo $ECHO_N "checking openssl/err.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: openssl/err.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: openssl/err.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: openssl/err.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: openssl/err.h: proceeding with the preprocessor's result" >&2;};; - no:yes ) - { echo "$as_me:$LINENO: WARNING: openssl/err.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: openssl/err.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: openssl/err.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: openssl/err.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: openssl/err.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: openssl/err.h: proceeding with the preprocessor's result" >&2;};; -esac -echo "$as_me:$LINENO: checking for openssl/err.h" >&5 -echo $ECHO_N "checking for openssl/err.h... $ECHO_C" >&6 -if test "${ac_cv_header_openssl_err_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_openssl_err_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_openssl_err_h" >&5 -echo "${ECHO_T}$ac_cv_header_openssl_err_h" >&6 - -fi -if test $ac_cv_header_openssl_err_h = yes; then - : -else - { { echo "$as_me:$LINENO: error: header file is required for OpenSSL" >&5 -echo "$as_me: error: header file is required for OpenSSL" >&2;} - { (exit 1); exit 1; }; } -fi - - -fi - -if test "$with_pam" = yes ; then - if test "${ac_cv_header_security_pam_appl_h+set}" = set; then - echo "$as_me:$LINENO: checking for security/pam_appl.h" >&5 -echo $ECHO_N "checking for security/pam_appl.h... $ECHO_C" >&6 -if test "${ac_cv_header_security_pam_appl_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_security_pam_appl_h" >&5 -echo "${ECHO_T}$ac_cv_header_security_pam_appl_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking security/pam_appl.h usability" >&5 -echo $ECHO_N "checking security/pam_appl.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking security/pam_appl.h presence" >&5 -echo $ECHO_N "checking security/pam_appl.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: security/pam_appl.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: security/pam_appl.h: proceeding with the preprocessor's result" >&2;};; - no:yes ) - { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: security/pam_appl.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: security/pam_appl.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: security/pam_appl.h: proceeding with the preprocessor's result" >&2;};; -esac -echo "$as_me:$LINENO: checking for security/pam_appl.h" >&5 -echo $ECHO_N "checking for security/pam_appl.h... $ECHO_C" >&6 -if test "${ac_cv_header_security_pam_appl_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_security_pam_appl_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_security_pam_appl_h" >&5 -echo "${ECHO_T}$ac_cv_header_security_pam_appl_h" >&6 - -fi -if test $ac_cv_header_security_pam_appl_h = yes; then - : -else - { { echo "$as_me:$LINENO: error: header file is required for PAM" >&5 -echo "$as_me: error: header file is required for PAM" >&2;} - { (exit 1); exit 1; }; } -fi - - -fi - - -## -## Types, structures, compiler characteristics -## - -echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 -echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 -if test "${ac_cv_c_const+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* FIXME: Include the comments suggested by Paul. */ -#ifndef __cplusplus - /* Ultrix mips cc rejects this. */ - typedef int charset[2]; - const charset x; - /* SunOS 4.1.1 cc rejects this. */ - char const *const *ccp; - char **p; - /* NEC SVR4.0.2 mips cc rejects this. */ - struct point {int x, y;}; - static struct point const zero = {0,0}; - /* AIX XL C 1.02.0.0 rejects this. - It does not let you subtract one const X* pointer from another in - an arm of an if-expression whose if-part is not a constant - expression */ - const char *g = "string"; - ccp = &g + (g ? g-g : 0); - /* HPUX 7.0 cc rejects these. */ - ++ccp; - p = (char**) ccp; - ccp = (char const *const *) p; - { /* SCO 3.2v4 cc rejects this. */ - char *t; - char const *s = 0 ? (char *) 0 : (char const *) 0; - - *t++ = 0; - } - { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ - int x[] = {25, 17}; - const int *foo = &x[0]; - ++foo; - } - { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ - typedef const int *iptr; - iptr p = 0; - ++p; - } - { /* AIX XL C 1.02.0.0 rejects this saying - "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ - struct s { int j; const int *ap[3]; }; - struct s *b; b->j = 5; - } - { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ - const int foo = 10; - } -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_const=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_c_const=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 -echo "${ECHO_T}$ac_cv_c_const" >&6 -if test $ac_cv_c_const = no; then - -cat >>confdefs.h <<\_ACEOF -#define const -_ACEOF - -fi - -echo "$as_me:$LINENO: checking for inline" >&5 -echo $ECHO_N "checking for inline... $ECHO_C" >&6 -if test "${ac_cv_c_inline+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_c_inline=no -for ac_kw in inline __inline__ __inline; do - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#ifndef __cplusplus -static $ac_kw int static_foo () {return 0; } -$ac_kw int foo () {return 0; } -#endif - -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_inline=$ac_kw; break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest.$ac_ext -done - -fi -echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 -echo "${ECHO_T}$ac_cv_c_inline" >&6 -case $ac_cv_c_inline in - inline | yes) ;; - no) -cat >>confdefs.h <<\_ACEOF -#define inline -_ACEOF - ;; - *) cat >>confdefs.h <<_ACEOF -#define inline $ac_cv_c_inline -_ACEOF - ;; -esac - -echo "$as_me:$LINENO: checking for preprocessor stringizing operator" >&5 -echo $ECHO_N "checking for preprocessor stringizing operator... $ECHO_C" >&6 -if test "${ac_cv_c_stringize+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#define x(y) #y - -char *s = x(teststring); -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "#teststring" >/dev/null 2>&1; then - ac_cv_c_stringize=no -else - ac_cv_c_stringize=yes -fi -rm -f conftest* - -fi -echo "$as_me:$LINENO: result: $ac_cv_c_stringize" >&5 -echo "${ECHO_T}$ac_cv_c_stringize" >&6 -if test $ac_cv_c_stringize = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_STRINGIZE 1 -_ACEOF - -fi - -echo "$as_me:$LINENO: checking for signed types" >&5 -echo $ECHO_N "checking for signed types... $ECHO_C" >&6 -if test "${pgac_cv_c_signed+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -signed char c; signed short s; signed int i; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - pgac_cv_c_signed=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -pgac_cv_c_signed=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $pgac_cv_c_signed" >&5 -echo "${ECHO_T}$pgac_cv_c_signed" >&6 -if test x"$pgac_cv_c_signed" = xno ; then - -cat >>confdefs.h <<\_ACEOF -#define signed -_ACEOF - -fi -echo "$as_me:$LINENO: checking for working volatile" >&5 -echo $ECHO_N "checking for working volatile... $ECHO_C" >&6 -if test "${ac_cv_c_volatile+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - -volatile int x; -int * volatile y; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_c_volatile=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_c_volatile=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_c_volatile" >&5 -echo "${ECHO_T}$ac_cv_c_volatile" >&6 -if test $ac_cv_c_volatile = no; then - -cat >>confdefs.h <<\_ACEOF -#define volatile -_ACEOF - -fi - -echo "$as_me:$LINENO: checking whether struct tm is in sys/time.h or time.h" >&5 -echo $ECHO_N "checking whether struct tm is in sys/time.h or time.h... $ECHO_C" >&6 -if test "${ac_cv_struct_tm+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#include - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -struct tm *tp; tp->tm_sec; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_struct_tm=time.h -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_struct_tm=sys/time.h -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_struct_tm" >&5 -echo "${ECHO_T}$ac_cv_struct_tm" >&6 -if test $ac_cv_struct_tm = sys/time.h; then - -cat >>confdefs.h <<\_ACEOF -#define TM_IN_SYS_TIME 1 -_ACEOF - -fi - -echo "$as_me:$LINENO: checking for struct tm.tm_zone" >&5 -echo $ECHO_N "checking for struct tm.tm_zone... $ECHO_C" >&6 -if test "${ac_cv_member_struct_tm_tm_zone+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#include <$ac_cv_struct_tm> - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static struct tm ac_aggr; -if (ac_aggr.tm_zone) -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_member_struct_tm_tm_zone=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_member_struct_tm_tm_zone=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_member_struct_tm_tm_zone" >&5 -echo "${ECHO_T}$ac_cv_member_struct_tm_tm_zone" >&6 -if test $ac_cv_member_struct_tm_tm_zone = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_TM_TM_ZONE 1 -_ACEOF - - -fi - -if test "$ac_cv_member_struct_tm_tm_zone" = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_TM_ZONE 1 -_ACEOF - -else - echo "$as_me:$LINENO: checking for tzname" >&5 -echo $ECHO_N "checking for tzname... $ECHO_C" >&6 -if test "${ac_cv_var_tzname+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#ifndef tzname /* For SGI. */ -extern char *tzname[]; /* RS6000 and others reject char **tzname. */ -#endif - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -atoi(*tzname); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_var_tzname=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_var_tzname=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_var_tzname" >&5 -echo "${ECHO_T}$ac_cv_var_tzname" >&6 - if test $ac_cv_var_tzname = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_TZNAME 1 -_ACEOF - - fi -fi - -echo "$as_me:$LINENO: checking for union semun" >&5 -echo $ECHO_N "checking for union semun... $ECHO_C" >&6 -if test "${ac_cv_type_union_semun+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#include -#include - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -if ((union semun *) 0) - return 0; -if (sizeof (union semun)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_union_semun=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_type_union_semun=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_union_semun" >&5 -echo "${ECHO_T}$ac_cv_type_union_semun" >&6 -if test $ac_cv_type_union_semun = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_UNION_SEMUN 1 -_ACEOF - - -fi - -echo "$as_me:$LINENO: checking for struct sockaddr_un" >&5 -echo $ECHO_N "checking for struct sockaddr_un... $ECHO_C" >&6 -if test "${ac_cv_type_struct_sockaddr_un+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#ifdef HAVE_SYS_UN_H -#include -#endif - - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -if ((struct sockaddr_un *) 0) - return 0; -if (sizeof (struct sockaddr_un)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_struct_sockaddr_un=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_type_struct_sockaddr_un=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_un" >&5 -echo "${ECHO_T}$ac_cv_type_struct_sockaddr_un" >&6 -if test $ac_cv_type_struct_sockaddr_un = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_SOCKADDR_UN 1 -_ACEOF - - -fi - - -echo "$as_me:$LINENO: checking for struct cmsgcred" >&5 -echo $ECHO_N "checking for struct cmsgcred... $ECHO_C" >&6 -if test "${ac_cv_type_struct_cmsgcred+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#include -#include - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -if ((struct cmsgcred *) 0) - return 0; -if (sizeof (struct cmsgcred)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_struct_cmsgcred=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_type_struct_cmsgcred=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_struct_cmsgcred" >&5 -echo "${ECHO_T}$ac_cv_type_struct_cmsgcred" >&6 -if test $ac_cv_type_struct_cmsgcred = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_CMSGCRED 1 -_ACEOF - - -fi -echo "$as_me:$LINENO: checking for struct fcred" >&5 -echo $ECHO_N "checking for struct fcred... $ECHO_C" >&6 -if test "${ac_cv_type_struct_fcred+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#include -#include - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -if ((struct fcred *) 0) - return 0; -if (sizeof (struct fcred)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_struct_fcred=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_type_struct_fcred=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_struct_fcred" >&5 -echo "${ECHO_T}$ac_cv_type_struct_fcred" >&6 -if test $ac_cv_type_struct_fcred = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_FCRED 1 -_ACEOF - - -fi -echo "$as_me:$LINENO: checking for struct sockcred" >&5 -echo $ECHO_N "checking for struct sockcred... $ECHO_C" >&6 -if test "${ac_cv_type_struct_sockcred+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#include -#include - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -if ((struct sockcred *) 0) - return 0; -if (sizeof (struct sockcred)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_struct_sockcred=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_type_struct_sockcred=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockcred" >&5 -echo "${ECHO_T}$ac_cv_type_struct_sockcred" >&6 -if test $ac_cv_type_struct_sockcred = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_STRUCT_SOCKCRED 1 -_ACEOF - - -fi - - -if test "$with_zlib" = yes; then - # Check that defines z_streamp (versions before about 1.0.4 - # did not). While we could work around the lack of z_streamp, it - # seems unwise to encourage people to use such old zlib versions... - echo "$as_me:$LINENO: checking for z_streamp" >&5 -echo $ECHO_N "checking for z_streamp... $ECHO_C" >&6 -if test "${ac_cv_type_z_streamp+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -if ((z_streamp *) 0) - return 0; -if (sizeof (z_streamp)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_z_streamp=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_type_z_streamp=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_z_streamp" >&5 -echo "${ECHO_T}$ac_cv_type_z_streamp" >&6 -if test $ac_cv_type_z_streamp = yes; then - : -else - { { echo "$as_me:$LINENO: error: zlib version is too old -Use --without-zlib to disable zlib support." >&5 -echo "$as_me: error: zlib version is too old -Use --without-zlib to disable zlib support." >&2;} - { (exit 1); exit 1; }; } -fi - -fi - -if test "$with_krb5" = yes; then -# Check for differences between MIT and Heimdal (KTH) releases - echo "$as_me:$LINENO: checking for krb5_ticket.enc_part2" >&5 -echo $ECHO_N "checking for krb5_ticket.enc_part2... $ECHO_C" >&6 -if test "${ac_cv_member_krb5_ticket_enc_part2+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static krb5_ticket ac_aggr; -if (ac_aggr.enc_part2) -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_member_krb5_ticket_enc_part2=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_member_krb5_ticket_enc_part2=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_member_krb5_ticket_enc_part2" >&5 -echo "${ECHO_T}$ac_cv_member_krb5_ticket_enc_part2" >&6 -if test $ac_cv_member_krb5_ticket_enc_part2 = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_KRB5_TICKET_ENC_PART2 1 -_ACEOF - - -else - echo "$as_me:$LINENO: checking for krb5_ticket.client" >&5 -echo $ECHO_N "checking for krb5_ticket.client... $ECHO_C" >&6 -if test "${ac_cv_member_krb5_ticket_client+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static krb5_ticket ac_aggr; -if (ac_aggr.client) -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_member_krb5_ticket_client=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_member_krb5_ticket_client=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_member_krb5_ticket_client" >&5 -echo "${ECHO_T}$ac_cv_member_krb5_ticket_client" >&6 -if test $ac_cv_member_krb5_ticket_client = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_KRB5_TICKET_CLIENT 1 -_ACEOF - - -else - { { echo "$as_me:$LINENO: error: could not determine how to get client name from Kerberos 5 ticket" >&5 -echo "$as_me: error: could not determine how to get client name from Kerberos 5 ticket" >&2;} - { (exit 1); exit 1; }; } -fi - -fi - - echo "$as_me:$LINENO: checking for krb5_error.text.data" >&5 -echo $ECHO_N "checking for krb5_error.text.data... $ECHO_C" >&6 -if test "${ac_cv_member_krb5_error_text_data+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static krb5_error ac_aggr; -if (ac_aggr.text.data) -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_member_krb5_error_text_data=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_member_krb5_error_text_data=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_member_krb5_error_text_data" >&5 -echo "${ECHO_T}$ac_cv_member_krb5_error_text_data" >&6 -if test $ac_cv_member_krb5_error_text_data = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_KRB5_ERROR_TEXT_DATA 1 -_ACEOF - - -else - echo "$as_me:$LINENO: checking for krb5_error.e_data" >&5 -echo $ECHO_N "checking for krb5_error.e_data... $ECHO_C" >&6 -if test "${ac_cv_member_krb5_error_e_data+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static krb5_error ac_aggr; -if (ac_aggr.e_data) -return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_member_krb5_error_e_data=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_member_krb5_error_e_data=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_member_krb5_error_e_data" >&5 -echo "${ECHO_T}$ac_cv_member_krb5_error_e_data" >&6 -if test $ac_cv_member_krb5_error_e_data = yes; then - : -else - { { echo "$as_me:$LINENO: error: could not determine how to extract Kerberos 5 error messages" >&5 -echo "$as_me: error: could not determine how to extract Kerberos 5 error messages" >&2;} - { (exit 1); exit 1; }; } -fi - -fi - -fi - - -## -## Functions, global variables -## -echo "$as_me:$LINENO: checking for int timezone" >&5 -echo $ECHO_N "checking for int timezone... $ECHO_C" >&6 -if test "${pgac_cv_var_int_timezone+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -int res; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -res = timezone / 60; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - pgac_cv_var_int_timezone=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -pgac_cv_var_int_timezone=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $pgac_cv_var_int_timezone" >&5 -echo "${ECHO_T}$pgac_cv_var_int_timezone" >&6 -if test x"$pgac_cv_var_int_timezone" = xyes ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_INT_TIMEZONE -_ACEOF - -fi -echo "$as_me:$LINENO: checking types of arguments for accept()" >&5 -echo $ECHO_N "checking types of arguments for accept()... $ECHO_C" >&6 - if test "${ac_cv_func_accept_arg1+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "${ac_cv_func_accept_arg2+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "${ac_cv_func_accept_arg3+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - 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 - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -extern int accept ($ac_cv_func_accept_arg1, $ac_cv_func_accept_arg2, $ac_cv_func_accept_arg3 *); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_not_found=no; break 3 -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_not_found=yes -fi -rm -f conftest.$ac_objext conftest.$ac_ext - done - done - done - if test "$ac_not_found" = yes; then - { { echo "$as_me:$LINENO: error: could not determine argument types" >&5 -echo "$as_me: error: could not determine argument types" >&2;} - { (exit 1); exit 1; }; } - fi - if test "$ac_cv_func_accept_arg3" = "void"; then - ac_cv_func_accept_arg3=int - fi - -fi - -fi - -fi - echo "$as_me:$LINENO: result: $ac_cv_func_accept_arg1, $ac_cv_func_accept_arg2, $ac_cv_func_accept_arg3 *" >&5 -echo "${ECHO_T}$ac_cv_func_accept_arg1, $ac_cv_func_accept_arg2, $ac_cv_func_accept_arg3 *" >&6 - -cat >>confdefs.h <<_ACEOF -#define ACCEPT_TYPE_ARG1 $ac_cv_func_accept_arg1 -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define ACCEPT_TYPE_ARG2 $ac_cv_func_accept_arg2 -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define ACCEPT_TYPE_ARG3 $ac_cv_func_accept_arg3 -_ACEOF - - -echo "$as_me:$LINENO: checking whether gettimeofday takes only one argument" >&5 -echo $ECHO_N "checking whether gettimeofday takes only one argument... $ECHO_C" >&6 -if test "${pgac_cv_func_gettimeofday_1arg+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -struct timeval *tp; -struct timezone *tzp; -gettimeofday(tp,tzp); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - pgac_cv_func_gettimeofday_1arg=no -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -pgac_cv_func_gettimeofday_1arg=yes -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $pgac_cv_func_gettimeofday_1arg" >&5 -echo "${ECHO_T}$pgac_cv_func_gettimeofday_1arg" >&6 -if test x"$pgac_cv_func_gettimeofday_1arg" = xyes ; then - -cat >>confdefs.h <<\_ACEOF -#define GETTIMEOFDAY_1ARG -_ACEOF - -fi - -# SunOS doesn't handle negative byte comparisons properly with +/- return -echo "$as_me:$LINENO: checking for 8-bit clean memcmp" >&5 -echo $ECHO_N "checking for 8-bit clean memcmp... $ECHO_C" >&6 -if test "${pgac_cv_func_memcmp_clean+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - pgac_cv_func_memcmp_clean=no -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -main() -{ - char c0 = 0x40, c1 = 0x80, c2 = 0x81; - exit(memcmp(&c0, &c2, 1) < 0 && memcmp(&c1, &c2, 1) < 0 ? 0 : 1); -} - -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - pgac_cv_func_memcmp_clean=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -( exit $ac_status ) -pgac_cv_func_memcmp_clean=no -fi -rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -echo "$as_me:$LINENO: result: $pgac_cv_func_memcmp_clean" >&5 -echo "${ECHO_T}$pgac_cv_func_memcmp_clean" >&6 -if test $pgac_cv_func_memcmp_clean = no ; then - MEMCMP=memcmp.o -else - MEMCMP= -fi - - - - - - - - - - - - - - -for ac_func in cbrt fcvt getopt_long memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen fdatasync -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - -echo "$as_me:$LINENO: checking whether fdatasync is declared" >&5 -echo $ECHO_N "checking whether fdatasync is declared... $ECHO_C" >&6 -if test "${ac_cv_have_decl_fdatasync+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -#ifndef fdatasync - char *p = (char *) fdatasync; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_have_decl_fdatasync=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_have_decl_fdatasync=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_have_decl_fdatasync" >&5 -echo "${ECHO_T}$ac_cv_have_decl_fdatasync" >&6 -if test $ac_cv_have_decl_fdatasync = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_FDATASYNC 1 -_ACEOF - - -else - cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_FDATASYNC 0 -_ACEOF - - -fi - - - -echo "$as_me:$LINENO: checking for PS_STRINGS" >&5 -echo $ECHO_N "checking for PS_STRINGS... $ECHO_C" >&6 -if test "${pgac_cv_var_PS_STRINGS+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#include - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -PS_STRINGS->ps_nargvstr = 1; -PS_STRINGS->ps_argvstr = "foo"; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - pgac_cv_var_PS_STRINGS=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -pgac_cv_var_PS_STRINGS=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $pgac_cv_var_PS_STRINGS" >&5 -echo "${ECHO_T}$pgac_cv_var_PS_STRINGS" >&6 -if test "$pgac_cv_var_PS_STRINGS" = yes ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_PS_STRINGS -_ACEOF - -fi - - -# We use our snprintf.c emulation if either snprintf() or vsnprintf() -# is missing. Yes, there are machines that have only one. We may -# also decide to use snprintf.c if snprintf() is present but does not -# have working "long long int" support -- see below. - -SNPRINTF='' - -for ac_func in snprintf -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - SNPRINTF='snprintf.o' -fi -done - - -for ac_func in vsnprintf -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - SNPRINTF='snprintf.o' -fi -done - - - - -# Check whether declares snprintf() and vsnprintf(); if not, -# include/c.h will provide declarations. Note this is a separate test -# from whether the functions exist in the C library --- there are -# systems that have the functions but don't bother to declare them :-( - -echo "$as_me:$LINENO: checking whether snprintf is declared" >&5 -echo $ECHO_N "checking whether snprintf is declared... $ECHO_C" >&6 -if test "${ac_cv_have_decl_snprintf+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -#ifndef snprintf - char *p = (char *) snprintf; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_have_decl_snprintf=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_have_decl_snprintf=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_have_decl_snprintf" >&5 -echo "${ECHO_T}$ac_cv_have_decl_snprintf" >&6 -if test $ac_cv_have_decl_snprintf = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_SNPRINTF 1 -_ACEOF - - -else - cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_SNPRINTF 0 -_ACEOF - - -fi -echo "$as_me:$LINENO: checking whether vsnprintf is declared" >&5 -echo $ECHO_N "checking whether vsnprintf is declared... $ECHO_C" >&6 -if test "${ac_cv_have_decl_vsnprintf+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -#ifndef vsnprintf - char *p = (char *) vsnprintf; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_have_decl_vsnprintf=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_have_decl_vsnprintf=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_have_decl_vsnprintf" >&5 -echo "${ECHO_T}$ac_cv_have_decl_vsnprintf" >&6 -if test $ac_cv_have_decl_vsnprintf = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_VSNPRINTF 1 -_ACEOF - - -else - cat >>confdefs.h <<_ACEOF -#define HAVE_DECL_VSNPRINTF 0 -_ACEOF - - -fi - - - - -# do this one the hard way in case isinf() is a macro -echo "$as_me:$LINENO: checking for isinf" >&5 -echo $ECHO_N "checking for isinf... $ECHO_C" >&6 -if test "${ac_cv_func_isinf+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -double x = 0.0; int res = isinf(x); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_isinf=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_func_isinf=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_isinf" >&5 -echo "${ECHO_T}$ac_cv_func_isinf" >&6 - -if test $ac_cv_func_isinf = yes ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_ISINF 1 -_ACEOF - - ISINF= -else - ISINF='isinf.o' - # Look for a way to implement a substitute for isinf() - - - - -for ac_func in fpclass fp_class fp_class_d class -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - break -fi -done - -fi - - - - -for ac_func in getrusage -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - GETRUSAGE='getrusage.o' -fi -done - - - -for ac_func in srandom -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - SRANDOM='srandom.o' -fi -done - - - -for ac_func in gethostname -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - GETHOSTNAME='gethostname.o' -fi -done - - - -for ac_func in random -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - MISSING_RANDOM='random.o' -fi -done - - - -for ac_func in inet_aton -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - INET_ATON='inet_aton.o' -fi -done - - - -for ac_func in strerror -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - STRERROR='strerror.o' -fi -done - - - -for ac_func in strdup -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - STRDUP='../../utils/strdup.o' -fi -done - - - -for ac_func in strtol -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - STRTOL='strtol.o' -fi -done - - - -for ac_func in strtoul -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - STRTOUL='strtoul.o' -fi -done - - - -for ac_func in strcasecmp -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - STRCASECMP='strcasecmp.o' -fi -done - - - -# On HPUX 9, rint() is not in regular libm.a but in /lib/pa1.1/libm.a; -# this hackery with HPUXMATHLIB allows us to cope. -HPUXMATHLIB="" -case $host_cpu in - hppa1.1) - if [ -r /lib/pa1.1/libm.a ] ; then - HPUXMATHLIB="-L /lib/pa1.1 -lm" - fi ;; -esac - - - -for ac_func in rint -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - echo "$as_me:$LINENO: checking for rint in -lm" >&5 -echo $ECHO_N "checking for rint in -lm... $ECHO_C" >&6 -if test "${ac_cv_lib_m_rint+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lm $HPUXMATHLIB $LIBS" -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char rint (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -rint (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_lib_m_rint=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_lib_m_rint=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_lib_m_rint" >&5 -echo "${ECHO_T}$ac_cv_lib_m_rint" >&6 -if test $ac_cv_lib_m_rint = yes; then - cat >>confdefs.h <<\_ACEOF -#define HAVE_RINT 1 -_ACEOF - -fi - -fi -done - - - -if test "$with_readline" = yes; then - echo "$as_me:$LINENO: checking for rl_completion_append_character" >&5 -echo $ECHO_N "checking for rl_completion_append_character... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#ifdef HAVE_READLINE_READLINE_H -# include -#elif defined(HAVE_READLINE_H) -# include -#endif - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -rl_completion_append_character = 'x'; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - -cat >>confdefs.h <<\_ACEOF -#define HAVE_RL_COMPLETION_APPEND_CHARACTER 1 -_ACEOF - -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - - -for ac_func in rl_completion_matches rl_filename_completion_function -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - -fi - - -echo "$as_me:$LINENO: checking for finite" >&5 -echo $ECHO_N "checking for finite... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -int dummy=finite(1.0); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_FINITE 1 -_ACEOF - -echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - -echo "$as_me:$LINENO: checking for sigsetjmp" >&5 -echo $ECHO_N "checking for sigsetjmp... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -sigjmp_buf x; sigsetjmp(x, 1); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_SIGSETJMP 1 -_ACEOF - -echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - -echo "$as_me:$LINENO: checking for syslog" >&5 -echo $ECHO_N "checking for syslog... $ECHO_C" >&6 -if test "${ac_cv_func_syslog+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char syslog (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char syslog (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_syslog) || defined (__stub___syslog) -choke me -#else -f = syslog; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_func_syslog=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_func_syslog=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_func_syslog" >&5 -echo "${ECHO_T}$ac_cv_func_syslog" >&6 -if test $ac_cv_func_syslog = yes; then - if test "${ac_cv_header_syslog_h+set}" = set; then - echo "$as_me:$LINENO: checking for syslog.h" >&5 -echo $ECHO_N "checking for syslog.h... $ECHO_C" >&6 -if test "${ac_cv_header_syslog_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_syslog_h" >&5 -echo "${ECHO_T}$ac_cv_header_syslog_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking syslog.h usability" >&5 -echo $ECHO_N "checking syslog.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking syslog.h presence" >&5 -echo $ECHO_N "checking syslog.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: syslog.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: syslog.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: syslog.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: syslog.h: proceeding with the preprocessor's result" >&2;};; - no:yes ) - { echo "$as_me:$LINENO: WARNING: syslog.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: syslog.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: syslog.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: syslog.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: syslog.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: syslog.h: proceeding with the preprocessor's result" >&2;};; -esac -echo "$as_me:$LINENO: checking for syslog.h" >&5 -echo $ECHO_N "checking for syslog.h... $ECHO_C" >&6 -if test "${ac_cv_header_syslog_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_syslog_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_syslog_h" >&5 -echo "${ECHO_T}$ac_cv_header_syslog_h" >&6 - -fi -if test $ac_cv_header_syslog_h = yes; then - cat >>confdefs.h <<\_ACEOF -#define HAVE_SYSLOG 1 -_ACEOF - -fi - - -fi - - -echo "$as_me:$LINENO: checking for optreset" >&5 -echo $ECHO_N "checking for optreset... $ECHO_C" >&6 -if test "${pgac_cv_var_int_optreset+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -extern int optreset; optreset = 1; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - pgac_cv_var_int_optreset=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -pgac_cv_var_int_optreset=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $pgac_cv_var_int_optreset" >&5 -echo "${ECHO_T}$pgac_cv_var_int_optreset" >&6 -if test x"$pgac_cv_var_int_optreset" = x"yes"; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_INT_OPTRESET 1 -_ACEOF - -fi - - -# This test makes sure that run tests work at all. Sometimes a shared -# library is found by the linker, but the runtime linker can't find it. -# This check should come after all modifications of compiler or linker -# variables, and before any other run tests. -echo "$as_me:$LINENO: checking test program" >&5 -echo $ECHO_N "checking test program... $ECHO_C" >&6 -if test "$cross_compiling" = yes; then - echo "$as_me:$LINENO: result: cross-compiling" >&5 -echo "${ECHO_T}cross-compiling" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -int main() { return 0; } -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - echo "$as_me:$LINENO: result: ok" >&5 -echo "${ECHO_T}ok" >&6 -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -( exit $ac_status ) -echo "$as_me:$LINENO: result: failed" >&5 -echo "${ECHO_T}failed" >&6 -{ { echo "$as_me:$LINENO: error: -*** Could not execute a simple test program. This may be a problem -*** related to locating shared libraries. Check the file 'config.log' -*** for the exact reason." >&5 -echo "$as_me: error: -*** Could not execute a simple test program. This may be a problem -*** related to locating shared libraries. Check the file 'config.log' -*** for the exact reason." >&2;} - { (exit 1); exit 1; }; } -fi -rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - - - -echo "$as_me:$LINENO: checking whether long int is 64 bits" >&5 -echo $ECHO_N "checking whether long int is 64 bits... $ECHO_C" >&6 -if test "${pgac_cv_type_long_int_64+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - pgac_cv_type_long_int_64=no -{ echo "$as_me:$LINENO: WARNING: 64 bit arithmetic disabled when cross-compiling" >&5 -echo "$as_me: WARNING: 64 bit arithmetic disabled when cross-compiling" >&2;} -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -typedef long int 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()); -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - pgac_cv_type_long_int_64=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -( exit $ac_status ) -pgac_cv_type_long_int_64=no -fi -rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -echo "$as_me:$LINENO: result: $pgac_cv_type_long_int_64" >&5 -echo "${ECHO_T}$pgac_cv_type_long_int_64" >&6 - -HAVE_LONG_INT_64=$pgac_cv_type_long_int_64 -if test x"$pgac_cv_type_long_int_64" = xyes ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LONG_INT_64 -_ACEOF - -fi - - -if test x"$HAVE_LONG_INT_64" = x"no" ; then - echo "$as_me:$LINENO: checking whether long long int is 64 bits" >&5 -echo $ECHO_N "checking whether long long int is 64 bits... $ECHO_C" >&6 -if test "${pgac_cv_type_long_long_int_64+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then - pgac_cv_type_long_long_int_64=no -{ echo "$as_me:$LINENO: WARNING: 64 bit arithmetic disabled when cross-compiling" >&5 -echo "$as_me: WARNING: 64 bit arithmetic disabled when cross-compiling" >&2;} -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -typedef long long int 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()); -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - pgac_cv_type_long_long_int_64=yes -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -( exit $ac_status ) -pgac_cv_type_long_long_int_64=no -fi -rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -echo "$as_me:$LINENO: result: $pgac_cv_type_long_long_int_64" >&5 -echo "${ECHO_T}$pgac_cv_type_long_long_int_64" >&6 - -HAVE_LONG_LONG_INT_64=$pgac_cv_type_long_long_int_64 -if test x"$pgac_cv_type_long_long_int_64" = xyes ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LONG_LONG_INT_64 -_ACEOF - -fi - -fi - - - -if [ x"$HAVE_LONG_LONG_INT_64" = xyes ] ; then - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -#define INT64CONST(x) x##LL -long long int foo = INT64CONST(0x1234567890123456); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LL_CONSTANTS 1 -_ACEOF - -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi - - - -if [ x"$HAVE_LONG_LONG_INT_64" = xyes ] ; then - if [ x$SNPRINTF = x ] ; then - echo "$as_me:$LINENO: checking whether snprintf handles 'long long int' as %lld" >&5 -echo $ECHO_N "checking whether snprintf handles 'long long int' as %lld... $ECHO_C" >&6 - if test "$cross_compiling" = yes; then - echo "$as_me:$LINENO: result: assuming not on target machine" >&5 -echo "${ECHO_T}assuming not on target machine" >&6 - # Force usage of our own snprintf, since we cannot test foreign snprintf - SNPRINTF='snprintf.o' - INT64_FORMAT='"%lld"' - -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -typedef long long int int64; -#define INT64_FORMAT "%lld" - -int64 a = 20000001; -int64 b = 40000005; - -int does_int64_snprintf_work() -{ - int64 c; - char buf[100]; - - if (sizeof(int64) != 8) - return 0; /* doesn't look like the right size */ - - c = a * b; - snprintf(buf, 100, INT64_FORMAT, c); - if (strcmp(buf, "800000140000005") != 0) - return 0; /* either multiply or snprintf is busted */ - return 1; -} -main() { - exit(! does_int64_snprintf_work()); -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - INT64_FORMAT='"%lld"' - -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -( exit $ac_status ) - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - echo "$as_me:$LINENO: checking whether snprintf handles 'long long int' as %qd" >&5 -echo $ECHO_N "checking whether snprintf handles 'long long int' as %qd... $ECHO_C" >&6 - if test "$cross_compiling" = yes; then - echo "$as_me:$LINENO: result: assuming not on target machine" >&5 -echo "${ECHO_T}assuming not on target machine" >&6 - # Force usage of our own snprintf, since we cannot test foreign snprintf - SNPRINTF='snprintf.o' - INT64_FORMAT='"%lld"' - -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -typedef long long int int64; -#define INT64_FORMAT "%qd" - -int64 a = 20000001; -int64 b = 40000005; - -int does_int64_snprintf_work() -{ - int64 c; - char buf[100]; - - if (sizeof(int64) != 8) - return 0; /* doesn't look like the right size */ - - c = a * b; - snprintf(buf, 100, INT64_FORMAT, c); - if (strcmp(buf, "800000140000005") != 0) - return 0; /* either multiply or snprintf is busted */ - return 1; -} -main() { - exit(! does_int64_snprintf_work()); -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6 - INT64_FORMAT='"%qd"' - -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -( exit $ac_status ) - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - # Force usage of our own snprintf, since system snprintf is broken - SNPRINTF='snprintf.o' - INT64_FORMAT='"%lld"' - -fi -rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi - else - # here if we previously decided we needed to use our own snprintf - INT64_FORMAT='"%lld"' - fi -else - # Here if we are not using 'long long int' at all - INT64_FORMAT='"%ld"' -fi - - -cat >>confdefs.h <<_ACEOF -#define INT64_FORMAT $INT64_FORMAT -_ACEOF - - - - - -for ac_func in strtoll strtoq -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - break -fi -done - - - -for ac_func in strtoull strtouq -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - break -fi -done - - -# Check for one of atexit() or on_exit() - -for ac_func in atexit -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - -for ac_func in on_exit -do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 -if eval "test \"\${$as_ac_var+set}\" = set"; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $ac_func (); below. */ -#include -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char $ac_func (); -char (*f) (); - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_$ac_func) || defined (__stub___$ac_func) -choke me -#else -f = $ac_func; -#endif - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - eval "$as_ac_var=yes" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -eval "$as_ac_var=no" -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 -echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 -if test `eval echo '${'$as_ac_var'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -else - { { echo "$as_me:$LINENO: error: neither atexit() nor on_exit() found" >&5 -echo "$as_me: error: neither atexit() nor on_exit() found" >&2;} - { (exit 1); exit 1; }; } -fi -done - -fi -done - - - -echo "$as_me:$LINENO: checking for unsigned long" >&5 -echo $ECHO_N "checking for unsigned long... $ECHO_C" >&6 -if test "${ac_cv_type_unsigned_long+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -if ((unsigned long *) 0) - return 0; -if (sizeof (unsigned long)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_unsigned_long=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_type_unsigned_long=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_unsigned_long" >&5 -echo "${ECHO_T}$ac_cv_type_unsigned_long" >&6 - -echo "$as_me:$LINENO: checking size of unsigned long" >&5 -echo $ECHO_N "checking size of unsigned long... $ECHO_C" >&6 -if test "${ac_cv_sizeof_unsigned_long+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$ac_cv_type_unsigned_long" = yes; then - # The cast to unsigned long works around a bug in the HP C Compiler - # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects - # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. - # This bug is HP SR number 8606223364. - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi -rm -f conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi -rm -f conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo= ac_hi= -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !(((long) (sizeof (unsigned long))) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo=`expr '(' $ac_mid ')' + 1` -fi -rm -f conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) ac_cv_sizeof_unsigned_long=$ac_lo;; -'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long), 77" >&5 -echo "$as_me: error: cannot compute sizeof (unsigned long), 77" >&2;} - { (exit 1); exit 1; }; } ;; -esac -else - if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling" >&5 -echo "$as_me: error: cannot run test program while cross compiling" >&2;} - { (exit 1); exit 1; }; } -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -long longval () { return (long) (sizeof (unsigned long)); } -unsigned long ulongval () { return (long) (sizeof (unsigned long)); } -#include -#include -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - exit (1); - if (((long) (sizeof (unsigned long))) < 0) - { - long i = longval (); - if (i != ((long) (sizeof (unsigned long)))) - exit (1); - fprintf (f, "%ld\n", i); - } - else - { - unsigned long i = ulongval (); - if (i != ((long) (sizeof (unsigned long)))) - exit (1); - fprintf (f, "%lu\n", i); - } - exit (ferror (f) || fclose (f) != 0); - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_sizeof_unsigned_long=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -( exit $ac_status ) -{ { echo "$as_me:$LINENO: error: cannot compute sizeof (unsigned long), 77" >&5 -echo "$as_me: error: cannot compute sizeof (unsigned long), 77" >&2;} - { (exit 1); exit 1; }; } -fi -rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -rm -f conftest.val -else - ac_cv_sizeof_unsigned_long=0 -fi -fi -echo "$as_me:$LINENO: result: $ac_cv_sizeof_unsigned_long" >&5 -echo "${ECHO_T}$ac_cv_sizeof_unsigned_long" >&6 -cat >>confdefs.h <<_ACEOF -#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long -_ACEOF - - - -cat >>confdefs.h <<_ACEOF -#define SIZEOF_DATUM $ac_cv_sizeof_unsigned_long -_ACEOF - - -# Determine memory alignment requirements for the basic C data types. - -echo "$as_me:$LINENO: checking for short" >&5 -echo $ECHO_N "checking for short... $ECHO_C" >&6 -if test "${ac_cv_type_short+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -if ((short *) 0) - return 0; -if (sizeof (short)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_short=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_type_short=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_short" >&5 -echo "${ECHO_T}$ac_cv_type_short" >&6 - -echo "$as_me:$LINENO: checking alignment of short" >&5 -echo $ECHO_N "checking alignment of short... $ECHO_C" >&6 -if test "${pgac_cv_alignof_short+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$ac_cv_type_short" = yes; then - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; short field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; short field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi -rm -f conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; short field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; short field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi -rm -f conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo= ac_hi= -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; short field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo=`expr '(' $ac_mid ')' + 1` -fi -rm -f conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) pgac_cv_alignof_short=$ac_lo;; -'') { { echo "$as_me:$LINENO: error: cannot compute alignment of short, 77" >&5 -echo "$as_me: error: cannot compute alignment of short, 77" >&2;} - { (exit 1); exit 1; }; } ;; -esac -else - if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling" >&5 -echo "$as_me: error: cannot run test program while cross compiling" >&2;} - { (exit 1); exit 1; }; } -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; short field; } pgac_struct; -long longval () { return ((char*) & pgac_struct.field) - ((char*) & pgac_struct); } -unsigned long ulongval () { return ((char*) & pgac_struct.field) - ((char*) & pgac_struct); } -#include -#include -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - exit (1); - if ((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) < 0) - { - long i = longval (); - if (i != (((char*) & pgac_struct.field) - ((char*) & pgac_struct))) - exit (1); - fprintf (f, "%ld\n", i); - } - else - { - unsigned long i = ulongval (); - if (i != (((char*) & pgac_struct.field) - ((char*) & pgac_struct))) - exit (1); - fprintf (f, "%lu\n", i); - } - exit (ferror (f) || fclose (f) != 0); - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - pgac_cv_alignof_short=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -( exit $ac_status ) -{ { echo "$as_me:$LINENO: error: cannot compute alignment of short, 77" >&5 -echo "$as_me: error: cannot compute alignment of short, 77" >&2;} - { (exit 1); exit 1; }; } -fi -rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -rm -f conftest.val -else - pgac_cv_alignof_short=0 -fi -fi -echo "$as_me:$LINENO: result: $pgac_cv_alignof_short" >&5 -echo "${ECHO_T}$pgac_cv_alignof_short" >&6 -cat >>confdefs.h <<_ACEOF -#define ALIGNOF_SHORT $pgac_cv_alignof_short -_ACEOF - - -echo "$as_me:$LINENO: checking for int" >&5 -echo $ECHO_N "checking for int... $ECHO_C" >&6 -if test "${ac_cv_type_int+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -if ((int *) 0) - return 0; -if (sizeof (int)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_int=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_type_int=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_int" >&5 -echo "${ECHO_T}$ac_cv_type_int" >&6 - -echo "$as_me:$LINENO: checking alignment of int" >&5 -echo $ECHO_N "checking alignment of int... $ECHO_C" >&6 -if test "${pgac_cv_alignof_int+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$ac_cv_type_int" = yes; then - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; int field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; int field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi -rm -f conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; int field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; int field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi -rm -f conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo= ac_hi= -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; int field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo=`expr '(' $ac_mid ')' + 1` -fi -rm -f conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) pgac_cv_alignof_int=$ac_lo;; -'') { { echo "$as_me:$LINENO: error: cannot compute alignment of int, 77" >&5 -echo "$as_me: error: cannot compute alignment of int, 77" >&2;} - { (exit 1); exit 1; }; } ;; -esac -else - if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling" >&5 -echo "$as_me: error: cannot run test program while cross compiling" >&2;} - { (exit 1); exit 1; }; } -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; int field; } pgac_struct; -long longval () { return ((char*) & pgac_struct.field) - ((char*) & pgac_struct); } -unsigned long ulongval () { return ((char*) & pgac_struct.field) - ((char*) & pgac_struct); } -#include -#include -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - exit (1); - if ((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) < 0) - { - long i = longval (); - if (i != (((char*) & pgac_struct.field) - ((char*) & pgac_struct))) - exit (1); - fprintf (f, "%ld\n", i); - } - else - { - unsigned long i = ulongval (); - if (i != (((char*) & pgac_struct.field) - ((char*) & pgac_struct))) - exit (1); - fprintf (f, "%lu\n", i); - } - exit (ferror (f) || fclose (f) != 0); - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - pgac_cv_alignof_int=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -( exit $ac_status ) -{ { echo "$as_me:$LINENO: error: cannot compute alignment of int, 77" >&5 -echo "$as_me: error: cannot compute alignment of int, 77" >&2;} - { (exit 1); exit 1; }; } -fi -rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -rm -f conftest.val -else - pgac_cv_alignof_int=0 -fi -fi -echo "$as_me:$LINENO: result: $pgac_cv_alignof_int" >&5 -echo "${ECHO_T}$pgac_cv_alignof_int" >&6 -cat >>confdefs.h <<_ACEOF -#define ALIGNOF_INT $pgac_cv_alignof_int -_ACEOF - - -echo "$as_me:$LINENO: checking for long" >&5 -echo $ECHO_N "checking for long... $ECHO_C" >&6 -if test "${ac_cv_type_long+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -if ((long *) 0) - return 0; -if (sizeof (long)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_long=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_type_long=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5 -echo "${ECHO_T}$ac_cv_type_long" >&6 - -echo "$as_me:$LINENO: checking alignment of long" >&5 -echo $ECHO_N "checking alignment of long... $ECHO_C" >&6 -if test "${pgac_cv_alignof_long+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$ac_cv_type_long" = yes; then - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; long field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; long field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi -rm -f conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; long field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; long field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi -rm -f conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo= ac_hi= -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; long field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo=`expr '(' $ac_mid ')' + 1` -fi -rm -f conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) pgac_cv_alignof_long=$ac_lo;; -'') { { echo "$as_me:$LINENO: error: cannot compute alignment of long, 77" >&5 -echo "$as_me: error: cannot compute alignment of long, 77" >&2;} - { (exit 1); exit 1; }; } ;; -esac -else - if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling" >&5 -echo "$as_me: error: cannot run test program while cross compiling" >&2;} - { (exit 1); exit 1; }; } -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; long field; } pgac_struct; -long longval () { return ((char*) & pgac_struct.field) - ((char*) & pgac_struct); } -unsigned long ulongval () { return ((char*) & pgac_struct.field) - ((char*) & pgac_struct); } -#include -#include -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - exit (1); - if ((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) < 0) - { - long i = longval (); - if (i != (((char*) & pgac_struct.field) - ((char*) & pgac_struct))) - exit (1); - fprintf (f, "%ld\n", i); - } - else - { - unsigned long i = ulongval (); - if (i != (((char*) & pgac_struct.field) - ((char*) & pgac_struct))) - exit (1); - fprintf (f, "%lu\n", i); - } - exit (ferror (f) || fclose (f) != 0); - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - pgac_cv_alignof_long=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -( exit $ac_status ) -{ { echo "$as_me:$LINENO: error: cannot compute alignment of long, 77" >&5 -echo "$as_me: error: cannot compute alignment of long, 77" >&2;} - { (exit 1); exit 1; }; } -fi -rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -rm -f conftest.val -else - pgac_cv_alignof_long=0 -fi -fi -echo "$as_me:$LINENO: result: $pgac_cv_alignof_long" >&5 -echo "${ECHO_T}$pgac_cv_alignof_long" >&6 -cat >>confdefs.h <<_ACEOF -#define ALIGNOF_LONG $pgac_cv_alignof_long -_ACEOF - - -if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then - echo "$as_me:$LINENO: checking for long long int" >&5 -echo $ECHO_N "checking for long long int... $ECHO_C" >&6 -if test "${ac_cv_type_long_long_int+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -if ((long long int *) 0) - return 0; -if (sizeof (long long int)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_long_long_int=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_type_long_long_int=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_long_long_int" >&5 -echo "${ECHO_T}$ac_cv_type_long_long_int" >&6 - -echo "$as_me:$LINENO: checking alignment of long long int" >&5 -echo $ECHO_N "checking alignment of long long int... $ECHO_C" >&6 -if test "${pgac_cv_alignof_long_long_int+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$ac_cv_type_long_long_int" = yes; then - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; long long int field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; long long int field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi -rm -f conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; long long int field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; long long int field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi -rm -f conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo= ac_hi= -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; long long int field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo=`expr '(' $ac_mid ')' + 1` -fi -rm -f conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) pgac_cv_alignof_long_long_int=$ac_lo;; -'') { { echo "$as_me:$LINENO: error: cannot compute alignment of long long int, 77" >&5 -echo "$as_me: error: cannot compute alignment of long long int, 77" >&2;} - { (exit 1); exit 1; }; } ;; -esac -else - if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling" >&5 -echo "$as_me: error: cannot run test program while cross compiling" >&2;} - { (exit 1); exit 1; }; } -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; long long int field; } pgac_struct; -long longval () { return ((char*) & pgac_struct.field) - ((char*) & pgac_struct); } -unsigned long ulongval () { return ((char*) & pgac_struct.field) - ((char*) & pgac_struct); } -#include -#include -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - exit (1); - if ((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) < 0) - { - long i = longval (); - if (i != (((char*) & pgac_struct.field) - ((char*) & pgac_struct))) - exit (1); - fprintf (f, "%ld\n", i); - } - else - { - unsigned long i = ulongval (); - if (i != (((char*) & pgac_struct.field) - ((char*) & pgac_struct))) - exit (1); - fprintf (f, "%lu\n", i); - } - exit (ferror (f) || fclose (f) != 0); - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - pgac_cv_alignof_long_long_int=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -( exit $ac_status ) -{ { echo "$as_me:$LINENO: error: cannot compute alignment of long long int, 77" >&5 -echo "$as_me: error: cannot compute alignment of long long int, 77" >&2;} - { (exit 1); exit 1; }; } -fi -rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -rm -f conftest.val -else - pgac_cv_alignof_long_long_int=0 -fi -fi -echo "$as_me:$LINENO: result: $pgac_cv_alignof_long_long_int" >&5 -echo "${ECHO_T}$pgac_cv_alignof_long_long_int" >&6 -cat >>confdefs.h <<_ACEOF -#define ALIGNOF_LONG_LONG_INT $pgac_cv_alignof_long_long_int -_ACEOF - - -fi -echo "$as_me:$LINENO: checking for double" >&5 -echo $ECHO_N "checking for double... $ECHO_C" >&6 -if test "${ac_cv_type_double+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -if ((double *) 0) - return 0; -if (sizeof (double)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_double=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_type_double=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_double" >&5 -echo "${ECHO_T}$ac_cv_type_double" >&6 - -echo "$as_me:$LINENO: checking alignment of double" >&5 -echo $ECHO_N "checking alignment of double... $ECHO_C" >&6 -if test "${pgac_cv_alignof_double+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$ac_cv_type_double" = yes; then - if test "$cross_compiling" = yes; then - # Depending upon the size, compute the lo and hi bounds. -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; double field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) >= 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=0 ac_mid=0 - while :; do - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; double field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo=`expr $ac_mid + 1` - if test $ac_lo -le $ac_mid; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid + 1` -fi -rm -f conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; double field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) < 0)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=-1 ac_mid=-1 - while :; do - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; double field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) >= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_lo=$ac_mid; break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_hi=`expr '(' $ac_mid ')' - 1` - if test $ac_mid -le $ac_hi; then - ac_lo= ac_hi= - break - fi - ac_mid=`expr 2 '*' $ac_mid` -fi -rm -f conftest.$ac_objext conftest.$ac_ext - done -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo= ac_hi= -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -rm -f conftest.$ac_objext conftest.$ac_ext -# Binary search between lo and hi bounds. -while test "x$ac_lo" != "x$ac_hi"; do - ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo` - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; double field; } pgac_struct; -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -static int test_array [1 - 2 * !((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) <= $ac_mid)]; -test_array [0] = 0 - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_hi=$ac_mid -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_lo=`expr '(' $ac_mid ')' + 1` -fi -rm -f conftest.$ac_objext conftest.$ac_ext -done -case $ac_lo in -?*) pgac_cv_alignof_double=$ac_lo;; -'') { { echo "$as_me:$LINENO: error: cannot compute alignment of double, 77" >&5 -echo "$as_me: error: cannot compute alignment of double, 77" >&2;} - { (exit 1); exit 1; }; } ;; -esac -else - if test "$cross_compiling" = yes; then - { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling" >&5 -echo "$as_me: error: cannot run test program while cross compiling" >&2;} - { (exit 1); exit 1; }; } -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -struct { char filler; double field; } pgac_struct; -long longval () { return ((char*) & pgac_struct.field) - ((char*) & pgac_struct); } -unsigned long ulongval () { return ((char*) & pgac_struct.field) - ((char*) & pgac_struct); } -#include -#include -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - - FILE *f = fopen ("conftest.val", "w"); - if (! f) - exit (1); - if ((((char*) & pgac_struct.field) - ((char*) & pgac_struct)) < 0) - { - long i = longval (); - if (i != (((char*) & pgac_struct.field) - ((char*) & pgac_struct))) - exit (1); - fprintf (f, "%ld\n", i); - } - else - { - unsigned long i = ulongval (); - if (i != (((char*) & pgac_struct.field) - ((char*) & pgac_struct))) - exit (1); - fprintf (f, "%lu\n", i); - } - exit (ferror (f) || fclose (f) != 0); - - ; - return 0; -} -_ACEOF -rm -f conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { ac_try='./conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - pgac_cv_alignof_double=`cat conftest.val` -else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -( exit $ac_status ) -{ { echo "$as_me:$LINENO: error: cannot compute alignment of double, 77" >&5 -echo "$as_me: error: cannot compute alignment of double, 77" >&2;} - { (exit 1); exit 1; }; } -fi -rm -f core core.* *.core conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext -fi -fi -rm -f conftest.val -else - pgac_cv_alignof_double=0 -fi -fi -echo "$as_me:$LINENO: result: $pgac_cv_alignof_double" >&5 -echo "${ECHO_T}$pgac_cv_alignof_double" >&6 -cat >>confdefs.h <<_ACEOF -#define ALIGNOF_DOUBLE $pgac_cv_alignof_double -_ACEOF - - - -# Compute maximum alignment of any basic type. -# We assume long's alignment is at least as strong as char, short, or int; -# but we must check long long (if it exists) and double. - -MAX_ALIGNOF=$pgac_cv_alignof_long -if test $MAX_ALIGNOF -lt $pgac_cv_alignof_double ; then - MAX_ALIGNOF=$pgac_cv_alignof_double -fi -if test x"$HAVE_LONG_LONG_INT_64" = xyes && test $MAX_ALIGNOF -lt $pgac_cv_alignof_long_long_int ; then - MAX_ALIGNOF="$pgac_cv_alignof_long_long_int" -fi - -cat >>confdefs.h <<_ACEOF -#define MAXIMUM_ALIGNOF $MAX_ALIGNOF -_ACEOF - - - -# Some platforms predefine the types int8, int16, etc. Only check -# a (hopefully) representative subset. -echo "$as_me:$LINENO: checking for int8" >&5 -echo $ECHO_N "checking for int8... $ECHO_C" >&6 -if test "${ac_cv_type_int8+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#ifdef HAVE_SUPPORTDEFS_H -#include -#endif - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -if ((int8 *) 0) - return 0; -if (sizeof (int8)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_int8=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_type_int8=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_int8" >&5 -echo "${ECHO_T}$ac_cv_type_int8" >&6 -if test $ac_cv_type_int8 = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_INT8 1 -_ACEOF - - -fi -echo "$as_me:$LINENO: checking for uint8" >&5 -echo $ECHO_N "checking for uint8... $ECHO_C" >&6 -if test "${ac_cv_type_uint8+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#ifdef HAVE_SUPPORTDEFS_H -#include -#endif - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -if ((uint8 *) 0) - return 0; -if (sizeof (uint8)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_uint8=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_type_uint8=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_uint8" >&5 -echo "${ECHO_T}$ac_cv_type_uint8" >&6 -if test $ac_cv_type_uint8 = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_UINT8 1 -_ACEOF - - -fi -echo "$as_me:$LINENO: checking for int64" >&5 -echo $ECHO_N "checking for int64... $ECHO_C" >&6 -if test "${ac_cv_type_int64+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#ifdef HAVE_SUPPORTDEFS_H -#include -#endif - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -if ((int64 *) 0) - return 0; -if (sizeof (int64)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_int64=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_type_int64=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_int64" >&5 -echo "${ECHO_T}$ac_cv_type_int64" >&6 -if test $ac_cv_type_int64 = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_INT64 1 -_ACEOF - - -fi -echo "$as_me:$LINENO: checking for uint64" >&5 -echo $ECHO_N "checking for uint64... $ECHO_C" >&6 -if test "${ac_cv_type_uint64+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#ifdef HAVE_SUPPORTDEFS_H -#include -#endif - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -if ((uint64 *) 0) - return 0; -if (sizeof (uint64)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_uint64=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_type_uint64=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_uint64" >&5 -echo "${ECHO_T}$ac_cv_type_uint64" >&6 -if test $ac_cv_type_uint64 = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_UINT64 1 -_ACEOF - - -fi - - -# We also check for sig_atomic_t, which *should* be defined per ANSI -# C, but is missing on some old platforms. -echo "$as_me:$LINENO: checking for sig_atomic_t" >&5 -echo $ECHO_N "checking for sig_atomic_t... $ECHO_C" >&6 -if test "${ac_cv_type_sig_atomic_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -if ((sig_atomic_t *) 0) - return 0; -if (sizeof (sig_atomic_t)) - return 0; - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_type_sig_atomic_t=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_cv_type_sig_atomic_t=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $ac_cv_type_sig_atomic_t" >&5 -echo "${ECHO_T}$ac_cv_type_sig_atomic_t" >&6 -if test $ac_cv_type_sig_atomic_t = yes; then - -cat >>confdefs.h <<_ACEOF -#define HAVE_SIG_ATOMIC_T 1 -_ACEOF - - -fi - - - -echo "$as_me:$LINENO: checking for POSIX signal interface" >&5 -echo $ECHO_N "checking for POSIX signal interface... $ECHO_C" >&6 -if test "${pgac_cv_func_posix_signals+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -struct sigaction act, oact; -sigemptyset(&act.sa_mask); -act.sa_flags = SA_RESTART; -sigaction(0, &act, &oact); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - pgac_cv_func_posix_signals=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -pgac_cv_func_posix_signals=no -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $pgac_cv_func_posix_signals" >&5 -echo "${ECHO_T}$pgac_cv_func_posix_signals" >&6 -if test x"$pgac_cv_func_posix_signals" = xyes ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_POSIX_SIGNALS -_ACEOF - -fi -HAVE_POSIX_SIGNALS=$pgac_cv_func_posix_signals - - - -# Select semaphore implementation type. -if test x"$USE_NAMED_POSIX_SEMAPHORES" = x"1" ; then - -cat >>confdefs.h <<\_ACEOF -#define USE_NAMED_POSIX_SEMAPHORES 1 -_ACEOF - - SEMA_IMPLEMENTATION="src/backend/port/posix_sema.c" -else - if test x"$USE_UNNAMED_POSIX_SEMAPHORES" = x"1" ; then - -cat >>confdefs.h <<\_ACEOF -#define USE_UNNAMED_POSIX_SEMAPHORES 1 -_ACEOF - - SEMA_IMPLEMENTATION="src/backend/port/posix_sema.c" - else - -cat >>confdefs.h <<\_ACEOF -#define USE_SYSV_SEMAPHORES 1 -_ACEOF - - SEMA_IMPLEMENTATION="src/backend/port/sysv_sema.c" - fi -fi - - -# Select shared-memory implementation type. - -cat >>confdefs.h <<\_ACEOF -#define USE_SYSV_SHARED_MEMORY 1 -_ACEOF - -SHMEM_IMPLEMENTATION="src/backend/port/sysv_shmem.c" - - -if test "$enable_nls" = yes ; then - - echo "$as_me:$LINENO: checking for library containing gettext" >&5 -echo $ECHO_N "checking for library containing gettext... $ECHO_C" >&6 -if test "${ac_cv_search_gettext+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -ac_cv_search_gettext=no -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char gettext (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -gettext (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_gettext="none required" -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext -if test "$ac_cv_search_gettext" = no; then - for ac_lib in intl; do - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" - -/* Override any gcc2 internal prototype to avoid an error. */ -#ifdef __cplusplus -extern "C" -#endif -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char gettext (); -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -gettext (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest$ac_exeext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_cv_search_gettext="-l$ac_lib" -break -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -fi -rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext - done -fi -LIBS=$ac_func_search_save_LIBS -fi -echo "$as_me:$LINENO: result: $ac_cv_search_gettext" >&5 -echo "${ECHO_T}$ac_cv_search_gettext" >&6 -if test "$ac_cv_search_gettext" != no; then - test "$ac_cv_search_gettext" = "none required" || LIBS="$ac_cv_search_gettext $LIBS" - -else - { { echo "$as_me:$LINENO: error: a gettext implementation is required for NLS" >&5 -echo "$as_me: error: a gettext implementation is required for NLS" >&2;} - { (exit 1); exit 1; }; } -fi - - if test "${ac_cv_header_libintl_h+set}" = set; then - echo "$as_me:$LINENO: checking for libintl.h" >&5 -echo $ECHO_N "checking for libintl.h... $ECHO_C" >&6 -if test "${ac_cv_header_libintl_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_libintl_h" >&5 -echo "${ECHO_T}$ac_cv_header_libintl_h" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking libintl.h usability" >&5 -echo $ECHO_N "checking libintl.h usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking libintl.h presence" >&5 -echo $ECHO_N "checking libintl.h presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: libintl.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: libintl.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: libintl.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: libintl.h: proceeding with the preprocessor's result" >&2;};; - no:yes ) - { echo "$as_me:$LINENO: WARNING: libintl.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: libintl.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: libintl.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: libintl.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: libintl.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: libintl.h: proceeding with the preprocessor's result" >&2;};; -esac -echo "$as_me:$LINENO: checking for libintl.h" >&5 -echo $ECHO_N "checking for libintl.h... $ECHO_C" >&6 -if test "${ac_cv_header_libintl_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_libintl_h=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_libintl_h" >&5 -echo "${ECHO_T}$ac_cv_header_libintl_h" >&6 - -fi -if test $ac_cv_header_libintl_h = yes; then - : -else - { { echo "$as_me:$LINENO: error: header file is required for NLS" >&5 -echo "$as_me: error: header file is required for NLS" >&2;} - { (exit 1); exit 1; }; } -fi - - - for ac_prog in msgfmt -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_MSGFMT+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$MSGFMT"; then - ac_cv_prog_MSGFMT="$MSGFMT" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_MSGFMT="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -MSGFMT=$ac_cv_prog_MSGFMT -if test -n "$MSGFMT"; then - echo "$as_me:$LINENO: result: $MSGFMT" >&5 -echo "${ECHO_T}$MSGFMT" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$MSGFMT" && break -done - - if test -z "$MSGFMT"; then - { { echo "$as_me:$LINENO: error: msgfmt is required for NLS" >&5 -echo "$as_me: error: msgfmt is required for NLS" >&2;} - { (exit 1); exit 1; }; } - fi - for ac_prog in msgmerge -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_MSGMERGE+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$MSGMERGE"; then - ac_cv_prog_MSGMERGE="$MSGMERGE" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_MSGMERGE="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -MSGMERGE=$ac_cv_prog_MSGMERGE -if test -n "$MSGMERGE"; then - echo "$as_me:$LINENO: result: $MSGMERGE" >&5 -echo "${ECHO_T}$MSGMERGE" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$MSGMERGE" && break -done - - for ac_prog in xgettext -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_XGETTEXT+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$XGETTEXT"; then - ac_cv_prog_XGETTEXT="$XGETTEXT" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_XGETTEXT="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -XGETTEXT=$ac_cv_prog_XGETTEXT -if test -n "$XGETTEXT"; then - echo "$as_me:$LINENO: result: $XGETTEXT" >&5 -echo "${ECHO_T}$XGETTEXT" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$XGETTEXT" && break -done - - - # 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 - - - -cat >>confdefs.h <<_ACEOF -#define LOCALEDIR "$exp_localedir" -_ACEOF - - -fi - -if test "$with_CXX" = yes; then - - -ac_ext=cc -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - -if test "${ac_cv_header_string+set}" = set; then - echo "$as_me:$LINENO: checking for string" >&5 -echo $ECHO_N "checking for string... $ECHO_C" >&6 -if test "${ac_cv_header_string+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -echo "$as_me:$LINENO: result: $ac_cv_header_string" >&5 -echo "${ECHO_T}$ac_cv_header_string" >&6 -else - # Is the header compilable? -echo "$as_me:$LINENO: checking string usability" >&5 -echo $ECHO_N "checking string usability... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -ac_header_compiler=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6 - -# Is the header present? -echo "$as_me:$LINENO: checking string presence" >&5 -echo $ECHO_N "checking string presence... $ECHO_C" >&6 -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -_ACEOF -if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 - (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 - ac_status=$? - egrep -v '^ *\+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_cxx_preproc_warn_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_header_preproc=no -fi -rm -f conftest.err conftest.$ac_ext -echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6 - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc in - yes:no ) - { echo "$as_me:$LINENO: WARNING: string: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: string: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: string: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: string: proceeding with the preprocessor's result" >&2;};; - no:yes ) - { echo "$as_me:$LINENO: WARNING: string: present but cannot be compiled" >&5 -echo "$as_me: WARNING: string: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: string: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: string: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: string: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: string: proceeding with the preprocessor's result" >&2;};; -esac -echo "$as_me:$LINENO: checking for string" >&5 -echo $ECHO_N "checking for string... $ECHO_C" >&6 -if test "${ac_cv_header_string+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_string=$ac_header_preproc -fi -echo "$as_me:$LINENO: result: $ac_cv_header_string" >&5 -echo "${ECHO_T}$ac_cv_header_string" >&6 - -fi -if test $ac_cv_header_string = yes; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_CXX_STRING_HEADER 1 -_ACEOF - -else - echo "$as_me:$LINENO: checking for class string in " >&5 -echo $ECHO_N "checking for class string in ... $ECHO_C" >&6 -if test "${pgac_cv_class_string_in_string_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#include -#include - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ -string foo = "test" - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - pgac_cv_class_string_in_string_h=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -pgac_cv_class_string_in_string_h=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -fi -echo "$as_me:$LINENO: result: $pgac_cv_class_string_in_string_h" >&5 -echo "${ECHO_T}$pgac_cv_class_string_in_string_h" >&6 - - if test x"$pgac_cv_class_string_in_string_h" != xyes ; then - { { echo "$as_me:$LINENO: error: neither nor seem to define the C++ class 'string'" >&5 -echo "$as_me: error: neither nor seem to define the C++ class 'string'" >&2;} - { (exit 1); exit 1; }; } - fi - -fi - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -echo "$as_me:$LINENO: checking for namespace std in C++" >&5 -echo $ECHO_N "checking for namespace std in C++... $ECHO_C" >&6 -if test "${pgac_cv_cxx_namespace_std+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - -ac_ext=cc -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - -cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" -#include "confdefs.h" -#include -#include -#ifdef HAVE_CXX_STRING_HEADER -#include -#endif -using namespace std; - -#ifdef F77_DUMMY_MAIN -# ifdef __cplusplus - extern "C" -# endif - int F77_DUMMY_MAIN() { return 1; } -#endif -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext -if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' - { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 - (eval $ac_try) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; }; then - pgac_cv_cxx_namespace_std=yes -else - echo "$as_me: failed program was:" >&5 -cat conftest.$ac_ext >&5 -pgac_cv_cxx_namespace_std=no -fi -rm -f conftest.$ac_objext conftest.$ac_ext -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -fi -echo "$as_me:$LINENO: result: $pgac_cv_cxx_namespace_std" >&5 -echo "${ECHO_T}$pgac_cv_cxx_namespace_std" >&6 - -if test $pgac_cv_cxx_namespace_std = yes ; then - -cat >>confdefs.h <<\_ACEOF -#define HAVE_NAMESPACE_STD 1 -_ACEOF - -fi -fi - - -# Check for Tcl configuration script tclConfig.sh -if test "$with_tcl" = yes; then - for ac_prog in tclsh tcl -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_path_TCLSH+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $TCLSH in - [\\/]* | ?:[\\/]*) - ac_cv_path_TCLSH="$TCLSH" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_TCLSH="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - ;; -esac -fi -TCLSH=$ac_cv_path_TCLSH - -if test -n "$TCLSH"; then - echo "$as_me:$LINENO: result: $TCLSH" >&5 -echo "${ECHO_T}$TCLSH" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$TCLSH" && break -done - -echo "$as_me:$LINENO: checking for tclConfig.sh" >&5 -echo $ECHO_N "checking for tclConfig.sh... $ECHO_C" >&6 -# Let user override test -if test -z "$TCL_CONFIG_SH"; then - pgac_test_dirs="$with_tclconfig" - - set X $pgac_test_dirs; shift - if test $# -eq 0; then - test -z "$TCLSH" && { { echo "$as_me:$LINENO: error: unable to locate tclConfig.sh because no Tcl shell was found" >&5 -echo "$as_me: error: unable to locate tclConfig.sh because no Tcl shell was found" >&2;} - { (exit 1); exit 1; }; } - 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 - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - { { echo "$as_me:$LINENO: error: file 'tclConfig.sh' is required for Tcl" >&5 -echo "$as_me: error: file 'tclConfig.sh' is required for Tcl" >&2;} - { (exit 1); exit 1; }; } -else - echo "$as_me:$LINENO: result: $TCL_CONFIG_SH" >&5 -echo "${ECHO_T}$TCL_CONFIG_SH" >&6 -fi - - - - . "$TCL_CONFIG_SH" -eval TCL_LIB_FILE=\"$TCL_LIB_FILE\" -eval TCL_LIBS=\"$TCL_LIBS\" -eval TCL_LIB_SPEC=\"$TCL_LIB_SPEC\" -eval TCL_SHARED_BUILD=\"$TCL_SHARED_BUILD\" - - fi - -# Check for Tk configuration script tkConfig.sh -if test "$with_tk" = yes; then - echo "$as_me:$LINENO: checking for tkConfig.sh" >&5 -echo $ECHO_N "checking for tkConfig.sh... $ECHO_C" >&6 -# Let user override test -if test -z "$TK_CONFIG_SH"; then - pgac_test_dirs="$with_tkconfig $with_tclconfig" - - set X $pgac_test_dirs; shift - if test $# -eq 0; then - test -z "$TCLSH" && { { echo "$as_me:$LINENO: error: unable to locate tkConfig.sh because no Tcl shell was found" >&5 -echo "$as_me: error: unable to locate tkConfig.sh because no Tcl shell was found" >&2;} - { (exit 1); exit 1; }; } - 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 - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 - { { echo "$as_me:$LINENO: error: file 'tkConfig.sh' is required for Tk" >&5 -echo "$as_me: error: file 'tkConfig.sh' is required for Tk" >&2;} - { (exit 1); exit 1; }; } -else - echo "$as_me:$LINENO: result: $TK_CONFIG_SH" >&5 -echo "${ECHO_T}$TK_CONFIG_SH" >&6 -fi - - - - . "$TK_CONFIG_SH" -eval TK_LIBS=\"$TK_LIBS\" -eval TK_LIB_SPEC=\"$TK_LIB_SPEC\" -eval TK_XINCLUDES=\"$TK_XINCLUDES\" - -fi - - -# -# Check for DocBook and tools -# -for ac_prog in onsgmls nsgmls -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_NSGMLS+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$NSGMLS"; then - ac_cv_prog_NSGMLS="$NSGMLS" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_NSGMLS="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -NSGMLS=$ac_cv_prog_NSGMLS -if test -n "$NSGMLS"; then - echo "$as_me:$LINENO: result: $NSGMLS" >&5 -echo "${ECHO_T}$NSGMLS" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$NSGMLS" && break -done - -for ac_prog in openjade jade -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_JADE+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$JADE"; then - ac_cv_prog_JADE="$JADE" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_JADE="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -JADE=$ac_cv_prog_JADE -if test -n "$JADE"; then - echo "$as_me:$LINENO: result: $JADE" >&5 -echo "${ECHO_T}$JADE" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$JADE" && break -done - - -echo "$as_me:$LINENO: checking for DocBook V3.1" >&5 -echo $ECHO_N "checking for DocBook V3.1... $ECHO_C" >&6 -if test "${pgac_cv_check_docbook+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.sgml < - - test - - random - - testsect - text - - - -EOF - -${NSGMLS-false} -s conftest.sgml 1>&5 2>&1 -if test $? -eq 0; then - pgac_cv_check_docbook=yes -else - pgac_cv_check_docbook=no -fi -rm -f conftest.sgml -fi -echo "$as_me:$LINENO: result: $pgac_cv_check_docbook" >&5 -echo "${ECHO_T}$pgac_cv_check_docbook" >&6 - -have_docbook=$pgac_cv_check_docbook - - -echo "$as_me:$LINENO: checking for DocBook stylesheets" >&5 -echo $ECHO_N "checking for DocBook stylesheets... $ECHO_C" >&6 -if test "${pgac_cv_path_stylesheets+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - 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 -fi - -DOCBOOKSTYLE=$pgac_cv_path_stylesheets - -if test -n "$DOCBOOKSTYLE"; then - echo "$as_me:$LINENO: result: $DOCBOOKSTYLE" >&5 -echo "${ECHO_T}$DOCBOOKSTYLE" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi -if test -n "$DOCBOOKSTYLE"; then - for ac_prog in collateindex.pl -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_path_COLLATEINDEX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $COLLATEINDEX in - [\\/]* | ?:[\\/]*) - ac_cv_path_COLLATEINDEX="$COLLATEINDEX" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $DOCBOOKSTYLE/bin $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_COLLATEINDEX="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - ;; -esac -fi -COLLATEINDEX=$ac_cv_path_COLLATEINDEX - -if test -n "$COLLATEINDEX"; then - echo "$as_me:$LINENO: result: $COLLATEINDEX" >&5 -echo "${ECHO_T}$COLLATEINDEX" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$COLLATEINDEX" && break -done - -else - for ac_prog in collateindex.pl -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_path_COLLATEINDEX+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - case $COLLATEINDEX in - [\\/]* | ?:[\\/]*) - ac_cv_path_COLLATEINDEX="$COLLATEINDEX" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_COLLATEINDEX="$as_dir/$ac_word$ac_exec_ext" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - - ;; -esac -fi -COLLATEINDEX=$ac_cv_path_COLLATEINDEX - -if test -n "$COLLATEINDEX"; then - echo "$as_me:$LINENO: result: $COLLATEINDEX" >&5 -echo "${ECHO_T}$COLLATEINDEX" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$COLLATEINDEX" && break -done - -fi -for ac_prog in sgmlspl -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 -if test "${ac_cv_prog_SGMLSPL+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test -n "$SGMLSPL"; then - ac_cv_prog_SGMLSPL="$SGMLSPL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_SGMLSPL="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done -done - -fi -fi -SGMLSPL=$ac_cv_prog_SGMLSPL -if test -n "$SGMLSPL"; then - echo "$as_me:$LINENO: result: $SGMLSPL" >&5 -echo "${ECHO_T}$SGMLSPL" >&6 -else - echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6 -fi - - test -n "$SGMLSPL" && break -done - - - -# prepare build tree if outside source tree -# Note 1: test -ef might not exist, but it's more reliable than `pwd`. -# Note 2: /bin/pwd might be better than shell's built-in at getting -# a symlink-free name. -if test "$no_create" != yes; then - if ( test "$srcdir" -ef . ) >/dev/null 2>&1 || test "`cd $srcdir && /bin/pwd`" = "`/bin/pwd`"; then - : - else - vpath_build=yes - - echo $ECHO_N "preparing build tree... $ECHO_C" >&6 - pgac_abs_top_srcdir=`cd "$srcdir" && pwd` - $SHELL "$ac_aux_dir/prep_buildtree" "$pgac_abs_top_srcdir" "." \ - || { { echo "$as_me:$LINENO: error: failed" >&5 -echo "$as_me: error: failed" >&2;} - { (exit 1); exit 1; }; } - echo "$as_me:$LINENO: result: done" >&5 -echo "${ECHO_T}done" >&6 - fi -fi - - -ac_config_files="$ac_config_files GNUmakefile src/Makefile.global" - - -ac_config_links="$ac_config_links src/backend/port/dynloader.c:src/backend/port/dynloader/${template}.c src/backend/port/pg_sema.c:${SEMA_IMPLEMENTATION} src/backend/port/pg_shmem.c:${SHMEM_IMPLEMENTATION} src/include/dynloader.h:src/backend/port/dynloader/${template}.h src/include/pg_config_os.h:src/include/port/${template}.h src/Makefile.port:src/makefiles/Makefile.${template}" - - -ac_config_headers="$ac_config_headers src/include/pg_config.h" - - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overriden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -{ - (set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" - ;; - esac; -} | - sed ' - t clear - : clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - : end' >>confcache -if cmp -s $cache_file confcache; then :; else - if test -w $cache_file; then - test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" - cat confcache >$cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# VPATH may cause trouble with some makes, so we remove $(srcdir), -# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=/{ -s/:*\$(srcdir):*/:/; -s/:*\${srcdir}:*/:/; -s/:*@srcdir@:*/:/; -s/^\([^=]*=[ ]*\):*/\1/; -s/:*$//; -s/^[^=]*=[ ]*$//; -}' -fi - -DEFS=-DHAVE_CONFIG_H - - -: ${CONFIG_STATUS=./config.status} -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 -echo "$as_me: creating $CONFIG_STATUS" >&6;} -cat >$CONFIG_STATUS <<_ACEOF -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -SHELL=\${CONFIG_SHELL-$SHELL} -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF - -## --------------------- ## -## M4sh Initialization. ## -## --------------------- ## - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: -elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then - set -o posix -fi - -# NLS nuisances. -# Support unset when possible. -if (FOO=FOO; unset FOO) >/dev/null 2>&1; then - as_unset=unset -else - as_unset=false -fi - -(set +x; test -n "`(LANG=C; export LANG) 2>&1`") && - { $as_unset LANG || test "${LANG+set}" != set; } || - { LANG=C; export LANG; } -(set +x; test -n "`(LC_ALL=C; export LC_ALL) 2>&1`") && - { $as_unset LC_ALL || test "${LC_ALL+set}" != set; } || - { LC_ALL=C; export LC_ALL; } -(set +x; test -n "`(LC_TIME=C; export LC_TIME) 2>&1`") && - { $as_unset LC_TIME || test "${LC_TIME+set}" != set; } || - { LC_TIME=C; export LC_TIME; } -(set +x; test -n "`(LC_CTYPE=C; export LC_CTYPE) 2>&1`") && - { $as_unset LC_CTYPE || test "${LC_CTYPE+set}" != set; } || - { LC_CTYPE=C; export LC_CTYPE; } -(set +x; test -n "`(LANGUAGE=C; export LANGUAGE) 2>&1`") && - { $as_unset LANGUAGE || test "${LANGUAGE+set}" != set; } || - { LANGUAGE=C; export LANGUAGE; } -(set +x; test -n "`(LC_COLLATE=C; export LC_COLLATE) 2>&1`") && - { $as_unset LC_COLLATE || test "${LC_COLLATE+set}" != set; } || - { LC_COLLATE=C; export LC_COLLATE; } -(set +x; test -n "`(LC_NUMERIC=C; export LC_NUMERIC) 2>&1`") && - { $as_unset LC_NUMERIC || test "${LC_NUMERIC+set}" != set; } || - { LC_NUMERIC=C; export LC_NUMERIC; } -(set +x; test -n "`(LC_MESSAGES=C; export LC_MESSAGES) 2>&1`") && - { $as_unset LC_MESSAGES || test "${LC_MESSAGES+set}" != set; } || - { LC_MESSAGES=C; export LC_MESSAGES; } - - -# Name of the executable. -as_me=`(basename "$0") 2>/dev/null || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)$' \| \ - . : '\(.\)' 2>/dev/null || -echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } - /^X\/\(\/\/\)$/{ s//\1/; q; } - /^X\/\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - -# PATH needs CR, and LINENO needs CR and PATH. -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conftest.sh - echo "exit 0" >>conftest.sh - chmod +x conftest.sh - if (PATH=".;."; conftest.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conftest.sh -fi - - - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" || { - # Find who we are. Look in the path if we contain no path at all - # relative or not. - case $0 in - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break -done - - ;; - esac - # We did not find ourselves, most probably we were run as `sh COMMAND' - # in which case we are not to be found in the path. - if test "x$as_myself" = x; then - as_myself=$0 - fi - if test ! -f "$as_myself"; then - { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 -echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} - { (exit 1); exit 1; }; } - fi - case $CONFIG_SHELL in - '') - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for as_base in sh bash ksh sh5; do - case $as_dir in - /*) - if ("$as_dir/$as_base" -c ' - as_lineno_1=$LINENO - as_lineno_2=$LINENO - as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` - test "x$as_lineno_1" != "x$as_lineno_2" && - test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then - CONFIG_SHELL=$as_dir/$as_base - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$0" ${1+"$@"} - fi;; - esac - done -done -;; - esac - - # Create $as_me.lineno as a copy of $as_myself, but with $LINENO - # uniformly replaced by the line number. The first 'sed' inserts a - # line-number line before each line; the second 'sed' does the real - # work. The second script uses 'N' to pair each line-number line - # with the numbered line, and appends trailing '-' during - # substitution so that $LINENO is not a special case at line end. - # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the - # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) - sed '=' <$as_myself | - sed ' - N - s,$,-, - : loop - s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, - t loop - s,-$,, - s,^['$as_cr_digits']*\n,, - ' >$as_me.lineno && - chmod +x $as_me.lineno || - { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 -echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} - { (exit 1); exit 1; }; } - - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensible to this). - . ./$as_me.lineno - # Exit status is that of the last command. - exit -} - - -case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in - *c*,-n*) ECHO_N= ECHO_C=' -' ECHO_T=' ' ;; - *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; - *) ECHO_N= ECHO_C='\c' ECHO_T= ;; -esac - -if expr a : '\(a\)' >/dev/null 2>&1; then - as_expr=expr -else - as_expr=false -fi - -rm -f conf$$ conf$$.exe conf$$.file -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - # We could just check for DJGPP; but this test a) works b) is more generic - # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). - if test -f conf$$.exe; then - # Don't use ln at all; we don't have any links - as_ln_s='cp -p' - else - as_ln_s='ln -s' - fi -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln -else - as_ln_s='cp -p' -fi -rm -f conf$$ conf$$.exe conf$$.file - -as_executable_p="test -f" - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" - - -# IFS -# We need space, tab and new line, in precisely that order. -as_nl=' -' -IFS=" $as_nl" - -# CDPATH. -$as_unset CDPATH || test "${CDPATH+set}" != set || { CDPATH=$PATH_SEPARATOR; export CDPATH; } - -exec 6>&1 - -# Open the log real soon, to keep \$[0] and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. Logging --version etc. is OK. -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX -} >&5 -cat >&5 <<_CSEOF - -This file was extended by PostgreSQL $as_me 7.3devel, which was -generated by GNU Autoconf 2.53. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -_CSEOF -echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 -echo >&5 -_ACEOF - -# Files that config.status was made for. -if test -n "$ac_config_files"; then - echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_headers"; then - echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_links"; then - echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS -fi - -if test -n "$ac_config_commands"; then - echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS -fi - -cat >>$CONFIG_STATUS <<\_ACEOF - -ac_cs_usage="\ -\`$as_me' instantiates files from templates according to the -current configuration. - -Usage: $0 [OPTIONS] [FILE]... - - -h, --help print this help, then exit - -V, --version print version number, then exit - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Configuration links: -$config_links - -Report bugs to ." -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF -ac_cs_version="\\ -PostgreSQL config.status 7.3devel -configured by $0, generated by GNU Autoconf 2.53, - with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" - -Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." -srcdir=$srcdir -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF -# If no file are specified by the user, then we need to provide default -# value. By we need to know if files were specified by the user. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=*) - ac_option=`expr "x$1" : 'x\([^=]*\)='` - ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` - shift - set dummy "$ac_option" "$ac_optarg" ${1+"$@"} - shift - ;; - -*);; - *) # This is not an option, so the user has probably given explicit - # arguments. - ac_need_defaults=false;; - esac - - case $1 in - # Handling of the options. -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion" - exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;; -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF - --version | --vers* | -V ) - echo "$ac_cs_version"; exit 0 ;; - --he | --h) - # Conflict between --help and --header - { { echo "$as_me:$LINENO: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: ambiguous option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; };; - --help | --hel | -h ) - echo "$ac_cs_usage"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - shift - CONFIG_FILES="$CONFIG_FILES $1" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - shift - CONFIG_HEADERS="$CONFIG_HEADERS $1" - ac_need_defaults=false;; - - # This is an error. - -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&5 -echo "$as_me: error: unrecognized option: $1 -Try \`$0 --help' for more information." >&2;} - { (exit 1); exit 1; }; } ;; - - *) ac_config_targets="$ac_config_targets $1" ;; - - esac - shift -done - -_ACEOF - - - - - -cat >>$CONFIG_STATUS <<\_ACEOF -for ac_config_target in $ac_config_targets -do - case "$ac_config_target" in - # Handling of arguments. - "GNUmakefile" ) CONFIG_FILES="$CONFIG_FILES GNUmakefile" ;; - "src/Makefile.global" ) CONFIG_FILES="$CONFIG_FILES src/Makefile.global" ;; - "src/backend/port/tas.s" ) CONFIG_LINKS="$CONFIG_LINKS src/backend/port/tas.s:src/backend/port/tas/${tas_file}" ;; - "src/backend/port/dynloader.c" ) CONFIG_LINKS="$CONFIG_LINKS src/backend/port/dynloader.c:src/backend/port/dynloader/${template}.c" ;; - "src/backend/port/pg_sema.c" ) CONFIG_LINKS="$CONFIG_LINKS src/backend/port/pg_sema.c:${SEMA_IMPLEMENTATION}" ;; - "src/backend/port/pg_shmem.c" ) CONFIG_LINKS="$CONFIG_LINKS src/backend/port/pg_shmem.c:${SHMEM_IMPLEMENTATION}" ;; - "src/include/dynloader.h" ) CONFIG_LINKS="$CONFIG_LINKS src/include/dynloader.h:src/backend/port/dynloader/${template}.h" ;; - "src/include/pg_config_os.h" ) CONFIG_LINKS="$CONFIG_LINKS src/include/pg_config_os.h:src/include/port/${template}.h" ;; - "src/Makefile.port" ) CONFIG_LINKS="$CONFIG_LINKS src/Makefile.port:src/makefiles/Makefile.${template}" ;; - "src/include/pg_config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS src/include/pg_config.h" ;; - *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -echo "$as_me: error: invalid argument: $ac_config_target" >&2;} - { (exit 1); exit 1; }; };; - esac -done - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links -fi - -# Create a temporary directory, and hook for its removal unless debugging. -$debug || -{ - trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 -} - -# Create a (secure) tmp directory for tmp files. -: ${TMPDIR=/tmp} -{ - tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=$TMPDIR/cs$$-$RANDOM - (umask 077 && mkdir $tmp) -} || -{ - echo "$me: cannot create a temporary directory in $TMPDIR" >&2 - { (exit 1); exit 1; } -} - -_ACEOF - -cat >>$CONFIG_STATUS <<_ACEOF - -# -# CONFIG_FILES section. -# - -# No need to generate the scripts if there are no CONFIG_FILES. -# This happens for instance when ./config.status config.h -if test -n "\$CONFIG_FILES"; then - # Protect against being on the right side of a sed subst in config.status. - sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; - s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF -s,@SHELL@,$SHELL,;t t -s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t -s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t -s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t -s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t -s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t -s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t -s,@exec_prefix@,$exec_prefix,;t t -s,@prefix@,$prefix,;t t -s,@program_transform_name@,$program_transform_name,;t t -s,@bindir@,$bindir,;t t -s,@sbindir@,$sbindir,;t t -s,@libexecdir@,$libexecdir,;t t -s,@datadir@,$datadir,;t t -s,@sysconfdir@,$sysconfdir,;t t -s,@sharedstatedir@,$sharedstatedir,;t t -s,@localstatedir@,$localstatedir,;t t -s,@libdir@,$libdir,;t t -s,@includedir@,$includedir,;t t -s,@oldincludedir@,$oldincludedir,;t t -s,@infodir@,$infodir,;t t -s,@mandir@,$mandir,;t t -s,@build_alias@,$build_alias,;t t -s,@host_alias@,$host_alias,;t t -s,@target_alias@,$target_alias,;t t -s,@DEFS@,$DEFS,;t t -s,@ECHO_C@,$ECHO_C,;t t -s,@ECHO_N@,$ECHO_N,;t t -s,@ECHO_T@,$ECHO_T,;t t -s,@LIBS@,$LIBS,;t t -s,@docdir@,$docdir,;t t -s,@configure_args@,$configure_args,;t t -s,@build@,$build,;t t -s,@build_cpu@,$build_cpu,;t t -s,@build_vendor@,$build_vendor,;t t -s,@build_os@,$build_os,;t t -s,@host@,$host,;t t -s,@host_cpu@,$host_cpu,;t t -s,@host_vendor@,$host_vendor,;t t -s,@host_os@,$host_os,;t t -s,@PORTNAME@,$PORTNAME,;t t -s,@TAS@,$TAS,;t t -s,@MULTIBYTE@,$MULTIBYTE,;t t -s,@enable_nls@,$enable_nls,;t t -s,@WANTED_LANGUAGES@,$WANTED_LANGUAGES,;t t -s,@default_port@,$default_port,;t t -s,@enable_shared@,$enable_shared,;t t -s,@enable_rpath@,$enable_rpath,;t t -s,@enable_debug@,$enable_debug,;t t -s,@CC@,$CC,;t t -s,@CFLAGS@,$CFLAGS,;t t -s,@LDFLAGS@,$LDFLAGS,;t t -s,@CPPFLAGS@,$CPPFLAGS,;t t -s,@ac_ct_CC@,$ac_ct_CC,;t t -s,@EXEEXT@,$EXEEXT,;t t -s,@OBJEXT@,$OBJEXT,;t t -s,@CPP@,$CPP,;t t -s,@GCC@,$GCC,;t t -s,@autodepend@,$autodepend,;t t -s,@INCLUDES@,$INCLUDES,;t t -s,@with_tcl@,$with_tcl,;t t -s,@with_tk@,$with_tk,;t t -s,@with_perl@,$with_perl,;t t -s,@with_python@,$with_python,;t t -s,@ANT@,$ANT,;t t -s,@with_java@,$with_java,;t t -s,@with_krb4@,$with_krb4,;t t -s,@with_krb5@,$with_krb5,;t t -s,@krb_srvtab@,$krb_srvtab,;t t -s,@with_pam@,$with_pam,;t t -s,@with_openssl@,$with_openssl,;t t -s,@enable_odbc@,$enable_odbc,;t t -s,@with_unixodbc@,$with_unixodbc,;t t -s,@with_iodbc@,$with_iodbc,;t t -s,@odbcinst_ini_dir@,$odbcinst_ini_dir,;t t -s,@ELF_SYS@,$ELF_SYS,;t t -s,@CXX@,$CXX,;t t -s,@CXXFLAGS@,$CXXFLAGS,;t t -s,@ac_ct_CXX@,$ac_ct_CXX,;t t -s,@CXXCPP@,$CXXCPP,;t t -s,@with_CXX@,$with_CXX,;t t -s,@GXX@,$GXX,;t t -s,@AWK@,$AWK,;t t -s,@FLEX@,$FLEX,;t t -s,@FLEXFLAGS@,$FLEXFLAGS,;t t -s,@LN_S@,$LN_S,;t t -s,@LD@,$LD,;t t -s,@with_gnu_ld@,$with_gnu_ld,;t t -s,@ld_R_works@,$ld_R_works,;t t -s,@RANLIB@,$RANLIB,;t t -s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t -s,@LORDER@,$LORDER,;t t -s,@TAR@,$TAR,;t t -s,@STRIP@,$STRIP,;t t -s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t -s,@STRIP_STATIC_LIB@,$STRIP_STATIC_LIB,;t t -s,@STRIP_SHARED_LIB@,$STRIP_SHARED_LIB,;t t -s,@YACC@,$YACC,;t t -s,@YFLAGS@,$YFLAGS,;t t -s,@WISH@,$WISH,;t t -s,@PERL@,$PERL,;t t -s,@perl_installsitearch@,$perl_installsitearch,;t t -s,@perl_installman3dir@,$perl_installman3dir,;t t -s,@perl_archlibexp@,$perl_archlibexp,;t t -s,@perl_privlibexp@,$perl_privlibexp,;t t -s,@perl_useshrplib@,$perl_useshrplib,;t t -s,@perl_man3ext@,$perl_man3ext,;t t -s,@perl_embed_ldflags@,$perl_embed_ldflags,;t t -s,@PYTHON@,$PYTHON,;t t -s,@python_version@,$python_version,;t t -s,@python_prefix@,$python_prefix,;t t -s,@python_execprefix@,$python_execprefix,;t t -s,@python_configdir@,$python_configdir,;t t -s,@python_moduledir@,$python_moduledir,;t t -s,@python_moduleexecdir@,$python_moduleexecdir,;t t -s,@python_includespec@,$python_includespec,;t t -s,@python_libspec@,$python_libspec,;t t -s,@MEMCMP@,$MEMCMP,;t t -s,@SNPRINTF@,$SNPRINTF,;t t -s,@ISINF@,$ISINF,;t t -s,@GETRUSAGE@,$GETRUSAGE,;t t -s,@SRANDOM@,$SRANDOM,;t t -s,@GETHOSTNAME@,$GETHOSTNAME,;t t -s,@MISSING_RANDOM@,$MISSING_RANDOM,;t t -s,@INET_ATON@,$INET_ATON,;t t -s,@STRERROR@,$STRERROR,;t t -s,@STRDUP@,$STRDUP,;t t -s,@STRTOL@,$STRTOL,;t t -s,@STRTOUL@,$STRTOUL,;t t -s,@STRCASECMP@,$STRCASECMP,;t t -s,@HPUXMATHLIB@,$HPUXMATHLIB,;t t -s,@HAVE_POSIX_SIGNALS@,$HAVE_POSIX_SIGNALS,;t t -s,@MSGFMT@,$MSGFMT,;t t -s,@MSGMERGE@,$MSGMERGE,;t t -s,@XGETTEXT@,$XGETTEXT,;t t -s,@localedir@,$localedir,;t t -s,@TCLSH@,$TCLSH,;t t -s,@TCL_CONFIG_SH@,$TCL_CONFIG_SH,;t t -s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t -s,@TCL_LIBS@,$TCL_LIBS,;t t -s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t -s,@TCL_SHARED_BUILD@,$TCL_SHARED_BUILD,;t t -s,@TCL_SHLIB_LD_LIBS@,$TCL_SHLIB_LD_LIBS,;t t -s,@TK_CONFIG_SH@,$TK_CONFIG_SH,;t t -s,@TK_LIBS@,$TK_LIBS,;t t -s,@TK_LIB_SPEC@,$TK_LIB_SPEC,;t t -s,@TK_XINCLUDES@,$TK_XINCLUDES,;t t -s,@NSGMLS@,$NSGMLS,;t t -s,@JADE@,$JADE,;t t -s,@have_docbook@,$have_docbook,;t t -s,@DOCBOOKSTYLE@,$DOCBOOKSTYLE,;t t -s,@COLLATEINDEX@,$COLLATEINDEX,;t t -s,@SGMLSPL@,$SGMLSPL,;t t -s,@vpath_build@,$vpath_build,;t t -CEOF - -_ACEOF - - cat >>$CONFIG_STATUS <<\_ACEOF - # Split the substitutions into bite-sized pieces for seds with - # small command number limits, like on Digital OSF/1 and HP-UX. - ac_max_sed_lines=48 - ac_sed_frag=1 # Number of current file. - ac_beg=1 # First line for current file. - ac_end=$ac_max_sed_lines # Line after last line for current file. - ac_more_lines=: - ac_sed_cmds= - while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - else - sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag - fi - if test ! -s $tmp/subs.frag; then - ac_more_lines=false - else - # The purpose of the label and of the branching condition is to - # speed up the sed processing (if there are no `@' at all, there - # is no need to browse any of the substitutions). - # These are the two extra sed commands mentioned above. - (echo ':t - /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" - else - ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" - fi - ac_sed_frag=`expr $ac_sed_frag + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_lines` - fi - done - if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat - fi -fi # test -n "$CONFIG_FILES" - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case $ac_file in - - | *:- | *:-:* ) # input from stdin - cat >$tmp/stdin - ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - * ) ac_file_in=$ac_file.in ;; - esac - - # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. - ac_dir=`(dirname "$ac_file") 2>/dev/null || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { case "$ac_dir" in - [\\/]* | ?:[\\/]* ) as_incr_dir=;; - *) as_incr_dir=.;; -esac -as_dummy="$ac_dir" -for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do - case $as_mkdir_dir in - # Skip DOS drivespec - ?:) as_incr_dir=$as_mkdir_dir ;; - *) - as_incr_dir=$as_incr_dir/$as_mkdir_dir - test -d "$as_incr_dir" || - mkdir "$as_incr_dir" || - { { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create \"$ac_dir\"" >&2;} - { (exit 1); exit 1; }; } - ;; - esac -done; } - - ac_builddir=. - -if test "$ac_dir" != .; then - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac -# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be -# absolute. -ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` -ac_abs_top_builddir=`cd "$ac_dir" && cd $ac_top_builddir && pwd` -ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` -ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` - - - - if test x"$ac_file" != x-; then - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - rm -f "$ac_file" - fi - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - if test x"$ac_file" = x-; then - configure_input= - else - configure_input="$ac_file. " - fi - configure_input=$configure_input"Generated from `echo $ac_file_in | - sed 's,.*/,,'` by configure." - - # First look for the input files in the build tree, otherwise in the - # src tree. - ac_file_inputs=`IFS=: - for f in $ac_file_in; do - case $f in - -) echo $tmp/stdin ;; - [\\/$]*) - # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - echo $f;; - *) # Relative - if test -f "$f"; then - # Build tree - echo $f - elif test -f "$srcdir/$f"; then - # Source tree - echo $srcdir/$f - else - # /dev/null tree - { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - fi;; - esac - done` || { (exit 1); exit 1; } -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF - sed "$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s,@configure_input@,$configure_input,;t t -s,@srcdir@,$ac_srcdir,;t t -s,@abs_srcdir@,$ac_abs_srcdir,;t t -s,@top_srcdir@,$ac_top_srcdir,;t t -s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t -s,@builddir@,$ac_builddir,;t t -s,@abs_builddir@,$ac_abs_builddir,;t t -s,@top_builddir@,$ac_top_builddir,;t t -s,@abs_top_builddir@,$ac_abs_top_builddir,;t t -" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out - rm -f $tmp/stdin - if test x"$ac_file" != x-; then - mv $tmp/out $ac_file - else - cat $tmp/out - rm -f $tmp/out - fi - -done -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF - -# -# CONFIG_HEADER section. -# - -# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where -# NAME is the cpp macro being defined and VALUE is the value it is being given. -# -# ac_d sets the value in "#define NAME VALUE" lines. -ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' -ac_dB='[ ].*$,\1#\2' -ac_dC=' ' -ac_dD=',;t' -# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". -ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' -ac_uB='$,\1#\2define\3' -ac_uC=' ' -ac_uD=',;t' - -for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case $ac_file in - - | *:- | *:-:* ) # input from stdin - cat >$tmp/stdin - ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` - ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; - * ) ac_file_in=$ac_file.in ;; - esac - - test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} - - # First look for the input files in the build tree, otherwise in the - # src tree. - ac_file_inputs=`IFS=: - for f in $ac_file_in; do - case $f in - -) echo $tmp/stdin ;; - [\\/$]*) - # Absolute (can't be DOS-style, as IFS=:) - test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - echo $f;; - *) # Relative - if test -f "$f"; then - # Build tree - echo $f - elif test -f "$srcdir/$f"; then - # Source tree - echo $srcdir/$f - else - # /dev/null tree - { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 -echo "$as_me: error: cannot find input file: $f" >&2;} - { (exit 1); exit 1; }; } - fi;; - esac - done` || { (exit 1); exit 1; } - # Remove the trailing spaces. - sed 's/[ ]*$//' $ac_file_inputs >$tmp/in - -_ACEOF - -# Transform confdefs.h into two sed scripts, `conftest.defines' and -# `conftest.undefs', that substitutes the proper values into -# config.h.in to produce config.h. The first handles `#define' -# templates, and the second `#undef' templates. -# And first: Protect against being on the right side of a sed subst in -# config.status. Protect against being in an unquoted here document -# in config.status. -rm -f conftest.defines conftest.undefs -# Using a here document instead of a string reduces the quoting nightmare. -# Putting comments in sed scripts is not portable. -# -# `end' is used to avoid that the second main sed command (meant for -# 0-ary CPP macros) applies to n-ary macro definitions. -# See the Autoconf documentation for `clear'. -cat >confdef2sed.sed <<\_ACEOF -s/[\\&,]/\\&/g -s,[\\$`],\\&,g -t clear -: clear -s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp -t end -s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp -: end -_ACEOF -# If some macros were called several times there might be several times -# the same #defines, which is useless. Nevertheless, we may not want to -# sort them, since we want the *last* AC-DEFINE to be honored. -uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines -sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs -rm -f confdef2sed.sed - -# This sed command replaces #undef with comments. This is necessary, for -# example, in the case of _POSIX_SOURCE, which is predefined and required -# on some systems where configure will not decide to define it. -cat >>conftest.undefs <<\_ACEOF -s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, -_ACEOF - -# Break up conftest.defines because some shells have a limit on the size -# of here documents, and old seds have small limits too (100 cmds). -echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS -echo ' if egrep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS -echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS -echo ' :' >>$CONFIG_STATUS -rm -f conftest.tail -while grep . conftest.defines >/dev/null -do - # Write a limited-size here document to $tmp/defines.sed. - echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS - # Speed up: don't consider the non `#define' lines. - echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS - # Work around the forget-to-reset-the-flag bug. - echo 't clr' >>$CONFIG_STATUS - echo ': clr' >>$CONFIG_STATUS - sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS - echo 'CEOF - sed -f $tmp/defines.sed $tmp/in >$tmp/out - rm -f $tmp/in - mv $tmp/out $tmp/in -' >>$CONFIG_STATUS - sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail - rm -f conftest.defines - mv conftest.tail conftest.defines -done -rm -f conftest.defines -echo ' fi # egrep' >>$CONFIG_STATUS -echo >>$CONFIG_STATUS - -# Break up conftest.undefs because some shells have a limit on the size -# of here documents, and old seds have small limits too (100 cmds). -echo ' # Handle all the #undef templates' >>$CONFIG_STATUS -rm -f conftest.tail -while grep . conftest.undefs >/dev/null -do - # Write a limited-size here document to $tmp/undefs.sed. - echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS - # Speed up: don't consider the non `#undef' - echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS - # Work around the forget-to-reset-the-flag bug. - echo 't clr' >>$CONFIG_STATUS - echo ': clr' >>$CONFIG_STATUS - sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS - echo 'CEOF - sed -f $tmp/undefs.sed $tmp/in >$tmp/out - rm -f $tmp/in - mv $tmp/out $tmp/in -' >>$CONFIG_STATUS - sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail - rm -f conftest.undefs - mv conftest.tail conftest.undefs -done -rm -f conftest.undefs - -cat >>$CONFIG_STATUS <<\_ACEOF - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - if test x"$ac_file" = x-; then - echo "/* Generated by configure. */" >$tmp/config.h - else - echo "/* $ac_file. Generated by configure. */" >$tmp/config.h - fi - cat $tmp/in >>$tmp/config.h - rm -f $tmp/in - if test x"$ac_file" != x-; then - if cmp -s $ac_file $tmp/config.h 2>/dev/null; then - { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 -echo "$as_me: $ac_file is unchanged" >&6;} - else - ac_dir=`(dirname "$ac_file") 2>/dev/null || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { case "$ac_dir" in - [\\/]* | ?:[\\/]* ) as_incr_dir=;; - *) as_incr_dir=.;; -esac -as_dummy="$ac_dir" -for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do - case $as_mkdir_dir in - # Skip DOS drivespec - ?:) as_incr_dir=$as_mkdir_dir ;; - *) - as_incr_dir=$as_incr_dir/$as_mkdir_dir - test -d "$as_incr_dir" || - mkdir "$as_incr_dir" || - { { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5 -echo "$as_me: error: cannot create \"$ac_dir\"" >&2;} - { (exit 1); exit 1; }; } - ;; - esac -done; } - - rm -f $ac_file - mv $tmp/config.h $ac_file - fi - else - cat $tmp/config.h - rm -f $tmp/config.h - fi - # Run the commands associated with the file. - case $ac_file in - src/include/pg_config.h ) -# Update timestamp for pg_config.h (see Makefile.global) -echo >src/include/stamp-h - ;; - esac -done -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF - -# -# CONFIG_LINKS section. -# - -for ac_file in : $CONFIG_LINKS; do test "x$ac_file" = x: && continue - ac_dest=`echo "$ac_file" | sed 's,:.*,,'` - ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` - - { echo "$as_me:$LINENO: linking $srcdir/$ac_source to $ac_dest" >&5 -echo "$as_me: linking $srcdir/$ac_source to $ac_dest" >&6;} - - if test ! -r $srcdir/$ac_source; then - { { echo "$as_me:$LINENO: error: $srcdir/$ac_source: file not found" >&5 -echo "$as_me: error: $srcdir/$ac_source: file not found" >&2;} - { (exit 1); exit 1; }; } - fi - rm -f $ac_dest - - # Make relative symlinks. - ac_dest_dir=`(dirname "$ac_dest") 2>/dev/null || -$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_dest" : 'X\(//\)[^/]' \| \ - X"$ac_dest" : 'X\(//\)$' \| \ - X"$ac_dest" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || -echo X"$ac_dest" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } - /^X\(\/\/\)[^/].*/{ s//\1/; q; } - /^X\(\/\/\)$/{ s//\1/; q; } - /^X\(\/\).*/{ s//\1/; q; } - s/.*/./; q'` - { case "$ac_dest_dir" in - [\\/]* | ?:[\\/]* ) as_incr_dir=;; - *) as_incr_dir=.;; -esac -as_dummy="$ac_dest_dir" -for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do - case $as_mkdir_dir in - # Skip DOS drivespec - ?:) as_incr_dir=$as_mkdir_dir ;; - *) - as_incr_dir=$as_incr_dir/$as_mkdir_dir - test -d "$as_incr_dir" || - mkdir "$as_incr_dir" || - { { echo "$as_me:$LINENO: error: cannot create \"$ac_dest_dir\"" >&5 -echo "$as_me: error: cannot create \"$ac_dest_dir\"" >&2;} - { (exit 1); exit 1; }; } - ;; - esac -done; } - - ac_builddir=. - -if test "$ac_dest_dir" != .; then - ac_dir_suffix=/`echo "$ac_dest_dir" | sed 's,^\.[\\/],,'` - # A "../" for each directory in $ac_dir_suffix. - ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` -else - ac_dir_suffix= ac_top_builddir= -fi - -case $srcdir in - .) # No --srcdir option. We are building in place. - ac_srcdir=. - if test -z "$ac_top_builddir"; then - ac_top_srcdir=. - else - ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` - fi ;; - [\\/]* | ?:[\\/]* ) # Absolute path. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir ;; - *) # Relative path. - ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_builddir$srcdir ;; -esac -# Don't blindly perform a `cd "$ac_dest_dir"/$ac_foo && pwd` since $ac_foo can be -# absolute. -ac_abs_builddir=`cd "$ac_dest_dir" && cd $ac_builddir && pwd` -ac_abs_top_builddir=`cd "$ac_dest_dir" && cd $ac_top_builddir && pwd` -ac_abs_srcdir=`cd "$ac_dest_dir" && cd $ac_srcdir && pwd` -ac_abs_top_srcdir=`cd "$ac_dest_dir" && cd $ac_top_srcdir && pwd` - - - case $srcdir in - [\\/$]* | ?:[\\/]* ) ac_rel_source=$srcdir/$ac_source ;; - *) ac_rel_source=$ac_top_builddir$srcdir/$ac_source ;; - esac - - # Make a symlink if possible; otherwise try a hard link. - ln -s $ac_rel_source $ac_dest 2>/dev/null || - ln $srcdir/$ac_source $ac_dest || - { { echo "$as_me:$LINENO: error: cannot link $ac_dest to $srcdir/$ac_source" >&5 -echo "$as_me: error: cannot link $ac_dest to $srcdir/$ac_source" >&2;} - { (exit 1); exit 1; }; } -done -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF - -{ (exit 0); exit 0; } -_ACEOF -chmod +x $CONFIG_STATUS -ac_clean_files=$ac_clean_files_save - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - exec 5>/dev/null - $SHELL $CONFIG_STATUS || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || { (exit 1); exit 1; } -fi - diff --git a/configure.in b/configure.in deleted file mode 100644 index 0accbce508..0000000000 --- a/configure.in +++ /dev/null @@ -1,1266 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. -dnl $Header: /cvsroot/pgsql/configure.in,v 1.186 2002/05/28 16:57:53 petere Exp $ -dnl -dnl Developers, please strive to achieve this order: -dnl -dnl 0. Initialization and options processing -dnl 1. Programs -dnl 2. Libraries -dnl 3. Header files -dnl 4. Types -dnl 5. Structures -dnl 6. Compiler characteristics -dnl 7. Functions, global variables -dnl 8. System services -dnl -dnl Read the Autoconf manual for details. -dnl -m4_pattern_forbid(^PGAC_)dnl to catch undefined macros -dnl -dnl The GNU folks apparently haven't heard that some people don't use -dnl Texinfo. Use this sorcery to use "docdir" instead of "infodir". -m4_define([info], [doc]) -m4_define([infodir], [docdir]) -AC_INIT([PostgreSQL], [7.3devel], [pgsql-bugs@postgresql.org]) -m4_undefine([infodir]) -m4_undefine([info]) -AC_SUBST(docdir) - -AC_PREREQ(2.53) -AC_COPYRIGHT([Copyright 2002 PostgreSQL Global Development Group]) -AC_CONFIG_SRCDIR([src/backend/access/common/heaptuple.c]) -AC_CONFIG_AUX_DIR(config) -AC_PREFIX_DEFAULT(/usr/local/pgsql) -AC_SUBST(configure_args, [$ac_configure_args]) - -AC_DEFINE_UNQUOTED(PG_VERSION, "$PACKAGE_VERSION", [PostgreSQL version]) - -AC_CANONICAL_HOST - -template= -AC_MSG_CHECKING([which template to use]) - -PGAC_ARG_REQ(with, template, [], -[ - case $withval in - list) echo; ls "$srcdir/src/template"; exit;; - *) if test -f "$srcdir/src/template/$with_template" ; then - template=$withval - else - AC_MSG_ERROR(['$withval' is not a valid template name. Use 'list' for a list.]) - fi;; - esac -], -[ - # --with-template not given - -case $host_os in - aix*) template=aix ;; - beos*) template=beos ;; - bsdi*) template=bsdi ;; - cygwin*) template=win ;; - darwin*) template=darwin ;; - dgux*) template=dgux ;; - freebsd*) template=freebsd ;; - hpux*) template=hpux ;; - irix*) template=irix5 ;; - linux*) template=linux ;; - netbsd*) template=netbsd ;; -nextstep*) template=nextstep ;; - openbsd*) template=openbsd ;; - osf*) template=osf ;; - qnx*) template=qnx4 ;; - sco*) template=sco ;; - solaris*) template=solaris ;; - sunos*) template=sunos4 ;; - sysv4.2*) - case $host_vendor in - univel) template=univel ;; - esac ;; - sysv4*) template=svr4 ;; - sysv5*) template=unixware ;; - ultrix*) template=ultrix4 ;; -esac - - if test x"$template" = x"" ; then - AC_MSG_ERROR([[ -******************************************************************* -PostgreSQL has apparently not been ported to your platform yet. -To try a manual configuration, look into the src/template directory -for a similar platform and use the '--with-template=' option. - -Please also contact to see about -rectifying this. Include the above 'checking host system type...' -line. -******************************************************************* -]]) - fi - -]) - -AC_MSG_RESULT([$template]) - -PORTNAME=$template -AC_SUBST(PORTNAME) - -# Pick right test-and-set (TAS) code. Most platforms have inline -# assembler code in src/include/storage/s_lock.h, so we just use -# a dummy file here. -case $host in - *-*-hpux*) need_tas=yes; tas_file=hpux.s ;; - sparc-*-solaris*) need_tas=yes; tas_file=solaris_sparc.s ;; - i?86-*-solaris*) need_tas=yes; tas_file=solaris_i386.s ;; - *) need_tas=no; tas_file=dummy.s ;; -esac -AC_CONFIG_LINKS([src/backend/port/tas.s:src/backend/port/tas/${tas_file}]) - -if test "$need_tas" = yes ; then - TAS=tas.o -fi -AC_SUBST(TAS) - - - -## -## Command line options -## - - -# -# Add non-standard directories to the include path -# -PGAC_ARG_REQ(with, includes, [ --with-includes=DIRS look for additional header files in DIRS]) - - -# -# Add non-standard directories to the library search path -# -PGAC_ARG_REQ(with, libraries, [ --with-libraries=DIRS look for additional libraries in DIRS], - [LIBRARY_DIRS=$withval]) - -PGAC_ARG_REQ(with, libs, [ --with-libs=DIRS alternative spelling of --with-libraries], - [LIBRARY_DIRS=$withval]) - - -# -# 64-bit integer date/time storage (--enable-integer-datetimes) -# -AC_MSG_CHECKING([whether to build with 64-bit integer date/time support]) -PGAC_ARG_BOOL(enable, integer-datetimes, no, [ --enable-integer-datetimes enable 64-bit integer date/time support], - [AC_DEFINE([USE_INTEGER_DATETIMES], 1, - [Set to 1 if you want integer date/time support (--enable-integer-datetimes)])]) -AC_MSG_RESULT([$enable_integer_datetimes]) - - -# Character set recode (--enable-recode) -# -AC_MSG_CHECKING([whether to build with recode support]) -PGAC_ARG_BOOL(enable, recode, no, [ --enable-recode enable character set recode support], - [AC_DEFINE([CYR_RECODE], 1, - [Set to 1 if you want cyrillic recode support (--enable-recode)])]) -AC_MSG_RESULT([$enable_recode]) - - -# -# Multibyte support -# -MULTIBYTE=SQL_ASCII -AC_DEFINE(MULTIBYTE, 1, [Set to 1 if you want to use multibyte characters (--enable-multibyte)]) -AC_SUBST(MULTIBYTE) - -# -# NLS -# -AC_MSG_CHECKING([whether NLS is wanted]) -PGAC_ARG_OPTARG(enable, nls, - [[ --enable-nls[=LANGUAGES] enable Native Language Support]], - [], - [WANTED_LANGUAGES=$enableval], - [AC_DEFINE(ENABLE_NLS, 1, - [Define to 1 if you want National Language Support (--enable-nls)])]) -AC_MSG_RESULT([$enable_nls]) -AC_SUBST(enable_nls) -AC_SUBST(WANTED_LANGUAGES) - -# -# Default port number (--with-pgport), default 5432 -# -AC_MSG_CHECKING([for default port number]) -PGAC_ARG_REQ(with, pgport, [ --with-pgport=PORTNUM change default port number [5432]], - [default_port=$withval], - [default_port=5432]) -AC_MSG_RESULT([$default_port]) -# Need both of these because some places want an integer and some a string -AC_DEFINE_UNQUOTED(DEF_PGPORT, ${default_port}, -[The default TCP port number on which the server listens and to which -clients will try to connect to. This can be overridden at run-time, -but it's convenient if your clients have the right default compiled in. -(--with-pgport=PORTNUM)]) -AC_DEFINE_UNQUOTED(DEF_PGPORT_STR, "${default_port}", - [Default TCP port number as string constant]) -AC_SUBST(default_port) - -# -# Maximum number of allowed connections (--with-maxbackends), default 32 -# -AC_MSG_CHECKING([for default soft limit on number of connections]) -PGAC_ARG_REQ(with, maxbackends, [ --with-maxbackends=N set default maximum number of connections [32]], - [], - [with_maxbackends=32]) -AC_MSG_RESULT([$with_maxbackends]) -AC_DEFINE_UNQUOTED([DEF_MAXBACKENDS], [$with_maxbackends], - [The default soft limit on the number of concurrent connections, i.e., the default for the postmaster -N switch (--with-maxbackends)]) - - -# -# Option to disable shared libraries -# -PGAC_ARG_BOOL(enable, shared, yes, - [ --disable-shared do not build shared libraries]) -AC_SUBST(enable_shared) - -# -# '-rpath'-like feature can be disabled -# -PGAC_ARG_BOOL(enable, rpath, yes, - [ --disable-rpath do not embed shared library search path in executables]) -AC_SUBST(enable_rpath) - - -# -# --enable-debug adds -g to compiler flags -# -PGAC_ARG_BOOL(enable, debug, no, - [ --enable-debug build with debugging symbols (-g)]) -AC_SUBST(enable_debug) - -# -# C compiler -# - -# For historical reasons you can also use --with-CC to specify the C compiler -# to use, although the standard way to do this is to set the CC environment -# variable. -PGAC_ARG_REQ(with, CC, [], [CC=$with_CC]) - -case $template in - aix) pgac_cc_list="gcc xlc";; - irix) pgac_cc_list="cc";; # no gcc - *) pgac_cc_list="gcc cc";; -esac - -AC_PROG_CC([$pgac_cc_list]) -# Read the template -. "$srcdir/src/template/$template" || exit - -if test "$ac_env_CFLAGS_set" = set; then - CFLAGS=$ac_env_CFLAGS_value -fi -if test "$enable_debug" = yes && test "$ac_cv_prog_cc_g" = yes; then - CFLAGS="$CFLAGS -g" -fi -AC_MSG_NOTICE([using CFLAGS=$CFLAGS]) -# Check if the compiler still works with the template settings -AC_MSG_CHECKING([whether the C compiler still works]) -AC_TRY_LINK([], [return 0;], - [AC_MSG_RESULT(yes)], - [AC_MSG_RESULT(no) - AC_MSG_ERROR([cannot proceed])]) -AC_PROG_CPP -AC_SUBST(GCC) - -# Create compiler version string -if test x"$GCC" = x"yes" ; then - cc_string="GCC `${CC} --version | sed q`" -else - cc_string=$CC -fi -AC_DEFINE_UNQUOTED(PG_VERSION_STR, ["PostgreSQL $PACKAGE_VERSION on $host, compiled by $cc_string"], [A canonical string containing the version number, platform, and C compiler]) - - -# -# Automatic dependency tracking -# -PGAC_ARG_BOOL(enable, depend, no, [ --enable-depend turn on automatic dependency tracking], - [autodepend=yes]) -AC_SUBST(autodepend) - - -# -# Enable assert checks -# -PGAC_ARG_BOOL(enable, cassert, no, [ --enable-cassert enable assertion checks (for debugging)], - [AC_DEFINE([USE_ASSERT_CHECKING], 1, - [Define to 1 to build with assertion checks])]) - - -# -# Include directories -# -ac_save_IFS=$IFS -IFS="${IFS}:" -# SRCH_INC comes from the template file -for dir in $with_includes $SRCH_INC; do - if test -d "$dir"; then - INCLUDES="$INCLUDES -I$dir" - else - AC_MSG_WARN([*** Include directory $dir does not exist.]) - fi -done -IFS=$ac_save_IFS -AC_SUBST(INCLUDES) - - -# -# Library directories -# -ac_save_IFS=$IFS -IFS="${IFS}:" -# LIBRARY_DIRS comes from command line, SRCH_LIB from template file. -for dir in $LIBRARY_DIRS $SRCH_LIB; do - if test -d "$dir"; then - LIBDIRS="$LIBDIRS -L$dir" - else - AC_MSG_WARN([*** Library directory $dir does not exist.]) - fi -done -IFS=$ac_save_IFS - - -# -# Tcl/Tk -# -AC_MSG_CHECKING([whether to build with Tcl]) -PGAC_ARG_BOOL(with, tcl, no, [ --with-tcl build Tcl and Tk interfaces]) -AC_MSG_RESULT([$with_tcl]) -AC_SUBST([with_tcl]) - -# If Tcl is enabled (above) then Tk is also, unless the user disables it using --without-tk -AC_MSG_CHECKING([whether to build with Tk]) -if test "$with_tcl" = yes; then - PGAC_ARG_BOOL(with, tk, yes, [ --without-tk do not build Tk interfaces if Tcl is enabled]) -else - with_tk=no -fi -AC_MSG_RESULT([$with_tk]) -AC_SUBST([with_tk]) - - -# We see if the path to the Tcl/Tk configuration scripts is specified. -# This will override the use of tclsh to find the paths to search. - -PGAC_ARG_REQ(with, tclconfig, [ --with-tclconfig=DIR tclConfig.sh and tkConfig.sh are in DIR]) - -# We see if the path to the Tk configuration scripts is specified. -# This will override the use of tclsh to find the paths to search. - -PGAC_ARG_REQ(with, tkconfig, [ --with-tkconfig=DIR tkConfig.sh is in DIR]) - -# -# Optionally build Perl modules (Pg.pm and PL/Perl) -# -AC_MSG_CHECKING([whether to build Perl modules]) -PGAC_ARG_BOOL(with, perl, no, [ --with-perl build Perl interface and PL/Perl]) -AC_MSG_RESULT([$with_perl]) -AC_SUBST(with_perl) - -# -# Optionally build Python interface module -# -AC_MSG_CHECKING([whether to build Python modules]) -PGAC_ARG_BOOL(with, python, no, [ --with-python build Python interface module]) -AC_MSG_RESULT([$with_python]) -AC_SUBST(with_python) - -# -# Optionally build the Java/JDBC tools -# -AC_MSG_CHECKING([whether to build Java/JDBC tools]) -PGAC_ARG_BOOL(with, java, no, [ --with-java build JDBC interface and Java tools], -[AC_MSG_RESULT(yes) -PGAC_PATH_ANT -if test -z "$ANT"; then - AC_MSG_ERROR([Ant is required to build Java components]) -fi], -[AC_MSG_RESULT(no)]) -AC_SUBST(with_java) - -dnl A note on the Kerberos and OpenSSL options: -dnl -dnl The user can give an argument to the option in order the specify -dnl the base path of the respective installation (what he specified -dnl perhaps as --prefix). If no argument is given ($withval is "yes") -dnl then we take the path where the package installs by default. This -dnl way the user doesn't have to use redundant --with-includes and -dnl --with-libraries options, but he can still use them if the layout -dnl is non-standard. - -# -# Kerberos 4 -# -AC_MSG_CHECKING([whether to build with Kerberos 4 support]) -PGAC_ARG_OPTARG(with, krb4, [[ --with-krb4[=DIR] build with Kerberos 4 support [/usr/athena]]], - [krb4_prefix=/usr/athena], - [krb4_prefix=$withval], -[ - AC_MSG_RESULT(yes) - AC_DEFINE(KRB4, 1, [Define if you are building with Kerberos 4 support.]) - - if test -d "$krb4_prefix/include"; then - INCLUDES="$INCLUDES -I$krb4_prefix/include" - fi - if test -d "$krb4_prefix/lib"; then - LIBDIRS="$LIBDIRS -L$krb4_prefix/lib" - fi - - krb_srvtab="/etc/srvtab" -], -[AC_MSG_RESULT(no)]) - -AC_SUBST(with_krb4) - - -# -# Kerberos 5 -# -AC_MSG_CHECKING([whether to build with Kerberos 5 support]) -PGAC_ARG_OPTARG(with, krb5, [[ --with-krb5[=DIR] build with Kerberos 5 support [/usr/athena]]], - [krb5_prefix=/usr/athena], - [krb5_prefix=$withval], -[ - AC_MSG_RESULT([yes]) - AC_DEFINE(KRB5, 1, [Define if you are building with Kerberos 5 support.]) - - if test -d "$krb5_prefix/include"; then - INCLUDES="$INCLUDES -I$krb5_prefix/include" - fi - if test -d "$krb5_prefix/lib"; then - LIBDIRS="$LIBDIRS -L$krb5_prefix/lib" - fi - - krb_srvtab="FILE:\$(sysconfdir)/krb5.keytab" -], -[AC_MSG_RESULT(no)]) - -AC_SUBST(with_krb5) - - -# Using both Kerberos 4 and Kerberos 5 at the same time isn't going to work. -if test "$with_krb4" = yes && test "$with_krb5" = yes ; then - AC_MSG_ERROR([Kerberos 4 and Kerberos 5 support cannot be combined]) -fi - -AC_SUBST(krb_srvtab) - - -# -# Kerberos configuration parameters -# -PGAC_ARG_REQ(with, krb-srvnam, - [ --with-krb-srvnam=NAME name of the service principal in Kerberos [postgres]], - [], - [with_krb_srvnam="postgres"]) -AC_DEFINE_UNQUOTED([PG_KRB_SRVNAM], ["$with_krb_srvnam"], - [The name of the PostgreSQL service principal in Kerberos]) - - -# -# PAM -# -AC_MSG_CHECKING([whether to build with PAM support]) -PGAC_ARG_BOOL(with, pam, no, - [ --with-pam build with PAM support], - [AC_DEFINE([USE_PAM], 1, [Define to build with PAM support])]) -AC_MSG_RESULT([$with_pam]) -AC_SUBST(with_pam) - - -# -# OpenSSL -# -PGAC_ARG_OPTARG(with, openssl, - [[ --with-openssl[=DIR] build with OpenSSL support [/usr/local/ssl]]], - [openssl_prefix=/usr/local/ssl], - [openssl_prefix=$withval], -[ - AC_MSG_RESULT([building with OpenSSL support]) - AC_DEFINE([USE_SSL], 1, [Define to build with (Open)SSL support]) - - if test -d "${openssl_prefix}/include" ; then - INCLUDES="$INCLUDES -I${openssl_prefix}/include" - fi - if test -d "${openssl_prefix}/lib" ; then - LIBDIRS="$LIBDIRS -L${openssl_prefix}/lib" - fi -]) - -AC_SUBST(with_openssl) - - -# -# Readline -# -PGAC_ARG_BOOL(with, readline, yes, - [ --without-readline do not use Readline]) - -# -# Zlib -# -PGAC_ARG_BOOL(with, zlib, yes, - [ --without-zlib do not use Zlib]) - - - -# -# Optionally enable the building of the ODBC driver -# - -# Old option name -if test "${with_odbc+set}" = set && test "${enable_odbc+set}" != set; then - enable_odbc=$with_odbc -fi - -AC_MSG_CHECKING([whether to build the ODBC driver]) -PGAC_ARG_BOOL(enable, odbc, no, [ --enable-odbc build the ODBC driver package]) -PGAC_ARG_BOOL(with, unixodbc, no, [ --with-unixodbc build ODBC driver for unixODBC]) -PGAC_ARG_BOOL(with, iodbc, no, [ --with-iodbc build ODBC driver for iODBC]) -if test "$with_unixodbc" = yes && test "$with_iodbc" = yes; then - AC_MSG_ERROR([ODBC driver cannot be built for both unixODBC and iODBC]) -fi -if test "$with_unixodbc" = yes || test "$with_iodbc" = yes; then - enable_odbc=yes -fi -case $enable_odbc:$with_unixodbc:$with_iodbc in - yes:no:no) AC_MSG_RESULT([yes (stand-alone)]);; - yes:yes:no) AC_MSG_RESULT([yes (unixODBC)]) - AC_DEFINE(WITH_UNIXODBC, 1, [Define to 1 to build with unixODBC support (--with-unixodbc)]) - ;; - yes:no:yes) AC_MSG_RESULT([yes (iODBC)]) - AC_DEFINE(WITH_IODBC, 1, [Define to 1 to build with iODBC support (--with-iodbc)]) - ;; - no:*) AC_MSG_RESULT(no);; -esac -AC_SUBST([enable_odbc]) -AC_SUBST([with_unixodbc]) -AC_SUBST([with_iodbc]) - - -# Allow for overriding the default location of the odbcinst.ini -# file which is normally ${sysconfdir} (i.e., ${prefix}/etc). -PGAC_ARG_REQ(with, odbcinst, - [ --with-odbcinst=DIR default directory for odbcinst.ini [sysconfdir]], - [odbcinst_ini_dir=$withval], - [odbcinst_ini_dir="\${sysconfdir}"]) -AC_SUBST([odbcinst_ini_dir]) - - - -# Assume system is ELF if it predefines __ELF__ as 1, -# otherwise believe host_os based default. -case $host_os in - freebsd1*|freebsd2*) elf=no;; - freebsd3*|freebsd4*) elf=yes;; -esac - -AC_EGREP_CPP(yes, -[#if __ELF__ - yes -#endif -], -[ELF_SYS=true], -[if test "X$elf" = "Xyes" ; then - ELF_SYS=true -else - ELF_SYS= -fi]) -AC_SUBST(ELF_SYS) - - - -# -# Optionally build C++ code (i.e., libpq++) -# -AC_MSG_CHECKING([whether to build C++ modules]) -PGAC_ARG_OPTARG(with, CXX, [ --with-CXX build C++ modules (libpq++)], - [], - [CXX=$withval], -[ - AC_MSG_RESULT(yes) - - # If the user has specified CXXFLAGS in the environment, leave it - # alone, else use a default. - - AC_PROG_CXX - if test "$ac_env_CXXFLAGS" != set; then - if test "$GXX" = yes; then - CXXFLAGS=-O2 - else - case $template in - osf) CXXFLAGS='-O4 -Olimit 2000' ;; - unixware) CXXFLAGS='-O' ;; - *) CXXFLAGS= ;; - esac - fi - fi - if test "$enable_debug" = yes && test "$ac_cv_prog_cxx_g" = yes; then - CXXFLAGS="$CXXFLAGS -g" - fi - AC_MSG_NOTICE([using CXXFLAGS=$CXXFLAGS]) - - AC_PROG_CXXCPP -], -[AC_MSG_RESULT(no)]) -AC_SUBST(with_CXX) -AC_SUBST(GXX) - -CPPFLAGS="$CPPFLAGS $INCLUDES" -LDFLAGS="$LDFLAGS $LIBDIRS" - -AC_MSG_NOTICE([using CPPFLAGS=$CPPFLAGS]) -AC_MSG_NOTICE([using LDFLAGS=$LDFLAGS]) - - -AC_PROG_AWK -PGAC_PATH_FLEX -AC_PROG_LN_S -AC_PROG_LD -AC_SUBST(LD) -AC_SUBST(with_gnu_ld) -case $host_os in sysv5*) - AC_CACHE_CHECK([whether ld -R works], [pgac_cv_prog_ld_R], - [ - pgac_save_LDFLAGS=$LDFLAGS; LDFLAGS="$LDFLAGS -Wl,-R/usr/lib" - AC_TRY_LINK([], [], [pgac_cv_prog_ld_R=yes], [pgac_cv_prog_ld_R=no]) - LDFLAGS=$pgac_save_LDFLAGS - ]) - ld_R_works=$pgac_cv_prog_ld_R - AC_SUBST(ld_R_works) -esac -AC_PROG_RANLIB -AC_CHECK_PROGS(LORDER, lorder) -AC_PATH_PROG(TAR, tar) -PGAC_CHECK_STRIP - -AC_CHECK_PROGS(YACC, ['bison -y']) -if test -z "$YACC"; then - AC_MSG_WARN([ -*** Without Bison you will not be able to build PostgreSQL from CVS or -*** change any of the parser definition files. You can obtain Bison 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 Bison -*** output is pre-generated.) To use a different yacc program (possible, -*** but not recommended), set the environment variable YACC before running -*** 'configure'.]) -fi -AC_SUBST(YFLAGS) - -if test "$with_tk" = yes; then - AC_PATH_PROG(WISH, wish) - test -z "$WISH" && AC_MSG_ERROR(['wish' is required for Tk support]) -fi - -PGAC_PATH_PERL -if test "$with_perl" = yes; then - PGAC_CHECK_PERL_CONFIGS([installsitearch,installman3dir, - archlibexp,privlibexp,useshrplib,man3ext]) - PGAC_CHECK_PERL_EMBED_LDFLAGS -fi - -if test "$with_python" = yes; then - PGAC_PATH_PYTHON - PGAC_CHECK_PYTHON_MODULE_SETUP - PGAC_CHECK_PYTHON_EMBED_SETUP -fi - - -## -## Libraries -## - -if test "$PORTNAME" != "aix" -a "$PORTNAME" != "alpha" -then - AC_CHECK_LIB(bsd, main) -fi -AC_CHECK_LIB(util, setproctitle) -AC_CHECK_LIB(m, main) -AC_CHECK_LIB(dl, main) -AC_CHECK_LIB(nsl, main) -AC_CHECK_LIB(socket, main) -AC_CHECK_LIB(ipc, main) -AC_CHECK_LIB(IPC, main) -AC_CHECK_LIB(lc, main) -AC_CHECK_LIB(dld, main) -AC_CHECK_LIB(ld, main) -AC_CHECK_LIB(compat, main) -AC_CHECK_LIB(BSD, main) -AC_CHECK_LIB(gen, main) -AC_CHECK_LIB(PW, main) -AC_CHECK_LIB(resolv, main) -# QNX: -AC_CHECK_LIB([[unix]], main) -AC_SEARCH_LIBS(crypt, crypt) -# BeOS: -AC_CHECK_LIB(bind, __inet_ntoa) -# Solaris: -AC_SEARCH_LIBS(fdatasync, [rt posix4]) - -if test "$with_readline" = yes; then - PGAC_CHECK_READLINE - if test x"$pgac_cv_check_readline" = x"no"; then - AC_MSG_ERROR([readline library not found -Use --without-readline to disable readline support.]) - fi -fi - -if test "$with_zlib" = yes; then - AC_CHECK_LIB(z, inflate, [], - [AC_MSG_ERROR([zlib library not found -Use --without-zlib to disable zlib support.])]) -fi - -if test "$with_krb4" = yes ; then - AC_CHECK_LIB(des, [des_encrypt], [], [AC_MSG_ERROR([library 'des' is required for Kerberos 4])]) - AC_CHECK_LIB(krb, [krb_sendauth], [], [AC_MSG_ERROR([library 'krb' is required for Kerberos 4])]) -fi - -if test "$with_krb5" = yes ; then - AC_SEARCH_LIBS(com_err, [krb5 'krb5 -ldes -lasn1 -lroken' com_err], [], - [AC_MSG_ERROR([could not find function 'com_err' required for Kerberos 5])]) - AC_SEARCH_LIBS(krb5_encrypt, [krb5 'krb5 -ldes -lasn1 -lroken' crypto k5crypto], [], - [AC_MSG_ERROR([could not find function 'krb5_encrypt' required for Kerberos 5])]) - AC_SEARCH_LIBS(krb5_sendauth, [krb5 'krb5 -ldes -lasn1 -lroken'], [], - [AC_MSG_ERROR([could not find function 'krb5_sendauth' required for Kerberos 5])]) -fi - -if test "$with_openssl" = yes ; then - dnl Order matters! - AC_CHECK_LIB(crypto, [CRYPTO_new_ex_data], [], [AC_MSG_ERROR([library 'crypto' is required for OpenSSL])]) - AC_CHECK_LIB(ssl, [SSL_library_init], [], [AC_MSG_ERROR([library 'ssl' is required for OpenSSL])]) -fi - -if test "$with_pam" = yes ; then - AC_CHECK_LIB(pam, [pam_start], [], [AC_MSG_ERROR([library 'pam' is required for PAM])]) -fi - - -## -## Header files -## -dnl sys/socket.h is required by AC_FUNC_ACCEPT_ARGTYPES -AC_CHECK_HEADERS([crypt.h dld.h endian.h fp_class.h getopt.h ieeefp.h pwd.h sys/ipc.h sys/pstat.h sys/select.h sys/sem.h sys/socket.h sys/shm.h sys/un.h termios.h kernel/OS.h kernel/image.h SupportDefs.h]) - -# At least on IRIX, cpp test for netinet/tcp.h will fail unless -# netinet/in.h is included first. -AC_CHECK_HEADERS([netinet/in.h]) -AC_CHECK_HEADERS([netinet/tcp.h], [], [], -[AC_INCLUDES_DEFAULT -#ifdef HAVE_NETINET_IN_H -#include -#endif -]) - -if test "$with_readline" = yes; then - AC_CHECK_HEADERS([readline/readline.h], [], - [AC_CHECK_HEADERS([readline.h], [], - [AC_MSG_ERROR([readline header not found -Use --without-readline to disable readline support.])])]) - AC_CHECK_HEADERS([readline/history.h], [], - [AC_CHECK_HEADERS([history.h], [], - [AC_MSG_ERROR([history header not found -Use --without-readline to disable readline support.])])]) -fi - -if test "$with_zlib" = yes; then - AC_CHECK_HEADER(zlib.h, [], [AC_MSG_ERROR([zlib header not found -Use --without-zlib to disable zlib support.])]) -fi - -if test "$with_krb4" = yes ; then - AC_CHECK_HEADER(krb.h, [], [AC_MSG_ERROR([header file is required for Kerberos 4])]) -fi - -if test "$with_krb5" = yes ; then - AC_CHECK_HEADER(krb5.h, [], [AC_MSG_ERROR([header file is required for Kerberos 5])]) - AC_CHECK_HEADER(com_err.h, [], [AC_MSG_ERROR([header file is required for Kerberos 5])]) -fi - -if test "$with_openssl" = yes ; then - AC_CHECK_HEADER([openssl/ssl.h], [], [AC_MSG_ERROR([header file is required for OpenSSL])]) - AC_CHECK_HEADER([openssl/err.h], [], [AC_MSG_ERROR([header file is required for OpenSSL])]) -fi - -if test "$with_pam" = yes ; then - AC_CHECK_HEADER([security/pam_appl.h], [], [AC_MSG_ERROR([header file is required for PAM])]) -fi - - -## -## Types, structures, compiler characteristics -## -m4_defun([AC_PROG_CC_STDC], []) dnl We don't want that. -AC_C_CONST -AC_C_INLINE -AC_C_STRINGIZE -PGAC_C_SIGNED -AC_C_VOLATILE -AC_STRUCT_TIMEZONE -PGAC_UNION_SEMUN -PGAC_STRUCT_SOCKADDR_UN - -AC_CHECK_TYPES([struct cmsgcred, struct fcred, struct sockcred], [], [], -[#include -#include -#include ]) - -if test "$with_zlib" = yes; then - # Check that defines z_streamp (versions before about 1.0.4 - # did not). While we could work around the lack of z_streamp, it - # seems unwise to encourage people to use such old zlib versions... - AC_CHECK_TYPE(z_streamp, [], [AC_MSG_ERROR([zlib version is too old -Use --without-zlib to disable zlib support.])], - [#include ]) -fi - -if test "$with_krb5" = yes; then -# Check for differences between MIT and Heimdal (KTH) releases - AC_CHECK_MEMBERS([krb5_ticket.enc_part2], [], - [AC_CHECK_MEMBERS([krb5_ticket.client], [], - [AC_MSG_ERROR([could not determine how to get client name from Kerberos 5 ticket])], - [#include ])], - [#include ]) - AC_CHECK_MEMBERS([krb5_error.text.data], [], - [AC_CHECK_MEMBER([krb5_error.e_data], [], - [AC_MSG_ERROR([could not determine how to extract Kerberos 5 error messages])], - [#include ])], - [#include ]) -fi - - -## -## Functions, global variables -## -PGAC_VAR_INT_TIMEZONE -AC_FUNC_ACCEPT_ARGTYPES -PGAC_FUNC_GETTIMEOFDAY_1ARG - -# SunOS doesn't handle negative byte comparisons properly with +/- return -PGAC_FUNC_MEMCMP - -AC_CHECK_FUNCS([cbrt fcvt getopt_long memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen fdatasync]) - -AC_CHECK_DECLS(fdatasync, [], [], [#include ]) - -AC_CACHE_CHECK([for PS_STRINGS], [pgac_cv_var_PS_STRINGS], -[AC_TRY_LINK( -[#include -#include -], -[PS_STRINGS->ps_nargvstr = 1; -PS_STRINGS->ps_argvstr = "foo";], -[pgac_cv_var_PS_STRINGS=yes], -[pgac_cv_var_PS_STRINGS=no])]) -if test "$pgac_cv_var_PS_STRINGS" = yes ; then - AC_DEFINE([HAVE_PS_STRINGS], [], [Define if the PS_STRINGS thing exists.]) -fi - - -# We use our snprintf.c emulation if either snprintf() or vsnprintf() -# is missing. Yes, there are machines that have only one. We may -# also decide to use snprintf.c if snprintf() is present but does not -# have working "long long int" support -- see below. - -SNPRINTF='' -AC_CHECK_FUNCS(snprintf, [], SNPRINTF='snprintf.o') -AC_CHECK_FUNCS(vsnprintf, [], SNPRINTF='snprintf.o') -AC_SUBST(SNPRINTF) - - -# Check whether declares snprintf() and vsnprintf(); if not, -# include/c.h will provide declarations. Note this is a separate test -# from whether the functions exist in the C library --- there are -# systems that have the functions but don't bother to declare them :-( - -AC_CHECK_DECLS([snprintf, vsnprintf]) - - -# do this one the hard way in case isinf() is a macro -AC_CACHE_CHECK([for isinf], ac_cv_func_isinf, -[AC_TRY_LINK( -[#include -], -[double x = 0.0; int res = isinf(x);], -[ac_cv_func_isinf=yes], -[ac_cv_func_isinf=no])]) - -if test $ac_cv_func_isinf = yes ; then - AC_DEFINE(HAVE_ISINF, 1, [Define to 1 if you have isinf()]) - ISINF= -else - ISINF='isinf.o' - # Look for a way to implement a substitute for isinf() - AC_CHECK_FUNCS([fpclass fp_class fp_class_d class], [break]) -fi -AC_SUBST(ISINF) - - -AC_CHECK_FUNCS(getrusage, [], GETRUSAGE='getrusage.o') -AC_SUBST(GETRUSAGE) -AC_CHECK_FUNCS(srandom, [], SRANDOM='srandom.o') -AC_SUBST(SRANDOM) -AC_CHECK_FUNCS(gethostname, [], GETHOSTNAME='gethostname.o') -AC_SUBST(GETHOSTNAME) -AC_CHECK_FUNCS(random, [], MISSING_RANDOM='random.o') -AC_SUBST(MISSING_RANDOM) -AC_CHECK_FUNCS(inet_aton, [], INET_ATON='inet_aton.o') -AC_SUBST(INET_ATON) -AC_CHECK_FUNCS(strerror, [], STRERROR='strerror.o') -AC_SUBST(STRERROR) -AC_CHECK_FUNCS(strdup, [], STRDUP='../../utils/strdup.o') -AC_SUBST(STRDUP) -AC_CHECK_FUNCS(strtol, [], STRTOL='strtol.o') -AC_SUBST(STRTOL) -AC_CHECK_FUNCS(strtoul, [], STRTOUL='strtoul.o') -AC_SUBST(STRTOUL) -AC_CHECK_FUNCS(strcasecmp, [], STRCASECMP='strcasecmp.o') -AC_SUBST(STRCASECMP) - -# On HPUX 9, rint() is not in regular libm.a but in /lib/pa1.1/libm.a; -# this hackery with HPUXMATHLIB allows us to cope. -HPUXMATHLIB="" -case $host_cpu in - hppa1.1) - if [[ -r /lib/pa1.1/libm.a ]] ; then - HPUXMATHLIB="-L /lib/pa1.1 -lm" - fi ;; -esac -AC_SUBST(HPUXMATHLIB) - -AC_CHECK_FUNCS(rint, [], - [AC_CHECK_LIB(m, rint, AC_DEFINE(HAVE_RINT), , $HPUXMATHLIB)]) - - -if test "$with_readline" = yes; then - PGAC_VAR_RL_COMPLETION_APPEND_CHARACTER - AC_CHECK_FUNCS([rl_completion_matches rl_filename_completion_function]) -fi - - -dnl Cannot use AC_CHECK_FUNC because finite may be a macro -AC_MSG_CHECKING(for finite) -AC_TRY_LINK([#include ], - [int dummy=finite(1.0);], - [AC_DEFINE(HAVE_FINITE, 1, [Set to 1 if you have finite()]) -AC_MSG_RESULT(yes)], - [AC_MSG_RESULT(no)]) - -dnl Cannot use AC_CHECK_FUNC because sigsetjmp may be a macro -dnl (especially on GNU libc) -dnl See also comments in pg_config.h. -AC_MSG_CHECKING(for sigsetjmp) -AC_TRY_LINK([#include ], - [sigjmp_buf x; sigsetjmp(x, 1);], - [AC_DEFINE(HAVE_SIGSETJMP, 1, [Set to 1 if you have sigsetjmp()]) -AC_MSG_RESULT(yes)], - [AC_MSG_RESULT(no)]) - -AC_CHECK_FUNC(syslog, - [AC_CHECK_HEADER(syslog.h, - [AC_DEFINE(HAVE_SYSLOG, 1, [])], - [])]) - -AC_CACHE_CHECK([for optreset], pgac_cv_var_int_optreset, -[AC_TRY_LINK([#include ], - [extern int optreset; optreset = 1;], - [pgac_cv_var_int_optreset=yes], - [pgac_cv_var_int_optreset=no])]) -if test x"$pgac_cv_var_int_optreset" = x"yes"; then - AC_DEFINE(HAVE_INT_OPTRESET, 1, [Define to 1 if you have the global variable 'int optreset']) -fi - - -# This test makes sure that run tests work at all. Sometimes a shared -# library is found by the linker, but the runtime linker can't find it. -# This check should come after all modifications of compiler or linker -# variables, and before any other run tests. -AC_MSG_CHECKING([test program]) -AC_TRY_RUN([int main() { return 0; }], -[AC_MSG_RESULT(ok)], -[AC_MSG_RESULT(failed) -AC_MSG_ERROR([[ -*** Could not execute a simple test program. This may be a problem -*** related to locating shared libraries. Check the file 'config.log' -*** for the exact reason.]])], -[AC_MSG_RESULT([cross-compiling])]) - - -dnl Check to see if we have a working 64-bit integer type. -dnl This breaks down into two steps: -dnl (1) figure out if the compiler has a 64-bit int type with working -dnl arithmetic, and if so -dnl (2) see whether snprintf() can format the type correctly. (Currently, -dnl snprintf is the only library routine we really need for int8 support.) -dnl It's entirely possible to have a compiler that handles a 64-bit type -dnl when the C library doesn't; this is fairly likely when using gcc on -dnl an older platform, for example. -dnl If there is no native snprintf() or it does not handle the 64-bit type, -dnl we force our own version of snprintf() to be used instead. -dnl Note this test must be run after our initial check for snprintf/vsnprintf. - -PGAC_TYPE_64BIT_INT([long int]) - -if test x"$HAVE_LONG_INT_64" = x"no" ; then - PGAC_TYPE_64BIT_INT([long long int]) -fi - - -dnl If we need to use "long long int", figure out whether nnnLL notation works. - -if [[ x"$HAVE_LONG_LONG_INT_64" = xyes ]] ; then - AC_TRY_COMPILE([ -#define INT64CONST(x) x##LL -long long int foo = INT64CONST(0x1234567890123456); -], - [], - [AC_DEFINE(HAVE_LL_CONSTANTS, 1, [Define if you have LL constants])], - []) -fi - - -dnl If we found "long int" is 64 bits, assume snprintf handles it. -dnl If we found we need to use "long long int", better check. -dnl We cope with snprintfs that use either %lld or %qd as the format. -dnl If neither works, fall back to our own snprintf emulation (which we -dnl know uses %lld). - -if [[ x"$HAVE_LONG_LONG_INT_64" = xyes ]] ; then - if [[ x$SNPRINTF = x ]] ; then - AC_MSG_CHECKING(whether snprintf handles 'long long int' as %lld) - AC_TRY_RUN([#include -typedef long long int int64; -#define INT64_FORMAT "%lld" - -int64 a = 20000001; -int64 b = 40000005; - -int does_int64_snprintf_work() -{ - int64 c; - char buf[100]; - - if (sizeof(int64) != 8) - return 0; /* doesn't look like the right size */ - - c = a * b; - snprintf(buf, 100, INT64_FORMAT, c); - if (strcmp(buf, "800000140000005") != 0) - return 0; /* either multiply or snprintf is busted */ - return 1; -} -main() { - exit(! does_int64_snprintf_work()); -}], - [ AC_MSG_RESULT(yes) - INT64_FORMAT='"%lld"' - ], - [ AC_MSG_RESULT(no) - AC_MSG_CHECKING(whether snprintf handles 'long long int' as %qd) - AC_TRY_RUN([#include -typedef long long int int64; -#define INT64_FORMAT "%qd" - -int64 a = 20000001; -int64 b = 40000005; - -int does_int64_snprintf_work() -{ - int64 c; - char buf[100]; - - if (sizeof(int64) != 8) - return 0; /* doesn't look like the right size */ - - c = a * b; - snprintf(buf, 100, INT64_FORMAT, c); - if (strcmp(buf, "800000140000005") != 0) - return 0; /* either multiply or snprintf is busted */ - return 1; -} -main() { - exit(! does_int64_snprintf_work()); -}], - [ AC_MSG_RESULT(yes) - INT64_FORMAT='"%qd"' - ], - [ AC_MSG_RESULT(no) - # Force usage of our own snprintf, since system snprintf is broken - SNPRINTF='snprintf.o' - INT64_FORMAT='"%lld"' - ], - [ AC_MSG_RESULT(assuming not on target machine) - # Force usage of our own snprintf, since we cannot test foreign snprintf - SNPRINTF='snprintf.o' - INT64_FORMAT='"%lld"' - ]) ], - [ AC_MSG_RESULT(assuming not on target machine) - # Force usage of our own snprintf, since we cannot test foreign snprintf - SNPRINTF='snprintf.o' - INT64_FORMAT='"%lld"' - ]) - else - # here if we previously decided we needed to use our own snprintf - INT64_FORMAT='"%lld"' - fi -else - # Here if we are not using 'long long int' at all - INT64_FORMAT='"%ld"' -fi - -AC_DEFINE_UNQUOTED(INT64_FORMAT, $INT64_FORMAT, - [Define this as the appropriate snprintf format for 64-bit ints, if any]) - - -AC_CHECK_FUNCS([strtoll strtoq], [break]) -AC_CHECK_FUNCS([strtoull strtouq], [break]) - -# Check for one of atexit() or on_exit() -AC_CHECK_FUNCS(atexit, [], - [AC_CHECK_FUNCS(on_exit, [], - [AC_MSG_ERROR([neither atexit() nor on_exit() found])])]) - -dnl Need a #define for the size of Datum (unsigned long) - -AC_CHECK_SIZEOF([unsigned long]) -AC_DEFINE_UNQUOTED(SIZEOF_DATUM, $ac_cv_sizeof_unsigned_long, [sizeof(Datum) -- don't change]) - -# Determine memory alignment requirements for the basic C data types. - -PGAC_CHECK_ALIGNOF(short) -PGAC_CHECK_ALIGNOF(int) -PGAC_CHECK_ALIGNOF(long) -if test x"$HAVE_LONG_LONG_INT_64" = x"yes" ; then - PGAC_CHECK_ALIGNOF(long long int) -fi -PGAC_CHECK_ALIGNOF(double) - -# Compute maximum alignment of any basic type. -# We assume long's alignment is at least as strong as char, short, or int; -# but we must check long long (if it exists) and double. - -MAX_ALIGNOF=$pgac_cv_alignof_long -if test $MAX_ALIGNOF -lt $pgac_cv_alignof_double ; then - MAX_ALIGNOF=$pgac_cv_alignof_double -fi -if test x"$HAVE_LONG_LONG_INT_64" = xyes && test $MAX_ALIGNOF -lt $pgac_cv_alignof_long_long_int ; then - MAX_ALIGNOF="$pgac_cv_alignof_long_long_int" -fi -AC_DEFINE_UNQUOTED(MAXIMUM_ALIGNOF, $MAX_ALIGNOF, [Define as the maximum alignment requirement of any type]) - - -# Some platforms predefine the types int8, int16, etc. Only check -# a (hopefully) representative subset. -AC_CHECK_TYPES([int8, uint8, int64, uint64], [], [], -[#include -#ifdef HAVE_SUPPORTDEFS_H -#include -#endif]) - -# We also check for sig_atomic_t, which *should* be defined per ANSI -# C, but is missing on some old platforms. -AC_CHECK_TYPES([sig_atomic_t], [], [], [#include ]) - - -PGAC_FUNC_POSIX_SIGNALS - - -# Select semaphore implementation type. -if test x"$USE_NAMED_POSIX_SEMAPHORES" = x"1" ; then - AC_DEFINE(USE_NAMED_POSIX_SEMAPHORES, 1, [Define to select named POSIX semaphores]) - SEMA_IMPLEMENTATION="src/backend/port/posix_sema.c" -else - if test x"$USE_UNNAMED_POSIX_SEMAPHORES" = x"1" ; then - AC_DEFINE(USE_UNNAMED_POSIX_SEMAPHORES, 1, [Define to select unnamed POSIX semaphores]) - SEMA_IMPLEMENTATION="src/backend/port/posix_sema.c" - else - AC_DEFINE(USE_SYSV_SEMAPHORES, 1, [Define to select SysV-style semaphores]) - SEMA_IMPLEMENTATION="src/backend/port/sysv_sema.c" - fi -fi - - -# Select shared-memory implementation type. -AC_DEFINE(USE_SYSV_SHARED_MEMORY, 1, [Define to select SysV-style shared memory]) -SHMEM_IMPLEMENTATION="src/backend/port/sysv_shmem.c" - - -if test "$enable_nls" = yes ; then - PGAC_CHECK_GETTEXT -fi - -if test "$with_CXX" = yes; then - PGAC_CLASS_STRING - PGAC_CXX_NAMESPACE_STD -fi - - -# Check for Tcl configuration script tclConfig.sh -if test "$with_tcl" = yes; then - PGAC_PATH_TCLCONFIGSH([$with_tclconfig]) - PGAC_EVAL_TCLCONFIGSH([$TCL_CONFIG_SH], - [TCL_LIB_FILE,TCL_LIBS,TCL_LIB_SPEC,TCL_SHARED_BUILD]) - AC_SUBST(TCL_SHLIB_LD_LIBS)dnl don't want to double-evaluate that one -fi - -# Check for Tk configuration script tkConfig.sh -if test "$with_tk" = yes; then - PGAC_PATH_TKCONFIGSH([$with_tkconfig $with_tclconfig]) - PGAC_EVAL_TCLCONFIGSH([$TK_CONFIG_SH], [TK_LIBS,TK_LIB_SPEC,TK_XINCLUDES]) -fi - - -# -# Check for DocBook and tools -# -PGAC_PROG_NSGMLS -PGAC_PROG_JADE -PGAC_CHECK_DOCBOOK([3.1]) -PGAC_PATH_DOCBOOK_STYLESHEETS -PGAC_PATH_COLLATEINDEX -AC_CHECK_PROGS(SGMLSPL, sgmlspl) - - -# prepare build tree if outside source tree -# Note 1: test -ef might not exist, but it's more reliable than `pwd`. -# Note 2: /bin/pwd might be better than shell's built-in at getting -# a symlink-free name. -if test "$no_create" != yes; then - if ( test "$srcdir" -ef . ) >/dev/null 2>&1 || test "`cd $srcdir && /bin/pwd`" = "`/bin/pwd`"; then - : - else - AC_SUBST(vpath_build, yes) - _AS_ECHO_N([preparing build tree... ]) - pgac_abs_top_srcdir=`cd "$srcdir" && pwd` - $SHELL "$ac_aux_dir/prep_buildtree" "$pgac_abs_top_srcdir" "." \ - || AC_MSG_ERROR(failed) - AC_MSG_RESULT(done) - fi -fi - - -AC_CONFIG_FILES([GNUmakefile src/Makefile.global]) - -AC_CONFIG_LINKS([ - src/backend/port/dynloader.c:src/backend/port/dynloader/${template}.c - src/backend/port/pg_sema.c:${SEMA_IMPLEMENTATION} - src/backend/port/pg_shmem.c:${SHMEM_IMPLEMENTATION} - src/include/dynloader.h:src/backend/port/dynloader/${template}.h - src/include/pg_config_os.h:src/include/port/${template}.h - src/Makefile.port:src/makefiles/Makefile.${template} -]) - -AC_CONFIG_HEADERS([src/include/pg_config.h], -[ -# Update timestamp for pg_config.h (see Makefile.global) -echo >src/include/stamp-h -]) - -AC_OUTPUT diff --git a/contrib/Makefile b/contrib/Makefile deleted file mode 100644 index fc265216e1..0000000000 --- a/contrib/Makefile +++ /dev/null @@ -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 diff --git a/contrib/README b/contrib/README deleted file mode 100644 index 1ffef6df32..0000000000 --- a/contrib/README +++ /dev/null @@ -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 - -btree_gist - - Support for emulating BTREE indexing in GiST - by Oleg Bartunov and Teodor Sigaev - -chkpass - - An auto-encrypted password datatype - by D'Arcy J.M. Cain - -cube - - Multidimensional-cube datatype (GiST indexing example) - by Gene Selkov, Jr. - -dbase - - Converts from dbase/xbase to PostgreSQL - by Maarten.Boekhold , - Frank Koormann , - Ivan Baldo - -dblink - - Allows remote query execution - by Joe Conway - -dbsize - - Reports database and table disk space - by Peter Eisentraut - -earthdistance - - Operator for computing earth distance for two points - by Hal Snyder - -findoidjoins - - Finds the joins used by oid columns by examining the actual - values in the oid columns and row oids. - by Bruce Momjian - -fulltextindex - - Full text indexing using triggers - by Maarten Boekhold - -fuzzystrmatch - - Levenshtein, metaphone, and soundex fuzzy string matching - by Joe Conway , Joel Burton - -intagg - - Integer aggregator - by mlw - - -intarray - - Index support for arrays of int4, using GiST - by Teodor Sigaev and Oleg Bartunov - -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 - -lo - - Large Object maintenance - by Peter Mount - -mSQL-interface - - mSQL API translation library - by Aldrin Leal - -mac - - Support functions for MAC address types - by Lawrence E. Rosenman - -miscutil - - PostgreSQL assert checking and various utility functions - by Massimo Dal Zotto - -mysql - - utility to convert MySQL schema dumps to SQL92 and PostgreSQL - by Thomas Lockhart - Max Rudensky - Valentine Danilchuk - -noupdate - - trigger to prevent updates on single columns - -oid2name - - maps numeric files to table names - by B Palmer - -oracle - - converts Oracle database schema to PostgreSQL - by Gilles Darold - -pg_controldata - - Dump contents of pg_control (database master file) - by Oliver Elphick - -pg_dumplo - - Dump large objects - by Karel Zak - -pg_logger - - Stdin-to-syslog gateway for PostgreSQL - by Nathan Myers - -pg_resetxlog - - Reset the WAL log (pg_xlog) to recover from crash or format change - by Tom Lane - -pg_upgrade - - Upgrade from previous PostgreSQL version without pg_dump/reload - by Bruce Momjian - -pgbench - - TPC-B like benchmarking tool - by Tatsuo Ishii - -pgcrypto - - Cryptographic functions - by Marko Kreen - -pgstattuple - - A function returns the percentage of "dead" tuples in a table - by Tatsuo Ishii - -retep - - tools to build retep tools packages - by Peter T Mount - -rserv - - replication server - by Vadim B. Mikheev - -rtree_gist - - Support for emulating RTREE indexing in GiST - by Oleg Bartunov and Teodor Sigaev - -seg - - Confidence-interval datatype (GiST indexing example) - by Gene Selkov, Jr. - -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 - -tips/apache_logging - - Getting Apache to log to PostgreSQL - by Terry Mackintosh - -tools - - Assorted developer tools - by Massimo Dal Zotto - -tsearch - - Full-text-index support using GiST - by Teodor Sigaev and Oleg Bartunov - . - -userlock - - User locks - by Massimo Dal Zotto - -vacuumlo - - Remove orphaned large objects - by Peter T Mount - -xml - - Storing XML in PostgreSQL - by John Gray diff --git a/contrib/array/Makefile b/contrib/array/Makefile deleted file mode 100644 index 324fd2660a..0000000000 --- a/contrib/array/Makefile +++ /dev/null @@ -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 diff --git a/contrib/array/README.array_iterator b/contrib/array/README.array_iterator deleted file mode 100644 index b072ebe397..0000000000 --- a/contrib/array/README.array_iterator +++ /dev/null @@ -1,49 +0,0 @@ -Array iterator functions, by Massimo Dal Zotto -Copyright (C) 1999, Massimo Dal Zotto - -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_]" 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. diff --git a/contrib/array/array_iterator.c b/contrib/array/array_iterator.c deleted file mode 100644 index 8a2455b673..0000000000 --- a/contrib/array/array_iterator.c +++ /dev/null @@ -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 - * ported to postgreSQL 6.3.2,added oid_functions, 18.1.1999, - * Tobias Gabele - * - * This software is distributed under the GNU General Public License - * either version 2, or (at your option) any later version. - */ - -#include "postgres.h" - -#include -#include -#include -#include - -#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: - */ diff --git a/contrib/array/array_iterator.h b/contrib/array/array_iterator.h deleted file mode 100644 index 7889fdc0b2..0000000000 --- a/contrib/array/array_iterator.h +++ /dev/null @@ -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: - */ diff --git a/contrib/array/array_iterator.sql.in b/contrib/array/array_iterator.sql.in deleted file mode 100644 index d4182b112e..0000000000 --- a/contrib/array/array_iterator.sql.in +++ /dev/null @@ -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 diff --git a/contrib/btree_gist/Makefile b/contrib/btree_gist/Makefile deleted file mode 100644 index 03aa1479be..0000000000 --- a/contrib/btree_gist/Makefile +++ /dev/null @@ -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 diff --git a/contrib/btree_gist/README.btree_gist b/contrib/btree_gist/README.btree_gist deleted file mode 100644 index d61db62c3c..0000000000 --- a/contrib/btree_gist/README.btree_gist +++ /dev/null @@ -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 < 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; - diff --git a/contrib/btree_gist/btree_gist.c b/contrib/btree_gist/btree_gist.c deleted file mode 100644 index c4eb852213..0000000000 --- a/contrib/btree_gist/btree_gist.c +++ /dev/null @@ -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); -} diff --git a/contrib/btree_gist/btree_gist.sql.in b/contrib/btree_gist/btree_gist.sql.in deleted file mode 100644 index 98b868afc7..0000000000 --- a/contrib/btree_gist/btree_gist.sql.in +++ /dev/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; - diff --git a/contrib/btree_gist/data/test_btree.data b/contrib/btree_gist/data/test_btree.data deleted file mode 100644 index d29aa02c52..0000000000 --- a/contrib/btree_gist/data/test_btree.data +++ /dev/null @@ -1,1000 +0,0 @@ -49 -200 -394 -274 -196 -543 -328 -645 -151 -849 -771 -704 -688 -485 -545 -931 -210 -222 -897 -676 -\N -201 -533 -703 -410 -301 -633 -319 -329 -13 -942 -737 -533 -407 -876 -622 -430 -264 -785 -938 -680 -91 -179 -147 -108 -510 -336 -781 -3 -16 -\N -136 -494 -570 -333 -447 -185 -\N -\N -213 -193 -565 -77 -904 -989 -471 -\N -566 -117 -102 -515 -105 -\N -61 -537 -278 -337 -46 -92 -723 -661 -619 -\N -293 -\N -919 -227 -536 -917 -779 -418 -15 -235 -425 -\N -362 -587 -590 -103 -563 -369 -775 -404 -408 -142 -133 -566 -727 -413 -382 -42 -32 -548 -540 -\N -86 -\N -58 -685 -11 -907 -274 -94 -987 -971 -383 -757 -327 -38 -854 -257 -318 -159 -224 -39 -\N -532 -461 -30 -\N -790 -\N -828 -35 -606 -845 -\N -313 -391 -869 -592 -821 -73 -\N -703 -222 -218 -209 -136 -774 -608 -531 -820 -119 -497 -889 -\N -592 -899 -\N -243 -\N -400 -\N -894 -\N -\N -386 -\N -550 -840 -606 -160 -386 -723 -16 -693 -601 -338 -368 -74 -436 -734 -806 -433 -679 -857 -679 -319 -85 -\N -153 -506 -110 -73 -485 -749 -205 -628 -746 -380 -\N -573 -146 -314 -439 -102 -606 -\N -179 -\N -921 -236 -509 -714 -353 -97 -\N -374 -131 -528 -805 -298 -533 -737 -\N -135 -119 -294 -725 -826 -393 -740 -487 -932 -\N -734 -333 -651 -460 -590 -530 -575 -352 -999 -319 -\N -277 -692 -939 -580 -\N -\N -568 -92 -182 -885 -839 -303 -709 -891 -538 -58 -271 -577 -827 -459 -852 -812 -823 -\N -375 -924 -\N -799 -297 -795 -853 -751 -\N -77 -339 -\N -\N -506 -577 -864 -118 -444 -731 -355 -390 -787 -352 -570 -389 -771 -110 -278 -59 -862 -846 -\N -362 -590 -719 -442 -525 -329 -945 -739 -857 -897 -835 -787 -657 -558 -455 -\N -159 -\N -672 -795 -\N -581 -818 -872 -123 -255 -816 -789 -\N -124 -\N -900 -\N -240 -819 -386 -841 -282 -269 -259 -893 -570 -505 -769 -959 -\N -426 -620 -857 -824 -102 -308 -351 -74 -950 -292 -580 -739 -575 -\N -594 -\N -489 -382 -498 -795 -664 -881 -918 -159 -108 -\N -679 -724 -964 -8 -664 -267 -101 -869 -676 -433 -469 -657 -78 -381 -43 -959 -695 -545 -780 -390 -697 -733 -693 -387 -864 -613 -301 -374 -222 -564 -450 -307 -\N -\N -912 -518 -593 -283 -529 -983 -379 -244 -819 -377 -225 -811 -69 -\N -380 -919 -724 -352 -248 -\N -416 -788 -663 -395 -394 -707 -352 -658 -759 -825 -881 -563 -271 -\N -407 -\N -157 -931 -233 -769 -78 -737 -525 -221 -216 -824 -353 -977 -757 -976 -843 -795 -603 -\N -85 -795 -382 -998 -136 -904 -563 -354 -288 -2 -835 -\N -714 -915 -471 -\N -\N -676 -556 -119 -490 -909 -\N -240 -106 -17 -474 -222 -721 -374 -\N -262 -913 -234 -797 -\N -723 -9 -126 -886 -617 -311 -241 -413 -134 -545 -145 -867 -120 -271 -\N -\N -\N -177 -\N -735 -435 -\N -855 -612 -803 -964 -417 -771 -359 -670 -682 -236 -492 -597 -220 -1 -585 -193 -837 -938 -389 -527 -423 -627 -\N -924 -741 -760 -280 -819 -128 -585 -412 -\N -816 -710 -359 -318 -478 -803 -771 -642 -\N -\N -842 -490 -462 -727 -214 -629 -276 -\N -274 -672 -875 -35 -873 -913 -185 -770 -126 -4 -770 -56 -621 -137 -62 -771 -561 -891 -80 -\N -45 -996 -722 -940 -823 -\N -883 -225 -788 -519 -317 -763 -563 -689 -635 -905 -500 -859 -55 -205 -651 -537 -787 -973 -195 -542 -\N -\N -857 -377 -\N -\N -834 -314 -314 -407 -865 -945 -675 -\N -\N -5 -715 -248 -168 -862 -37 -366 -936 -136 -\N -324 -845 -854 -831 -225 -\N -987 -545 -621 -140 -844 -132 -466 -899 -716 -907 -97 -511 -425 -225 -522 -702 -532 -132 -328 -278 -985 -869 -773 -\N -633 -624 -114 -879 -142 -762 -729 -890 -430 -241 -267 -616 -9 -457 -168 -\N -177 -3 -\N -675 -558 -2 -\N -310 -548 -992 -597 -950 -48 -33 -173 -460 -890 -757 -983 -492 -777 -22 -261 -973 -106 -666 -558 -226 -681 -\N -347 -92 -14 -96 -641 -495 -585 -458 -217 -386 -284 -719 -694 -\N -643 -\N -928 -976 -44 -941 -396 -\N -559 -969 -187 -669 -463 -769 -669 -\N -70 -861 -501 -\N -349 -44 -951 -375 -869 -441 -515 -322 -867 -983 -152 -623 -730 -148 -899 -236 -833 -961 -389 -448 -975 -523 -225 -\N -698 -314 -19 -935 -269 -178 -349 -685 -702 -523 -165 -453 -756 -266 -997 -499 -880 -402 -40 -487 -261 -506 -886 -193 -237 -631 -630 -570 -90 -558 -348 -203 -\N -598 -676 -834 -709 -796 -299 -197 -\N -94 -997 -458 -871 -964 -808 -321 -\N -525 -451 -785 -374 -530 -626 -850 -336 -138 -883 -143 -\N -299 -\N -754 -667 -820 -777 -438 -339 -600 -276 -987 -270 -949 -\N -474 -321 -325 -138 -620 -345 -\N -477 -\N -690 -714 -897 -36 -469 -965 -259 -715 -580 -\N -697 -495 -\N -284 -820 -992 -708 -638 -216 -181 -\N -101 -\N -730 -902 -703 -176 -561 -945 -915 -246 -632 -441 -849 -\N -552 -76 -960 -628 -413 -814 -746 -613 -417 -327 -178 -116 -829 -522 -761 -462 -518 -660 -87 -979 -143 -628 -960 -715 -\N -288 -\N -387 -29 -15 -544 -455 -57 -433 -158 -72 -49 -620 -616 -592 -584 -564 -735 -308 -661 -519 -1 -825 -665 -316 -970 -305 -204 -541 -544 -589 -827 -600 -126 -192 -610 -650 -647 -177 -625 -405 -465 -895 -\N -152 -594 -492 -385 -693 -442 -173 -\N -946 -934 -200 -532 -750 -158 -981 -670 -572 -608 -135 -48 -208 -\N -971 -594 -429 -655 diff --git a/contrib/btree_gist/data/test_btree_ts.data b/contrib/btree_gist/data/test_btree_ts.data deleted file mode 100644 index 7dc9a5b0c6..0000000000 --- a/contrib/btree_gist/data/test_btree_ts.data +++ /dev/null @@ -1,1000 +0,0 @@ -\N -Sun Jun 3 20:40:06 2001 -Sun Jun 3 02:45:19 2001 -Tue May 29 20:31:04 2001 -Fri Jun 1 04:23:33 2001 -Wed May 30 07:38:41 2001 -Sun Jun 3 11:21:57 2001 -Fri Jun 1 01:05:37 2001 -Mon May 28 21:42:37 2001 -Wed May 30 17:54:19 2001 -Mon Jun 4 18:45:50 2001 -Tue May 29 19:55:23 2001 -Tue May 29 12:15:50 2001 -Mon Jun 4 03:14:19 2001 -Tue May 29 08:42:21 2001 -Sun Jun 3 04:31:46 2001 -Tue May 29 15:13:14 2001 -Thu May 31 02:32:09 2001 -Thu May 31 01:12:54 2001 -Tue May 29 16:55:46 2001 -Fri Jun 1 18:01:47 2001 -Mon May 28 22:49:18 2001 -Tue May 29 16:51:44 2001 -Mon Jun 4 07:09:50 2001 -Mon May 28 21:12:17 2001 -Wed May 30 01:17:11 2001 -Thu May 31 02:02:53 2001 -Tue May 29 07:49:47 2001 -Sat Jun 2 16:06:10 2001 -Sun Jun 3 16:18:58 2001 -Tue May 29 03:16:58 2001 -Sat Jun 2 01:36:39 2001 -Sat Jun 2 19:42:28 2001 -Sat Jun 2 03:31:29 2001 -Wed May 30 14:28:07 2001 -Wed May 30 13:48:30 2001 -Sun Jun 3 22:24:38 2001 -Tue May 29 08:47:05 2001 -Mon Jun 4 01:10:50 2001 -Fri Jun 1 21:52:26 2001 -Tue May 29 16:47:26 2001 -Sat Jun 2 18:15:31 2001 -Sat Jun 2 05:56:51 2001 -Sun Jun 3 17:56:22 2001 -Sat Jun 2 11:23:49 2001 -Fri Jun 1 13:25:51 2001 -Wed May 30 22:32:03 2001 -Thu May 31 08:20:54 2001 -\N -Thu May 31 19:03:04 2001 -Fri Jun 1 20:11:05 2001 -Sun Jun 3 20:09:52 2001 -Wed May 30 05:56:53 2001 -Sat Jun 2 02:33:53 2001 -Fri Jun 1 23:33:12 2001 -Mon Jun 4 14:27:14 2001 -Sun Jun 3 07:17:52 2001 -Sat Jun 2 14:44:01 2001 -Wed May 30 16:15:42 2001 -\N -Thu May 31 08:24:36 2001 -Mon Jun 4 17:45:29 2001 -Thu May 31 10:46:18 2001 -Tue May 29 11:21:09 2001 -Sat Jun 2 19:27:48 2001 -Sat Jun 2 15:21:37 2001 -Thu May 31 15:07:29 2001 -Mon Jun 4 04:25:42 2001 -Sun Jun 3 19:21:05 2001 -Wed May 30 01:35:52 2001 -\N -Thu May 31 17:05:54 2001 -Thu May 31 02:22:03 2001 -Wed May 30 10:09:01 2001 -Wed May 30 15:36:50 2001 -Wed May 30 03:13:22 2001 -Tue May 29 19:54:54 2001 -Thu May 31 18:58:16 2001 -Fri Jun 1 11:31:40 2001 -Sat Jun 2 11:01:18 2001 -Wed May 30 10:17:52 2001 -\N -Sat Jun 2 04:07:24 2001 -Sat Jun 2 07:29:24 2001 -Fri Jun 1 03:17:40 2001 -Thu May 31 20:49:55 2001 -Mon Jun 4 08:07:37 2001 -Sat Jun 2 01:17:04 2001 -Wed May 30 19:59:30 2001 -Fri Jun 1 17:03:00 2001 -Thu May 31 22:50:11 2001 -Tue May 29 00:14:32 2001 -Sat Jun 2 06:53:18 2001 -Fri Jun 1 02:19:00 2001 -Tue May 29 15:22:30 2001 -Sun Jun 3 10:08:27 2001 -Wed May 30 18:30:36 2001 -Wed May 30 08:57:25 2001 -Tue May 29 06:59:32 2001 -Wed May 30 06:29:04 2001 -Tue May 29 13:16:29 2001 -Thu May 31 08:24:46 2001 -Thu May 31 20:50:41 2001 -\N -Wed May 30 20:34:27 2001 -Wed May 30 17:14:44 2001 -Tue May 29 13:06:28 2001 -Sun Jun 3 09:49:45 2001 -Thu May 31 11:11:56 2001 -Tue May 29 06:37:34 2001 -Mon May 28 22:38:25 2001 -Sat Jun 2 07:51:04 2001 -\N -Wed May 30 03:53:04 2001 -Tue May 29 00:01:38 2001 -Fri Jun 1 19:23:30 2001 -Thu May 31 08:36:36 2001 -Sun Jun 3 00:04:28 2001 -Thu May 31 02:07:37 2001 -Thu May 31 04:14:15 2001 -Wed May 30 22:23:45 2001 -Mon May 28 22:42:50 2001 -Wed May 30 01:37:14 2001 -Wed May 30 14:03:12 2001 -Sun Jun 3 23:40:54 2001 -Sat Jun 2 14:28:35 2001 -Sat Jun 2 11:48:57 2001 -Mon Jun 4 18:50:42 2001 -Wed May 30 20:56:22 2001 -Sat Jun 2 12:53:46 2001 -\N -Wed May 30 04:14:41 2001 -Thu May 31 02:12:07 2001 -Mon Jun 4 05:52:07 2001 -Fri Jun 1 05:25:34 2001 -Thu May 31 06:19:47 2001 -Mon Jun 4 03:39:58 2001 -Wed May 30 23:59:02 2001 -Sat Jun 2 11:12:50 2001 -Wed May 30 01:51:48 2001 -Sun Jun 3 03:22:55 2001 -Sat Jun 2 23:24:56 2001 -Sun Jun 3 01:37:30 2001 -Sat Jun 2 14:49:14 2001 -Fri Jun 1 09:21:57 2001 -Sun Jun 3 19:08:13 2001 -\N -Wed May 30 17:25:06 2001 -Thu May 31 23:43:31 2001 -Wed May 30 19:30:46 2001 -Sun Jun 3 12:12:08 2001 -Thu May 31 15:20:18 2001 -Thu May 31 22:14:37 2001 -Sun Jun 3 17:26:54 2001 -Wed May 30 18:23:42 2001 -Tue May 29 16:17:51 2001 -Sun Jun 3 02:03:30 2001 -Mon May 28 21:46:57 2001 -Sun Jun 3 15:41:51 2001 -Sat Jun 2 23:10:23 2001 -Tue May 29 02:03:28 2001 -Fri Jun 1 13:40:57 2001 -Sun Jun 3 18:39:05 2001 -Wed May 30 21:55:49 2001 -Thu May 31 23:45:28 2001 -Thu May 31 08:32:38 2001 -Tue May 29 22:11:25 2001 -Wed May 30 02:09:08 2001 -Fri Jun 1 03:04:47 2001 -Mon May 28 21:01:12 2001 -Wed May 30 01:55:13 2001 -\N -Tue May 29 22:52:13 2001 -Wed May 30 01:51:02 2001 -Sun Jun 3 01:34:33 2001 -Wed May 30 15:44:24 2001 -Wed May 30 04:27:54 2001 -Sat Jun 2 20:08:59 2001 -Sat Jun 2 13:11:14 2001 -Sun Jun 3 14:47:03 2001 -Wed May 30 07:41:49 2001 -Tue May 29 05:24:12 2001 -Sat Jun 2 07:03:17 2001 -Thu May 31 08:30:25 2001 -Sun Jun 3 13:48:30 2001 -Wed May 30 11:43:23 2001 -Wed May 30 11:12:01 2001 -Sun Jun 3 09:08:53 2001 -Thu May 31 06:27:12 2001 -Sat Jun 2 02:53:25 2001 -Mon Jun 4 05:23:09 2001 -Sat Jun 2 18:04:07 2001 -\N -Tue May 29 22:54:17 2001 -Sat Jun 2 18:53:11 2001 -Sun Jun 3 23:55:00 2001 -Fri Jun 1 14:56:29 2001 -\N -Sun Jun 3 01:10:21 2001 -Sun Jun 3 13:03:24 2001 -Sat Jun 2 12:44:32 2001 -Tue May 29 05:19:28 2001 -Thu May 31 16:36:01 2001 -Mon Jun 4 15:25:04 2001 -\N -Sun Jun 3 00:58:03 2001 -Thu May 31 10:10:45 2001 -Sun Jun 3 23:10:39 2001 -Thu May 31 17:08:54 2001 -Sat Jun 2 04:44:32 2001 -Mon Jun 4 20:37:32 2001 -Sun Jun 3 14:02:27 2001 -Fri Jun 1 00:15:11 2001 -Wed May 30 19:07:54 2001 -Thu May 31 21:09:07 2001 -Wed May 30 06:43:45 2001 -Thu May 31 17:03:48 2001 -Wed May 30 10:34:25 2001 -Thu May 31 19:30:19 2001 -Wed May 30 03:26:20 2001 -\N -Tue May 29 11:31:43 2001 -Wed May 30 10:41:13 2001 -Sun Jun 3 22:56:30 2001 -Sat Jun 2 11:24:17 2001 -\N -Tue May 29 08:31:26 2001 -Sun Jun 3 07:16:34 2001 -Fri Jun 1 07:03:59 2001 -Thu May 31 04:49:56 2001 -Fri Jun 1 14:39:21 2001 -Sat Jun 2 17:07:43 2001 -Tue May 29 01:49:41 2001 -Fri Jun 1 06:20:26 2001 -Mon Jun 4 05:09:06 2001 -Thu May 31 00:14:27 2001 -Sat Jun 2 17:21:41 2001 -\N -Tue May 29 02:56:39 2001 -Tue May 29 23:27:02 2001 -Mon May 28 23:50:53 2001 -Wed May 30 02:32:23 2001 -Fri Jun 1 12:37:50 2001 -Wed May 30 23:57:32 2001 -Tue May 29 01:50:18 2001 -Mon May 28 22:17:20 2001 -Tue May 29 01:59:52 2001 -Sat Jun 2 18:49:18 2001 -\N -Wed May 30 05:04:26 2001 -Sat Jun 2 19:04:41 2001 -Sun Jun 3 07:07:43 2001 -Thu May 31 12:32:31 2001 -Sat Jun 2 01:24:29 2001 -\N -Wed May 30 19:38:53 2001 -Fri Jun 1 02:48:16 2001 -\N -Wed May 30 16:12:42 2001 -Mon May 28 21:33:51 2001 -Thu May 31 15:02:55 2001 -Sun Jun 3 13:03:45 2001 -Tue May 29 08:44:17 2001 -Wed May 30 21:32:20 2001 -Sun Jun 3 23:50:24 2001 -Tue May 29 00:31:05 2001 -Thu May 31 09:13:07 2001 -Sat Jun 2 11:13:49 2001 -Thu May 31 20:47:16 2001 -Thu May 31 23:08:43 2001 -Wed May 30 11:53:35 2001 -Wed May 30 18:46:04 2001 -Wed May 30 11:35:10 2001 -Wed May 30 02:57:12 2001 -Fri Jun 1 21:02:27 2001 -Sat Jun 2 08:59:07 2001 -\N -Mon Jun 4 11:42:53 2001 -Sun Jun 3 16:53:56 2001 -Tue May 29 17:44:47 2001 -Fri Jun 1 18:51:21 2001 -Sun Jun 3 04:40:51 2001 -Tue May 29 23:47:08 2001 -Fri Jun 1 17:49:14 2001 -Mon Jun 4 09:00:55 2001 -Thu May 31 04:03:50 2001 -Fri Jun 1 12:29:04 2001 -Thu May 31 22:51:45 2001 -Sat Jun 2 03:50:06 2001 -Fri Jun 1 11:15:33 2001 -Sun Jun 3 21:42:22 2001 -Fri Jun 1 20:15:02 2001 -Fri Jun 1 00:28:51 2001 -Tue May 29 03:43:49 2001 -Mon Jun 4 17:44:11 2001 -Sun Jun 3 05:15:34 2001 -Tue May 29 01:38:51 2001 -Thu May 31 15:54:51 2001 -Tue May 29 13:35:33 2001 -Thu May 31 12:27:53 2001 -Thu May 31 01:12:50 2001 -Mon Jun 4 01:07:39 2001 -Fri Jun 1 17:10:46 2001 -Mon Jun 4 00:09:03 2001 -Thu May 31 14:54:00 2001 -Sun Jun 3 02:28:24 2001 -Sat Jun 2 00:26:46 2001 -Fri Jun 1 19:42:57 2001 -Thu May 31 11:55:21 2001 -Fri Jun 1 08:44:49 2001 -Thu May 31 09:32:30 2001 -Thu May 31 22:04:45 2001 -Thu May 31 11:39:08 2001 -Wed May 30 23:20:32 2001 -Mon Jun 4 07:58:17 2001 -\N -Mon Jun 4 15:28:43 2001 -Mon Jun 4 04:26:29 2001 -Wed May 30 03:52:48 2001 -Wed May 30 06:52:21 2001 -Sat Jun 2 13:06:29 2001 -Sun Jun 3 23:04:07 2001 -Sun Jun 3 10:34:38 2001 -Sun Jun 3 02:45:33 2001 -Sun Jun 3 01:43:03 2001 -Wed May 30 11:07:31 2001 -Wed May 30 20:26:35 2001 -Sun Jun 3 18:37:10 2001 -Fri Jun 1 06:53:17 2001 -Thu May 31 21:40:41 2001 -Wed May 30 12:39:25 2001 -Mon Jun 4 16:34:29 2001 -Mon Jun 4 09:50:31 2001 -Sun Jun 3 08:39:42 2001 -Thu May 31 08:03:17 2001 -Wed May 30 11:15:20 2001 -Mon Jun 4 19:43:28 2001 -Sat Jun 2 00:24:36 2001 -Mon Jun 4 01:54:40 2001 -Wed May 30 19:49:56 2001 -Wed May 30 10:53:06 2001 -Mon Jun 4 18:11:15 2001 -Sun Jun 3 01:43:14 2001 -Mon May 28 21:02:47 2001 -\N -Sat Jun 2 01:42:54 2001 -Sat Jun 2 10:15:31 2001 -Thu May 31 15:28:59 2001 -Tue May 29 21:21:39 2001 -Sun Jun 3 20:36:37 2001 -Sun Jun 3 04:50:43 2001 -Fri Jun 1 04:49:37 2001 -Tue May 29 13:13:15 2001 -\N -Fri Jun 1 03:27:34 2001 -Tue May 29 20:30:51 2001 -Wed May 30 23:09:30 2001 -Fri Jun 1 05:11:20 2001 -\N -Sat Jun 2 18:29:35 2001 -Tue May 29 09:21:40 2001 -Mon May 28 23:07:57 2001 -Tue May 29 20:06:18 2001 -Thu May 31 00:36:38 2001 -Tue May 29 11:15:38 2001 -Sun Jun 3 08:41:27 2001 -Wed May 30 19:51:16 2001 -\N -Sat Jun 2 19:50:28 2001 -Sun Jun 3 11:07:04 2001 -Thu May 31 22:56:31 2001 -Thu May 31 02:33:47 2001 -Tue May 29 21:41:08 2001 -Mon Jun 4 20:06:53 2001 -Wed May 30 12:12:35 2001 -Mon May 28 21:05:46 2001 -\N -Fri Jun 1 03:53:06 2001 -Thu May 31 06:10:59 2001 -Sun Jun 3 22:22:20 2001 -Sat Jun 2 08:53:01 2001 -\N -Sun Jun 3 23:03:45 2001 -Wed May 30 04:38:42 2001 -Mon Jun 4 03:47:43 2001 -\N -Wed May 30 13:47:00 2001 -Tue May 29 13:59:04 2001 -Fri Jun 1 08:04:48 2001 -Fri Jun 1 23:10:41 2001 -Sun Jun 3 06:10:43 2001 -Fri Jun 1 09:05:06 2001 -Fri Jun 1 00:58:36 2001 -Wed May 30 23:08:13 2001 -\N -Fri Jun 1 04:39:19 2001 -Tue May 29 05:05:20 2001 -Mon Jun 4 06:34:52 2001 -Mon Jun 4 01:12:51 2001 -Mon Jun 4 19:28:05 2001 -Wed May 30 04:30:02 2001 -Tue May 29 07:06:29 2001 -Mon Jun 4 01:42:10 2001 -Thu May 31 03:47:17 2001 -Sat Jun 2 20:10:24 2001 -Fri Jun 1 13:33:51 2001 -Thu May 31 02:10:40 2001 -Mon Jun 4 11:40:35 2001 -Wed May 30 11:58:20 2001 -Thu May 31 14:21:17 2001 -Fri Jun 1 15:53:58 2001 -Thu May 31 03:15:55 2001 -Sat Jun 2 23:44:52 2001 -Sun Jun 3 06:50:50 2001 -Fri Jun 1 23:37:43 2001 -Wed May 30 04:47:24 2001 -Fri Jun 1 18:37:01 2001 -Mon Jun 4 05:54:07 2001 -Fri Jun 1 05:24:32 2001 -\N -Wed May 30 21:24:31 2001 -Mon Jun 4 07:49:01 2001 -Thu May 31 21:30:47 2001 -Tue May 29 22:04:07 2001 -Tue May 29 20:51:36 2001 -\N -Fri Jun 1 20:47:32 2001 -\N -Wed May 30 18:05:40 2001 -Sun Jun 3 08:32:17 2001 -Mon Jun 4 05:35:49 2001 -Sat Jun 2 17:02:47 2001 -Tue May 29 15:42:04 2001 -Sun Jun 3 03:10:33 2001 -\N -Sat Jun 2 02:57:36 2001 -Mon Jun 4 08:31:49 2001 -Tue May 29 16:46:56 2001 -Mon Jun 4 20:33:33 2001 -Mon Jun 4 09:10:45 2001 -Wed May 30 14:46:43 2001 -\N -Sun Jun 3 05:12:17 2001 -Mon Jun 4 04:12:42 2001 -Sat Jun 2 16:42:20 2001 -Tue May 29 17:29:35 2001 -Tue May 29 16:13:33 2001 -Fri Jun 1 12:46:59 2001 -Thu May 31 11:04:14 2001 -Tue May 29 23:45:19 2001 -\N -Thu May 31 23:42:08 2001 -Mon Jun 4 15:18:56 2001 -Mon Jun 4 20:33:12 2001 -Fri Jun 1 22:20:35 2001 -Wed May 30 12:53:06 2001 -Mon Jun 4 18:29:15 2001 -Sat Jun 2 03:01:22 2001 -\N -Sun Jun 3 04:33:18 2001 -Mon May 28 22:23:42 2001 -Sat Jun 2 05:42:57 2001 -\N -Thu May 31 18:58:14 2001 -Fri Jun 1 17:16:00 2001 -Tue May 29 00:40:26 2001 -Sun Jun 3 09:18:52 2001 -Thu May 31 10:01:25 2001 -Fri Jun 1 08:19:53 2001 -Fri Jun 1 02:15:07 2001 -Thu May 31 11:12:51 2001 -Mon Jun 4 17:36:57 2001 -Mon May 28 21:14:23 2001 -Sun Jun 3 01:10:25 2001 -Wed May 30 22:52:42 2001 -Fri Jun 1 12:41:55 2001 -Sun Jun 3 01:22:21 2001 -Mon Jun 4 00:59:07 2001 -Thu May 31 15:19:57 2001 -Tue May 29 08:47:42 2001 -Tue May 29 06:35:44 2001 -Sun Jun 3 06:41:40 2001 -Fri Jun 1 03:36:12 2001 -Sun Jun 3 06:01:51 2001 -\N -\N -\N -Mon Jun 4 00:35:16 2001 -Sun Jun 3 20:43:44 2001 -Thu May 31 17:03:03 2001 -Sun Jun 3 00:44:32 2001 -Thu May 31 06:26:40 2001 -Mon Jun 4 16:55:01 2001 -Fri Jun 1 23:52:24 2001 -Wed May 30 05:54:54 2001 -Mon Jun 4 01:33:25 2001 -Thu May 31 04:33:42 2001 -Fri Jun 1 03:06:05 2001 -Thu May 31 08:44:54 2001 -Wed May 30 04:50:48 2001 -Thu May 31 23:32:22 2001 -\N -Wed May 30 05:47:17 2001 -Tue May 29 00:14:58 2001 -Wed May 30 16:38:43 2001 -Wed May 30 09:48:16 2001 -Mon Jun 4 07:21:22 2001 -Sat Jun 2 13:18:48 2001 -Thu May 31 01:52:04 2001 -Mon Jun 4 02:11:26 2001 -Sun Jun 3 06:17:29 2001 -Fri Jun 1 14:53:18 2001 -\N -\N -Sun Jun 3 02:05:26 2001 -Sat Jun 2 10:28:04 2001 -Sun Jun 3 04:48:08 2001 -Wed May 30 09:26:19 2001 -Mon May 28 23:34:31 2001 -Sun Jun 3 13:46:32 2001 -Thu May 31 01:07:37 2001 -Sat Jun 2 12:08:18 2001 -\N -Wed May 30 03:40:30 2001 -Tue May 29 18:35:13 2001 -Sun Jun 3 13:56:51 2001 -Fri Jun 1 07:01:52 2001 -Thu May 31 10:31:06 2001 -Fri Jun 1 21:44:46 2001 -Sun Jun 3 00:22:13 2001 -Thu May 31 10:08:26 2001 -Tue May 29 10:49:29 2001 -Fri Jun 1 02:46:00 2001 -Sun Jun 3 02:08:29 2001 -Thu May 31 00:40:41 2001 -Tue May 29 20:26:38 2001 -\N -Wed May 30 04:13:05 2001 -Tue May 29 19:42:52 2001 -Sat Jun 2 08:51:50 2001 -Fri Jun 1 00:02:55 2001 -Mon Jun 4 09:21:49 2001 -\N -Mon May 28 20:47:42 2001 -\N -Sun Jun 3 16:12:38 2001 -Sat Jun 2 12:12:14 2001 -Sat Jun 2 07:08:40 2001 -Sat Jun 2 17:45:38 2001 -Sun Jun 3 10:49:35 2001 -Tue May 29 01:23:15 2001 -Sat Jun 2 09:01:38 2001 -Thu May 31 15:05:25 2001 -Tue May 29 08:02:41 2001 -Thu May 31 16:03:22 2001 -Mon Jun 4 02:21:36 2001 -Thu May 31 09:09:44 2001 -Mon Jun 4 20:33:40 2001 -Fri Jun 1 19:22:33 2001 -Tue May 29 21:46:52 2001 -Tue May 29 16:17:32 2001 -Sun Jun 3 22:54:05 2001 -\N -Sat Jun 2 17:06:31 2001 -Tue May 29 01:23:14 2001 -Fri Jun 1 00:26:49 2001 -Fri Jun 1 08:11:03 2001 -Thu May 31 23:38:11 2001 -Thu May 31 07:24:01 2001 -Mon Jun 4 09:25:23 2001 -Thu May 31 22:13:02 2001 -Sun Jun 3 11:37:32 2001 -Mon Jun 4 03:28:00 2001 -Sun Jun 3 23:43:04 2001 -Thu May 31 03:20:54 2001 -Sun Jun 3 07:29:28 2001 -Fri Jun 1 09:20:51 2001 -Fri Jun 1 03:02:32 2001 -\N -\N -Mon Jun 4 01:20:28 2001 -Tue May 29 17:00:15 2001 -Sun Jun 3 16:37:38 2001 -Thu May 31 15:10:35 2001 -\N -Wed May 30 10:45:33 2001 -Tue May 29 21:35:27 2001 -Thu May 31 11:59:22 2001 -Tue May 29 19:21:17 2001 -Sat Jun 2 02:03:20 2001 -Fri Jun 1 15:22:10 2001 -Sun Jun 3 18:30:25 2001 -Thu May 31 02:06:09 2001 -Tue May 29 14:34:44 2001 -Mon Jun 4 12:25:01 2001 -Tue May 29 00:38:48 2001 -Thu May 31 18:45:03 2001 -Mon Jun 4 04:41:41 2001 -Tue May 29 04:56:23 2001 -Sat Jun 2 16:03:09 2001 -Mon Jun 4 08:55:42 2001 -Sat Jun 2 16:38:42 2001 -\N -\N -Sat Jun 2 00:00:34 2001 -\N -Thu May 31 07:46:00 2001 -Fri Jun 1 08:41:21 2001 -Mon Jun 4 02:31:49 2001 -Wed May 30 03:02:20 2001 -Wed May 30 06:59:57 2001 -Thu May 31 15:19:53 2001 -Sun Jun 3 01:27:16 2001 -Sat Jun 2 01:35:23 2001 -\N -Fri Jun 1 22:27:39 2001 -Sat Jun 2 10:17:13 2001 -Fri Jun 1 13:33:55 2001 -Wed May 30 13:03:05 2001 -Mon Jun 4 11:01:32 2001 -Tue May 29 00:05:35 2001 -Mon Jun 4 00:15:04 2001 -Sat Jun 2 12:17:20 2001 -Sat Jun 2 00:06:55 2001 -Sun Jun 3 20:44:11 2001 -\N -\N -Thu May 31 11:39:15 2001 -Sat Jun 2 19:38:01 2001 -Sat Jun 2 23:25:19 2001 -Thu May 31 18:59:37 2001 -Tue May 29 06:00:36 2001 -Mon Jun 4 10:49:43 2001 -Thu May 31 09:03:07 2001 -Mon Jun 4 03:44:33 2001 -Sun Jun 3 16:48:20 2001 -Sat Jun 2 05:04:30 2001 -Thu May 31 08:15:22 2001 -\N -Mon Jun 4 13:54:06 2001 -Fri Jun 1 08:36:09 2001 -Sat Jun 2 20:22:49 2001 -Mon Jun 4 05:19:25 2001 -Fri Jun 1 10:44:30 2001 -Mon Jun 4 05:06:08 2001 -Sat Jun 2 20:19:29 2001 -Mon Jun 4 17:39:15 2001 -Fri Jun 1 04:16:56 2001 -Fri Jun 1 22:58:31 2001 -Mon Jun 4 20:09:25 2001 -Fri Jun 1 18:14:10 2001 -Sat Jun 2 08:24:33 2001 -Wed May 30 17:45:23 2001 -Sat Jun 2 22:08:54 2001 -Fri Jun 1 11:18:21 2001 -Wed May 30 17:19:04 2001 -Sat Jun 2 17:59:07 2001 -Fri Jun 1 06:34:56 2001 -Thu May 31 00:55:58 2001 -Thu May 31 00:10:09 2001 -Wed May 30 20:06:44 2001 -Sat Jun 2 08:54:43 2001 -Wed May 30 04:25:31 2001 -Sun Jun 3 12:44:50 2001 -Mon Jun 4 00:24:19 2001 -Sun Jun 3 01:54:55 2001 -Fri Jun 1 14:44:14 2001 -Thu May 31 18:06:48 2001 -Sat Jun 2 19:51:22 2001 -Tue May 29 14:51:06 2001 -Thu May 31 07:52:28 2001 -Mon Jun 4 16:15:49 2001 -Thu May 31 14:05:11 2001 -Fri Jun 1 09:37:05 2001 -Sun Jun 3 19:18:03 2001 -Thu May 31 02:47:07 2001 -Tue May 29 12:15:12 2001 -Mon Jun 4 17:54:21 2001 -Wed May 30 01:20:40 2001 -Tue May 29 20:30:46 2001 -\N -Fri Jun 1 20:24:23 2001 -Thu May 31 14:29:57 2001 -Sun Jun 3 15:56:14 2001 -\N -Mon Jun 4 01:08:48 2001 -Fri Jun 1 08:43:00 2001 -Sun Jun 3 02:21:13 2001 -Thu May 31 06:05:35 2001 -Wed May 30 22:01:30 2001 -Tue May 29 11:59:52 2001 -Wed May 30 08:57:11 2001 -Mon May 28 22:45:22 2001 -Fri Jun 1 19:57:26 2001 -Thu May 31 11:37:44 2001 -Wed May 30 15:14:58 2001 -Thu May 31 10:33:26 2001 -Thu May 31 22:22:31 2001 -Thu May 31 12:36:52 2001 -Mon Jun 4 01:59:08 2001 -\N -\N -\N -Tue May 29 10:11:09 2001 -\N -Tue May 29 04:12:23 2001 -Mon Jun 4 05:24:35 2001 -Sat Jun 2 12:10:15 2001 -Thu May 31 07:28:51 2001 -Tue May 29 19:39:54 2001 -Tue May 29 15:29:52 2001 -Fri Jun 1 02:54:21 2001 -Wed May 30 13:39:11 2001 -Sun Jun 3 10:13:42 2001 -Sat Jun 2 13:06:33 2001 -Wed May 30 07:39:12 2001 -\N -Sat Jun 2 17:46:35 2001 -Tue May 29 06:50:13 2001 -Sun Jun 3 16:15:59 2001 -\N -Wed May 30 10:58:14 2001 -Sat Jun 2 04:08:45 2001 -Fri Jun 1 08:04:00 2001 -Wed May 30 20:08:33 2001 -Wed May 30 01:04:38 2001 -Thu May 31 10:27:43 2001 -Sat Jun 2 07:40:34 2001 -Tue May 29 10:01:49 2001 -\N -Mon Jun 4 09:52:34 2001 -Tue May 29 22:03:01 2001 -Fri Jun 1 19:54:17 2001 -Sat Jun 2 09:24:29 2001 -Thu May 31 09:31:38 2001 -\N -Sat Jun 2 22:44:40 2001 -Thu May 31 16:58:45 2001 -Mon Jun 4 17:00:14 2001 -Sun Jun 3 22:08:04 2001 -Wed May 30 07:10:04 2001 -Fri Jun 1 02:48:34 2001 -Wed May 30 09:02:47 2001 -Sat Jun 2 17:37:10 2001 -Mon Jun 4 01:12:25 2001 -Wed May 30 11:30:45 2001 -Tue May 29 01:08:38 2001 -Sun Jun 3 18:00:32 2001 -Sat Jun 2 04:53:59 2001 -Mon Jun 4 16:01:01 2001 -\N -Thu May 31 10:31:19 2001 -Wed May 30 19:04:01 2001 -Thu May 31 07:47:32 2001 -Wed May 30 09:14:45 2001 -Tue May 29 10:25:48 2001 -Mon May 28 21:16:26 2001 -Wed May 30 13:41:26 2001 -Sat Jun 2 05:48:37 2001 -\N -Mon Jun 4 10:39:45 2001 -Thu May 31 21:15:25 2001 -Wed May 30 18:47:04 2001 -Sat Jun 2 18:00:19 2001 -Wed May 30 09:14:11 2001 -Tue May 29 02:50:43 2001 -Sat Jun 2 11:20:26 2001 -Fri Jun 1 20:15:58 2001 -Tue May 29 17:25:43 2001 -Wed May 30 10:26:53 2001 -Tue May 29 22:11:34 2001 -Tue May 29 21:22:11 2001 -Wed May 30 02:21:42 2001 -Sun Jun 3 11:21:58 2001 -\N -Thu May 31 01:51:59 2001 -Fri Jun 1 09:58:13 2001 -\N -Tue May 29 20:14:29 2001 -\N -Sun Jun 3 08:41:19 2001 -Thu May 31 15:43:41 2001 -Mon Jun 4 03:27:28 2001 -Mon Jun 4 07:16:48 2001 -Wed May 30 09:20:24 2001 -Thu May 31 05:15:06 2001 -Wed May 30 22:46:04 2001 -Mon May 28 23:09:17 2001 -Sun Jun 3 08:02:34 2001 -Wed May 30 08:10:27 2001 -Mon Jun 4 18:43:37 2001 -Fri Jun 1 09:47:08 2001 -Thu May 31 09:03:03 2001 -Fri Jun 1 08:00:48 2001 -Wed May 30 03:35:09 2001 -Thu May 31 15:34:51 2001 -Fri Jun 1 09:25:56 2001 -Sun Jun 3 00:12:03 2001 -Sat Jun 2 03:10:27 2001 -Sun Jun 3 01:15:17 2001 -Tue May 29 00:50:57 2001 -Sat Jun 2 11:06:55 2001 -Thu May 31 15:10:57 2001 -Fri Jun 1 19:21:27 2001 -Wed May 30 04:20:23 2001 -Mon Jun 4 06:06:45 2001 -Sat Jun 2 00:26:32 2001 -Thu May 31 18:48:31 2001 -Fri Jun 1 18:06:00 2001 -Thu May 31 22:33:26 2001 -Thu May 31 03:12:30 2001 -Fri Jun 1 18:25:34 2001 -Thu May 31 22:15:49 2001 -Thu May 31 23:51:17 2001 -Fri Jun 1 16:26:23 2001 -Sun Jun 3 01:27:34 2001 -Mon Jun 4 16:41:04 2001 -Tue May 29 02:28:50 2001 -Fri Jun 1 00:04:48 2001 -Sat Jun 2 11:07:09 2001 -Sun Jun 3 19:43:03 2001 -Thu May 31 20:00:50 2001 -Fri Jun 1 04:20:25 2001 -Mon Jun 4 15:06:35 2001 -Sat Jun 2 03:59:59 2001 -\N -Fri Jun 1 15:57:05 2001 -\N -Mon Jun 4 19:09:34 2001 -Sat Jun 2 09:13:53 2001 -Mon Jun 4 10:49:00 2001 -Thu May 31 17:35:02 2001 -Mon May 28 21:33:09 2001 -Sat Jun 2 23:57:28 2001 -Tue May 29 03:02:15 2001 -Thu May 31 13:51:11 2001 -Wed May 30 00:39:37 2001 -Wed May 30 20:21:00 2001 -\N -Wed May 30 08:31:34 2001 -Tue May 29 22:23:46 2001 -Mon Jun 4 13:34:50 2001 -Tue May 29 22:44:31 2001 -Sun Jun 3 01:03:16 2001 -Sat Jun 2 03:35:51 2001 -Thu May 31 21:35:27 2001 -Thu May 31 05:51:43 2001 -Sun Jun 3 23:45:46 2001 -Tue May 29 23:43:03 2001 -Sun Jun 3 08:38:33 2001 -Thu May 31 02:42:18 2001 -Mon Jun 4 00:11:42 2001 -Sun Jun 3 11:45:05 2001 -Sat Jun 2 16:45:14 2001 -\N -Mon Jun 4 14:57:51 2001 -Tue May 29 12:45:16 2001 -Wed May 30 18:55:42 2001 -Sat Jun 2 15:32:50 2001 -Sat Jun 2 18:05:21 2001 -Sat Jun 2 11:17:04 2001 -Tue May 29 17:55:19 2001 -Sat Jun 2 11:01:19 2001 -Sat Jun 2 14:25:20 2001 -Sun Jun 3 06:04:47 2001 -Mon Jun 4 07:17:11 2001 -Sun Jun 3 18:30:47 2001 -Mon Jun 4 17:43:58 2001 -Sat Jun 2 14:50:46 2001 -Wed May 30 05:12:48 2001 -Tue May 29 03:19:28 2001 -\N -Tue May 29 23:52:10 2001 -Wed May 30 20:53:02 2001 -Wed May 30 21:57:59 2001 -Sun Jun 3 13:54:02 2001 -\N -Wed May 30 07:36:16 2001 -Wed May 30 05:23:34 2001 -Tue May 29 15:11:32 2001 -Fri Jun 1 10:34:11 2001 -Sat Jun 2 19:20:29 2001 -Mon May 28 23:29:37 2001 -Tue May 29 05:16:03 2001 -Sun Jun 3 18:30:00 2001 -\N -\N -Sat Jun 2 23:55:01 2001 -\N -\N -Fri Jun 1 22:02:29 2001 -Mon Jun 4 18:36:37 2001 -Fri Jun 1 22:30:27 2001 -Thu May 31 08:35:03 2001 -Tue May 29 23:17:47 2001 -Wed May 30 10:38:34 2001 -Wed May 30 17:38:03 2001 -Tue May 29 20:11:39 2001 -Thu May 31 01:02:00 2001 -Fri Jun 1 00:18:08 2001 -Wed May 30 16:43:19 2001 -Sun Jun 3 06:24:18 2001 -Wed May 30 01:43:00 2001 -Sun Jun 3 18:18:07 2001 -Sat Jun 2 23:46:58 2001 -Sat Jun 2 15:39:12 2001 -Mon May 28 23:32:18 2001 -Fri Jun 1 05:14:51 2001 -Tue May 29 11:56:47 2001 -Tue May 29 08:16:59 2001 -Sat Jun 2 05:26:56 2001 -Fri Jun 1 03:55:01 2001 -Wed May 30 00:59:31 2001 -Thu May 31 05:19:37 2001 -Wed May 30 17:11:22 2001 -\N -Fri Jun 1 06:44:57 2001 -Tue May 29 00:12:11 2001 -Wed May 30 08:40:02 2001 -Sat Jun 2 13:18:32 2001 -Tue May 29 05:29:48 2001 -Tue May 29 04:57:40 2001 -Thu May 31 18:15:39 2001 -Thu May 31 15:54:26 2001 -Sat Jun 2 15:26:32 2001 -Fri Jun 1 01:50:55 2001 -\N -\N -Wed May 30 06:09:02 2001 -Sun Jun 3 08:33:33 2001 -Thu May 31 18:37:41 2001 -Sun Jun 3 03:45:31 2001 -Wed May 30 05:39:36 2001 -Tue May 29 13:26:37 2001 -Sun Jun 3 08:52:50 2001 -Wed May 30 05:31:07 2001 -Mon Jun 4 05:42:06 2001 -\N -Thu May 31 11:08:02 2001 -Mon Jun 4 11:43:38 2001 -Mon Jun 4 16:57:34 2001 -Sun Jun 3 02:27:59 2001 -Sun Jun 3 06:17:20 2001 -Mon Jun 4 16:28:26 2001 -Wed May 30 01:10:30 2001 -Sat Jun 2 20:29:35 2001 -Tue May 29 01:41:22 2001 -Tue May 29 18:25:46 2001 -Tue May 29 23:20:17 2001 -Mon Jun 4 06:25:51 2001 -Sun Jun 3 10:51:58 2001 -Fri Jun 1 04:58:46 2001 -Wed May 30 14:42:19 2001 -\N -Thu May 31 17:27:52 2001 -Thu May 31 22:57:20 2001 -Wed May 30 10:29:59 2001 -Sun Jun 3 16:35:53 2001 -Sat Jun 2 16:59:23 2001 -Wed May 30 05:11:44 2001 -Fri Jun 1 13:47:01 2001 -Mon Jun 4 11:46:01 2001 -Mon Jun 4 02:59:47 2001 -\N -Thu May 31 22:14:50 2001 -\N -Sun Jun 3 12:32:00 2001 -Tue May 29 12:40:55 2001 -Thu May 31 15:03:50 2001 -Thu May 31 10:52:21 2001 -Fri Jun 1 21:57:09 2001 -Sun Jun 3 01:46:18 2001 -Sat Jun 2 22:09:17 2001 -Sat Jun 2 10:02:36 2001 -Fri Jun 1 19:22:54 2001 -Wed May 30 22:10:36 2001 -Sun Jun 3 12:51:15 2001 -Thu May 31 22:15:01 2001 -Sun Jun 3 12:53:11 2001 -Mon Jun 4 12:38:50 2001 -Sun Jun 3 12:32:48 2001 -Mon Jun 4 06:58:26 2001 -Sun Jun 3 16:38:46 2001 -Fri Jun 1 18:25:56 2001 -Sun Jun 3 01:18:29 2001 -Sun Jun 3 06:53:41 2001 -Fri Jun 1 01:21:40 2001 -Fri Jun 1 23:55:58 2001 -Mon Jun 4 06:48:52 2001 -Wed May 30 15:02:56 2001 -Sun Jun 3 09:39:30 2001 -Wed May 30 22:21:37 2001 -Fri Jun 1 02:14:43 2001 -Thu May 31 06:59:11 2001 -Thu May 31 04:29:50 2001 -Mon Jun 4 10:23:29 2001 -Mon Jun 4 17:11:31 2001 -\N -Sun Jun 3 11:03:19 2001 -Fri Jun 1 09:44:07 2001 diff --git a/contrib/btree_gist/expected/btree_gist.out b/contrib/btree_gist/expected/btree_gist.out deleted file mode 100644 index 2c7cbd620e..0000000000 --- a/contrib/btree_gist/expected/btree_gist.out +++ /dev/null @@ -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) - diff --git a/contrib/btree_gist/sql/btree_gist.sql b/contrib/btree_gist/sql/btree_gist.sql deleted file mode 100644 index 31c778b747..0000000000 --- a/contrib/btree_gist/sql/btree_gist.sql +++ /dev/null @@ -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'; - diff --git a/contrib/chkpass/Makefile b/contrib/chkpass/Makefile deleted file mode 100644 index afa9ee46fa..0000000000 --- a/contrib/chkpass/Makefile +++ /dev/null @@ -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 diff --git a/contrib/chkpass/README.chkpass b/contrib/chkpass/README.chkpass deleted file mode 100644 index 41b0dea99f..0000000000 --- a/contrib/chkpass/README.chkpass +++ /dev/null @@ -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 - diff --git a/contrib/chkpass/chkpass.c b/contrib/chkpass/chkpass.c deleted file mode 100644 index b2e041f5ba..0000000000 --- a/contrib/chkpass/chkpass.c +++ /dev/null @@ -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 -#include -#include -#include -#ifdef HAVE_CRYPT_H -#include -#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); -} diff --git a/contrib/chkpass/chkpass.sql.in b/contrib/chkpass/chkpass.sql.in deleted file mode 100644 index 72ad5e559c..0000000000 --- a/contrib/chkpass/chkpass.sql.in +++ /dev/null @@ -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 --- diff --git a/contrib/contrib-global.mk b/contrib/contrib-global.mk deleted file mode 100644 index 415cc273e7..0000000000 --- a/contrib/contrib-global.mk +++ /dev/null @@ -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 diff --git a/contrib/cube/Makefile b/contrib/cube/Makefile deleted file mode 100644 index 1bf47b90e9..0000000000 --- a/contrib/cube/Makefile +++ /dev/null @@ -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 diff --git a/contrib/cube/README.cube b/contrib/cube/README.cube deleted file mode 100644 index cba90f6744..0000000000 --- a/contrib/cube/README.cube +++ /dev/null @@ -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 diff --git a/contrib/cube/buffer.c b/contrib/cube/buffer.c deleted file mode 100644 index bab7ae303c..0000000000 --- a/contrib/cube/buffer.c +++ /dev/null @@ -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; -} diff --git a/contrib/cube/buffer.h b/contrib/cube/buffer.h deleted file mode 100644 index eef9124dac..0000000000 --- a/contrib/cube/buffer.h +++ /dev/null @@ -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); diff --git a/contrib/cube/cube.c b/contrib/cube/cube.c deleted file mode 100644 index c97e86d3b4..0000000000 --- a/contrib/cube/cube.c +++ /dev/null @@ -1,1174 +0,0 @@ -/****************************************************************************** - This file contains routines that can be bound to a Postgres backend and - called by the backend in the process of processing queries. The calling - format for these routines is dictated by Postgres architecture. -******************************************************************************/ - -#include "postgres.h" - -#include - -#include "access/gist.h" -#include "access/rtree.h" -#include "utils/elog.h" -#include "utils/palloc.h" -#include "utils/builtins.h" - -#include "cubedata.h" - -#define max(a,b) ((a) > (b) ? (a) : (b)) -#define min(a,b) ((a) <= (b) ? (a) : (b)) -#define abs(a) ((a) < (0) ? (-a) : (a)) - -extern void set_parse_buffer(char *str); -extern int cube_yyparse(); - -/* -** Input/Output routines -*/ -NDBOX *cube_in(char *str); -char *cube_out(NDBOX * cube); - - -/* -** GiST support methods -*/ -bool g_cube_consistent(GISTENTRY *entry, NDBOX * query, StrategyNumber strategy); -GISTENTRY *g_cube_compress(GISTENTRY *entry); -GISTENTRY *g_cube_decompress(GISTENTRY *entry); -float *g_cube_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result); -GIST_SPLITVEC *g_cube_picksplit(bytea *entryvec, GIST_SPLITVEC *v); -bool g_cube_leaf_consistent(NDBOX * key, NDBOX * query, StrategyNumber strategy); -bool g_cube_internal_consistent(NDBOX * key, NDBOX * query, StrategyNumber strategy); -NDBOX *g_cube_union(bytea *entryvec, int *sizep); -NDBOX *g_cube_binary_union(NDBOX * r1, NDBOX * r2, int *sizep); -bool *g_cube_same(NDBOX * b1, NDBOX * b2, bool *result); - -/* -** R-tree support functions -*/ -bool cube_same(NDBOX * a, NDBOX * b); -bool cube_different(NDBOX * a, NDBOX * b); -bool cube_contains(NDBOX * a, NDBOX * b); -bool cube_contained(NDBOX * a, NDBOX * b); -bool cube_overlap(NDBOX * a, NDBOX * b); -NDBOX *cube_union(NDBOX * a, NDBOX * b); -NDBOX *cube_inter(NDBOX * a, NDBOX * b); -float *cube_size(NDBOX * a); -void rt_cube_size(NDBOX * a, float *sz); - -/* -** These make no sense for this type, but R-tree wants them -*/ -bool cube_over_left(NDBOX * a, NDBOX * b); -bool cube_over_right(NDBOX * a, NDBOX * b); -bool cube_left(NDBOX * a, NDBOX * b); -bool cube_right(NDBOX * a, NDBOX * b); - -/* -** miscellaneous -*/ -bool cube_lt(NDBOX * a, NDBOX * b); -bool cube_gt(NDBOX * a, NDBOX * b); -float *cube_distance(NDBOX * a, NDBOX * b); - -/* -** Auxiliary funxtions -*/ -static float distance_1D(float a1, float a2, float b1, float b2); -static NDBOX *swap_corners(NDBOX * a); - - -/***************************************************************************** - * Input/Output functions - *****************************************************************************/ - -/* NdBox = [(lowerleft),(upperright)] */ -/* [(xLL(1)...xLL(N)),(xUR(1)...xUR(n))] */ -NDBOX * -cube_in(char *str) -{ - void *result; - - set_parse_buffer(str); - - if (cube_yyparse(&result) != 0) - return NULL; - - return ((NDBOX *) result); -} - -/* - * You might have noticed a slight inconsistency between the following - * declaration and the SQL definition: - * CREATE FUNCTION cube_out(opaque) RETURNS opaque ... - * The reason is that the argument pass into cube_out is really just a - * pointer. POSTGRES thinks all output functions are: - * char *out_func(char *); - */ -char * -cube_out(NDBOX * cube) -{ - char *result; - char *p; - int equal = 1; - int dim = cube->dim; - int i; - - if (cube == NULL) - return (NULL); - - p = result = (char *) palloc(100); - - /* - * while printing the first (LL) corner, check if it is equal to the - * scond one - */ - p += sprintf(p, "("); - for (i = 0; i < dim; i++) - { - p += sprintf(p, "%g", cube->x[i]); - p += sprintf(p, ", "); - if (cube->x[i] != cube->x[i + dim]) - equal = 0; - } - p -= 2; /* get rid of the last ", " */ - p += sprintf(p, ")"); - - if (!equal) - { - p += sprintf(p, ",("); - for (i = dim; i < dim * 2; i++) - { - p += sprintf(p, "%g", cube->x[i]); - p += sprintf(p, ", "); - } - p -= 2; - p += sprintf(p, ")"); - } - - return (result); -} - - -/***************************************************************************** - * GiST functions - *****************************************************************************/ - -/* -** The GiST Consistent method for boxes -** Should return false if for all data items x below entry, -** the predicate x op query == FALSE, where op is the oper -** corresponding to strategy in the pg_amop table. -*/ -bool -g_cube_consistent(GISTENTRY *entry, - NDBOX * query, - StrategyNumber strategy) -{ - /* - * if entry is not leaf, use g_cube_internal_consistent, else use - * g_cube_leaf_consistent - */ - if (GIST_LEAF(entry)) - return g_cube_leaf_consistent((NDBOX *) DatumGetPointer(entry->key), - query, strategy); - else - return g_cube_internal_consistent((NDBOX *) DatumGetPointer(entry->key), - query, strategy); -} - - -/* -** The GiST Union method for boxes -** returns the minimal bounding box that encloses all the entries in entryvec -*/ -NDBOX * -g_cube_union(bytea *entryvec, int *sizep) -{ - int numranges, - i; - NDBOX *out = (NDBOX *) NULL; - NDBOX *tmp; - - /* - * fprintf(stderr, "union\n"); - */ - numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY); - tmp = (NDBOX *) DatumGetPointer((((GISTENTRY *) (VARDATA(entryvec)))[0]).key); - - /* - * sizep = sizeof(NDBOX); -- NDBOX has variable size - */ - *sizep = tmp->size; - - for (i = 1; i < numranges; i++) - { - out = g_cube_binary_union(tmp, (NDBOX *) - DatumGetPointer((((GISTENTRY *) (VARDATA(entryvec)))[i]).key), - sizep); - if (i > 1) - pfree(tmp); - tmp = out; - } - - return (out); -} - -/* -** GiST Compress and Decompress methods for boxes -** do not do anything. -*/ -GISTENTRY * -g_cube_compress(GISTENTRY *entry) -{ - return (entry); -} - -GISTENTRY * -g_cube_decompress(GISTENTRY *entry) -{ - return (entry); -} - -/* -** The GiST Penalty method for boxes -** As in the R-tree paper, we use change in area as our penalty metric -*/ -float * -g_cube_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result) -{ - NDBOX *ud; - float tmp1, - tmp2; - - ud = cube_union((NDBOX *) DatumGetPointer(origentry->key), - (NDBOX *) DatumGetPointer(newentry->key)); - rt_cube_size(ud, &tmp1); - rt_cube_size((NDBOX *) DatumGetPointer(origentry->key), &tmp2); - *result = tmp1 - tmp2; - pfree(ud); - - /* - * fprintf(stderr, "penalty\n"); fprintf(stderr, "\t%g\n", *result); - */ - return (result); -} - - - -/* -** The GiST PickSplit method for boxes -** We use Guttman's poly time split algorithm -*/ -GIST_SPLITVEC * -g_cube_picksplit(bytea *entryvec, - GIST_SPLITVEC *v) -{ - OffsetNumber i, - j; - NDBOX *datum_alpha, - *datum_beta; - NDBOX *datum_l, - *datum_r; - NDBOX *union_d, - *union_dl, - *union_dr; - NDBOX *inter_d; - bool firsttime; - float size_alpha, - size_beta, - size_union, - size_inter; - float size_waste, - waste; - float size_l, - size_r; - int nbytes; - OffsetNumber seed_1 = 0, - seed_2 = 0; - OffsetNumber *left, - *right; - OffsetNumber maxoff; - - /* - * fprintf(stderr, "picksplit\n"); - */ - maxoff = ((VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY)) - 2; - nbytes = (maxoff + 2) * sizeof(OffsetNumber); - v->spl_left = (OffsetNumber *) palloc(nbytes); - v->spl_right = (OffsetNumber *) palloc(nbytes); - - firsttime = true; - waste = 0.0; - - for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i)) - { - datum_alpha = (NDBOX *) DatumGetPointer(((GISTENTRY *) (VARDATA(entryvec)))[i].key); - for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j)) - { - datum_beta = (NDBOX *) DatumGetPointer(((GISTENTRY *) (VARDATA(entryvec)))[j].key); - - /* compute the wasted space by unioning these guys */ - /* size_waste = size_union - size_inter; */ - union_d = cube_union(datum_alpha, datum_beta); - rt_cube_size(union_d, &size_union); - inter_d = cube_inter(datum_alpha, datum_beta); - rt_cube_size(inter_d, &size_inter); - size_waste = size_union - size_inter; - - pfree(union_d); - - if (inter_d != (NDBOX *) NULL) - pfree(inter_d); - - /* - * are these a more promising split than what we've already - * seen? - */ - - if (size_waste > waste || firsttime) - { - waste = size_waste; - seed_1 = i; - seed_2 = j; - firsttime = false; - } - } - } - - left = v->spl_left; - v->spl_nleft = 0; - right = v->spl_right; - v->spl_nright = 0; - - datum_alpha = (NDBOX *) DatumGetPointer(((GISTENTRY *) (VARDATA(entryvec)))[seed_1].key); - datum_l = cube_union(datum_alpha, datum_alpha); - rt_cube_size(datum_l, &size_l); - datum_beta = (NDBOX *) DatumGetPointer(((GISTENTRY *) (VARDATA(entryvec)))[seed_2].key); - datum_r = cube_union(datum_beta, datum_beta); - rt_cube_size(datum_r, &size_r); - - /* - * Now split up the regions between the two seeds. An important - * property of this split algorithm is that the split vector v has the - * indices of items to be split in order in its left and right - * vectors. We exploit this property by doing a merge in the code - * that actually splits the page. - * - * For efficiency, we also place the new index tuple in this loop. This - * is handled at the very end, when we have placed all the existing - * tuples and i == maxoff + 1. - */ - - maxoff = OffsetNumberNext(maxoff); - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) - { - /* - * If we've already decided where to place this item, just put it - * on the right list. Otherwise, we need to figure out which page - * needs the least enlargement in order to store the item. - */ - - if (i == seed_1) - { - *left++ = i; - v->spl_nleft++; - continue; - } - else if (i == seed_2) - { - *right++ = i; - v->spl_nright++; - continue; - } - - /* okay, which page needs least enlargement? */ - datum_alpha = (NDBOX *) DatumGetPointer(((GISTENTRY *) (VARDATA(entryvec)))[i].key); - union_dl = cube_union(datum_l, datum_alpha); - union_dr = cube_union(datum_r, datum_alpha); - rt_cube_size(union_dl, &size_alpha); - rt_cube_size(union_dr, &size_beta); - - /* pick which page to add it to */ - if (size_alpha - size_l < size_beta - size_r) - { - pfree(datum_l); - pfree(union_dr); - datum_l = union_dl; - size_l = size_alpha; - *left++ = i; - v->spl_nleft++; - } - else - { - pfree(datum_r); - pfree(union_dl); - datum_r = union_dr; - size_r = size_alpha; - *right++ = i; - v->spl_nright++; - } - } - *left = *right = FirstOffsetNumber; /* sentinel value, see dosplit() */ - - v->spl_ldatum = PointerGetDatum(datum_l); - v->spl_rdatum = PointerGetDatum(datum_r); - - return v; -} - -/* -** Equality method -*/ -bool * -g_cube_same(NDBOX * b1, NDBOX * b2, bool *result) -{ - if (cube_same(b1, b2)) - *result = TRUE; - else - *result = FALSE; - - /* - * fprintf(stderr, "same: %s\n", (*result ? "TRUE" : "FALSE" )); - */ - return (result); -} - -/* -** SUPPORT ROUTINES -*/ -bool -g_cube_leaf_consistent(NDBOX * key, - NDBOX * query, - StrategyNumber strategy) -{ - bool retval; - - /* - * fprintf(stderr, "leaf_consistent, %d\n", strategy); - */ - switch (strategy) - { - case RTLeftStrategyNumber: - retval = (bool) cube_left(key, query); - break; - case RTOverLeftStrategyNumber: - retval = (bool) cube_over_left(key, query); - break; - case RTOverlapStrategyNumber: - retval = (bool) cube_overlap(key, query); - break; - case RTOverRightStrategyNumber: - retval = (bool) cube_over_right(key, query); - break; - case RTRightStrategyNumber: - retval = (bool) cube_right(key, query); - break; - case RTSameStrategyNumber: - retval = (bool) cube_same(key, query); - break; - case RTContainsStrategyNumber: - retval = (bool) cube_contains(key, query); - break; - case RTContainedByStrategyNumber: - retval = (bool) cube_contained(key, query); - break; - default: - retval = FALSE; - } - return (retval); -} - -bool -g_cube_internal_consistent(NDBOX * key, - NDBOX * query, - StrategyNumber strategy) -{ - bool retval; - - /* - * fprintf(stderr, "internal_consistent, %d\n", strategy); - */ - switch (strategy) - { - case RTLeftStrategyNumber: - case RTOverLeftStrategyNumber: - retval = (bool) cube_over_left(key, query); - break; - case RTOverlapStrategyNumber: - retval = (bool) cube_overlap(key, query); - break; - case RTOverRightStrategyNumber: - case RTRightStrategyNumber: - retval = (bool) cube_right(key, query); - break; - case RTSameStrategyNumber: - case RTContainsStrategyNumber: - retval = (bool) cube_contains(key, query); - break; - case RTContainedByStrategyNumber: - retval = (bool) cube_overlap(key, query); - break; - default: - retval = FALSE; - } - return (retval); -} - -NDBOX * -g_cube_binary_union(NDBOX * r1, NDBOX * r2, int *sizep) -{ - NDBOX *retval; - - retval = cube_union(r1, r2); - *sizep = retval->size; - - return (retval); -} - - -/* cube_union */ -NDBOX * -cube_union(NDBOX * box_a, NDBOX * box_b) -{ - int i; - NDBOX *result; - NDBOX *a = swap_corners(box_a); - NDBOX *b = swap_corners(box_b); - - if (a->dim >= b->dim) - { - result = palloc(a->size); - result->size = a->size; - result->dim = a->dim; - } - else - { - result = palloc(b->size); - result->size = b->size; - result->dim = b->dim; - } - - /* swap the box pointers if needed */ - if (a->dim < b->dim) - { - NDBOX *tmp = b; - - b = a; - a = tmp; - } - - /* - * use the potentially smaller of the two boxes (b) to fill in the - * result, padding absent dimensions with zeroes - */ - for (i = 0; i < b->dim; i++) - { - result->x[i] = b->x[i]; - result->x[i + a->dim] = b->x[i + b->dim]; - } - for (i = b->dim; i < a->dim; i++) - { - result->x[i] = 0; - result->x[i + a->dim] = 0; - } - - /* compute the union */ - for (i = 0; i < a->dim; i++) - result->x[i] = min(a->x[i], result->x[i]); - for (i = a->dim; i < a->dim * 2; i++) - result->x[i] = max(a->x[i], result->x[i]); - - pfree(a); - pfree(b); - - return (result); -} - -/* cube_inter */ -NDBOX * -cube_inter(NDBOX * box_a, NDBOX * box_b) -{ - int i; - NDBOX *result; - NDBOX *a = swap_corners(box_a); - NDBOX *b = swap_corners(box_b); - - if (a->dim >= b->dim) - { - result = palloc(a->size); - result->size = a->size; - result->dim = a->dim; - } - else - { - result = palloc(b->size); - result->size = b->size; - result->dim = b->dim; - } - - /* swap the box pointers if needed */ - if (a->dim < b->dim) - { - NDBOX *tmp = b; - - b = a; - a = tmp; - } - - /* - * use the potentially smaller of the two boxes (b) to fill in the - * result, padding absent dimensions with zeroes - */ - for (i = 0; i < b->dim; i++) - { - result->x[i] = b->x[i]; - result->x[i + a->dim] = b->x[i + b->dim]; - } - for (i = b->dim; i < a->dim; i++) - { - result->x[i] = 0; - result->x[i + a->dim] = 0; - } - - /* compute the intersection */ - for (i = 0; i < a->dim; i++) - result->x[i] = max(a->x[i], result->x[i]); - for (i = a->dim; i < a->dim * 2; i++) - result->x[i] = min(a->x[i], result->x[i]); - - pfree(a); - pfree(b); - - /* - * Is it OK to return a non-null intersection for non-overlapping - * boxes? - */ - return (result); -} - -/* cube_size */ -float * -cube_size(NDBOX * a) -{ - int i, - j; - float *result; - - result = (float *) palloc(sizeof(float)); - - *result = 1.0; - for (i = 0, j = a->dim; i < a->dim; i++, j++) - *result = (*result) * abs((a->x[j] - a->x[i])); - - return (result); -} - -void -rt_cube_size(NDBOX * a, float *size) -{ - int i, - j; - - if (a == (NDBOX *) NULL) - *size = 0.0; - else - { - *size = 1.0; - for (i = 0, j = a->dim; i < a->dim; i++, j++) - *size = (*size) * abs((a->x[j] - a->x[i])); - } - return; -} - -/* The following four methods compare the projections of the boxes - onto the 0-th coordinate axis. These methods are useless for dimensions - larger than 2, but it seems that R-tree requires all its strategies - map to real functions that return something */ - -/* is the right edge of (a) located to the left of - the right edge of (b)? */ -bool -cube_over_left(NDBOX * box_a, NDBOX * box_b) -{ - NDBOX *a; - NDBOX *b; - - if ((box_a == NULL) || (box_b == NULL)) - return (FALSE); - - a = swap_corners(box_a); - b = swap_corners(box_b); - - return (a->x[a->dim - 1] <= b->x[b->dim - 1] && !cube_left(a, b) && !cube_right(a, b)); -} - -/* is the left edge of (a) located to the right of - the left edge of (b)? */ -bool -cube_over_right(NDBOX * box_a, NDBOX * box_b) -{ - NDBOX *a; - NDBOX *b; - - if ((box_a == NULL) || (box_b == NULL)) - return (FALSE); - - a = swap_corners(box_a); - b = swap_corners(box_b); - - return (a->x[a->dim - 1] >= b->x[b->dim - 1] && !cube_left(a, b) && !cube_right(a, b)); -} - - -/* return 'true' if the projection of 'a' is - entirely on the left of the projection of 'b' */ -bool -cube_left(NDBOX * box_a, NDBOX * box_b) -{ - NDBOX *a; - NDBOX *b; - - if ((box_a == NULL) || (box_b == NULL)) - return (FALSE); - - a = swap_corners(box_a); - b = swap_corners(box_b); - - return (a->x[a->dim - 1] < b->x[0]); -} - -/* return 'true' if the projection of 'a' is - entirely on the right of the projection of 'b' */ -bool -cube_right(NDBOX * box_a, NDBOX * box_b) -{ - NDBOX *a; - NDBOX *b; - - if ((box_a == NULL) || (box_b == NULL)) - return (FALSE); - - a = swap_corners(box_a); - b = swap_corners(box_b); - - return (a->x[0] > b->x[b->dim - 1]); -} - -/* make up a metric in which one box will be 'lower' than the other - -- this can be useful for srting and to determine uniqueness */ -bool -cube_lt(NDBOX * box_a, NDBOX * box_b) -{ - int i; - int dim; - NDBOX *a; - NDBOX *b; - - if ((box_a == NULL) || (box_b == NULL)) - return (FALSE); - - a = swap_corners(box_a); - b = swap_corners(box_b); - dim = min(a->dim, b->dim); - - /* - * if all common dimensions are equal, the cube with more dimensions - * wins - */ - if (cube_same(a, b)) - { - if (a->dim < b->dim) - return (TRUE); - else - return (FALSE); - } - - /* compare the common dimensions */ - for (i = 0; i < dim; i++) - { - if (a->x[i] > b->x[i]) - return (FALSE); - if (a->x[i] < b->x[i]) - return (TRUE); - } - for (i = 0; i < dim; i++) - { - if (a->x[i + a->dim] > b->x[i + b->dim]) - return (FALSE); - if (a->x[i + a->dim] < b->x[i + b->dim]) - return (TRUE); - } - - /* compare extra dimensions to zero */ - if (a->dim > b->dim) - { - for (i = dim; i < a->dim; i++) - { - if (a->x[i] > 0) - return (FALSE); - if (a->x[i] < 0) - return (TRUE); - } - for (i = 0; i < dim; i++) - { - if (a->x[i + a->dim] > 0) - return (FALSE); - if (a->x[i + a->dim] < 0) - return (TRUE); - } - } - if (a->dim < b->dim) - { - for (i = dim; i < b->dim; i++) - { - if (b->x[i] > 0) - return (TRUE); - if (b->x[i] < 0) - return (FALSE); - } - for (i = 0; i < dim; i++) - { - if (b->x[i + b->dim] > 0) - return (TRUE); - if (b->x[i + b->dim] < 0) - return (FALSE); - } - } - - return (FALSE); -} - - -bool -cube_gt(NDBOX * box_a, NDBOX * box_b) -{ - int i; - int dim; - NDBOX *a; - NDBOX *b; - - if ((box_a == NULL) || (box_b == NULL)) - return (FALSE); - - a = swap_corners(box_a); - b = swap_corners(box_b); - dim = min(a->dim, b->dim); - - /* - * if all common dimensions are equal, the cube with more dimensions - * wins - */ - if (cube_same(a, b)) - { - if (a->dim > b->dim) - return (TRUE); - else - return (FALSE); - } - - /* compare the common dimensions */ - for (i = 0; i < dim; i++) - { - if (a->x[i] < b->x[i]) - return (FALSE); - if (a->x[i] > b->x[i]) - return (TRUE); - } - for (i = 0; i < dim; i++) - { - if (a->x[i + a->dim] < b->x[i + b->dim]) - return (FALSE); - if (a->x[i + a->dim] > b->x[i + b->dim]) - return (TRUE); - } - - - /* compare extra dimensions to zero */ - if (a->dim > b->dim) - { - for (i = dim; i < a->dim; i++) - { - if (a->x[i] < 0) - return (FALSE); - if (a->x[i] > 0) - return (TRUE); - } - for (i = 0; i < dim; i++) - { - if (a->x[i + a->dim] < 0) - return (FALSE); - if (a->x[i + a->dim] > 0) - return (TRUE); - } - } - if (a->dim < b->dim) - { - for (i = dim; i < b->dim; i++) - { - if (b->x[i] < 0) - return (TRUE); - if (b->x[i] > 0) - return (FALSE); - } - for (i = 0; i < dim; i++) - { - if (b->x[i + b->dim] < 0) - return (TRUE); - if (b->x[i + b->dim] > 0) - return (FALSE); - } - } - - return (FALSE); -} - - -/* Equal */ -bool -cube_same(NDBOX * box_a, NDBOX * box_b) -{ - int i; - NDBOX *a; - NDBOX *b; - - if ((box_a == NULL) || (box_b == NULL)) - return (FALSE); - - a = swap_corners(box_a); - b = swap_corners(box_b); - - /* swap the box pointers if necessary */ - if (a->dim < b->dim) - { - NDBOX *tmp = b; - - b = a; - a = tmp; - } - - for (i = 0; i < b->dim; i++) - { - if (a->x[i] != b->x[i]) - return (FALSE); - if (a->x[i + a->dim] != b->x[i + b->dim]) - return (FALSE); - } - - /* - * all dimensions of (b) are compared to those of (a); instead of - * those in (a) absent in (b), compare (a) to zero - */ - for (i = b->dim; i < a->dim; i++) - { - if (a->x[i] != 0) - return (FALSE); - if (a->x[i + a->dim] != 0) - return (FALSE); - } - - pfree(a); - pfree(b); - - return (TRUE); -} - -/* Different */ -bool -cube_different(NDBOX * box_a, NDBOX * box_b) -{ - return (!cube_same(box_a, box_b)); -} - - -/* Contains */ -/* Box(A) CONTAINS Box(B) IFF pt(A) < pt(B) */ -bool -cube_contains(NDBOX * box_a, NDBOX * box_b) -{ - int i; - NDBOX *a; - NDBOX *b; - - if ((box_a == NULL) || (box_b == NULL)) - return (FALSE); - - a = swap_corners(box_a); - b = swap_corners(box_b); - - if (a->dim < b->dim) - { - /* - * the further comparisons will make sense if the excess - * dimensions of (b) were zeroes - */ - for (i = a->dim; i < b->dim; i++) - { - if (b->x[i] != 0) - return (FALSE); - if (b->x[i + b->dim] != 0) - return (FALSE); - } - } - - /* Can't care less about the excess dimensions of (a), if any */ - for (i = 0; i < min(a->dim, b->dim); i++) - { - if (a->x[i] > b->x[i]) - return (FALSE); - if (a->x[i + a->dim] < b->x[i + b->dim]) - return (FALSE); - } - - pfree(a); - pfree(b); - - return (TRUE); -} - -/* Contained */ -/* Box(A) Contained by Box(B) IFF Box(B) Contains Box(A) */ -bool -cube_contained(NDBOX * a, NDBOX * b) -{ - if (cube_contains(b, a) == TRUE) - return (TRUE); - else - return (FALSE); -} - -/* Overlap */ -/* Box(A) Overlap Box(B) IFF (pt(a)LL < pt(B)UR) && (pt(b)LL < pt(a)UR) */ -bool -cube_overlap(NDBOX * box_a, NDBOX * box_b) -{ - int i; - NDBOX *a; - NDBOX *b; - - /* - * This *very bad* error was found in the source: if ( (a==NULL) || - * (b=NULL) ) return(FALSE); - */ - if ((box_a == NULL) || (box_b == NULL)) - return (FALSE); - - a = swap_corners(box_a); - b = swap_corners(box_b); - - /* swap the box pointers if needed */ - if (a->dim < b->dim) - { - NDBOX *tmp = b; - - b = a; - a = tmp; - } - - /* compare within the dimensions of (b) */ - for (i = 0; i < b->dim; i++) - { - if (a->x[i] > b->x[i + b->dim]) - return (FALSE); - if (a->x[i + a->dim] < b->x[i]) - return (FALSE); - } - - /* compare to zero those dimensions in (a) absent in (b) */ - for (i = b->dim; i < a->dim; i++) - { - if (a->x[i] > 0) - return (FALSE); - if (a->x[i + a->dim] < 0) - return (FALSE); - } - - pfree(a); - pfree(b); - - return (TRUE); -} - - -/* Distance */ -/* The distance is computed as a per axis sum of the squared distances - between 1D projections of the boxes onto Cartesian axes. Assuming zero - distance between overlapping projections, this metric coincides with the - "common sense" geometric distance */ -float * -cube_distance(NDBOX * a, NDBOX * b) -{ - int i; - double d, - distance; - float *result; - - result = (float *) palloc(sizeof(float)); - - /* swap the box pointers if needed */ - if (a->dim < b->dim) - { - NDBOX *tmp = b; - - b = a; - a = tmp; - } - - distance = 0.0; - /* compute within the dimensions of (b) */ - for (i = 0; i < b->dim; i++) - { - d = distance_1D(a->x[i], a->x[i + a->dim], b->x[i], b->x[i + b->dim]); - distance += d * d; - } - - /* compute distance to zero for those dimensions in (a) absent in (b) */ - for (i = b->dim; i < a->dim; i++) - { - d = distance_1D(a->x[i], a->x[i + a->dim], 0.0, 0.0); - distance += d * d; - } - - *result = (float) sqrt(distance); - - return (result); -} - -static float -distance_1D(float a1, float a2, float b1, float b2) -{ - /* interval (a) is entirely on the left of (b) */ - if ((a1 <= b1) && (a2 <= b1) && (a1 <= b2) && (a2 <= b2)) - return (min(b1, b2) - max(a1, a2)); - - /* interval (a) is entirely on the right of (b) */ - if ((a1 > b1) && (a2 > b1) && (a1 > b2) && (a2 > b2)) - return (min(a1, a2) - max(b1, b2)); - - /* the rest are all sorts of intersections */ - return (0.0); -} - -/* normalize the box's co-ordinates by placing min(xLL,xUR) to LL - and max(xLL,xUR) to UR -*/ -static NDBOX * -swap_corners(NDBOX * a) -{ - int i, - j; - NDBOX *result; - - result = palloc(a->size); - result->size = a->size; - result->dim = a->dim; - - for (i = 0, j = a->dim; i < a->dim; i++, j++) - { - result->x[i] = min(a->x[i], a->x[j]); - result->x[j] = max(a->x[i], a->x[j]); - } - - return (result); -} diff --git a/contrib/cube/cube.sql.in b/contrib/cube/cube.sql.in deleted file mode 100644 index a1a78ca9f5..0000000000 --- a/contrib/cube/cube.sql.in +++ /dev/null @@ -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; diff --git a/contrib/cube/cubedata.h b/contrib/cube/cubedata.h deleted file mode 100644 index a1c5e8efcd..0000000000 --- a/contrib/cube/cubedata.h +++ /dev/null @@ -1,6 +0,0 @@ -typedef struct NDBOX -{ - unsigned int size; /* required to be a Postgres varlena type */ - unsigned int dim; - float x[1]; -} NDBOX; diff --git a/contrib/cube/cubeparse.y b/contrib/cube/cubeparse.y deleted file mode 100644 index 33b7c1ef6b..0000000000 --- a/contrib/cube/cubeparse.y +++ /dev/null @@ -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 -#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); -} - diff --git a/contrib/cube/cubescan.l b/contrib/cube/cubescan.l deleted file mode 100644 index e10e7faad8..0000000000 --- a/contrib/cube/cubescan.l +++ /dev/null @@ -1,54 +0,0 @@ -%{ -/* -** A scanner for EMP-style numeric ranges -*/ - -#define YYSTYPE char * -#define yylval cube_yylval - -#include -#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; -} diff --git a/contrib/cube/data/test_cube.data b/contrib/cube/data/test_cube.data deleted file mode 100644 index d67cd122cf..0000000000 --- a/contrib/cube/data/test_cube.data +++ /dev/null @@ -1,3100 +0,0 @@ -(12699,9028),(12654,8987) -(22689,4680),(22614,4626) -(43263,47296),(43217,47217) -(6184,8397),(6182,8379) -(863,28537),(788,28456) -(33783,4733),(33746,4693) -(40456,47134),(40426,47087) -(45950,8153),(45887,8060) -(33433,36474),(33399,36460) -(41106,22017),(41086,21962) -(19214,36781),(19179,36767) -(11582,40823),(11498,40737) -(35565,5404),(35546,5360) -(26489,17387),(26405,17356) -(30874,13849),(30796,13814) -(38255,1619),(38227,1593) -(4445,32006),(4405,31914) -(3923,32921),(3876,32913) -(36054,39464),(36032,39434) -(46540,6780),(46524,6758) -(12184,45811),(12118,45787) -(13198,17090),(13143,17051) -(30939,44578),(30865,44486) -(12502,4939),(12431,4902) -(3250,1108),(3169,1063) -(34029,41240),(33976,41180) -(47057,44018),(46967,43927) -(699,10114),(686,10058) -(5925,26020),(5845,25979) -(9462,39388),(9382,39388) -(270,32616),(226,32607) -(3959,49145),(3861,49115) -(207,40886),(179,40879) -(48480,43312),(48412,43233) -(37183,37209),(37161,37110) -(13576,13505),(13521,13487) -(5877,1037),(5818,1036) -(6777,16694),(6776,16692) -(49362,13905),(49299,13845) -(29356,14606),(29313,14562) -(5492,6976),(5441,6971) -(288,49588),(204,49571) -(36698,37213),(36682,37158) -(718,41336),(645,41272) -(8725,23369),(8660,23333) -(40115,9894),(40025,9818) -(40051,41181),(40015,41153) -(5739,1740),(5715,1731) -(25120,27935),(25054,27876) -(27475,46084),(27447,46003) -(33197,3252),(33161,3245) -(10892,15691),(10869,15662) -(39012,44712),(38995,44640) -(4506,6484),(4458,6459) -(13970,26316),(13964,26236) -(28009,28104),(27968,28030) -(5991,27613),(5906,27607) -(23649,6338),(23610,6314) -(25942,10008),(25911,9928) -(25651,29943),(25590,29906) -(24555,40334),(24546,40330) -(46870,43762),(46789,43709) -(20030,2752),(19945,2687) -(30758,26754),(30718,26678) -(4320,44673),(4286,44625) -(1011,15576),(939,15574) -(41936,40699),(41854,40655) -(20594,19002),(20561,18995) -(9388,41056),(9325,41042) -(34771,46693),(34751,46645) -(49398,46359),(49332,46357) -(23115,35380),(23036,35306) -(46305,34840),(46283,34765) -(16768,21692),(16691,21647) -(28695,3128),(28654,3112) -(22182,7107),(22107,7074) -(14567,1210),(14468,1139) -(14156,37139),(14136,37119) -(33500,38351),(33477,38286) -(39983,41981),(39944,41954) -(26773,20824),(26719,20813) -(42516,22947),(42460,22932) -(26127,10701),(26044,10650) -(17808,13803),(17724,13710) -(14913,49873),(14849,49836) -(37013,820),(36955,736) -(39071,1399),(39022,1381) -(9785,42546),(9687,42540) -(13423,14066),(13354,14052) -(3417,14558),(3336,14478) -(25212,46368),(25128,46316) -(10124,39848),(10027,39820) -(39722,39226),(39656,39162) -(6298,28101),(6250,28076) -(45852,5846),(45809,5750) -(48292,4885),(48290,4841) -(18905,4454),(18894,4424) -(18965,43474),(18902,43444) -(39843,28239),(39761,28199) -(18087,44660),(18019,44632) -(33886,10382),(33794,10286) -(38383,13163),(38362,13092) -(18861,25050),(18842,24965) -(29887,14326),(29806,14274) -(18733,11644),(18698,11644) -(5119,37952),(5089,37950) -(16191,34884),(16149,34864) -(29544,1104),(29496,1062) -(27740,41555),(27701,41540) -(4672,4087),(4633,4060) -(45441,38994),(45377,38958) -(3272,1176),(3232,1146) -(12820,26606),(12790,26575) -(30910,7590),(30877,7512) -(42476,39152),(42377,39127) -(6562,38490),(6542,38447) -(30046,20332),(29988,20259) -(40723,15950),(40671,15949) -(4945,46857),(4908,46817) -(47986,16882),(47963,16877) -(9842,22339),(9805,22305) -(29831,23169),(29818,23122) -(12322,34404),(12250,34312) -(22846,11091),(22759,10992) -(47627,2424),(47603,2397) -(18375,43632),(18347,43577) -(40441,974),(40394,965) -(34260,10573),(34194,10522) -(32914,9549),(32828,9503) -(49023,37827),(48978,37799) -(22183,10691),(22111,10669) -(38036,15828),(38014,15759) -(34604,16801),(34508,16746) -(26737,29997),(26675,29976) -(47375,40298),(47293,40210) -(771,2661),(732,2649) -(28514,25659),(28504,25577) -(13438,46494),(13376,46455) -(7187,17877),(7125,17786) -(49957,43390),(49897,43384) -(26543,20067),(26482,20057) -(16416,29803),(16385,29724) -(36353,7484),(36286,7414) -(26498,3377),(26415,3358) -(28990,32205),(28936,32193) -(45005,3842),(45001,3816) -(21672,23566),(21603,23566) -(33360,43465),(33302,43429) -(29884,9544),(29838,9520) -(5599,15012),(5596,14930) -(22396,21481),(22344,21422) -(24810,14955),(24780,14887) -(47114,18866),(47081,18784) -(39013,39245),(38953,39237) -(12863,40534),(12803,40529) -(351,37068),(310,37019) -(12916,34327),(12891,34240) -(49191,2694),(49170,2628) -(24127,38407),(24050,38325) -(3264,23053),(3213,23007) -(8172,30385),(8144,30336) -(19630,35716),(19573,35640) -(42554,5148),(42521,5117) -(42168,33453),(42136,33426) -(17732,32093),(17666,32057) -(1039,16626),(1037,16587) -(21287,7757),(21265,7679) -(47063,8260),(47039,8225) -(38645,16238),(38561,16204) -(18258,25358),(18196,25341) -(30458,1742),(30458,1695) -(35147,9273),(35121,9233) -(7670,16625),(7642,16545) -(49503,23432),(49484,23383) -(31089,23146),(31062,23093) -(47758,2734),(47670,2703) -(35276,1027),(35259,972) -(26337,17603),(26313,17579) -(35649,16777),(35626,16777) -(42454,5105),(42362,5101) -(21682,24951),(21646,24920) -(48383,25174),(48303,25156) -(14672,3532),(14601,3460) -(22570,22587),(22515,22512) -(23566,25623),(23484,25573) -(9530,24542),(9504,24459) -(41271,451),(41236,401) -(5556,37528),(5502,37527) -(12479,25042),(12447,24991) -(16568,22916),(16499,22864) -(42700,13084),(42676,12992) -(35523,40973),(35504,40932) -(32948,16962),(32857,16901) -(7808,13469),(7712,13469) -(13920,35203),(13870,35131) -(22731,31563),(22658,31557) -(22909,43956),(22900,43857) -(33077,35080),(33074,35030) -(48064,29307),(48022,29280) -(20232,46682),(20212,46613) -(29949,16790),(29867,16711) -(30260,32029),(30180,31979) -(17184,34503),(17110,34482) -(16066,42687),(16039,42648) -(2947,19819),(2857,19788) -(4900,47934),(4818,47894) -(27193,19014),(27174,18976) -(15597,27948),(15590,27939) -(11090,28623),(11002,28589) -(26956,18651),(26920,18620) -(3107,47753),(3103,47711) -(6745,24151),(6711,24083) -(43923,19213),(43871,19124) -(33451,23578),(33370,23534) -(8944,20605),(8862,20601) -(14905,7536),(14892,7441) -(2412,18357),(2383,18354) -(37060,1443),(36974,1366) -(15501,6230),(15429,6190) -(30333,50),(30273,6) -(35567,9965),(35482,9912) -(49847,7128),(49798,7067) -(27685,36396),(27668,36384) -(43832,18491),(43825,18431) -(36849,34600),(36785,34589) -(2348,47938),(2307,47902) -(20473,22131),(20445,22113) -(38486,4293),(38471,4288) -(30611,30451),(30553,30400) -(3883,21299),(3819,21260) -(7696,37555),(7644,37534) -(22399,7913),(22317,7911) -(42565,38605),(42500,38598) -(36595,12151),(36500,12106) -(587,35217),(571,35123) -(5764,15300),(5764,15231) -(12003,21265),(11983,21210) -(42564,4803),(42470,4737) -(42359,36834),(42271,36746) -(44700,14680),(44658,14670) -(19690,5627),(19620,5607) -(17780,43602),(17714,43565) -(45073,3491),(45041,3434) -(35043,2136),(35017,2084) -(39653,19215),(39646,19198) -(23970,25560),(23935,25502) -(28698,49233),(28600,49223) -(30266,3605),(30245,3540) -(25538,7857),(25500,7791) -(17711,1757),(17708,1756) -(5248,594),(5190,587) -(2730,32454),(2671,32436) -(1722,49089),(1635,49067) -(40954,5743),(40921,5722) -(21382,4426),(21298,4331) -(7885,18629),(7872,18605) -(42838,6459),(42748,6451) -(8217,19894),(8207,19845) -(20489,18524),(20433,18520) -(17383,23559),(17309,23515) -(38952,38968),(38934,38913) -(44665,18137),(44636,18051) -(22416,41220),(22383,41213) -(9901,664),(9818,646) -(23475,21981),(23449,21973) -(41875,17991),(41818,17988) -(36517,47731),(36509,47713) -(37595,49849),(37581,49834) -(38771,32720),(38748,32684) -(810,38523),(736,38452) -(29695,14942),(29665,14907) -(31911,15168),(31906,15113) -(3454,36839),(3438,36831) -(4832,47554),(4820,47473) -(11590,8292),(11539,8272) -(8193,33323),(8106,33317) -(16043,14799),(16001,14710) -(19574,11395),(19514,11316) -(26290,41424),(26224,41342) -(22844,12516),(22807,12471) -(15709,49580),(15655,49553) -(13387,28084),(13379,28066) -(2780,38807),(2690,38711) -(22031,32458),(22028,32377) -(13511,3351),(13440,3297) -(14648,26473),(14614,26383) -(17798,19885),(17726,19852) -(32355,27940),(32324,27861) -(43773,21031),(43767,20985) -(15419,45759),(15403,45666) -(770,38863),(729,38806) -(21221,35619),(21183,35596) -(38924,31021),(38894,30961) -(7395,32439),(7345,32416) -(2324,25118),(2268,25074) -(2958,15089),(2935,15087) -(2424,160),(2424,81) -(12123,18644),(12099,18616) -(7459,30276),(7422,30218) -(15847,45488),(15814,45428) -(26409,29897),(26389,29863) -(12336,34322),(12279,34322) -(9440,23550),(9396,23466) -(4991,30850),(4905,30768) -(47262,11940),(47201,11939) -(30584,42868),(30555,42838) -(23144,24089),(23056,24067) -(35930,11609),(35847,11573) -(7812,17271),(7789,17203) -(17946,37554),(17878,37480) -(27356,32869),(27298,32813) -(29971,47783),(29933,47697) -(26075,46494),(25988,46451) -(39314,41366),(39289,41269) -(31708,42900),(31688,42865) -(4510,10231),(4439,10203) -(43806,8482),(43758,8446) -(45990,49694),(45927,49617) -(48815,27640),(48782,27573) -(41675,26733),(41622,26723) -(23229,7709),(23175,7693) -(48976,17733),(48962,17731) -(10686,41470),(10597,41434) -(18053,27059),(17989,27012) -(35495,25950),(35459,25912) -(41896,45014),(41881,44999) -(22654,41896),(22572,41801) -(18581,7087),(18524,6988) -(14697,22406),(14681,22311) -(40092,28122),(40043,28030) -(35844,24243),(35816,24238) -(1254,25653),(1250,25644) -(1603,21730),(1556,21640) -(33048,21779),(32991,21763) -(29979,1632),(29916,1592) -(8620,633),(8580,620) -(22992,27035),(22932,27008) -(21409,29315),(21390,29309) -(3610,44748),(3547,44699) -(20402,9318),(20343,9267) -(31001,8709),(30908,8658) -(46840,47640),(46773,47551) -(49173,4705),(49143,4630) -(5339,31657),(5251,31622) -(8644,49668),(8630,49648) -(45387,2893),(45309,2885) -(47641,31020),(47584,30941) -(40238,10636),(40208,10568) -(19247,36924),(19227,36924) -(917,19957),(827,19887) -(40967,17841),(40870,17820) -(15850,4109),(15794,4085) -(20181,30916),(20085,30870) -(161,24465),(107,24374) -(21737,49690),(21667,49663) -(10328,20911),(10232,20852) -(24187,49823),(24128,49768) -(36084,4578),(36007,4501) -(38771,31741),(38673,31674) -(2202,30102),(2111,30006) -(27322,16074),(27228,16039) -(6843,17280),(6765,17248) -(16972,39744),(16912,39700) -(10608,38741),(10553,38708) -(4917,34801),(4828,34766) -(39281,33659),(39268,33618) -(31706,7119),(31645,7063) -(3427,44006),(3422,44004) -(10134,42608),(10044,42599) -(26294,32080),(26200,32068) -(21777,34680),(21769,34606) -(23373,25957),(23314,25915) -(10710,8401),(10681,8400) -(42062,19458),(42019,19394) -(26530,43036),(26458,43004) -(3394,46081),(3360,46077) -(38743,33953),(38677,33924) -(32438,8226),(32345,8160) -(9210,27333),(9118,27301) -(19594,1600),(19568,1551) -(10003,12278),(9952,12255) -(31737,7206),(31650,7146) -(16594,15821),(16502,15759) -(28208,30296),(28189,30278) -(30602,46237),(30555,46185) -(20715,5155),(20697,5140) -(48892,35271),(48793,35210) -(3175,5590),(3113,5525) -(34220,27947),(34132,27865) -(35105,39792),(35011,39727) -(21919,27314),(21839,27286) -(23963,3723),(23917,3699) -(16312,14078),(16236,14045) -(19233,49824),(19185,49794) -(1447,11768),(1356,11699) -(17311,17709),(17224,17653) -(11962,31709),(11871,31627) -(21355,40131),(21355,40085) -(33750,35273),(33724,35180) -(38896,25539),(38879,25524) -(39569,44899),(39569,44893) -(11075,41547),(11039,41500) -(3215,12202),(3199,12127) -(46215,33458),(46132,33455) -(15121,38012),(15083,37974) -(44448,18726),(44412,18690) -(3899,38263),(3870,38262) -(13854,13353),(13786,13298) -(8252,5402),(8191,5320) -(46849,37968),(46820,37897) -(16422,13957),(16376,13897) -(47369,7665),(47353,7629) -(11982,40874),(11956,40806) -(9552,27580),(9496,27562) -(32247,19399),(32176,19337) -(32704,2169),(32635,2091) -(7471,44213),(7411,44130) -(48433,7096),(48379,7089) -(37357,6543),(37338,6452) -(30460,29624),(30433,29535) -(20350,28794),(20341,28705) -(6326,32360),(6267,32317) -(1711,47519),(1654,47430) -(49540,16510),(49521,16426) -(26975,618),(26908,579) -(24118,30880),(24020,30821) -(3675,15477),(3625,15418) -(44953,9577),(44953,9530) -(38323,7965),(38235,7910) -(6629,36482),(6579,36448) -(33953,16460),(33878,16408) -(49222,16790),(49186,16695) -(17308,16951),(17274,16904) -(14135,6888),(14077,6833) -(38617,47768),(38603,47760) -(7345,10992),(7290,10914) -(35261,42152),(35176,42096) -(28586,4809),(28544,4735) -(37521,25299),(37495,25217) -(41941,17954),(41912,17915) -(1209,46863),(1171,46863) -(20103,34947),(20048,34896) -(32716,33816),(32656,33769) -(11113,6531),(11036,6467) -(48635,7321),(48563,7262) -(28435,37059),(28349,37014) -(12311,17208),(12232,17112) -(1466,48010),(1379,48008) -(11226,11997),(11223,11925) -(46896,32540),(46821,32510) -(32661,31255),(32632,31187) -(37739,20376),(37655,20306) -(44002,43326),(43920,43257) -(30337,1023),(30271,968) -(34436,23357),(34432,23345) -(21367,8168),(21353,8091) -(36370,21611),(36369,21569) -(4152,36488),(4080,36476) -(17696,13924),(17664,13853) -(34252,19395),(34159,19316) -(12574,3072),(12573,2975) -(3995,21243),(3943,21167) -(44553,30126),(44513,30108) -(4599,45275),(4552,45254) -(33191,11404),(33176,11348) -(14245,18633),(14177,18540) -(32457,20705),(32393,20700) -(40052,10499),(40016,10457) -(29824,44065),(29785,44037) -(31613,12565),(31557,12543) -(42692,29000),(42652,28996) -(40680,22219),(40603,22140) -(33575,27661),(33488,27644) -(46194,1385),(46184,1355) -(38442,48501),(38407,48426) -(25305,21544),(25236,21523) -(15562,8226),(15561,8208) -(20844,43614),(20752,43558) -(22566,30541),(22554,30532) -(2760,47802),(2672,47789) -(25515,30745),(25433,30675) -(48382,45134),(48382,45093) -(9940,27094),(9871,27087) -(48690,44361),(48610,44338) -(18992,11585),(18899,11582) -(21551,49983),(21492,49885) -(46778,29113),(46770,29071) -(43219,9593),(43212,9548) -(40291,1248),(40224,1190) -(12687,22225),(12635,22219) -(49372,38790),(49306,38721) -(49503,46808),(49411,46798) -(24745,5162),(24732,5138) -(5046,26517),(5023,26424) -(5583,46538),(5495,46531) -(6084,35950),(6079,35895) -(3503,23096),(3437,23024) -(45275,8420),(45244,8418) -(13514,45251),(13491,45249) -(42112,2748),(42047,2668) -(7810,21907),(7806,21878) -(48378,36029),(48303,35979) -(32568,48605),(32510,48563) -(859,18915),(810,18915) -(41963,17950),(41939,17915) -(42723,8031),(42685,7955) -(19587,5965),(19556,5961) -(8713,33083),(8629,32996) -(21243,7769),(21226,7740) -(43752,43026),(43720,42944) -(7883,41311),(7859,41242) -(10178,47874),(10157,47826) -(32177,48725),(32093,48646) -(22960,2784),(22953,2774) -(25101,49159),(25087,49090) -(32142,48915),(32086,48850) -(6636,44887),(6590,44825) -(37814,11606),(37769,11578) -(2870,23198),(2820,23121) -(21025,16364),(20947,16271) -(31341,36137),(31269,36114) -(38921,7906),(38888,7831) -(6966,17259),(6922,17199) -(32426,13344),(32401,13253) -(8084,30572),(8078,30572) -(42230,47674),(42150,47603) -(20724,44854),(20724,44830) -(27471,38453),(27454,38430) -(24590,37973),(24544,37941) -(45832,26077),(45772,26031) -(9589,24239),(9582,24156) -(37484,49472),(37409,49432) -(30044,19340),(30004,19333) -(16966,14632),(16936,14572) -(9439,40491),(9403,40482) -(28945,5814),(28913,5805) -(43788,41302),(43746,41231) -(33631,43451),(33614,43354) -(17590,49396),(17510,49324) -(15173,32572),(15109,32507) -(1912,23580),(1840,23504) -(38165,16185),(38076,16154) -(6729,1179),(6637,1177) -(6994,45406),(6983,45325) -(2912,21327),(2908,21305) -(14678,14244),(14659,14222) -(29944,14959),(29898,14900) -(47432,35658),(47407,35610) -(25542,39243),(25466,39149) -(5330,7206),(5304,7165) -(24790,27196),(24695,27118) -(38806,1961),(38795,1906) -(23290,4487),(23212,4416) -(35035,24337),(34990,24297) -(5549,38948),(5549,38891) -(24558,15492),(24501,15425) -(4636,3011),(4574,2933) -(26522,39986),(26451,39940) -(33486,18424),(33410,18366) -(36638,14324),(36625,14287) -(35115,41236),(35055,41191) -(31927,16896),(31841,16806) -(5796,43937),(5697,43886) -(25681,41645),(25663,41608) -(10962,42777),(10894,42732) -(32715,11026),(32672,10991) -(45803,20406),(45710,20371) -(34730,17672),(34658,17606) -(8809,6323),(8798,6232) -(39471,23837),(39390,23749) -(34078,17435),(33987,17433) -(9133,4544),(9041,4509) -(47274,29126),(47242,29060) -(6404,28488),(6403,28475) -(48894,49751),(48846,49694) -(17324,43023),(17301,42972) -(15599,8433),(15557,8386) -(48575,10202),(48488,10175) -(27638,24428),(27608,24378) -(45277,47456),(45240,47422) -(26482,46607),(26482,46570) -(41400,33898),(41397,33802) -(49853,18504),(49848,18503) -(11528,25165),(11476,25080) -(49902,41752),(49818,41746) -(1956,47506),(1922,47424) -(21834,22058),(21802,21964) -(19414,21842),(19386,21822) -(34801,13722),(34744,13681) -(13924,29243),(13835,29160) -(47749,21986),(47664,21894) -(47051,39582),(46974,39489) -(31287,49923),(31236,49913) -(47429,8625),(47337,8585) -(46987,44364),(46901,44277) -(16158,27510),(16099,27467) -(41184,6400),(41148,6317) -(1847,42471),(1829,42426) -(14409,48602),(14320,48555) -(38137,42951),(38045,42918) -(42875,2312),(42832,2243) -(27242,30617),(27181,30535) -(24882,44559),(24812,44548) -(22021,1596),(22015,1581) -(24300,1523),(24250,1443) -(43946,35909),(43869,35868) -(816,15988),(776,15967) -(25243,9401),(25237,9332) -(27967,25958),(27928,25949) -(6575,33949),(6484,33900) -(44812,35980),(44800,35913) -(37577,13064),(37495,13019) -(30891,29967),(30814,29884) -(15829,28836),(15753,28807) -(11128,34180),(11126,34117) -(9834,12537),(9801,12508) -(4899,29069),(4809,29024) -(29370,38459),(29276,38382) -(40743,46653),(40647,46559) -(9618,2723),(9578,2631) -(32542,26837),(32515,26769) -(5625,13409),(5576,13355) -(47490,19229),(47472,19203) -(48118,40275),(48063,40203) -(19245,20549),(19227,20546) -(25312,22243),(25280,22164) -(18797,28934),(18723,28881) -(31609,49393),(31512,49366) -(26183,32888),(26135,32824) -(46198,26153),(46180,26149) -(45383,16904),(45353,16888) -(7132,11408),(7091,11338) -(48262,43227),(48236,43159) -(31722,12861),(31675,12810) -(41695,48924),(41691,48921) -(48318,12877),(48287,12802) -(12069,32241),(11978,32231) -(8395,2694),(8380,2661) -(19552,34590),(19550,34497) -(12203,26166),(12187,26143) -(35745,9571),(35654,9542) -(22384,22535),(22352,22439) -(21459,28189),(21360,28189) -(7418,7203),(7343,7182) -(39497,48412),(39413,48318) -(1058,11132),(979,11051) -(45623,31417),(45548,31381) -(23887,31921),(23876,31891) -(7797,1244),(7785,1155) -(23679,43650),(23594,43644) -(21891,30561),(21833,30485) -(4069,6870),(4019,6785) -(5134,25117),(5103,25034) -(36101,41895),(36085,41810) -(39617,39211),(39544,39191) -(37437,6604),(37434,6585) -(7749,32601),(7740,32515) -(26203,34991),(26159,34946) -(31856,39006),(31783,39003) -(45828,24767),(45788,24723) -(49836,35965),(49757,35871) -(44113,49024),(44033,48995) -(38237,22326),(38187,22253) -(45235,19087),(45190,19005) -(1588,45285),(1520,45254) -(46628,8701),(46552,8665) -(47707,18258),(47668,18250) -(9377,26162),(9325,26079) -(28331,16766),(28302,16731) -(15792,27875),(15727,27809) -(16454,1972),(16415,1967) -(21012,15828),(20972,15784) -(27465,30603),(27390,30560) -(39256,7697),(39225,7604) -(25908,32801),(25854,32770) -(25215,40109),(25201,40106) -(23280,4613),(23190,4596) -(32440,30879),(32405,30807) -(49156,4224),(49126,4126) -(20005,40423),(19911,40370) -(20978,8226),(20930,8170) -(32127,22611),(32126,22579) -(21764,26509),(21701,26455) -(32923,2834),(32914,2830) -(7499,25331),(7426,25300) -(6163,36942),(6107,36908) -(41118,14583),(41034,14486) -(21211,33369),(21208,33331) -(7899,27682),(7853,27603) -(16546,48436),(16535,48400) -(24898,40195),(24855,40174) -(43029,982),(43004,952) -(26266,7962),(26252,7950) -(11308,44367),(11210,44322) -(8902,28402),(8808,28334) -(11671,19619),(11665,19549) -(47202,23593),(47153,23505) -(21981,40220),(21905,40160) -(46721,2514),(46687,2471) -(3450,33839),(3424,33811) -(41854,45864),(41762,45792) -(40183,47816),(40114,47742) -(26119,33910),(26077,33816) -(3430,16518),(3365,16500) -(40063,32176),(40005,32166) -(38702,15253),(38679,15187) -(17719,12291),(17658,12257) -(46131,30669),(46068,30587) -(42738,10952),(42731,10907) -(8721,45155),(8650,45076) -(45317,26123),(45244,26113) -(42694,11561),(42614,11490) -(10043,12479),(10009,12391) -(27584,2345),(27578,2257) -(30889,8253),(30866,8167) -(5176,48928),(5107,48838) -(9781,21023),(9745,20976) -(32430,27908),(32404,27859) -(3984,7391),(3973,7352) -(18904,8094),(18842,8091) -(20573,5508),(20482,5496) -(7806,44368),(7753,44297) -(18875,41452),(18817,41376) -(6632,12142),(6566,12079) -(33066,17865),(33055,17854) -(45726,19628),(45714,19589) -(26971,18459),(26941,18423) -(26554,23641),(26515,23592) -(45503,1325),(45441,1231) -(11898,20164),(11880,20115) -(27868,22837),(27843,22776) -(34931,8206),(34855,8144) -(42375,33603),(42350,33539) -(3184,8308),(3129,8238) -(26667,15813),(26661,15785) -(5760,49617),(5730,49546) -(794,27001),(777,26992) -(13518,45289),(13459,45235) -(34430,29754),(34363,29736) -(37912,24574),(37880,24543) -(8130,2270),(8083,2258) -(26930,21516),(26848,21455) -(3634,33511),(3592,33489) -(33080,5036),(33035,4972) -(48389,13942),(48316,13915) -(9231,5298),(9150,5232) -(1357,10601),(1321,10548) -(35175,15295),(35091,15269) -(33917,36863),(33879,36784) -(8279,12052),(8239,12021) -(11868,19083),(11862,19034) -(24019,30777),(24006,30703) -(44619,6959),(44618,6938) -(28610,2626),(28523,2582) -(29579,41801),(29482,41775) -(23448,37609),(23396,37534) -(40676,11252),(40670,11191) -(39656,14077),(39564,13999) -(33060,31042),(33033,30950) -(11720,6816),(11654,6792) -(13775,28873),(13730,28868) -(47851,39121),(47802,39084) -(30923,40255),(30860,40199) -(44169,15070),(44085,15015) -(42574,28664),(42558,28590) -(8993,43487),(8941,43460) -(40782,11648),(40763,11631) -(18516,10143),(18423,10137) -(39068,551),(39005,491) -(39672,12000),(39575,11913) -(18508,37761),(18464,37712) -(19083,35318),(19079,35280) -(30286,13736),(30222,13672) -(7223,9164),(7132,9069) -(20764,29286),(20700,29210) -(5733,8063),(5699,8058) -(8566,43873),(8549,43797) -(22126,27444),(22062,27366) -(15105,8717),(15078,8660) -(43987,33145),(43940,33083) -(46833,38652),(46755,38612) -(47768,27202),(47681,27169) -(22792,1183),(22731,1152) -(25650,43310),(25562,43247) -(37084,20116),(37045,20057) -(47461,32556),(47423,32555) -(41225,18124),(41215,18117) -(17623,25218),(17553,25158) -(13770,21703),(13770,21700) -(48958,35441),(48870,35388) -(2976,1808),(2892,1802) -(45118,22318),(45049,22224) -(42287,26616),(42281,26560) -(25525,6327),(25468,6244) -(40756,31634),(40713,31568) -(23105,26565),(23078,26565) -(48268,39862),(48265,39827) -(41656,26254),(41567,26243) -(28062,17920),(28045,17825) -(6443,17321),(6402,17238) -(10191,45466),(10151,45447) -(18097,39706),(18043,39649) -(37592,3244),(37569,3197) -(29809,5978),(29762,5950) -(12145,11251),(12130,11202) -(37507,42999),(37446,42956) -(10820,2866),(10782,2830) -(36440,42904),(36421,42832) -(38370,3386),(38279,3311) -(9345,17279),(9313,17197) -(20477,14864),(20395,14807) -(37147,37769),(37110,37729) -(15325,36135),(15284,36053) -(29034,32897),(29009,32854) -(2116,22274),(2037,22216) -(15078,38330),(15048,38251) -(7968,33600),(7914,33573) -(832,23851),(770,23786) -(38669,4348),(38594,4344) -(8521,48573),(8425,48564) -(1060,43320),(969,43289) -(26170,10150),(26144,10069) -(32324,8539),(32285,8506) -(13121,18044),(13109,18021) -(1597,9383),(1594,9367) -(49539,35164),(49505,35065) -(39464,10295),(39409,10261) -(8921,37898),(8825,37803) -(31171,47076),(31093,47039) -(7178,41397),(7108,41304) -(16240,34832),(16162,34761) -(2829,20119),(2782,20091) -(45854,21265),(45810,21250) -(6382,12106),(6315,12030) -(22301,46291),(22291,46274) -(34142,14181),(34078,14158) -(11258,29748),(11198,29742) -(37450,6943),(37398,6882) -(41675,27207),(41643,27130) -(13578,49562),(13573,49479) -(37132,37397),(37081,37301) -(49404,37193),(49332,37170) -(33536,31809),(33444,31735) -(45990,42751),(45893,42708) -(38852,20510),(38802,20509) -(27453,15836),(27391,15802) -(9347,29004),(9284,28946) -(44871,27727),(44778,27668) -(14978,19646),(14970,19644) -(23243,47091),(23166,47080) -(45204,21431),(45167,21370) -(14082,22316),(14078,22235) -(42778,22694),(42744,22606) -(4834,25241),(4760,25196) -(20497,18110),(20494,18038) -(45738,35524),(45706,35496) -(21575,5151),(21493,5092) -(2194,10052),(2172,9960) -(47735,24472),(47682,24460) -(46740,35700),(46695,35609) -(24647,42807),(24568,42779) -(18000,30576),(17975,30506) -(48638,46630),(48544,46628) -(48508,33600),(48477,33578) -(38703,45408),(38670,45313) -(21712,15015),(21625,14956) -(5840,42007),(5768,41992) -(44011,11138),(43953,11117) -(3899,33262),(3897,33238) -(30142,23967),(30096,23927) -(36950,13226),(36908,13141) -(13130,26915),(13071,26873) -(38576,35408),(38539,35392) -(16776,46244),(16700,46176) -(38251,25969),(38168,25948) -(3512,32256),(3417,32242) -(31923,31225),(31832,31197) -(5144,4969),(5124,4937) -(34499,46164),(34430,46162) -(39432,31907),(39388,31828) -(17316,24606),(17221,24533) -(20751,49352),(20709,49323) -(41673,30418),(41623,30377) -(29026,24400),(28971,24345) -(21929,30617),(21894,30598) -(35539,12421),(35536,12355) -(24938,45583),(24870,45525) -(27442,33090),(27353,33064) -(23949,12046),(23949,12036) -(11399,377),(11360,294) -(47099,9989),(47023,9942) -(641,33118),(639,33084) -(13687,41308),(13682,41290) -(3682,17727),(3645,17660) -(13262,19396),(13185,19357) -(18791,389),(18774,366) -(12489,45384),(12403,45369) -(12065,6364),(12015,6325) -(32705,23886),(32619,23827) -(7004,37333),(6911,37240) -(28594,38078),(28530,38050) -(5805,21797),(5710,21701) -(41145,18905),(41058,18873) -(35599,10002),(35591,9956) -(5387,39087),(5326,38994) -(11703,14003),(11671,13912) -(4093,10472),(4091,10470) -(14110,49740),(14063,49695) -(4170,470),(4097,463) -(22219,17296),(22164,17221) -(2505,20879),(2446,20842) -(47235,24744),(47151,24667) -(30035,23234),(30013,23197) -(3489,11659),(3461,11607) -(38435,46322),(38429,46230) -(12315,32880),(12277,32854) -(33350,35297),(33317,35263) -(18845,37671),(18836,37589) -(24855,23554),(24783,23520) -(48251,44461),(48188,44408) -(17695,43353),(17605,43286) -(4964,21292),(4893,21270) -(33919,29907),(33852,29878) -(29139,40010),(29084,39957) -(41611,37750),(41572,37741) -(41773,34717),(41682,34700) -(8225,7424),(8221,7363) -(1785,28248),(1771,28219) -(21553,36307),(21505,36257) -(7552,18199),(7527,18119) -(14410,30977),(14349,30944) -(20940,49142),(20901,49069) -(36892,5522),(36810,5478) -(40192,20926),(40179,20926) -(44702,15182),(44641,15117) -(43431,4921),(43337,4827) -(41129,21654),(41084,21642) -(6205,42785),(6113,42722) -(23714,10224),(23666,10205) -(9318,35175),(9274,35139) -(40698,12676),(40618,12627) -(49954,1340),(49905,1294) -(32774,33062),(32763,33062) -(4336,22183),(4241,22157) -(10241,47657),(10151,47592) -(6746,16718),(6666,16634) -(26842,49694),(26839,49680) -(34870,47437),(34820,47347) -(26365,22266),(26326,22183) -(39859,932),(39829,840) -(33995,10888),(33902,10793) -(32972,22342),(32951,22340) -(19951,10161),(19932,10111) -(26779,45188),(26745,45151) -(11235,13593),(11184,13589) -(27334,20968),(27288,20953) -(9586,43102),(9488,43085) -(43935,49759),(43925,49680) -(10548,37032),(10474,36955) -(9326,14927),(9295,14848) -(41340,11312),(41311,11303) -(6500,44553),(6454,44515) -(8198,26841),(8104,26749) -(47761,34183),(47702,34140) -(43637,17912),(43577,17910) -(17623,11138),(17590,11122) -(48122,13132),(48077,13060) -(27911,39796),(27908,39777) -(1108,7918),(1080,7832) -(18776,24329),(18699,24326) -(1171,37901),(1075,37871) -(38437,33948),(38364,33907) -(1913,11593),(1817,11533) -(22684,266),(22656,181) -(13299,17075),(13241,17074) -(6924,30196),(6851,30113) -(4367,13150),(4298,13053) -(37381,6101),(37380,6046) -(10307,28383),(10270,28349) -(12283,8636),(12256,8610) -(20230,32775),(20144,32723) -(32942,12812),(32905,12714) -(46140,7138),(46140,7047) -(37235,29436),(37161,29425) -(42486,25454),(42478,25444) -(47860,46973),(47842,46961) -(41760,21026),(41662,20955) -(29663,20088),(29566,20026) -(19167,33241),(19101,33235) -(12306,37845),(12301,37803) -(11288,873),(11203,857) -(30309,5120),(30282,5060) -(46927,19737),(46856,19687) -(16664,20052),(16649,19989) -(7330,8675),(7296,8613) -(45067,45724),(44991,45631) -(45317,10862),(45218,10842) -(15012,47009),(14998,46956) -(47882,10146),(47813,10099) -(31571,46215),(31511,46148) -(32257,2619),(32187,2531) -(38924,41305),(38872,41285) -(49981,34876),(49898,34786) -(30501,35099),(30418,35011) -(45862,41438),(45854,41434) -(38448,31878),(38391,31822) -(8278,43463),(8274,43378) -(5883,30629),(5878,30564) -(49501,40346),(49447,40275) -(31651,43116),(31560,43106) -(44244,32940),(44244,32926) -(17941,18079),(17938,18035) -(9518,32524),(9470,32511) -(30707,43469),(30686,43457) -(3284,46542),(3187,46477) -(43423,29642),(43393,29602) -(19940,16825),(19877,16736) -(26194,47446),(26194,47407) -(30386,24675),(30333,24652) -(42707,44466),(42688,44456) -(43395,18525),(43320,18467) -(28346,32259),(28276,32196) -(45106,40786),(45026,40767) -(36734,20414),(36722,20363) -(37140,11569),(37099,11475) -(8967,6409),(8882,6341) -(31036,27923),(30993,27890) -(22442,47682),(22347,47663) -(32511,24029),(32482,23970) -(22593,34444),(22519,34399) -(41534,15495),(41518,15455) -(35862,19997),(35818,19928) -(31419,8323),(31404,8285) -(31036,19023),(30978,19000) -(46900,15192),(46891,15102) -(12774,9651),(12765,9604) -(49985,6436),(49927,6338) -(7184,47344),(7089,47285) -(12792,45021),(12740,45011) -(15019,27192),(14940,27096) -(35415,23106),(35381,23095) -(42129,14283),(42095,14245) -(29375,45807),(29347,45743) -(21763,24916),(21700,24889) -(47656,8794),(47579,8774) -(6139,49571),(6059,49472) -(44492,45607),(44483,45532) -(22699,4301),(22628,4240) -(27407,24241),(27335,24158) -(38424,34460),(38403,34458) -(46572,48456),(46554,48402) -(39676,29056),(39643,28981) -(4202,33076),(4107,33010) -(32499,10592),(32482,10575) -(22504,45417),(22459,45378) -(49619,40322),(49619,40268) -(14463,9305),(14426,9224) -(10070,20300),(10035,20211) -(35060,28561),(34965,28553) -(23970,47522),(23887,47428) -(46803,19155),(46790,19131) -(46151,49848),(46058,49830) -(45266,40766),(45209,40738) -(31041,32195),(31007,32110) -(41401,17245),(41334,17224) -(37445,654),(37435,602) -(45568,31904),(45508,31857) -(29326,7923),(29285,7896) -(27078,34643),(27027,34606) -(34492,43443),(34437,43345) -(34109,4307),(34083,4265) -(2755,45325),(2727,45312) -(12571,24218),(12536,24195) -(41224,2454),(41149,2445) -(711,34828),(655,34788) -(9104,18865),(9036,18850) -(3508,26816),(3456,26771) -(20159,16212),(20116,16160) -(36871,7425),(36777,7421) -(2751,45244),(2734,45222) -(35867,28071),(35769,28052) -(46878,35730),(46850,35725) -(20610,35086),(20513,35037) -(3903,32612),(3887,32517) -(9330,40226),(9289,40169) -(6338,28242),(6329,28184) -(35668,18344),(35606,18304) -(29892,48927),(29878,48879) -(26999,646),(26932,612) -(36377,38898),(36338,38847) -(40289,31459),(40236,31436) -(30377,1164),(30306,1069) -(7642,12183),(7590,12112) -(40325,1716),(40296,1662) -(36412,38787),(36318,38691) -(3967,33268),(3923,33261) -(33914,40774),(33873,40763) -(45978,41431),(45963,41332) -(39195,12546),(39120,12520) -(29962,30878),(29941,30846) -(9365,10732),(9310,10726) -(28801,23943),(28740,23885) -(28934,38858),(28928,38807) -(22126,45897),(22068,45803) -(2923,33832),(2918,33751) -(25116,2276),(25083,2272) -(31174,14546),(31144,14460) -(11728,9072),(11658,9004) -(19804,49195),(19730,49125) -(23090,28826),(23010,28787) -(33989,27553),(33947,27486) -(39702,47613),(39641,47553) -(31397,3607),(31304,3519) -(5835,9262),(5791,9226) -(40112,37022),(40038,36926) -(12346,29356),(12282,29344) -(28503,9623),(28469,9591) -(38449,43143),(38378,43066) -(36950,37311),(36905,37265) -(34824,5729),(34818,5706) -(9288,26969),(9225,26900) -(2535,42176),(2478,42159) -(29098,49051),(29085,49031) -(44759,33326),(44727,33230) -(42849,2970),(42821,2919) -(46014,27193),(45985,27151) -(14506,13713),(14417,13626) -(19342,44905),(19332,44895) -(38178,37003),(38147,36925) -(29179,27310),(29084,27288) -(42713,10158),(42671,10060) -(43336,38389),(43290,38326) -(41260,34410),(41245,34327) -(27907,2695),(27830,2596) -(16309,44972),(16222,44966) -(6230,22262),(6214,22249) -(9266,39458),(9175,39447) -(33120,33548),(33087,33538) -(43659,11416),(43599,11375) -(49707,39258),(49702,39159) -(23520,22140),(23486,22072) -(24736,46502),(24668,46412) -(7826,16851),(7730,16807) -(39114,6048),(39056,5965) -(11859,8753),(11764,8701) -(42254,48367),(42240,48328) -(26136,49185),(26056,49175) -(38395,11209),(38334,11137) -(33249,9425),(33209,9348) -(22131,38502),(22112,38460) -(5306,24344),(5267,24268) -(30292,1198),(30233,1149) -(9903,10896),(9850,10806) -(25568,22911),(25487,22868) -(22048,43391),(22043,43362) -(20852,25827),(20851,25766) -(35204,17119),(35114,17093) -(5575,43431),(5554,43410) -(17727,13623),(17678,13560) -(14721,29520),(14709,29461) -(40317,42220),(40267,42166) -(31435,31012),(31386,30931) -(40655,10103),(40645,10006) -(35783,17802),(35773,17763) -(34874,10210),(34856,10200) -(3694,14279),(3610,14239) -(27854,5493),(27799,5433) -(34913,7234),(34894,7220) -(15758,26445),(15738,26421) -(23710,7272),(23705,7270) -(33679,13468),(33628,13415) -(31271,40495),(31178,40461) -(759,187),(662,163) -(14419,40434),(14402,40381) -(45879,42933),(45814,42872) -(167,17214),(92,17184) -(9964,12210),(9958,12195) -(35834,46257),(35817,46211) -(26077,5629),(25978,5621) -(46177,44640),(46082,44544) -(44780,28753),(44707,28692) -(35491,24729),(35425,24690) -(33914,34190),(33914,34131) -(17709,33253),(17668,33227) -(45516,11888),(45423,11848) -(24497,24752),(24411,24710) -(30333,5952),(30331,5886) -(444,12587),(430,12497) -(7592,22353),(7541,22287) -(13387,37414),(13329,37318) -(21504,35227),(21449,35210) -(18533,12909),(18438,12848) -(41049,27148),(41048,27088) -(18205,12222),(18151,12140) -(18026,5164),(18026,5156) -(34104,29862),(34006,29815) -(18520,49686),(18454,49602) -(37000,41493),(36920,41424) -(43025,25711),(42986,25687) -(38620,47018),(38535,46934) -(24119,36813),(24023,36739) -(48887,26359),(48879,26302) -(47827,14625),(47810,14609) -(10792,30746),(10776,30716) -(30384,40672),(30318,40582) -(48417,22790),(48358,22746) -(14854,5819),(14785,5798) -(19142,44414),(19085,44406) -(31179,27081),(31145,27005) -(19692,8711),(19659,8642) -(39689,14082),(39603,14051) -(11181,39091),(11119,39002) -(46015,23374),(45936,23328) -(12517,49702),(12427,49690) -(21926,21137),(21841,21111) -(31956,12509),(31870,12494) -(5895,2030),(5851,2020) -(27094,5447),(27014,5377) -(35781,8717),(35780,8618) -(14012,12023),(13972,12015) -(1702,12442),(1696,12419) -(28549,5251),(28462,5248) -(26441,21007),(26360,20925) -(49820,7990),(49771,7967) -(26424,29698),(26339,29693) -(35146,6820),(35071,6817) -(15438,18788),(15435,18729) -(47115,5235),(47096,5143) -(33982,9002),(33915,8925) -(14206,37041),(14174,36955) -(24300,36616),(24232,36613) -(44658,1788),(44580,1769) -(31539,43550),(31463,43464) -(16722,9673),(16633,9652) -(44813,20573),(44733,20544) -(42114,32559),(42040,32552) -(41561,36244),(41477,36241) -(39589,33796),(39548,33716) -(20365,26770),(20329,26709) -(28511,208),(28479,114) -(10010,25524),(9930,25508) -(1549,45666),(1512,45621) -(16193,1927),(16166,1869) -(34486,11500),(34421,11401) -(14048,37944),(13994,37901) -(21692,9594),(21617,9496) -(2568,37899),(2557,37811) -(4360,24503),(4278,24443) -(50027,49230),(49951,49214) -(44849,14867),(44836,14813) -(16695,34896),(16683,34840) -(12600,35217),(12593,35129) -(23113,24009),(23030,23962) -(49907,30225),(49810,30158) -(18026,25208),(17970,25208) -(49711,39844),(49651,39790) -(5427,42682),(5357,42637) -(23901,14221),(23802,14184) -(15470,12185),(15376,12163) -(47302,34023),(47292,34001) -(24336,17418),(24315,17393) -(13948,17043),(13903,16970) -(8555,8986),(8530,8953) -(48830,6038),(48743,5986) -(48720,40687),(48623,40610) -(21161,30970),(21146,30896) -(9507,36316),(9411,36261) -(36643,18136),(36614,18106) -(1858,7457),(1851,7402) -(24452,44306),(24372,44252) -(3292,807),(3205,806) -(6845,30694),(6792,30627) -(21333,25786),(21237,25751) -(23008,22574),(22999,22511) -(8790,8893),(8772,8806) -(43333,47968),(43264,47900) -(5377,24103),(5302,24076) -(18410,23993),(18329,23907) -(24752,19126),(24713,19069) -(49772,11378),(49696,11293) -(3468,12920),(3396,12873) -(1746,40342),(1736,40333) -(49187,29737),(49139,29681) -(27657,44952),(27581,44917) -(35407,30177),(35345,30151) -(4071,40568),(4058,40544) -(25998,30513),(25965,30452) -(8195,45403),(8097,45310) -(8276,41689),(8183,41670) -(48435,28550),(48355,28455) -(8139,25449),(8136,25380) -(20302,25574),(20297,25531) -(22055,46659),(22034,46567) -(3531,49962),(3463,49934) -(46828,46938),(46739,46902) -(42294,786),(42212,739) -(8779,3292),(8761,3275) -(48146,46170),(48082,46151) -(21571,10000),(21531,9919) -(35526,26029),(35450,25945) -(38893,22225),(38865,22197) -(22189,37520),(22132,37497) -(810,43261),(751,43198) -(10352,39144),(10290,39093) -(8740,35435),(8720,35432) -(31657,13551),(31583,13484) -(39803,4019),(39755,4014) -(46353,7853),(46312,7824) -(30078,48975),(30021,48970) -(2847,32036),(2819,31966) -(25250,10147),(25165,10140) -(15643,38953),(15585,38947) -(40792,29798),(40731,29731) -(43249,26858),(43215,26835) -(47229,2199),(47201,2134) -(10052,23601),(9958,23570) -(38981,21615),(38892,21604) -(3651,45004),(3570,44917) -(21503,8261),(21409,8166) -(13518,34201),(13465,34105) -(13899,25117),(13836,25114) -(18327,17403),(18301,17349) -(19503,13648),(19483,13607) -(3554,19487),(3529,19466) -(41102,43355),(41070,43314) -(4663,45858),(4583,45765) -(3971,3023),(3931,2975) -(37124,7061),(37080,6993) -(48530,47172),(48459,47160) -(14575,29843),(14509,29750) -(43443,23124),(43357,23038) -(8864,48290),(8857,48263) -(41597,39852),(41577,39791) -(35610,33392),(35556,33353) -(36415,17906),(36328,17846) -(24919,43933),(24839,43883) -(7457,14056),(7395,14051) -(43851,4090),(43801,4080) -(43567,18468),(43471,18388) -(16711,6084),(16652,6055) -(45888,45934),(45846,45880) -(45630,9313),(45585,9248) -(27119,25969),(27094,25884) -(36155,11420),(36120,11405) -(41880,47111),(41808,47049) -(17554,20379),(17482,20374) -(38848,5936),(38763,5869) -(28324,31019),(28276,30944) -(43257,17152),(43176,17091) -(42717,24613),(42691,24527) -(16786,41486),(16763,41403) -(19259,28780),(19160,28711) -(25843,28265),(25760,28171) -(48645,34816),(48546,34755) -(7004,49289),(6976,49236) -(30261,21833),(30181,21776) -(5290,46672),(5219,46661) -(21237,31901),(21188,31849) -(23340,38537),(23253,38472) -(17269,3682),(17183,3586) -(48200,15377),(48110,15369) -(16546,22195),(16477,22142) -(21436,8460),(21378,8449) -(46598,17235),(46577,17138) -(30212,36184),(30152,36092) -(18037,155),(17941,109) -(4945,29201),(4933,29184) -(32835,18782),(32770,18750) -(34160,33104),(34120,33007) -(5151,26989),(5149,26909) -(1801,15549),(1710,15461) -(48988,34819),(48951,34764) -(20904,32547),(20856,32497) -(32654,35183),(32606,35144) -(14336,11763),(14328,11712) -(30546,23808),(30463,23773) -(6813,21006),(6781,20924) -(14199,22030),(14185,21934) -(3783,14709),(3747,14658) -(49428,47052),(49422,46973) -(29551,27682),(29470,27654) -(29170,37260),(29151,37181) -(48924,24689),(48894,24680) -(48497,34052),(48453,33966) -(21263,8203),(21242,8176) -(46537,3797),(46462,3735) -(18406,14579),(18393,14563) -(11583,16529),(11536,16471) -(10564,46257),(10478,46228) -(49769,34513),(49761,34458) -(9202,6482),(9138,6391) -(40387,37411),(40357,37360) -(11966,11802),(11888,11751) -(15551,47438),(15486,47406) -(12017,43288),(11969,43230) -(9717,22574),(9701,22495) -(35083,49443),(35075,49355) -(33857,9320),(33813,9269) -(32106,10581),(32012,10560) -(14345,12485),(14273,12424) -(24187,46416),(24175,46402) -(43854,42159),(43808,42129) -(35399,40707),(35359,40646) -(29585,25576),(29493,25556) -(24919,7829),(24911,7753) -(17049,48390),(17022,48304) -(25224,35012),(25217,34922) -(47397,20853),(47346,20779) -(17221,16558),(17181,16516) -(8669,16491),(8645,16486) -(23502,44241),(23484,44164) -(36169,37046),(36072,37010) -(44775,32394),(44763,32357) -(30685,36871),(30662,36792) -(21783,47642),(21714,47630) -(34847,27467),(34761,27372) -(43925,49912),(43888,49878) -(16455,27861),(16364,27813) -(38406,18310),(38329,18309) -(5408,9461),(5319,9426) -(41856,36900),(41784,36854) -(23723,4460),(23646,4448) -(18454,40138),(18430,40046) -(17505,36822),(17418,36763) -(36686,33534),(36641,33476) -(11347,9454),(11289,9436) -(27816,34752),(27745,34736) -(44213,8559),(44162,8461) -(45359,26789),(45315,26776) -(31249,19475),(31224,19421) -(25917,44239),(25819,44149) -(47313,40691),(47264,40685) -(40577,33848),(40513,33794) -(9606,45253),(9582,45174) -(30005,24521),(29910,24496) -(49332,35375),(49309,35299) -(12164,33871),(12075,33820) -(19598,43327),(19593,43314) -(3818,28584),(3815,28504) -(35579,8611),(35541,8604) -(8811,20986),(8750,20954) -(16139,44777),(16128,44686) -(35550,41501),(35534,41458) -(43180,11927),(43109,11891) -(45798,8465),(45711,8460) -(18196,6886),(18126,6845) -(1774,32167),(1701,32073) -(7030,40790),(7029,40711) -(11676,23009),(11665,22915) -(33990,22561),(33953,22474) -(30366,9447),(30284,9353) -(37626,32913),(37596,32853) -(7730,42561),(7665,42470) -(49347,8403),(49315,8387) -(6874,3499),(6812,3458) -(44189,16999),(44169,16964) -(6312,30167),(6231,30083) -(18932,6611),(18909,6518) -(32262,13076),(32223,13057) -(45989,249),(45910,222) -(42710,855),(42692,796) -(25562,9849),(25535,9802) -(13348,46719),(13260,46689) -(30022,42196),(30005,42160) -(22263,45954),(22243,45950) -(18918,18890),(18820,18795) -(31918,12003),(31852,11989) -(12252,39453),(12211,39398) -(40208,9789),(40194,9759) -(35943,21767),(35914,21693) -(18439,10706),(18383,10618) -(2803,18999),(2778,18925) -(14953,27444),(14875,27397) -(12587,22025),(12545,21928) -(33930,21090),(33918,21009) -(10444,2606),(10407,2553) -(28700,29782),(28665,29703) -(1402,13497),(1397,13465) -(24155,3075),(24083,3062) -(38378,1864),(38339,1849) -(29261,49910),(29247,49818) -(38139,37073),(38098,37057) -(24468,41130),(24418,41053) -(9989,1015),(9959,939) -(47001,33561),(46994,33518) -(47058,16030),(46983,16012) -(35509,1814),(35426,1748) -(3630,48019),(3597,47923) -(47781,12986),(47741,12947) -(16364,9908),(16356,9882) -(17290,41508),(17287,41410) -(42423,26477),(42349,26434) -(10039,920),(9952,833) -(16851,21338),(16846,21314) -(23104,7700),(23062,7688) -(5619,2079),(5611,2075) -(31471,49632),(31375,49549) -(25793,12526),(25783,12456) -(3935,29528),(3866,29513) -(5957,1646),(5947,1595) -(2467,22376),(2429,22349) -(43715,32673),(43664,32595) -(6726,13093),(6636,12994) -(31477,18347),(31421,18299) -(34232,36635),(34200,36552) -(49061,14516),(49008,14442) -(43996,6129),(43955,6074) -(7728,33802),(7670,33703) -(6131,36766),(6053,36749) -(35791,16361),(35696,16329) -(45759,8935),(45675,8886) -(43634,2029),(43537,1940) -(4916,32233),(4844,32181) -(46701,23508),(46623,23477) -(29590,4893),(29552,4871) -(38647,4423),(38574,4396) -(7593,25845),(7497,25751) -(8510,43552),(8432,43492) -(18791,39181),(18730,39162) -(7462,2956),(7454,2858) -(1394,26795),(1392,26780) -(16707,21993),(16609,21932) -(26838,10866),(26803,10836) -(31642,29842),(31585,29760) -(21891,3502),(21863,3406) -(13258,587),(13250,507) -(6072,47397),(6021,47369) -(16605,49730),(16579,49659) -(42830,40981),(42791,40981) -(12975,3706),(12913,3637) -(30925,21660),(30826,21649) -(1455,14229),(1410,14156) -(17583,16486),(17562,16474) -(33377,3387),(33333,3381) -(784,6177),(750,6095) -(22111,44110),(22106,44013) -(1444,403),(1346,344) -(4010,46220),(3982,46212) -(17932,8150),(17861,8127) -(38685,31466),(38636,31416) -(14257,11549),(14242,11522) -(14990,15217),(14904,15211) -(21395,21533),(21307,21520) -(31948,33725),(31885,33694) -(433,49033),(390,48961) -(45205,609),(45173,523) -(25065,35494),(25003,35455) -(33265,6677),(33224,6611) -(18179,22345),(18133,22256) -(3916,13759),(3820,13732) -(1696,13478),(1604,13436) -(47203,25980),(47130,25907) -(24913,13361),(24868,13268) -(13824,40177),(13792,40130) -(25671,13555),(25585,13494) -(20133,37769),(20105,37679) -(26368,16734),(26288,16726) -(30545,35438),(30458,35376) -(48816,22926),(48812,22831) -(48807,31389),(48739,31330) -(11003,10859),(10950,10765) -(17288,8570),(17247,8485) -(38377,31415),(38331,31379) -(19085,23425),(19059,23326) -(40059,17068),(40052,17006) -(18811,13493),(18734,13394) -(36319,17197),(36225,17181) -(14939,38780),(14863,38714) -(49539,17656),(49479,17629) -(42530,45951),(42466,45854) -(27318,26654),(27233,26610) -(49980,35004),(49937,34963) -(18326,32558),(18322,32502) -(45951,28555),(45896,28481) -(12104,33531),(12014,33501) -(22311,41113),(22215,41066) -(25073,18721),(25047,18656) -(14524,13486),(14510,13390) -(40040,36688),(40000,36599) -(21594,11473),(21563,11436) -(44031,22274),(43938,22187) -(729,30683),(668,30601) -(14114,20873),(14102,20803) -(28239,41377),(28222,41308) -(26404,11922),(26317,11843) -(41660,34586),(41585,34501) -(21128,2384),(21101,2368) -(30209,16952),(30156,16858) -(39078,24963),(39045,24898) -(5598,1348),(5499,1294) -(38474,7436),(38450,7364) -(15117,45734),(15024,45693) -(23909,39853),(23888,39780) -(24292,30183),(24282,30148) -(48871,17661),(48868,17637) -(918,18752),(847,18708) -(43615,16162),(43606,16104) -(33763,47410),(33751,47409) -(4798,6485),(4773,6388) -(18524,41539),(18433,41518) -(47745,42449),(47651,42364) -(38936,21237),(38864,21204) -(5251,3516),(5194,3475) -(22269,36269),(22183,36228) -(18736,40983),(18685,40947) -(38393,15444),(38356,15363) -(38134,29898),(38103,29862) -(37789,39557),(37732,39474) -(31906,23005),(31838,23003) -(10647,40094),(10560,40040) -(9914,41547),(9867,41545) -(44221,443),(44125,433) -(41479,10936),(41381,10847) -(42586,6301),(42563,6235) -(2504,17588),(2449,17554) -(7045,18782),(7028,18764) -(41840,32018),(41768,31938) -(38416,17158),(38330,17060) -(8605,39015),(8605,38933) -(5764,43548),(5719,43496) -(20789,29902),(20696,29843) -(36104,47896),(36079,47816) -(31736,13834),(31722,13832) -(32617,19701),(32597,19684) -(1671,18997),(1622,18945) -(36007,26545),(36005,26535) -(31864,17494),(31820,17455) -(27346,28388),(27303,28289) -(8191,9653),(8133,9589) -(7501,21616),(7405,21536) -(35450,9580),(35368,9563) -(29281,37276),(29247,37255) -(6225,17192),(6200,17135) -(43689,8119),(43670,8028) -(41917,49601),(41835,49563) -(44295,13116),(44205,13078) -(22721,44772),(22667,44748) -(32640,11107),(32636,11050) -(20639,28851),(20613,28839) -(32479,10159),(32446,10061) -(27251,16978),(27196,16959) -(41401,33148),(41339,33074) -(49001,8538),(48989,8444) -(37958,35843),(37874,35802) -(46969,41229),(46903,41138) -(18541,8876),(18541,8870) -(4080,31634),(4061,31627) -(8097,35240),(8040,35152) -(18470,21414),(18463,21412) -(20914,17897),(20838,17869) -(42688,11681),(42666,11641) -(47525,25005),(47443,24907) -(32439,14438),(32397,14400) -(39667,19626),(39622,19542) -(1212,44525),(1169,44516) -(29766,4433),(29668,4401) -(25847,49657),(25813,49605) -(33859,17356),(33827,17263) -(28989,45953),(28904,45854) -(37211,30830),(37113,30819) -(45220,26382),(45219,26340) -(12312,43250),(12234,43246) -(37775,41504),(37762,41421) -(45889,33499),(45822,33411) -(49461,22601),(49369,22553) -(39857,33844),(39816,33824) -(46102,15822),(46030,15778) -(46605,31239),(46598,31170) -(23925,5856),(23862,5808) -(15459,4262),(15407,4241) -(12019,4907),(12015,4818) -(38258,17973),(38229,17923) -(40575,29566),(40477,29521) -(29715,45919),(29697,45891) -(11694,9510),(11670,9490) -(7053,44257),(7012,44231) -(16465,8603),(16391,8505) -(29170,15592),(29098,15527) -(20400,37354),(20345,37328) -(5281,10265),(5252,10184) -(6084,48782),(6058,48727) -(11006,6889),(10971,6796) -(16299,19461),(16286,19411) -(13718,29192),(13642,29106) -(3999,2965),(3963,2903) -(18509,12235),(18430,12208) -(49542,38575),(49537,38534) -(15093,41715),(15071,41634) -(6802,8385),(6714,8300) -(15127,17507),(15097,17424) -(36921,3025),(36835,2995) -(32117,24327),(32101,24262) -(27244,24151),(27165,24104) -(36339,42360),(36313,42358) -(47288,46252),(47245,46184) -(37867,6649),(37818,6565) -(14886,22103),(14865,22089) -(39611,17952),(39513,17951) -(37329,31436),(37298,31436) -(5715,39115),(5698,39099) -(13266,7364),(13203,7296) -(16076,10945),(16006,10942) -(7197,41509),(7126,41413) -(14411,40868),(14330,40772) -(12872,33481),(12862,33454) -(17786,19616),(17758,19560) -(1052,37358),(996,37311) -(42825,12643),(42762,12625) -(20007,49858),(19921,49778) -(27155,6355),(27072,6257) -(14117,40208),(14022,40155) -(47280,34069),(47279,34028) -(17551,15803),(17482,15763) -(1725,6673),(1676,6649) -(43984,31128),(43961,31105) -(43772,47042),(43731,47038) -(46901,47317),(46817,47228) -(19877,14179),(19837,14168) -(20691,19989),(20675,19935) -(4011,18914),(3963,18817) -(1023,23378),(933,23317) -(30051,46118),(29966,46039) -(43499,46488),(43496,46409) -(43531,2412),(43447,2396) -(16034,32285),(15976,32220) -(12817,21365),(12740,21298) -(7607,47293),(7585,47293) -(32512,12218),(32463,12170) -(1848,21496),(1839,21439) -(17567,23073),(17478,23046) -(35813,31847),(35807,31792) -(563,30859),(540,30842) -(13145,15488),(13063,15433) -(36754,37479),(36731,37411) -(1125,26069),(1057,25997) -(4539,20676),(4519,20618) -(8476,34721),(8409,34681) -(7794,25691),(7727,25656) -(23842,514),(23800,473) -(47678,41396),(47668,41365) -(6837,25974),(6799,25892) -(13355,11174),(13304,11161) -(37243,25548),(37158,25471) -(12528,30208),(12441,30205) -(14929,1672),(14886,1607) -(27263,49026),(27263,49010) -(15892,21645),(15835,21642) -(29446,48978),(29360,48967) -(41304,9892),(41211,9825) -(37418,49393),(37338,49296) -(41146,32178),(41120,32165) -(28738,13326),(28722,13266) -(14899,36595),(14873,36559) -(1973,31435),(1921,31426) -(19485,17742),(19421,17661) -(33072,20995),(32980,20903) -(47091,30055),(47080,30037) -(45753,12998),(45686,12992) -(11528,7826),(11509,7794) -(21104,13921),(21060,13836) -(16768,15491),(16747,15470) -(13279,20396),(13249,20326) -(4342,49518),(4339,49446) -(20413,15476),(20349,15447) -(45532,5649),(45484,5627) -(18647,27196),(18619,27115) -(1326,17473),(1261,17400) -(47646,19644),(47588,19609) -(35088,1813),(35080,1732) -(38461,34839),(38410,34838) -(34358,11540),(34285,11506) -(26969,7078),(26953,6989) -(12629,40352),(12617,40264) -(33800,7037),(33731,6992) -(24462,13518),(24392,13486) -(33164,47357),(33096,47329) -(15422,18451),(15413,18376) -(19643,12916),(19567,12912) -(40860,42125),(40770,42050) -(49103,29614),(49039,29606) -(36319,35582),(36222,35528) -(8924,36083),(8873,36018) -(49603,44022),(49505,44021) -(7783,40633),(7702,40618) -(25388,49107),(25346,49042) -(28375,38947),(28306,38919) -(47324,22672),(47321,22660) -(2287,8808),(2266,8719) -(44343,16339),(44248,16318) -(2374,28839),(2336,28798) -(22913,40710),(22819,40688) -(47747,684),(47658,627) -(16043,46011),(16021,45984) -(34958,32168),(34903,32092) -(4840,49328),(4752,49258) -(24341,2087),(24330,2009) -(18378,19374),(18327,19358) -(48165,7217),(48156,7141) -(14232,6044),(14182,6004) -(23080,4196),(22983,4191) -(259,1850),(175,1820) -(270,29508),(264,29440) -(45088,11375),(45050,11295) -(29666,39386),(29656,39302) -(8712,8782),(8660,8713) -(15900,6650),(15855,6561) -(28946,28348),(28917,28347) -(32544,25845),(32538,25779) -(44047,6957),(43951,6942) -(36465,588),(36382,503) -(28167,26679),(28150,26673) -(16065,4268),(15975,4180) -(12950,23494),(12893,23494) -(30145,24679),(30056,24654) -(3027,16162),(3001,16071) -(8259,34537),(8202,34484) -(41447,1515),(41427,1454) -(18407,28362),(18309,28303) -(21393,41872),(21328,41816) -(46040,26497),(45996,26408) -(49944,25163),(49902,25153) -(16195,11843),(16159,11831) -(44257,15270),(44254,15214) -(49760,4791),(49699,4713) -(22558,33709),(22519,33681) -(28375,10003),(28336,9938) -(18179,24310),(18106,24256) -(707,30688),(664,30669) -(5851,26118),(5822,26037) -(4266,1292),(4221,1217) -(16516,11331),(16432,11248) -(32374,38277),(32313,38245) -(21939,8015),(21927,7952) -(34322,32051),(34242,32003) -(6262,35977),(6260,35953) -(16717,38594),(16622,38498) -(14564,3433),(14535,3425) -(21078,1000),(20994,974) -(28584,956),(28575,868) -(5538,9962),(5465,9870) -(34183,44102),(34175,44085) -(42507,10289),(42441,10288) -(12671,19936),(12594,19920) -(24835,12179),(24770,12173) -(15664,11538),(15598,11494) -(28892,24446),(28821,24350) -(41654,26720),(41570,26632) -(36583,387),(36503,357) -(10842,34824),(10795,34788) -(11518,42588),(11429,42565) -(12577,40322),(12486,40266) -(2453,4045),(2439,3956) -(31837,33705),(31803,33681) -(24403,27711),(24383,27705) -(4431,2748),(4337,2656) -(3036,2887),(3014,2826) -(37664,16118),(37615,16022) -(8606,18063),(8587,18038) -(24738,25458),(24656,25362) -(45756,34022),(45671,33948) -(34079,15236),(33981,15171) -(9251,22488),(9228,22470) -(25136,2809),(25126,2717) -(5548,47695),(5543,47685) -(13765,40800),(13707,40754) -(25216,30678),(25144,30677) -(22441,17169),(22392,17106) -(1091,4770),(1054,4734) -(36311,50073),(36258,49987) -(22461,33163),(22457,33128) -(35873,28907),(35845,28867) -(42907,15848),(42904,15785) -(6549,24897),(6540,24861) -(21928,37764),(21891,37681) -(21237,41132),(21139,41086) -(12207,24266),(12173,24235) -(40643,49770),(40574,49687) -(32833,35686),(32815,35674) -(14545,18143),(14541,18098) -(33892,42783),(33884,42707) -(33933,8381),(33921,8369) -(12450,19044),(12403,19002) -(10176,45158),(10088,45145) -(35828,12080),(35732,12022) -(28102,13694),(28061,13666) -(49432,31744),(49340,31711) -(16192,37743),(16162,37697) -(46830,867),(46756,790) -(9200,28048),(9159,27986) -(13397,19369),(13340,19288) -(30879,43562),(30785,43545) -(21995,48224),(21920,48143) -(11871,47569),(11809,47568) -(29366,22196),(29280,22154) -(26243,28176),(26203,28116) -(28995,35031),(28906,35014) -(29384,39276),(29352,39183) -(8497,13798),(8471,13789) -(7412,27226),(7334,27220) -(25403,47678),(25363,47654) -(11599,5556),(11574,5502) -(44056,5123),(44008,5111) -(49603,30877),(49579,30840) -(32261,45876),(32206,45865) -(35104,41659),(35048,41587) -(5457,35844),(5376,35782) -(29423,3977),(29354,3959) -(18059,3001),(17965,2961) -(8509,5691),(8463,5620) -(27118,5762),(27083,5747) -(2991,48605),(2939,48559) -(44482,3484),(44425,3459) -(45143,16439),(45046,16365) -(2236,37531),(2147,37530) -(41561,3217),(41490,3210) -(6270,27200),(6171,27166) -(49195,24871),(49138,24798) -(46985,38881),(46897,38845) -(37486,23522),(37404,23441) -(26907,14490),(26900,14391) -(30829,16111),(30756,16056) -(3644,17291),(3587,17262) -(20508,49775),(20472,49680) -(43279,8972),(43198,8936) -(33744,7470),(33734,7439) -(46303,20538),(46284,20498) -(10365,48246),(10291,48154) -(12636,24987),(12545,24933) -(40998,46992),(40989,46916) -(30536,6073),(30531,6018) -(22102,9643),(22051,9594) -(18616,34348),(18530,34332) -(8222,8907),(8123,8848) -(45698,28860),(45698,28770) -(26958,1748),(26924,1726) -(26735,35073),(26659,35025) -(48370,40813),(48293,40737) -(13140,993),(13108,934) -(10588,22893),(10528,22883) -(23645,40789),(23567,40698) -(49548,12374),(49546,12329) -(41135,39626),(41100,39602) -(41374,10856),(41328,10769) -(12234,5765),(12146,5674) -(12832,46941),(12764,46917) -(47886,34532),(47851,34500) -(23777,10549),(23735,10495) -(1291,16913),(1194,16873) -(29239,30554),(29202,30500) -(36485,30007),(36454,29924) -(7067,11320),(7045,11229) -(16939,30482),(16904,30462) -(27423,34386),(27379,34303) -(35170,32021),(35155,31979) -(42570,36477),(42474,36457) -(19695,679),(19682,594) -(47537,39450),(47446,39450) -(19410,22942),(19375,22922) -(34216,40166),(34152,40158) -(37000,24351),(36972,24299) -(24989,1681),(24954,1672) -(54,38679),(3,38602) -(41461,40693),(41411,40599) -(7576,46054),(7545,45963) -(35505,28262),(35413,28222) -(1158,16976),(1145,16927) -(23494,42291),(23437,42229) -(32894,32519),(32880,32485) -(604,13413),(509,13401) -(18396,19712),(18355,19646) -(26657,28234),(26597,28191) -(24240,47211),(24154,47191) -(41778,10741),(41766,10730) -(44022,43776),(44010,43677) -(35967,30055),(35906,29969) -(28878,18042),(28806,18027) -(31507,27302),(31428,27267) -(13267,21935),(13265,21872) -(122,46832),(64,46762) -(10348,45916),(10306,45844) -(22962,12644),(22927,12607) -(6320,22290),(6284,22247) -(2297,11372),(2216,11298) -(29366,36660),(29325,36654) -(13962,39307),(13921,39220) -(11094,19151),(11092,19143) -(32289,23776),(32258,23760) -(36044,17356),(35956,17273) -(46304,38692),(46232,38675) -(10934,42999),(10922,42909) -(4271,21177),(4207,21093) -(7837,19926),(7747,19905) -(25537,36605),(25477,36584) -(22161,14999),(22079,14962) -(5127,31243),(5074,31213) -(14904,40664),(14838,40593) -(29308,8480),(29268,8438) -(17731,7410),(17699,7352) -(44840,29293),(44797,29248) -(15523,31519),(15505,31485) -(34429,38479),(34421,38478) -(3530,23456),(3440,23390) -(4699,6889),(4603,6796) -(47405,48524),(47389,48514) -(23357,43160),(23305,43156) -(16923,1995),(16860,1937) -(47592,33853),(47537,33758) -(31624,37490),(31595,37473) -(42321,13380),(42303,13337) -(3088,16094),(3079,16060) -(22884,2955),(22856,2857) -(17784,23073),(17724,23044) -(32638,45577),(32553,45512) -(13876,44091),(13801,44000) -(27844,24384),(27758,24330) -(28178,10225),(28155,10167) -(39910,14277),(39857,14241) -(30372,19524),(30301,19514) -(38732,43151),(38724,43151) -(32628,2068),(32547,2068) -(13950,28652),(13932,28566) -(38996,41070),(38919,40993) -(31759,45246),(31676,45215) -(5424,34145),(5382,34106) -(14727,45600),(14699,45547) -(31429,21537),(31414,21499) -(14740,3420),(14650,3323) -(21793,39498),(21743,39471) -(18102,25924),(18037,25868) -(33299,683),(33213,594) -(45882,48765),(45809,48721) -(49215,4098),(49180,4067) -(49698,33743),(49614,33663) -(21532,5215),(21514,5151) -(24840,26877),(24826,26808) -(32680,28433),(32631,28364) -(20661,27511),(20584,27414) -(28048,30385),(28009,30315) -(45403,42533),(45389,42464) -(46531,36947),(46531,36850) -(36943,32817),(36865,32737) -(37984,43763),(37888,43748) -(20593,10650),(20557,10610) -(5387,40595),(5326,40585) -(34412,10600),(34352,10539) -(7237,47546),(7206,47451) -(39931,26644),(39915,26598) -(29843,4734),(29800,4669) -(37503,8867),(37406,8821) -(2583,2373),(2570,2294) -(29275,46433),(29256,46350) -(3332,45620),(3287,45581) -(22472,39287),(22472,39257) -(36786,18907),(36708,18884) -(45503,28576),(45482,28494) -(33262,28386),(33163,28365) -(3606,49757),(3538,49697) -(2082,49380),(1991,49281) -(12065,3734),(11983,3663) -(15606,9048),(15596,9028) -(14687,19309),(14637,19263) -(4568,15461),(4499,15428) -(43938,7429),(43923,7391) -(2168,50012),(2108,49914) -(16022,8934),(15963,8928) -(24567,39147),(24561,39102) -(42781,14149),(42765,14088) -(39501,21084),(39468,21078) -(6697,29628),(6693,29584) -(11441,16164),(11364,16125) -(39946,1920),(39868,1844) -(18138,45512),(18111,45438) -(20799,41217),(20718,41138) -(30264,16697),(30240,16639) -(30746,50040),(30727,49992) -(37429,43273),(37423,43205) -(22854,28863),(22789,28810) -(11380,48298),(11287,48242) -(16471,37273),(16439,37223) -(32737,39842),(32661,39811) -(30959,3447),(30949,3357) -(36396,13263),(36348,13187) -(29607,14625),(29531,14619) -(7851,43399),(7824,43334) -(38515,14575),(38496,14492) -(29125,3289),(29086,3264) -(6866,10476),(6839,10424) -(318,31489),(235,31404) -(1140,7007),(1113,6945) -(36574,9291),(36484,9275) -(40320,40937),(40246,40866) -(588,25849),(552,25801) -(6728,42539),(6645,42507) -(12180,6185),(12123,6123) -(32913,44123),(32899,44037) -(25464,16803),(25441,16749) -(23711,5829),(23695,5750) -(31424,34930),(31377,34906) -(42171,8298),(42124,8222) -(451,31104),(375,31083) -(39996,3278),(39943,3260) -(25816,40396),(25735,40362) -(34471,28587),(34399,28547) -(45344,21540),(45297,21496) -(27269,16787),(27246,16763) -(18070,4469),(18022,4423) -(12668,16367),(12645,16295) -(13823,17276),(13730,17251) -(20555,45544),(20511,45498) -(35893,42189),(35861,42177) -(37081,45730),(37076,45705) -(17270,15651),(17201,15552) -(48690,46034),(48667,45945) -(456,16088),(368,16023) -(48707,12416),(48670,12363) -(29692,11509),(29614,11483) -(7005,3668),(6981,3574) -(12162,389),(12103,309) -(12371,24983),(12366,24964) -(6886,48414),(6868,48327) -(10653,26234),(10624,26142) -(8526,48205),(8517,48117) -(10521,31892),(10480,31798) -(43353,1086),(43281,1071) -(21007,35650),(20998,35649) -(2343,4396),(2310,4320) -(29379,12895),(29284,12891) -(27662,17407),(27570,17313) -(9845,29346),(9807,29321) -(43855,38669),(43790,38599) -(20461,44189),(20397,44158) -(11627,17368),(11581,17289) -(2971,38855),(2938,38807) -(43204,47082),(43128,47018) -(9930,46902),(9909,46871) -(30561,48461),(30536,48365) -(44059,7591),(44038,7563) -(46260,16898),(46162,16886) -(27491,2891),(27396,2814) -(36512,26034),(36455,25941) -(31193,20022),(31100,19942) -(17057,13643),(16960,13621) -(26897,3399),(26844,3318) -(1760,5504),(1683,5431) -(29347,5511),(29346,5450) -(38761,42083),(38688,41999) -(11226,4089),(11165,4068) -(46427,42983),(46361,42970) -(12958,30737),(12912,30712) -(44432,46521),(44333,46443) -(16124,2948),(16113,2852) -(24704,25422),(24635,25340) -(30833,46152),(30790,46122) -(4487,37006),(4473,36968) -(41047,23376),(41036,23327) -(16312,49392),(16298,49330) -(30081,14687),(30042,14660) -(11160,13954),(11103,13938) -(33207,23246),(33143,23168) -(14872,7635),(14860,7585) -(20139,23987),(20059,23955) -(10946,49757),(10923,49746) -(39438,36158),(39426,36134) -(35502,2385),(35464,2327) -(17073,42173),(16987,42130) -(6079,17258),(6068,17195) -(40458,15752),(40364,15728) -(23340,7879),(23313,7806) -(31819,15096),(31762,15059) -(31159,40864),(31158,40780) -(26975,32144),(26915,32113) -(34530,10378),(34440,10298) -(18855,49577),(18780,49528) -(16787,16625),(16723,16586) -(32330,26538),(32314,26458) -(34270,28674),(34265,28595) -(10022,16026),(10006,15962) -(23143,1479),(23095,1469) -(33676,4483),(33583,4408) -(31066,22074),(31059,22035) -(21603,47121),(21563,47082) -(30051,4244),(30021,4157) -(30634,39478),(30615,39446) -(34404,48724),(34393,48724) -(31103,21414),(31039,21380) -(22945,47397),(22849,47313) -(18133,32025),(18073,31941) -(4053,25759),(3977,25667) -(39185,39091),(39102,39068) -(43287,7407),(43225,7314) -(13137,31188),(13112,31182) -(46264,1438),(46258,1389) -(22804,43892),(22769,43822) -(7542,1044),(7487,983) -(33022,8321),(32925,8267) -(384,39161),(286,39073) -(28205,24401),(28142,24382) -(31708,39086),(31696,39026) -(36626,15708),(36560,15690) -(17099,16924),(17079,16924) -(10817,6989),(10747,6955) -(24338,19293),(24291,19277) -(27566,17576),(27544,17545) -(23041,38384),(22970,38320) -(12786,8485),(12702,8435) -(13876,49473),(13813,49448) -(31585,46998),(31490,46929) -(30227,8768),(30206,8715) -(32062,39306),(32023,39292) -(25003,35753),(24921,35687) -(3281,6758),(3232,6704) -(11395,30299),(11376,30220) -(5088,15275),(5007,15203) -(31100,39538),(31003,39444) -(2741,17877),(2726,17793) -(42897,48620),(42860,48537) -(4230,15778),(4181,15776) -(17835,27530),(17815,27431) -(34189,10933),(34135,10921) -(7537,39974),(7494,39973) -(21554,3507),(21528,3476) -(9350,32326),(9273,32275) -(16455,8874),(16420,8793) -(7346,34235),(7330,34224) -(16417,48134),(16352,48066) -(41916,4971),(41849,4886) -(15856,1522),(15807,1521) -(41549,40218),(41494,40144) -(9978,16226),(9972,16181) -(14856,13312),(14808,13283) -(38490,41641),(38428,41583) -(25828,7438),(25807,7378) -(21876,30633),(21796,30587) -(1908,14279),(1825,14247) -(32207,10251),(32121,10184) -(370,9493),(328,9441) -(42072,17634),(41974,17600) -(47298,9910),(47235,9846) -(17856,11266),(17782,11225) -(35009,21400),(34956,21396) -(18337,11145),(18335,11133) -(25425,9139),(25381,9085) -(35642,27783),(35621,27782) -(3629,33164),(3575,33163) -(17151,41255),(17115,41204) -(17417,5835),(17402,5751) -(33407,14226),(33329,14141) -(1930,29955),(1889,29931) -(41101,10942),(41065,10844) -(36333,27288),(36281,27233) -(21423,36868),(21367,36825) -(36385,19566),(36341,19510) -(27073,38301),(27066,38232) -(43989,34187),(43984,34174) -(48366,7488),(48316,7483) -(37497,36075),(37415,36043) -(46917,9891),(46887,9870) -(37179,657),(37103,634) -(3877,44736),(3811,44684) -(30556,2975),(30547,2962) -(7629,11447),(7547,11416) -(45687,48147),(45591,48088) -(5635,7184),(5571,7146) -(9611,47327),(9541,47246) -(7119,48224),(7117,48152) -(15233,26480),(15138,26430) -(37468,1526),(37466,1513) -(20855,2786),(20828,2711) -(30538,44084),(30480,44061) -(42231,41527),(42149,41454) -(14963,13239),(14952,13146) -(26819,43996),(26745,43934) -(42172,35953),(42086,35928) -(28785,12611),(28710,12534) -(14089,1704),(14047,1629) -(4343,26242),(4341,26169) -(20327,42244),(20231,42212) -(33671,12700),(33666,12630) -(42144,32642),(42128,32569) -(26590,19483),(26503,19442) -(21741,46259),(21723,46226) -(8822,34700),(8760,34693) -(2710,33521),(2675,33505) -(26067,19998),(26026,19989) -(12244,34509),(12202,34489) -(47162,598),(47119,499) -(33093,49382),(33068,49359) -(35170,26340),(35153,26264) -(22552,35785),(22490,35735) -(36791,23032),(36781,22976) -(22857,10857),(22833,10797) -(47207,37405),(47138,37365) -(21867,2836),(21854,2811) -(3387,31487),(3311,31456) -(47174,48121),(47167,48101) -(24415,22232),(24366,22224) -(7970,29251),(7959,29211) -(18635,31294),(18539,31221) -(8403,13380),(8370,13372) -(738,18097),(737,18054) -(37238,19195),(37218,19114) -(582,47934),(570,47897) -(12359,4635),(12350,4619) -(43272,2013),(43195,1958) -(47568,27149),(47521,27088) -(24695,12827),(24661,12796) -(26259,14077),(26168,14019) -(48478,36135),(48425,36092) -(5230,39250),(5206,39174) -(3488,18562),(3423,18489) -(39502,16331),(39460,16275) -(18296,1478),(18233,1471) -(28627,12430),(28559,12410) -(25257,21981),(25206,21954) -(2410,41192),(2325,41142) -(43681,9631),(43587,9538) -(15086,45309),(15064,45270) -(13824,40807),(13759,40787) -(7090,2207),(7062,2159) -(3685,2480),(3630,2391) -(14810,38335),(14801,38275) -(26668,38018),(26581,38012) -(45562,1517),(45506,1424) -(11001,32481),(10962,32402) -(27743,25245),(27673,25161) -(15952,10598),(15948,10535) -(12705,13308),(12694,13232) -(31992,21195),(31975,21118) -(25834,16652),(25745,16626) -(21022,43625),(20990,43576) -(45094,27254),(45000,27240) -(9688,42601),(9643,42533) -(17746,24659),(17694,24616) -(1509,38859),(1503,38809) -(2067,20438),(2041,20369) -(7885,44528),(7839,44444) -(27432,33052),(27422,32987) -(26577,17157),(26563,17142) -(10815,35985),(10734,35908) -(44891,24067),(44794,23979) -(48626,1900),(48595,1850) -(40659,35541),(40659,35489) -(22231,26628),(22210,26579) -(37408,23016),(37375,22919) -(5920,15916),(5906,15895) -(33125,9952),(33037,9880) -(12142,29705),(12141,29670) -(3672,20995),(3649,20899) -(39147,31967),(39101,31907) -(33812,48458),(33748,48399) -(25038,14639),(24978,14586) -(3859,16010),(3857,15994) -(31926,39496),(31889,39417) -(49300,28064),(49297,28026) -(24121,38305),(24048,38256) -(9252,4205),(9155,4149) -(36124,30451),(36056,30395) -(28809,49557),(28794,49533) -(30500,44504),(30471,44476) -(26866,42395),(26822,42332) -(48195,1784),(48101,1734) -(46201,14109),(46112,14097) -(2415,9975),(2354,9914) -(30485,9581),(30415,9558) -(6385,36838),(6305,36838) -(2799,11189),(2723,11095) -(21998,20503),(21923,20406) -(29151,10714),(29090,10671) -(28850,29276),(28757,29207) -(43386,48845),(43305,48834) -(25173,8310),(25101,8294) -(34244,32352),(34204,32342) -(35595,23728),(35533,23672) -(1122,13581),(1119,13538) -(388,21716),(296,21678) -(48782,11064),(48701,11005) -(40293,12997),(40213,12927) -(28194,46428),(28113,46414) -(4791,18118),(4708,18105) -(471,29808),(448,29775) -(3536,37803),(3447,37737) -(1336,28416),(1275,28392) -(16484,48478),(16422,48454) -(25846,19320),(25811,19296) -(48669,27703),(48575,27615) -(24032,44217),(24029,44127) -(12236,5019),(12233,4986) -(1179,29838),(1113,29778) -(33893,22049),(33867,21955) -(16718,19462),(16700,19440) -(17992,49438),(17894,49433) -(35163,39941),(35081,39885) -(33897,8362),(33853,8328) -(2480,6640),(2456,6599) -(28011,19729),(27937,19679) -(15819,41516),(15809,41440) -(29818,9136),(29747,9089) -(28551,37016),(28529,36941) -(36406,26879),(36374,26872) -(16821,48925),(16758,48914) -(23692,48163),(23595,48160) -(4803,10619),(4759,10522) -(46600,33581),(46553,33518) -(41349,11767),(41310,11710) -(20856,29642),(20799,29562) -(16559,46161),(16504,46131) -(23041,1300),(23003,1287) -(16630,44902),(16554,44853) -(43065,14299),(43013,14274) -(24818,22397),(24796,22348) -(22282,24949),(22218,24921) -(36668,28538),(36631,28456) -(8080,1220),(8018,1146) -(47282,34302),(47277,34269) -(35603,33558),(35557,33495) -(44764,32189),(44700,32175) -(46488,23965),(46449,23868) -(46314,15047),(46216,15013) -(6348,25381),(6286,25363) -(3871,49288),(3819,49251) -(462,38894),(398,38867) -(23196,29214),(23136,29169) -(29024,9775),(29016,9759) -(42016,18555),(41934,18472) -(8772,45981),(8692,45973) -(11028,1351),(10986,1278) -(26684,21668),(26641,21656) -(37262,26005),(37260,25947) -(14899,44069),(14814,44066) -(39635,18701),(39587,18698) -(28528,22948),(28457,22857) -(7755,36528),(7681,36454) -(32461,1172),(32427,1106) -(18775,27359),(18736,27329) -(15379,20031),(15337,19934) -(45888,33592),(45881,33544) -(44013,24694),(43962,24645) -(43347,10699),(43343,10699) -(49999,27218),(49908,27176) -(13698,17326),(13630,17317) -(34850,44313),(34775,44302) -(38076,49235),(37983,49214) -(35570,40218),(35500,40136) -(40062,28973),(40032,28878) -(3567,39847),(3523,39781) -(498,2442),(480,2401) -(29660,43620),(29577,43561) -(10946,47356),(10878,47351) -(8073,44233),(8005,44144) -(9720,13473),(9710,13462) -(3643,38014),(3598,37932) -(16887,1408),(16810,1375) -(7559,27914),(7508,27874) -(30356,18573),(30275,18569) -(12193,48176),(12130,48116) -(11884,7756),(11819,7731) -(18293,33272),(18227,33234) -(46697,47874),(46696,47828) -(35788,32517),(35760,32446) -(33877,36987),(33821,36958) -(31253,22819),(31184,22808) -(7744,23115),(7729,23103) -(21291,39817),(21219,39778) -(13877,43379),(13861,43290) -(42955,1406),(42876,1382) -(49232,15950),(49210,15880) -(48419,32001),(48326,31902) -(18940,43246),(18860,43150) -(32317,38240),(32310,38201) -(11307,48298),(11304,48222) -(38015,18190),(38000,18176) -(27821,1177),(27818,1131) -(18935,26757),(18865,26682) -(42659,48284),(42562,48244) -(30185,23350),(30146,23291) -(16496,11970),(16441,11919) -(162,26040),(120,25963) -(24238,47784),(24185,47746) -(32326,8612),(32274,8568) -(26141,13423),(26051,13407) -(40132,22815),(40089,22812) -(21151,48794),(21056,48740) -(22044,28358),(22031,28334) -(6680,14746),(6605,14669) -(40686,25139),(40632,25070) -(22823,27549),(22816,27507) -(2513,22841),(2427,22811) -(36316,27787),(36218,27728) -(554,35489),(540,35441) -(536,30674),(534,30609) -(25385,38468),(25295,38416) -(19467,47386),(19437,47317) -(22425,38591),(22387,38536) -(32493,17321),(32396,17298) -(40115,47315),(40109,47235) -(25002,2107),(24963,2104) -(3901,9790),(3898,9706) -(40316,1721),(40315,1658) -(40089,3454),(40074,3443) -(793,17897),(761,17897) -(6490,43552),(6434,43522) -(10825,487),(10820,405) -(47703,36067),(47641,36011) -(4480,11671),(4468,11653) -(37713,10642),(37711,10615) -(12315,5302),(12273,5203) -(8709,6617),(8647,6557) -(24467,30535),(24455,30494) -(40440,32757),(40369,32668) -(49449,42447),(49426,42428) -(44867,11197),(44792,11137) -(39173,33241),(39143,33187) -(43836,2212),(43803,2184) -(23819,47613),(23739,47575) -(20583,2134),(20485,2042) -(48922,6169),(48889,6111) -(5230,44613),(5131,44604) -(37060,8051),(37032,7975) -(19148,36711),(19112,36704) -(36305,4216),(36243,4118) -(6329,39089),(6302,39047) -(36703,26367),(36623,26307) -(44753,19721),(44701,19631) -(42094,43310),(42094,43285) -(4276,22377),(4241,22352) -(30329,18906),(30327,18815) -(21970,19605),(21871,19590) -(23722,41924),(23709,41861) -(30965,39775),(30908,39692) -(32394,37895),(32351,37890) -(23968,42162),(23873,42095) -(1776,2621),(1732,2548) -(24951,47758),(24900,47679) -(32917,35771),(32847,35753) -(5428,27773),(5343,27769) -(19650,142),(19630,51) -(39769,17276),(39743,17229) -(5171,24562),(5119,24470) -(32976,35249),(32917,35199) -(4174,24603),(4099,24504) -(38565,36960),(38535,36926) -(39084,4328),(39031,4301) -(32153,38043),(32070,37990) -(38085,30640),(38041,30603) -(14269,18426),(14185,18422) -(42941,30850),(42892,30788) -(32403,25999),(32339,25960) -(16906,191),(16816,139) -(3456,48722),(3418,48721) -(3050,18287),(3022,18243) -(6331,8439),(6234,8364) -(5331,20797),(5319,20793) -(39225,37408),(39216,37348) -(34510,19838),(34488,19810) -(45789,33873),(45770,33786) -(369,1457),(278,1409) -(16531,43785),(16482,43729) -(11974,14789),(11973,14730) -(23128,6811),(23094,6798) -(43962,33659),(43944,33599) -(20967,3115),(20947,3079) -(39257,38606),(39241,38595) -(22431,8246),(22381,8235) -(26007,14672),(25996,14593) -(24762,4261),(24675,4261) -(35402,32077),(35343,31988) -(5141,16476),(5139,16393) -(16439,17564),(16344,17472) -(36983,46663),(36903,46567) -(35170,14144),(35162,14048) -(22290,7841),(22283,7810) -(22414,38398),(22404,38319) -(9011,18177),(8932,18150) -(154,4019),(138,3990) -(20447,4998),(20383,4970) -(38867,35757),(38795,35659) -(32322,15845),(32227,15804) -(29889,12142),(29852,12055) -(36235,36918),(36217,36897) -(41620,6581),(41568,6581) -(24758,38504),(24731,38483) -(42524,12904),(42473,12895) -(17954,49975),(17865,49915) -(1938,39019),(1927,39013) -(4864,33279),(4817,33258) -(45373,41967),(45313,41885) -(28786,19028),(28782,18978) -(41913,44950),(41911,44908) -(33408,14698),(33392,14681) -(27602,3460),(27576,3419) -(3336,3728),(3334,3715) -(9099,910),(9080,813) -(34141,6403),(34071,6367) -(48270,17216),(48252,17130) -(2549,16546),(2461,16474) -(27802,33669),(27735,33642) -(48419,1682),(48323,1583) -(5094,41211),(5002,41123) -(11192,6217),(11190,6146) -(6979,18503),(6959,18421) -(41210,48187),(41140,48143) -(15303,29527),(15273,29441) -(12326,45572),(12267,45570) -(29293,5861),(29212,5826) -(23847,37241),(23761,37178) -(44656,23926),(44653,23831) -(30043,16194),(29977,16105) -(902,9358),(879,9339) -(23850,46501),(23834,46494) -(42333,13300),(42287,13246) -(25226,18086),(25169,18005) -(40252,12082),(40183,12038) -(49275,18076),(49216,18055) -(8255,28878),(8238,28862) -(11325,41286),(11320,41235) -(16948,18588),(16926,18528) -(31394,1099),(31374,1038) -(30705,35772),(30637,35766) -(3858,39131),(3771,39125) -(17565,24892),(17515,24808) -(9221,49715),(9216,49661) -(44945,25769),(44875,25722) -(33408,13563),(33310,13527) -(48505,4407),(48408,4373) -(21859,37217),(21763,37217) -(39393,14422),(39335,14364) -(19905,1154),(19841,1098) -(25946,10388),(25906,10366) -(10104,13748),(10027,13746) -(5822,24629),(5820,24599) -(38194,11287),(38127,11252) -(15694,46757),(15625,46716) -(326,18837),(285,18817) -(49611,47078),(49533,47052) -(48233,18850),(48150,18842) -(29239,9962),(29208,9875) -(40062,44554),(39973,44460) -(19135,20729),(19059,20643) -(31969,40664),(31896,40643) -(3725,9191),(3711,9095) -(44280,40158),(44264,40108) -(37236,42756),(37160,42694) -(27958,19055),(27888,18959) -(45270,17661),(45187,17601) -(12115,39546),(12061,39525) -(10227,32295),(10168,32231) -(39264,31123),(39226,31085) -(6566,40000),(6532,39904) -(30058,6975),(30012,6903) -(49631,6909),(49597,6823) -(42168,10926),(42134,10905) -(44892,30042),(44858,29970) -(19540,19803),(19495,19788) -(18403,25454),(18371,25404) -(22929,26795),(22841,26722) -(16648,30213),(16626,30174) -(3440,7495),(3429,7468) -(30708,49028),(30643,48998) -(26258,14164),(26255,14151) -(44206,31653),(44121,31637) -(1510,15179),(1426,15130) -(6986,30496),(6887,30416) -(7192,43403),(7138,43339) -(39921,22071),(39866,21976) -(45870,17011),(45796,16919) -(15939,9563),(15917,9539) -(23728,24737),(23691,24725) -(6444,40416),(6363,40375) -(21899,23861),(21857,23765) -(20610,36765),(20533,36742) -(46520,33082),(46433,32983) -(21406,20902),(21311,20895) -(37913,42300),(37814,42269) -(18216,8177),(18161,8173) -(32967,8258),(32899,8244) -(14978,40230),(14971,40149) -(30343,39152),(30266,39101) -(25917,5835),(25843,5806) -(5169,45366),(5141,45314) -(16221,20898),(16209,20875) -(13151,19869),(13145,19811) -(44399,2801),(44337,2713) -(10959,48311),(10957,48230) -(4794,11711),(4732,11661) -(764,10149),(762,10091) -(15985,46067),(15898,46028) -(41434,22870),(41342,22867) -(43769,23796),(43743,23756) -(10017,18440),(9919,18384) -(21141,43119),(21097,43112) -(7782,13424),(7694,13398) -(25088,36224),(25059,36150) -(46325,48722),(46241,48631) -(11042,33125),(11011,33071) -(22347,13460),(22290,13375) -(3508,20538),(3483,20536) -(5331,42945),(5272,42875) -(2368,15537),(2339,15503) -(45314,31830),(45254,31817) -(34358,2649),(34319,2589) -(17576,30407),(17572,30323) -(29836,41324),(29746,41287) -(21036,39996),(21014,39899) -(26886,6460),(26787,6400) -(15709,5625),(15627,5558) -(37415,15979),(37414,15911) -(47761,16860),(47728,16813) -(35814,48252),(35755,48173) -(28559,20810),(28496,20715) -(12034,11921),(12002,11905) -(1818,27450),(1805,27406) -(33810,45499),(33806,45413) -(17376,18175),(17323,18138) -(34106,28135),(34049,28106) -(44947,23165),(44919,23091) -(37670,41904),(37616,41840) -(12614,15027),(12555,14969) -(43301,75),(43227,43) -(27526,15096),(27450,15088) -(26947,33409),(26853,33333) -(1537,43572),(1471,43499) -(21607,35452),(21605,35375) -(24869,46565),(24818,46531) -(4774,30335),(4723,30257) -(11615,18316),(11579,18310) -(18444,15819),(18354,15763) -(47267,22574),(47203,22518) -(22287,49538),(22203,49511) -(43010,16270),(43010,16202) -(1623,8350),(1578,8254) -(21220,43808),(21137,43748) -(40397,16471),(40358,16434) -(34839,1377),(34744,1327) -(17096,5730),(17090,5637) -(28156,37782),(28155,37723) -(3672,5686),(3586,5638) -(21856,48656),(21840,48638) -(6907,7791),(6892,7761) -(17952,21370),(17862,21350) -(37793,13461),(37784,13381) -(14740,49655),(14709,49604) -(21690,6337),(21593,6289) -(10423,33548),(10364,33498) -(39187,23274),(39136,23197) -(21882,37247),(21835,37167) -(11343,16957),(11281,16914) -(38279,43400),(38264,43352) -(23167,30271),(23086,30224) -(46278,6037),(46180,5964) -(28626,31165),(28605,31095) -(31018,367),(30946,333) -(23541,12541),(23530,12523) -(49741,14535),(49691,14511) -(31444,12702),(31425,12612) -(22406,26536),(22316,26534) -(6807,9761),(6758,9723) -(15698,1941),(15687,1848) -(49310,4625),(49295,4584) -(21345,18939),(21269,18887) -(31433,30493),(31411,30439) -(44980,12400),(44950,12372) -(25054,13949),(24984,13949) -(40538,7253),(40483,7212) -(16967,8627),(16936,8604) -(26872,3646),(26804,3594) -(24575,42883),(24530,42883) -(11823,5755),(11771,5721) -(2553,46189),(2513,46174) -(24993,14552),(24898,14470) -(28453,1719),(28419,1665) -(8925,22603),(8878,22589) -(47635,15380),(47546,15378) -(35378,18112),(35324,18058) -(27347,22264),(27293,22200) -(44323,29044),(44273,28958) -(41538,38324),(41484,38290) -(19128,49932),(19112,49849) -(17904,12548),(17867,12503) -(35103,14426),(35092,14336) -(29807,10142),(29714,10052) -(44507,22903),(44462,22847) -(11419,13324),(11399,13251) -(8573,42221),(8562,42123) -(46798,45843),(46765,45765) -(12028,31783),(11967,31749) -(10635,45300),(10604,45251) -(9626,8248),(9587,8194) -(18290,741),(18246,732) -(39949,44672),(39932,44641) -(7897,11692),(7893,11637) -(20165,42246),(20112,42168) -(4341,48390),(4285,48338) -(30126,28913),(30088,28869) -(40565,1733),(40472,1721) -(9981,30147),(9915,30133) -(47292,25511),(47217,25462) -(20137,24489),(20104,24392) -(2385,28283),(2381,28189) -(20429,10052),(20357,10009) -(8395,38568),(8348,38480) -(17381,36112),(17349,36038) -(37845,30953),(37759,30926) -(27452,12732),(27411,12652) -(38196,32186),(38114,32116) -(6527,49356),(6508,49315) -(43891,29789),(43856,29723) -(6146,37192),(6085,37107) -(42012,28897),(41939,28808) -(14909,13815),(14846,13757) -(11120,24095),(11035,24049) -(3132,41545),(3053,41526) -(40084,40315),(39994,40261) -(39671,17445),(39576,17361) -(47135,35853),(47085,35831) -(39297,1941),(39290,1911) -(47143,35898),(47072,35880) -(16017,6711),(15989,6686) -(47110,30305),(47087,30213) -(38102,27639),(38091,27602) -(17954,22544),(17863,22453) -(39891,11791),(39815,11739) -(13996,20290),(13922,20278) -(22284,23143),(22190,23081) -(25345,24019),(25313,24017) -(47134,44803),(47055,44761) -(41360,16573),(41326,16503) -(10464,1071),(10457,998) -(23515,47517),(23451,47499) -(9308,8452),(9238,8392) -(28695,5657),(28671,5644) -(45104,9913),(45077,9871) -(337,455),(240,359) -(11562,45479),(11472,45428) -(11952,18466),(11931,18425) -(35789,5154),(35775,5128) -(19024,18299),(18979,18230) -(43056,38113),(42975,38067) -(10075,26847),(10064,26806) -(3065,8107),(3029,8038) -(24766,19059),(24749,18985) -(14438,24805),(14413,24708) -(9523,3058),(9485,2998) -(24516,31262),(24478,31204) -(49513,26044),(49434,26035) -(14110,38528),(14103,38461) -(31679,35618),(31619,35618) -(10029,20258),(10008,20248) -(39269,37586),(39233,37539) -(12343,8197),(12247,8113) -(11155,44223),(11111,44134) -(25437,20606),(25338,20534) -(46604,16156),(46570,16131) -(4636,14004),(4592,13941) -(15975,29628),(15912,29556) -(49887,24274),(49805,24184) -(11812,13440),(11723,13418) -(21589,38179),(21531,38085) -(32255,44463),(32219,44454) -(15023,12698),(14989,12687) -(28906,48630),(28818,48568) -(28886,38905),(28861,38832) -(34786,22285),(34740,22240) -(46513,46780),(46425,46780) -(26626,31759),(26551,31677) -(19792,25967),(19763,25933) -(20432,14394),(20388,14365) -(27092,7301),(27052,7278) -(22283,987),(22198,928) -(6197,24363),(6112,24311) -(46601,49259),(46551,49231) -(12392,48052),(12363,48038) -(46116,31386),(46067,31356) -(7354,16855),(7289,16778) -(47501,42808),(47495,42761) -(16461,25487),(16391,25398) -(42678,18798),(42678,18756) -(9466,18207),(9419,18185) -(17467,14177),(17416,14097) -(28533,31886),(28487,31832) -(13225,38472),(13188,38395) -(5180,40970),(5173,40902) -(83,10271),(15,10265) -(2111,6784),(2016,6690) -(41835,11064),(41798,10995) -(29273,48585),(29181,48536) -(29066,21615),(28985,21543) -(19805,44143),(19727,44128) -(48919,21468),(48875,21467) -(28790,34287),(28721,34251) -(10911,33074),(10869,32989) -(6111,16519),(6032,16489) -(43889,33838),(43837,33768) -(32323,21685),(32304,21644) -(9552,27819),(9539,27753) -(38266,49852),(38233,49844) -(37672,48362),(37663,48277) -(32550,47029),(32529,46931) -(46307,6620),(46272,6616) -(23192,46608),(23105,46566) -(30399,48330),(30335,48239) -(36268,25058),(36235,24984) -(19181,8120),(19089,8098) -(24376,19983),(24294,19925) -(18297,18375),(18202,18292) -(31608,6215),(31575,6168) -(12788,49510),(12784,49468) -(46071,13013),(46035,12991) -(27647,8218),(27582,8201) -(49580,11076),(49537,11050) -(35501,33782),(35501,33687) -(19969,3148),(19964,3082) -(37728,49153),(37726,49152) -(5322,48440),(5321,48435) -(48003,10096),(47904,10005) -(39361,22318),(39348,22236) -(30488,7456),(30437,7430) -(18533,39476),(18481,39394) -(39462,23701),(39433,23604) -(26701,18300),(26686,18235) -(17405,35577),(17387,35517) -(33971,29928),(33953,29919) -(6328,10241),(6276,10217) -(32459,44259),(32453,44217) -(1715,42385),(1647,42357) -(48113,6960),(48103,6872) -(30561,4255),(30476,4240) -(38907,43619),(38827,43553) -(29149,20773),(29070,20698) -(17006,1543),(16970,1497) -(11737,18808),(11714,18788) -(13019,30534),(13005,30481) -(39224,31729),(39191,31683) -(4942,41680),(4907,41596) -(12287,37187),(12188,37172) -(30758,29579),(30725,29531) -(16604,17963),(16581,17912) -(19459,15888),(19409,15812) -(34696,24783),(34600,24725) -(21621,14159),(21558,14110) -(12193,46149),(12145,46096) -(37781,4715),(37692,4635) -(41854,44125),(41807,44040) -(23604,23585),(23571,23533) -(7853,36967),(7797,36908) -(2755,13279),(2720,13206) -(4314,15424),(4283,15383) -(29584,12685),(29493,12594) -(25138,33726),(25042,33691) -(38393,10270),(38326,10185) -(4247,12615),(4225,12567) -(36100,33156),(36100,33107) -(20024,40796),(20016,40708) -(3927,44892),(3914,44843) -(10317,43168),(10226,43096) -(22057,3419),(22042,3334) -(37097,21814),(37025,21811) -(32084,21564),(31996,21491) -(34079,39921),(34058,39911) -(23078,47459),(23018,47373) -(38109,616),(38082,568) -(11862,40382),(11764,40292) -(33403,33320),(33389,33289) -(36639,24829),(36623,24829) -(12995,45080),(12992,45040) -(16545,19981),(16532,19891) -(26155,10659),(26154,10634) -(24423,255),(24360,213) -(823,22487),(781,22442) -(12823,20064),(12735,20040) -(19688,11710),(19681,11654) -(2892,20452),(2836,20424) -(15533,10807),(15464,10711) -(46994,41143),(46955,41082) -(18155,2421),(18069,2392) -(2628,12688),(2605,12602) -(35128,8396),(35044,8365) -(44765,49615),(44758,49524) -(11226,44529),(11178,44515) -(31334,32463),(31291,32456) -(43224,23387),(43168,23364) -(30882,10414),(30798,10395) -(29139,967),(29139,923) -(29959,45244),(29877,45223) -(19946,217),(19941,118) -(49732,22033),(49642,22012) -(32914,15360),(32879,15290) -(47825,21097),(47747,21030) -(10788,5131),(10746,5086) -(15497,9698),(15481,9678) -(10617,47195),(10601,47117) -(42392,10583),(42340,10550) -(10753,33520),(10669,33509) -(5553,21580),(5521,21527) -(36840,12336),(36817,12320) -(49785,12554),(49702,12553) -(17737,38349),(17639,38277) -(48000,7823),(47956,7814) -(5019,3184),(4931,3160) -(30120,3524),(30063,3492) -(37044,2016),(37001,1942) -(23496,38566),(23469,38528) -(17255,48957),(17200,48903) -(27815,2138),(27808,2090) -(40440,11129),(40368,11105) -(35305,21772),(35272,21717) -(41308,45065),(41229,44973) -(14893,28807),(14817,28789) -(30776,45824),(30731,45772) -(742,40724),(652,40672) -(5985,41133),(5927,41097) -(9576,10226),(9540,10218) -(21407,23207),(21323,23160) -(44880,34228),(44877,34169) -(29146,49694),(29143,49682) -(28502,34886),(28471,34832) -(30662,5584),(30604,5528) -(12612,26081),(12552,26001) -(17166,49308),(17098,49270) -(9586,14116),(9488,14104) -(37323,47576),(37264,47482) -(48009,49713),(48004,49614) -(49308,23780),(49297,23760) -(8667,32342),(8592,32294) -(37826,48560),(37822,48485) -(24493,18653),(24486,18616) -(17914,3850),(17887,3775) -(34270,43873),(34231,43826) -(7753,44715),(7660,44651) -(44328,36364),(44265,36350) -(10146,3030),(10111,2975) -(35273,40106),(35269,40062) -(38566,43846),(38547,43760) -(12400,41394),(12377,41378) -(45196,38286),(45153,38250) -(48511,14972),(48428,14883) -(25939,36328),(25886,36277) -(38997,11007),(38979,10917) -(30342,518),(30244,453) -(6876,7468),(6867,7454) -(17566,27575),(17566,27480) -(18869,28538),(18858,28475) -(16825,33309),(16726,33255) -(14585,26111),(14490,26035) -(28743,49392),(28664,49349) -(26652,23359),(26618,23297) -(40129,33653),(40102,33584) -(41074,26393),(41038,26389) -(3869,33564),(3869,33536) -(28455,14205),(28364,14163) -(13866,45603),(13770,45543) -(21666,30586),(21578,30544) -(29978,11931),(29893,11868) -(1594,1043),(1517,971) -(948,1201),(907,1156) -(27547,13692),(27545,13677) -(13661,38184),(13566,38154) -(2389,40026),(2317,39938) -(35481,46379),(35481,46320) -(26917,45698),(26864,45689) -(23933,41617),(23909,41539) -(8912,8471),(8862,8401) -(9625,4747),(9558,4692) -(34743,35056),(34721,34969) -(39544,21762),(39475,21717) -(11741,26330),(11656,26293) -(39015,1315),(38966,1285) -(13418,44237),(13326,44202) -(2107,17672),(2093,17616) -(42448,28844),(42370,28764) -(49843,5175),(49808,5145) -(6536,23000),(6467,22958) -(11114,5822),(11027,5739) -(48457,11074),(48384,11024) -(12343,23110),(12310,23074) -(17300,24847),(17276,24825) -(8823,8253),(8793,8238) -(3449,171),(3354,108) -(21650,23955),(21605,23883) -(13260,3234),(13193,3214) -(25361,10896),(25305,10806) -(25051,25042),(25011,25001) -(25044,25088),(25015,25005) -(25007,25061),(25002,25013) -(25066,25105),(25003,25007) -(25028,25012),(25015,25011) -(25031,25057),(25006,25018) -(25015,25042),(25004,25012) -(25091,25049),(25019,25019) -(25023,25011),(25000,25004) -(25053,25104),(25010,25012) -(25058,25001),(25018,25000) -(25059,25051),(25008,25016) -(25043,25069),(25007,25004) -(25006,25101),(25002,25002) -(25095,25012),(25014,25007) -(25054,25052),(25019,25013) -(25108,25077),(25009,25018) -(25007,25023),(25003,25002) -(25076,25098),(25002,25016) -(25030,25077),(25012,25006) diff --git a/contrib/cube/expected/cube.out b/contrib/cube/expected/cube.out deleted file mode 100644 index ed94a25b44..0000000000 --- a/contrib/cube/expected/cube.out +++ /dev/null @@ -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) - diff --git a/contrib/cube/sql/cube.sql b/contrib/cube/sql/cube.sql deleted file mode 100644 index 0e0de38bc4..0000000000 --- a/contrib/cube/sql/cube.sql +++ /dev/null @@ -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; diff --git a/contrib/dbase/Makefile b/contrib/dbase/Makefile deleted file mode 100644 index 5089298c3f..0000000000 --- a/contrib/dbase/Makefile +++ /dev/null @@ -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 diff --git a/contrib/dbase/README.dbf2pg b/contrib/dbase/README.dbf2pg deleted file mode 100644 index 7203be4029..0000000000 --- a/contrib/dbase/README.dbf2pg +++ /dev/null @@ -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 - - diff --git a/contrib/dbase/dbf.c b/contrib/dbase/dbf.c deleted file mode 100644 index 053e9adffb..0000000000 --- a/contrib/dbase/dbf.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include - -#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; -} diff --git a/contrib/dbase/dbf.h b/contrib/dbase/dbf.h deleted file mode 100644 index 254e8d19e9..0000000000 --- a/contrib/dbase/dbf.h +++ /dev/null @@ -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 - -/********************************************************************** - - 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 */ diff --git a/contrib/dbase/dbf2pg.1 b/contrib/dbase/dbf2pg.1 deleted file mode 100644 index a377e489c8..0000000000 --- a/contrib/dbase/dbf2pg.1 +++ /dev/null @@ -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. diff --git a/contrib/dbase/dbf2pg.c b/contrib/dbase/dbf2pg.c deleted file mode 100644 index 5f5e9d2823..0000000000 --- a/contrib/dbase/dbf2pg.c +++ /dev/null @@ -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 -#include -#include -#ifdef HAVE_TERMIOS_H -#include -#endif -#ifdef HAVE_ICONV_H -#include -#endif -#ifdef HAVE_GETOPT_H -#include -#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 */ -/* 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); -} diff --git a/contrib/dbase/endian.c b/contrib/dbase/endian.c deleted file mode 100644 index f45d958e40..0000000000 --- a/contrib/dbase/endian.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Maarten Boekhold (maarten.boekhold@reuters.com) oktober 1995 */ - -#include -#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; -} diff --git a/contrib/dblink/Makefile b/contrib/dblink/Makefile deleted file mode 100644 index 8b730fab73..0000000000 --- a/contrib/dblink/Makefile +++ /dev/null @@ -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 diff --git a/contrib/dblink/README.dblink b/contrib/dblink/README.dblink deleted file mode 100644 index 8e6adf069f..0000000000 --- a/contrib/dblink/README.dblink +++ /dev/null @@ -1,415 +0,0 @@ -/* - * dblink - * - * Functions returning results from a remote database - * - * Copyright (c) Joseph Conway , 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 - diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c deleted file mode 100644 index 26fa62417f..0000000000 --- a/contrib/dblink/dblink.c +++ /dev/null @@ -1,1429 +0,0 @@ -/* - * dblink.c - * - * Functions returning results from a remote database - * - * Copyright (c) Joseph Conway , 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. - * - */ - -#include "dblink.h" - - -/* - * Internal declarations - */ -static dblink_results *init_dblink_results(MemoryContext fn_mcxt); -static dblink_array_results *init_dblink_array_results(MemoryContext fn_mcxt); -static char **get_pkey_attnames(Oid relid, int16 *numatts); -static char *get_strtok(char *fldtext, char *fldsep, int fldnum); -static char *get_sql_insert(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattvals, char **tgt_pkattvals); -static char *get_sql_delete(Oid relid, int16 *pkattnums, int16 pknumatts, char **tgt_pkattvals); -static char *get_sql_update(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattvals, char **tgt_pkattvals); -static char *quote_literal_cstr(char *rawstr); -static char *quote_ident_cstr(char *rawstr); -static int16 get_attnum_pk_pos(int16 *pkattnums, int16 pknumatts, int16 key); -static HeapTuple get_tuple_of_interest(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattvals); -static Oid get_relid_from_relname(text *relname_text); -static dblink_results *get_res_ptr(int32 res_id_index); -static void append_res_ptr(dblink_results *results); -static void remove_res_ptr(dblink_results *results); - -/* Global */ -List *res_id = NIL; -int res_id_index = 0; - -PG_FUNCTION_INFO_V1(dblink); -Datum -dblink(PG_FUNCTION_ARGS) -{ - PGconn *conn = NULL; - PGresult *res = NULL; - dblink_results *results; - char *optstr; - char *sqlstatement; - char *execstatement; - char *msg; - int ntuples = 0; - ReturnSetInfo *rsi; - - if (fcinfo->resultinfo == NULL || !IsA(fcinfo->resultinfo, ReturnSetInfo)) - elog(ERROR, "dblink: function called in context that does not accept a set result"); - - optstr = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0)))); - sqlstatement = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(1)))); - - if (fcinfo->flinfo->fn_extra == NULL) - { - - conn = PQconnectdb(optstr); - if (PQstatus(conn) == CONNECTION_BAD) - { - msg = pstrdup(PQerrorMessage(conn)); - PQfinish(conn); - elog(ERROR, "dblink: connection error: %s", msg); - } - - execstatement = (char *) palloc(strlen(sqlstatement) + 1); - if (execstatement != NULL) - { - strcpy(execstatement, sqlstatement); - strcat(execstatement, "\0"); - } - else - elog(ERROR, "dblink: insufficient memory"); - - res = PQexec(conn, execstatement); - if (!res || (PQresultStatus(res) != PGRES_COMMAND_OK && PQresultStatus(res) != PGRES_TUPLES_OK)) - { - msg = pstrdup(PQerrorMessage(conn)); - PQclear(res); - PQfinish(conn); - elog(ERROR, "dblink: sql error: %s", msg); - } - else - { - /* - * got results, start fetching them - */ - ntuples = PQntuples(res); - - /* - * increment resource index - */ - res_id_index++; - - results = init_dblink_results(fcinfo->flinfo->fn_mcxt); - results->tup_num = 0; - results->res_id_index = res_id_index; - results->res = res; - - /* - * Append node to res_id to hold pointer to results. - * Needed by dblink_tok to access the data - */ - append_res_ptr(results); - - /* - * save pointer to results for the next function manager call - */ - fcinfo->flinfo->fn_extra = (void *) results; - - /* close the connection to the database and cleanup */ - PQfinish(conn); - - rsi = (ReturnSetInfo *) fcinfo->resultinfo; - rsi->isDone = ExprMultipleResult; - - PG_RETURN_INT32(res_id_index); - } - } - else - { - /* - * check for more results - */ - results = fcinfo->flinfo->fn_extra; - - results->tup_num++; - res_id_index = results->res_id_index; - ntuples = PQntuples(results->res); - - if (results->tup_num < ntuples) - { - /* - * fetch them if available - */ - - rsi = (ReturnSetInfo *) fcinfo->resultinfo; - rsi->isDone = ExprMultipleResult; - - PG_RETURN_INT32(res_id_index); - } - else - { - /* - * or if no more, clean things up - */ - results = fcinfo->flinfo->fn_extra; - - remove_res_ptr(results); - PQclear(results->res); - pfree(results); - fcinfo->flinfo->fn_extra = NULL; - - rsi = (ReturnSetInfo *) fcinfo->resultinfo; - rsi->isDone = ExprEndResult; - - PG_RETURN_NULL(); - } - } - PG_RETURN_NULL(); -} - - -/* - * dblink_tok - * parse dblink output string - * return fldnum item (0 based) - * based on provided field separator - */ - -PG_FUNCTION_INFO_V1(dblink_tok); -Datum -dblink_tok(PG_FUNCTION_ARGS) -{ - dblink_results *results; - int fldnum; - text *result_text; - char *result; - int nfields = 0; - int text_len = 0; - - results = get_res_ptr(PG_GETARG_INT32(0)); - if (results == NULL) - { - if (res_id != NIL) - { - freeList(res_id); - res_id = NIL; - res_id_index = 0; - } - - elog(ERROR, "dblink_tok: function called with invalid resource id"); - } - - fldnum = PG_GETARG_INT32(1); - if (fldnum < 0) - elog(ERROR, "dblink_tok: field number < 0 not permitted"); - - nfields = PQnfields(results->res); - if (fldnum > (nfields - 1)) - elog(ERROR, "dblink_tok: field number %d does not exist", fldnum); - - if (PQgetisnull(results->res, results->tup_num, fldnum) == 1) - PG_RETURN_NULL(); - else - { - text_len = PQgetlength(results->res, results->tup_num, fldnum); - - result = (char *) palloc(text_len + 1); - - if (result != NULL) - { - strcpy(result, PQgetvalue(results->res, results->tup_num, fldnum)); - strcat(result, "\0"); - } - else - elog(ERROR, "dblink: insufficient memory"); - - result_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(result))); - - PG_RETURN_TEXT_P(result_text); - } -} - - -/* - * dblink_strtok - * parse input string - * return ord item (0 based) - * based on provided field separator - */ -PG_FUNCTION_INFO_V1(dblink_strtok); -Datum -dblink_strtok(PG_FUNCTION_ARGS) -{ - char *fldtext; - char *fldsep; - int fldnum; - char *buffer; - text *result_text; - - fldtext = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(0)))); - fldsep = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(PG_GETARG_TEXT_P(1)))); - fldnum = PG_GETARG_INT32(2); - - if (fldtext[0] == '\0') - { - elog(ERROR, "get_strtok: blank list not permitted"); - } - if (fldsep[0] == '\0') - { - elog(ERROR, "get_strtok: blank field separator not permitted"); - } - - buffer = get_strtok(fldtext, fldsep, fldnum); - - pfree(fldtext); - pfree(fldsep); - - if (buffer == NULL) - { - PG_RETURN_NULL(); - } - else - { - result_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(buffer))); - pfree(buffer); - - PG_RETURN_TEXT_P(result_text); - } -} - - -/* - * dblink_get_pkey - * - * Return comma delimited list of primary key - * fields for the supplied relation, - * or NULL if none exists. - */ -PG_FUNCTION_INFO_V1(dblink_get_pkey); -Datum -dblink_get_pkey(PG_FUNCTION_ARGS) -{ - text *relname_text; - Oid relid; - char **result; - text *result_text; - int16 numatts; - ReturnSetInfo *rsi; - dblink_array_results *ret_set; - - if (fcinfo->resultinfo == NULL || !IsA(fcinfo->resultinfo, ReturnSetInfo)) - elog(ERROR, "dblink: function called in context that does not accept a set result"); - - if (fcinfo->flinfo->fn_extra == NULL) - { - relname_text = PG_GETARG_TEXT_P(0); - - /* - * Convert relname to rel OID. - */ - relid = get_relid_from_relname(relname_text); - if (!OidIsValid(relid)) - elog(ERROR, "dblink_get_pkey: relation does not exist"); - - /* - * get an array of attnums. - */ - result = get_pkey_attnames(relid, &numatts); - - if ((result != NULL) && (numatts > 0)) - { - ret_set = init_dblink_array_results(fcinfo->flinfo->fn_mcxt); - - ret_set->elem_num = 0; - ret_set->num_elems = numatts; - ret_set->res = result; - - fcinfo->flinfo->fn_extra = (void *) ret_set; - - rsi = (ReturnSetInfo *) fcinfo->resultinfo; - rsi->isDone = ExprMultipleResult; - - result_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(result[ret_set->elem_num]))); - - PG_RETURN_TEXT_P(result_text); - } - else - { - rsi = (ReturnSetInfo *) fcinfo->resultinfo; - rsi->isDone = ExprEndResult; - - PG_RETURN_NULL(); - } - } - else - { - /* - * check for more results - */ - ret_set = fcinfo->flinfo->fn_extra; - ret_set->elem_num++; - result = ret_set->res; - - if (ret_set->elem_num < ret_set->num_elems) - { - /* - * fetch next one - */ - rsi = (ReturnSetInfo *) fcinfo->resultinfo; - rsi->isDone = ExprMultipleResult; - - result_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(result[ret_set->elem_num]))); - PG_RETURN_TEXT_P(result_text); - } - else - { - int i; - - /* - * or if no more, clean things up - */ - for (i = 0; i < ret_set->num_elems; i++) - pfree(result[i]); - - pfree(ret_set->res); - pfree(ret_set); - - rsi = (ReturnSetInfo *) fcinfo->resultinfo; - rsi->isDone = ExprEndResult; - - PG_RETURN_NULL(); - } - } - PG_RETURN_NULL(); -} - - -/* - * dblink_last_oid - * return last inserted oid - */ -PG_FUNCTION_INFO_V1(dblink_last_oid); -Datum -dblink_last_oid(PG_FUNCTION_ARGS) -{ - dblink_results *results; - - results = get_res_ptr(PG_GETARG_INT32(0)); - if (results == NULL) - { - if (res_id != NIL) - { - freeList(res_id); - res_id = NIL; - res_id_index = 0; - } - - elog(ERROR, "dblink_tok: function called with invalid resource id"); - } - - PG_RETURN_OID(PQoidValue(results->res)); -} - - -/* - * dblink_build_sql_insert - * - * Used to generate an SQL insert statement - * based on an existing tuple in a local relation. - * This is useful for selectively replicating data - * to another server via dblink. - * - * API: - * - name of local table of interest - * - an int2vector of attnums which will be used - * to identify the local tuple of interest - * - number of attnums in pkattnums - * - text array of key values which will be used - * to identify the local tuple of interest - * - text array of key values which will be used - * to build the string for execution remotely. These are substituted - * for their counterparts in src_pkattvals_arry - */ -PG_FUNCTION_INFO_V1(dblink_build_sql_insert); -Datum -dblink_build_sql_insert(PG_FUNCTION_ARGS) -{ - Oid relid; - text *relname_text; - int16 *pkattnums; - int16 pknumatts; - char **src_pkattvals; - char **tgt_pkattvals; - ArrayType *src_pkattvals_arry; - ArrayType *tgt_pkattvals_arry; - int src_ndim; - int *src_dim; - int src_nitems; - int tgt_ndim; - int *tgt_dim; - int tgt_nitems; - int i; - char *ptr; - char *sql; - text *sql_text; - - relname_text = PG_GETARG_TEXT_P(0); - - /* - * Convert relname to rel OID. - */ - relid = get_relid_from_relname(relname_text); - if (!OidIsValid(relid)) - elog(ERROR, "dblink_build_sql_insert: relation does not exist"); - - pkattnums = (int16 *) PG_GETARG_POINTER(1); - pknumatts = PG_GETARG_INT16(2); - /* - * There should be at least one key attribute - */ - if (pknumatts == 0) - elog(ERROR, "dblink_build_sql_insert: number of key attributes must be > 0."); - - src_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(3); - tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(4); - - /* - * Source array is made up of key values that will be used to - * locate the tuple of interest from the local system. - */ - src_ndim = ARR_NDIM(src_pkattvals_arry); - src_dim = ARR_DIMS(src_pkattvals_arry); - src_nitems = ArrayGetNItems(src_ndim, src_dim); - - /* - * There should be one source array key value for each key attnum - */ - if (src_nitems != pknumatts) - elog(ERROR, "dblink_build_sql_insert: source key array length does not match number of key attributes."); - - /* - * get array of pointers to c-strings from the input source array - */ - src_pkattvals = (char **) palloc(src_nitems * sizeof(char *)); - ptr = ARR_DATA_PTR(src_pkattvals_arry); - for (i = 0; i < src_nitems; i++) - { - src_pkattvals[i] = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(ptr))); - ptr += INTALIGN(*(int32 *) ptr); - } - - /* - * Target array is made up of key values that will be used to - * build the SQL string for use on the remote system. - */ - tgt_ndim = ARR_NDIM(tgt_pkattvals_arry); - tgt_dim = ARR_DIMS(tgt_pkattvals_arry); - tgt_nitems = ArrayGetNItems(tgt_ndim, tgt_dim); - - /* - * There should be one target array key value for each key attnum - */ - if (tgt_nitems != pknumatts) - elog(ERROR, "dblink_build_sql_insert: target key array length does not match number of key attributes."); - - /* - * get array of pointers to c-strings from the input target array - */ - tgt_pkattvals = (char **) palloc(tgt_nitems * sizeof(char *)); - ptr = ARR_DATA_PTR(tgt_pkattvals_arry); - for (i = 0; i < tgt_nitems; i++) - { - tgt_pkattvals[i] = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(ptr))); - ptr += INTALIGN(*(int32 *) ptr); - } - - /* - * Prep work is finally done. Go get the SQL string. - */ - sql = get_sql_insert(relid, pkattnums, pknumatts, src_pkattvals, tgt_pkattvals); - - /* - * Make it into TEXT for return to the client - */ - sql_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(sql))); - - /* - * And send it - */ - PG_RETURN_TEXT_P(sql_text); -} - - -/* - * dblink_build_sql_delete - * - * Used to generate an SQL delete statement. - * This is useful for selectively replicating a - * delete to another server via dblink. - * - * API: - * - name of remote table of interest - * - an int2vector of attnums which will be used - * to identify the remote tuple of interest - * - number of attnums in pkattnums - * - text array of key values which will be used - * to build the string for execution remotely. - */ -PG_FUNCTION_INFO_V1(dblink_build_sql_delete); -Datum -dblink_build_sql_delete(PG_FUNCTION_ARGS) -{ - Oid relid; - text *relname_text; - int16 *pkattnums; - int16 pknumatts; - char **tgt_pkattvals; - ArrayType *tgt_pkattvals_arry; - int tgt_ndim; - int *tgt_dim; - int tgt_nitems; - int i; - char *ptr; - char *sql; - text *sql_text; - - relname_text = PG_GETARG_TEXT_P(0); - - /* - * Convert relname to rel OID. - */ - relid = get_relid_from_relname(relname_text); - if (!OidIsValid(relid)) - elog(ERROR, "dblink_build_sql_delete: relation does not exist"); - - pkattnums = (int16 *) PG_GETARG_POINTER(1); - pknumatts = PG_GETARG_INT16(2); - /* - * There should be at least one key attribute - */ - if (pknumatts == 0) - elog(ERROR, "dblink_build_sql_insert: number of key attributes must be > 0."); - - tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(3); - - /* - * Target array is made up of key values that will be used to - * build the SQL string for use on the remote system. - */ - tgt_ndim = ARR_NDIM(tgt_pkattvals_arry); - tgt_dim = ARR_DIMS(tgt_pkattvals_arry); - tgt_nitems = ArrayGetNItems(tgt_ndim, tgt_dim); - - /* - * There should be one target array key value for each key attnum - */ - if (tgt_nitems != pknumatts) - elog(ERROR, "dblink_build_sql_insert: target key array length does not match number of key attributes."); - - /* - * get array of pointers to c-strings from the input target array - */ - tgt_pkattvals = (char **) palloc(tgt_nitems * sizeof(char *)); - ptr = ARR_DATA_PTR(tgt_pkattvals_arry); - for (i = 0; i < tgt_nitems; i++) - { - tgt_pkattvals[i] = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(ptr))); - ptr += INTALIGN(*(int32 *) ptr); - } - - /* - * Prep work is finally done. Go get the SQL string. - */ - sql = get_sql_delete(relid, pkattnums, pknumatts, tgt_pkattvals); - - /* - * Make it into TEXT for return to the client - */ - sql_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(sql))); - - /* - * And send it - */ - PG_RETURN_TEXT_P(sql_text); -} - - -/* - * dblink_build_sql_update - * - * Used to generate an SQL update statement - * based on an existing tuple in a local relation. - * This is useful for selectively replicating data - * to another server via dblink. - * - * API: - * - name of local table of interest - * - an int2vector of attnums which will be used - * to identify the local tuple of interest - * - number of attnums in pkattnums - * - text array of key values which will be used - * to identify the local tuple of interest - * - text array of key values which will be used - * to build the string for execution remotely. These are substituted - * for their counterparts in src_pkattvals_arry - */ -PG_FUNCTION_INFO_V1(dblink_build_sql_update); -Datum -dblink_build_sql_update(PG_FUNCTION_ARGS) -{ - Oid relid; - text *relname_text; - int16 *pkattnums; - int16 pknumatts; - char **src_pkattvals; - char **tgt_pkattvals; - ArrayType *src_pkattvals_arry; - ArrayType *tgt_pkattvals_arry; - int src_ndim; - int *src_dim; - int src_nitems; - int tgt_ndim; - int *tgt_dim; - int tgt_nitems; - int i; - char *ptr; - char *sql; - text *sql_text; - - relname_text = PG_GETARG_TEXT_P(0); - - /* - * Convert relname to rel OID. - */ - relid = get_relid_from_relname(relname_text); - if (!OidIsValid(relid)) - elog(ERROR, "dblink_build_sql_update: relation does not exist"); - - pkattnums = (int16 *) PG_GETARG_POINTER(1); - pknumatts = PG_GETARG_INT16(2); - /* - * There should be one source array key values for each key attnum - */ - if (pknumatts == 0) - elog(ERROR, "dblink_build_sql_insert: number of key attributes must be > 0."); - - src_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(3); - tgt_pkattvals_arry = PG_GETARG_ARRAYTYPE_P(4); - - /* - * Source array is made up of key values that will be used to - * locate the tuple of interest from the local system. - */ - src_ndim = ARR_NDIM(src_pkattvals_arry); - src_dim = ARR_DIMS(src_pkattvals_arry); - src_nitems = ArrayGetNItems(src_ndim, src_dim); - - /* - * There should be one source array key value for each key attnum - */ - if (src_nitems != pknumatts) - elog(ERROR, "dblink_build_sql_insert: source key array length does not match number of key attributes."); - - /* - * get array of pointers to c-strings from the input source array - */ - src_pkattvals = (char **) palloc(src_nitems * sizeof(char *)); - ptr = ARR_DATA_PTR(src_pkattvals_arry); - for (i = 0; i < src_nitems; i++) - { - src_pkattvals[i] = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(ptr))); - ptr += INTALIGN(*(int32 *) ptr); - } - - /* - * Target array is made up of key values that will be used to - * build the SQL string for use on the remote system. - */ - tgt_ndim = ARR_NDIM(tgt_pkattvals_arry); - tgt_dim = ARR_DIMS(tgt_pkattvals_arry); - tgt_nitems = ArrayGetNItems(tgt_ndim, tgt_dim); - - /* - * There should be one target array key value for each key attnum - */ - if (tgt_nitems != pknumatts) - elog(ERROR, "dblink_build_sql_insert: target key array length does not match number of key attributes."); - - /* - * get array of pointers to c-strings from the input target array - */ - tgt_pkattvals = (char **) palloc(tgt_nitems * sizeof(char *)); - ptr = ARR_DATA_PTR(tgt_pkattvals_arry); - for (i = 0; i < tgt_nitems; i++) - { - tgt_pkattvals[i] = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(ptr))); - ptr += INTALIGN(*(int32 *) ptr); - } - - /* - * Prep work is finally done. Go get the SQL string. - */ - sql = get_sql_update(relid, pkattnums, pknumatts, src_pkattvals, tgt_pkattvals); - - /* - * Make it into TEXT for return to the client - */ - sql_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(sql))); - - /* - * And send it - */ - PG_RETURN_TEXT_P(sql_text); -} - - -/* - * dblink_current_query - * return the current query string - * to allow its use in (among other things) - * rewrite rules - */ -PG_FUNCTION_INFO_V1(dblink_current_query); -Datum -dblink_current_query(PG_FUNCTION_ARGS) -{ - text *result_text; - - result_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(debug_query_string))); - PG_RETURN_TEXT_P(result_text); -} - - -/* - * dblink_replace_text - * replace all occurences of 'old_sub_str' in 'orig_str' - * with 'new_sub_str' to form 'new_str' - * - * returns 'orig_str' if 'old_sub_str' == '' or 'orig_str' == '' - * otherwise returns 'new_str' - */ -PG_FUNCTION_INFO_V1(dblink_replace_text); -Datum -dblink_replace_text(PG_FUNCTION_ARGS) -{ - text *left_text; - text *right_text; - text *buf_text; - text *ret_text; - char *ret_str; - int curr_posn; - text *src_text = PG_GETARG_TEXT_P(0); - int src_text_len = DatumGetInt32(DirectFunctionCall1(textlen, PointerGetDatum(src_text))); - text *from_sub_text = PG_GETARG_TEXT_P(1); - int from_sub_text_len = DatumGetInt32(DirectFunctionCall1(textlen, PointerGetDatum(from_sub_text))); - text *to_sub_text = PG_GETARG_TEXT_P(2); - char *to_sub_str = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(to_sub_text))); - StringInfo str = makeStringInfo(); - - if (src_text_len == 0 || from_sub_text_len == 0) - PG_RETURN_TEXT_P(src_text); - - buf_text = DatumGetTextPCopy(PointerGetDatum(src_text)); - curr_posn = DatumGetInt32(DirectFunctionCall2(textpos, PointerGetDatum(buf_text), PointerGetDatum(from_sub_text))); - - while (curr_posn > 0) - { - left_text = DatumGetTextP(DirectFunctionCall3(text_substr, PointerGetDatum(buf_text), 1, DatumGetInt32(DirectFunctionCall2(textpos, PointerGetDatum(buf_text), PointerGetDatum(from_sub_text))) - 1)); - right_text = DatumGetTextP(DirectFunctionCall3(text_substr, PointerGetDatum(buf_text), DatumGetInt32(DirectFunctionCall2(textpos, PointerGetDatum(buf_text), PointerGetDatum(from_sub_text))) + from_sub_text_len, -1)); - - appendStringInfo(str, DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(left_text)))); - appendStringInfo(str, to_sub_str); - - pfree(buf_text); - pfree(left_text); - buf_text = right_text; - curr_posn = DatumGetInt32(DirectFunctionCall2(textpos, PointerGetDatum(buf_text), PointerGetDatum(from_sub_text))); - } - - appendStringInfo(str, DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(buf_text)))); - pfree(buf_text); - - ret_str = pstrdup(str->data); - ret_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(ret_str))); - - PG_RETURN_TEXT_P(ret_text); -} - - -/************************************************************* - * internal functions - */ - - -/* - * init_dblink_results - * - create an empty dblink_results data structure - */ -static dblink_results * -init_dblink_results(MemoryContext fn_mcxt) -{ - MemoryContext oldcontext; - dblink_results *retval; - - oldcontext = MemoryContextSwitchTo(fn_mcxt); - - retval = (dblink_results *) palloc(sizeof(dblink_results)); - MemSet(retval, 0, sizeof(dblink_results)); - - retval->tup_num = -1; - retval->res_id_index =-1; - retval->res = NULL; - - MemoryContextSwitchTo(oldcontext); - - return retval; -} - - -/* - * init_dblink_array_results - * - create an empty dblink_array_results data structure - */ -static dblink_array_results * -init_dblink_array_results(MemoryContext fn_mcxt) -{ - MemoryContext oldcontext; - dblink_array_results *retval; - - oldcontext = MemoryContextSwitchTo(fn_mcxt); - - retval = (dblink_array_results *) palloc(sizeof(dblink_array_results)); - MemSet(retval, 0, sizeof(dblink_array_results)); - - retval->elem_num = -1; - retval->num_elems = 0; - retval->res = NULL; - - MemoryContextSwitchTo(oldcontext); - - return retval; -} - -/* - * get_pkey_attnames - * - * Get the primary key attnames for the given relation. - * Return NULL, and set numatts = 0, if no primary key exists. - */ -static char ** -get_pkey_attnames(Oid relid, int16 *numatts) -{ - Relation indexRelation; - ScanKeyData entry; - HeapScanDesc scan; - HeapTuple indexTuple; - int i; - char **result = NULL; - Relation rel; - TupleDesc tupdesc; - - /* - * Open relation using relid, get tupdesc - */ - rel = relation_open(relid, AccessShareLock); - tupdesc = rel->rd_att; - - /* - * Initialize numatts to 0 in case no primary key - * exists - */ - *numatts = 0; - - /* - * Use relid to get all related indexes - */ - indexRelation = heap_openr(IndexRelationName, AccessShareLock); - ScanKeyEntryInitialize(&entry, 0, Anum_pg_index_indrelid, - F_OIDEQ, ObjectIdGetDatum(relid)); - scan = heap_beginscan(indexRelation, SnapshotNow, 1, &entry); - - while ((indexTuple = heap_getnext(scan, ForwardScanDirection)) != NULL) - { - Form_pg_index index = (Form_pg_index) GETSTRUCT(indexTuple); - - /* - * We're only interested if it is the primary key - */ - if (index->indisprimary == TRUE) - { - i = 0; - while (index->indkey[i++] != 0) - (*numatts)++; - - if (*numatts > 0) - { - result = (char **) palloc(*numatts * sizeof(char *)); - for (i = 0; i < *numatts; i++) - result[i] = SPI_fname(tupdesc, index->indkey[i]); - } - break; - } - } - heap_endscan(scan); - heap_close(indexRelation, AccessShareLock); - relation_close(rel, AccessShareLock); - - return result; -} - - -/* - * get_strtok - * - * parse input string - * return ord item (0 based) - * based on provided field separator - */ -static char * -get_strtok(char *fldtext, char *fldsep, int fldnum) -{ - int j = 0; - char *result; - - if (fldnum < 0) - { - elog(ERROR, "get_strtok: field number < 0 not permitted"); - } - - if (fldsep[0] == '\0') - { - elog(ERROR, "get_strtok: blank field separator not permitted"); - } - - result = strtok(fldtext, fldsep); - for (j = 1; j < fldnum + 1; j++) - { - result = strtok(NULL, fldsep); - if (result == NULL) - return NULL; - } - - return pstrdup(result); -} - -static char * -get_sql_insert(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattvals, char **tgt_pkattvals) -{ - Relation rel; - char *relname; - HeapTuple tuple; - TupleDesc tupdesc; - int natts; - StringInfo str = makeStringInfo(); - char *sql = NULL; - char *val = NULL; - int16 key; - unsigned int i; - - /* - * Open relation using relid - */ - rel = relation_open(relid, AccessShareLock); - relname = RelationGetRelationName(rel); - tupdesc = rel->rd_att; - natts = tupdesc->natts; - - tuple = get_tuple_of_interest(relid, pkattnums, pknumatts, src_pkattvals); - - appendStringInfo(str, "INSERT INTO %s(", quote_ident_cstr(relname)); - for (i = 0; i < natts; i++) - { - if (i > 0) - appendStringInfo(str, ","); - - appendStringInfo(str, NameStr(tupdesc->attrs[i]->attname)); - } - - appendStringInfo(str, ") VALUES("); - - /* - * remember attvals are 1 based - */ - for (i = 0; i < natts; i++) - { - if (i > 0) - appendStringInfo(str, ","); - - if (tgt_pkattvals != NULL) - key = get_attnum_pk_pos(pkattnums, pknumatts, i + 1); - else - key = -1; - - if (key > -1) - val = pstrdup(tgt_pkattvals[key]); - else - val = SPI_getvalue(tuple, tupdesc, i + 1); - - if (val != NULL) - { - appendStringInfo(str, quote_literal_cstr(val)); - pfree(val); - } - else - appendStringInfo(str, "NULL"); - } - appendStringInfo(str, ")"); - - sql = pstrdup(str->data); - pfree(str->data); - pfree(str); - relation_close(rel, AccessShareLock); - - return (sql); -} - -static char * -get_sql_delete(Oid relid, int16 *pkattnums, int16 pknumatts, char **tgt_pkattvals) -{ - Relation rel; - char *relname; - TupleDesc tupdesc; - int natts; - StringInfo str = makeStringInfo(); - char *sql = NULL; - char *val = NULL; - unsigned int i; - - /* - * Open relation using relid - */ - rel = relation_open(relid, AccessShareLock); - relname = RelationGetRelationName(rel); - tupdesc = rel->rd_att; - natts = tupdesc->natts; - - appendStringInfo(str, "DELETE FROM %s WHERE ", quote_ident_cstr(relname)); - for (i = 0; i < pknumatts; i++) - { - int16 pkattnum = pkattnums[i]; - - if (i > 0) - appendStringInfo(str, " AND "); - - appendStringInfo(str, NameStr(tupdesc->attrs[pkattnum - 1]->attname)); - - if (tgt_pkattvals != NULL) - val = pstrdup(tgt_pkattvals[i]); - else - elog(ERROR, "Target key array must not be NULL"); - - if (val != NULL) - { - appendStringInfo(str, "="); - appendStringInfo(str, quote_literal_cstr(val)); - pfree(val); - } - else - appendStringInfo(str, "IS NULL"); - } - - sql = pstrdup(str->data); - pfree(str->data); - pfree(str); - relation_close(rel, AccessShareLock); - - return (sql); -} - -static char * -get_sql_update(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattvals, char **tgt_pkattvals) -{ - Relation rel; - char *relname; - HeapTuple tuple; - TupleDesc tupdesc; - int natts; - StringInfo str = makeStringInfo(); - char *sql = NULL; - char *val = NULL; - int16 key; - int i; - - /* - * Open relation using relid - */ - rel = relation_open(relid, AccessShareLock); - relname = RelationGetRelationName(rel); - tupdesc = rel->rd_att; - natts = tupdesc->natts; - - tuple = get_tuple_of_interest(relid, pkattnums, pknumatts, src_pkattvals); - - appendStringInfo(str, "UPDATE %s SET ", quote_ident_cstr(relname)); - - for (i = 0; i < natts; i++) - { - if (i > 0) - appendStringInfo(str, ","); - - appendStringInfo(str, NameStr(tupdesc->attrs[i]->attname)); - appendStringInfo(str, "="); - - if (tgt_pkattvals != NULL) - key = get_attnum_pk_pos(pkattnums, pknumatts, i + 1); - else - key = -1; - - if (key > -1) - val = pstrdup(tgt_pkattvals[key]); - else - val = SPI_getvalue(tuple, tupdesc, i + 1); - - if (val != NULL) - { - appendStringInfo(str, quote_literal_cstr(val)); - pfree(val); - } - else - appendStringInfo(str, "NULL"); - } - - appendStringInfo(str, " WHERE "); - - for (i = 0; i < pknumatts; i++) - { - int16 pkattnum = pkattnums[i]; - - if (i > 0) - appendStringInfo(str, " AND "); - - appendStringInfo(str, NameStr(tupdesc->attrs[pkattnum - 1]->attname)); - - if (tgt_pkattvals != NULL) - val = pstrdup(tgt_pkattvals[i]); - else - val = SPI_getvalue(tuple, tupdesc, pkattnum); - - if (val != NULL) - { - appendStringInfo(str, "="); - appendStringInfo(str, quote_literal_cstr(val)); - pfree(val); - } - else - appendStringInfo(str, "IS NULL"); - } - - sql = pstrdup(str->data); - pfree(str->data); - pfree(str); - relation_close(rel, AccessShareLock); - - return (sql); -} - -/* - * Return a properly quoted literal value. - * Uses quote_literal in quote.c - */ -static char * -quote_literal_cstr(char *rawstr) -{ - text *rawstr_text; - text *result_text; - char *result; - - rawstr_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(rawstr))); - result_text = DatumGetTextP(DirectFunctionCall1(quote_literal, PointerGetDatum(rawstr_text))); - result = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(result_text))); - - return result; -} - -/* - * Return a properly quoted identifier. - * Uses quote_ident in quote.c - */ -static char * -quote_ident_cstr(char *rawstr) -{ - text *rawstr_text; - text *result_text; - char *result; - - rawstr_text = DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(rawstr))); - result_text = DatumGetTextP(DirectFunctionCall1(quote_ident, PointerGetDatum(rawstr_text))); - result = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(result_text))); - - return result; -} - -static int16 -get_attnum_pk_pos(int16 *pkattnums, int16 pknumatts, int16 key) -{ - int i; - - /* - * Not likely a long list anyway, so just scan for - * the value - */ - for (i = 0; i < pknumatts; i++) - if (key == pkattnums[i]) - return i; - - return -1; -} - -static HeapTuple -get_tuple_of_interest(Oid relid, int16 *pkattnums, int16 pknumatts, char **src_pkattvals) -{ - Relation rel; - char *relname; - TupleDesc tupdesc; - StringInfo str = makeStringInfo(); - char *sql = NULL; - int ret; - HeapTuple tuple; - int i; - char *val = NULL; - - /* - * Open relation using relid - */ - rel = relation_open(relid, AccessShareLock); - relname = RelationGetRelationName(rel); - tupdesc = rel->rd_att; - - /* - * Connect to SPI manager - */ - if ((ret = SPI_connect()) < 0) - elog(ERROR, "get_tuple_of_interest: SPI_connect returned %d", ret); - - /* - * Build sql statement to look up tuple of interest - * Use src_pkattvals as the criteria. - */ - appendStringInfo(str, "SELECT * from %s WHERE ", relname); - - for (i = 0; i < pknumatts; i++) - { - int16 pkattnum = pkattnums[i]; - - if (i > 0) - appendStringInfo(str, " AND "); - - appendStringInfo(str, NameStr(tupdesc->attrs[pkattnum - 1]->attname)); - - val = pstrdup(src_pkattvals[i]); - if (val != NULL) - { - appendStringInfo(str, "="); - appendStringInfo(str, quote_literal_cstr(val)); - pfree(val); - } - else - appendStringInfo(str, "IS NULL"); - } - - sql = pstrdup(str->data); - pfree(str->data); - pfree(str); - /* - * Retrieve the desired tuple - */ - ret = SPI_exec(sql, 0); - pfree(sql); - - /* - * Only allow one qualifying tuple - */ - if ((ret == SPI_OK_SELECT) && (SPI_processed > 1)) - { - elog(ERROR, "get_tuple_of_interest: Source criteria may not match more than one record."); - } - else if (ret == SPI_OK_SELECT && SPI_processed == 1) - { - SPITupleTable *tuptable = SPI_tuptable; - tuple = SPI_copytuple(tuptable->vals[0]); - - return tuple; - } - else - { - /* - * no qualifying tuples - */ - return NULL; - } - - /* - * never reached, but keep compiler quiet - */ - return NULL; -} - -static Oid -get_relid_from_relname(text *relname_text) -{ -#ifdef NamespaceRelationName - RangeVar *relvar; - Relation rel; - Oid relid; - - relvar = makeRangeVarFromNameList(textToQualifiedNameList(relname_text, "get_relid_from_relname")); - rel = heap_openrv(relvar, AccessShareLock); - relid = RelationGetRelid(rel); - relation_close(rel, AccessShareLock); -#else - char *relname; - Relation rel; - Oid relid; - - relname = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(relname_text))); - rel = relation_openr(relname, AccessShareLock); - relid = RelationGetRelid(rel); - relation_close(rel, AccessShareLock); -#endif /* NamespaceRelationName */ - - return relid; -} - -static dblink_results * -get_res_ptr(int32 res_id_index) -{ - List *ptr; - - /* - * short circuit empty list - */ - if(res_id == NIL) - return NULL; - - /* - * OK, should be good to go - */ - foreach(ptr, res_id) - { - dblink_results *this_res_id = (dblink_results *) lfirst(ptr); - if (this_res_id->res_id_index == res_id_index) - return this_res_id; - } - return NULL; -} - -/* - * Add node to global List res_id - */ -static void -append_res_ptr(dblink_results *results) -{ - res_id = lappend(res_id, results); -} - -/* - * Remove node from global List - * using res_id_index - */ -static void -remove_res_ptr(dblink_results *results) -{ - res_id = lremove(results, res_id); - - if (res_id == NIL) - res_id_index = 0; -} - diff --git a/contrib/dblink/dblink.h b/contrib/dblink/dblink.h deleted file mode 100644 index 4d53005ac6..0000000000 --- a/contrib/dblink/dblink.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * dblink.h - * - * Functions returning results from a remote database - * - * Copyright (c) Joseph Conway , 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 -#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 */ diff --git a/contrib/dblink/dblink.sql.in b/contrib/dblink/dblink.sql.in deleted file mode 100644 index bea4378907..0000000000 --- a/contrib/dblink/dblink.sql.in +++ /dev/null @@ -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); diff --git a/contrib/dbsize/Makefile b/contrib/dbsize/Makefile deleted file mode 100644 index ad72a12be2..0000000000 --- a/contrib/dbsize/Makefile +++ /dev/null @@ -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 diff --git a/contrib/dbsize/README.dbsize b/contrib/dbsize/README.dbsize deleted file mode 100644 index 879341cd02..0000000000 --- a/contrib/dbsize/README.dbsize +++ /dev/null @@ -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. diff --git a/contrib/dbsize/dbsize.c b/contrib/dbsize/dbsize.c deleted file mode 100644 index b072a86912..0000000000 --- a/contrib/dbsize/dbsize.c +++ /dev/null @@ -1,164 +0,0 @@ -#include "postgres.h" - -#include -#include -#include -#include -#include - -#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); -} diff --git a/contrib/dbsize/dbsize.sql.in b/contrib/dbsize/dbsize.sql.in deleted file mode 100644 index b00a36fa20..0000000000 --- a/contrib/dbsize/dbsize.sql.in +++ /dev/null @@ -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); diff --git a/contrib/earthdistance/Makefile b/contrib/earthdistance/Makefile deleted file mode 100644 index 94ad370d59..0000000000 --- a/contrib/earthdistance/Makefile +++ /dev/null @@ -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 diff --git a/contrib/earthdistance/README.earthdistance b/contrib/earthdistance/README.earthdistance deleted file mode 100644 index f4ecef80fe..0000000000 --- a/contrib/earthdistance/README.earthdistance +++ /dev/null @@ -1,31 +0,0 @@ -Date: Wed, 1 Apr 1998 15:19:32 -0600 (CST) -From: Hal Snyder -To: vmehr@ctp.com -Subject: [QUESTIONS] Re: Spatial data, R-Trees - -> From: Vivek Mehra -> 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. diff --git a/contrib/earthdistance/earthdistance.c b/contrib/earthdistance/earthdistance.c deleted file mode 100644 index c1962272f4..0000000000 --- a/contrib/earthdistance/earthdistance.c +++ /dev/null @@ -1,72 +0,0 @@ -#include "postgres.h" - -#include - -#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; -} diff --git a/contrib/earthdistance/earthdistance.sql.in b/contrib/earthdistance/earthdistance.sql.in deleted file mode 100644 index 087484da51..0000000000 --- a/contrib/earthdistance/earthdistance.sql.in +++ /dev/null @@ -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; diff --git a/contrib/findoidjoins/Makefile b/contrib/findoidjoins/Makefile deleted file mode 100644 index d285abd5a6..0000000000 --- a/contrib/findoidjoins/Makefile +++ /dev/null @@ -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 diff --git a/contrib/findoidjoins/README.findoidjoins b/contrib/findoidjoins/README.findoidjoins deleted file mode 100644 index 14c17e1e0e..0000000000 --- a/contrib/findoidjoins/README.findoidjoins +++ /dev/null @@ -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) diff --git a/contrib/findoidjoins/findoidjoins.c b/contrib/findoidjoins/findoidjoins.c deleted file mode 100644 index c426b5523a..0000000000 --- a/contrib/findoidjoins/findoidjoins.c +++ /dev/null @@ -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; -} diff --git a/contrib/findoidjoins/make_oidjoins_check b/contrib/findoidjoins/make_oidjoins_check deleted file mode 100755 index 72bb645251..0000000000 --- a/contrib/findoidjoins/make_oidjoins_check +++ /dev/null @@ -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 diff --git a/contrib/fulltextindex/Makefile b/contrib/fulltextindex/Makefile deleted file mode 100644 index 11029ed139..0000000000 --- a/contrib/fulltextindex/Makefile +++ /dev/null @@ -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 diff --git a/contrib/fulltextindex/README.fti b/contrib/fulltextindex/README.fti deleted file mode 100644 index 5c3d6362a6..0000000000 --- a/contrib/fulltextindex/README.fti +++ /dev/null @@ -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 -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% diff --git a/contrib/fulltextindex/TODO b/contrib/fulltextindex/TODO deleted file mode 100644 index a1b359256f..0000000000 --- a/contrib/fulltextindex/TODO +++ /dev/null @@ -1 +0,0 @@ -Place "stop" words in lookup table diff --git a/contrib/fulltextindex/fti.c b/contrib/fulltextindex/fti.c deleted file mode 100644 index aabb2caf9f..0000000000 --- a/contrib/fulltextindex/fti.c +++ /dev/null @@ -1,443 +0,0 @@ -#include "postgres.h" - -#include - -#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); -} diff --git a/contrib/fulltextindex/fti.pl b/contrib/fulltextindex/fti.pl deleted file mode 100644 index 58080a5425..0000000000 --- a/contrib/fulltextindex/fti.pl +++ /dev/null @@ -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 = ); - - return $n;; -} - -sub get_password { - print "Password: "; - - system("stty -echo < /dev/tty"); - chop($pwd = ); - print "\n"; - system("stty echo < /dev/tty"); - - return $pwd; -} - -sub main { - getopts('d:t:c:f:u'); - - if (!$opt_d || !$opt_t || !$opt_c || !$opt_f) { - print STDERR "usage: $0 [-u] -d database -t table -c column[,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(); diff --git a/contrib/fulltextindex/fti.sql.in b/contrib/fulltextindex/fti.sql.in deleted file mode 100644 index e0da2353c5..0000000000 --- a/contrib/fulltextindex/fti.sql.in +++ /dev/null @@ -1,3 +0,0 @@ -create function fti() returns opaque as - 'MODULE_PATHNAME' - language 'C'; \ No newline at end of file diff --git a/contrib/fulltextindex/timings.sh b/contrib/fulltextindex/timings.sh deleted file mode 100755 index ad1495128c..0000000000 --- a/contrib/fulltextindex/timings.sh +++ /dev/null @@ -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 - - - - - - - - - diff --git a/contrib/fuzzystrmatch/Makefile b/contrib/fuzzystrmatch/Makefile deleted file mode 100644 index 81d61de71c..0000000000 --- a/contrib/fuzzystrmatch/Makefile +++ /dev/null @@ -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 diff --git a/contrib/fuzzystrmatch/README.fuzzystrmatch b/contrib/fuzzystrmatch/README.fuzzystrmatch deleted file mode 100644 index 8d310b4ade..0000000000 --- a/contrib/fuzzystrmatch/README.fuzzystrmatch +++ /dev/null @@ -1,129 +0,0 @@ -/* - * fuzzystrmatch.c - * - * Functions for "fuzzy" comparison of strings - * - * Copyright (c) Joseph Conway , 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 - * 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 - diff --git a/contrib/fuzzystrmatch/README.soundex b/contrib/fuzzystrmatch/README.soundex deleted file mode 100644 index b9a6149542..0000000000 --- a/contrib/fuzzystrmatch/README.soundex +++ /dev/null @@ -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'; diff --git a/contrib/fuzzystrmatch/fuzzystrmatch.c b/contrib/fuzzystrmatch/fuzzystrmatch.c deleted file mode 100644 index fbb16f66b3..0000000000 --- a/contrib/fuzzystrmatch/fuzzystrmatch.c +++ /dev/null @@ -1,731 +0,0 @@ -/* - * fuzzystrmatch.c - * - * Functions for "fuzzy" comparison of strings - * - * Copyright (c) Joseph Conway , 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 - * 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; - } -} diff --git a/contrib/fuzzystrmatch/fuzzystrmatch.h b/contrib/fuzzystrmatch/fuzzystrmatch.h deleted file mode 100644 index 59e0d9258c..0000000000 --- a/contrib/fuzzystrmatch/fuzzystrmatch.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * fuzzystrmatch.h - * - * Functions for "fuzzy" comparison of strings - * - * Copyright (c) Joseph Conway , 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 - * 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 -#include -#include - -#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 */ diff --git a/contrib/fuzzystrmatch/fuzzystrmatch.sql.in b/contrib/fuzzystrmatch/fuzzystrmatch.sql.in deleted file mode 100644 index b02f1b28eb..0000000000 --- a/contrib/fuzzystrmatch/fuzzystrmatch.sql.in +++ /dev/null @@ -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'; diff --git a/contrib/intagg/Makefile b/contrib/intagg/Makefile deleted file mode 100644 index 60a84b646e..0000000000 --- a/contrib/intagg/Makefile +++ /dev/null @@ -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 diff --git a/contrib/intagg/README.int_aggregate b/contrib/intagg/README.int_aggregate deleted file mode 100644 index 0c7317ccc9..0000000000 --- a/contrib/intagg/README.int_aggregate +++ /dev/null @@ -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 ; - - diff --git a/contrib/intagg/int_aggregate.c b/contrib/intagg/int_aggregate.c deleted file mode 100644 index 6e8d17b747..0000000000 --- a/contrib/intagg/int_aggregate.c +++ /dev/null @@ -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 -#include -#include -#include -#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(); -} diff --git a/contrib/intagg/int_aggregate.sql.in b/contrib/intagg/int_aggregate.sql.in deleted file mode 100644 index e08324aead..0000000000 --- a/contrib/intagg/int_aggregate.sql.in +++ /dev/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'; - diff --git a/contrib/intarray/Makefile b/contrib/intarray/Makefile deleted file mode 100644 index 7cb06da2ac..0000000000 --- a/contrib/intarray/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/intarray/Makefile,v 1.8 2001/09/06 10:49:29 petere Exp $ - -subdir = contrib/intarray -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -MODULES = _int -DATA_built = _int.sql -DOCS = README.intarray -REGRESS = _int - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/intarray/README.intarray b/contrib/intarray/README.intarray deleted file mode 100644 index f0138a1484..0000000000 --- a/contrib/intarray/README.intarray +++ /dev/null @@ -1,100 +0,0 @@ -This is an implementation of RD-tree data structure using GiST interface -of PostgreSQL. It has built-in lossy compression. - -Current implementation provides index support for one-dimensional array of -int4's - gist__int_ops, suitable for small and medium size of arrays (used on -default), and gist__intbig_ops for indexing large arrays (we use superimposed -signature with length of 4096 bits to represent sets). - -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. - -CHANGES: - -October 1, 2001 - 1. Change search method in array to binary -September 28, 2001 - 1. gist__int_ops now is without lossy - 2. add sort entry in picksplit -September 21, 2001 - 1. Added support for boolean query (indexable operator @@, looks like - a @@ '1|(2&3)', perfomance is better in any case ) - 2. Done some small optimizations -March 19, 2001 - 1. Added support for toastable keys - 2. Improved split algorithm for intbig (selection speedup is about 30%) - -INSTALLATION: - - gmake - gmake install - -- load functions - psql < _int.sql - -REGRESSION TEST: - - gmake installcheck - -EXAMPLE USAGE: - - create table message (mid int not null,sections int[]); - create table message_section_map (mid int not null,sid int not null); - - -- create indices -CREATE unique index message_key on message ( mid ); -CREATE unique index message_section_map_key2 on message_section_map (sid, mid ); -CREATE INDEX message_rdtree_idx on message using gist ( sections gist__int_ops); - - -- select some messages with section in 1 OR 2 - OVERLAP operator - select message.mid from message where message.sections && '{1,2}'; - - -- select messages contains in sections 1 AND 2 - CONTAINS operator - select message.mid from message where message.sections @ '{1,2}'; - -- the same, CONTAINED operator - select message.mid from message where '{1,2}' ~ message.sections; - -BENCHMARK: - - subdirectory bench contains benchmark suite. - cd ./bench - 1. createdb TEST - 2. psql TEST < ../_int.sql - 3. ./create_test.pl | psql TEST - 4. ./bench.pl - perl script to benchmark queries, supports OR, AND queries - with/without RD-Tree. Run script without arguments to - see availbale options. - - a)test without RD-Tree (OR) - ./bench.pl -d TEST -s 1,2 -v - b)test with RD-Tree - ./bench.pl -d TEST -s 1,2 -v -r - -BENCHMARKS: - -Size of table : 200000 -Size of table : 268538 - -Distribution of messages by sections: - -section 0: 73899 messages -section 1: 16298 messages -section 50: 1241 messages -section 99: 705 messages - -old - without RD-Tree support, -new - with RD-Tree - -+----------+---------------+----------------+ -|Search set|OR, time in sec|AND, time in sec| -| +-------+-------+--------+-------+ -| | old | new | old | new | -+----------+-------+-------+--------+-------+ -| 1| 1.427| 0.215| -| -| -+----------+-------+-------+--------+-------+ -| 99| 1.029| 0.018| -| -| -+----------+-------+-------+--------+-------+ -| 1,2| 1.829| 0.334| 5.654| 0.042| -+----------+-------+-------+--------+-------+ -| 1,2,50,60| 2.057| 0.359| 5.044| 0.007| -+----------+-------+-------+--------+-------+ diff --git a/contrib/intarray/_int.c b/contrib/intarray/_int.c deleted file mode 100644 index d956543af5..0000000000 --- a/contrib/intarray/_int.c +++ /dev/null @@ -1,2219 +0,0 @@ -/****************************************************************************** - This file contains routines that can be bound to a Postgres backend and - called by the backend in the process of processing queries. The calling - format for these routines is dictated by Postgres architecture. -******************************************************************************/ - -/* -#define BS_DEBUG -#define GIST_DEBUG -#define GIST_QUERY_DEBUG -*/ - -#include "postgres.h" - -#include - -#include "access/gist.h" -#include "access/itup.h" -#include "access/rtree.h" -#include "utils/elog.h" -#include "utils/palloc.h" -#include "utils/array.h" -#include "utils/builtins.h" -#include "storage/bufpage.h" - -/* number ranges for compression */ -#define MAXNUMRANGE 100 - -#define max(a,b) ((a) > (b) ? (a) : (b)) -#define min(a,b) ((a) <= (b) ? (a) : (b)) -#define abs(a) ((a) < (0) ? -(a) : (a)) - -/* dimension of array */ -#define NDIM 1 - -/* - * flags for gist__int_ops, use ArrayType->flags - * which is unused (see array.h) - */ -#define LEAFKEY (1<<31) -#define ISLEAFKEY(x) ( ((ArrayType*)(x))->flags & LEAFKEY ) - -/* useful macros for accessing int4 arrays */ -#define ARRPTR(x) ( (int4 *) ARR_DATA_PTR(x) ) -#define ARRNELEMS(x) ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x)) - -#define ARRISVOID(x) ( (x) ? ( ( ARR_NDIM(x) == NDIM ) ? ( ( ARRNELEMS( x ) ) ? 0 : 1 ) : ( ( ARR_NDIM(x) ) ? (elog(ERROR,"Array is not one-dimensional: %d dimensions",ARRNELEMS( x )),1) : 0 ) ) : 0 ) - -#define SORT(x) \ - do { \ - if ( ARRNELEMS( x ) > 1 ) \ - isort( ARRPTR( x ), ARRNELEMS( x ) ); \ - } while(0) - -#define PREPAREARR(x) \ - do { \ - if ( ARRNELEMS( x ) > 1 ) \ - if ( isort( ARRPTR( x ), ARRNELEMS( x ) ) ) \ - x = _int_unique( x ); \ - } while(0) - -/* "wish" function */ -#define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) ) - - -/* bigint defines */ -#define BITBYTE 8 -#define SIGLENINT 64 /* >122 => key will toast, so very slow!!! */ -#define SIGLEN ( sizeof(int)*SIGLENINT ) -#define SIGLENBIT (SIGLEN*BITBYTE) - -typedef char BITVEC[SIGLEN]; -typedef char *BITVECP; - -#define SIGPTR(x) ( (BITVECP) ARR_DATA_PTR(x) ) - - -#define LOOPBYTE(a) \ - for(i=0;i> (i)) & 0x01 ) -#define CLRBIT(x,i) GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITBYTE ) ) -#define SETBIT(x,i) GETBYTE(x,i) |= ( 0x01 << ( (i) % BITBYTE ) ) -#define GETBIT(x,i) ( (GETBYTE(x,i) >> ( (i) % BITBYTE )) & 0x01 ) -#define HASHVAL(val) (((unsigned int)(val)) % SIGLENBIT) -#define HASH(sign, val) SETBIT((sign), HASHVAL(val)) - - -#ifdef GIST_DEBUG -static void -printarr(ArrayType *a, int num) -{ - char bbb[16384]; - char *cur; - int l; - int *d; - - d = ARRPTR(a); - *bbb = '\0'; - cur = bbb; - for (l = 0; l < min(num, ARRNELEMS(a)); l++) - { - sprintf(cur, "%d ", d[l]); - cur = strchr(cur, '\0'); - } - elog(DEBUG3, "\t\t%s", bbb); -} -static void -printbitvec(BITVEC bv) -{ - int i; - char str[SIGLENBIT + 1]; - - str[SIGLENBIT] = '\0'; - LOOPBIT(str[i] = (GETBIT(bv, i)) ? '1' : '0'); - - elog(DEBUG3, "BV: %s", str); -} - -#endif - -/* -** types for functions -*/ -typedef ArrayType *(*formarray) (ArrayType *, ArrayType *); -typedef void (*formfloat) (ArrayType *, float *); - -/* -** usefull function -*/ -static bool isort(int4 *a, const int len); -static ArrayType *new_intArrayType(int num); -static ArrayType *copy_intArrayType(ArrayType *a); -static ArrayType *resize_intArrayType(ArrayType *a, int num); -static int internal_size(int *a, int len); -static ArrayType *_int_unique(ArrayType *a); - -/* common GiST function*/ -static GIST_SPLITVEC *_int_common_picksplit(bytea *entryvec, - GIST_SPLITVEC *v, - formarray unionf, - formarray interf, - formfloat sizef, - float coef); -static float *_int_common_penalty(GISTENTRY *origentry, - GISTENTRY *newentry, - float *result, - formarray unionf, - formfloat sizef); -static ArrayType *_int_common_union(bytea *entryvec, - int *sizep, - formarray unionf); - -/* -** GiST support methods -*/ -PG_FUNCTION_INFO_V1( g_int_consistent ); -PG_FUNCTION_INFO_V1( g_int_compress ); -PG_FUNCTION_INFO_V1( g_int_decompress ); -PG_FUNCTION_INFO_V1( g_int_penalty ); -PG_FUNCTION_INFO_V1( g_int_picksplit ); -PG_FUNCTION_INFO_V1( g_int_union ); -PG_FUNCTION_INFO_V1( g_int_same ); - -Datum g_int_consistent(PG_FUNCTION_ARGS); -Datum g_int_compress(PG_FUNCTION_ARGS); -Datum g_int_decompress(PG_FUNCTION_ARGS); -Datum g_int_penalty(PG_FUNCTION_ARGS); -Datum g_int_picksplit(PG_FUNCTION_ARGS); -Datum g_int_union(PG_FUNCTION_ARGS); -Datum g_int_same(PG_FUNCTION_ARGS); - - -/* -** R-tree support functions -*/ -static bool inner_int_contains(ArrayType *a, ArrayType *b); -static bool inner_int_overlap(ArrayType *a, ArrayType *b); -static ArrayType *inner_int_union(ArrayType *a, ArrayType *b); -static ArrayType *inner_int_inter(ArrayType *a, ArrayType *b); -static void rt__int_size(ArrayType *a, float *sz); - -PG_FUNCTION_INFO_V1( _int_different ); -PG_FUNCTION_INFO_V1( _int_same ); -PG_FUNCTION_INFO_V1( _int_contains ); -PG_FUNCTION_INFO_V1( _int_contained ); -PG_FUNCTION_INFO_V1( _int_overlap ); -PG_FUNCTION_INFO_V1( _int_union ); -PG_FUNCTION_INFO_V1( _int_inter ); - -Datum _int_different(PG_FUNCTION_ARGS); -Datum _int_same(PG_FUNCTION_ARGS); -Datum _int_contains(PG_FUNCTION_ARGS); -Datum _int_contained(PG_FUNCTION_ARGS); -Datum _int_overlap(PG_FUNCTION_ARGS); -Datum _int_union(PG_FUNCTION_ARGS); -Datum _int_inter(PG_FUNCTION_ARGS); - -/* -** _intbig methods -*/ -PG_FUNCTION_INFO_V1( g_intbig_consistent ); -PG_FUNCTION_INFO_V1( g_intbig_compress ); -PG_FUNCTION_INFO_V1( g_intbig_decompress ); -PG_FUNCTION_INFO_V1( g_intbig_penalty ); -PG_FUNCTION_INFO_V1( g_intbig_picksplit ); -PG_FUNCTION_INFO_V1( g_intbig_union ); -PG_FUNCTION_INFO_V1( g_intbig_same ); - -Datum g_intbig_consistent(PG_FUNCTION_ARGS); -Datum g_intbig_compress(PG_FUNCTION_ARGS); -Datum g_intbig_decompress(PG_FUNCTION_ARGS); -Datum g_intbig_penalty(PG_FUNCTION_ARGS); -Datum g_intbig_picksplit(PG_FUNCTION_ARGS); -Datum g_intbig_union(PG_FUNCTION_ARGS); -Datum g_intbig_same(PG_FUNCTION_ARGS); - -static bool _intbig_contains(ArrayType *a, ArrayType *b); -static bool _intbig_overlap(ArrayType *a, ArrayType *b); -static ArrayType *_intbig_union(ArrayType *a, ArrayType *b); - -static ArrayType * _intbig_inter(ArrayType *a, ArrayType *b); -static void rt__intbig_size(ArrayType *a, float *sz); - - - -/***************************************************************************** - * Boolean Search - *****************************************************************************/ - -#define BooleanSearchStrategy 20 - -/* - * item in polish notation with back link - * to left operand - */ -typedef struct ITEM { - int2 type; - int2 left; - int4 val; -} ITEM; - -typedef struct { - int4 len; - int4 size; - char data[1]; -} QUERYTYPE; - -#define HDRSIZEQT ( 2*sizeof(int4) ) -#define COMPUTESIZE(size) ( HDRSIZEQT + size * sizeof(ITEM) ) -#define GETQUERY(x) (ITEM*)( (char*)(x)+HDRSIZEQT ) - -PG_FUNCTION_INFO_V1(bqarr_in); -PG_FUNCTION_INFO_V1(bqarr_out); -Datum bqarr_in(PG_FUNCTION_ARGS); -Datum bqarr_out(PG_FUNCTION_ARGS); - -PG_FUNCTION_INFO_V1(boolop); -Datum boolop(PG_FUNCTION_ARGS); - -PG_FUNCTION_INFO_V1(rboolop); -Datum rboolop(PG_FUNCTION_ARGS); - -PG_FUNCTION_INFO_V1(querytree); -Datum querytree(PG_FUNCTION_ARGS); - -static bool signconsistent( QUERYTYPE *query, BITVEC sign, bool leaf ); -static bool execconsistent( QUERYTYPE *query, ArrayType *array, bool leaf ); - -/***************************************************************************** - * GiST functions - *****************************************************************************/ - -/* -** The GiST Consistent method for _intments -** Should return false if for all data items x below entry, -** the predicate x op query == FALSE, where op is the oper -** corresponding to strategy in the pg_amop table. -*/ -Datum -g_int_consistent(PG_FUNCTION_ARGS) { - GISTENTRY *entry = (GISTENTRY *)PG_GETARG_POINTER(0); - ArrayType *query = ( ArrayType * )PG_GETARG_POINTER(1); - StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); - bool retval; - - if ( strategy == BooleanSearchStrategy ) - PG_RETURN_BOOL(execconsistent( (QUERYTYPE*)query, - (ArrayType *) DatumGetPointer(entry->key), - ISLEAFKEY( (ArrayType *) DatumGetPointer(entry->key) ) ) ); - - /* XXX are we sure it's safe to scribble on the query object here? */ - /* XXX what about toasted input? */ - /* sort query for fast search, key is already sorted */ - if ( ARRISVOID( query ) ) - PG_RETURN_BOOL(false); - PREPAREARR(query); - - switch (strategy) - { - case RTOverlapStrategyNumber: - retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key), - query); - break; - case RTSameStrategyNumber: - if ( GIST_LEAF(entry) ) - DirectFunctionCall3( - g_int_same, - entry->key, - PointerGetDatum(query), - PointerGetDatum(&retval) - ); - else - retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key), - query); - break; - case RTContainsStrategyNumber: - retval = inner_int_contains((ArrayType *) DatumGetPointer(entry->key), - query); - break; - case RTContainedByStrategyNumber: - if ( GIST_LEAF(entry) ) - retval = inner_int_contains(query, - (ArrayType *) DatumGetPointer(entry->key) ); - else - retval = inner_int_overlap((ArrayType *) DatumGetPointer(entry->key), - query); - break; - default: - retval = FALSE; - } - PG_RETURN_BOOL(retval); -} - -Datum -g_int_union(PG_FUNCTION_ARGS) -{ - PG_RETURN_POINTER( _int_common_union( - (bytea *) PG_GETARG_POINTER(0), - (int *) PG_GETARG_POINTER(1), - inner_int_union - ) ); -} - -/* -** GiST Compress and Decompress methods -*/ -Datum -g_int_compress(PG_FUNCTION_ARGS) -{ - GISTENTRY *entry = (GISTENTRY *)PG_GETARG_POINTER(0); - GISTENTRY *retval; - ArrayType *r; - int len; - int *dr; - int i, - min, - cand; - - if (entry->leafkey) { - r = (ArrayType *) PG_DETOAST_DATUM_COPY(entry->key); - PREPAREARR(r); - r->flags |= LEAFKEY; - retval = palloc(sizeof(GISTENTRY)); - gistentryinit(*retval, PointerGetDatum(r), - entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE); - - PG_RETURN_POINTER(retval); - } - - r = (ArrayType *) PG_DETOAST_DATUM(entry->key); - if ( ISLEAFKEY( r ) || ARRISVOID(r) ) { - if ( r != (ArrayType*)DatumGetPointer(entry->key) ) - pfree(r); - PG_RETURN_POINTER(entry); - } - - if ( (len=ARRNELEMS(r)) >= 2 * MAXNUMRANGE) { /* compress */ - if ( r == (ArrayType*)DatumGetPointer( entry->key) ) - r = (ArrayType *) PG_DETOAST_DATUM_COPY(entry->key); - r = resize_intArrayType(r, 2 * (len)); - - dr = ARRPTR(r); - - for (i = len - 1; i >= 0; i--) - dr[2 * i] = dr[2 * i + 1] = dr[i]; - - len *= 2; - cand = 1; - while (len > MAXNUMRANGE * 2) - { - min = 0x7fffffff; - for (i = 2; i < len; i += 2) - if (min > (dr[i] - dr[i - 1])) - { - min = (dr[i] - dr[i - 1]); - cand = i; - } - memmove((void *) &dr[cand - 1], (void *) &dr[cand + 1], (len - cand - 1) * sizeof(int)); - len -= 2; - } - r = resize_intArrayType(r, len); - retval = palloc(sizeof(GISTENTRY)); - gistentryinit(*retval, PointerGetDatum(r), - entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE); - PG_RETURN_POINTER(retval); - } else { - PG_RETURN_POINTER(entry); - } - - PG_RETURN_POINTER(entry); -} - -Datum -g_int_decompress(PG_FUNCTION_ARGS) -{ - GISTENTRY *entry = (GISTENTRY *)PG_GETARG_POINTER(0); - GISTENTRY *retval; - ArrayType *r; - int *dr, - lenr; - ArrayType *in; - int lenin; - int *din; - int i, - j; - - in = (ArrayType *) PG_DETOAST_DATUM(entry->key); - - if ( ARRISVOID(in) ) { - PG_RETURN_POINTER(entry); - } - - lenin = ARRNELEMS(in); - - if (lenin < 2 * MAXNUMRANGE || ISLEAFKEY( in ) ) { /* not comressed value */ - if ( in != (ArrayType *) DatumGetPointer(entry->key)) { - retval = palloc(sizeof(GISTENTRY)); - gistentryinit(*retval, PointerGetDatum(in), - entry->rel, entry->page, entry->offset, VARSIZE(in), FALSE); - - PG_RETURN_POINTER(retval); - } - PG_RETURN_POINTER(entry); - } - - din = ARRPTR(in); - lenr = internal_size(din, lenin); - - r = new_intArrayType(lenr); - dr = ARRPTR(r); - - for (i = 0; i < lenin; i += 2) - for (j = din[i]; j <= din[i + 1]; j++) - if ((!i) || *(dr - 1) != j) - *dr++ = j; - - if (in != (ArrayType *) DatumGetPointer(entry->key)) - pfree(in); - retval = palloc(sizeof(GISTENTRY)); - gistentryinit(*retval, PointerGetDatum(r), - entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE); - - PG_RETURN_POINTER(retval); -} - -/* -** The GiST Penalty method for _intments -*/ -Datum -g_int_penalty(PG_FUNCTION_ARGS) -{ - PG_RETURN_POINTER( _int_common_penalty( - (GISTENTRY *)PG_GETARG_POINTER(0), - (GISTENTRY *)PG_GETARG_POINTER(1), - (float *) PG_GETARG_POINTER(2), - inner_int_union, rt__int_size - ) ); -} - - -Datum -g_int_picksplit(PG_FUNCTION_ARGS) -{ - PG_RETURN_POINTER( _int_common_picksplit( - (bytea *)PG_GETARG_POINTER(0), - (GIST_SPLITVEC *)PG_GETARG_POINTER(1), - inner_int_union, - inner_int_inter, - rt__int_size, - 0.01 - ) ); -} - -/* -** Equality methods -*/ - - -Datum -g_int_same(PG_FUNCTION_ARGS) -{ - ArrayType *a = (ArrayType*)PointerGetDatum(PG_GETARG_POINTER(0)); - ArrayType *b = (ArrayType*)PointerGetDatum(PG_GETARG_POINTER(1)); - bool *result = (bool *)PG_GETARG_POINTER(2); - int4 n = ARRNELEMS(a); - int4 *da, *db; - - if ( n != ARRNELEMS(b) ) { - *result = false; - PG_RETURN_POINTER(result); - } - *result = TRUE; - da = ARRPTR(a); - db = ARRPTR(b); - while(n--) - if (*da++ != *db++) { - *result = FALSE; - break; - } - - PG_RETURN_POINTER(result); -} - -Datum -_int_contained(PG_FUNCTION_ARGS) -{ - PG_RETURN_BOOL( DatumGetBool( - DirectFunctionCall2( - _int_contains, - PointerGetDatum(PG_GETARG_POINTER(1)), - PointerGetDatum(PG_GETARG_POINTER(0)) - ) - )); -} - -Datum -_int_contains(PG_FUNCTION_ARGS) -{ - ArrayType *a = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0))); - ArrayType *b = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1))); - bool res; - - if (ARRISVOID(a) || ARRISVOID(b)) - return FALSE; - - PREPAREARR(a); - PREPAREARR(b); - res = inner_int_contains(a, b); - pfree(a); - pfree(b); - PG_RETURN_BOOL( res ); -} - -static bool -inner_int_contains(ArrayType *a, ArrayType *b) -{ - int na, - nb; - int i, - j, - n; - int *da, - *db; - - if (ARRISVOID(a) || ARRISVOID(b)) - return FALSE; - - na = ARRNELEMS(a); - nb = ARRNELEMS(b); - da = ARRPTR(a); - db = ARRPTR(b); - -#ifdef GIST_DEBUG - elog(DEBUG3, "contains %d %d", na, nb); -#endif - - i = j = n = 0; - while (i < na && j < nb) - if (da[i] < db[j]) - i++; - else if (da[i] == db[j]) - { - n++; - i++; - j++; - } - else - j++; - - return (n == nb) ? TRUE : FALSE; -} - -/***************************************************************************** - * Operator class for R-tree indexing - *****************************************************************************/ - -Datum -_int_different(PG_FUNCTION_ARGS) -{ - PG_RETURN_BOOL( ! DatumGetBool( - DirectFunctionCall2( - _int_same, - PointerGetDatum(PG_GETARG_POINTER(0)), - PointerGetDatum(PG_GETARG_POINTER(1)) - ) - )); -} - -Datum -_int_same(PG_FUNCTION_ARGS) -{ - ArrayType *a = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0))); - ArrayType *b = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1))); - int na, - nb; - int n; - int *da, - *db; - bool result; - bool avoid = ARRISVOID(a); - bool bvoid = ARRISVOID(b); - - if (avoid || bvoid) - return (avoid && bvoid) ? TRUE : FALSE; - - SORT(a); - SORT(b); - na = ARRNELEMS(a); - nb = ARRNELEMS(b); - da = ARRPTR(a); - db = ARRPTR(b); - - result = FALSE; - - if (na == nb) - { - result = TRUE; - for (n = 0; n < na; n++) - if (da[n] != db[n]) - { - result = FALSE; - break; - } - } - - pfree(a); - pfree(b); - - PG_RETURN_BOOL(result); -} - -/* _int_overlap -- does a overlap b? - */ -Datum -_int_overlap(PG_FUNCTION_ARGS) -{ - ArrayType *a = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0))); - ArrayType *b = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1))); - bool result; - - if (ARRISVOID(a) || ARRISVOID(b)) - return FALSE; - - SORT(a); - SORT(b); - - result = inner_int_overlap(a, b); - - pfree(a); - pfree(b); - - PG_RETURN_BOOL( result ); -} - -static bool -inner_int_overlap(ArrayType *a, ArrayType *b) -{ - int na, - nb; - int i, - j; - int *da, - *db; - - if (ARRISVOID(a) || ARRISVOID(b)) - return FALSE; - - na = ARRNELEMS(a); - nb = ARRNELEMS(b); - da = ARRPTR(a); - db = ARRPTR(b); - -#ifdef GIST_DEBUG - elog(DEBUG3, "g_int_overlap"); -#endif - - i = j = 0; - while (i < na && j < nb) - if (da[i] < db[j]) - i++; - else if (da[i] == db[j]) - return TRUE; - else - j++; - - return FALSE; -} - -Datum -_int_union(PG_FUNCTION_ARGS) -{ - ArrayType *a = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0))); - ArrayType *b = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1))); - ArrayType *result; - - if (!ARRISVOID(a)) - SORT(a); - if (!ARRISVOID(b)) - SORT(b); - - result = inner_int_union(a, b); - - if (a) - pfree(a); - if (b) - pfree(b); - - PG_RETURN_POINTER( result ); -} - -static ArrayType * -inner_int_union(ArrayType *a, ArrayType *b) -{ - ArrayType *r = NULL; - int na, - nb; - int *da, - *db, - *dr; - int i, - j; - - if (ARRISVOID(a) && ARRISVOID(b)) - return new_intArrayType(0); - if (ARRISVOID(a)) - r = copy_intArrayType(b); - if (ARRISVOID(b)) - r = copy_intArrayType(a); - - if (r) - dr = ARRPTR(r); - else - { - na = ARRNELEMS(a); - nb = ARRNELEMS(b); - da = ARRPTR(a); - db = ARRPTR(b); - - r = new_intArrayType(na + nb); - dr = ARRPTR(r); - - /* union */ - i = j = 0; - while (i < na && j < nb) - if (da[i] < db[j]) - *dr++ = da[i++]; - else - *dr++ = db[j++]; - - while (i < na) - *dr++ = da[i++]; - while (j < nb) - *dr++ = db[j++]; - - } - - if (ARRNELEMS(r) > 1) - r = _int_unique(r); - - return r; -} - - -Datum -_int_inter(PG_FUNCTION_ARGS) -{ - ArrayType *a = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0))); - ArrayType *b = (ArrayType *)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1))); - ArrayType *result; - - if (ARRISVOID(a) || ARRISVOID(b)) - PG_RETURN_POINTER(new_intArrayType(0)); - - SORT(a); - SORT(b); - - result = inner_int_inter(a, b); - - pfree(a); - pfree(b); - - PG_RETURN_POINTER( result ); -} - -static ArrayType * -inner_int_inter(ArrayType *a, ArrayType *b) -{ - ArrayType *r; - int na, - nb; - int *da, - *db, - *dr; - int i, - j; - - if (ARRISVOID(a) || ARRISVOID(b)) - return new_intArrayType(0); - - na = ARRNELEMS(a); - nb = ARRNELEMS(b); - da = ARRPTR(a); - db = ARRPTR(b); - r = new_intArrayType(min(na, nb)); - dr = ARRPTR(r); - - i = j = 0; - while (i < na && j < nb) - if (da[i] < db[j]) - i++; - else if (da[i] == db[j]) - { - if (i + j == 0 || (i + j > 0 && *(dr - 1) != db[j])) - *dr++ = db[j]; - i++; - j++; - } - else - j++; - - if ((dr - ARRPTR(r)) == 0) - { - pfree(r); - return new_intArrayType(0); - } - else - return resize_intArrayType(r, dr - ARRPTR(r)); -} - -static void -rt__int_size(ArrayType *a, float *size) -{ - *size = (float) ARRNELEMS(a); - - return; -} - - -/***************************************************************************** - * Miscellaneous operators and functions - *****************************************************************************/ - -/* len >= 2 */ -static bool -isort(int4 *a, int len) -{ - int4 tmp, - index; - int4 *cur, - *end; - bool r = FALSE; - - end = a + len; - do - { - index = 0; - cur = a + 1; - while (cur < end) - { - if (*(cur - 1) > *cur) - { - tmp = *(cur - 1); - *(cur - 1) = *cur; - *cur = tmp; - index = 1; - } - else if (!r && *(cur - 1) == *cur) - r = TRUE; - cur++; - } - } while (index); - return r; -} - -static ArrayType * -new_intArrayType(int num) -{ - ArrayType *r; - int nbytes = ARR_OVERHEAD(NDIM) + sizeof(int) * num; - - r = (ArrayType *) palloc(nbytes); - - MemSet(r, 0, nbytes); - r->size = nbytes; - r->ndim = NDIM; - r->flags &= ~LEAFKEY; - *((int *) ARR_DIMS(r)) = num; - *((int *) ARR_LBOUND(r)) = 1; - - return r; -} - -static ArrayType * -resize_intArrayType(ArrayType *a, int num) -{ - int nbytes = ARR_OVERHEAD(NDIM) + sizeof(int) * num; - - if (num == ARRNELEMS(a)) - return a; - - a = (ArrayType *) repalloc(a, nbytes); - - a->size = nbytes; - *((int *) ARR_DIMS(a)) = num; - return a; -} - -static ArrayType * -copy_intArrayType(ArrayType *a) -{ - ArrayType *r; - - r = new_intArrayType(ARRNELEMS(a)); - memmove(r, a, VARSIZE(a)); - return r; -} - -/* num for compressed key */ -static int -internal_size(int *a, int len) -{ - int i, - size = 0; - - for (i = 0; i < len; i += 2) - if (!i || a[i] != a[i - 1]) /* do not count repeated range */ - size += a[i + 1] - a[i] + 1; - - return size; -} - -/* r is sorted and size of r > 1 */ -static ArrayType * -_int_unique(ArrayType *r) -{ - int *tmp, - *dr, - *data; - int num = ARRNELEMS(r); - - data = tmp = dr = ARRPTR(r); - while (tmp - data < num) - if (*tmp != *dr) - *(++dr) = *tmp++; - else - tmp++; - return resize_intArrayType(r, dr + 1 - ARRPTR(r)); -} - -/********************************************************************* -** intbig functions -*********************************************************************/ -static void -gensign(BITVEC sign, int *a, int len) -{ - int i; - - /* we assume that the sign vector is previously zeroed */ - for (i = 0; i < len; i++) - { - HASH(sign, *a); - a++; - } -} - -static bool -_intbig_overlap(ArrayType *a, ArrayType *b) -{ - int i; - BITVECP da, - db; - - da = SIGPTR(a); - db = SIGPTR(b); - - LOOPBYTE(if (da[i] & db[i]) return TRUE); - return FALSE; -} - -static bool -_intbig_contains(ArrayType *a, ArrayType *b) -{ - int i; - BITVECP da, - db; - - da = SIGPTR(a); - db = SIGPTR(b); - - LOOPBYTE(if (db[i] & ~da[i]) return FALSE); - - return TRUE; -} - -static void -rt__intbig_size(ArrayType *a, float *sz) -{ - int i, - len = 0; - BITVECP bv = SIGPTR(a); - - LOOPBYTE( - len += - GETBITBYTE(bv,0) + - GETBITBYTE(bv,1) + - GETBITBYTE(bv,2) + - GETBITBYTE(bv,3) + - GETBITBYTE(bv,4) + - GETBITBYTE(bv,5) + - GETBITBYTE(bv,6) + - GETBITBYTE(bv,7) ; - bv = (BITVECP) ( ((char*)bv) + 1 ); - ); - - *sz = (float) len; - return; -} - -static ArrayType * -_intbig_union(ArrayType *a, ArrayType *b) -{ - ArrayType *r; - BITVECP da, - db, - dr; - int i; - - r = new_intArrayType(SIGLENINT); - - da = SIGPTR(a); - db = SIGPTR(b); - dr = SIGPTR(r); - - LOOPBYTE(dr[i] = da[i] | db[i]); - - return r; -} - -static ArrayType * -_intbig_inter(ArrayType *a, ArrayType *b) -{ - ArrayType *r; - BITVECP da, - db, - dr; - int i; - - r = new_intArrayType(SIGLENINT); - - da = SIGPTR(a); - db = SIGPTR(b); - dr = SIGPTR(r); - - LOOPBYTE(dr[i] = da[i] & db[i]); - - return r; -} - -Datum -g_intbig_same(PG_FUNCTION_ARGS) -{ - ArrayType *a = (ArrayType *)PG_GETARG_POINTER(0); - ArrayType *b = (ArrayType *)PG_GETARG_POINTER(1); - bool *result = (bool *)PG_GETARG_POINTER(2); - BITVECP da, - db; - int i; - - da = SIGPTR(a); - db = SIGPTR(b); - - LOOPBYTE( - if (da[i] != db[i]) - { - *result = FALSE; - PG_RETURN_POINTER( result ); - } - ); - - *result = TRUE; - PG_RETURN_POINTER( result ); -} - -Datum -g_intbig_compress(PG_FUNCTION_ARGS) -{ - GISTENTRY *entry = (GISTENTRY *)PG_GETARG_POINTER(0); - GISTENTRY *retval; - ArrayType *r, - *in; - bool maycompress = true; - int i; - - if (DatumGetPointer(entry->key) != NULL) - in = (ArrayType *) PG_DETOAST_DATUM(entry->key); - else - in = NULL; - - if (!entry->leafkey) { - LOOPBYTE( - if ( ( ((char*)ARRPTR(in))[i] & 0xff ) != 0xff ) { - maycompress = false; - break; - } - ); - if ( maycompress ) { - retval = palloc(sizeof(GISTENTRY)); - r = new_intArrayType(1); - gistentryinit(*retval, PointerGetDatum(r), - entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE); - PG_RETURN_POINTER( retval ); - } - PG_RETURN_POINTER( entry ); - } - - retval = palloc(sizeof(GISTENTRY)); - r = new_intArrayType( SIGLENINT ); - - if (ARRISVOID(in)) - { - gistentryinit(*retval, PointerGetDatum(r), - entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE); - if (in != (ArrayType *) DatumGetPointer(entry->key)) - pfree(in); - PG_RETURN_POINTER (retval); - } - - gensign(SIGPTR(r), - ARRPTR(in), - ARRNELEMS(in)); - - LOOPBYTE( - if( ( ((char*)ARRPTR(in))[i] & 0xff ) != 0xff ) { - maycompress = false; - break; - } - ); - - if ( maycompress ) { - pfree(r); - r = new_intArrayType(1); - } - - gistentryinit(*retval, PointerGetDatum(r), entry->rel, entry->page, entry->offset, VARSIZE(r), FALSE); - - if ( in != (ArrayType *) DatumGetPointer(entry->key)) - pfree(in); - - PG_RETURN_POINTER (retval); -} - -Datum -g_intbig_decompress(PG_FUNCTION_ARGS) -{ - GISTENTRY *entry = (GISTENTRY *)PG_GETARG_POINTER(0); - ArrayType *key; - - key = (ArrayType *) PG_DETOAST_DATUM(entry->key); - - if ( key != (ArrayType *) DatumGetPointer(entry->key)) - { - GISTENTRY *retval; - - retval = palloc(sizeof(GISTENTRY)); - - gistentryinit(*retval, PointerGetDatum(key), - entry->rel, entry->page, entry->offset, (key) ? VARSIZE(key) : 0, FALSE); - PG_RETURN_POINTER( retval ); - } - if ( ARRNELEMS(key) == 1 ) { - GISTENTRY *retval; - ArrayType *newkey; - - retval = palloc(sizeof(GISTENTRY)); - newkey = new_intArrayType(SIGLENINT); - MemSet( (void*)ARRPTR(newkey), 0xff, SIGLEN ); - - gistentryinit(*retval, PointerGetDatum(newkey), - entry->rel, entry->page, entry->offset, VARSIZE(newkey), FALSE); - PG_RETURN_POINTER( retval ); - } - PG_RETURN_POINTER( entry ); -} - -Datum -g_intbig_picksplit(PG_FUNCTION_ARGS) -{ - PG_RETURN_POINTER( _int_common_picksplit( - (bytea *)PG_GETARG_POINTER(0), - (GIST_SPLITVEC *)PG_GETARG_POINTER(1), - _intbig_union, - _intbig_inter, - rt__intbig_size, - 0.1 - ) ); -} - -Datum -g_intbig_union(PG_FUNCTION_ARGS) -{ - PG_RETURN_POINTER( _int_common_union( - (bytea *) PG_GETARG_POINTER(0), - (int *) PG_GETARG_POINTER(1), - _intbig_union - ) ); -} - -Datum -g_intbig_penalty(PG_FUNCTION_ARGS) -{ - PG_RETURN_POINTER( _int_common_penalty( - (GISTENTRY *)PG_GETARG_POINTER(0), - (GISTENTRY *)PG_GETARG_POINTER(1), - (float *) PG_GETARG_POINTER(2), - _intbig_union, rt__intbig_size - ) ); -} - -Datum -g_intbig_consistent(PG_FUNCTION_ARGS) { - GISTENTRY *entry = (GISTENTRY *)PG_GETARG_POINTER(0); - ArrayType *query = ( ArrayType * )PG_GETARG_POINTER(1); - StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); - bool retval; - ArrayType *q; - - if ( strategy == BooleanSearchStrategy ) - PG_RETURN_BOOL(signconsistent( (QUERYTYPE*)query, - SIGPTR((ArrayType *) DatumGetPointer(entry->key)), - false ) ); - - /* XXX what about toasted input? */ - if (ARRISVOID(query)) - return FALSE; - - q = new_intArrayType(SIGLENINT); - gensign(SIGPTR(q), - ARRPTR(query), - ARRNELEMS(query)); - - switch (strategy) - { - case RTOverlapStrategyNumber: - retval = _intbig_overlap((ArrayType *) DatumGetPointer(entry->key), q); - break; - case RTSameStrategyNumber: - if ( GIST_LEAF(entry) ) - DirectFunctionCall3( - g_intbig_same, - entry->key, - PointerGetDatum(q), - PointerGetDatum(&retval) - ); - else - retval = _intbig_contains((ArrayType *) DatumGetPointer(entry->key), q); - break; - case RTContainsStrategyNumber: - retval = _intbig_contains((ArrayType *) DatumGetPointer(entry->key), q); - break; - case RTContainedByStrategyNumber: - retval = _intbig_overlap((ArrayType *) DatumGetPointer(entry->key), q); - break; - default: - retval = FALSE; - } - pfree(q); - PG_RETURN_BOOL(retval); -} - -/***************************************************************** -** Common GiST Method -*****************************************************************/ - -/* -** The GiST Union method for _intments -** returns the minimal set that encloses all the entries in entryvec -*/ -static ArrayType * -_int_common_union(bytea *entryvec, int *sizep, formarray unionf) -{ - int numranges, - i; - ArrayType *out = (ArrayType *) NULL; - ArrayType *tmp; - -#ifdef GIST_DEBUG - elog(DEBUG3, "_int_common_union in"); -#endif - - numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY); - tmp = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[0].key); - - for (i = 1; i < numranges; i++) - { - out = (*unionf) (tmp, (ArrayType *) - DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key)); - if (i > 1 && tmp) - pfree(tmp); - tmp = out; - } - - out->flags &= ~LEAFKEY; - *sizep = VARSIZE(out); - if (*sizep == 0) - { - pfree(out); -#ifdef GIST_DEBUG - elog(DEBUG3, "_int_common_union out1"); -#endif - return NULL; - } -#ifdef GIST_DEBUG - elog(DEBUG3, "_int_common_union out"); -#endif - return (out); - -} - -/***************************************** - * The GiST Penalty method for _intments * - *****************************************/ - -static float * -_int_common_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result, - formarray unionf, - formfloat sizef) -{ - ArrayType *ud; - float tmp1, - tmp2; - -#ifdef GIST_DEBUG - elog(DEBUG3, "penalty"); -#endif - ud = (*unionf) ((ArrayType *) DatumGetPointer(origentry->key), - (ArrayType *) DatumGetPointer(newentry->key)); - (*sizef) (ud, &tmp1); - (*sizef) ((ArrayType *) DatumGetPointer(origentry->key), &tmp2); - *result = tmp1 - tmp2; - pfree(ud); - -#ifdef GIST_DEBUG - elog(DEBUG3, "--penalty\t%g", *result); -#endif - - return (result); -} - -typedef struct { - OffsetNumber pos; - float cost; -} SPLITCOST; - -static int -comparecost( const void *a, const void *b ) { - if ( ((SPLITCOST*)a)->cost == ((SPLITCOST*)b)->cost ) - return 0; - else - return ( ((SPLITCOST*)a)->cost > ((SPLITCOST*)b)->cost ) ? 1 : -1; -} - -/* -** The GiST PickSplit method for _intments -** We use Guttman's poly time split algorithm -*/ -static GIST_SPLITVEC * -_int_common_picksplit(bytea *entryvec, - GIST_SPLITVEC *v, - formarray unionf, - formarray interf, - formfloat sizef, - float coef) -{ - OffsetNumber i, - j; - ArrayType *datum_alpha, - *datum_beta; - ArrayType *datum_l, - *datum_r; - ArrayType *union_d, - *union_dl, - *union_dr; - ArrayType *inter_d; - bool firsttime; - float size_alpha, - size_beta, - size_union, - size_inter; - float size_waste, - waste; - float size_l, - size_r; - int nbytes; - OffsetNumber seed_1 = 0, - seed_2 = 0; - OffsetNumber *left, - *right; - OffsetNumber maxoff; - SPLITCOST *costvector; - -#ifdef GIST_DEBUG - elog(DEBUG3, "--------picksplit %d", (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY)); -#endif - - maxoff = ((VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY)) - 2; - nbytes = (maxoff + 2) * sizeof(OffsetNumber); - v->spl_left = (OffsetNumber *) palloc(nbytes); - v->spl_right = (OffsetNumber *) palloc(nbytes); - - firsttime = true; - waste = 0.0; - for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i)) - { - datum_alpha = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key); - for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j)) - { - datum_beta = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[j].key); - - /* compute the wasted space by unioning these guys */ - /* size_waste = size_union - size_inter; */ - union_d = (*unionf) (datum_alpha, datum_beta); - (*sizef) (union_d, &size_union); - inter_d = (*interf) (datum_alpha, datum_beta); - (*sizef) (inter_d, &size_inter); - size_waste = size_union - size_inter; - - pfree(union_d); - - if (inter_d != (ArrayType *) NULL) - pfree(inter_d); - - /* - * are these a more promising split that what we've already - * seen? - */ - - if (size_waste > waste || firsttime) - { - waste = size_waste; - seed_1 = i; - seed_2 = j; - firsttime = false; - } - } - } - - left = v->spl_left; - v->spl_nleft = 0; - right = v->spl_right; - v->spl_nright = 0; - if ( seed_1 == 0 || seed_2 == 0 ) { - seed_1 = 1; - seed_2 = 2; - } - - datum_alpha = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[seed_1].key); - datum_l = copy_intArrayType(datum_alpha); - (*sizef) (datum_l, &size_l); - datum_beta = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[seed_2].key); - datum_r = copy_intArrayType(datum_beta); - (*sizef) (datum_r, &size_r); - - maxoff = OffsetNumberNext(maxoff); - /* - * sort entries - */ - costvector=(SPLITCOST*)palloc( sizeof(SPLITCOST)*maxoff ); - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { - costvector[i-1].pos = i; - datum_alpha = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key); - union_d = (*unionf)(datum_l, datum_alpha); - (*sizef)(union_d, &size_alpha); - pfree( union_d ); - union_d = (*unionf)(datum_r, datum_alpha); - (*sizef)(union_d, &size_beta); - pfree( union_d ); - costvector[i-1].cost = abs( (size_alpha - size_l) - (size_beta - size_r) ); - } - qsort( (void*)costvector, maxoff, sizeof(SPLITCOST), comparecost ); - - /* - * Now split up the regions between the two seeds. An important - * property of this split algorithm is that the split vector v has the - * indices of items to be split in order in its left and right - * vectors. We exploit this property by doing a merge in the code - * that actually splits the page. - * - * For efficiency, we also place the new index tuple in this loop. This - * is handled at the very end, when we have placed all the existing - * tuples and i == maxoff + 1. - */ - - - for (j = 0; j < maxoff; j++) { - i = costvector[j].pos; - - /* - * If we've already decided where to place this item, just put it - * on the right list. Otherwise, we need to figure out which page - * needs the least enlargement in order to store the item. - */ - - if (i == seed_1) - { - *left++ = i; - v->spl_nleft++; - continue; - } - else if (i == seed_2) - { - *right++ = i; - v->spl_nright++; - continue; - } - - /* okay, which page needs least enlargement? */ - datum_alpha = (ArrayType *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key); - union_dl = (*unionf) (datum_l, datum_alpha); - union_dr = (*unionf) (datum_r, datum_alpha); - (*sizef) (union_dl, &size_alpha); - (*sizef) (union_dr, &size_beta); - - /* pick which page to add it to */ - if (size_alpha - size_l < size_beta - size_r + WISH_F(v->spl_nleft, v->spl_nright, coef)) - { - if (datum_l) - pfree(datum_l); - if (union_dr) - pfree(union_dr); - datum_l = union_dl; - size_l = size_alpha; - *left++ = i; - v->spl_nleft++; - } - else - { - if (datum_r) - pfree(datum_r); - if (union_dl) - pfree(union_dl); - datum_r = union_dr; - size_r = size_beta; - *right++ = i; - v->spl_nright++; - } - } - pfree( costvector ); - *right = *left = FirstOffsetNumber; - - datum_l->flags &= ~LEAFKEY; - datum_r->flags &= ~LEAFKEY; - v->spl_ldatum = PointerGetDatum(datum_l); - v->spl_rdatum = PointerGetDatum(datum_r); - -#ifdef GIST_DEBUG - elog(DEBUG3, "--------ENDpicksplit %d %d", v->spl_nleft, v->spl_nright); -#endif - return v; -} - -/***************************************************************************** - * BoolSearch - *****************************************************************************/ - - -#define END 0 -#define ERR 1 -#define VAL 2 -#define OPR 3 -#define OPEN 4 -#define CLOSE 5 - -/* parser's states */ -#define WAITOPERAND 1 -#define WAITENDOPERAND 2 -#define WAITOPERATOR 3 - -/* - * node of query tree, also used - * for storing polish notation in parser - */ -typedef struct NODE { - int4 type; - int4 val; - struct NODE *next; -} NODE; - -typedef struct { - char *buf; - int4 state; - int4 count; - /* reverse polish notation in list (for temprorary usage)*/ - NODE *str; - /* number in str */ - int4 num; -} WORKSTATE; - -/* - * get token from query string - */ -static int4 -gettoken( WORKSTATE* state, int4* val ) { - char nnn[16], *curnnn; - - curnnn=nnn; - while(1) { - switch(state->state) { - case WAITOPERAND: - curnnn=nnn; - if ( (*(state->buf)>='0' && *(state->buf)<='9') || - *(state->buf)=='-' ) { - state->state = WAITENDOPERAND; - *curnnn = *(state->buf); - curnnn++; - } else if ( *(state->buf) == '!' ) { - (state->buf)++; - *val = (int4)'!'; - return OPR; - } else if ( *(state->buf) == '(' ) { - state->count++; - (state->buf)++; - return OPEN; - } else if ( *(state->buf) != ' ' ) - return ERR; - break; - case WAITENDOPERAND: - if ( *(state->buf)>='0' && *(state->buf)<='9' ) { - *curnnn = *(state->buf); - curnnn++; - } else { - *curnnn = '\0'; - *val=(int4)atoi( nnn ); - state->state = WAITOPERATOR; - return ( state->count && *(state->buf) == '\0' ) - ? ERR : VAL; - } - break; - case WAITOPERATOR: - if ( *(state->buf) == '&' || *(state->buf) == '|' ) { - state->state = WAITOPERAND; - *val = (int4) *(state->buf); - (state->buf)++; - return OPR; - } else if ( *(state->buf) == ')' ) { - (state->buf)++; - state->count--; - return ( state->count <0 ) ? ERR : CLOSE; - } else if ( *(state->buf) == '\0' ) { - return ( state->count ) ? ERR : END; - } else if ( *(state->buf) != ' ' ) - return ERR; - break; - default: - return ERR; - break; - } - (state->buf)++; - } - return END; -} - -/* - * push new one in polish notation reverse view - */ -static void -pushquery( WORKSTATE *state, int4 type, int4 val ) { - NODE *tmp = (NODE*)palloc(sizeof(NODE)); - tmp->type=type; - tmp->val =val; - tmp->next = state->str; - state->str = tmp; - state->num++; -} - -#define STACKDEPTH 16 - -/* - * make polish notaion of query - */ -static int4 -makepol(WORKSTATE *state) { - int4 val,type; - int4 stack[STACKDEPTH]; - int4 lenstack=0; - - while( (type=gettoken(state, &val))!=END ) { - switch(type) { - case VAL: - pushquery(state, type, val); - while ( lenstack && (stack[ lenstack-1 ] == (int4)'&' || - stack[ lenstack-1 ] == (int4)'!') ) { - lenstack--; - pushquery(state, OPR, stack[ lenstack ]); - } - break; - case OPR: - if ( lenstack && val == (int4) '|' ) { - pushquery(state, OPR, val); - } else { - if ( lenstack == STACKDEPTH ) - elog(ERROR,"Stack too short"); - stack[ lenstack ] = val; - lenstack++; - } - break; - case OPEN: - if ( makepol( state ) == ERR ) return ERR; - if ( lenstack && (stack[ lenstack-1 ] == (int4)'&' || - stack[ lenstack-1 ] == (int4)'!') ) { - lenstack--; - pushquery(state, OPR, stack[ lenstack ]); - } - break; - case CLOSE: - while ( lenstack ) { - lenstack--; - pushquery(state, OPR, stack[ lenstack ]); - }; - return END; - break; - case ERR: - default: - elog(ERROR,"Syntax error"); - return ERR; - - } - } - - while (lenstack) { - lenstack--; - pushquery(state, OPR, stack[ lenstack ]); - }; - return END; -} - -typedef struct { - int4 *arrb; - int4 *arre; -} CHKVAL; - -/* - * is there value 'val' in array or not ? - */ -static bool -checkcondition_arr( void *checkval, int4 val ) { - int4 *StopLow = ((CHKVAL*)checkval)->arrb; - int4 *StopHigh = ((CHKVAL*)checkval)->arre; - int4 *StopMiddle; - - /* Loop invariant: StopLow <= val < StopHigh */ - - while (StopLow < StopHigh) { - StopMiddle = StopLow + (StopHigh - StopLow) / 2; - if (*StopMiddle == val) - return (true); - else if (*StopMiddle < val ) - StopLow = StopMiddle + 1; - else - StopHigh = StopMiddle; - } - return false; -} - -static bool -checkcondition_bit( void *checkval, int4 val ) { - return GETBIT( checkval, HASHVAL( val ) ); -} - -/* - * check for boolean condition - */ -static bool -execute( ITEM* curitem, void *checkval, bool calcnot, bool (*chkcond)(void *checkval, int4 val )) { - - if ( curitem->type == VAL ) { - return (*chkcond)( checkval, curitem->val ); - } else if ( curitem->val == (int4)'!' ) { - return ( calcnot ) ? - ( ( execute(curitem - 1, checkval, calcnot, chkcond) ) ? false : true ) - : true; - } else if ( curitem->val == (int4)'&' ) { - if ( execute(curitem + curitem->left, checkval, calcnot, chkcond) ) - return execute(curitem - 1, checkval, calcnot, chkcond); - else - return false; - } else { /* |-operator */ - if ( execute(curitem + curitem->left, checkval, calcnot, chkcond) ) - return true; - else - return execute(curitem - 1, checkval, calcnot, chkcond); - } - return false; -} - -/* - * signconsistent & execconsistent called by *_consistent - */ -static bool -signconsistent( QUERYTYPE *query, BITVEC sign, bool calcnot ) { - return execute( - GETQUERY(query) + query->size-1 , - (void*)sign, calcnot, - checkcondition_bit - ); -} - -static bool -execconsistent( QUERYTYPE *query, ArrayType *array, bool calcnot ) { - CHKVAL chkval; - - chkval.arrb = ARRPTR(array); - chkval.arre = chkval.arrb + ARRNELEMS(array); - return execute( - GETQUERY(query) + query->size-1 , - (void*)&chkval, calcnot, - checkcondition_arr - ); -} - -/* - * boolean operations - */ -Datum -rboolop(PG_FUNCTION_ARGS) { - return DirectFunctionCall2( - boolop, - PG_GETARG_DATUM(1), - PG_GETARG_DATUM(0) - ); -} - -Datum -boolop(PG_FUNCTION_ARGS) { - ArrayType *val = ( ArrayType * )PG_DETOAST_DATUM_COPY(PG_GETARG_POINTER(0)); - QUERYTYPE *query = ( QUERYTYPE * )PG_DETOAST_DATUM(PG_GETARG_POINTER(1)); - CHKVAL chkval; - bool result; - - if ( ARRISVOID( val ) ) { - pfree(val); - PG_FREE_IF_COPY(query,1); - PG_RETURN_BOOL( false ); - } - - PREPAREARR(val); - chkval.arrb = ARRPTR(val); - chkval.arre = chkval.arrb + ARRNELEMS(val); - result = execute( - GETQUERY(query) + query->size-1 , - &chkval, true, - checkcondition_arr - ); - pfree(val); - - PG_FREE_IF_COPY(query,1); - PG_RETURN_BOOL( result ); -} - -static void -findoprnd( ITEM *ptr, int4 *pos ) { -#ifdef BS_DEBUG - elog(DEBUG3, ( ptr[*pos].type == OPR ) ? - "%d %c" : "%d %d ", *pos, ptr[*pos].val ); -#endif - if ( ptr[*pos].type == VAL ) { - ptr[*pos].left = 0; - (*pos)--; - } else if ( ptr[*pos].val == (int4)'!' ) { - ptr[*pos].left = -1; - (*pos)--; - findoprnd( ptr, pos ); - } else { - ITEM *curitem = &ptr[*pos]; - int4 tmp = *pos; - (*pos)--; - findoprnd(ptr,pos); - curitem->left = *pos - tmp; - findoprnd(ptr,pos); - } -} - - -/* - * input - */ -Datum -bqarr_in(PG_FUNCTION_ARGS) { - char *buf=(char*)PG_GETARG_POINTER(0); - WORKSTATE state; - int4 i; - QUERYTYPE *query; - int4 commonlen; - ITEM *ptr; - NODE *tmp; - int4 pos=0; -#ifdef BS_DEBUG - char pbuf[16384],*cur; -#endif - - state.buf = buf; - state.state = WAITOPERAND; - state.count = 0; - state.num = 0; - state.str=NULL; - - /* make polish notation (postfix, but in reverse order) */ - makepol( &state ); - if (!state.num) - elog( ERROR,"Empty query"); - - commonlen = COMPUTESIZE(state.num); - query = (QUERYTYPE*) palloc( commonlen ); - query->len = commonlen; - query->size = state.num; - ptr = GETQUERY(query); - - for(i=state.num-1; i>=0; i-- ) { - ptr[i].type = state.str->type; - ptr[i].val = state.str->val; - tmp = state.str->next; - pfree( state.str ); - state.str = tmp; - } - - pos = query->size-1; - findoprnd( ptr, &pos ); -#ifdef BS_DEBUG - cur = pbuf; - *cur = '\0'; - for( i=0;isize;i++ ) { - if ( ptr[i].type == OPR ) - sprintf(cur, "%c(%d) ", ptr[i].val, ptr[i].left); - else - sprintf(cur, "%d ", ptr[i].val ); - cur = strchr(cur,'\0'); - } - elog(DEBUG3,"POR: %s", pbuf); -#endif - - PG_RETURN_POINTER( query ); -} - - -/* - * out function - */ -typedef struct { - ITEM *curpol; - char *buf; - char *cur; - int4 buflen; -} INFIX; - -#define RESIZEBUF(inf,addsize) while( ( inf->cur - inf->buf ) + addsize + 1 >= inf->buflen ) { \ - int4 len = inf->cur - inf->buf; \ - inf->buflen *= 2; \ - inf->buf = (char*) repalloc( (void*)inf->buf, inf->buflen ); \ - inf->cur = inf->buf + len; \ -} - -static void -infix(INFIX *in, bool first) { - if ( in->curpol->type == VAL ) { - RESIZEBUF(in, 11); - sprintf(in->cur, "%d", in->curpol->val ); - in->cur = strchr( in->cur, '\0' ); - in->curpol--; - } else if ( in->curpol->val == (int4)'!' ) { - bool isopr = false; - RESIZEBUF(in, 1); - *(in->cur) = '!'; - in->cur++; - *(in->cur) = '\0'; - in->curpol--; - if ( in->curpol->type == OPR ) { - isopr = true; - RESIZEBUF(in, 2); - sprintf(in->cur, "( "); - in->cur = strchr( in->cur, '\0' ); - } - infix( in, isopr ); - if ( isopr ) { - RESIZEBUF(in, 2); - sprintf(in->cur, " )"); - in->cur = strchr( in->cur, '\0' ); - } - } else { - int4 op = in->curpol->val; - INFIX nrm; - - in->curpol--; - if ( op == (int4)'|' && ! first) { - RESIZEBUF(in, 2); - sprintf(in->cur, "( "); - in->cur = strchr( in->cur, '\0' ); - } - - nrm.curpol = in->curpol; - nrm.buflen = 16; - nrm.cur = nrm.buf = (char*)palloc( sizeof(char) * nrm.buflen ); - - /* get right operand */ - infix( &nrm, false ); - - /* get & print left operand */ - in->curpol = nrm.curpol; - infix( in, false ); - - /* print operator & right operand*/ - RESIZEBUF(in, 3 + (nrm.cur - nrm.buf) ); - sprintf(in->cur, " %c %s", op, nrm.buf); - in->cur = strchr( in->cur, '\0' ); - pfree( nrm.buf ); - - if ( op == (int4)'|' && ! first) { - RESIZEBUF(in, 2); - sprintf(in->cur, " )"); - in->cur = strchr( in->cur, '\0' ); - } - } -} - - -Datum -bqarr_out(PG_FUNCTION_ARGS) { - QUERYTYPE *query = (QUERYTYPE*)PG_DETOAST_DATUM(PG_GETARG_POINTER(0)); - INFIX nrm; - - if ( query->size == 0 ) - elog(ERROR,"Empty"); - nrm.curpol = GETQUERY(query) + query->size - 1; - nrm.buflen = 32; - nrm.cur = nrm.buf = (char*)palloc( sizeof(char) * nrm.buflen ); - *(nrm.cur) = '\0'; - infix( &nrm, true ); - - PG_FREE_IF_COPY(query,0); - PG_RETURN_POINTER( nrm.buf ); -} - -static int4 -countdroptree( ITEM *q, int4 pos ) { - if ( q[pos].type == VAL ) { - return 1; - } else if ( q[pos].val == (int4)'!' ) { - return 1+countdroptree(q, pos-1); - } else { - return 1 + countdroptree(q, pos-1) + countdroptree(q, pos + q[pos].left); - } -} - -/* - * common algorithm: - * result of all '!' will be = 'true', so - * we can modify query tree for clearing - */ -static int4 -shorterquery( ITEM *q, int4 len ) { - int4 index,posnot,poscor; - bool notisleft = false; - int4 drop,i; - - /* out all '!' */ - do { - index=0; - drop=0; - /* find ! */ - for(posnot=0; posnot < len; posnot++) - if ( q[posnot].type == OPR && q[posnot].val == (int4)'!') { - index=1; - break; - } - - if ( posnot == len ) - return len; - - /* last operator is ! */ - if ( posnot == len-1 ) - return 0; - - /* find operator for this operand */ - for( poscor=posnot+1; poscorsize == 0 ) - elog(ERROR,"Empty"); - - q = (ITEM*)palloc( sizeof(ITEM) * query->size ); - memcpy( (void*)q, GETQUERY(query), sizeof(ITEM) * query->size ); - len = shorterquery( q, query->size ); - PG_FREE_IF_COPY(query,0); - - if ( len == 0 ) { - res = (text*) palloc( 1 + VARHDRSZ ); - VARATT_SIZEP(res) = 1 + VARHDRSZ; - *((char*)VARDATA(res)) = 'T'; - } else { - nrm.curpol = q + len - 1; - nrm.buflen = 32; - nrm.cur = nrm.buf = (char*)palloc( sizeof(char) * nrm.buflen ); - *(nrm.cur) = '\0'; - infix( &nrm, true ); - - res = (text*) palloc( nrm.cur-nrm.buf + VARHDRSZ ); - VARATT_SIZEP(res) = nrm.cur-nrm.buf + VARHDRSZ; - strncpy( VARDATA(res), nrm.buf, nrm.cur-nrm.buf ); - } - pfree(q); - - PG_RETURN_POINTER( res ); -} diff --git a/contrib/intarray/_int.sql.in b/contrib/intarray/_int.sql.in deleted file mode 100644 index 4d9031f653..0000000000 --- a/contrib/intarray/_int.sql.in +++ /dev/null @@ -1,437 +0,0 @@ --- Create the user-defined type for the 1-D integer arrays (_int4) --- -BEGIN TRANSACTION; - --- Query type -CREATE FUNCTION bqarr_in(opaque) -RETURNS opaque -AS 'MODULE_PATHNAME' -LANGUAGE 'c' with (isstrict); - -CREATE FUNCTION bqarr_out(opaque) -RETURNS opaque -AS 'MODULE_PATHNAME' -LANGUAGE 'c' with (isstrict); - -CREATE TYPE query_int ( -internallength = -1, -input = bqarr_in, -output = bqarr_out -); - ---only for debug -CREATE FUNCTION querytree(query_int) -RETURNS text -AS 'MODULE_PATHNAME' -LANGUAGE 'c' with (isstrict); - - -CREATE FUNCTION boolop(_int4, query_int) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION boolop(_int4, query_int) IS 'boolean operation with array'; - -CREATE FUNCTION rboolop(query_int, _int4) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION rboolop(query_int, _int4) IS 'boolean operation with array'; - -CREATE OPERATOR @@ ( - LEFTARG = _int4, RIGHTARG = query_int, PROCEDURE = boolop, - COMMUTATOR = '~~', RESTRICT = contsel, JOIN = contjoinsel -); - -CREATE OPERATOR ~~ ( - LEFTARG = query_int, RIGHTARG = _int4, PROCEDURE = rboolop, - COMMUTATOR = '@@', RESTRICT = contsel, JOIN = contjoinsel -); - - --- --- External C-functions for R-tree methods --- - --- Comparison methods - -CREATE FUNCTION _int_contains(_int4, _int4) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION _int_contains(_int4, _int4) IS 'contains'; - -CREATE FUNCTION _int_contained(_int4, _int4) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION _int_contained(_int4, _int4) IS 'contained in'; - -CREATE FUNCTION _int_overlap(_int4, _int4) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION _int_overlap(_int4, _int4) IS 'overlaps'; - -CREATE FUNCTION _int_same(_int4, _int4) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION _int_same(_int4, _int4) IS 'same as'; - -CREATE FUNCTION _int_different(_int4, _int4) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION _int_different(_int4, _int4) IS 'different'; - --- support routines for indexing - -CREATE FUNCTION _int_union(_int4, _int4) RETURNS _int4 - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -CREATE FUNCTION _int_inter(_int4, _int4) RETURNS _int4 - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - --- --- OPERATORS --- - -CREATE OPERATOR && ( - LEFTARG = _int4, RIGHTARG = _int4, PROCEDURE = _int_overlap, - COMMUTATOR = '&&', - RESTRICT = contsel, JOIN = contjoinsel -); - ---CREATE OPERATOR = ( --- LEFTARG = _int4, RIGHTARG = _int4, PROCEDURE = _int_same, --- COMMUTATOR = '=', NEGATOR = '<>', --- RESTRICT = eqsel, JOIN = eqjoinsel, --- SORT1 = '<', SORT2 = '<' ---); - -CREATE OPERATOR <> ( - LEFTARG = _int4, RIGHTARG = _int4, PROCEDURE = _int_different, - COMMUTATOR = '<>', NEGATOR = '=', - RESTRICT = neqsel, JOIN = neqjoinsel -); - -CREATE OPERATOR @ ( - LEFTARG = _int4, RIGHTARG = _int4, PROCEDURE = _int_contains, - COMMUTATOR = '~', RESTRICT = contsel, JOIN = contjoinsel -); - -CREATE OPERATOR ~ ( - LEFTARG = _int4, RIGHTARG = _int4, PROCEDURE = _int_contained, - COMMUTATOR = '@', RESTRICT = contsel, JOIN = contjoinsel -); - - --- define the GiST support methods -CREATE FUNCTION g_int_consistent(opaque,_int4,int4) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION g_int_compress(opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION g_int_decompress(opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION g_int_penalty(opaque,opaque,opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -CREATE FUNCTION g_int_picksplit(opaque, opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION g_int_union(bytea, opaque) RETURNS _int4 - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION g_int_same(_int4, _int4, 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__int_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, - 0); - - --- get the comparators for _intments and store them in a tmp table -SELECT o.oid AS opoid, o.oprname -INTO TEMP TABLE _int_ops_tmp -FROM pg_operator o, pg_type t, pg_type tq -WHERE o.oprleft = t.oid and ( o.oprright = t.oid or o.oprright=tq.oid ) - and t.typname = '_int4' - and tq.typname='query_int'; - --- make sure we have the right operators --- SELECT * from _int_ops_tmp; - --- using the tmp table, generate the amop entries - --- _int_overlap -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 3, false, c.opoid - FROM pg_opclass opcl, _int_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist__int_ops' - and c.oprname = '&&'; - --- _int_same -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 6, true, c.opoid - FROM pg_opclass opcl, _int_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist__int_ops' - and c.oprname = '='; - --- _int_contains -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 7, false, c.opoid - FROM pg_opclass opcl, _int_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist__int_ops' - and c.oprname = '@'; - --- _int_contained -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 8, false, c.opoid - FROM pg_opclass opcl, _int_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist__int_ops' - and c.oprname = '~'; - ---boolean search -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 20, false, c.opoid - FROM pg_opclass opcl, _int_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist__int_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, 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__int_ops' - and proname = 'g_int_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__int_ops' - and proname = 'g_int_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__int_ops' - and proname = 'g_int_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__int_ops' - and proname = 'g_int_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__int_ops' - and proname = 'g_int_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__int_ops' - and proname = 'g_int_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__int_ops' - and proname = 'g_int_same'; - - ---------------------------------------------- --- intbig ---------------------------------------------- --- define the GiST support methods -CREATE FUNCTION g_intbig_consistent(opaque,_int4,int4) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION g_intbig_compress(opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION g_intbig_decompress(opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION g_intbig_penalty(opaque,opaque,opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -CREATE FUNCTION g_intbig_picksplit(opaque, opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION g_intbig_union(bytea, opaque) RETURNS _int4 - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION g_intbig_same(_int4, _int4, opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - --- register the opclass for indexing (not as default) -INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype) - VALUES ( - (SELECT oid FROM pg_am WHERE amname = 'gist'), - 'gist__intbig_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'), - false, - 0); - - --- get the comparators for _intments and store them in a tmp table -SELECT o.oid AS opoid, o.oprname -INTO TEMP TABLE _int_ops_tmp -FROM pg_operator o, pg_type t, pg_type tq -WHERE o.oprleft = t.oid and ( o.oprright = t.oid or o.oprright=tq.oid ) - and t.typname = '_int4' - and tq.typname='query_int'; - --- make sure we have the right operators --- SELECT * from _int_ops_tmp; - --- using the tmp table, generate the amop entries --- note: these operators are all lossy - --- _int_overlap -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 3, true, c.opoid - FROM pg_opclass opcl, _int_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist__intbig_ops' - and c.oprname = '&&'; - --- _int_contains -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 7, true, c.opoid - FROM pg_opclass opcl, _int_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist__intbig_ops' - and c.oprname = '@'; - --- _int_contained -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 8, true, c.opoid - FROM pg_opclass opcl, _int_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist__intbig_ops' - and c.oprname = '~'; - --- _int_same -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 6, true, c.opoid - FROM pg_opclass opcl, _int_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist__intbig_ops' - and c.oprname = '='; - ---boolean search -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 20, true, c.opoid - FROM pg_opclass opcl, _int_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist__intbig_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, 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__intbig_ops' - and proname = 'g_intbig_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__intbig_ops' - and proname = 'g_intbig_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__intbig_ops' - and proname = 'g_intbig_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__intbig_ops' - and proname = 'g_intbig_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__intbig_ops' - and proname = 'g_intbig_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__intbig_ops' - and proname = 'g_intbig_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__intbig_ops' - and proname = 'g_intbig_same'; - -END TRANSACTION; diff --git a/contrib/intarray/bench/bench.pl b/contrib/intarray/bench/bench.pl deleted file mode 100755 index 2e30956721..0000000000 --- a/contrib/intarray/bench/bench.pl +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/perl - -use strict; -# make sure we are in a sane environment. -use DBI(); -use DBD::Pg(); -use Time::HiRes qw( usleep ualarm gettimeofday tv_interval ); -use Getopt::Std; - -my %opt; -getopts('d:b:s:veorauc', \%opt); - -if ( !( scalar %opt && defined $opt{s} ) ) { - print <connect('DBI:Pg:dbname='.$opt{d}); - -my %table; -my @where; - -$table{message}=1; - -if ( $opt{a} ) { - if ( $opt{r} ) { - push @where, "message.sections @ '{$opt{s}}'"; - } else { - foreach my $sid ( split(/[,\s]+/, $opt{s} )) { - push @where, "EXISTS ( select message_section_map.mid from message_section_map where message.mid=message_section_map.mid and message_section_map.sid = $sid )"; - } - } -} else { - if ( $opt{r} ) { - push @where, "message.sections && '{$opt{s}}'"; - } else { - $table{message_section_map} = 1; - push @where, "message.mid = message_section_map.mid"; - push @where, "message_section_map.sid in ($opt{s})"; - } -} - -my $outf; -if ( $opt{c} ) { - $outf = ( $opt{u} ) ? 'count( distinct message.mid )' : 'count( message.mid )'; -} else { - $outf = ( $opt{u} ) ? 'distinct( message.mid )' : 'message.mid'; -} -my $sql = "select $outf from ".join(', ', keys %table)." where ".join(' AND ', @where).';'; - -if ( $opt{v} ) { - print "$sql\n"; -} - -if ( $opt{e} ) { - $dbi->do("explain $sql"); -} - -my $t0 = [gettimeofday]; -my $count=0; -my $b=$opt{b}; -$b||=1; -my @a; -foreach ( 1..$b ) { - @a=exec_sql($dbi,$sql); - $count=$#a; -} -my $elapsed = tv_interval ( $t0, [gettimeofday]); -if ( $opt{o} ) { - foreach ( @a ) { - print "$_->{mid}\t$_->{sections}\n"; - } -} -print sprintf("total: %.02f sec; number: %d; for one: %.03f sec; found %d docs\n", $elapsed, $b, $elapsed/$b, $count+1 ); -$dbi -> disconnect; - -sub exec_sql { - my ($dbi, $sql, @keys) = @_; - my $sth=$dbi->prepare($sql) || die; - $sth->execute( @keys ) || die; - my $r; - my @row; - while ( defined ( $r=$sth->fetchrow_hashref ) ) { - push @row, $r; - } - $sth->finish; - return @row; -} - diff --git a/contrib/intarray/bench/create_test.pl b/contrib/intarray/bench/create_test.pl deleted file mode 100755 index b39d1fb473..0000000000 --- a/contrib/intarray/bench/create_test.pl +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/perl - -use strict; -print <message.tmp") || die; -open(MAP,">message_section_map.tmp") || die; - -srand( 1 ); -#foreach my $i ( 1..1778 ) { -#foreach my $i ( 1..3443 ) { -#foreach my $i ( 1..5000 ) { -#foreach my $i ( 1..29362 ) { -#foreach my $i ( 1..33331 ) { -#foreach my $i ( 1..83268 ) { -foreach my $i ( 1..200000 ) { - my @sect; - if ( rand() < 0.7 ) { - $sect[0] = int( (rand()**4)*100 ); - } else { - my %hash; - @sect = grep { $hash{$_}++; $hash{$_} <= 1 } map { int( (rand()**4)*100) } 0..( int(rand()*5) ); - } - if ( $#sect < 0 || rand() < 0.1 ) { - print MSG "$i\t\\N\n"; - } else { - print MSG "$i\t{".join(',',@sect)."}\n"; - map { print MAP "$i\t$_\n" } @sect; - } -} -close MAP; -close MSG; - -copytable('message'); -copytable('message_section_map'); - -print <) { print; } - close FFF; - print "\\.\n"; -} diff --git a/contrib/intarray/data/test__int.data b/contrib/intarray/data/test__int.data deleted file mode 100644 index b3903d0f33..0000000000 --- a/contrib/intarray/data/test__int.data +++ /dev/null @@ -1,7000 +0,0 @@ -{18,31,54,95} -{23,50,13,9,39} -{99,54,77} -{79,83,16,63,32} -{52,41,61,79,94,87} -{76,59,39,36,21} -{} -{41,79,76,96,3} -{25,59,5,96,32} -{92,58,12,57} -{24,48,41,88} -{39,5,17} -{10,41,78,25,35} -{31,89,4} -{68,74,94} -{97,78,44,68,81,16} -{87,76} -{30,81} -{72,20,99,26} -{87,90,98,40,44} -{24,99,66,61} -{79,8,48,16} -{62,99,48,80,75,39} -{10,60,35,15} -{45,71,10,97,56} -{64,79,19,31} -{30,57,42,31,45} -{61,42,14,26} -{12,38,65,36,56,36} -{17,62,18,56} -{84,85,90,60,55,17} -{27,11,82,20,43} -{14,27,18,48,39,51} -{53,13,52} -{56,35,81,60,27} -{79,89,89,7} -{65,17,31,17,29,85} -{21,3} -{53,55,16,83,4} -{62,3,63} -{73,40,99} -{23,80} -{2,74,42,37,21} -{12,16} -{80,60} -{19,62,34} -{38,19,31,6,15,2} -{63,96,64,4,36,15} -{9,3} -{91,87,15,18,7,66} -{17,10} -{77,96} -{11,43,31,2,89} -{17,77,89,50} -{24,6,61,88,51} -{61,50,59,90,5,89} -{58,1,39,48} -{78,36,70,92} -{43,3,22,95,51} -{} -{88,64,25,64,86} -{34,6,49,90,25} -{86,35,13,22} -{21,44,83} -{42,88,72,65,59,96} -{36,33,1,98} -{16,54} -{35,16,44} -{73,23,20} -{84,25,1,52,35} -{27,36,54,87,31} -{38,47,83,3} -{64,13} -{65,84,85,16,22} -{57,9,39,73} -{89,11,67,55,73} -{78,39,84,63,62,45} -{50,63,8} -{} -{96,36,58,65,96} -{59,86,41,30} -{90,60,39,47,19} -{70,100,73,99} -{} -{85,14,39} -{76,53} -{96,38,52,13,87,85} -{97,51,15,30,53,87} -{30,59,9,40,13} -{31,91,68,79} -{37,56,39,78,75} -{82,2,47} -{33,25,45,40} -{51,21,92,20,18,76} -{84,93,36,95,34,69} -{66,25,5,40} -{77,6,57,42} -{} -{88,81,85,37,12} -{56,73,38} -{70,70,6,19} -{82,54,91} -{75,8} -{45,33,64,90,95} -{8,71,66,12} -{56,26,68,94} -{70,77,4,96,62,83} -{23,87} -{34,34,4,33} -{28,84} -{78,75,77} -{88,53} -{27,38} -{2,2,82} -{30,52,88,61,33} -{29,72,94,68} -{85,72} -{88,4} -{63,90,43,66,24,33} -{88,48,47} -{3,11,98,37,61} -{45,65,63,15,38} -{79,45,56,94} -{56,74,78,19,76} -{24,81,64,13,100} -{93,27,63,71,27,3} -{74,13,85,86,32,60} -{98,40,63,13} -{41,95,19,93,17,84} -{90,28,100,100,19,2} -{35,15,54} -{29,81,77} -{54,64,63,12,18} -{38,43,85,21,35} -{84,28,27,4,80,27} -{80,77,55,98} -{13,71,48,55,89,38} -{58,43,27,5,57} -{5,33,96,6} -{73,93,87,69,100,24} -{58,96,38,85,55,51} -{37,30,88,4,8,59} -{24,68,43,48,18,84} -{23,100,82,30,42} -{23,36,16,99,27} -{41,75} -{66,41,10,37,16,6} -{54,49,60} -{4,56,44,72,40} -{71,96,67,100,59} -{7,41} -{8,3,27} -{38,69,47,68,5,24} -{43,100,59,62} -{92,14,34,5,71,48} -{72,5,91,29,99,36} -{62,71,37,80,62,50} -{32,45,17} -{89,68} -{52,17,55} -{21,47,15,92} -{36,100,5} -{14,76,59,11,15} -{59,72} -{37,55,89,49} -{87,79,96,20,93} -{6,44} -{32,46,25} -{27,47,76,4,54} -{2,16} -{90,36} -{11,19,27,79} -{54,4} -{72,88} -{14,85,71,69,5,22} -{31,48} -{28,35,18} -{77,55,100,73,57,62} -{} -{14,59,53} -{98,3} -{13,56} -{26,61,88,54,88,33} -{70,12} -{55,16,15,42,76} -{13,75} -{97,38,82,51,86,53} -{41,76,39,84,32} -{94,66,47} -{55,28} -{} -{94,65,59,20} -{55,50,56,14,58} -{14,94,52,25,69,95} -{20,96} -{37,38} -{26,35,9,98,74} -{11,9,41,79} -{36,57,87,69,92,89} -{11,39,60,4,47,3} -{97,5} -{16,58,38,98,42} -{46,69} -{35,54} -{36,79,54} -{} -{63,78} -{12,86,52,29,60,30} -{29,27,58,86,42,62} -{42,12,60} -{90,93,85,29} -{16,8,45} -{29,33,85} -{32,14,6,47,74} -{14,85,14,26,3} -{46,71,10,16} -{30,63} -{} -{91,30,56} -{46,36,68,91,36,88} -{24,61} -{66,21,80,14} -{43,63,50,21,11} -{38,46,18,51} -{38,28,70} -{17,41,76,1,30} -{47,63} -{56,80,85,1,7,97} -{75,5,79,32} -{5,17,66,51,68} -{6,83,2} -{25,40,79,84} -{58,38,12,68} -{55,86,20,67,27} -{58,64} -{14,51} -{12,86,57,68} -{61,91,65,3,83,68} -{40,31,82,21} -\N -{24,64,35,32} -{32,83,18,27,43,32} -{50,83} -{94,84,58,3,25,79} -{66,2,27,36,24} -{71,34} -{17,57} -{22,40,49,50,10} -{79,62,94,78} -{92,79,24,72} -{23,41} -{69,60,77,70,18,48} -{39,45,91,85} -{27,43,22,21,85} -{84,51,96,7,18} -{100,38,69,93,66,39} -{73,42,35,15,69,98} -{100,17,37,15,40} -{1,91,2,17,90,48} -{18,12,52,24} -{39,43,89} -{16,13,88} -{69,8,75} -{34,91,54,81} -{37,68,89,1,56} -{81,83,39,36,14} -{12,15,2} -{14,16,88,43} -{59,12} -{1,62,21,94} -{29,43,70,52,93} -{29,36,56,78} -{91,56,86,89,53} -{14,83,39,94} -{29,58,72,4,45} -{76,56,84,28,58} -{4,52,6,88,43,17} -{21,1,35,62,77,6} -{78,74} -{1,20,93,43} -\N -{30,100,35,94,74,64} -{81,3,21,4} -{9,19,33} -{28,62,40,64,26} -{69,72,26,30,90} -{52,70,78,43} -{91,58,33,22,92,26} -{98,36,96,94,66} -{86,43,82} -{93,52,4,58,51} -\N -{49,61,80,79,90} -{50,81,72} -{57,29} -{54,31,36} -{52,31,6,48,2} -{4,51,37,83,17} -{60,20,94,82,18} -{52,64,26,81,69,61} -{39,8,22,2,8} -{31,25,95,99} -{11,72,30,95,20,28} -{78,87} -{21,40,98,41,73,33} -{67,88,42,62,11,47} -{85,1} -{4,68,100,72,24} -{82,43} -{97,55,47,52} -{51,52} -{20,21} -{69,46,34,59,54,61} -{9,31,43} -{68,20} -{73,63} -{71,12,93,8,48,10} -{44,46,42,91,21} -{98,52} -{45,60} -{95,38,30,3} -{27,77,2,46,53,18} -{99,5} -{79,33,34,48,82} -{3,29,82,72,35} -{73,75,83} -{25,43,37,26} -\N -{51,95,40} -{18,23,10,90,15,20} -{85,66} -{25,76,22,87,88,18} -{92,4} -{27,51} -{25,77,12,37} -{44,52,69,39,21,63} -{94,30,74,36} -{60,18} -{62,88,94,93,26} -{5,72,96,25} -{99,1,85,98,85,70} -{33,21,37,19} -{44,78} -{47,2,73,32,3} -{91,35,10,81} -{80,64,7,45,84} -{86,16,96,8,88} -{32,29,84,81,30,8} -{51,28,6,16} -{88,51,50,54,56,96} -{79,19,41,40} -{40,26,10,26,2} -{60,34,3,29} -{68,80,70,56} -{60,23,39} -{50,69,6,71,70,25} -{98,53,94,14,45,11} -{98,39,64,89,98,32} -\N -{45,5,15,23,41,63} -{54,31,55,58,32} -{36,56} -{38,78,65,4,75,38} -\N -{40,6,93,40,13,59} -{42,50,10,65,96} -{6,94,49} -{63,44,36,55} -{40,79} -{39,75,27} -{8,31} -{81,75} -{99,82,85,34,24,89} -{86,82,20} -{63,96} -{47,83,29} -{70,46,48} -{44,11} -{94,19,84,79,77,22} -{68,47,100,48,65,77} -\N -{76,12,86,58} -{13,14,79,61,12} -{68,65,16,93,89} -{95,18,29,89,92,43} -{19,12,50,47} -{82,93,85} -{71,40,85} -{95,96,100,86} -{2,40,71,36,25} -{11,95,25} -{79,46,41,35,39} -\N -\N -{88,29} -{54,14,94,88} -{59,67,81,41} -{46,68,78,56,47,30} -{5,76,87} -{23,89,47,46} -{47,98,14,31,1,60} -{32,14,96,61,37} -{79,66,93} -{98,1,77,44} -{21,68,2,31,17} -{94,23,15} -{48,47,57,94,49,71} -{54,3} -{99,40,81,86,81} -{85,12,98,81,5} -{60,41,21} -{38,82,55,41,96} -{11,98,12,69,93} -{11,70,66,44} -{23,92,80} -{10,8,43,97} -{17,30} -{78,56,58} -{84,87,84} -{12,32,7,58,47,48} -{29,46} -{87,34} -{59,30,72,85,71} -{67,48,83,98} -{35,10,73,71,1,77} -{21,51,16,60,64,12} -{36,61} -{54,98} -{44,74,84} -{83,14} -{71,52,48,48,15,92} -{79,78,98,35} -{52,29,47,86,96} -{10,37} -{21,25} -{57,22,28,30,97,47} -{15,28} -{88,24,98,45,65} -{78,42} -{36,70} -{40,48} -{72,3,78,69,57,33} -\N -{21,96,16,21,75,23} -{55,5,72,45} -{99,2,72,29} -{48,17} -{84,84,40,1,59} -{34,11} -{34,80,45,31} -{56,82,25,65,22,64} -{10,4,55} -{74,67,42,74,80} -{84,22,42,6,87,30} -{6,51,89,2,84,78} -{19,95,93,87,8} -{45,84,25} -{7,12,16,92} -{89,82,16} -{22,64} -{16,31,49,48,45,14} -{69,64,19,14,39,8} -{40,96,26,48,65} -{17,45,4,57} -{73,8} -{85,89,1,15,74,51} -\N -{57,89} -{25,12,55} -{39,62,35} -{85,88,71,98,83} -{64,63,75,72} -{100,40,38,1} -{2,44} -{13,46,59,43} -{87,9,93,50} -{77,7,11,30} -{61,11,18} -{19,25,68,83} -{67,25} -{54,18,85} -{96,81,38,11,3} -{87,32,47,79,62,56} -{42,49} -{41,65,24,13,79,75} -{85,32,96} -\N -{3,63,47,84,67,13} -{53,57,59,61} -{95,27,8,89,35} -{76,78,76,76,14,37} -{31,62,65} -{97,57,60,80} -{18,81,93,67} -{8,10} -{65,25} -{68,1,62,63,64,88} -{27,56,74} -{29,61,78,40} -{54,72} -{96,30,71,21,99} -{67,11,67} -{26,65,31} -{89,90,89,68} -{56,39,63,39} -{50,67} -{72,100,24,84,9} -{29,57,65,37,3} -{72,75,79,30} -{78,44,87,67} -{100,19} -{35,60,82} -{16,83,69,38} -{29,98,13,60} -{42,60,87} -{18,67,60} -{31,77,50} -{3,22,40,59,7} -{82,80} -\N -{32,92,70,30,18,35} -{48,38,92,82} -{10,92,66,59} -{4,67,42,21,71} -{27,88,20,21,9} -{46,22,27,85,36} -{42,55,36} -{24,2,96} -{96,48,40,48,52} -{15,5,90,10,68,20} -{30,2,67,92,96,63} -{16,82,87,26} -{88,98,76,29} -{29,11,94,23} -{58,20} -{52,18,55,73} -{20,81,52,19,37} -{93,21,97} -{2,77} -{46,91,80,48,71,20} -{87,7,93} -{68,77,61} -{59,33,52} -{67,62,89,2,62,90} -{30,82,72,44} -{72,18,60,38} -{11,14,59} -{74,65,54,58,67,66} -{74,56,40,73,50,66} -{42,17,56,59,53,19} -{75,25,76,9,72,50} -{14,57} -{61,47} -{90,11,72,13} -{52,27} -{80,84,53,55,98} -{16,26,55,17,79,96} -{42,73,77} -{6,84,67,54,96} -{99,48,99,63,73,77} -{5,41,72,5,88,81} -{19,20,20} -{21,89,55,44} -{82,67,11,64,61,5} -{44,34,8,62,53} -{75,53,66,36,100} -{46,65,6,70,4} -{84,10,56,35,18} -{65,60} -{88,56,27,11} -{10,9,97} -{97,49,100,100,76,32} -{2,98,57} -{47,57,84,74,79} -{80,9,24} -{96,33,86,28,19} -{43,76} -{46,14,55,92} -{60,69,66,62,22} -{45,85} -{45,9,36,13,45,1} -{24,49,8,37,66,64} -{98,53,96,47,2} -{36,44,32,4} -{77,36,78,51,63} -{82,36} -\N -{54,55,33,45,69,18} -{82,93} -{65,59,2,62,10,25} -{75,70,76,69,7,23} -{10,34,67,85} -{94,66,28,40,64,41} -{35,73,64,28,45,68} -{75,2} -{58,49,4,87,19} -{91,99,11,66,75,70} -{26,64} -\N -{13,51,18} -{39,33,21,18} -{27,50,82,2,3,71} -{51,89,44,53} -{88,91,34} -{45,96,27,12,51,52} -{31,96} -{2,9,54,89} -\N -{57,99} -{87,84,70,7,98,42} -{32,80} -{57,64,28} -{24,39,76,4,30} -{59,38,15,45,47,28} -{71,20,37,1} -{72,59} -{7,44} -{50,37,18,1,58,40} -{13,18,21,56} -{72,3,26,74,91} -{60,22,71,49} -{55,82,61,8,48,66} -{28,22,75,41,52} -{51,63,27,41,16} -{59,89,40,85,86} -{12,1} -{52,11,6} -{37,10,43,88,15,7} -{14,94,81} -{34,56,57,4} -{81,43,11,88,74,76} -\N -{67,10,50,79,70,35} -{14,51} -{49,50,23,84} -{51,41,57,100,19,14} -{31,55,40,96} -{8,42,33} -{83,34,1} -{56,80,22,93} -\N -{8,77,91} -{58,39} -{55,30,74} -{50,22,63,73} -{80,19,67,70,18} -{7,99,45,23,59,78} -{36,97,10,33,22,45} -{43,78,90} -\N -{1,68} -{63,95,54} -{5,67,61,37,89} -{32,97,2,56} -{83,31,6,80,63} -\N -{34,15,30,40,16} -{13,43,6} -{35,86,31} -{45,59,4,95,26} -{63,48,25} -{56,97,89,45,87,21} -{42,81,69} -{49,99,87} -{81,21,15,36,70,2} -{93,41,53} -{54,71,82} -{88,90,51} -{100,35,18} -{88,81} -{76,16,87,14} -{16,83,81,44} -{16,53,100,91} -{55,75,92} -{27,97,76,88,66} -{14,100,95,95} -{95,84,93,29,67} -{32,10} -{82,12,51} -{40,6,18,14,29,70} -{3,100,81} -{83,69} -{35,63,31,15} -{5,100,81,54,37,78} -{99,76,33} -{88,85,16} -{46,20,15,10,6,90} -{53,15,75,76,94} -{5,76} -{16,7,21,70} -{3,84,15} -{29,58,73,91} -{82,39,64} -{49,66,83,76} -{79,49,19,67,18,76} -{9,56,41} -{12,22,19} -{62,54} -{20,73,40} -{34,53,58,68,96} -{97,14,61,63} -{38,55,90,63} -{83,78,81,29,12,46} -{96,97,40,89,10} -{67,33,19,19,74,47} -{78,31} -{92,74,93} -{59,54,90,52,29,87} -{92,39,55,89,81,21} -{20,85,64} -{13,97} -{88,18,85,24,54,90} -{67,51,47} -{27,29,90} -{48,27,7,92} -{100,37,24,41,68,66} -{45,7,100,83,51} -{34,10} -{60,36,44} -{55,46,4} -{86,64} -{61,77,98,64} -{14,82,14,50,1} -\N -{53,31} -{64,43,35,44,98,75} -{98,15,52,58,76} -{55,94,92,40,80} -{1,14,100,42,45,74} -{13,90,84,97,18,92} -\N -{13,91} -{67,33,15} -{18,96,38} -{95,70,34,100} -{17,29,64,32} -{19,14,83,69,60,99} -{69,29,64,61,45,17} -{78,48,24} -{40,60,61,93,17} -{19,89,22,71} -{48,8,13,11,56} -{75,18,77,100} -{29,78} -{51,92,97,31} -{83,5,2,97,68,69} -{39,86,86,94,41} -{66,21,27} -{30,84,11,60} -{50,61,28,46,38,45} -{12,59,66,80,15,64} -{69,22} -{30,54,58,99} -{14,28,80,22} -{44,31,14,61,83,72} -{55,53,78,91,76,55} -{43,3,90,22,7} -{51,34,24} -{3,99,5,72,82} -{95,38,61} -{22,8} -{78,40,93,65,18,26} -{21,17,19,8,89} -\N -\N -{94,88,27} -{49,45} -{67,24,64,86,18,1} -{5,33,18,84,51} -{15,71,89,48,94,81} -{71,69} -{98,63,73,64} -{14,75,12} -{47,42,88,13} -{35,51,60} -{63,41} -{73,11,66,99,8} -\N -{2,17,6,44,97} -{95,24} -{2,13,35,21} -{76,29} -{81,37,21} -{23,63,27,53} -{70,66,58,27,4} -{69,62,22} -{62,96,44} -{68,87,99} -{51,40,81,52,93} -{81,11,45,92,22,21} -{5,39,46} -{44,7} -{14,63,62,9,12} -{9,19,90,72,51} -{70,61,24,36} -\N -{29,19,3,30} -{76,86,28,58,38} -{59,27} -{9,65,65,10,37,6} -{89,51,50,23} -{65,2} -{33,51} -{25,55,69,55,1,78} -{76,71,93,46,23} -{70,30,50,11,2,89} -{74,39} -{4,29,22,80,15,23} -{16,30,69,76,61,67} -{43,34,4,70,36} -{59,32,25,93,32,98} -{64,4} -{52,33,47} -{31,49,7,62,7,95} -{44,69,12,45,34,8} -{81,37,83,35,3} -{24,74,16,89,94,27} -{79,71,72,49,88,35} -{17,96,72,87,48} -{81,18,50} -{11,19,70} -{42,95,42,58,90} -{27,65,83,86,33} -{55,7} -{43,55,92,79} -{97,55} -{85,25} -{93,42,69,44,26,78} -{2,40,46,19,84} -{8,42,16,26,87} -{36,8,42} -{31,47,61,44,13} -{85,97,47} -{27,30,71,88,15,100} -{69,27,4,19} -{3,52,31,62,98} -{64,86} -{91,6} -{76,40} -{57,77,7,40} -{71,34,48,53,37} -{36,72} -{61,99,53,2,31,6} -{86,15} -{52,93,59,51} -{57,27,52} -{48,67,31,69} -{34,90,37,73,60,83} -{71,24,49,59} -{93,71,90} -{77,31,77} -{47,40,32,20} -{97,40,63,80,44} -{88,55,10,40} -{86,36,40,72,38,9} -{31,97} -{56,19,55,62,60} -{53,95} -{33,36} -{50,12,55,42,96,100} -{41,17,100,76} -{65,1,61,69,64,21} -{90,92} -\N -{74,42,86} -{2,4} -{99,78,5,92,1,61} -{1,69} -{80,73,60,31} -\N -{10,25,13} -{50,34,75} -{12,90,6,36,42} -{23,54,46} -{67,28,66,87} -{8,88,88,51,55,32} -{15,19,24,91,75} -{80,16,70} -{41,7,90,37} -{97,57,32,21} -{54,74,29,12,55,78} -{60,76,37,92,44,73} -{1,56,14} -{40,79} -{97,1,30,78,56} -{36,25,61} -{33,3,51,30,38} -{2,94,19,15} -{7,38,72} -{96,18,3} -{18,95,15,62,74,53} -{59,61} -{18,66,66,65,4,33} -{49,83,10} -{17,52,90,39,61,87} -{38,92,55,26} -{8,43} -{77,51,68,23,47} -{27,65,24,43,88,73} -{54,34,30,2,19,62} -{12,36,81,24,66,8} -{38,91,90,99,84} -{51,55,94,97,91,15} -{50,42,20,22} -{70,4,22} -{64,26} -{56,86,16,21,31,61} -{7,19,86,49,10,53} -{81,16,74} -{95,9,11,46,47} -{34,23,16} -{94,38,19,4,4} -{39,79} -{41,3,62} -{84,67,53,90,46} -{17,46,23} -{62,1,5,58,52,1} -{23,83,80,62,19} -{99,61,77} -{51,95,48,96,75} -{39,2,6,95,43,36} -{69,9,59} -{62,97,31} -{75,96} -{33,29,35,13,94,78} -{28,71,16,99} -{72,86,25} -{5,28,15,33} -\N -{13,13,52,20} -{58,98,83,85,81} -{13,75,42} -{7,91,3,83,82,37} -{72,91} -{10,67,61} -\N -{43,86,76} -{36,62} -{64,56} -{63,13,22,24} -{76,49,38,23,9,8} -\N -{92,58,24,19,96,90} -{24,37,76,37,1,95} -{91,9} -{46,35,48,37,91,76} -{72,21,6} -{30,80,39,90,89,18} -{83,30,67,17} -{43,36,46,43} -{4,31,34,36,33,48} -\N -{16,49} -{75,56,8,91,4} -{92,80} -{74,72,68,89,7,82} -{79,17,26} -{14,15,28,72,58} -{42,21,9} -{71,39,98,98,61} -{68,63,23,74,74,48} -{91,80,22,100,57,30} -{63,60} -{90,9,10,67,89,14} -{53,93} -{75,49,34,30,38} -{2,43} -{32,4,24,48,23,31} -{45,24,31,15,51} -{65,62,21} -{83,50} -{10,90,98,86,87,1} -{63,2,9,17,30} -\N -{77,46,60} -{49,39} -{37,86,4,63} -{33,28,37,33} -{4,88,80,14,47,45} -{90,64,17,65} -{60,90,12} -{7,2,38,33} -\N -{39,90,7} -{89,32} -{27,47,63,31} -{54,10,10,73,84,87} -{55,58,25,87} -{41,24} -{71,26,8,31} -{74,19,33,81,74} -{47,58} -{44,16,22,59} -{2,10,97,16,25} -{1,98,3,41,6,80} -{12,13} -{3,50,61,85} -{54,5,44,97,71,86} -{54,72,94} -{59,13,28,79} -{73,68,7,13} -{90,49,63,45} -{95,47,84} -{31,79,98,22} -\N -{13,15,83,89,87,20} -{1,58,87} -{15,21,39} -{93,27} -{40,81,13,31} -{29,52} -{28,48,36,41} -\N -{71,23,89} -{29,59,31,45,35} -{49,83,24,19,44,26} -{41,61,36,34,38,88} -{66,17,18,9} -{55,38,93,33} -{84,42,71,15,12} -{11,38,78,80,90,92} -{1,6,28,68,58} -{96,63,73,22,74,29} -{65,97,68} -{92,29,92,36} -{47,25,30} -{25,44,67,95,16} -{7,26,41} -{79,12,44,69} -{17,27,4,60} -{45,30,57} -{68,24,63} -{39,64,94,92} -{27,68,39,68,75,8} -{88,48,48} -{86,86,8,54,7,45} -{93,60,14,90,14} -{97,42,54,67,38} -{13,38} -{84,34,30} -{34,71,77,71,13} -{82,18} -{53,7,79,79} -{28,65,38,20,93,100} -{96,10} -{94,12,93,48,51,20} -{12,4,41,11,25,59} -{95,69,23,25,1,19} -\N -{44,38} -{12,4,96,7,48} -{18,24,52,81,58,77} -{15,36,1,50,81,23} -{39,66,74} -{52,22,99} -{51,11,77,44,22} -{51,19,18,91,75} -{20,17,5,96,63,30} -{31,56,9,21} -{45,70,31,62,9} -{84,22} -{99,62,97,44,87,90} -{95,94,95,24,25,47} -{79,72,57,18,3,26} -{54,67,37,57} -{3,90,9,3} -{95,90,40,7} -{36,70,76,68,14,71} -{15,59,7,1,48} -{91,29,79,62,94} -{76,36,92,82} -{50,79,68} -{55,63,88,87} -{86,89,49,17} -{19,74,14,52,8,59} -{8,58} -\N -{77,74,20,39,26,29} -{38,89} -{58,21,44,81,17,16} -{40,72,12,32,90} -{93,34,92,17,39,85} -{39,2} -{43,21,83} -{81,3,59,28} -{34,97,52} -\N -{84,90,6,74,43,70} -{41,6,10,98,86,41} -{13,72,78,11,37,5} -{100,40,54,75,33} -{66,31} -{58,58,75,83} -{81,90,8,73,87,41} -{9,63,22} -{19,66,19,93,52} -{39,88,13,25,66} -{80,85,66} -{66,76,11,71,97,77} -{70,35,87} -{36,17,69,2,41} -{30,85,65,39,38} -{39,35} -{64,100} -{83,53} -{25,29,29,72} -{19,63} -{32,2,82,15} -{31,31,46,11,2} -{41,1} -\N -{55,41,15} -{18,61,43,22,100} -{47,60,16} -{80,5} -{52,2,76} -{40,26} -{81,12,16,25} -{31,93,89,20,95,75} -{26,75,86,1} -{36,69,70,73,79} -{38,39} -{45,49,52} -{88,53,45,10,49,31} -{21,14,1,83} -{7,71} -{59,38,83,64,44} -{6,52} -{99,99,26,54,47,8} -{13,46,72,5,23} -{7,86,40,73,55} -{28,47,50,62,44} -{32,89} -{39,48,50,100,62,95} -{66,56,11,21,58,59} -{7,44,95,53,95,36} -{83,33,79} -{34,65,51,52} -{67,95,46,45,61} -{69,84,71,38,46} -\N -{24,57,48,27,97} -{83,91,97,94,37,44} -{22,31,38,77,21} -{72,32,53} -{30,45} -{93,94,27,95} -{95,4,79,3} -{33,90,92,54} -{55,8,76,39,85,64} -{82,54,93} -{31,42,5} -{38,14,73,12,14} -{64,13,64,28,32,89} -{5,28,4,22,72} -{37,78,94} -{58,73} -{24,57,33} -{48,28} -{69,42} -{97,91,75,84} -{95,69} -{64,95} -{1,3} -{76,38,81,11,90} -{21,30,54} -{92,100,97,21} -{10,76,64} -{85,79,100,79,76,63} -{13,96} -{91,47,84} -{100,19,45,49} -{99,71,21,10,69} -{19,41,7,63,56,85} -{16,32,6,92} -\N -{62,7,22,65} -{1,86,67,47,83} -{26,2,100,51,1} -{20,22,86} -{74,95,79} -{8,53} -{85,59,61,45,83,8} -{2,76,63,26} -{40,42,84,55,56,23} -{37,7,25,14,2,47} -{86,16,98,41,33} -{76,30} -\N -{16,88,61,4,41,42} -{59,92,94,76} -{96,76,57,62,99,61} -{14,30,23,13,9,32} -{47,49,86} -{48,19} -{73,25,40} -{29,75,31} -{53,26} -{28,95,78,84} -\N -{22,77,13,64,68} -{15,69,82,26} -{42,37} -{64,59,95} -{37,72,86,95} -{9,59,92,57} -{65,37,13} -{93,67,81,54,89} -{21,52,78,59,30} -{98,90} -{17,35,57,4} -{44,56} -\N -\N -{25,26,13} -{62,41,60} -{28,92,16,74,4} -{92,19,85,77,11} -{20,67,85,22} -{75,69,34,29,64,73} -{70,40,2,29} -{87,27,70,54,6} -{10,8,9,62} -{71,41,14,22,23} -{83,79,46,37,99} -{79,42,3,54,20} -{12,60,42,100,39,33} -{13,79} -{95,28,54,52,77,3} -{55,50,25,41,42,16} -{96,67,23,54} -{65,54,32,52,16} -{100,11,69,96,95} -{1,18,93} -{53,78} -{24,40,47,30,40,11} -{87,7,12,10,52,90} -{3,72,95,15,32} -{60,69,19,8,43,72} -{88,10,11,55,37} -{67,48,31,48} -{98,70,38,97,14} -\N -{52,12,94} -{41,26} -{81,65} -{66,74,9,66,12,3} -{47,6,33,92} -{95,2,12,90,73,97} -{23,76,34,23,2,20} -{7,22,37,83,15} -{44,61,21,8,36} -{88,52,8} -{66,3,67,43,87} -{16,51,10} -{66,43,28,69,70} -{47,2,94} -{57,67,55} -{40,59,6} -{63,19} -{51,71,68,28} -{73,97,48,56,70} -{3,4,28,48,18} -{31,94,27,70,44} -{85,18,40,6} -{78,91,79,88,33} -{11,90,78,49,97} -{74,91,27,79,75,53} -{1,70,3,40,43,99} -{97,35} -{58,27,40,6,47,33} -{43,42,60,94} -{41,34,23,53} -{57,44,50} -{8,10} -{49,53,22} -{91,2,90,13} -{46,80,27,82,42,99} -{12,96,72,23,83,56} -{48,82,71,8,35,16} -{38,69,38,49,47} -{80,28,13,9} -\N -{84,13,12,33} -{31,57} -{68,86} -{4,96,64,19,48,29} -{66,8} -{33,86} -{32,38,86,86,41,84} -{38,51,31} -{59,17,76,36} -{52,87,60,54} -{7,58} -{34,52,58,90} -\N -{30,67,97,2,1} -{93,10} -{47,16,46,8,39,84} -{90,77,37} -{92,58} -{38,94,49,53,11} -{70,49,35,67,18,28} -{58,81} -{79,100,9} -\N -{97,13,56} -{99,40,87,67,58} -{24,47,19,16} -{12,27,47,48,3,59} -{1,58,15} -{97,28,6} -{94,50,31} -{71,34,94,53} -{26,5} -{46,66,56,27,37} -{76,4,1} -{80,63,40} -{89,82} -{39,100,71,82,95,8} -{81,86,27,83,57,47} -{30,30,92,8,33} -{95,20} -{4,19,8,74} -{20,32,83,62,19,18} -{75,29} -{100,13,6,41,23} -{63,5,93,72,43} -{64,13,73} -{35,91,61,26,41,96} -{49,56} -{2,28,80,84} -{15,48} -{32,49,96} -{72,73,57,69,16} -{95,1,88,64} -{70,55,88,66} -{76,66,30,92,1} -{88,21,74,65,93} -{72,75,75,3,26} -{55,32,85,68,84} -{45,40,93,33,72,20} -{83,89,6} -{4,60} -{72,56} -{73,7,69,25,96,74} -{100,72,41,48,63,37} -{21,72,70,94,67,54} -{6,9,58,77,35} -{70,59,35,25} -{86,96,87,62,13,5} -{93,52,74,57,58} -{93,23,88,50,56} -\N -{95,72,68} -{63,52,58,41,54,90} -{52,23,53,32} -{93,87,39} -{23,73,6,46,79,72} -{44,17,12} -{79,59} -{31,62,14,26,75,23} -{64,72,18,48,63,50} -{71,40,59,87} -\N -{82,17,10} -{44,29} -{6,4,39,16,21} -{94,17} -{91,61,37,36,9} -{53,38,7,28,92} -{95,93,35,18,48} -{35,77,53,87,97,92} -{56,28,68,19,28,86} -\N -{23,91,56} -{97,5,89,24} -{18,81,17,78,63} -{83,19,46,10,22,66} -{100,17,45} -{25,87,61,79} -{17,57,99,1,39,1} -\N -{2,51,26} -{93,69,84,85,87} -{40,58,70} -{86,84,96,41} -{28,36} -{39,85} -{16,84,75,68,87,17} -{14,84,57} -{25,85,35,82,56} -\N -\N -{7,30,17,2,66,91} -{45,17,57,27,98,65} -{57,86,15,40,68,23} -{82,32,28,89,41,79} -{28,3,35,61} -{76,95,19,81,48,50} -{34,6,85,47,65,2} -{70,23,91,33,15} -{30,24,47,96,61,47} -{78,88,64,60} -{87,40,86,97} -{47,14,54,37,100} -{48,95,32,77,69} -{58,12} -{63,20,49} -{78,85,41,72,6} -{39,20,89,21,62,76} -{71,6,10} -{63,4,71} -{51,21,37,63,54} -{66,6,63,12,58} -{89,97} -{64,70} -{53,1,65} -{57,73,30,26} -{15,99,47,89,95,99} -{12,86,7} -{50,68,1,31,67} -{47,86,54,44} -{78,7,86,76,22} -{46,71,98,62,67} -\N -{64,91,80,63} -{82,61,17,58} -{85,64,90} -{37,26,64,97} -{68,25,26,61,68} -{11,21} -{63,53} -\N -{87,88,75,65,10,48} -{32,7,38,72,44} -{99,81,59,10} -{31,58,60,66,41,28} -{23,27,57,74,4} -{20,94,28,29} -{91,5,15,61,50,29} -{34,58,15,85,65,29} -{52,50,2,95,87} -{3,94,54} -{7,61,96,49} -{51,70,23} -{87,49,27,6,7} -{83,61} -{36,92,48,57,20,83} -{53,12,60} -{60,11} -{68,43,74,23,66,55} -{66,8,54,24} -{48,72,41,74} -{81,99,50,33,20,13} -{27,80,60,83,26,74} -{80,1,59,50,15,99} -{11,70,20,29} -{23,84,63} -{63,24,91,19,28} -{25,17,95} -{94,13,81,69,26,89} -{31,48} -{45,20,74,51,62,33} -{77,55,17,63,4,18} -{89,14} -{85,85} -{23,11,85,74} -{29,76} -{62,40,96} -{1,29,25} -{56,26,12} -{5,22,6} -{61,9,6,85} -\N -{31,34,49,11,19} -\N -{14,20,64,73} -{63,1,85} -{2,58,61,100,9} -{89,92} -{37,13,81,77} -{36,26,16,76} -{78,10,10,92,63} -{68,6,35,71,92,27} -{2,88,33,14,85,27} -{80,95,71,98} -{8,33,33,55,90} -{62,74,15,10,64} -{60,18} -{6,77} -{27,38,4,49,27,89} -{94,84,94,8,98} -{15,73,47,47,26} -{73,38,69,90,9,13} -{17,33,32} -{51,57,25,40,41,37} -{77,70} -{66,10} -{50,90} -{96,88,30,65} -{30,49,100} -{34,46,19,89,52,24} -{83,85,62,72,10,64} -{98,56,23,77,79} -{97,90,83,85} -{19,66,70} -{70,89,59,12,71} -{24,96,22,4} -{43,32} -\N -{92,85,41} -{96,90} -\N -{4,5,82} -{58,32,34,86,30} -{51,8,44} -{31,96,37,47} -{51,15,41,97} -{86,41} -{41,26,61} -{62,79,68,73,5} -{32,9,88,30} -{89,34,64} -{70,18} -{64,31} -{14,73,1,50,75} -{57,1} -{53,92,38,13,56} -{41,1,87,40,60} -{83,75,19} -{69,98,25,64} -{69,75} -{84,13,25,8,81} -{41,52} -{90,80,17} -{19,53,72,62,94} -{29,30,99,32} -{32,85,73,26,47} -{6,48,89,93,23} -{73,47,93,10,48} -{60,21,26,60,63} -{85,41} -{75,61,61,45} -{51,7,5} -{9,46} -{83,36,7,84,96} -{71,78,55} -{43,53,88} -{8,1,80,69} -{88,86,51,12,37} -{45,69,40,85} -\N -{36,53,60,15,7,7} -\N -{92,5} -\N -{51,13,34} -{39,23} -{16,26,93} -{91,96,19} -{89,64,2} -{8,74,29,24,66} -{26,19,30,27} -{81,59,52} -{99,28} -{5,12,63,79} -{14,80,90,83,47,79} -{67,64,32,58,44,19} -{27,32,52,79,55} -{68,87} -{14,31,20,12} -{38,99,65,32,15} -{27,57,35,17,53} -{63,64,6,60} -{70,38,47,65} -{24,87,20,4} -{86,27,19,56} -{62,44,1} -{46,10,26,48} -{40,57} -{61,9,59,80,51,20} -{83,44} -{77,1} -{78,63,42} -{75,93,95,76,9,52} -{20,58,10,37} -{72,75,41,73} -{63,93,5} -{57,65,47} -{34,6,51,38,21} -{54,7,19,9} -{61,6,47,64,100,86} -{39,45,55,17} -{81,53,67,33,70} -{11,94} -{57,98} -{78,81} -{75,71,20,8,13} -{3,2,58,95} -{37,58,5,46,54} -{40,50,36,27,69} -{73,42,86} -{97,73,87,80,38} -{27,56,94,73} -{80,81,74} -{53,79,86} -{79,4,55,21,34,74} -{84,63,21,97,92,38} -{72,38,76,63,97,79} -\N -{64,91,100,98} -{34,10} -{97,73,7} -{49,31} -{87,39,65,96} -{54,88,60,55,18,4} -{20,72,96,26} -{40,51} -{37,46,89} -{88,53,3,52,39} -{10,34,77,95} -{20,66,84,12} -{51,19,61} -{67,35} -{73,56,89,43,35} -{94,54,27,63} -{63,53,21,79,76,49} -{79,23,28,63,49} -{47,94,75,11} -{67,95,56} -{80,86} -\N -{62,73} -{98,69,11,57,24,90} -{87,41,77,21,94} -{21,87} -{3,40,75} -{67,53,78,29,16} -{18,46,70,76,98} -{14,67,50,63,22} -{4,2,92,4,8} -\N -{41,76,79,95,96,61} -{35,30,18,57} -{34,91,89,27} -{22,25,9,34,85} -{4,53} -{23,6,65,86,56,93} -{54,81,8,59,36,47} -{90,10,4,25,31,46} -{91,82,82,80} -\N -{64,12,59,21,10} -{49,93,76,26} -{22,10,21,15,57} -{14,29,93,31} -{68,21} -{62,95,12} -{34,74,55,4} -{26,39,93,31} -{67,31,63} -{23,89,98,88} -{48,93,22,79,28} -{1,88} -{95,74,84,18,38} -\N -{82,29,22,45,15,81} -{15,48} -\N -{17,36,97,77} -{93,59,71,15,51,35} -{67,33,57,11} -{35,80,72,43} -{69,89,69,48} -{52,29,16,52,100,22} -{60,30,45,19,25} -{28,3,39,86,13} -{81,40,25,20,39,5} -{77,14,93,47,23,6} -{42,19} -{52,52,98} -{9,29} -{78,77,6,72} -{2,59,73} -{13,85,77,26,29} -{64,63,94} -{54,76,3} -{7,1,5,91,100} -{24,94,57,94,79,55} -{4,22,1,75} -{34,53,19,87} -{69,75} -{71,47,47,61,42,89} -{3,32} -{84,61,4,13,73} -{74,61} -{47,65,85} -{50,84,83,18} -{51,97,11,3} -{59,92,4} -{49,42,65,27,97,52} -{19,33,40,44,71,100} -{82,68,99,60,47,59} -{47,33,82} -{3,45} -{47,28,60} -{3,98,60,30,50} -\N -{11,40} -{33,67,72,43,74} -{9,49} -{42,47,48} -{53,88} -{17,87,28} -{20,4,72,62} -{65,25,22,76,64} -{9,62,57} -{59,93,52,93,60} -{85,85,1,55,50} -{69,22,57} -{8,50,81,32,4} -{80,47} -{60,88} -{16,54,80,66} -{99,87,66,65} -{60,19,58,18} -{14,77,66,48,59,41} -{75,96,82} -{42,72,93,79} -{14,23,78,82,40} -\N -{29,47,16,41} -{13,11,45,67,23,92} -\N -{8,3,52,41,56} -{57,41,63} -{5,50,59,87,50,58} -{58,99,9} -{60,99,15,63} -{59,14,9} -{68,81,34} -{83,18,3,94,39} -{27,52,100,66,48,82} -{10,23,50,96} -{72,14,12,68,62} -\N -{45,30,55,86,89,48} -{5,80,97} -{52,67,86,81} -{99,4,38,79} -{21,98,78,71,73} -{10,23,38,61} -{12,17,19,70} -{79,23} -{55,66,65,60,19} -{7,34,68,88} -{37,70,5} -{41,57,86,31,10,6} -{70,59,96,78} -{88,18,32,22,56,21} -{93,72,81,47,89,72} -{100,14,49} -{83,80} -{73,11,97,14} -{60,47,32,34,13,29} -{39,6,88,24,6} -{54,66,55,52,47} -{56,89,88,98,94,48} -{2,37} -{13,54} -{68,39,68} -{60,81,10,85} -{74,54,14} -{30,52} -{41,74,47} -{77,28,8} -{90,3,43,89,4} -{29,46,84,63,79,83} -{26,15,80,19} -{76,28,77,6,47,91} -{51,15} -{93,15,51} -{8,68,34,58,15} -{5,56,57,81} -{27,87,61,54,41} -{31,37} -{68,80,3,98,49,6} -{96,10,39} -{25,19,21,72,79} -{69,1} -{5,51,61,80} -{76,25} -{36,92} -{54,46,31,87,13,8} -{25,13,83,57} -{29,53,73} -{83,60,26,19} -{27,89,34,13,20,38} -{29,74,26,67,65} -{90,36} -\N -{32,15,43,50} -\N -{55,86,68,51} -{91,14,53,70,49,38} -{75,29,79} -{19,59,38,44,18,79} -{43,31,24,20,16} -{43,83,59,37} -{61,17,95,61} -{67,89,1} -{65,20,46,58,49} -{72,54,38,52,49} -{75,12} -{63,95} -{99,17,79,11,35} -{62,60} -\N -{69,83,89,73,20} -{30,60,39,73} -{78,99,29,45,61,21} -{38,61} -{51,15,47,11,4} -{34,75} -{57,26,42,42} -{8,90,4,68} -{63,70,99,3} -{74,70,33,50,59} -{27,18,73,83} -{36,90} -{82,77,2,83} -{90,99} -{15,25} -{65,30,39,82,89,34} -{12,24,64,54,49,83} -{54,59} -{63,49,81,36,75,52} -{6,59,90,55,87} -\N -{97,52,54,97,3} -{8,53,89,42,30} -{68,42,64} -{97,42,99,74} -{19,31,32,52,7} -{69,83} -{61,17,35,39} -{81,47,70,7,63} -{78,10,63,97,31,48} -{84,92} -{64,82,40,39,57,44} -{39,25,92,33,5} -{27,74,85} -{90,67,21,28,84} -{36,33,62} -{77,87,98,82,11,88} -\N -{11,41,17,91,56} -{1,1} -{84,100,8,22,20} -{57,39,85,5} -{55,47} -{13,2,36,59,45} -{95,66,53,32,29} -{21,92} -{35,32,9,58,77} -{19,71,99,82} -{19,37,87,43} -{100,18} -{67,86,29,40} -\N -{66,54,64,55} -{67,25,18,31} -{60,26,59,86,26,67} -{26,21} -{70,67,30} -{93,82} -{89,58,39,91,95} -{15,86,25,8,12} -{59,20,41,33,78,87} -{10,72,89} -\N -{52,17,99} -{77,29,7,7,1} -{49,96,57,24,66,67} -{10,26,83,84} -{82,7,25} -{66,77,57,25} -{92,77} -{24,48} -{44,26,37,75,11} -{73,80} -{51,47,93,21,25,78} -{76,49,15,98} -{12,85,63,59,6} -{25,51,47,58} -{16,10} -{17,30} -{67,5} -\N -{54,96,21} -{12,47} -{29,90,69,22,89,82} -{78,93,86,65,66} -{83,84,58,67,13} -{85,35,81,27,1,2} -{76,29} -{64,82,91} -{35,89,38,89,10} -{19,40,96} -{83,70,85} -{72,85,70,99} -{34,1,39,16} -{84,53,22,86,73} -{32,23,70,49} -{15,67,91,11} -{73,95} -{71,57,64} -{88,91,56} -{12,16} -\N -{62,82,26,84} -{70,51,52,63,96} -{34,93,49,57} -{16,5,47} -{18,59,12,82,83,51} -{61,93,87,9} -{46,9,45,38} -{15,85,28,73} -{31,99,26,3} -{66,91,48,73} -{98,80,9} -{31,55,42,69,13,58} -{43,8,70,29,83} -{39,57,53,70,74} -{89,13,60,38,89,3} -{37,28,15} -{67,77} -{30,100,89,36,53,75} -{36,19,48} -{7,8} -{12,76,26} -{14,56,52,47,39,67} -{87,83,51,2,97,25} -{51,1} -{59,69,37} -{95,93,21} -{100,92,37} -{37,23,66,95,7,63} -{52,56,77,86,46} -{31,62,17} -{57,48,79} -{26,96,40,5,43,54} -{40,92} -{75,83,1,73,71} -{75,61} -{6,38} -{35,23,76} -{52,3,38,25,100,99} -{45,15,44} -{96,9,11,35,16,58} -{9,80,76} -{22,43,34,43,46} -{34,68,21} -{95,70,83} -{60,7} -{34,22,68,2} -{78,30} -{46,70,90,96} -{5,24,69,61,32} -{41,17,79,27} -{59,88,64} -{12,48,41,68,15,98} -{43,84,59,62,36,14} -{84,8,71,88,4,23} -{45,67,67,17} -{14,96,72,66} -{91,23,4,11,28} -{18,5} -{65,51} -{31,87,33} -{17,97,76,81,69} -{56,71} -{95,23} -{33,58,66,47} -{46,99,69} -{43,87,40} -{49,1,26} -{18,36,89,87,25,100} -{76,37,19} -{57,91,9,100,23,59} -{80,60} -{55,23,32,49} -{15,73} -{87,50} -{43,62,50,54} -{65,3,89,49,77} -\N -{73,12,25,78} -{79,89,38,59} -\N -{44,62,25} -{96,13,57} -{35,14,3} -{90,71} -{34,8,59,81,63,90} -{15,90,89,32,69} -{90,61,54,10,29} -{22,3,85,41,66} -{17,4,99,91,45,57} -{89,32,43,39,61,9} -{45,40,6} -{47,100,75,8,85} -{88,43,89} -{45,41} -{54,48,87,66,100,5} -{58,65,39} -{17,82} -{95,14,31,51} -{30,3,46} -{8,66,22,52,51,24} -{61,62,38} -{4,50,83,32,76} -{96,36} -{87,27} -{82,100,44} -{30,91,44} -{29,48,8,38,43,96} -{56,65} -{34,36,99,11} -{11,1,25,65,12,89} -{17,100,62,53,24} -{86,81,63} -{17,63,30,82,87,91} -{12,63,76,78,85} -{52,19} -{21,91,53,86,49,83} -{67,65,78} -{8,77} -{89,1,56,100,72,96} -{20,51,41,21,30,20} -{41,73,37,92,9,5} -{95,34,21,12} -{28,14,2,62} -{14,74,33,32} -{37,82,67} -{65,99,56,11,21,83} -{99,51} -{56,42} -{59,30,74,40} -{18,27,63,44,86} -{48,25,41} -{5,26,63,88} -\N -{24,66,64,1,26} -{72,74,11,61,70} -{28,27,90,30} -{96,35,21} -{64,100,75,94,88,3} -{93,79,42} -\N -{37,51,4,41} -{31,68} -{93,42} -{76,96,47} -{8,6,16,57,51,72} -{67,72} -{50,36,40} -{69,28} -{17,92,40} -{72,74} -{76,87,93,22,95,30} -{14,88} -{39,56,74,36,25,87} -{55,68} -{32,9} -{35,2,17,86} -{92,73,82} -{40,13,95} -{15,28,95} -{65,40} -{47,56} -{63,72,78,20,22} -{71,49,4,80} -{68,16,50,44,29,38} -{81,96,23} -{44,73} -{4,68} -{30,54,41,66,89} -{92,33} -{10,92,49,46,59,42} -{14,91,18,96,27,37} -{40,32,12} -{14,97,15,96,44} -{75,96,52} -{50,20,9} -{39,84,83} -\N -{14,48,3} -{47,85,76,27} -{5,3,25} -{55,36,29,76,41,44} -{34,56} -{62,29,83,6,58} -{67,32,85} -{75,62,4,66,100} -{47,31,27,43,9,57} -{92,44,36} -{31,22} -{14,88} -{18,25} -{82,63} -{54,67,6,59} -{90,42,19,91,37,75} -{70,39,87,52,32} -{51,20,34} -{85,62} -\N -{95,6,55,93} -{44,67,15} -{93,58,20,12} -{42,6,22,29,36} -{46,81} -{57,95,56,52} -{3,79,69,45,8,74} -{75,44} -{4,17,78,96,66,41} -{27,100} -{85,76,22,17,45,58} -{9,12,70,29,96} -{5,68} -{54,79,5,19,17,24} -{99,13,9,52,86} -{94,6,99,57} -{71,62} -{63,50,9} -{42,42,80} -{25,96} -{93,20,10} -{83,73} -{14,76,36} -{57,31,29} -{17,25,18,18,54,95} -{34,27,86,37,92,83} -{57,57,28,32} -{98,53,60} -{8,59,41,88,49,46} -{95,42,30} -{12,51,98,74,76} -{6,49,26} -{21,35,27,32,83,93} -{16,56,89} -{85,34,73,74} -{52,95,22,4,71} -{96,42,63,88,80,91} -{78,34,41,99} -{11,68,27} -{50,14} -{78,52,66,15} -{100,82,1} -{35,2,93,71,45} -{4,56,8} -{83,19,5} -{82,39,63} -{50,64,83,87,76} -{47,59,93,88,22,67} -{16,6} -{86,98,88} -{32,4,52,34,30,71} -{68,25,97} -\N -{19,17,91,84} -{97,88,89,98,33} -{37,56,70} -{27,17} -{56,58,51} -{69,80,47,84} -{89,22,89,88,16,1} -{95,14} -{14,95,97} -{47,15} -\N -{19,20,65,74,83,38} -{57,56} -{78,67,68,89,1,95} -{61,84,93} -{10,56,96,31,56} -{3,51,90} -{15,85,42,25,15,41} -\N -{50,7,89,89,96} -{90,10,44} -{11,43,15,27,30} -{55,68,48,30,44} -{38,69,3,95,39,6} -{57,51,88,94,82,23} -{69,37,2,67,49} -{93,94,5,84,39,47} -{45,47} -{58,55,79,63,64} -{63,65,59} -{42,36,76,75,89,86} -{41,83,98} -{13,90,13,46,11,37} -{76,33,52,65} -{52,29} -{20,60,45,23,29} -{89,6,14,8} -{91,69,64,72,41} -{46,91,31,66,83,33} -{6,58,61,65} -\N -\N -{90,65,16,5} -{24,46,33,36,47,45} -{11,62,40,98,21,88} -{28,95,58,33,27} -{45,63,99,31,38,90} -{11,49,41} -{23,24,82,25,28} -{42,3,34} -{52,10,58,88,97,37} -{20,41,11} -{86,30} -{36,92,93,10} -{5,36,85,50,71} -{51,75,100,46} -{55,81,31,45,87,8} -{83,10,45,81,33} -{16,94,91,23,76,44} -{62,73,14,39} -{16,14,83,100,82,7} -{25,69,86,12,71} -{29,86,45} -{76,62,100,47,57,52} -{41,21} -{33,56,58} -{23,96,44,16,91,86} -{65,15} -{3,92,56,4,21} -{32,39,95} -{95,87} -{65,96} -{16,96,93,100,35,78} -{64,33,55} -{96,75,41,40,62} -{50,50,86,11} -{93,34,83} -{19,30,62,67,93,19} -{53,67} -{55,46,99} -{70,32,38,4,84,91} -{50,36,40} -{21,93} -{29,6,10} -{4,73,45} -{72,33} -{36,73,18,55,27,100} -{65,73,98,90} -{20,1} -{59,36,60,87} -{20,79,63,93,34,31} -{60,18,92,6} -{48,34} -{63,70,78,1,2} -{15,32} -{5,15,84,73} -{32,35,90,11,40,23} -{91,41,7,52} -{84,90,88,30} -{12,10} -{84,86,36,79} -{76,45,84,66} -{41,25,61,96,97} -{18,100} -{63,39,17,34,32} -{22,45,74} -{83,24,45,48,69,84} -{43,41,12,44,75,91} -{69,75,95} -{100,28,14,66,1,14} -{94,91,60,36} -{88,28,54,63} -{68,78} -{29,68,6,100} -{12,84,35,44,59,55} -{30,59} -{64,18,40,57} -{97,97} -{85,64,73,82,49,88} -{99,31,24,6,90} -{23,89,38,20,40,95} -{84,64} -{21,3,91,7,7,87} -{91,74,32,76,43} -{13,22,96,8,75} -{59,71} -\N -{34,94,45} -{14,5} -{95,10,37,74} -{69,82} -{6,58,45,49,81} -{72,72} -{17,58,10} -{62,77,9,6,44,62} -{37,53,49,41} -{24,11,11} -{10,57} -{26,72} -{18,15,83,60,54,80} -{88,49,73,92,67} -{26,88,64,2,59} -{49,50,3,90,44,49} -{58,54,43} -\N -{86,78,40} -{42,17,65} -{1,86,17,6} -{79,27,37,60,8} -{46,62,46,22} -{9,75,17,68,54,35} -{99,86,64,10,20} -{3,21,35,6,24,64} -{25,62,9,50} -{63,2,79,42,81} -{44,41,2} -{99,93,98,78} -{2,92,9,96} -{79,82,25,64} -{47,84,52} -{97,77} -\N -{47,94,38} -{22,33,76} -{35,52,11} -{17,48} -{1,100,27} -{87,93,19} -{72,3,32,78,81} -{47,28,4,23,79} -{27,88,7,85} -{49,40,47} -\N -{91,89} -{80,2} -{86,78,42,6,81} -{7,50,25,4,8,22} -{23,3,64,59,53} -{1,42,63} -{95,81,86,31} -\N -{81,83,52,47,25,43} -{17,57,100,49,59,63} -{44,91,95,72,29,100} -{80,78,55,41} -{14,52,20,64,9,87} -{48,14,82} -{31,5} -{64,50,66,38,97} -{61,2,90,2,64} -{64,69,26} -\N -{64,62,68,89,12} -{12,10,88,71} -{41,66} -\N -{67,77,25,6} -{14,75,15,66,19} -\N -{88,52} -{78,56,61} -{93,88,47,38,52} -{72,100,54,34,18} -{77,99,89,53,25} -{38,51} -{3,25} -{83,39,85} -{60,15,77,59,69} -{38,64,91,97} -{65,35,30,8} -{46,6,48} -{63,91,29,91,85} -{43,100,56,60,74,53} -{95,30} -{86,63,28,62,37,79} -{2,48,29} -{1,44,20,47,56} -{43,34,86,86,64,14} -{11,82,99,71,63,41} -{77,45,74,17,56} -{18,25} -{51,82} -{27,35} -{1,20,84} -\N -{89,37,16,90} -{58,83,34,88,50,21} -{61,25,1} -{41,6} -{9,100,32,54,38,66} -{40,53} -{29,76,16,13,55,31} -{71,67,54,83,3,82} -{19,62,18,94,73,38} -{17,83,8,45,52} -{80,25,50,59,53} -{4,2} -{52,48,6,72} -{50,32,70} -{36,97} -{17,82,36,97,20} -{22,87} -{46,29,96,98,14,90} -{14,92,5} -{69,9,68} -{20,86,29,61,54} -{62,67,87} -{86,18,31,80,82,45} -{65,89,67,34,41} -{44,8,48,38,91} -{47,32} -{85,25,56,39} -{15,54} -{84,57,44,46} -{65,61,29,86,77,53} -\N -{26,58} -{76,1,57,93} -{57,91} -{13,15,66,11} -{84,12} -{43,32} -{83,24,31} -{82,9,65,84,27,94} -{62,93,55,7,39,46} -{90,100,33,22,61,46} -{9,51} -{87,93,82,94} -{49,45,95,95,66,39} -{100,56} -{11,5,78,42,45,37} -{3,57,80,46,13,34} -{1,74,53,31,33} -{11,84,8} -{27,99,21,31,96,58} -{99,81,90,17} -\N -{66,49,47,55} -{88,30} -{76,62,17,88,83} -{40,7,42,61} -{17,57,9,64,54,1} -{9,54,84} -{50,61} -{72,15,25,30,6} -{64,95,69,89,11} -{64,18,86,25} -{81,59,70,6,92} -{78,76} -{33,40,29} -{15,63,1,12,14,57} -{33,81,8,65,26} -{58,15,56,37,67} -{2,50,35,92,11,27} -{17,13} -{91,100,15,27,39,24} -{58,48,46} -{5,95,28} -{7,21,99} -{5,15,6,10} -{82,99} -{66,22,86,83,76} -{99,68,39} -{43,90,22} -{31,94} -{21,64,56,26,95,40} -{7,81,3,53,83} -{29,42,90,60} -{53,49} -\N -{26,31,14,73,88,51} -{69,2,100,9,34,16} -{78,35,97} -{68,16} -{34,45,42,73} -{7,19,55,70,69,11} -{11,62,61} -{32,17,51,33,87,6} -\N -{54,97,36,13,45,12} -{46,2,26} -{14,6,17} -{99,20,31,61,6,4} -{60,72,53,31,34,25} -{88,46,68,78} -{56,94,49} -\N -{33,65} -{70,51,84} -{55,91,27,33} -{22,19} -{34,78,11,94,3} -{16,67,91} -\N -\N -{64,5} -{76,18,83,5} -{57,13,30,56} -{60,92,25,31,43} -{38,17,54,5,2} -{56,58,39} -{42,43,5,69,56,89} -\N -{50,23,97,85,70,39} -{97,56,33,90,64,2} -{9,54,51,26,24,99} -{18,7,59} -{44,5,40,69,18} -{77,96} -{44,58,47,17,26,45} -{90,71} -{88,32,11,96,17,13} -{42,3} -{97,28,56,10} -{38,36} -{50,52,47,31} -{64,5,99,77,83} -{11,56,1} -{91,92} -{7,53,35,52} -{93,65,47,97,44,82} -\N -{64,66} -\N -{62,4,57,23,34,91} -{52,55,75,99,27} -{29,54,44,87,61,96} -{21,3,66,35,25,80} -{96,68} -{3,41,66,81,78} -{49,98,79,65} -{71,38} -{88,79,70,37,3,82} -{49,74} -{19,29} -{57,68,9,8,99} -{81,88,14} -{99,29,24,99} -{55,96,29,89,49} -\N -{56,2,84,79,74} -{30,52,64,74,62,5} -{88,32,19,25,9} -{40,11,49} -{98,52,27} -{11,86,29,86,6} -{91,53,63,53,44,28} -{88,10,30,48} -{75,64,75} -{14,92} -{98,62,35,67,66,35} -{40,65,11,80,73} -{1,1,63} -{85,32,53} -{91,27,68,50,66,63} -{66,54,38} -\N -{45,43,14,94} -{62,84} -{54,24,83,33,46} -{93,72,2} -{43,4,14} -{18,11,5,99,79,94} -{26,59,9,2} -{58,69,70,45,14,54} -{84,5,42,97} -{7,82,41} -{69,53,8,55,20} -{4,13,6,45,83} -{41,92,41,98,51,85} -{72,85,74} -{19,50,79} -{79,47,47} -{25,25} -{17,56,46,30,73,78} -\N -{92,42,83,34,92,29} -{8,52,76,80,9,55} -{80,100,2,52,24,4} -{55,15,92,27,86,50} -{83,79,41,88,86,53} -\N -{44,16,90,54} -{99,20,64} -{44,30,26,26} -{35,35,24,74,72} -{97,24,94,55} -{78,42,32,76,100,98} -{31,86,12,87,72,86} -{87,35,33,88,33} -{31,83,23} -{46,51,5,6,71,31} -{39,97,91,53,39} -{19,18,25} -{16,4} -{65,77,13} -{61,30,13,26,75} -{67,9} -\N -{31,3} -{15,19} -{97,39,71,30} -{12,96} -{36,96,82,62,5,74} -{81,22,46,11,19} -{97,55} -{58,67} -{10,68,79,74,23} -{29,71} -{50,59,8,1} -{12,51,32,7} -{62,16} -{48,82} -{84,21,24,13} -{46,86} -{100,96,32,54,13} -{72,41,3,67} -{61,9,7,75} -{39,44,50,30,38,6} -{63,63,6} -{69,35,6} -\N -{7,91,82,48,55} -{57,22,31,57} -{55,72,91} -\N -{76,98,43,71,10} -{100,34} -{78,53,14,73,23} -{42,90,28,44,44} -{90,34,22,81} -{60,32,56} -{98,53,58,58,61} -{61,70,59,78} -{2,96,27} -{83,99,25,47,13} -{17,54,11,47,70} -{70,43,11,89} -{93,70,82} -{72,57} -{35,95,49,36,19} -{82,25,16,49,43,93} -{2,51,96,48,88} -{20,81} -{74,4} -{66,83} -{90,75,98} -{25,87,59,92,55,96} -\N -{20,80,92,93} -{59,63,39,3,7,38} -{64,10,85,22} -{63,32,18,38,83} -{49,38,83,54,1} -{27,97} -{18,34,84,58,7,86} -{93,4,67} -{43,49,32} -\N -{29,14,5,50,30} -{59,15} -\N -{76,31,31,47,17,35} -{95,41,71,27} -{47,43} -{75,80,56,78} -{56,75,43} -{99,10,100,76,44,1} -{5,31,72,3,25} -{21,90,59} -{59,45,75,93,78,88} -{76,55,4} -{20,87,44,94,56,78} -{38,87,71,13,23} -{33,6,79,91,92,27} -{13,15,31,15,11} -{57,18,57,71,11} -{67,60,64} -{66,15} -{57,45,74} -{93,91,97,30,12,94} -{37,83,62,18,28} -{94,88} -{12,11,85,10} -{42,96,89} -{15,65,5,65} -{52,58,36,27,10} -{72,88,76,50,96} -{40,70,55,93} -{80,33,24} -{53,35,50} -{11,37,55} -{25,80,32,91,68} -{11,2,52,39,37} -{17,51,45,44,85,84} -{81,21,77,15} -{67,93,27,70,72,94} -{86,99,95,98,83,28} -{9,65} -{1,26,5,23,5,17} -{57,82,42,60} -{46,67,65,98,69,79} -{41,50,94} -{77,81} -{87,82,18,57} -{88,27} -\N -{32,58,81,88,94,90} -{23,37,65,38,29} -{61,11,65,77,25} -{50,53} -{38,2,11,9,27,94} -{64,9} -{1,45,97} -{61,41,67,46} -{13,41,90,15,80,82} -{83,6,9,22,25,37} -{95,74,22,64} -{16,17,4,80,66,33} -{25,42,43,84,96,85} -{25,93,50,87,6} -{35,67,90} -{82,37,59} -{4,44,83,2,81} -{78,46} -{64,79} -{18,41,3} -{56,20,51,83} -{26,77,52,70,93,13} -{54,53,12,47,57,63} -{94,48} -{39,12,41,5,3} -{28,33,93} -{20,29,9} -{75,38,10} -{96,54,96} -{47,87} -{19,35,11,3,80,72} -{75,56,84,24,55,48} -{58,5,13,6} -{10,53,32,6} -{23,8,59} -{71,2,35} -{41,16,99} -{77,6,16} -{30,27,56,85,11} -{47,21,93,82} -{50,68,85,34,19,57} -{14,76,58} -{78,81} -{68,99} -{19,79,67} -{91,73,82,88,44,36} -{49,18,75,32} -{54,18,99,74,9} -{51,58,60,30} -{99,86,83,22,88} -{24,42,76,30} -{86,16,54,69} -{37,39,72,45} -{92,62,3,36} -{31,80} -{43,22,11,15} -{38,88,95,25,49} -{92,21,10,28,47,55} -{99,18} -{26,64,72} -{29,12,17} -{54,69,49,84} -{57,42,4,61,10} -{60,85,74} -{24,29} -{91,71} -{96,49} -{47,51} -{88,67,59,18,86} -{32,18,64,54,41,27} -{78,100} -{77,30,85,93,2,20} -{80,90,68} -{49,37,5,42} -{88,12,94,51} -{85,65,2,41} -{60,38} -{87,37,20} -{27,81,94,37,54,84} -\N -\N -{38,74,78,78,89} -{3,100} -{42,80,68} -{34,17,96,91} -{7,29,83,71,87,26} -{28,81,76,8,43,48} -{74,11} -{28,85,84,78,59,69} -{30,22} -{3,83,75,60,78,11} -{20,62,18} -{74,69} -{91,44,50,62} -{57,18,9} -{14,48,21,33} -{91,1,53,58,92,51} -{64,41,90,52} -{81,95,38,78,7,44} -{65,25,15,90,40,51} -{66,41,31} -{5,92} -{17,98,7,57} -{97,36,99,77,50,88} -{96,56} -{40,62,88,8,53,62} -{18,91,63,93,94} -{88,79,43} -{31,87,98,85} -{12,88,58,53,77,38} -{83,10,37,69,1,7} -{13,47,66} -{85,33,39,48,6,39} -{74,87} -\N -{26,50,26} -{48,78,10,39,17} -{27,43} -{58,17,18,80} -{86,43,58,77,67} -{53,12} -{9,79,9} -{85,79,89,88} -{35,77,22,52} -{93,64} -{47,52,90,17} -{75,15,25,68,28} -{35,6,68,37,18,53} -{80,14,2,89,4} -{52,49,5,66,59,44} -{5,26,96,1,84} -{71,8,61,19,72} -{17,94,84,72,55,83} -{72,10,16,40,17,75} -{6,70,15} -{22,99,7,19} -{55,19,4} -{6,47,69,42} -{17,9,63,44,15} -{23,20,72} -{10,80,20,87} -{99,3,23} -{11,76,8,77,58,38} -{45,14} -{22,89,73,63,54,9} -{16,19} -{1,26,29} -{92,20,65,33,16,40} -{27,64} -{22,19,95} -{36,16,9,30,31,14} -{40,50,68,52,77,58} -{35,15,11} -{67,2} -\N -{63,48,76,25} -{14,65,42,60} -{61,58,31,51,70,4} -{35,41,72,29,46,62} -{98,48} -{90,23} -{1,79,80} -{10,5,54,59,16} -{15,1,9,75} -{34,100,90} -{73,76,25,77} -{98,82,77,67} -{79,5,20} -{9,69,9,52,2} -{23,22,77,80,79} -{32,51} -{23,52,5,33} -{95,20,96,78,48} -{100,37,6,15} -{98,1,53,20,97} -{5,28,26,78,33} -{19,75} -{49,42,30,72} -{50,98,56,26,87} -{76,59} -{51,16,18,48,46,97} -{80,60,51,43,58,28} -{23,12,70} -{40,16,14,18,46,21} -{72,79,47,57,23} -{7,17} -{49,95,6} -{14,24,29,13,90} -{82,28,34,55,15,87} -{31,24,3,50,45} -{86,95} -{97,22,17} -{27,14,27} -{61,63,31,74} -{55,81,87,67,90} -{81,9,79} -{100,29,43} -{41,88,37,29} -{62,57,16,91,60,65} -{94,90,34,94,27,48} -{15,36,80,30,23,90} -{47,91,6,42,93} -{53,74,5} -{84,14,56} -{30,56} -{10,12,92} -{33,7,75} -{96,39,50,77} -{89,85} -{20,39,63,22,44,18} -\N -{90,23,79,91,85,8} -\N -{73,70,52} -{75,100} -{27,4,29,96,25} -{56,31,80,59} -{1,91} -{16,67} -\N -{17,88,59,41} -{13,49,29,76,71,9} -{41,38,16,29,66,40} -{68,67} -{39,74,47,71,63,80} -{4,74,33,92} -{17,60,82,7,52} -{62,88,39,19,22} -{77,21,1,95,42,2} -{98,62} -{55,17,81,31,11,88} -{73,52,18,94} -{16,64,90,33} -{87,41,81,95,85} -{20,55,96,75} -{71,72,11,11,83} -{75,94,89,47,41,7} -{56,48} -{76,29,74,31,67} -{47,70,68,36,70} -{5,69,10,94,54,32} -{29,96,71} -{64,28,86,58} -{82,57} -{42,2} -{64,48,59,8,45} -{61,69,43,40,1} -{69,84} -{68,51} -{32,20} -{21,7,5,60,35} -{100,40,18,98,37} -{50,96} -{87,10,12,27} -{47,3,46,43} -{60,87,10,31} -{92,87,50,37,72,73} -{99,61,77,87,29} -{23,95,31} -{96,100,43} -{17,64,84} -{13,19,57} -{65,86,4,75,46,69} -{49,60,99,37,50,11} -{77,82,88,12} -{12,95,66,98,63} -{83,78,68} -{76,14,87,25,29,14} -{20,9,99,73,67} -{42,51} -{36,22,33,6,63} -{53,46,22} -{40,89} -{37,7,89,17} -{32,89,16} -{65,87,4} -{16,16,57,35} -{34,90} -{80,54,1} -{11,93,34} -{5,19,31,50,99,33} -{98,1,33,54,7} -{45,39,23,78} -{37,47,98,83,10,5} -{55,88} -{42,76,18,99} -{86,31,25,5,45} -{67,87,47,1} -{23,15} -{78,88,66,96} -{58,55,41,67,86,41} -{21,53} -{90,14,28,38,95,71} -{20,5,13,52,1,88} -{29,98,50,75} -{91,3,24,75,82} -{62,33} -{56,69,31,95,66} -{46,85,40} -{17,22,67,57,39,16} -{58,25,92} -{31,53,82,64,69,40} -{40,12,30,1,39} -{78,10,42,40,25} -{58,27,1,12} -{28,11,80} -{36,89,69} -{50,95} -{61,63,59,62} -{51,77} -{90,24,88,84} -{61,27,57} -{51,81,33,75,48} -{47,30,33,23,44} -\N -{79,51} -{62,44,5} -{98,83,80} -{31,33,89,69,19,40} -{22,38,61} -\N -{90,70,10} -{37,90,49,65,95,52} -{95,42,4,47} -{92,100,43,31,27,1} -{39,17,88,20,2,80} -{82,64,36,84} -{31,18,21,18,52,34} -{3,35,36,33} -{26,39,69} -{67,63,66} -{54,85} -{65,71} -{26,14,84} -{63,82,73,30} -{66,79,21} -{71,13} -{57,25,40,14,22} -{63,9,91,31} -{70,63,36,32,93} -\N -{11,85,47,31,54} -{34,47} -{42,78,92,85} -{75,64,12,83} -{33,98,52,91} -{22,25,91,79,33} -{33,51,20,77,23,65} -{83,66,46,24} -{54,65,31} -{43,41} -{52,47,66} -\N -{59,85,85,63,83,53} -{16,76} -{44,97,48,52} -{26,36,72} -{26,55,98,7} -{70,88,7,87,62,37} -{11,42} -{98,38,36,72} -{51,90,82,33,92} -{59,80,79} -{76,77,18,71} -{34,56,62} -{85,12,37,66} -{34,64,74} -{77,63,28,76,11} -{2,63,87,50} -{60,98,60,19,15,57} -{93,66,33,71,36,3} -{41,94} -{62,72,87,19} -{57,83,36} -{63,64,21,13,70,32} -{71,36,9,55,34} -{92,52,90,45,88} -{59,54} -{4,51} -{55,25,35,90,93,2} -\N -{75,15} -{25,86,43,18,77} -\N -{31,40} -{55,49} -{67,1,84,20,9} -{15,1,48,18,100} -{62,46} -{4,39,86,55} -{49,17} -{65,20,71,49,55,49} -{40,57,63,14,3} -{48,68} -{67,97,58,55,5,34} -{3,73} -{79,97} -{82,63,87,66,32} -{19,49,96,50,55} -{32,19,41} -{17,53} -{64,81,70} -{66,75,18,92,54,93} -{7,94,38,86} -{16,62,45,19,10,11} -{18,47} -{58,96,69} -{65,25,58,98} -{29,51,37,40,44} -{91,78} -{37,84,85,65} -{70,61,31,22,32,22} -{67,12,99,39,78} -{41,79,46,54,84,22} -{38,26,43,4,45,75} -{29,68,35} -{69,59,69,33} -{4,46,52,49} -{1,25,44,12,71,29} -{38,75,99} -{83,58,86,6} -{93,35,35,34} -{85,26} -{15,46,95,60} -{62,63,65,49,10} -{44,67,19,80,83} -{63,41,30,43,85} -{13,46} -\N -{13,95,1,34,72,37} -{4,32,22,47,6} -{67,65,77,3} -{40,70,22,44} -{74,9} -{44,28,5,32,67,51} -{55,14} -{41,3,72,68} -{64,82,72} -\N -{11,88} -{91,90,92} -{68,66,95,80,58,54} -{30,49,11} -{54,86,59,69,67} -{56,83,36} -{15,67,9,47} -{92,30,78,2,87} -{12,54,2,1,59,36} -{84,25,67,38,19,53} -{28,45} -{54,84,9,75,59,26} -{47,35,54,93} -{36,96,59,75} -{78,78,52,93} -{87,96,67} -{5,61,15,13,27} -{53,58,6,78,86} -{43,70} -{72,38,15,61,58} -{75,27,30,12,35,71} -{18,72,35,62,81} -{45,10} -{36,91,73,25} -{81,85,22,34,29} -\N -{15,97,82,44,19,83} -{51,23,18,6,74} -{53,75} -{62,9,73,95,37} -{58,42,33,41,71} -{5,97} -{30,2,89,81,93,61} -{32,3,18,84,24} -{6,97,20,89,23} -{27,74} -{22,86,81} -{77,19,42} -{92,9} -{58,90,59,91,30,54} -{29,51,92,34} -{85,68,59} -{36,83,75} -{37,50,86,9} -{79,70} -{33,46,93} -{97,17,6,88,10} -{18,42,88,4} -{41,95,71,27,95} -{8,2,81,56} -{54,94,54,28,70} -{34,87,20,10,5} -{36,76,87,5,100} -{97,91,25,89,89,95} -{76,26,73} -{82,23,7,42,58,72} -{53,16,99} -{10,34,57,47,2,96} -{81,93,26,19} -{8,1} -{79,55,37,61,62,3} -{34,16,69,58} -\N -{41,7,99,87} -{70,21,86} -{59,2,49,45,91,97} -{37,2,74,2,61,68} -{97,39,15,4,13,1} -{67,71,8} -{51,2,84,38} -{55,8} -\N -{75,27} -{37,36,49,70,82,41} -{70,20,85,89,99,90} -{69,61,100,49,75,35} -{11,4,67,4,91,17} -{77,56,65,78,25,8} -{16,58,6} -\N -{88,38,19,88,27,27} -{12,46} -{36,67} -{62,33,96,94,80,96} -{56,94,12,1,65,54} -{58,73} -{19,80,27,72} -{47,55} -{14,91} -{94,75,92,32,19} -{99,12,91,4,85} -{56,55} -{86,83,77,66,66,87} -{46,68,13,45} -{49,75,62,35,39} -{20,25,33} -\N -{91,47,56,68,14} -{88,43,24,42,4} -{50,24,94,18} -\N -{71,54,91,66,97,22} -{81,16,19,67,6} -{78,46,81} -{63,93,71,75,87} -{90,38,10,85,12} -{11,24,93,42,25,77} -{30,14,32,67,70} -\N -{86,91,77} -{73,74,64,66} -\N -{7,18} -{85,94} -{37,15,55,100,59} -{55,18,44,79,57} -\N -{52,40,97,75} -{60,53} -{38,9} -{27,67,77} -\N -{43,83,82,24,35,64} -{22,75,29} -{9,19} -{67,1} -{15,35,11} -{65,45,95} -{65,9} -{63,84,99,89,6,77} -{20,44,31} -{82,50,88} -{29,12,46,21,98,7} -{98,71,3,73,6,86} -{61,44,74,2,45,33} -{16,56} -{31,87} -{72,30,37,94} -{65,30,82,17,12} -{86,19} -{55,76,96,61} -\N -{44,92,83} -{41,22,79,95,20} -{36,33,86,9,61} -{22,88,8,57,73,30} -{63,97} -{36,53} -{56,52,48} -\N -{35,8,3,93} -\N -{53,52} -{7,48,78,46,70,14} -{33,92,55,17} -{39,57} -{71,43,72,7} -{92,85,55,38,35} -{68,30,67,8,18,92} -{9,85,82,24} -{46,46,19,14} -{96,97,31,59} -{35,99} -{54,7,20,28,29} -{20,21,56,82,19,40} -{2,39} -{33,49,63,49,93} -{35,40,26} -{30,35} -{94,70,2,23,91,74} -{34,37,72,19,15} -{92,21} -{72,63,64,35,40} -{59,11,9} -{24,3} -{93,75} -{22,14} -{63,99} -{39,47,10,14,3,45} -{51,74,5,85,70} -{6,33,15,4,89,20} -{97,82,29,15,66} -{47,47} -{88,79,57,10,68} -{18,22,13,100,100,67} -{75,50,9} -{3,12,34} -{39,51,20} -{56,5,63,18} -{83,44,86,46,37} -\N -\N -{60,16,54,75,62} -{91,95} -{39,55,11} -{37,7} -{29,49} -{38,4,52,85,67,38} -{36,56,2} -{52,14,92,39,77,16} -{42,25,49,55} -{70,10,33} -{53,46} -{83,15,28,59} -{35,69,82,4,58,46} -{73,55,64,9} -\N -\N -{60,25,8,8,39} -{50,71,61,64,64} -\N -{65,67,67,34} -{77,59,18,64,16} -{43,72,32,44,59} -{55,57} -{12,47} -{30,75,89,81} -{23,92,16,31} -{64,45,21,74,19} -{4,47,49,47,96} -{37,14,20,18,87} -{61,45,38,39,1,87} -{4,98,99,52,27} -\N -{23,6,50} -{22,61,46,79} -{90,54,60,9,49,42} -{73,27,51,72} -{73,11,23,60} -{7,31,52,34} -{27,68,39} -{39,8,21,48,64} -{86,64,92,60} -{55,36,40,46,23,46} -{32,79,86,44} -{72,29} -{33,87,57} -{57,87,61,22} -{67,84} -{32,99,26,92} -{22,27,34,82,8} -{99,25,99} -\N -{29,75} -{39,63,25,45,7} -{39,67,18,13,18} -{23,83} -{77,69,22} -{60,13,46} -{2,10,42} -{37,20,27} -{30,21} -{85,15,52} -{6,89,38} -{68,22,26,37,96} -{6,85} -{93,51,63,46,26,64} -{79,77,15,26} -{90,6,39} -\N -{50,58,85,27} -{69,8,72,47} -{7,59} -{55,16,54,95} -{96,5,50} -\N -{77,92,13} -{46,30} -{43,65} -{17,65,32} -{10,6,46,1,47,75} -{48,82,71} -{63,12} -{68,14,10,97,34} -{15,45,58,100,7,74} -{9,23,88,1,95} -{61,60,15,12,58} -{84,51,46,41,71,26} -{58,62,39} -{86,67,31} -{32,31,89,2,30} -\N -{90,74} -{65,79,76} -{22,30,77,47,40,23} -{67,99,56,73} -{11,24,30,93,89} -{70,17,65,78} -{100,6,67,29} -{39,4,22,59} -{84,29,70,9} -{74,43,72,27,55,27} -{12,39} -{1,83,100} -{48,23,9} -{21,88,21,35,16} -{92,34,44} -{91,96,13} -{93,57,40,79,81} -{86,3,94,82,43} -{78,70,19,97,49} -{47,22,98,36} -{20,59,65,54,81,27} -{58,13,73,19,54,96} -{26,20} -{70,75,14,70,82} -{77,67,53,33,83} -{2,43,36} -{84,17,28} -{68,25,95,62,92} -{47,90,15,69,85,23} -{92,92,24,37} -{96,14,14,38,38} -{80,4} -{66,86,28,15} -{18,90,74} -{93,76} -{64,96,14} -{76,41,86,67,64} -{58,95,2,86} -{12,60,96,70} -{22,37,58} -{1,67} -{75,23,24,7} -{3,57,66} -{57,30,68,100} -{68,57,33} -{26,32,65,51,75} -{40,14,60,97,83} -{88,96,42} -{66,21,21,78,34} -{15,56} -{86,60,66,66,16} -{94,6,58} -{99,63,70,57,10} -{82,59,62,38,82,51} -{48,61,9,46,28,57} -{29,23,61} -{12,30,42,20} -{99,65,24,7,97} -{20,5} -{6,49,85,56,97,4} -{62,93,88,86,75,29} -{46,2,94} -{57,71,45} -{38,60,21,78} -{95,53,92} -{61,1,88} -{67,80,49} -{59,82,1,48} -{19,94} -{25,64,16} -{96,73,50,85} -{28,17,46} -{81,51,50,18} -{57,99,66,93} -\N -{23,62,57,94,40} -{21,6,83} -{4,11} -{83,16,50} -{46,41,23,1} -{4,15,8} -{86,51,29,80} -{48,34,55,81,89} -{5,2,43,67,66} -{42,59,37,91,1} -{14,98,27,80,33} -{18,58} -{49,93,60,91,94,88} -{32,62,64,63,48} -{51,1,90} -{56,8,68,49} -{16,34,79,18,76} -{66,88,41} -{31,66,93,44,96,40} -{100,99,30} -{37,49,95,91,18,43} -{95,2,94} -{84,15,70,31,30,84} -{31,41,45} -{9,73,2,7,34} -{17,35,43,1,25,72} -{8,70,8} -{1,93,32,16,71,61} -{98,51,27,56,46,65} -{1,11,57,72,33,7} -{48,96,64,55,75} -{83,82} -{7,74,70,29,59,60} -{29,44,5,77,52} -{84,58} -{87,63,62,52,69} -{29,58,32,11,13,17} -{35,99,67,67,93} -{54,31} -{53,24} -{58,59,32,22} -{8,76,23,63,94,54} -{3,88,75,17,64,91} -{29,30} -{3,81,39,9,77,82} -{77,85,59,56,8} -{47,12,63,13,40} -{66,81} -{67,33} -{39,46,28,79,95,67} -{49,13,98,63,10,58} -{14,42} -{80,70,60,92} -{63,54} -{30,70} -{60,89,14,62} -{56,40,94,55} -{70,31,46,20,95} -{18,65,89,7,75} -{60,33,80,43,37,4} -{85,19,98,79,36,84} -{69,1,48} -\N -{30,87,9,22,99,60} -\N -{23,96,9,85} -{22,94,39,58} -{30,38,4,97} -{16,70,62,5} -{35,52} -{32,10,72} -{35,34,40,31,66,80} -{7,77,14,48,97} -{67,64,37,22,69} -{51,53} -{67,71,90} -{87,71,45} -{44,84} -{19,58,11,34,45,85} -{68,19,55} -{27,16} -{7,14,92,22,33,46} -{47,2,49,53,63,32} -{15,39} -{13,47,84} -{29,74,97} -{51,74} -{70,26,46,33,51} -{31,86,14,23,61} -{20,85} -{21,10,57} -{90,94,59,72,97} -{97,30,74,84} -{15,89,69} -{11,40,2} -{68,19,47,28} -{47,65} -{2,7,52,53,44} -{40,74,34,36,78,71} -{22,60} -\N -{37,75,47} -{53,78,2} -{4,32,42} -{35,76,69,88} -{95,13,3,38,3} -{74,74,62,90} -{8,72,42,2} -{11,43,5,43,70,16} -{69,19} -{61,37,26,49} -{16,100,69,32,35} -{58,77,26,76} -{74,87,37,47,84} -{8,82,29,93,15} -{74,88,93,85,97,95} -\N -{29,23,99,98,36,93} -{8,36,87,64} -{71,90,43} -{7,28,78,46,52} -{62,25} -{33,90,7} -{60,72,39,18,86} -{98,59,73,24} -{17,69,2} -{49,16,63,56} -{13,37,62,1,95} -{98,89,69,92} -{50,26,34} -{90,16} -\N -{40,54,3,79,51,19} -{29,24} -{6,12,82,24} -{92,52} -{89,2} -{64,25,68,55,81,2} -{64,77} -{71,46,58,50,56,34} -{94,17,35,30,60,33} -{37,30,2,40} -{98,15,16,92,2,50} -{44,19,82,57} -{37,34,6} -{59,43,1,53,79} -{7,37,14,14,92} -{80,78,49,81,23,17} -\N -{91,51,12,35,79} -{9,14,2,84} -{62,3,77} -{25,5,40,12,40,79} -{65,88,82,94,89,90} -{20,35} -{80,71,83} -{6,9,83} -{94,58} -{2,76,55,61,42,53} -{60,53,45,82,3} -{1,37,75,96} -{82,61,81,10} -{36,46,1,31,90,45} -{22,55,11,25,21} -{69,13,29,20} -{95,54} -{16,79,82,67} -{4,58,84,84} -{52,7} -{25,14,94} -{69,8,67,54} -{30,71,36} -{81,78,23,38,76,58} -{86,59,61} -{11,42,63,74,99} -{66,4,55,34,16} -{39,57} -{10,81,9,8,21,10} -{75,55,64,97,7,45} -{8,46,86} -{39,100,52} -{30,51,7,13,54} -{72,85} -{10,52} -\N -{61,7} -{93,1} -\N -{74,31,3} -{90,96,26,84} -{88,58,74} -{28,45,74,24,74} -{95,88} -{42,70,43,64,22} -{46,83,48,36} -{81,99,100,43,11} -{47,24} -{46,67,63} -{26,15,36,89} -{90,11,78,70,81,87} -{65,90} -{89,99,21,81,47,38} -{37,42} -\N -{94,51} -{12,57,95,63,29} -\N -{68,99} -{27,8} -{16,52,11} -{72,5,85,44,57,51} -{11,6,91,7} -{87,80} -{94,61,1,38,77,89} -{93,60,6,98,46} -{52,47,44} -{93,66,61,22} -{7,61} -{15,83,93,91,12,40} -{66,3,5,72,72,36} -{67,72,68} -{42,42} -{38,17} -{75,60,47,39} -{58,28,51} -{61,8,61,81,65} -{46,52,97,84,27,47} -{97,53,47} -{64,93,83,72,27} -{34,79,34,36} -{25,5,92,37} -{12,20,55,94} -{17,43} -{39,37,16,70} -{79,62,15,16,64,28} -{80,87,96,41} -{51,55,1,94,72} -{75,22,56} -{2,55,7,20,39} -{8,91} -{73,8,42,73,31} -{90,90,23} -{82,68} -{63,64,68,12,59,19} -{100,80,23,24,17} -{23,46} -{25,13,31} -{43,95,54,85} -{40,62,21,21,82} -{70,20,16} -{90,11,23,18} -{16,9} -{51,57,30,27,21} -{50,55,75,77,53,33} -{84,92} -{14,66,32} -{44,100,16,30,82} -{41,48,58,60,7,44} -{81,76,13} -{18,26,82} -{84,35,15,98} -{52,84} -{13,80,36,35,28} -{91,16,71,55} -{87,89,6,20,28} -{12,75,92} -{48,41,55} -{59,75,26} -{48,19,48,72} -{91,4,100,25,17} -{46,52,97,78,94} -{7,81,76} -{54,54,49} -{89,37} -{78,22,57} -{75,25,83} -{25,89,10,38,96} -{52,12,1,74,35} -{13,48,88,7} -{6,97,20,19,91} -{53,2,99,76} -{4,58,46} -{30,30,89} -{97,2,87,47,55} -{14,11,72,83,97,74} -{44,69,11,51} -{47,17,86,27} -{15,19,56,96,24,94} -{81,67} -{11,11} -{20,94,49,36,39} -{39,78,40,46} -{33,87} -{76,89,58} -{94,74,25} -{33,77,5,47,55} -{28,67,99,81,93,83} -{31,10,19,65,60} -{53,25,74,24,48} -{73,69,23,45,88} -{70,56,41} -{21,73,72,28,99,5} -{75,69} -{78,99} -{66,49,89,86,2} -{30,53,18,21} -{67,69} -{1,98,38} -{91,25,16,39} -\N -{75,54,93,39,18} -{96,84} -\N -{64,71} -{6,15,78,50} -{8,45,26,15,25} -{8,90,94} -{52,66,13,98,86,69} -{3,25,28,56,88} -{84,72,89} -{10,33,46,6,57,100} -{13,91,99,2,49} -{83,59} -{88,64,42,50,77,16} -{81,12,27,45} -{12,17,31,93,22,53} -\N -{28,84,85,35,3} -\N -{42,12,86,76,37,63} -{46,23,18} -{45,80,76} -{94,18,100} -{17,80,84,80} -{84,88,29,16,10} -{7,42,90,51,33,40} -{79,51,22,2} -{31,30,72,24,23,84} -\N -{55,50} -{69,47,82,29,83} -{94,56,69,18} -{7,81,71} -{95,13,32} -{66,59,68,62} -{52,19,62,51,80,32} -{38,18} -{73,24,81,58,22} -{11,59,41,19,96} -{61,11,56,89,89} -{61,72,9} -{63,12,8} -{76,54,75,84,6,44} -{74,3,11,62,30,74} -{46,60,71,55} -{28,47,52,71,33,33} -{35,51,37} -{38,89,40,29,30} -{18,26,99,89} -{36,44,8,100,72} -{1,23,6,5,23} -\N -{84,17,16,44,81} -{29,70,24,85} -{23,57} -{20,98,30,23,1,66} -{82,3} -{70,7} -{15,49,58} -{19,40,70,88,35} -{45,10} -{62,89,47,71,55} -{34,100,88,44,3,91} -{92,65,16,24,7,9} -{20,12,61,95,7} -\N -{57,49,42,87,88,14} -{89,99,86,31} -{32,55,51,78} -{55,66,78,10,12} -{37,19} -{13,5,36,66} -{89,7,40,45} -{41,58,41,24,11} -{98,8,9,27,40} -{49,83,89} -{91,36,78,44,100,62} -{76,78,9,52,57,27} -{100,59,37} -{51,1} -{92,83} -{45,1,85} -{8,81,45,94,32} -{52,26,9,98,7} -{97,52,4,85,13,11} -{94,38,58,4,72,91} -{5,39,26,14,74,51} -{31,44,37,24,89} -{8,74} -{56,93,36,3} -{23,46,25,90,42} -{4,98} -{31,95,27,26,20} -{3,7,79,9,90} -{29,22} -\N -{35,34} -{80,28,12,21} -\N -\N -\N -{36,49,94,83,25,9} -{6,62,89,93,59} -{67,75,3,93} -\N -{94,62,3} -{97,36} -{43,89,26,94} -{46,56,22} -{50,15} -{45,47,39,61} -{23,32,24,45,43,11} -{97,66,29,8,52,67} -{37,1,48} -{30,84,86,91} -{4,46,59,35} -{76,37,41,90} -{26,28,92,27,88,17} -{76,37,27,41} -{74,51,31} -{16,33} -{66,85,68} -{4,81,72,62} -{65,14} -\N -{11,43,28,14,9,43} -{60,88,95,1} -{52,92,69,48} -{37,81,85} -{57,73,8,79} -{50,26} -{52,41,99,6,33} -{9,34,58,22,9} -{56,37,19,77,50} -{93,21,18,90,41,40} -{28,89,76} -{4,36} -{89,54} -{70,28} -{66,11,3,47,30,43} -{69,54,86} -{45,41,57,34,18} -{91,46,32,68,42,68} -{25,87} -{75,57,12} -{55,15,68} -{6,63} -{22,39,88} -{77,39,10} -{39,49,69,61,66,77} -{78,25,42,73,89} -{17,47,36,27,79} -{33,83,44} -{27,75,12,96,94,87} -{50,17,95,42,25} -{67,13,22} -{59,85,95,2} -{81,57,83} -{25,11,72} -{32,84,97,6,65,52} -{62,25,24,27,50} -{80,64,23,74,54,75} -{97,17,15,100} -{50,11,41} -{57,82,40} -{10,90,41,52,39} -{4,11,86} -{79,17,51} -{48,100,92,77,58} -{88,67,19} -{40,96,52,35,16} -{89,63,32,81,28,63} -{44,56,66,50,55} -{28,73,46} -{32,40} -{52,65,85} -\N -{51,34,18,82,83} -{49,49,90,71} -{84,16,74,78,86,10} -\N -{73,9,47} -{51,59,49,90} -{85,13,78} -{98,77,18,15,92,85} -{40,94,66,94} -{89,51,80,12} -{23,26,75,17} -{96,2,51} -{88,62,90,32} -{85,19,87,89,30,15} -{33,38,9,46,19,87} -{27,45,15} -{39,79,82,88} -{31,33} -{41,64,10,1} -{35,61,22,76,74} -{75,11,90,16} -{71,23,43} -{35,3,97} -{88,4,97} -{100,61,28} -\N -{64,74} -{9,44,81,98,55} -\N -\N -{76,89} -{18,34,80} -{77,83,91,50,20,41} -{65,50,26,65} -{79,18,90} -{5,60} -{42,21} -{31,70,80} -{20,98,15,14} -{58,65,45,6,64} -\N -\N -{88,82,98} -{75,81,32,34,59} -{37,14} -{30,36,55,70,65} -{84,55,26} -{56,64,1} -{31,41,89} -{46,43,43,90,34,100} -{78,36,21,14,69} -{100,10,45} -{73,69} -{60,86,5,70,78,99} -{6,89,92,8} -{86,68} -{44,4,71} -{41,36} -{95,80,42,94,34} -{73,29,50,49} -{61,20,57,17,36} -{37,58,67} -{56,83,77,37} -{98,67,40,10,35,76} -{54,84,6} -{7,71} -{65,74,43,6} -{62,98,74} -{81,26,17,22,47} -{49,32,59,35,11,94} -{80,50} -{91,1,50,97} -{71,35,84} -{97,4,46,45,8,36} -\N -{81,62,76} -{69,78} -{89,3,16,64,17,17} -{78,72,26,88,81} -{25,34,9} -{50,27,34} -\N -{55,44} -{61,51,39,53,44,46} -{23,94,32,92,90} -{91,47,67} -{1,13,76,57,63} -{77,19,73,18,95} -{100,82,87,6,83,23} -{69,58,48,97,60,50} -{4,83,85,6} -{3,5,91,37,94} -{91,72,31,32,80} -{57,23,39,46,50,20} -{92,28,53} -{71,27,46} -\N -{59,73,29,21,89,30} -{1,83,96} -{34,41,65,35} -{52,89} -{62,68,80,7} -{82,82} -\N -{11,2,62,46,28,9} -{9,16} -\N -{22,44,73,82,39,86} -{97,52} -{46,36,76,56} -{17,97,26,72} -{16,78,9,70} -{65,55,30,91,16} -{27,45,76} -{17,5,90} -{86,52,93,89,42,27} -{51,70,41,35,1} -{91,57,66} -{53,59,62,57,52,56} -{100,100} -{32,78,87} -{61,57,74} -{86,79} -{55,94,64} -{81,20,26,22,23} -{9,96} -{86,65,35,19,88} -{1,37,90,51} -{79,47} -{93,93} -{32,85,69} -{49,12,6,69} -{6,44,92,37} -{28,42,57,28,2,69} -\N -{63,90,25} -{53,28,74,42} -{83,79,94,37,64,69} -{93,100,57,84,80} -{39,93,80} -{97,92,55} -{27,6} -{20,100} -{19,66,3,66} -{7,76,15} -{7,56,92,11} -{61,76,6,98,52} -{20,46,51} -{12,77,45,67} -{78,79,32,22,21,47} -{62,35,1} -{86,66,57,10,47,43} -{43,24,76,18,87,68} -{39,52,71,35,87} -{81,78,8,10} -{33,70,53,54} -{25,77,27,68,95} -{29,53,89,62,51} -{21,76,33,72,39} -{13,22} -{1,1,51,73,20} -{26,97} -{64,75,23,94,62,68} -{25,20,84,57,27} -{26,7} -{92,80,17,48,72,73} -{73,49,88} -{24,36,70,53} -{7,79} -{80,58,33,25,91} -{19,43,61} -{54,49,73} -{51,88,4} -{9,32,5,83} -{17,68,90,15,30} -{98,50,42} -{29,52} -{32,41,4} -{33,97,69,34} -{94,2,60,5,83} -{23,86,43,74,35} -{63,37,38,58,39,14} -{56,7,82} -{88,81} -{50,75} -{78,49,67,68} -{10,61,58} -{84,35,20,30} -{36,34,48,31,16} -{35,7,47,22} -{98,40,56,43} -{16,4,7,9,44,55} -{86,90,30,80,47,91} -{34,91} -\N -{12,67,77,23,11} -{94,8} -{5,68,31,82} -{26,65} -{51,19,86} -{55,83,39,39,96,51} -{31,22,70} -{20,50,15,93} -{1,55,64} -{8,2,14,3,40} -{2,71,25,41,5,5} -{98,61} -{21,64} -{100,76,99,18,78} -{17,4,69,97,61} -{52,79,97} -{52,26} -\N -{90,54,2,62,11,51} -{33,12,34,45,2} -{91,63,51,42,82} -{100,79,73,70,54,14} -{57,94,81,55} -{13,18,94,17,16,34} -{58,79} -{90,64,68,46,95} -\N -{37,46} -{91,94,10,85,100,24} -{65,86} -{94,89,7} -{72,79,77,53,95} -{65,19,92} -{41,79,53,8,63} -{28,60,50,42,9,32} -\N -{6,23,97,23,10} -{12,28,16,39,70,50} -{26,97,61,48,79,23} -{38,98,21,34,65,89} -{29,13,36,19,13,45} -{72,65,58,81} -{43,98,84,5} -{79,41,100} -{35,30,69,42} -{59,13} -{65,90} -{40,38,21,23} -{2,19,26,38,66} -{5,16} -{84,85,97,84} -{34,26} -{87,17,21,32,29,25} -{75,66,87,90,18} -{84,32,29,51,71,68} -{57,25,73,24,53,2} -{74,16,92} -{99,60,19} -{98,14,70,72} -{24,34} -{37,34,81,100} -{67,10,17,60,16,55} -{39,58,5,23,85,95} -{75,93,19,31,47} -{13,27} -{42,14,32,90} -{59,79,70} -{48,96,45,38,58} -{96,87,84} -{23,70} -{25,31,81,36,75,32} -{64,49} -{30,18,38} -{69,27} -{76,82,43,96,73,17} -{84,95,97,12,20} -{57,69,36} -{60,79,19,67,9,12} -{32,39,3,21} -{55,83,51,48} -\N -{37,11,98,53,11} -{2,73,24,18,77,74} -{69,96,17,49} -{53,2} -{1,76,72} -{35,93} -{35,36,36,25} -{59,77,30,13} -{35,69,36,31} -\N -{20,23,51} -{81,83,57} -{87,43,40,56,81,64} -{24,63} -{29,51,45,93} -{73,85} -{59,1} -\N -{13,57,14,11,34,91} -{69,1,4,28,77} -{63,68,41,53,64,43} -{11,1,46,40,6,88} -{51,19,77,10,86,66} -{74,40} -{25,54,46,62} -{94,17,64,15,20,36} -{100,71} -{63,66} -{33,88,5,92} -{92,86} -{91,69,75,13,20} -{57,22,32,33} -{72,87,44,64,46,6} -{50,56} -{36,23,7} -{74,63,3,6,14,29} -{91,42,8,11,49} -{32,64,94,88} -{91,78,55,27,59} -{2,20} -{52,95} -{57,59,35} -{51,15,52,24,14,13} -{64,16,18} -{50,98,71,10} -{92,99,92,80,77,73} -{96,12,70,85,54,73} -{10,44,30,77} -{29,47} -{40,55,62,58,30} -{59,93,7,21,6,20} -{58,91} -{5,70} -{36,23,58,80} -{16,93,54} -{20,8,97} -{78,32} -{10,31} -{24,10} -{56,14,28,10,45} -{1,79,53} -{56,58,86} -{93,83,17,89,93} -{12,4,26,45,97,17} -{42,67,17,13} -{31,90,59,38,4,20} -{86,52,67,10} -\N -{49,59,10,25} -{69,88,31,38,7,36} -{84,21,57} -\N -{60,8,19} -{35,81,66,96} -{13,95,54,38,31} -{27,25,34,11,65,64} -{54,43,20,20,65,95} -\N -{19,27,100,69,43} -{91,8} -{30,65,98,87,84} -{83,85,100,16,20,18} -{80,48,56} -{61,5,92} -{14,94,43,91} -{35,52,60,43} -{73,25,26,61} -{66,41,39,16} -{2,96,90,37,99,92} -{25,31} -{72,57,50,82} -{40,69,5} -{98,34,66} -{90,44} -{34,78,93,15,65,71} -{98,1,28,36} -{16,59,79} -{88,1,14,45} -{41,91,87,20,72} -{46,9,81,90,63,32} -{2,84,29,56} -{2,57,92,69,63,46} -{3,32,76,62,36} -{11,81,3,81,90,16} -{36,1,42,51} -{29,86,53,51,85} -{17,66,16} -{4,21,25,17,65,92} -{13,26,33} -{74,6,46} -{69,19} -{47,78,85,46,41} -{41,62,100,85} -{22,71,66} -{28,15,58,84,22,92} -{68,82,82,85,15,54} -{34,58,72,35,99} -{51,100,40,13,61} -{80,89,94,31,96} -{48,29,33} -{32,85,75} -{76,43,17} -{79,70,3,64} -{76,64,85} -{94,90,3,85} -{86,21,1,8,54} -{87,92,30,36,59} -{20,51,62,17} -{81,61,86,96,47,67} -{5,75,97} -{60,24,79,3} -{85,49,49,48,61} -{66,60,58,92,88,90} -{2,18} -{42,54} -{42,83,68} -{98,76,42,25,90,32} -{64,36,39,45,34,95} -{56,43,78,10,63,18} -{51,40,98} -{85,11,74,41,14,25} -{37,12} -{76,32} -{6,77,16,86,36,25} -{23,93,18} -{75,51,67,29} -{22,9} -{18,58,25,88} -{95,31,12,20,62,54} -{23,97,89,63,73} -{77,41,11,27} -{91,86,97,98} -{84,6} -{74,69,55} -{58,42,92,65,52} -{77,31} -{8,91} -{5,83} -{64,48} -{1,37} -{51,4,49,97,64} -{29,70,3,62,57,1} -{91,8,31} -{86,71} -\N -{61,50,8,6,59,76} -{83,8,54} -{50,45,66,86,52} -{75,48,18,88,82} -{1,52,60,78,45} -{46,65} -{53,2,63} -\N -{89,97} -\N -{75,23} -{30,58,13,50,2} -{59,73,52,8,70,39} -{20,35,77,34,10} -{55,86,14,74,14} -{67,46,48} -{20,9} -{20,92,62,75,34,98} -\N -{72,14,18,46} -{48,71,92,17,31,13} -{47,46,42} -{42,75,14,86} -{97,55,97,78,72} -{8,4,96} -{44,13,13,18,15} -{16,40,87} -{87,66,79} -{14,44} -{35,79,25,57,99,96} -{23,66} -{90,49,24,11,8} -{50,3,24,55} -{60,94,68,36} -{11,20,83} -{66,100,47,4,56,38} -{36,34,69} -{41,57,15,32,84} -{32,25,100,45,44,44} -{70,32} -{15,37,67,63,71,34} -\N -{81,62,20,91} -{32,62,1,68,86,54} -{20,91,40} -{79,69,22,98,14} -{45,42,24,2} -{30,53,15,62} -{81,100,42,20,96,42} -{93,19,7,59,100,49} -{25,7,18,64} -{11,27,1} -{89,67,65} -{39,97} -{47,62,30,61,58} -{4,11,83,18} -{38,30,95,58,13,81} -{83,6,33,73,64} -{89,51,77,45,58,16} -{13,11,88} -{96,79,71} -\N -{18,66,83,52,84,76} -{52,17} -{74,95,16,5,16,51} -{21,20,16,39,84,71} -\N -{75,47,36} -{65,45,12,5,100} -{41,74,84,21,73} -\N -{8,90,46,39,30} -{47,84,42,49,17} -{76,100,35,89,17} -{61,53,50,31,8} -{94,53,20,33,15} -{97,46,62,85,74} -{8,59,40} -{95,71,21,41,85,81} -{55,71,20,74} -{70,95} -{61,42} -{83,74,25,84,18} -{56,43,46,40} -{42,78} -{95,48,98,93,35,98} -{77,34} -{4,54,58} -\N -{13,54} -{87,66} -{12,88,90,95,6,95} -{65,20,10} -{62,74,59} -{49,17,51} -{14,17,65,3,27,41} -{43,42,43,46,79} -{88,75} -{21,46,84,95,31} -{17,17,28} -{32,73,29,11,46,94} -{3,34,81} -{80,83,1,92,69,100} -{9,24,56,17} -{3,80,57,36,14,94} -{39,89,54,17,31} -{70,19,67,21,31,72} -{82,48,68,52} -{96,81} -{92,18,39,50,18} -{6,54,27,52,28,100} -{23,40,7,74,93,50} -{87,51,38,88} -{98,42,43,30,8,71} -{33,26} -{20,21,83,35,99,100} -{28,77,94,32,1,13} -{17,15} -{35,100,9} -{42,6} -{16,28,55} -{7,94,81,60,91} -{100,63,21,28} -{65,20,35,16,76} -{95,3,88,62,1} -{73,44,46,13,55,69} -\N -{60,49,71,77} -{93,39,75,63,69} -{97,36} -\N -{77,16} -\N -{57,30} -{39,31,56,51} -{62,78,62,38,54} -{69,86,99,10,12} -{11,43} -{60,70,83} -{83,82,3,1,60} -{24,55,61,85} -{65,72,13,77,79,100} -\N -\N -{28,97,71,78,68,95} -{34,1,72,79,84} -{10,49,91,44,27,51} -{15,48,80,37,69} -{42,46,32,34,86} -{80,21,26,50,5,8} -{61,71,100,78,54,50} -{36,20,80} -{67,40,47,68} -{60,7,36,36,55,2} -{32,91,13,98,88} -{15,56,65,23,13} -{20,66,81} -{19,36,99,54,86,92} -{82,28} -{43,32,91,37,70,68} -{71,78,82,50} -{1,31,23,48,10,12} -{88,96,1,44} -{27,49,97,29,89,35} -{63,72,58} -{79,9,32,64} -{75,67} -{46,31,83,54} -{66,24,6,89} -{82,10,64} -\N -{19,31,52,34,89} -{16,36,11,12,23} -{55,50,6,20} -{81,72} -{71,74,8,6,31} -{6,20,96,80} -{95,85,56,91} -{36,33,88,12,50} -{77,44,52,50,50} -{94,12,7} -{97,44,40,43,8,21} -\N -{61,14,40,75,87} -{43,21,67,66} -{46,19,80,12,46,28} -{56,11,14,59} -{31,94,50} -{45,26,61,15} -{84,45,44,82} -{9,16,86,54,93,30} -{50,39,37} -{35,60,64,55,73,90} -{61,65,87,20,30} -{12,59,44} -{23,8,97} -{30,59,7} -{85,32,14,95,38} -{18,91} -{10,40,20,8,58} -{5,58,4,94} -{100,11,96,70} -{66,72,7} -{5,31,89,89,4} -{81,68,44,37} -{22,22,76,67,72} -{22,26,30} -{73,47,27,18,54,30} -{44,13,73,95,83} -{18,93,72} -{30,22,73,13,16} -{14,11,66} -{45,33,59,72,92,81} -{97,82} -{30,4} -{1,9,46,70} -{47,50,20,71,48,60} -{26,62,53,70,63,49} -{39,26} -{47,94,9} -{55,3,18,1,75,22} -{42,87,74,57,60,55} -{95,46,21,38,27} -\N -{13,35,48} -{24,39,24,67} -{44,83,49,72} -{22,8} -{77,39,87} -{37,41,44} -{100,57} -{48,54,58,79} -{14,84,40} -{11,51} -{23,80} -{80,82,43,59,2} -{92,53,56,44,90,66} -{44,67,78,9} -{43,91} -{70,74,100,69} -{12,5,75} -{65,51,22,65,56,36} -{52,54} -{38,78} -{30,45,38,99} -{18,88,88,63,51} -{61,24,53} -{72,24,77} -{61,46} -{11,83,49,86,27,60} -{86,60,83,34,33,28} -{65,15,10,51} -{98,92} -{49,49,60,3} -{58,56,43} -{19,25,15} -{24,40,36,49,61} -{5,62,9} -{72,8,71} -{64,85} -{72,84,67} -\N -\N -{80,87,30,70,21} -{30,86,95,19,21} -{17,90,15,89,81} -{40,51} -{77,88} -{14,89,82,62} -{40,66,93,16,55,45} -{22,46,31,17,4,71} -{8,41,88,94,25,61} -{80,8,23,71,59,53} -{61,70,23} -{2,4,79,6,67} -{27,70,42,68,33} -{46,27,10} -{1,93,42,12,8} -{31,9,19,32,62,15} -{16,42,81} -{56,29,12,17,61} -{52,100,98,42} -\N -{29,38} -{49,40,47,63,22,4} -{99,70,13} -{70,28,67,100} -{37,75,65,63,35} -{45,67,37,28} -{42,78,71,39} -{33,35,76,69} -{65,84,57,63} -{17,12,86,23} -{31,62,79} -{3,22} -{85,81,59} -{38,5,15,100,1,27} -{36,96,93,46,75} -{44,61,85,70,71} -{79,72,86,71,77,9} -{23,51,47} -{4,59,48,38,44} -{93,54,86,98} -{60,29} -{49,38} -{54,84} -{72,25} -{51,40,25,27,68} -{24,17} -{95,3,82,31,95} -{56,37,57} -{15,84,98,16,53} -{47,36,15} -{27,36,76} -{38,82,26} -{47,70} -{60,89} -{59,73,99,7,28,89} -{87,49,70,76} -{71,93,76,81,11,46} -{74,87,92,24,43,22} -\N -{26,1,85} -{18,73,43,94} -{92,2,73} -{5,58,85} -{20,7,39,18,59,90} -{11,16,19,77,60,56} -{77,1,95} -{4,4,11} -{48,40,56,74,96,29} -{71,1,62,69} -\N -{34,61,26} -{86,75,13,73,28} -{17,35} -{100,29,37,26,47} -{69,36,52,61} -\N -{81,51,54} -{54,78,46} -{1,78,96} -{33,54} -{72,9,37,30,100} -{67,10,52} -{77,19,74} -{52,27,41,37,98,73} -{8,74,86} -{4,40,99,6,59} -\N -{98,43} -{74,91} -{69,45,73,59,19} -{87,43,31,85} -{2,51,54,3} -{45,73,8,86,4,40} -{2,51,96} -{74,5,8,64,1,46} -{5,64,86,63,12,75} -{6,62,71,24} -{56,84,54} -{61,37,79,63} -{81,39,78,23,86,74} -{50,79,34,23} -{85,36,78,80,19} -{34,94,1,46} -{5,23,38,4,78,2} -{85,100,80,13,73} -{48,86,9} -{47,22,65} -{49,81,18,52,36} -{84,85} -{89,15,71,88,44} -{1,21,81,52,2} -{53,18,7,53,50,11} -{91,89} -\N -{20,6,20,70,12,32} -{98,94,70,52,41,35} -{43,25,2,63} -{95,86,6,82,2,41} -{79,24,63} -{12,96,7,18,48,67} -{55,35,4,75,28,39} -{48,46,33,75} -{10,99,5,5,98,25} -{43,87,5,53,76,64} -\N -{100,13,9,4} -{4,35,65,56} -{27,74,88} -{59,66,10} -\N -{59,85,39,48,17,29} -{59,42,17} -{27,99,12,21} -{9,10} -{15,4,80,25,67,59} -{12,89,96} -{50,32,92,49} -{40,74,10,6,26,43} -{80,71,29,54} -{74,82} -{22,25,27,65,12} -{84,88,53,43,75} -{84,16,51,84,46} -{10,9,44,95} -{87,19,22,10,44,80} -{18,20,87,41,86} -\N -{9,64,4,33} -{65,87,23,65,32,92} -{50,2,23,68} -{29,8,82,28} -{54,92,6,2,28,70} -{23,11,65,78,34} -{77,85} -{30,49,59,8,60} -{77,30,34} -{55,73} -{89,68,55,81,8,81} -{54,28} -{35,22,67,63,48} -{43,37,46,56,81} -{16,78,32,81,77,37} -{35,80,41,76} -{4,93} -{3,32,23} -{43,18,50} -{87,5} -{30,40,91} -{36,69,17,82,70,57} -{73,71,47,63,58} -{24,11,36} -{2,72,61,76,9} -{61,97,10,85,92,56} -{5,44,47} -{24,57,79} -{69,39,97,8} -{78,16} -{62,52,17,35,28} -{48,79,66,64,36} -{14,72,75,30} -{17,21,41,25} -{28,100,66,56,15} -{89,3,32,86,6} -{67,34,16} -\N -{48,27,70,60,1,40} -{69,34,36,46,95} -{59,24,84} -{44,21,90} -{22,30,5,62,13,58} -{79,67,44,10,1} -{67,8} -{40,48} -{64,5,65,35} -{74,45,75,15,31,69} -{42,3,49,33,52,97} -{86,59,69,84,53} -{64,64,41,64,99} -{47,95,16,78,73,68} -{54,11,52,90} -{54,62,79,58,96,59} -{28,34} -{52,94,17,42,9} -{94,22,77,7,56} -{72,24,47} -{6,11,3,23} -{9,6,97,82,40,39} -{73,47,57,8,7,97} -{27,26,1,2} -{64,45,38} -{71,6,6,83,33} -{78,28,40} -{25,8,17,15} -{24,67,53} -{72,42} -{66,25,56,36,32,93} -{18,11,22} -{88,9,75,23} -{20,32,24,44,51,34} -{76,86,11,7,1,61} -{11,77,41,55,87,59} -{62,53,94,46} -{77,20} -{74,97,59,78,9} -{7,94,26,18,77} -\N -{49,59} -{72,22,42,89,14,80} -{49,14,38,19} -{43,88,25,58,39,24} -{21,34,37,65} -{85,3,46} -\N -{11,60,86,65,49,83} -{51,98,7,28} -{85,17,34,59,14,86} -{89,81,48} -{67,40,11,60,75} -{13,45,42,22,82,82} -{98,21,89} -{30,63} -{35,45,68} -{9,29} -{43,71} -{82,44,59,72,48} -{1,48,29,44,14,11} -{75,33,85} -{7,32,92} -{62,14} -{29,31,1,36,51} -{92,12,28,20} -{13,67} -{88,72,14,22,61,42} -{15,98,49} -{65,27,9,76} -\N -{15,95,26,12,52,40} -{17,20,74} -{57,63,15,22,38} -{93,71,8} -{26,84,82} -{20,52,3,3} -{72,95} -{10,9,80} -{9,9,18,51} -{74,24,63,63,57,89} -{64,91,95,18,15} -{64,37,20,36,74} -{52,9,53,6} -{17,31,42} -{3,73,92,13,62} -{57,81,58,49} -{52,56,2,26,18} -\N -\N -{90,90} -{16,92} -{66,51,7,19,10} -{100,81,69,86,95} -{48,64,81} -{87,54,73} -{6,80,100,24,26,8} -{44,67} -{27,94,2,25,34} -{80,25} -{12,2,77,75,15} -{63,14,30} -{85,75,59} -{72,73,54,44,25,76} -{95,44,69,91,62} -{94,73,78,5} -{28,52} -{86,31} -{69,90,95,66} -{6,10} -{68,72,112} -{9,165} -{91,132,164} -{57,82,144,167,184} -{3,6,101,118} -{111,158} -{22,29,30,174} -{41,66} -{39,76,189} -{7,20,21,196} -{52,126,169,171,184} -{21,77,91,176,196} -{16,97,121} -{83,135,137} -{8,140,160,164,165,195} -{38,65,185} -{112,152} -{111,129,134,148} -{47,80,114,135,147,165} -{24,98,119,123} -{43,48,60,147,154} -{19,54,138,171,186} -{156,175} -{20,51,123,193,193} -{37,41,136,173,192} -{14,22,111,125} -{44,125,160,184} -{19,75,99,103,107,164} -{24,113,145} -{27,157} -{12,107,133,134} -{72,94,102,158,194} -{104,157} -{122,171} -{28,47,89,104,112} -{25,35,82,105,155} -{106,107,139,181} -{50,110,132,136} -{90,110,166} -{1,1,55,60,85,108} -{8,22,31,106,172,196} -{24,69,109,121,154} -{0,26,44,59,132,175} -{103,125,172,188,190} -{11,23,78,109,131} -{81,146,169,181,196} -{2,84,113,189} -{8,46,126,131} -{13,73,73,125,127} -{67,117,139,184} -{29,65,77,120,182} -{0,87,100,102,135} -{111,146,156} -{13,87,123,137,182,197} -{60,61,164} -{7,20,186} -{0,24,53,135,147} -{94,136} -{47,168} -{70,80} -{43,148} -{3,81,104,191} -{104,171,189} -{9,14,117,160,180} -{67,158} -{50,57,66,78,170,197} -{31,60,73,101,193,197} -{37,89,92,96,127} -{29,179} -{17,47,137,155,157,187} -{33,77,154} -{48,63,85,150,184} -{32,53,61,95,172} -{20,35,47,171,179,196} -{2,17,40,169,184} -{116,127,131,142} -{16,26,27,87,164,198} -{58,129} -{67,98,108,132,157,197} -{145,157} -{13,49,56} -{59,103,180,196} -{35,65,104,106,120,126} -{18,96,115,133} -{27,61} -{61,194,197} -{11,27,36,94} -{15,36,101,128,197} -{51,62,115,149} -{83,198} -{30,120,127,145,184} -{50,149} -{13,35,87,117,135,158} -{57,60,74,113,128,178} -{11,90,123,163,170} -{39,121,148,171,198,199} -{30,77,78,137,140,162} -{52,69,120,141} -{9,100,137} -{56,161} -{44,57,75,110,154} -{98,123,155,167} -{10,60,85,105,164,168} -{13,92,179,186} -{13,171,173,176,178} -{33,53,88,123,144,172} -{21,57,70,131,151} -{13,51,63,169,169} -{36,104,119,166} -{54,59,84,166,172} -{7,87,100,102,142,187} -{2,5,6,43,174} -{4,26,29,59,77} -{10,82,98,103,104} -{104,147} -{47,55,99} -{102,154,165} -{0,96,107,139,157,159} -{66,167,174} -{92,97,117} -{21,75,180,185} -{54,64,139,180} -{23,141,189} -{32,38,147} -{82,87} -{6,34,34,161,183} -{25,64,69,97,122} -{80,152,170,189} -{44,78,143,162} -{52,53,64,69,112,158} -{77,80,123,150,175} -{110,121,125,125,128,198} -{0,8,57,104,127,188} -{17,46,48,93,129,150} -{135,193} -{89,111,135,166,184} -{132,181} -{47,54,101,108,125} -{18,55,103,142} -{11,125} -{18,49,58,68,122,153} -{37,47,137,179,185} -{57,78,167,187,192} -{28,32,38,67,77,184} -{67,83} -{43,104,191} -{22,40,118,194} -{24,53,66,195} -{27,87,89,101,130,191} -{71,86,157,167,183} -{31,87,102} -{48,53,70,101,149,174} -{21,33,59,129,195} -{144,160} -{4,8,174,194} -{69,103,127,127,160} -{6,29,62,77,132} -{61,69,108,144,174} -{51,55,109,128,153} -{10,30} -{2,5,6,70,146,183} -{0,1,75,97,166,180} -{53,78,104} -{31,45,68,108,161} -{3,40,78,103,109,130} -{33,44,159} -{28,82,93,136,148,157} -{31,32,76,143,157} -{2,55,106} -{21,66,80,129,129,152} -{1,34,59,128,154,195} -{10,154,172,177} -{2,7,31,47,82,125} -{60,131,149,156} -{20,141} -{23,38,43,100} -{51,70} -{3,41,164} -{126,160,165,169} -{61,71,143} -{65,70,81,100,146} -{40,48,57,75,85,85} -{116,153} -{31,42,49,103,183} -{28,44,62,85,133,177} -{50,68,164,170} -{4,26,60,87,119,141} -{5,102,160} -{20,129,177} -{98,120,135,157,164,168} -{66,150} -{101,101} -{164,187} -{43,65,96,166,189} -{18,36,58,109,118} -{25,32,135,161,170} -{55,104,183} -{69,139,144,181,182} -{84,131,155} -{6,18,63,156,159} -{7,66,67,88} -{8,46,52,95,178} -{58,58,83,119,119,163} -{27,143} -{78,80,122,149,164,176} -{6,83,107,183,198} -{86,199} -{22,74} -{28,62,64,114} -{15,56} -{41,97,139,152,161,161} -{48,192} -{16,62,99,138,155} -{32,84,145} -{108,137} -{93,112,120,155} -{73,117} -{20,26,197} -{4,141} -{110,132} -{95,133,142,152,183,193} -{85,141} -{53,76,86,131} -{5,59,73,74,101,130} -{0,1,64,151,188} -{15,131,131,174} -{80,98,106,187} -{41,102,167,173} -{9,42,133} -{103,110,110,134,175,185} -{168,187} -{42,47,108,121,165,198} -{81,171} -{38,122,123,149} -{16,79} -{45,64,131,176,182,197} -{35,82,87,100,123,196} -{41,52} -{33,68} -{60,140} -{12,41,152} -{54,71} -{88,95,95,146,148,180} -{47,66,89,121,168,182} -{15,70,94,122,137,154} -{42,48,129,162} -{70,151} -{11,55,89,118} -{36,74,121,130,152} -{46,48,52,120,179} -{70,81} -{96,146,183} -{76,78,108,153} -{71,168} -{66,106,108,167} -{22,44,49,85,87,195} -{17,52,143,175} -{86,103} -{16,46,176} -{95,111,162,173,198} -{44,191} -{7,48,107,115,116} -{12,120,141,179,184} -{83,188} -{83,85,86,139,154} -{50,74,89,154,179} -{79,87,120,128,183} -{13,121} -{16,52,62,86,168,199} -{7,16,29,35,157,181} -{23,48,65,119,180} -{10,173} -{7,98,128,143,145,162} -{23,27,88,91,127} -{35,53,56,56,118} -{7,161} -{0,42,67,174} -{44,161} -{75,80,110,170} -{17,93,117,140,168,196} -{18,100,150,184} -{108,132} -{54,90,97,103,149} -{9,12,30,43,82,95} -{131,163} -{67,99,168} -{91,150,172} -{47,164,195} -{72,90,98} -{24,78,130,172} -{1,27,32,64,66,156} -{7,26,72,88,130,140} -{56,126,130} -{1,76,81,122,169,188} -{60,154} -{101,103,135,150} -{22,25,33} -{99,117} -{24,95,122,186} -{48,95,102,108,125,170} -{13,113,154} -{155,177} -{37,73,106} -{7,64,124,195} -{101,124,133,157,166,188} -{27,34,60,100} -{26,104,163} -{34,43,108,133,165} -{64,79,89,122,132} -{10,96,168} -{2,22,89,118,122,198} -{122,192} -{42,101,104,135,168,181} -{7,38,63,86,101,152} -{29,84,89,114,123,184} -{33,46,59,137,153,175} -{3,54,66,92} -{31,34,148,159,185} -{3,52,97,99} -{3,26} -{42,57,62,148,199} -{15,26,198} -{14,34,109,111,128,193} -{107,197} -{16,107} -{9,21,136,169} -{67,97,99,153,165,173} -{46,76,89,100,164} -{96,102,150,167,180} -{31,103,137,146,180} -{21,40,157,163,170,183} -{139,170} -{1,75,82,148,169,198} -{13,39,107} -{13,50,97,101,106} -{52,176} -{18,169} -{129,140,146,183,189} -{95,122,145} -{5,6,102,130,151} -{5,118,140,153} -{27,78,140,164,182} -{36,140,148} -{58,100,127} -{9,16} -{26,33,119} -{1,17,18,165} -{14,182} -{11,13,48,89,140,165} -{9,19,78,113} -{121,171} -{18,23,46,113,159,162} -{17,104} -{50,104,132,167,179} -{55,89,102,132,176} -{19,109} -{60,70,73,153,163} -{18,127,145} -{80,106,146,170} -{10,39,72,74,84,150} -{3,71} -{1,10,64} -{82,95,127,132,141,152} -{43,55,57,89,120,197} -{155,182} -{23,34,57,111,153} -{99,188} -{86,114,124} -{113,191} -{31,129,184} -{125,159,159} -{22,27,81,156} -{3,54,80,122,128,168} -{76,112} -{152,174} -{22,27,70,172} -{26,86} -{49,59,102,186} -{53,55,75,125} -{152,199} -{11,15,46,102,105,168} -{132,148,154} -{24,114,121,126,138,165} -{82,107} -{36,93,122,184,194} -{1,59,76,146} -{73,165} -{38,98,176} -{53,72,121,153} -{127,147} -{31,77,128,177} -{107,186,189} -{119,126,127,160} -{24,74,148,197} -{85,126,134,146} -{76,77,81,134} -{67,112,159,174,183} -{22,169,170} -{79,112,177,199} -{1,56} -{21,42,50,172} -{6,63,105,166,189} -{31,95,106,152,171,177} -{21,49,99,101,122,187} -{63,104,113,161,186} -{37,126,144,166,173} -{32,53,147} -{123,123,130} -{78,85,177} -{2,69,95,146,187} -{6,11,14,43,121} -{76,105,184} -{63,96,114,122,195} -{11,22,34,45,120,156} -{22,83,119,131,138,167} -{9,56,96,106,114} -{92,132,162} -{25,45,83,119,139,150} -{19,21,56,59,141} -{14,26,62,119,180,190} -{6,34,49,99,139,170} -{10,56,150,166,166} -{14,57,119,153,167,198} -{26,41,150,158,169} -{152,167} -{1,61,93,180} -{46,110,138,199} -{4,56,81,110,173} -{28,32,148,185} -{8,9,28,29,39,195} -{14,39,68,144} -{26,37,79,81,110} -{115,158,161} -{6,39,145,191} -{67,118,125,142,184,198} -{127,163} -{52,118} -{22,78,131,156} -{46,68,86,142,145,197} -{85,188} -{37,54,64,147,158} -{31,134,141,183,185} -{10,33,135,198} -{41,124,173,180} -{0,14,92,129,154,198} -{39,73,128,154,182,196} -{40,83,94,168} -{106,142} -{76,99} -{19,62,77,108,165,186} -{68,90,97,119,176} -{44,108,193} -{2,124} -{137,174,175,176,180} -{28,62,81,132,165,186} -{98,112,148,181} -{86,125} -{70,161} -{5,13,188} -{136,168} -{82,87} -{30,42,57} -{132,136,152} -{20,59,87,98,195} -{6,53,112,113,183,195} -{64,147,157} -{61,140,192} -{44,59,88,123,161} -{90,175} -{38,46,105,121,159} -{35,62,66,90,155} -{2,2,21,38} -{123,144} -{117,155} -{60,86} -{4,39,129,146,179} -{66,71,87,135,148,157} -{29,67,108,196} -{30,64,76,124,172} -{36,39,79,130,140,149} -{30,44,136,196} -{5,15,20,117,198} -{20,87,87,121} -{42,136,142,148} -{0,56} -{16,38,56,57} -{52,138} -{103,115} -{10,29,43,93,120,134} -{44,140,150,180} -{74,98,132,160} -{2,62,98,160} -{14,32,43,63,92} -{23,87,128,152,177,197} -{30,86,111,178,180} -{49,61,114,195,196} -{133,158,195} -{18,105,165,190} -{77,83,175} -{29,33,51,166,188} -{37,51,96,103,127} -{119,125,128,140} -{8,80,93,189} -{76,96,110,131,170} -{81,90} -{13,25,28,41,128,142} -{56,62,73,110} -{60,62,128,136,166,193} -{34,34,61,74} -{32,84,87,92,112,181} -{10,66,93,153} -{23,77,182} -{2,7,156} -{5,13,49,61,103,179} -{67,136,136,163,181,196} -{26,60,74,100,160} -{39,59,69,93,111} -{9,77,90} -{1,20,52,75,156,169} -{25,95,103,157,163,193} -{95,136} -{47,108,137,157,164} -{37,99,151,153,169,189} -{112,126,139,171,184,195} -{39,188} -{4,20,71,80,136,156} -{24,33,77,82} -{103,188} -{74,116} -{82,90,110,154,194,195} -{25,149,180} -{120,123,130,171} -{20,38,104,126,175,176} -{14,62,97,130,135,193} -{35,118} -{20,42,64,73,76,120} -{11,40,60,74,144,148} -{13,26,46,63,76} -{24,29,98,106} -{6,139,171,186} -{5,109,197} -{20,45,84,125} -{1,137,150,195} -{1,8,80,111} -{57,90,102,167} -{53,186} -{8,31,115,145,156,165} -{10,18,31,116,164} -{43,47} -{33,143,154} -{106,153,174,190} -{73,106,158} -{18,137,158,173} -{73,80,107,123,141,199} -{17,43,123,130,130,155} -{15,31,37,91,164,181} -{38,86} -{49,105,142,145,173,190} -{18,107,108,135,138} -{43,65,107,112,193} -{8,68,68,74} -{54,106,108,109,164} -{53,153} -{59,134,154,173,180} -{34,93} -{11,33,124} -{8,104} -{27,37,46,65,125,174} -{0,122,189} -{15,74,107,147,188} -{35,63,78} -{28,49,123,129,177,193} -{11,89,104} -{117,171,197} -{11,15,62,136,145,145} -{2,127,193} -{17,28,42,113,145} -{31,44,118,148} -{52,103,128,161,182} -{45,47,70,102,161,184} -{15,52,82,86} -{60,87,102,108,127,170} -{24,57,102,145,181} -{12,53} -{5,52,92,129,164} -{87,128} -{80,143,170} -{59,85,134,139} -{61,67,110,117,156,157} -{6,8,60,112,154,170} -{92,122,133} -{121,148,161} -{9,22,61,187} -{12,40,78,107,176} -{30,45,58,189,198} -{83,107,123,148} -{3,66,98,124,126,150} -{13,34} -{16,41,132} -{16,85} -{3,25} -{30,58,138,167} -{24,36,87,151,159,186} -{2,4,121,196} -{79,95,99,107} -{11,49,146,169} -{51,90} -{76,155} -{26,26,116,120,146,182} -{44,66,72,117,132,174} -{7,161,179,197} -{2,81,158} -{4,22,59,107,146,170} -{0,0,133,192} -{57,82} -{17,61} -{28,29,42,77,89,124} -{53,78,127,188} -{31,57,103,104,162} -{9,84,100} -{3,52,114,133,161,188} -{8,37,97,158,189} -{0,13,88} -{29,79,92,158,160,171} -{59,63,77,139,165} -{25,77,116,169} -{50,88,151,166} -{52,162,167} -{32,149,191,194,194} -{47,57,74,95,97} -{30,65,96,153,184} -{80,130,150,172} -{79,91,141,153,157} -{93,110,114,194} -{62,66,156,175} -{55,56,97,117} -{74,152,171,186} -{13,24,50,50,131} -{0,16,95,141,146,161} -{1,51,158} -{37,71,96,122} -{71,104,145} -{47,52,124,131,169} -{111,188} -{59,61,95,152,156,157} -{5,31,106,164,176} -{44,82,113,134,188} -{13,55,65,99,150} -{25,73,130,192} -{88,120,193} -{79,123,153,175} -{24,158,162} -{52,53,81} -{5,32,78,102} -{73,97,111,151} -{71,72,102,151} -{5,61,73,85,129,151} -{66,177} -{26,77,139,152} -{46,117} -{55,72,122,148,157,174} -{3,53,76,184,196} -{34,36,41,61,194} -{8,153,163,182} -{51,59} -{113,115,149} -{54,57,78} -{39,137} -{75,81,93} -{5,30,44,80,86,126} -{68,107,128,160,179} -{98,108,162} -{55,126} -{24,54,121,122} -{75,90} -{10,83,139} -{16,120,148} -{97,175} -{53,70,71,120,135,189} -{9,110,123,150} -{24,42,44,96,138,170} -{17,61} -{23,65,110,135,155,157} -{19,59,139} -{50,65,127,179} -{15,138,152,162} -{15,34} -{25,29,63,135,161} -{47,113,123,129,163} -{25,138,157,184} -{50,92,199} -{110,116} -{15,36,134,145,165,182} -{4,75,82,175} -{24,49,63,89,128} -{174,182} -{103,116,119} -{101,125,180,192} -{47,66,113,127,148} -{15,60,118} -{20,51,90,91,117} -{25,72,146,199} -{34,93,199} -{31,71,106,115,186} -{1,10,119,144,188,197} -{49,80,185} -{134,178,188} -{42,67,170,172} -{13,43,91,91} -{13,31,48,98,155,158} -{37,44,70,76,141,160} -{50,60,72} -{51,65,166,188} -{11,103,129,144} -{136,167,181} -{165,178} -{34,107} -{54,120} -{33,132,136,165,178} -{60,79,119,127,187,197} -{27,31,130,132} -{125,129} -{97,111} -{71,171,187,191} -{68,91,94} -{94,119,159,178} -{2,29,51,173} -{37,61,97,113,147} -{11,35,79,91} -{67,71} -{4,20,103,107,169,179} -{35,77} -{71,94} -{29,31,67,101,172,174} -{52,122} -{87,125} -{129,142,164} -{13,30,85,139} -{17,57,65,170,179} -{46,65,151,167,192,197} -{31,78,132,136,158} -{38,161} -{15,101,111,134} -{42,118,139,142,178} -{57,95,132,134} -{5,42,116,152,173,192} -{144,199} -{38,70,77,143,175,188} -{38,84,93,149} -{56,98,153,165,170,191} -{1,52,112,112,131,145} -{16,132,150,184} -{14,60,111,153} -{49,109,112,165} -{69,136,152} -{59,90,94,158,168} -{42,47} -{18,194} -{33,70,94,167,175,177} -{40,57,125,138,159} -{3,10,31} -{2,5,8,26,141,181} -{27,29,142,175,186,195} -{31,49,99,120} -{109,123} -{21,76,112,119,124} -{41,49,146,173} -{101,173} -{49,73,85,89,179} -{22,36,154,192} -{136,163} -{111,165} -{94,128} -{81,167} -{35,165} -{41,109,119} -{13,74,80,114} -{72,106,189} -{65,172} -{30,31,35,52,63} -{80,116} -{0,149} -{139,189} -{0,65,107,153,179} -{15,40,46,51,75,160} -{12,28,48,79,105} -{76,98,146,157,180} -{45,62,79,83,113,155} -{130,162,184} -{78,140,145,181,196,198} -{108,168} -{3,13,14,15,77} -{22,29,68,117,142,143} -{67,110,122,167,183} -{22,25,58,93,143,151} -{53,82,170} -{1,18,50,98,108,174} -{58,140} -{49,179,196} -{109,171} -{38,82,132,183} -{32,151,175} -{53,90,106,169,187} -{99,136,141,146,171} -{27,108,111,155,192} -{28,77,86} -{11,109,118,149,154,183} -{7,74,122,137,185} -{70,110,151,154,175} -{7,48,88,181,181,182} -{97,101,105,123,139,156} -{19,139} -{17,107,134} -{63,64,178} -{100,133,143} -{64,173} -{1,88,109,120,145,160} -{113,198} -{84,112,121,184} -{90,185,193} -{91,135,155,185} -{56,191} -{14,15,48,61,92,171} -{18,139,152,199} -{16,80,107,125,144,166} -{8,92,112,173,176} -{27,196} -{9,169,183,190} -{20,29,40,98,106,182} -{77,115,149,181} -{31,65} -{7,29,62,90,157,178} -{10,33,79,186} -{42,74,113,178,192} -{17,86,88,118} -{27,58,104,122,166} -{16,97,102,105,192} -{16,59,115,127} -{27,56,60} -{104,175} -{52,84} -{127,137} -{7,13,18,81,139,140} -{11,31,81,150,189} -{44,55,107} -{45,58,127,137} -{70,76,80,93,145} -{27,60} -{40,76,172} -{7,123,192} -{55,170} -{61,137,137,184,187} -{49,50,190} -{99,126,152,164} -{56,79,88,98,132} -{45,74,119,123,158,175} -{66,96} -{100,114} -{62,84,111,122} -{8,22,141,172,181} -{70,141} -{3,48,106,193} -{33,114,168,174,183} -{46,186,194} -{58,71,82,122,190} -{60,67} -{14,30,132,144,174} -{9,113,124} -{11,14,29,63,110,182} -{4,64,102,168,178} -{90,108,110,160,165,199} -{44,86,191} -{6,19,84,125,125,156} -{53,105,122,154,175,190} -{83,177,183} -{96,103,181} -{38,156} -{2,6,60,116,131} -{12,144} -{13,73,93,132} -{142,167} -{37,61,71,75,121,144} -{32,43,146} -{41,59,144,176} -{11,14,44,54,92,177} -{37,198} -{39,80,81,104,138,193} -{13,73,92,127,149,194} -{34,57,69,104,118,186} -{7,48,84,96,108} -{32,41,64,111} -{108,131,150,174,195} -{50,53,184,191} -{8,32} -{26,76,88} -{4,50,100,134,134} -{36,40,148,158,177} -{7,16,57,59} -{35,96,113,129,167} -{46,63,128,163} -{8,46,94,97,105,178} -{12,70} -{45,93,134,135,188,195} -{11,52,76,103,131,192} -{19,45,57,119,123,136} -{19,62} -{1,49,64,197} -{0,42,60,102,134,147} -{102,152,156,160} -{51,54,129} -{50,68,71,72,170} -{0,11,184} -{19,105} -{144,185,191} -{17,51,76,98,118,135} -{52,64,143,171} -{1,46,62,74,81} -{8,36,129} -{5,25,96,113,146,152} -{19,28,59,110,131,142} -{7,18,176,179} -{17,21,48,63,121} -{34,79,81,85,152,155} -{8,82,104,122,139,193} -{34,50,128,140,175} -{51,173} -{48,128,138} -{126,129,178} -{42,51,61,141,170,180} -{59,91,144} -{64,74,118,170,191} -{12,55,116,157,159} -{97,157} -{32,34,102,105,178} -{36,103,125} -{15,36,184} -{6,13} -{0,100,144,185,198} -{32,47,64,66,118,143} -{23,112,117} -{34,44,47,81,124,135} -{21,49,115} -{29,158} -{34,114,127,151} -{111,199} -{23,53,76,113,122,123} -{89,113,117,137} -{52,76,126,155,164} -{4,48,78,114,147,179} -{27,56,151,191} -{3,183} -{30,41,72,145} -{15,41,152,177,196} -{44,58,124,164,177} -{9,51,70,174} -{13,18,81,136,178} -{85,139,142} -{12,62,118,156} -{50,142,149,175} -{35,38,99,100,128} -{53,54,92,123,153,160} -{121,133} -{12,63,117,148,149,187} -{88,153,170,192,195} -{22,51,67,104,141} -{186,198} -{39,40,82,159,189} -{59,74,149} -{88,99,136,145,191} -{5,48,90,120,138,193} -{22,76,155,180} -{118,122,141,176} -{87,104,116,159,172,191} -{63,104,155} -{8,153,168} -{119,141,178,179} -{100,110} -{14,65,164} -{2,92,97,117,188} -{47,59,64,141,148,187} -{109,137,139,151,169} -{68,78,156} -{37,39,103,183,190,194} -{50,58,74,180} -{12,121,155,175} -{26,43,97} -{102,159,161} -{3,138,163,179} -{55,69,78,164} -{67,87,136} -{67,150} -{74,113,199} -{103,126,187} -{39,141,155} -{6,19,25,75,157} -{10,49,71,105,114,154} -{3,24,35,54,88} -{16,25,73,114,181,191} -{2,2,63,154} -{68,74,107,187,199} -{13,235} -{40,122,203,232,233,235} -{115,152,193,202,242} -{3,50,86,111,248} -{25,66,181,188,279} -{80,116} -{38,83,106,119,134} -{29,63,203} -{7,27,186,200,201} -{88,92,94,272,295} -{35,68,136,158} -{148,225,293} -{1,87,195} -{48,100,203} -{0,35,61,91,280} -{130,160,168,216} -{4,104,148,164} -{35,40,91,145,155,214} -{46,107} -{21,276} -{42,143,150,238,291} -{64,70,140,165,228,257} -{0,148,197} -{72,131,195,202,251,270} -{99,195,224,264,292} -{5,184,186,243} -{93,132,137,148,228,251} -{66,125,198,211,285} -{29,79,180} -{41,60,65,66,254} -{4,69,79,207} -{113,182,203,252,259,298} -{10,20} -{99,200,276} -{109,262} -{4,87,193,207,220,273} -{30,183,215} -{7,138,202,215,217} -{25,79,194,203,260} -{128,178} -{62,152,211,279} -{57,99,204,280} -{41,59} -{18,52,200} -{81,132,190,275} -{89,158} -{32,72,122,228,245,249} -{24,72,196,233,299} -{0,5,46,122,213} -{197,242} -{43,105,241,272} -{74,118,158,173,208,288} -{145,149,197,238,252,297} -{32,39,189} -{98,240} -{65,140,149,197,203,204} -{103,225,266} -{84,277,283} -{35,246} -{10,101,239} -{40,75,192,253} -{106,152,247,272,287} -{50,293} -{85,134} -{59,204} -{54,64,88,269,286} -{4,92,111,121,154,182} -{80,163,202,234,277,298} -{129,147,158,196,283,290} -{49,144,232,293} -{20,29,226,244,274} -{64,101,185,189,234,268} -{23,157} -{56,93,133} -{9,57,241,289} -{50,124,181,194,238} -{11,38,67,69,213} -{149,220} -{168,189,267} -{34,133,235,264,284} -{81,239,241,260} -{35,78,80,201,262,297} -{0,196,285} -{71,108,239,258,277,278} -{4,94} -{77,132,140,251} -{11,78,132} -{43,145,188} -{97,144,148,161,254} -{109,132} -{48,83,189,242} -{115,176,276} -{162,210} -{88,109,136,153,154,159} -{265,280} -{74,86,195} -{17,112,188,213,231,266} -{36,136,160,218,239} -{179,273} -{79,118,136,154,200,259} -{161,212} -{24,98,178} -{161,187} -{45,169,227,236} -{218,253} -{10,18,74,258} -{70,199,210,213,285,291} -{12,50,69,92,184,186} -{130,131,163,295} -{198,239,297} -{49,86,125,176,234,282} -{7,129,146,223,269} -{144,173} -{30,52,133,228} -{21,88,176} -{5,70,299} -{37,69,285} -{14,17,45,72,99,197} -{125,196} -{30,220} -{55,103,127,251} -{108,114,156,200,207,217} -{7,195,250} -{64,111,193,202,236} -{92,115,232,233,240} -{22,232,260} -{18,44,191,253,294} -{40,158} -{86,92,103,154,207,294} -{33,177,191,223,235} -{65,116,158,253} -{49,125,152,194} -{100,149,191,266,288} -{13,64,103,254,283} -{42,75,80,103,155} -{77,128,198,280} -{118,218,287} -{0,36,52,101,148} -{1,64,181,201,221} -{6,44,47,71,150,225} -{13,85,88,167} -{31,40,69,91,99,281} -{60,115,157,224,252,273} -{30,87,200,270,285} -{171,293} -{24,33} -{59,69,74,118,190,216} -{147,258,288} -{62,73,219,232,266} -{50,74,225,238,271} -{6,88,115,185,205,262} -{97,230} -{76,76,150,211,228,262} -{134,195} -{104,235} -{38,41,204} -{64,71,124} -{44,63,111,231} -{186,188} -{5,132,225} -{113,286} -{43,161,276} -{8,294} -{18,90,105,169} -{213,213} -{29,45,161,289} -{79,152} -{10,110,162,177,217,238} -{63,98,192,244} -{118,147,187,281} -{5,15,36,94,263} -{40,81,220} -{29,74,76,157,162,206} -{11,28,53,68,126,222} -{73,73,181,239} -{36,60,164} -{16,47,82,152,167,289} -{149,149,219,268,294} -{97,169} -{32,160,210,257} -{32,69} -{7,63,73,195} -{54,110} -{61,75,135,270} -{22,43,127,174,184,208} -{106,113,174} -{0,70,90,239} -{191,260} -{43,80,168} -{25,54,257,263} -{118,213} -{110,207,220,251,287} -{126,139,161,248,252} -{51,79,116,132,190,291} -{183,199,200,254} -{86,233} -{105,109,176,211} -{12,109} -{3,65,158} -{21,86} -{12,15,191} -{181,223,224,256,259,276} -{112,191,219,232,239} -{51,215} -{36,46,278} -{68,75,169,228,244,270} -{10,16,52,172,189,274} -{177,191,197,209,222,282} -{41,119,190,202} -{128,277,292,298} -{34,38} -{22,36,81,117} -{81,161,248,279} -{75,85,103,149,190,211} -{127,279} -{50,74,152} -{122,168,209,240,276,282} -{66,102,208,239,291} -{9,113} -{72,199,237} -{110,112,135,141,270} -{26,109,130,159,291} -{108,206} -{2,289} -{63,238} -{4,57,104,119,142,214} -{46,97,239} -{210,297} -{207,268} -{13,64,80} -{62,109,171,195,232} -{11,260,262,276,292} -{21,75,78,80,140,226} -{38,56} -{122,251,297} -{108,180,213} -{57,58,135,231,233} -{75,136,185,211} -{52,109,122,174,178,255} -{65,91,234,249} -{5,24,53,218} -{90,211,246} -{106,242,260} -{61,136} -{49,87,177,280} -{38,89,104,189,297} -{43,76,293,298} -{182,255,289} -{25,57,64,272} -{23,122,149} -{49,50,129,153} -{183,188,204} -{27,164,226,230} -{0,13,67,145,160,259} -{22,32,43,85,105,124} -{20,199} -{31,119} -{14,16,152,158,196} -{5,59,91,202,217,280} -{100,128,187} -{20,193,214,258,272} -{17,27,55,151,177,219} -{53,55,63,208,213,230} -{15,160,258,260} -{71,147,235,258} -{26,49,173,234,271} -{50,52,58,167,257} -{15,154,213,232} -{6,35,86,94,286} -{0,4,83,262,281} -{93,148,284} -{28,165,262,290} -{18,99,160,266} -{63,223,291,295} -{103,154,180} -{12,110,144,221} -{9,158,203} -{20,207,275} -{9,20,48,88,120,289} -{67,110,133,151,225,297} -{71,102} -{168,208} -{48,137,163,164,280,287} -{90,209} -{28,244} -{107,224,293} -{86,206} -{8,113,147,165,285,286} -{7,159,160,237} -{0,66,87,146,225,294} -{58,100,112,124,189} -{13,108} -{121,168,216,253} -{147,242,282} -{236,240} -{21,28,83,103,166} -{30,88,108,280,295} -{23,136,298} -{125,290} -{140,249,276,277} -{49,81,135,147,164,267} -{28,63,198,297} -{30,101,216,232,267,287} -{54,195,204,223,236,251} -{27,176,179,204,264,291} -{136,164,172,273} -{43,67,81,121,277} -{128,131,256,269} -{176,219,289} -{127,175,259} -{35,94,153,177,222,253} -{29,154,178,240,260} -{165,176,201,243,259} -{17,298} -{29,203,232,241,289} -{107,136,153,238} -{49,198} -{68,179,202,253} -{157,178} -{23,199,287} -{131,228} -{19,19,39,111,138,277} -{49,86,178,194,223,226} -{114,201} -{149,282} -{109,147,150,176,209,229} -{122,131,167,228,258} -{5,40,120,154,266} -{135,207,238,263} -{75,128} -{80,117,296} -{60,82,122,131,138} -{57,146,159,233,244,278} -{15,80,157,182,244,272} -{114,116,160,176,287} -{10,133,279} -{27,115,126,293} -{89,161} -{95,120,218} -{26,269} -{109,281} -{53,62,103,107,118,239} -{185,186,227,252} -{3,125,146,161,288} -{171,245,256,283} -{23,153,201,238} -{0,82,93,218,242} -{101,124,137,150,194} -{21,96,104,201,244,266} -{88,121,147,155,173,225} -{24,106,112,193} -{26,67,115,212,283} -{23,120,280} -{45,99} -{30,66,136,199} -{17,213} -{14,37,55,103,265} -{52,258,284} -{119,213,272,274,285} -{43,45,105,254,288} -{64,81,123,126,164,292} -{88,229,260} -{25,117} -{7,149,197,227,258} -{74,83,240,246,284,292} -{2,4,63,103,115,289} -{92,239} -{12,26,130,228,265} -{53,99,131,142,164,291} -{63,248,259,283} -{186,215,282} -{67,110,160} -{166,191} -{33,156,224} -{152,166,190,250,297} -{123,126,153,199,204} -{49,70,199,238,238,289} -{14,18,65,74,146,235} -{63,77,172,180,186,225} -{1,48,105,170} -{37,56,113,133,196} -{193,261,266} -{190,273} -{38,129,261} -{251,252,253,254,275,296} -{249,275} -{167,205,266} -{27,152,256} -{19,72,248} -{40,73,141,249} -{105,197} -{156,243,277,282} -{165,168,227,298} -{8,31,202,271} -{10,101,109,167,236,277} -{33,91,165,192,206,211} -{102,122,232} -{190,239,283} -{160,185} -{2,13,65,70} -{11,68,170,192,229,284} -{66,90,228,237} -{1,6,92,99,222,242} -{42,128,133,207,289} -{12,100,164,191} -{26,31,120,176,204,220} -{13,39,95,105,120,182} -{114,120,295} -{31,34,55,181,197,235} -{24,52,64,80,142} -{3,49,148,255,268} -{132,175,254} -{32,71,141} -{112,116,186,270,271} -{64,106,209,228,297} -{128,268} -{107,208,299} -{151,173,187,192,213} -{3,296} -{20,31,135,153,289} -{138,193,212,269,277,288} -{73,92,130,295} -{73,80,105} -{50,96,138,199,265} -{4,7,8,183,260,267} -{66,71,118,145} -{15,63,116,160,175,181} -{88,217} -{56,69,106,106,127,274} -{84,205} -{83,101,241,269} -{21,254} -{22,32,83,150,293} -{198,221} -{30,46,95,179,197} -{46,85,208} -{56,112,236} -{71,217} -{31,57,145,253} -{34,133,170} -{48,53,119,187,268,287} -{111,203,229,239} -{62,136} -{49,54,187,254,298} -{20,26,148,159,190,286} -{3,13,193,252,284} -{40,137,154,167,248,259} -{3,47,242,278} -{77,100,143,232} -{51,130} -{66,90,148,220,242,273} -{143,151,211} -{10,23} -{21,30,179} -{17,47,105,156,193,213} -{0,23,25,125,144,146} -{179,209} -{79,113,117,192} -{5,53,216,275,285} -{187,197} -{22,68,218,221} -{0,71,78,110,120,173} -{46,97,117,149,253,286} -{10,20,129,162,171,195} -{60,97,130,163,190} -{57,145,179,283} -{99,274} -{151,161,228,251} -{3,177,192,286} -{21,81,142} -{180,283} -{13,102,131,149,246} -{19,99,132,162,167,257} -{15,86,188,260} -{203,251,281} -{5,45,138,155,157} -{1,2,4,213,278} -{21,123,208,219,263,267} -{36,106,181,231,238} -{103,120,168,184,224,287} -{53,104,139,251} -{1,91,141,202,268} -{75,115,216,253} -{56,167,268,296} -{66,158,235,249} -{82,124,198} -{56,67,112,140,170,176} -{16,75,266} -{38,165,200,219,291,297} -{86,151,229,241,275} -{0,57,141,176,229,258} -{18,72,164,195,235} -{94,282} -{83,139,242,269,294} -{9,44,145,251,272} -{132,203,249,282} -{7,41,170,254} -{6,153,193,291} -{18,134,137,227,261} -{14,36,115,124,172,229} -{54,206} -{49,91,131,185,204} -{7,242} -{41,57,161} -{93,224,241,288} -{119,288} -{90,99,117,196,296} -{67,85,154} -{147,169,216,264} -{79,92,164} -{19,120,132,197,267} -{76,264} -{30,133} -{27,37,93,138,218} -{152,155,244} -{41,149,182,259} -{29,178,224} -{115,201,268} -{141,166,253,282} -{3,65,125,245,264} -{6,150,159,202,206,277} -{217,276} -{28,96,144,193} -{7,59,190} -{144,217} -{10,79,96,100,126,222} -{7,61,253} -{14,69,263} -{3,30,63,125,186,277} -{2,10,79,100,223} -{131,131,239} -{116,195,199,240} -{87,99,158} -{52,180} -{7,12,140,208,275} -{65,67,83,280} -{4,52,125,126,137,176} -{9,48,79,203,217,243} -{43,206,251} -{19,112,196,263,266} -{29,70,256} -{161,236,258} -{8,25,42,97,291} -{63,144,242,271} -{7,17} -{1,85,250} -{104,244,250} -{18,22,31,99,266,281} -{51,138,237,268,288} -{8,40,91,221,273} -{0,176,230,249,254,255} -{44,140,176,194,197} -{56,197,264} -{229,246,283} -{53,128,173,233,282} -{45,193,221} -{21,80,286} -{4,18,267} -{15,97,220} -{62,70,83,147,149,244} -{120,134,159,174,250} -{116,269} -{23,108} -{10,91,239} -{7,128,142,243,286} -{134,201,245,275,278} -{13,208,227,288} -{30,78,85} -{107,179} -{31,59,153,217,240,298} -{27,130,233,282,286} -{15,59,136,262} -{85,186,233} -{10,152,165,181,181} -{137,183} -{40,56,125,256,265,280} -{12,22,120,183} -{62,229} -{38,59,81,113,261} -{67,194,229} -{7,173} -{37,43,296} -{59,162,285} -{171,200,213,213} -{116,123,209,234,277} -{52,175} -{189,213} -{30,94,99,228,238} -{46,101,154,260,272,274} -{30,32,59} -{65,172,292} -{18,22,131,170,271} -{2,53,88,104,264,265} -{60,194,288} -{15,108,121,161,201} -{40,85,173,195,201,221} -{54,86,107,174,287} -{20,71,190,227} -{16,46,66,175,197,252} -{130,243,252,282} -{142,219,266,272} -{14,202,204,231,241,276} -{161,172,212,222} -{15,183,275} -{83,270} -{67,204} -{65,184,264} -{73,119,183,190,242} -{53,287} -{24,171} -{72,220,220} -{101,136,176,204,224,280} -{39,47,282} -{106,162,238,252} -{23,242,247,265} -{98,108,189,209,273} -{122,245,270} -{109,127,128,244,299} -{41,162,186,191} -{60,196} -{0,123,129,213,248} -{29,79,89,91} -{172,298} -{122,140,162,228,263,268} -{2,116,247,294} -{6,138} -{17,98,287} -{53,166,187,219,248,296} -{15,26,90,175,196} -{184,193,198} -{17,69,76,105,183,264} -{56,101,110} -{15,108,139,168,272} -{5,71,104,141} -{136,179} -{72,189} -{54,79,208} -{98,113,150,184,190,246} -{37,69,132,210,285} -{1,29,45,74,109,145} -{11,72,133,149,216} -{34,57,84,212,280} -{131,211,294} -{70,84,173} -{193,213,230,266,285,299} -{57,94,163,182,227} -{44,133,143} -{31,32,211} -{130,142,165,188,194,231} -{52,61,139,226,239,287} -{7,103,157} -{155,224,230} -{127,135,139} -{77,237,294} -{10,213,278} -{28,90,185,274} -{59,105,282,297} -{39,128,174,268} -{32,158,215} -{24,145,189,213,278} -{78,148,230,263} -{42,68,93,160,287,299} -{4,12,70,91,191,237} -{20,294} -{45,53,77,113,211,240} -{232,237} -{125,152,284} -{58,81,155,215,296} -{4,8,44} -{1,52,102,128,184,218} -{185,199,226,299} -{10,178,262,285} -{80,95,230,240,266} -{4,5,213} -{156,187,271,298} -{88,298} -{109,233,290} -{47,65,91,105,249,269} -{97,129} -{46,92,207} -{2,163,249,259,291} -{89,102,140,158,231} -{162,184,283} -{36,213} -{163,259} -{47,220,250} -{37,89,105,124,143,198} -{3,71} -{142,165,190,256,269,269} -{152,256} -{27,49,191,198,220,285} -{71,73,87,189,260} -{11,54,90,106,130,216} -{193,245,252} -{2,8,57,91,163,184} -{18,171,283} -{28,41,110,112} -{5,57} -{137,262,285} -{19,57,156,229,269} -{138,179,190,199,281} -{35,98,196,242} -{122,152} -{83,132,181,212,280,288} -{219,298} -{57,88,103} -{5,203} -{98,156,266} -{10,45,72,169,211} -{45,101,156,214,269} -{68,73,81} -{16,127,259} -{9,32,246} -{66,173,261,261,274} -{17,115,157,169,251} -{49,158} -{25,37} -{2,73,103,178,194,236} -{238,269,273} -{162,178,276} -{48,52,160,237,288} -{54,82,130,135,169,275} -{29,142} -{205,249,253,275,291} -{60,76,84,115,126} -{48,108,153,213,231} -{23,124,175,210,226,293} -{9,181} -{20,99,112,166,201,242} -{102,150,201} -{41,98,240,244,260} -{7,44,98,293} -{0,125,177,283} -{28,118,124,148,241,290} -{73,91,122} -{9,72,109,130,202,290} -{70,111,120,160,216,262} -{59,175,296} -{2,201} -{83,297} -{76,293} -{83,127,136,242,275,285} -{169,190,195} -{83,122,186,189,217,229} -{98,210,229} -{117,133} -{74,294} -{6,31,59,143,156,273} -{98,180,241} -{26,52,114,243} -{112,240} -{104,217} -{148,162,259,279} -{92,101,150,226,272,295} -{55,86,118,202,237,275} -{81,203} -{79,126,177,265} -{57,193} -{169,240,244} -{21,171,190,250,263} -{23,37,215,235} -{40,54,240,286} -{105,177,190,276,285} -{44,45,122,151} -{28,31,187} -{127,135,211} -{5,13,150,194,259} -{136,181,280} -{20,147,158,189,200} -{15,83,88,128,169} -{10,14,25,26,150,158} -{42,101,172,205} -{85,185,226,236,271} -{34,127,188,250,268} -{27,143} -{26,48,99,110,117,207} -{22,56,190,269,287} -{200,278} -{70,134,138,204,216,298} -{175,219,297} -{99,273} -{206,216} -{23,214} -{131,140} -{11,140,240} -{73,148} -{7,66,125,210} -{2,61,92} -{0,137} -{143,188,265} -{177,238} -{0,93,163,229} -{35,49} -{8,8,111,144,165} -{99,278} -{21,44,71,224,252,270} -{119,150,175,233,245,294} -{15,87} -{84,211,217,225} -{20,41,87,123,124,299} -{62,120,169} -{37,43,92,175,206,222} -{95,168,180,250,269,296} -{60,228,278,285} -{173,195,232,276} -{1,2,139,256,278} -{51,119} -{212,238,291} -{120,172,292} -{138,279} -{251,261} -{151,181,278,296} -{163,207,220,289,295} -{89,278,290} -{24,137,157,206,271,278} -{7,63,83,89,155,189} -{2,5,172,195,215,260} -{243,281} -{60,125} -{74,87,222,236} -{45,70,159,194} -{69,159,250} -{150,214,296} -{101,158,250} -{56,134} -{57,87,160,167,247,285} -{123,269} -{235,242} -{79,95,115,167,287} -{31,56,132,244,276} -{25,218,241,241} -{57,82,151,170,204} -{69,103,288} -{88,138,154,292} -{14,98,138,227,245,249} -{175,222,274} -{38,139,193,208,277} -{79,141} -{5,77,197,209} -{15,37,77,110,116} -{26,226} -{68,93,101,140,233} -{53,96,170,192,290} -{29,89,102,216,220} -{11,85,136,239} -{158,180,195,200,226} -{10,49,118,137,172} -{144,172,183} -{14,176,188,215,272} -{42,97,125} -{114,166} -{52,61,162,171,249} -{140,195,242} -{59,99,233} -{31,76,136,181,187} -{81,112,157,168,271,294} -{8,35,44,48,190,297} -{145,195,201} -{160,248,291} -{94,270,285} -{116,139,225} -{111,131,140} -{158,277} -{59,229,257} -{25,47,99,123,239} -{8,36,205,274,295} -{132,152,178,192,235} -{19,40,96,204} -{7,77} -{211,282} -{26,100,180,244,281,296} -{200,212,286} -{5,94,151,290} -{75,80,128,179,269,269} -{7,111} -{7,26,69,158,269,276} -{7,36,74,94,171,215} -{2,62,65,93,124,271} -{78,96,109,189} -{182,197,280,298} -{17,78,82,85,85,208} -{6,122,155} -{14,33,130} -{1,21,167,169} -{49,85,158,175,213} -{59,194} -{125,132,259,285} -{20,38,81,89,234,274} -{106,140,156,287} -{57,125} -{53,103,158,204,234,267} -{0,49,160,189,235} -{34,115,142,207} -{162,173,181,190,298} -{11,76,116,166,191} -{2,87,99,236,279} -{40,203} -{2,33,39,215,254} -{53,69,83,224,228} -{79,136,183,216,226,227} -{10,109,137,163,240} -{24,126,141} -{69,255} -{103,138,230,246,259,283} -{136,290} -{13,34,78,145,166,242} -{38,74,83,242,294} -{54,248,273} -{107,162} -{50,170,176,191,207,275} -{32,134,166,288,292} -{163,167,186,274,291,296} -{31,86,123,156,160} -{114,133,136,176,281,290} -{105,147,211} -{124,151,179,222,299} -{87,101} -{145,169,181,205,247} -{6,266} -{26,33,52,56,106,116} -{19,21,65,89,104,168} -{164,181,208} -{36,67,92,116,248} -{145,200,247} -{155,215} -{49,212} -{29,57,105,117,131} -{2,13,68,128,139,140} -{193,273,273} -{3,78,105,111,297} -{49,142,244} -{32,259} -{161,205} -{96,146,179,259} -{44,45,211,233} -{56,91,146,166,285} -{87,107,120,262,299} -{76,160,276,297} -{248,266} -{5,12,188,240,247} -{164,206,293} -{15,18,60,163} -{53,134,172,230,287,290} -{117,137,146,153,155} -{72,270} -{171,251} -{80,125,137,141,169} -{52,108,200,219,225,271} -{29,78,106,221} -{21,74,110,273} -{28,88,98,170} -{83,104} -{12,152} -{7,69,143,246,265,269} -{62,106,157,200} -{113,260,272,272,294} -{16,35,80,121,165,176} -{96,154,172,198,263} -{29,53,109,128,129,195} -{131,230,271,273,295,299} -{53,160,208,231} -{23,180,208,249,272} -{45,208,264} -{14,29,169} -{116,147,272} -{7,193,237,271} -{158,198,253} -{41,60,71} -{110,133,200,249} -{24,159,255} -{26,39,61,114,218,229} -{141,286,299} -{74,278} -{67,71,155} -{151,257,284} -{13,28,72,131,206} -{60,152,275,295} -{88,105,184,185} -{85,190,205,256,283,285} -{202,285} -{14,92,160,200,246,279} -{42,95,157,195} -{50,99,224,276} -{32,97,101,122} -{66,85} -{19,146,180,242,269,286} -{24,86,247,274} -{54,264,270,284} -{72,77,85,124,127,285} -{47,249} -{25,73,102,237} -{33,68,84,117,120} -{29,62,172,240,242,273} -{42,140,182,248,261,282} -{118,228,284} -{1,89,158,294} -{29,89,122,155,208,283} -{173,208,229} -{6,22,142,267,299} -{22,122,173,245,293} diff --git a/contrib/intarray/expected/_int.out b/contrib/intarray/expected/_int.out deleted file mode 100644 index d1b440f5a9..0000000000 --- a/contrib/intarray/expected/_int.out +++ /dev/null @@ -1,377 +0,0 @@ --- --- first, define the datatype. Turn off echoing so that expected file --- does not depend on contents of seg.sql. --- -\set ECHO none ---test query_int -select '1'::query_int; - query_int ------------ - 1 -(1 row) - -select ' 1'::query_int; - query_int ------------ - 1 -(1 row) - -select '1 '::query_int; - query_int ------------ - 1 -(1 row) - -select ' 1 '::query_int; - query_int ------------ - 1 -(1 row) - -select ' ! 1 '::query_int; - query_int ------------ - !1 -(1 row) - -select '!1'::query_int; - query_int ------------ - !1 -(1 row) - -select '1|2'::query_int; - query_int ------------ - 1 | 2 -(1 row) - -select '1|!2'::query_int; - query_int ------------ - 1 | !2 -(1 row) - -select '!1|2'::query_int; - query_int ------------ - !1 | 2 -(1 row) - -select '!1|!2'::query_int; - query_int ------------ - !1 | !2 -(1 row) - -select '!(!1|!2)'::query_int; - query_int --------------- - !( !1 | !2 ) -(1 row) - -select '!(!1|2)'::query_int; - query_int -------------- - !( !1 | 2 ) -(1 row) - -select '!(1|!2)'::query_int; - query_int -------------- - !( 1 | !2 ) -(1 row) - -select '!(1|2)'::query_int; - query_int ------------- - !( 1 | 2 ) -(1 row) - -select '1&2'::query_int; - query_int ------------ - 1 & 2 -(1 row) - -select '!1&2'::query_int; - query_int ------------ - !1 & 2 -(1 row) - -select '1&!2'::query_int; - query_int ------------ - 1 & !2 -(1 row) - -select '!1&!2'::query_int; - query_int ------------ - !1 & !2 -(1 row) - -select '(1&2)'::query_int; - query_int ------------ - 1 & 2 -(1 row) - -select '1&(2)'::query_int; - query_int ------------ - 1 & 2 -(1 row) - -select '!(1)&2'::query_int; - query_int ------------ - !1 & 2 -(1 row) - -select '!(1&2)'::query_int; - query_int ------------- - !( 1 & 2 ) -(1 row) - -select '1|2&3'::query_int; - query_int ------------ - 1 | 2 & 3 -(1 row) - -select '1|(2&3)'::query_int; - query_int ------------ - 1 | 2 & 3 -(1 row) - -select '(1|2)&3'::query_int; - query_int ---------------- - ( 1 | 2 ) & 3 -(1 row) - -select '1|2&!3'::query_int; - query_int ------------- - 1 | 2 & !3 -(1 row) - -select '1|!2&3'::query_int; - query_int ------------- - 1 | !2 & 3 -(1 row) - -select '!1|2&3'::query_int; - query_int ------------- - !1 | 2 & 3 -(1 row) - -select '!1|(2&3)'::query_int; - query_int ------------- - !1 | 2 & 3 -(1 row) - -select '!(1|2)&3'::query_int; - query_int ----------------- - !( 1 | 2 ) & 3 -(1 row) - -select '(!1|2)&3'::query_int; - query_int ----------------- - ( !1 | 2 ) & 3 -(1 row) - -select '1|(2|(4|(5|6)))'::query_int; - query_int -------------------------------- - 1 | ( 2 | ( 4 | ( 5 | 6 ) ) ) -(1 row) - -select '1|2|4|5|6'::query_int; - query_int -------------------------------- - ( ( ( 1 | 2 ) | 4 ) | 5 ) | 6 -(1 row) - -select '1&(2&(4&(5&6)))'::query_int; - query_int -------------------- - 1 & 2 & 4 & 5 & 6 -(1 row) - -select '1&2&4&5&6'::query_int; - query_int -------------------- - 1 & 2 & 4 & 5 & 6 -(1 row) - -select '1&(2&(4&(5|6)))'::query_int; - query_int ------------------------ - 1 & 2 & 4 & ( 5 | 6 ) -(1 row) - -select '1&(2&(4&(5|!6)))'::query_int; - query_int ------------------------- - 1 & 2 & 4 & ( 5 | !6 ) -(1 row) - -CREATE TABLE test__int( a int[] ); -\copy test__int from 'data/test__int.data' -SELECT count(*) from test__int WHERE a && '{23,50}'; - count -------- - 403 -(1 row) - -SELECT count(*) from test__int WHERE a @@ '23|50'; - count -------- - 403 -(1 row) - -SELECT count(*) from test__int WHERE a @ '{23,50}'; - count -------- - 12 -(1 row) - -SELECT count(*) from test__int WHERE a @@ '23&50'; - count -------- - 12 -(1 row) - -SELECT count(*) from test__int WHERE a @ '{20,23}'; - count -------- - 12 -(1 row) - -SELECT count(*) from test__int WHERE a @@ '50&68'; - count -------- - 9 -(1 row) - -SELECT count(*) from test__int WHERE a @ '{20,23}' or a @ '{50,68}'; - count -------- - 21 -(1 row) - -SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)'; - count -------- - 21 -(1 row) - -CREATE INDEX text_idx on test__int using gist ( a gist__int_ops ); -SELECT count(*) from test__int WHERE a && '{23,50}'; - count -------- - 403 -(1 row) - -SELECT count(*) from test__int WHERE a @@ '23|50'; - count -------- - 403 -(1 row) - -SELECT count(*) from test__int WHERE a @ '{23,50}'; - count -------- - 12 -(1 row) - -SELECT count(*) from test__int WHERE a @@ '23&50'; - count -------- - 12 -(1 row) - -SELECT count(*) from test__int WHERE a @ '{20,23}'; - count -------- - 12 -(1 row) - -SELECT count(*) from test__int WHERE a @@ '50&68'; - count -------- - 9 -(1 row) - -SELECT count(*) from test__int WHERE a @ '{20,23}' or a @ '{50,68}'; - count -------- - 21 -(1 row) - -SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)'; - count -------- - 21 -(1 row) - -drop index text_idx; -CREATE INDEX text_idx on test__int using gist ( a gist__intbig_ops ); -SELECT count(*) from test__int WHERE a && '{23,50}'; - count -------- - 403 -(1 row) - -SELECT count(*) from test__int WHERE a @@ '23|50'; - count -------- - 403 -(1 row) - -SELECT count(*) from test__int WHERE a @ '{23,50}'; - count -------- - 12 -(1 row) - -SELECT count(*) from test__int WHERE a @@ '23&50'; - count -------- - 12 -(1 row) - -SELECT count(*) from test__int WHERE a @ '{20,23}'; - count -------- - 12 -(1 row) - -SELECT count(*) from test__int WHERE a @@ '50&68'; - count -------- - 9 -(1 row) - -SELECT count(*) from test__int WHERE a @ '{20,23}' or a @ '{50,68}'; - count -------- - 21 -(1 row) - -SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)'; - count -------- - 21 -(1 row) - diff --git a/contrib/intarray/sql/_int.sql b/contrib/intarray/sql/_int.sql deleted file mode 100644 index 52313ef7a1..0000000000 --- a/contrib/intarray/sql/_int.sql +++ /dev/null @@ -1,84 +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 _int.sql -\set ECHO all - ---test query_int -select '1'::query_int; -select ' 1'::query_int; -select '1 '::query_int; -select ' 1 '::query_int; -select ' ! 1 '::query_int; -select '!1'::query_int; -select '1|2'::query_int; -select '1|!2'::query_int; -select '!1|2'::query_int; -select '!1|!2'::query_int; -select '!(!1|!2)'::query_int; -select '!(!1|2)'::query_int; -select '!(1|!2)'::query_int; -select '!(1|2)'::query_int; -select '1&2'::query_int; -select '!1&2'::query_int; -select '1&!2'::query_int; -select '!1&!2'::query_int; -select '(1&2)'::query_int; -select '1&(2)'::query_int; -select '!(1)&2'::query_int; -select '!(1&2)'::query_int; -select '1|2&3'::query_int; -select '1|(2&3)'::query_int; -select '(1|2)&3'::query_int; -select '1|2&!3'::query_int; -select '1|!2&3'::query_int; -select '!1|2&3'::query_int; -select '!1|(2&3)'::query_int; -select '!(1|2)&3'::query_int; -select '(!1|2)&3'::query_int; -select '1|(2|(4|(5|6)))'::query_int; -select '1|2|4|5|6'::query_int; -select '1&(2&(4&(5&6)))'::query_int; -select '1&2&4&5&6'::query_int; -select '1&(2&(4&(5|6)))'::query_int; -select '1&(2&(4&(5|!6)))'::query_int; - - -CREATE TABLE test__int( a int[] ); - -\copy test__int from 'data/test__int.data' - -SELECT count(*) from test__int WHERE a && '{23,50}'; -SELECT count(*) from test__int WHERE a @@ '23|50'; -SELECT count(*) from test__int WHERE a @ '{23,50}'; -SELECT count(*) from test__int WHERE a @@ '23&50'; -SELECT count(*) from test__int WHERE a @ '{20,23}'; -SELECT count(*) from test__int WHERE a @@ '50&68'; -SELECT count(*) from test__int WHERE a @ '{20,23}' or a @ '{50,68}'; -SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)'; - -CREATE INDEX text_idx on test__int using gist ( a gist__int_ops ); - -SELECT count(*) from test__int WHERE a && '{23,50}'; -SELECT count(*) from test__int WHERE a @@ '23|50'; -SELECT count(*) from test__int WHERE a @ '{23,50}'; -SELECT count(*) from test__int WHERE a @@ '23&50'; -SELECT count(*) from test__int WHERE a @ '{20,23}'; -SELECT count(*) from test__int WHERE a @@ '50&68'; -SELECT count(*) from test__int WHERE a @ '{20,23}' or a @ '{50,68}'; -SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)'; - -drop index text_idx; -CREATE INDEX text_idx on test__int using gist ( a gist__intbig_ops ); - -SELECT count(*) from test__int WHERE a && '{23,50}'; -SELECT count(*) from test__int WHERE a @@ '23|50'; -SELECT count(*) from test__int WHERE a @ '{23,50}'; -SELECT count(*) from test__int WHERE a @@ '23&50'; -SELECT count(*) from test__int WHERE a @ '{20,23}'; -SELECT count(*) from test__int WHERE a @@ '50&68'; -SELECT count(*) from test__int WHERE a @ '{20,23}' or a @ '{50,68}'; -SELECT count(*) from test__int WHERE a @@ '(20&23)|(50&68)'; - diff --git a/contrib/ipc_check/README b/contrib/ipc_check/README deleted file mode 100644 index 392902b0d1..0000000000 --- a/contrib/ipc_check/README +++ /dev/null @@ -1,22 +0,0 @@ - -This simple perl script was designed under FreeBSD, and, right now, is -limited to it. It provides a simple way of determining and directing -administrators in what has to be done to get IPC working, and configured. - -Usage: - -ipc_check.pl - - - simply checks for semaphores and shared memory being enabled - - if one or other is not enabled, appropriate "options" are provided - to get it compiled into the kernel - -ipc_check.pl -B <# of buffers> - - - checks to see if there are sufficient shared memory buffers to - run the postmaster with a -B option as provided - - if insufficient buffers are provided, appropriate 'sysctl' commands, - and instructions, are provided to the administrator to increase - them - - diff --git a/contrib/ipc_check/ipc_check.pl b/contrib/ipc_check/ipc_check.pl deleted file mode 100644 index cc65294718..0000000000 --- a/contrib/ipc_check/ipc_check.pl +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/perl - -# Notes ... -B 1 == 8k - -if(@ARGV > 1) { - if($ARGV[0] eq "-B") { - $buffers = $ARGV[1]; - } -} - -if($buffers > 0) { - $kb_memory_required = $buffers * 8; -} - -$shm = `sysctl kern.ipc | grep shmall`; -( $junk, $shm_amt ) = split(/ /, $shm); -chomp($shm_amt); -$sem = `sysctl kern.ipc | grep semmap`; - -print "\n\n"; -if(length($shm) > 0) { - printf "shared memory enabled: %d kB available\n", $shm_amt * 4; - if($buffers > 0) { - if($kb_memory_required / 4 > $shm_amt) { - print "\n"; - print "to provide enough shared memory for a \"-B $buffers\" setting\n"; - print "issue the following command\n\n"; - printf "\tsysctl -w kern.ipc.shmall=%d\n", $kb_memory_required / 4; - print "\nand add the following to your /etc/sysctl.conf file:\n\n"; - printf "\tkern.ipc.shmall=%d\n", $kb_memory_required / 4; - } else { - print "\n"; - print "no changes to kernel required for a \"-B $buffers\" setting\n"; - } - } -} else { - print "no shared memory support available\n"; - print "add the following option to your kernel config:\n\n"; - print "\toptions SYSVSHM\n\n"; -} - -print "\n==========================\n\n"; -if(length($sem) > 0) { - print "semaphores enabled\n"; -} else { - print "no semaphore support available\n"; - print "add the following option to your kernel config:\n\n"; - print "\toptions SYSVSEM\n\n"; -} - - diff --git a/contrib/isbn_issn/Makefile b/contrib/isbn_issn/Makefile deleted file mode 100644 index 3310f40944..0000000000 --- a/contrib/isbn_issn/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/isbn_issn/Attic/Makefile,v 1.11 2001/09/06 10:49:29 petere Exp $ - -subdir = contrib/isbn_issn -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -MODULES = isbn_issn -DATA_built = isbn_issn.sql -DOCS = README.isbn_issn - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/isbn_issn/README.isbn_issn b/contrib/isbn_issn/README.isbn_issn deleted file mode 100644 index 6b734ce905..0000000000 --- a/contrib/isbn_issn/README.isbn_issn +++ /dev/null @@ -1,22 +0,0 @@ - -ISBN (books) and ISSN (serials) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This directory contains definitions for a couple of PostgreSQL -external types, for a couple of international-standard namespaces: -ISBN (books) and ISSN (serials). Rather than just using a char() -member of the appropriate length, I wanted my database to include -the validity-checking that both these numbering systems were designed -to encompass. A little bit of research revealed the formulae -for computing the check digits, and I also included some validity -constraints on the number of hyphens. - -The internal representation of these types is intended to be -compatible with `char16', in the (perhaps vain) hope that -this will make it possible to create indices of these types -using char16_ops. - -These are based on Tom Ivar Helbekkmo's IP address type definition, -from which I have copied the entire form of the implementation. - -Garrett A. Wollman, August 1998 diff --git a/contrib/isbn_issn/isbn_issn.c b/contrib/isbn_issn/isbn_issn.c deleted file mode 100644 index 70115ceab2..0000000000 --- a/contrib/isbn_issn/isbn_issn.c +++ /dev/null @@ -1,376 +0,0 @@ -/* - * PostgreSQL type definitions for ISBNs. - * - * $Id: isbn_issn.c,v 1.4 2001/11/05 17:46:23 momjian Exp $ - */ - -#include "postgres.h" - - -/* - * This is the internal storage format for ISBNs. - * NB: This is an intentional type pun with builtin type `char16'. - */ - -typedef struct isbn -{ - char num[13]; - char pad[3]; -} isbn; - -/* - * Various forward declarations: - */ - -isbn *isbn_in(char *str); -char *isbn_out(isbn * addr); - -bool isbn_lt(isbn * a1, isbn * a2); -bool isbn_le(isbn * a1, isbn * a2); -bool isbn_eq(isbn * a1, isbn * a2); -bool isbn_ge(isbn * a1, isbn * a2); -bool isbn_gt(isbn * a1, isbn * a2); - -bool isbn_ne(isbn * a1, isbn * a2); - -int4 isbn_cmp(isbn * a1, isbn * a2); - -int4 isbn_sum(char *str); - -/* - * ISBN reader. - */ - -isbn * -isbn_in(char *str) -{ - isbn *result; - - if (strlen(str) != 13) - { - elog(ERROR, "isbn_in: invalid ISBN \"%s\"", str); - return (NULL); - } - if (isbn_sum(str) != 0) - { - elog(ERROR, "isbn_in: purported ISBN \"%s\" failed checksum", - str); - return (NULL); - } - - result = (isbn *) palloc(sizeof(isbn)); - - strncpy(result->num, str, 13); - memset(result->pad, ' ', 3); - return (result); -} - -/* - * The ISBN checksum is defined as follows: - * - * Number the digits from 1 to 9 (call this N). - * Compute the sum, S, of N * D_N. - * The check digit, C, is the value which satisfies the equation - * S + 10*C === 0 (mod 11) - * The value 10 for C is written as `X'. - * - * For our purposes, we want the complete sum including the check - * digit; if this is zero, then the checksum passed. We also check - * the syntactic validity if the provided string, and return 12 - * if any errors are found. - */ -int4 -isbn_sum(char *str) -{ - int4 sum = 0, - dashes = 0, - val; - int i; - - for (i = 0; str[i] && i < 13; i++) - { - switch (str[i]) - { - case '-': - if (++dashes > 3) - return 12; - continue; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - val = str[i] - '0'; - break; - - case 'X': - case 'x': - val = 10; - break; - - default: - return 12; - } - - sum += val * (i + 1 - dashes); - } - return (sum % 11); -} - -/* - * ISBN output function. - */ - -char * -isbn_out(isbn * num) -{ - char *result; - - if (num == NULL) - return (NULL); - - result = (char *) palloc(14); - - result[0] = '\0'; - strncat(result, num->num, 13); - return (result); -} - -/* - * Boolean tests for magnitude. - */ - -bool -isbn_lt(isbn * a1, isbn * a2) -{ - return (strncmp(a1->num, a2->num, 13) < 0); -}; - -bool -isbn_le(isbn * a1, isbn * a2) -{ - return (strncmp(a1->num, a2->num, 13) <= 0); -}; - -bool -isbn_eq(isbn * a1, isbn * a2) -{ - return (strncmp(a1->num, a2->num, 13) == 0); -}; - -bool -isbn_ge(isbn * a1, isbn * a2) -{ - return (strncmp(a1->num, a2->num, 13) >= 0); -}; - -bool -isbn_gt(isbn * a1, isbn * a2) -{ - return (strncmp(a1->num, a2->num, 13) > 0); -}; - -bool -isbn_ne(isbn * a1, isbn * a2) -{ - return (strncmp(a1->num, a2->num, 13) != 0); -}; - -/* - * Comparison function for sorting: - */ - -int4 -isbn_cmp(isbn * a1, isbn * a2) -{ - return (strncmp(a1->num, a2->num, 13)); -} - - -/* ----------------------------- ISSN --------------------------- */ - -/* - * This is the internal storage format for ISSNs. - * NB: This is an intentional type pun with builtin type `char16'. - */ - -typedef struct issn -{ - char num[9]; - char pad[7]; -} issn; - -/* - * Various forward declarations: - */ - -issn *issn_in(char *str); -char *issn_out(issn * addr); - -bool issn_lt(issn * a1, issn * a2); -bool issn_le(issn * a1, issn * a2); -bool issn_eq(issn * a1, issn * a2); -bool issn_ge(issn * a1, issn * a2); -bool issn_gt(issn * a1, issn * a2); - -bool issn_ne(issn * a1, issn * a2); - -int4 issn_cmp(issn * a1, issn * a2); - -int4 issn_sum(char *str); - -/* - * ISSN reader. - */ - -issn * -issn_in(char *str) -{ - issn *result; - - if (strlen(str) != 9) - { - elog(ERROR, "issn_in: invalid ISSN \"%s\"", str); - return (NULL); - } - if (issn_sum(str) != 0) - { - elog(ERROR, "issn_in: purported ISSN \"%s\" failed checksum", - str); - return (NULL); - } - - result = (issn *) palloc(sizeof(issn)); - - strncpy(result->num, str, 9); - memset(result->pad, ' ', 7); - return (result); -} - -/* - * The ISSN checksum works just like the ISBN sum, only different - * (of course!). - * Here, the weights start at 8 and decrease. - */ -int4 -issn_sum(char *str) -{ - int4 sum = 0, - dashes = 0, - val; - int i; - - for (i = 0; str[i] && i < 9; i++) - { - switch (str[i]) - { - case '-': - if (++dashes > 1) - return 12; - continue; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - val = str[i] - '0'; - break; - - case 'X': - case 'x': - val = 10; - break; - - default: - return 12; - } - - sum += val * (8 - (i - dashes)); - } - return (sum % 11); -} - -/* - * ISSN output function. - */ - -char * -issn_out(issn * num) -{ - char *result; - - if (num == NULL) - return (NULL); - - result = (char *) palloc(14); - - result[0] = '\0'; - strncat(result, num->num, 9); - return (result); -} - -/* - * Boolean tests for magnitude. - */ - -bool -issn_lt(issn * a1, issn * a2) -{ - return (strncmp(a1->num, a2->num, 9) < 0); -}; - -bool -issn_le(issn * a1, issn * a2) -{ - return (strncmp(a1->num, a2->num, 9) <= 0); -}; - -bool -issn_eq(issn * a1, issn * a2) -{ - return (strncmp(a1->num, a2->num, 9) == 0); -}; - -bool -issn_ge(issn * a1, issn * a2) -{ - return (strncmp(a1->num, a2->num, 9) >= 0); -}; - -bool -issn_gt(issn * a1, issn * a2) -{ - return (strncmp(a1->num, a2->num, 9) > 0); -}; - -bool -issn_ne(issn * a1, issn * a2) -{ - return (strncmp(a1->num, a2->num, 9) != 0); -}; - -/* - * Comparison function for sorting: - */ - -int4 -issn_cmp(issn * a1, issn * a2) -{ - return (strncmp(a1->num, a2->num, 9)); -} - -/* - * eof - */ diff --git a/contrib/isbn_issn/isbn_issn.sql.in b/contrib/isbn_issn/isbn_issn.sql.in deleted file mode 100644 index f837fad378..0000000000 --- a/contrib/isbn_issn/isbn_issn.sql.in +++ /dev/null @@ -1,228 +0,0 @@ --- --- PostgreSQL code for ISSNs. --- --- $Id: isbn_issn.sql.in,v 1.2 2000/06/19 13:53:39 momjian Exp $ --- - - --- --- Input and output functions and the type itself: --- - -create function issn_in(opaque) - returns opaque - as 'MODULE_PATHNAME' - language 'c'; - -create function issn_out(opaque) - returns opaque - as 'MODULE_PATHNAME' - language 'c'; - -create type issn ( - internallength = 16, - externallength = 9, - input = issn_in, - output = issn_out -); - --- --- The various boolean tests: --- - -create function issn_lt(issn, issn) - returns bool - as 'MODULE_PATHNAME' - language 'c'; - -create function issn_le(issn, issn) - returns bool - as 'MODULE_PATHNAME' - language 'c'; - -create function issn_eq(issn, issn) - returns bool - as 'MODULE_PATHNAME' - language 'c'; - -create function issn_ge(issn, issn) - returns bool - as 'MODULE_PATHNAME' - language 'c'; - -create function issn_gt(issn, issn) - returns bool - as 'MODULE_PATHNAME' - language 'c'; - -create function issn_ne(issn, issn) - returns bool - as 'MODULE_PATHNAME' - language 'c'; - --- --- Now the operators. Note how some of the parameters to some --- of the 'create operator' commands are commented out. This --- is because they reference as yet undefined operators, and --- will be implicitly defined when those are, further down. --- - -create operator < ( - leftarg = issn, - rightarg = issn, --- negator = >=, - procedure = issn_lt -); - -create operator <= ( - leftarg = issn, - rightarg = issn, --- negator = >, - procedure = issn_le -); - -create operator = ( - leftarg = issn, - rightarg = issn, - commutator = =, --- negator = <>, - procedure = issn_eq -); - -create operator >= ( - leftarg = issn, - rightarg = issn, - negator = <, - procedure = issn_ge -); - -create operator > ( - leftarg = issn, - rightarg = issn, - negator = <=, - procedure = issn_gt -); - -create operator <> ( - leftarg = issn, - rightarg = issn, - negator = =, - procedure = issn_ne -); - --- --- eof --- --- --- PostgreSQL code for ISBNs. --- --- $Id: isbn_issn.sql.in,v 1.2 2000/06/19 13:53:39 momjian Exp $ --- --- --- Input and output functions and the type itself: --- - -create function isbn_in(opaque) - returns opaque - as 'MODULE_PATHNAME' - language 'c'; - -create function isbn_out(opaque) - returns opaque - as 'MODULE_PATHNAME' - language 'c'; - -create type isbn ( - internallength = 16, - externallength = 13, - input = isbn_in, - output = isbn_out -); - --- --- The various boolean tests: --- - -create function isbn_lt(isbn, isbn) - returns bool - as 'MODULE_PATHNAME' - language 'c'; - -create function isbn_le(isbn, isbn) - returns bool - as 'MODULE_PATHNAME' - language 'c'; - -create function isbn_eq(isbn, isbn) - returns bool - as 'MODULE_PATHNAME' - language 'c'; - -create function isbn_ge(isbn, isbn) - returns bool - as 'MODULE_PATHNAME' - language 'c'; - -create function isbn_gt(isbn, isbn) - returns bool - as 'MODULE_PATHNAME' - language 'c'; - -create function isbn_ne(isbn, isbn) - returns bool - as 'MODULE_PATHNAME' - language 'c'; - --- --- Now the operators. Note how some of the parameters to some --- of the 'create operator' commands are commented out. This --- is because they reference as yet undefined operators, and --- will be implicitly defined when those are, further down. --- - -create operator < ( - leftarg = isbn, - rightarg = isbn, --- negator = >=, - procedure = isbn_lt -); - -create operator <= ( - leftarg = isbn, - rightarg = isbn, --- negator = >, - procedure = isbn_le -); - -create operator = ( - leftarg = isbn, - rightarg = isbn, - commutator = =, --- negator = <>, - procedure = isbn_eq -); - -create operator >= ( - leftarg = isbn, - rightarg = isbn, - negator = <, - procedure = isbn_ge -); - -create operator > ( - leftarg = isbn, - rightarg = isbn, - negator = <=, - procedure = isbn_gt -); - -create operator <> ( - leftarg = isbn, - rightarg = isbn, - negator = =, - procedure = isbn_ne -); - --- --- eof --- diff --git a/contrib/lo/Makefile b/contrib/lo/Makefile deleted file mode 100644 index 5743c0d4f5..0000000000 --- a/contrib/lo/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/lo/Makefile,v 1.11 2001/09/06 10:49:29 petere Exp $ - -subdir = contrib/lo -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -MODULES = lo -DATA_built = lo.sql -DATA = lo_drop.sql lo_test.sql -DOCS = README.lo - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/lo/README.lo b/contrib/lo/README.lo deleted file mode 100644 index aa06adf084..0000000000 --- a/contrib/lo/README.lo +++ /dev/null @@ -1,69 +0,0 @@ -PostgreSQL type extension for managing Large Objects ----------------------------------------------------- - -Overview - -One of the problems with the JDBC driver (and this affects the ODBC driver -also), is that the specification assumes that references to BLOBS (Binary -Large OBjectS) are stored within a table, and if that entry is changed, the -associated BLOB is deleted from the database. - -As PostgreSQL stands, this doesn't occur. It allocates an OID for each object, -and it is up to the application to store, and ultimately delete the objects. - -Now this is fine for new postgresql specific applications, but existing ones -using JDBC or ODBC wont delete the objects, arising to orphaning - objects -that are not referenced by anything, and simply occupy disk space. - -The Fix - -I've fixed this by creating a new data type 'lo', some support functions, and -a Trigger which handles the orphaning problem. - -The 'lo' type was created because we needed to differenciate between normal -Oid's and Large Objects. Currently the JDBC driver handles this dilema easily, -but (after talking to Byron), the ODBC driver needed a unique type. They had created an 'lo' type, but not the solution to orphaning. - -Install - -Ok, first build the shared library, and install. Typing 'make install' in the -contrib/lo directory should do it. - -Then, as the postgres super user, run the lo.sql script. This will install the -type, and define the support functions. - -How to Use - -The easiest way is by an example: - -> create table image (title text,raster lo); -> create trigger t_image before update or delete on image for each row execute procedure lo_manage(raster); - -Here, a trigger is created for each column that contains a lo type. - -Issues - -* dropping a table will still orphan any objects it contains, as the trigger - is not actioned. - - For now, precede the 'drop table' with 'delete from {table}'. However, this - could be fixed by having 'drop table' perform an additional - - 'select lo_unlink({colname}::oid) from {tablename}' - - for each column, before actually dropping the table. - -* Some frontends may create their own tables, and will not create the - associated trigger(s). Also, users may not remember (or know) to create - the triggers. - - This can be solved, but would involve changes to the parser. - -As the ODBC driver needs a permanent lo type (& JDBC could be optimised to -use it if it's Oid is fixed), and as the above issues can only be fixed by -some internal changes, I feel it should become a permanent built-in type. - -I'm releasing this into contrib, just to get it out, and tested. - -Peter Mount June 13 1998 - diff --git a/contrib/lo/lo.c b/contrib/lo/lo.c deleted file mode 100644 index 8215c4cbbc..0000000000 --- a/contrib/lo/lo.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * PostgreSQL type definitions for managed LargeObjects. - * - * $Header: /cvsroot/pgsql/contrib/lo/lo.c,v 1.11 2001/12/07 04:18:31 inoue Exp $ - * - */ - -#include "postgres.h" - -/* Required for largeobjects */ -#include "libpq/libpq-fs.h" -#include "libpq/be-fsstubs.h" - -/* Required for SPI */ -#include "executor/spi.h" - -/* Required for triggers */ -#include "commands/trigger.h" - - -#define atooid(x) ((Oid) strtoul((x), NULL, 10)) - - -/* - * This is the internal storage format for managed large objects - * - */ - -typedef Oid Blob; - -/* - * Various forward declarations: - */ - -Blob *lo_in(char *str); /* Create from String */ -char *lo_out(Blob * addr); /* Output oid as String */ -Oid lo_oid(Blob * addr); /* Return oid as an oid */ -Blob *lo(Oid oid); /* Return Blob based on oid */ -Datum lo_manage(PG_FUNCTION_ARGS); /* Trigger handler */ - -/* - * This creates a large object, and sets its OID to the value in the - * supplied string. - * - * If the string is empty, then a new LargeObject is created, and its oid - * is placed in the resulting lo. - */ -Blob * -lo_in(char *str) -{ - Blob *result; - Oid oid; - int count; - - if (strlen(str) > 0) - { - count = sscanf(str, "%u", &oid); - - if (count < 1) - elog(ERROR, "lo_in: error in parsing \"%s\"", str); - - if (oid == InvalidOid) - elog(ERROR, "lo_in: illegal oid \"%s\"", str); - } - else - { - /* - * There is no Oid passed, so create a new one - */ - oid = DatumGetObjectId(DirectFunctionCall1(lo_creat, - Int32GetDatum(INV_READ | INV_WRITE))); - if (oid == InvalidOid) - elog(ERROR, "lo_in: InvalidOid returned from lo_creat"); - } - - result = (Blob *) palloc(sizeof(Blob)); - - *result = oid; - - return (result); -} - -/* - * This simply outputs the Oid of the Blob as a string. - */ -char * -lo_out(Blob * addr) -{ - char *result; - - if (addr == NULL) - return (NULL); - - result = (char *) palloc(32); - sprintf(result, "%u", *addr); - return (result); -} - -/* - * This function converts Blob to oid. - * - * eg: select lo_export(raster::oid,'/path/file') from table; - * - */ -Oid -lo_oid(Blob * addr) -{ - if (addr == NULL) - return InvalidOid; - return (Oid) (*addr); -} - -/* - * This function is used so we can convert oid's to lo's - * - * ie: insert into table values(lo_import('/path/file')::lo); - * - */ -Blob * -lo(Oid oid) -{ - Blob *result = (Blob *) palloc(sizeof(Blob)); - - *result = oid; - return (result); -} - -/* - * This handles the trigger that protects us from orphaned large objects - */ -PG_FUNCTION_INFO_V1(lo_manage); - -Datum -lo_manage(PG_FUNCTION_ARGS) -{ - TriggerData *trigdata = (TriggerData *) fcinfo->context; - int attnum; /* attribute number to monitor */ - char **args; /* Args containing attr name */ - TupleDesc tupdesc; /* Tuple Descriptor */ - HeapTuple rettuple; /* Tuple to be returned */ - bool isdelete; /* are we deleting? */ - HeapTuple newtuple = NULL; /* The new value for tuple */ - HeapTuple trigtuple; /* The original value of tuple */ - - if (!CALLED_AS_TRIGGER(fcinfo)) - elog(ERROR, "lo: not fired by trigger manager"); - - /* - * Fetch some values from trigdata - */ - newtuple = trigdata->tg_newtuple; - trigtuple = trigdata->tg_trigtuple; - tupdesc = trigdata->tg_relation->rd_att; - args = trigdata->tg_trigger->tgargs; - - /* tuple to return to Executor */ - if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) - rettuple = newtuple; - else - rettuple = trigtuple; - - /* Are we deleting the row? */ - isdelete = TRIGGER_FIRED_BY_DELETE(trigdata->tg_event); - - /* Get the column were interested in */ - attnum = SPI_fnumber(tupdesc, args[0]); - - /* - * Handle updates - * - * Here, if the value of the monitored attribute changes, then the large - * object associated with the original value is unlinked. - */ - if (newtuple != NULL) - { - char *orig = SPI_getvalue(trigtuple, tupdesc, attnum); - char *newv = SPI_getvalue(newtuple, tupdesc, attnum); - - if (orig != NULL && (newv == NULL || strcmp(orig, newv))) - DirectFunctionCall1(lo_unlink, - ObjectIdGetDatum(atooid(orig))); - - if (newv) - pfree(newv); - if (orig) - pfree(orig); - } - - /* - * Handle deleting of rows - * - * Here, we unlink the large object associated with the managed attribute - * - */ - if (isdelete) - { - char *orig = SPI_getvalue(trigtuple, tupdesc, attnum); - - if (orig != NULL) - { - DirectFunctionCall1(lo_unlink, - ObjectIdGetDatum(atooid(orig))); - - pfree(orig); - } - } - - return PointerGetDatum(rettuple); -} diff --git a/contrib/lo/lo.sql.in b/contrib/lo/lo.sql.in deleted file mode 100644 index f9fed597fd..0000000000 --- a/contrib/lo/lo.sql.in +++ /dev/null @@ -1,56 +0,0 @@ --- --- PostgreSQL code for LargeObjects --- --- $Id: lo.sql.in,v 1.6 2000/11/21 21:51:58 tgl Exp $ --- --- --- Create the data type --- - --- used by the lo type, it takes an oid and returns an lo object -create function lo_in(opaque) - returns opaque - as 'MODULE_PATHNAME' - language 'c'; - --- used by the lo type, it returns the oid of the object -create function lo_out(opaque) - returns opaque - as 'MODULE_PATHNAME' - language 'c'; - --- finally the type itself -create type lo ( - internallength = 4, - externallength = variable, - input = lo_in, - output = lo_out -); - --- this returns the oid associated with a lo object -create function lo_oid(lo) - returns oid - as 'MODULE_PATHNAME' - language 'c'; - --- same function, named to allow it to be used as a type coercion, eg: --- create table a (image lo); --- select image::oid from a; --- -create function oid(lo) - returns oid - as 'MODULE_PATHNAME', 'lo_oid' - language 'c'; - --- this allows us to convert an oid to a managed lo object --- ie: insert into test values (lo_import('/fullpath/file')::lo); -create function lo(oid) - returns lo - as 'MODULE_PATHNAME' - language 'c'; - --- This is used in triggers -create function lo_manage() - returns opaque - as 'MODULE_PATHNAME' - language 'c'; diff --git a/contrib/lo/lo_drop.sql b/contrib/lo/lo_drop.sql deleted file mode 100644 index 2472715a3d..0000000000 --- a/contrib/lo/lo_drop.sql +++ /dev/null @@ -1,21 +0,0 @@ --- --- This removes the type (and a test table) --- It's used just for development --- - --- remove our test table -drop table a; - --- now drop any sql based functions associated with the lo type -drop function oid(lo); - --- now drop the type -drop type lo; - --- as the type is gone, remove the C based functions -drop function lo_in(opaque); -drop function lo_out(opaque); -drop function lo(oid); -drop function lo_manage(); - --- the lo stuff is now removed from the system diff --git a/contrib/lo/lo_test.sql b/contrib/lo/lo_test.sql deleted file mode 100644 index 0c0da2cfd6..0000000000 --- a/contrib/lo/lo_test.sql +++ /dev/null @@ -1,57 +0,0 @@ --- --- This runs some common tests against the type --- --- It's used just for development --- - --- ignore any errors here - simply drop the table if it already exists -drop table a; - --- create the test table -create table a (fname name,image lo); - --- insert a null object -insert into a values ('null'); - --- insert an empty large object -insert into a values ('empty',''); - --- insert a large object based on a file -insert into a values ('/etc/group',lo_import('/etc/group')::lo); - --- now select the table -select * from a; - --- this select also returns an oid based on the lo column -select *,image::oid from a; - --- now test the trigger -create trigger t_a before update or delete on a for each row execute procedure lo_manage(image); - --- insert -insert into a values ('aa',''); -select * from a where fname like 'aa%'; - --- update -update a set image=lo_import('/etc/group')::lo where fname='aa'; -select * from a where fname like 'aa%'; - --- update the 'empty' row which should be null -update a set image=lo_import('/etc/hosts')::lo where fname='empty'; -select * from a where fname like 'empty%'; -update a set image=null where fname='empty'; -select * from a where fname like 'empty%'; - --- delete the entry -delete from a where fname='aa'; -select * from a where fname like 'aa%'; - --- This deletes the table contents. Note, if you comment this out, and --- expect the drop table to remove the objects, think again. The trigger --- doesn't get thrown by drop table. -delete from a; - --- finally drop the table -drop table a; - --- end of tests diff --git a/contrib/mSQL-interface/Makefile b/contrib/mSQL-interface/Makefile deleted file mode 100644 index 063569d9c7..0000000000 --- a/contrib/mSQL-interface/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# $Header: /cvsroot/pgsql/contrib/mSQL-interface/Attic/Makefile,v 1.7 2001/02/20 19:20:27 petere Exp $ -# - -subdir = contrib/mSQL-interface -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -NAME := mpgsql -SO_MAJOR_VERSION := 0 -SO_MINOR_VERSION := 0 -OBJS := mpgsql.o - -override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) - -include $(top_srcdir)/src/Makefile.shlib - -all: all-lib - -install: all installdirs install-lib - $(INSTALL_DATA) README.$(NAME) $(docdir)/contrib - -installdirs: - $(mkinstalldirs) $(libdir) $(docdir)/contrib - -uninstall: uninstall-lib - rm -f $(docdir)/contrib/README.$(NAME) - -clean distclean maintainer-clean: clean-lib - rm -f $(OBJS) diff --git a/contrib/mSQL-interface/README.mpgsql b/contrib/mSQL-interface/README.mpgsql deleted file mode 100644 index 714ab29056..0000000000 --- a/contrib/mSQL-interface/README.mpgsql +++ /dev/null @@ -1,86 +0,0 @@ - -Hello! :) - -(Sorry for my english. But if i wrote in portuguese, you wouldn't - understand nothing. :]) - - I found it's the right place to post this. I'm a newcomer in these -lists. I hope i did it right. :] - - - When i started using SQL, i started with mSQL. I developed a lot -of useful apps for me and my job with C, mainly because i loved it's -elegant, simple api. But for a large project i'm doing in these days, i -thought is was not enough, because it felt a lot of features i started to -need, like security and subselects. (and it's not free :)) - So after looking at the options, choose to start again with -postgres. It offered everything that i needed, and the documentation is -really good (remember me to thank the one who wrote'em). - But for my little apps, i needed to start porting them to libpq. -After looking at pq's syntax, i found it was better to write a bridge -between the mSQL api and libpq. I found that rewriting the libmsql.a -routines that calls libpq would made things much easier. I guess the -results are quite good right now. - - - Ok. Lets' summarize it: - - mpgsql.c is the bridge. Acting as a wrapper, it's really good, -since i could run mSQL. But it's not accurate. Some highlights: - - CONS: - * It's not well documented - (this post is it's first documentation attempt, in fact); - * It doesn't handle field types correctly. I plan to fix it, - if people start doing feedbacks; - * It's limited to 10 simultaneous connections. I plan to enhance - this, i'm just figuring out; - * I'd like to make it reentrant/thread safe, although i don't - think this could be done without changing the API structure; - * Error Management should be better. This is my first priority - now; - * Some calls are just empty implementations. - - PROS: - * the mSQL Monitor runs Okay. :] - * It's really cool. :) - * Make mSQL-made applications compatible with postgresql just by - changing link options. - * Uses postgreSQL. :] - * the mSQL API it's far easier to use and understand than libpq. - Consider this example: - -#include "msql.h" - -void main(int argc, char **argv, char **envp) { - int sid; - - sid = msqlConnect(NULL); /* Connects via unix socket */ - - if (sid >= 0) { - m_result *rlt; - m_row *row; - msqlSelectDB(sid, "hosts"); - if (msqlQuery(sid, "select host_id from hosts")) { - rlt = msqlStoreResult(); - while (row = (m_row*)msqlFetchRow(rlt)) - printf("hostid: %s\n", row[0]); - msqlFreeResult(rlt); - } - msqlClose(sid); - } -} - - I enclose mpgsql.c inside. I'd like to maintain it, and (maybe, am -i dreaming) make it as part of the pgsql distribution. I guess it doesn't -depends on me, but mainly on it's acceptance by its users. - - Hm... i forgot: you'll need a msql.h copy, since it's copyrighted -by Hughes Technologies Pty Ltd. If you haven't it yes, fetch one -from www.hughes.com.au. - - I would like to catch users ideas. My next goal is to add better -error handling, and to make it better documented, and try to let relshow -run through it. :) - - done. Aldrin Leal diff --git a/contrib/mSQL-interface/mpgsql.c b/contrib/mSQL-interface/mpgsql.c deleted file mode 100644 index 8b59485471..0000000000 --- a/contrib/mSQL-interface/mpgsql.c +++ /dev/null @@ -1,365 +0,0 @@ -#include -#include -#include -#include "msql.h" -#include "libpq-fe.h" - -#define HNDMAX 10 - -PGconn *PGh[HNDMAX] = { - NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL -}; - -#define E_NOHANDLERS 0 - -char *msqlErrors[] = { - "Out of database handlers." -}; - -char msqlErrMsg[BUFSIZ], - *tfrom = "dunno"; -PGresult *queryres = NULL; - -int -msqlConnect(char *host) -{ - int count; - - for (count = 0; count < HNDMAX; count++) - if (PGh[count] == NULL) - break; - - if (count == HNDMAX) - { - strncpy(msqlErrMsg, msqlErrors[E_NOHANDLERS], BUFSIZ); - return -1; - } - - PGh[count] = malloc(sizeof(PGconn)); - PGh[count]->pghost = host ? strdup(host) : NULL; - return count; -} - -int -msqlSelectDB(int handle, char *dbname) -{ - char *options = calloc(1, BUFSIZ); - char *e = getenv("PG_OPTIONS"); - - if (e == NULL) - e = ""; - - if (PGh[handle]->pghost) - { - strcat(options, "host="); - strncat(options, PGh[handle]->pghost, BUFSIZ); - strncat(options, " ", BUFSIZ); - free(PGh[handle]->pghost); - PGh[handle]->pghost = NULL; - } - strncat(options, "dbname=", BUFSIZ); - strncat(options, dbname, BUFSIZ); - strncat(options, " ", BUFSIZ); - strncat(options, e, BUFSIZ); - free(PGh[handle]); - PGh[handle] = PQconnectdb(options); - free(options); - strncpy(msqlErrMsg, PQerrorMessage(PGh[handle]), BUFSIZ); - return (PQstatus(PGh[handle]) == CONNECTION_BAD ? -1 : 0); -} - -int -msqlQuery(int handle, char *query) -{ - char *tq = strdup(query); - char *p = tq; - PGresult *res; - PGconn *conn = PGh[handle]; - ExecStatusType rcode; - - res = PQexec(conn, p); - - rcode = PQresultStatus(res); - - if (rcode == PGRES_TUPLES_OK) - { - queryres = res; - return PQntuples(res); - } - else if (rcode == PGRES_FATAL_ERROR || rcode == PGRES_NONFATAL_ERROR) - { - PQclear(res); - queryres = NULL; - return -1; - } - else - { - PQclear(res); - queryres = NULL; - return 0; - } -} - -int -msqlCreateDB(int a, char *b) -{ - char tbuf[BUFSIZ]; - - sprintf(tbuf, "create database %s", b); - return msqlQuery(a, tbuf) >= 0 ? 0 : -1; -} - -int -msqlDropDB(int a, char *b) -{ - char tbuf[BUFSIZ]; - - sprintf(tbuf, "drop database %s", b); - return msqlQuery(a, tbuf) >= 0 ? 0 : -1; -} - -int -msqlShutdown(int a) -{ -} - -int -msqlGetProtoInfo(void) -{ -} - -int -msqlReloadAcls(int a) -{ -} - -char * -msqlGetServerInfo(void) -{ -} - -char * -msqlGetHostInfo(void) -{ -} - -char * -msqlUnixTimeToDate(time_t date) -{ -} - -char * -msqlUnixTimeToTime(time_t time) -{ -} - -void -msqlClose(int a) -{ - PQfinish(PGh[a]); - PGh[a] = NULL; - if (queryres) - { - free(queryres); - queryres = NULL; - } -} - -void -msqlDataSeek(m_result * result, int count) -{ - int c; - - result->cursor = result->queryData; - for (c = 1; c < count; c++) - if (result->cursor->next) - result->cursor = result->cursor->next; -} - -void -msqlFieldSeek(m_result * result, int count) -{ - int c; - - result->fieldCursor = result->fieldData; - for (c = 1; c < count; c++) - if (result->fieldCursor->next) - result->fieldCursor = result->fieldCursor->next; -} - -void -msqlFreeResult(m_result * result) -{ - if (result) - { - /* Clears fields */ - free(result->fieldData); - result->cursor = result->queryData; - while (result->cursor) - { - int c; - m_row m = result->cursor->data; - - for (c = 0; m[c]; c++) - free(m[c]); - - result->cursor = result->cursor->next; - } - free(result->queryData); - free(result); - } -} - -m_row -msqlFetchRow(m_result * row) -{ - m_data *r = row->cursor; - - if (r) - { - row->cursor = row->cursor->next; - return (m_row) r->data; - } - return (m_row) NULL; -} - -m_seq * -msqlGetSequenceInfo(int a, char *b) -{ -} - -m_field * -msqlFetchField(m_result * mr) -{ - m_field *m = (m_field *) mr->fieldCursor; - - if (m) - { - mr->fieldCursor = mr->fieldCursor->next; - return m; - } - return NULL; -} - -m_result * -msqlListDBs(int a) -{ - m_result *m; - - if (msqlQuery(a, "select datname from pg_database") > 0) - { - m = msqlStoreResult(); - return m; - } - else - return NULL; -} - -m_result * -msqlListTables(int a) -{ - m_result *m; - char tbuf[BUFSIZ]; - - sprintf(tbuf, "select relname from pg_class where relkind='r' and relowner=%d", getuid()); - if (msqlQuery(a, tbuf) > 0) - { - m = msqlStoreResult(); - return m; - } - else - return NULL; -} - -m_result * -msqlListFields(int a, char *b) -{ - -} - -m_result * -msqlListIndex(int a, char *b, char *c) -{ - m_result *m; - char tbuf[BUFSIZ]; - - sprintf(tbuf, "select relname from pg_class where relkind='i' and relowner=%d", getuid()); - if (msqlQuery(a, tbuf) > 0) - { - m = msqlStoreResult(); - return m; - } - else - return NULL; -} - -m_result * -msqlStoreResult(void) -{ - if (queryres) - { - m_result *mr = malloc(sizeof(m_result)); - m_fdata *mf; - m_data *md; - int count; - - mr->queryData = mr->cursor = NULL; - mr->numRows = PQntuples(queryres); - mr->numFields = PQnfields(queryres); - - mf = calloc(PQnfields(queryres), sizeof(m_fdata)); - for (count = 0; count < PQnfields(queryres); count++) - { - (m_fdata *) (mf + count)->field.name = strdup(PQfname(queryres, count)); - (m_fdata *) (mf + count)->field.table = tfrom; - (m_fdata *) (mf + count)->field.type = CHAR_TYPE; - (m_fdata *) (mf + count)->field.length = PQfsize(queryres, count); - (m_fdata *) (mf + count)->next = (m_fdata *) (mf + count + 1); - } - (m_fdata *) (mf + count - 1)->next = NULL; - - md = calloc(PQntuples(queryres), sizeof(m_data)); - for (count = 0; count < PQntuples(queryres); count++) - { - m_row rows = calloc(PQnfields(queryres) * sizeof(m_row) + 1, 1); - int c; - - for (c = 0; c < PQnfields(queryres); c++) - rows[c] = strdup(PQgetvalue(queryres, count, c)); - (m_data *) (md + count)->data = rows; - - (m_data *) (md + count)->width = PQnfields(queryres); - (m_data *) (md + count)->next = (m_data *) (md + count + 1); - } - (m_data *) (md + count - 1)->next = NULL; - - mr->queryData = mr->cursor = md; - mr->fieldCursor = mr->fieldData = mf; - - return mr; - } - else - return NULL; -} - -time_t -msqlDateToUnixTime(char *a) -{ -} - -time_t -msqlTimeToUnixTime(char *b) -{ -} - -char * -msql_tmpnam(void) -{ - return tmpnam("/tmp/msql.XXXXXX"); -} - -int -msqlLoadConfigFile(char *a) -{ -} diff --git a/contrib/mac/README.mac b/contrib/mac/README.mac deleted file mode 100644 index f68a5fafa4..0000000000 --- a/contrib/mac/README.mac +++ /dev/null @@ -1,8 +0,0 @@ -This directory contains tools to create a mapping table from MAC -addresses (e.g., Ethernet hardware addresses) to human-readable -manufacturer strings. The `createoui' script builds the table -structure, `updateoui' obtains the current official mapping table -from the web site of the IEEE, converts it, and stores it in the -database, `dropoui' removes everything. Use the --help option to -get more usage information from the respective script. All three -use the psql program; any extra arguments will be passed to psql. diff --git a/contrib/mac/createoui b/contrib/mac/createoui deleted file mode 100755 index 56d81c20d3..0000000000 --- a/contrib/mac/createoui +++ /dev/null @@ -1,52 +0,0 @@ -#! /bin/sh -# Utility to create manufacturer's oui table -# OUI is "Organizationally Unique Identifier" assigned by IEEE. -# There are currently three duplicate listings, so we can not enforce -# uniqueness in the OUI field. -# - thomas 2000-08-21 - -args= -update=0 - -while [ $# -gt 0 ] -do - case "$1" in - --update) - update=1 - ;; - --noupdate) - update=0 - ;; - --help) - echo "Usage: $0 --[no]update dbname" - exit - ;; - *) - args="$args $1" - ;; - esac - shift -done - -psql -e $args < -# Original Date: 30 July 2000 (in this form). -# This AWK script takes the IEEE's oui.txt file and creates insert -# statements to populate a SQL table with the following attributes: -# create table oui ( -# oui macaddr primary key, -# manufacturer text); -# the table name is set by setting the AWK variable TABLE -# -# we translate the character apostrophe (') to double apostrophe ('') inside -# the company name to avoid SQL errors. -# - -BEGIN { - TABLE="macoui"; - printf "DELETE FROM %s;",TABLE; - printf "BEGIN TRANSACTION;"; - nrec=0; -} - -END { -# if (nrec > 0) - printf "COMMIT TRANSACTION;"; -} - -# match ONLY lines that begin with 2 hex numbers, -, and another hex number -/^[0-9a-fA-F][0-9a-fA-F]-[0-9a-fA-F]/ { -# if (nrec >= 100) { -# printf "COMMIT TRANSACTION;"; -# printf "BEGIN TRANSACTION;"; -# nrec=0; -# } else { -# nrec++; -# } - # Get the OUI - OUI=$1; - # Skip the (hex) tag to get to Company Name - Company=$3; - # make the OUI look like a macaddr - gsub("-",":",OUI); - OUI=OUI ":00:00:00" - # Pick up the rest of the company name - for (i=4;i<=NF;i++) - Company=Company " " $i; - # Modify any apostrophes (') to avoid grief below. - gsub("'","''",Company); - # Print out for the SQL table insert - printf "INSERT INTO %s (addr, name) VALUES (trunc(macaddr \'%s\'),\'%s\');\n", - TABLE,OUI,Company; -} diff --git a/contrib/mac/updateoui b/contrib/mac/updateoui deleted file mode 100755 index 2a6a07c3df..0000000000 --- a/contrib/mac/updateoui +++ /dev/null @@ -1,34 +0,0 @@ -#! /bin/sh -# Utility to create manufacturer's OUI table - -args= -refresh=0 - -while [ $# -gt 0 ] -do - case "$1" in - --refresh|--fetch|-r) - refresh=1 - ;; - --norefresh|--nofetch) - refresh=0 - ;; - --help) - echo "Usage: $0 --[no]refresh dbname" - exit - ;; - *) - args="$args $1" - ;; - esac - shift -done - -if [ $refresh -gt 0 ]; then - [ -e oui.txt ] && rm -rf oui.txt - wget -nd 'http://standards.ieee.org/regauth/oui/oui.txt' -fi - -awk -f ouiparse.awk < oui.txt | psql -e $args - -exit diff --git a/contrib/miscutil/Makefile b/contrib/miscutil/Makefile deleted file mode 100644 index 95daef72ba..0000000000 --- a/contrib/miscutil/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/miscutil/Attic/Makefile,v 1.16 2001/09/06 10:49:29 petere Exp $ - -subdir = contrib/miscutil -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -MODULES = misc_utils -DATA_built = misc_utils.sql -DOCS = README.misc_utils - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/miscutil/README.misc_utils b/contrib/miscutil/README.misc_utils deleted file mode 100644 index 0a8eca6c9c..0000000000 --- a/contrib/miscutil/README.misc_utils +++ /dev/null @@ -1,26 +0,0 @@ -Miscellaneous utility functions for PostgreSQL. -Copyright (C) 1999, Massimo Dal Zotto - -This software is distributed under the GNU General Public License -either version 2, or (at your option) any later version. - -backend_pid() - - return the pid of our corresponding backend. - -unlisten(relname) - - unlisten from a relation or from all relations if the argument - is null, empty or '*'. - It is now obsoleted by the new unlisten command but still useful - if you want unlisten a name computed by the query. - Note that a listen/notify relname can be any ascii string, not - just valid relation names. - -min(x,y) -max(x,y) - - return the min or max of two integers. - --- -Massimo Dal Zotto diff --git a/contrib/miscutil/misc_utils.c b/contrib/miscutil/misc_utils.c deleted file mode 100644 index 26bbabe46f..0000000000 --- a/contrib/miscutil/misc_utils.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * misc_utils.c -- - * - * This file defines miscellaneous PostgreSQL utility functions. - * - * Copyright (C) 1999, Massimo Dal Zotto - * - * This file is distributed under the GNU General Public License - * either version 2, or (at your option) any later version. - */ - -#include "postgres.h" - -#include -#include -#include -#include - -#include "access/heapam.h" -#include "access/htup.h" -#include "access/relscan.h" -#include "access/skey.h" -#include "access/tupdesc.h" -#include "catalog/catname.h" -#include "catalog/pg_listener.h" -#include "commands/async.h" -#include "fmgr.h" -#include "storage/lmgr.h" -#include "utils/fmgroids.h" -#include "utils/palloc.h" -#include "utils/rel.h" -#include "utils/tqual.h" - -#include "misc_utils.h" - -#undef MIN -#define MIN(x,y) ((x)<=(y) ? (x) : (y)) - - -int -backend_pid() -{ - return getpid(); -} - -int -unlisten(char *relname) -{ - Async_Unlisten(relname, getpid()); - return 0; -} - -int -max(int x, int y) -{ - return ((x > y) ? x : y); -} - -int -min(int x, int y) -{ - return ((x < y) ? x : y); -} - -/* - * Return the number of active listeners on a relation name. - */ -int -active_listeners(text *relname) -{ - HeapTuple lTuple; - Relation lRel; - HeapScanDesc sRel; - TupleDesc tdesc; - ScanKeyData key; - Datum d; - bool isnull; - int len, - pid; - int count = 0; - int ourpid = getpid(); - char listen_name[NAMEDATALEN]; - - lRel = heap_openr(ListenerRelationName, AccessShareLock); - tdesc = RelationGetDescr(lRel); - - if (relname && (VARSIZE(relname) > VARHDRSZ)) - { - MemSet(listen_name, 0, NAMEDATALEN); - len = MIN(VARSIZE(relname) - VARHDRSZ, NAMEDATALEN - 1); - memcpy(listen_name, VARDATA(relname), len); - ScanKeyEntryInitialize(&key, 0, - Anum_pg_listener_relname, - F_NAMEEQ, - PointerGetDatum(listen_name)); - sRel = heap_beginscan(lRel, SnapshotNow, 1, &key); - } - else - sRel = heap_beginscan(lRel, SnapshotNow, 0, (ScanKey) NULL); - - while ((lTuple = heap_getnext(sRel, ForwardScanDirection)) != NULL) - { - d = heap_getattr(lTuple, Anum_pg_listener_pid, tdesc, &isnull); - pid = DatumGetInt32(d); - if ((pid == ourpid) || (kill(pid, SIGTSTP) == 0)) - count++; - } - heap_endscan(sRel); - - heap_close(lRel, AccessShareLock); - - return count; -} diff --git a/contrib/miscutil/misc_utils.h b/contrib/miscutil/misc_utils.h deleted file mode 100644 index f4577f49de..0000000000 --- a/contrib/miscutil/misc_utils.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef MISC_UTILS_H -#define MISC_UTILS_H - -int backend_pid(void); -int unlisten(char *relname); -int max(int x, int y); -int min(int x, int y); -int active_listeners(text *relname); - -#endif diff --git a/contrib/miscutil/misc_utils.sql.in b/contrib/miscutil/misc_utils.sql.in deleted file mode 100644 index 39d4fd51e9..0000000000 --- a/contrib/miscutil/misc_utils.sql.in +++ /dev/null @@ -1,46 +0,0 @@ --- misc_utils.sql -- --- --- SQL code to define misc functions. --- --- Copyright (c) 1998, Massimo Dal Zotto --- --- This file is distributed under the GNU General Public License --- either version 2, or (at your option) any later version. - --- Return the pid of the backend. --- -create function backend_pid() returns int4 - as 'MODULE_PATHNAME' - language 'C'; - --- Unlisten from a relation. --- -create function "unlisten"(name) returns int4 - as 'MODULE_PATHNAME' - language 'C'; - --- Unlisten from all relations for this backend. --- -create function "unlisten"() returns int4 - as 'select "unlisten"(''*'')' - language 'sql'; - --- min(x,y) --- -create function min(int4,int4) returns int4 - as 'MODULE_PATHNAME' - language 'C'; - --- max(x,y) --- -create function max(int4,int4) returns int4 - as 'MODULE_PATHNAME' - language 'C'; - --- Return the number of active listeners on a relation --- -create function active_listeners(text) returns int4 - as 'MODULE_PATHNAME' - language 'C'; - --- end of file diff --git a/contrib/mysql/README b/contrib/mysql/README deleted file mode 100644 index 5511df6c67..0000000000 --- a/contrib/mysql/README +++ /dev/null @@ -1,9 +0,0 @@ -Here are two conversion utilities for MySQL dumps. Use the one you prefer. - -The most recent version of my2pg.pl can be obtained from: - - http://ziet.zhitomir.ua/~fonin/code/ - -Another tool, mysql2pgsql, can be found at: - - http://www.rot13.org/~dpavlin/sql.html diff --git a/contrib/mysql/my2pg.pl b/contrib/mysql/my2pg.pl deleted file mode 100755 index 9ceaca46f5..0000000000 --- a/contrib/mysql/my2pg.pl +++ /dev/null @@ -1,948 +0,0 @@ -#!/usr/bin/perl - -# -# My2Pg: MySQL to PostgreSQL dump conversion utility -# -# (c) 2000,2001 Maxim Rudensky -# (c) 2000 Valentine Danilchuk -# All right reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. All advertising materials mentioning features or use of this software -# must display the following acknowledgement: -# This product includes software developed by the Max Rudensky -# and its contributors. -# 4. Neither the name of the author nor the names of its contributors -# may be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $My2pg: my2pg.pl,v 1.24 2001/12/06 19:32:20 fonin Exp $ -# $Id: my2pg.pl,v 1.8 2002/04/24 01:42:29 momjian Exp $ - -# TODO: -# + Handle SETs -# - LIKE implementation -# - memory use optimisation in SET_output function -# - raw integer values as input values must be OK -# - Use autoconf & automake to auto-build makefiles - -# -# $Log: my2pg.pl,v $ -# Revision 1.8 2002/04/24 01:42:29 momjian -# Update to my2pg 1.24. -# -# Revision 1.24 2002/04/20 14:15:43 fonin -# Patch by Felipe Nievinski . -# A table I was re-creating had a composite primary key, and I was using -# the -d switch to maintain the table and column names -# adding double quotes around them. -# -# The SQL code generated was something like this: -# -# CREATE TABLE "rinav" ( -# "UnidadeAtendimento" INT8 DEFAULT '0' NOT NULL, -# "NumeroRinav" INT8 DEFAULT '0' NOT NULL, -# -- ... -# PRIMARY KEY ("UnidadeAtendimento"," NumeroRinav") -# ); -# -# Please note the space inside the second column name string in the PK -# definition. Because of this PostgreSQL was not able to create the table. -# -# FIXED. -# -# Revision 1.23 2002/02/07 22:13:52 fonin -# Bugfix by Hans-Juergen Schoenig : additional space after -# FLOAT8 is required. -# -# Revision 1.22 2001/12/06 19:32:20 fonin -# Patch: On line 594 where you check for UNIQUE, I believe the regex should try -# and match 'UNIQUE KEY'. Otherwise it outputs no unique indexes for the -# postgres dump. -# Thanks to Brad Hilton -# -# Revision 1.21 2001/08/25 18:55:28 fonin -# Incorporated changes from Yunliang Yu : -# - By default table & column names are not quoted; use the new -# "-d" option if you want to, -# - Use conditional substitutions to speed up and preserve -# the data integrity. -# Fixes by Max: -# - timestamps conversion fix. Shouldn't break now matching binary data and -# strings. -# -# Revision 1.21 2001/07/23 03:04:39 yu -# Updates & fixes by Yunliang Yu -# . By default table & column names are not quoted; use the new -# "-d" option if you want to, -# . Use conditional substitutions to speed up and preserve -# the data integrity. -# -# Revision 1.20 2001/07/05 12:45:05 fonin -# Timestamp conversion enhancement from Joakim Lemström -# -# Revision 1.19 2001/05/07 19:36:38 fonin -# Fixed a bug in quoting PRIMARY KEYs, KEYs and UNIQUE indexes with more than 2 columns. Thanks to Jeff Waugh . -# -# Revision 1.18 2001/03/06 22:25:40 fonin -# Documentation up2dating. -# -# Revision 1.17 2001/03/04 13:01:50 fonin -# Fixes to make work it right with MySQL 3.23 dumps. Tested on mysqldump 8.11. -# Also, AUTO_INCREMENT->SERIAL fields no more have DEFAULT and NOT NULL -# definitions. -# -# Revision 1.16 2001/02/02 08:15:34 fonin -# Sequences should be created BEFORE creating any objects \nthat depends on it. -# -# Revision 1.15 2001/01/30 10:13:36 fonin -# Re-released under BSD-like license. -# -# Revision 1.14 2000/12/18 20:55:13 fonin -# Better -n implementation. -# -# Revision 1.13 2000/12/18 15:26:33 fonin -# Added command-line options. -n forces *CHAR DEFAULT '' NOT NULL to be -# converted to *CHAR NULL. -# AUTO_INCREMENT fields converted not in SERIAL but in -# INT* NOT NULL DEFAULT nextval('seqname'). -# Documentation refreshed. -# Dump enclosed in single transaction from now. -# -# Revision 1.12 2000/12/14 20:57:15 fonin -# Doublequotation bug fixed (in CREATE INDEX ON TABLE (field1,field2)) -# -# Revision 1.10 2000/11/27 14:18:22 fonin -# Fixed bug - occasionaly was broken CREATE SEQUENCE generation -# -# Revision 1.8 2000/11/24 15:24:16 fonin -# TIMESTAMP fix: MySQL output YYYYMMDDmmhhss to YYYYMMDD mmhhss -# -# Revision 1.7 2000/11/22 23:04:41 fonin -# TIMESTAMP field fix. Better doublequoting. Splitting output dump -# into 2 transactions - create/load/indexing first, sequence setvals then. -# Added POD documentation. -# -# - -use Getopt::Std; - -my %opts; # command line options -my $chareg=''; # CHAR conversion regexps -my $dq=''; # double quote - -# parse command line -getopts('nhd',\%opts); - -# output syntax -if($opts{h} ne '') { - usage(); - exit; -} - -# convert CHAR types from NOT NULL DEFAULT '' to NULL -if($opts{n} ne '') { - $chareg='\s*?(default\s*?\'\')*?\s*?not\s*?null'; -} -# want double quotes -if($opts{d} ne '') { - $dq='"'; -} - -$|=1; - -print("------------------------------------------------------------------"); -print("\n-- My2Pg 1.24 translated dump"); -print("\n--"); -print("\n------------------------------------------------------------------"); - -print("\n\nBEGIN;\n\n\n"); - -my %index; # contains array of CREATE INDEX for each table -my %seq; # contains CREATE SEQUENCE for each table -my %primary; # contains primary (eg SERIAL) fields for each table -my %identifier; # contains generated by this program identifiers -my $j=-1; # current position in $index{table} -my @check; # CHECK constraint for current - -# generating full path to libtypes.c -my $libtypesource='libtypes.c'; -my $libtypename=`pwd`; -chomp($libtypename); -$libtypename.='/libtypes.so'; - -# push header to libtypes.c -open(LIBTYPES,">$libtypesource"); -print LIBTYPES "/******************************************************"; -print LIBTYPES "\n * My2Pg \$Revision: 1.8 $ \translated dump"; -print LIBTYPES "\n * User types definitions"; -print LIBTYPES "\n ******************************************************/"; -print LIBTYPES "\n\n#include \n"; -print LIBTYPES "\n#define ADD_COMMA if(strcmp(result,\"\")!=0) strcat(result,\",\")\n"; - -# reading STDIN... -my $tabledef=0; # we are outside a table definition -while (<>) { - - if(!$tabledef && /^CREATE TABLE \S+/i){ - $tabledef=1; - }elsif($tabledef && /^\);/i){ # /^\w/i - $tabledef=0; - } - -# Comments start with -- in SQL - if(/^#/) {# !/insert into.*\(.*#.*\)/i, in mysqldump output - s/#/--/; - } - - if($tabledef){################################## -# Convert numeric types - s/tinyint\(\d+\)/INT2/i; - s/smallint\(\d+\)/INT2/i; - s/mediumint\(\d+\)/INT4/i; - s/bigint\(\d+\)/INT8/i; - s/int\(\d+\)/INT4/i; - s/float(\(\d+,\d*\))/DECIMAL$1/i; - s/double precision/FLOAT8 /i; - s/([\W])double(\(\d+,\d*\))/$1DECIMAL$2/i; - s/([\W])double[\W]/$1FLOAT8 /i; - s/([\W])real[\W]/$1FLOAT8 /i; - s/([\W])real(\(\d+,\d*\))/$1DECIMAL$2/i; - -# Convert string types - s/\w*blob$chareg/text/i; - s/mediumtext$chareg/text/i; - s/tinytext$chareg/text/i; - s/\stext\s+not\s+null/ TEXT DEFAULT '' NOT NULL/i; - s/(.*?char\(.*?\))$chareg/$1/i; - -# Old and New are reserved words in Postgres - s/^(\s+)Old /${1}MyOld /; - s/^(\s+)New /${1}MyNew /; - -# Convert DATE types - s/datetime/TIMESTAMP/; - s/timestamp\(\d+\)/TIMESTAMP/i; - s/ date / DATE /i; - s/,(\d{4})(\d{2})(\d{2}),/,'$1-$2-$3 00:00:00',/g; - -# small hack - convert "default" to uppercase, because below we -# enclose all lowercase words in double quotes - s/default/DEFAULT/; - -# Change all AUTO_INCREMENT fields to SERIAL ones with a pre-defined sequence - if(/([\w\d]+)\sint.*auto_increment/i) { - $tmpseq=new_name("$table_name"."_"."$+"."_SEQ",28); - $seq{$table_name}=$tmpseq; - $primary{$table_name}=$+; - s/(int.*?) .*AUTO_INCREMENT/$1 DEFAULT nextval\('$tmpseq'\)/i; - #s/(int.*?)DEFAULT\s*?'.*?'(.*?)AUTO_INCREMENT/$1$2DEFAULT nextval\('$tmpseq'\)/i; - } - -# convert UNSIGNED to CHECK constraints - if(/^\s+?([\w\d_]+).*?unsigned/i) { - $check.=",\n CHECK ($dq$1$dq>=0)"; - } - s/unsigned//i; - -# Limited ENUM support - little heuristic - s/enum\('N','Y'\)/BOOL/i; - s/enum\('Y','N'\)/BOOL/i; -# ENUM support - if(/^\s+?([\w\d_]+).*?enum\((.*?)\)/i) { - my $enumlist=$2; - my @item; - $item[0]=''; - while($enumlist=~s/'([\d\w_]+)'//i) { - $item[++$#item]=$1; - } -# forming identifier name - $typename=new_name('enum_'.$table_name.'_'.$item[1],28); -# $typename=lc('enum_'.$table_name.'_'.$item[1]); -# creating input type function - my $func_in=" -int2* $typename"."_in (char *str) { - int2* result; - - if(str==NULL) - return NULL; - - result=(int2*)palloc(sizeof(int2)); - *result=-1;"; - for(my $i=0;$i<=$#item;$i++) { - $func_in.=" - if(strcmp(str,\"$item[$i]\")==0) { - *result=$i; - }"; - } - $func_in.=" - if(*result == -1) { - elog(ERROR,\"$typename"."_in: incorrect input value\"); - return NULL; - } - return (result); -}\n"; - $types.="\n---"; - $types.="\n--- Types for table ".uc($table_name); - $types.="\n---\n"; - print LIBTYPES "\n/*"; - print LIBTYPES "\n * Types for table ".uc($table_name); - print LIBTYPES "\n */\n"; - - $types.="\nCREATE FUNCTION $typename"."_in (opaque) - RETURNS $typename - AS '$libtypename' - LANGUAGE 'c' - WITH (ISCACHABLE);\n"; - -# creating output function - my $func_out=" -char* $typename"."_out (int2 *outvalue) { - char* result; - - if(outvalue==NULL) - return NULL; - - result=(char*)palloc(10); - switch (*outvalue) {"; - for(my $i=0;$i<=$#item;$i++) { - $func_out.=" - case $i: - strcpy(result,\"$item[$i]\"); - break;"; - } - $func_out.=" - default : - elog(ERROR,\"$typename"."_out: incorrect stored value\"); - return NULL; - break; - } - return result; -}\n"; - $func_out.="\nbool $typename"."_eq(int2* a, int2* b) { - return (*a==*b); -} - -bool $typename"."_ne(int2* a, int2* b) { - return (*a!=*b); -} - -bool $typename"."_lt(int2* a, int2* b) { - return (*a<*b); -} - -bool $typename"."_le(int2* a, int2* b) { - return (*a<=*b); -} - -bool $typename"."_gt(int2* a, int2* b) { - return (*a>*b); -} - -bool $typename"."_ge(int2* a, int2* b) { - return (*a>=*b); -}\n"; - - $types.="\nCREATE FUNCTION $typename"."_out (opaque) - RETURNS opaque - AS '$libtypename' - LANGUAGE 'c' - WITH (ISCACHABLE);\n"; - - $types.="\nCREATE TYPE $typename ( - internallength = 2, - input = $typename\_in, - output = $typename\_out -);\n"; - - $types.="\nCREATE FUNCTION $typename"."_eq ($typename,$typename) - RETURNS bool - AS '$libtypename' - LANGUAGE 'c'; - -CREATE FUNCTION $typename"."_lt ($typename,$typename) - RETURNS bool - AS '$libtypename' - LANGUAGE 'c'; - -CREATE FUNCTION $typename"."_le ($typename,$typename) - RETURNS bool - AS '$libtypename' - LANGUAGE 'c'; - -CREATE FUNCTION $typename"."_gt ($typename,$typename) - RETURNS bool - AS '$libtypename' - LANGUAGE 'c'; - -CREATE FUNCTION $typename"."_ge ($typename,$typename) - RETURNS bool - AS '$libtypename' - LANGUAGE 'c'; - -CREATE FUNCTION $typename"."_ne ($typename,$typename) - RETURNS bool - AS '$libtypename' - LANGUAGE 'c'; - -CREATE OPERATOR < ( - leftarg = $typename, - rightarg = $typename, --- negator = >=, - procedure = $typename"."_lt -); - -CREATE OPERATOR <= ( - leftarg = $typename, - rightarg = $typename, --- negator = >, - procedure = $typename"."_le -); - -CREATE OPERATOR = ( - leftarg = $typename, - rightarg = $typename, - commutator = =, --- negator = <>, - procedure = $typename"."_eq -); - -CREATE OPERATOR >= ( - leftarg = $typename, - rightarg = $typename, - negator = <, - procedure = $typename"."_ge -); - -CREATE OPERATOR > ( - leftarg = $typename, - rightarg = $typename, - negator = <=, - procedure = $typename"."_gt -); - -CREATE OPERATOR <> ( - leftarg = $typename, - rightarg = $typename, - negator = =, - procedure = $typename"."_ne -);\n"; - - print LIBTYPES $func_in; - print LIBTYPES $func_out; - s/enum\(.*?\)/$typename/i; - } - -# SET support - if(/^\s+?([\w\d_]+).*?set\((.*?)\)/i) { - my $setlist=$2; - my @item; - $item[0]=''; - my $maxlen=0; # maximal string length - while($setlist=~s/'([\d\w_]+)'//i) { - $item[++$#item]=$1; - $maxlen+=length($item[$#item])+1; - } - $maxlen+=1; - my $typesize=int($#item/8); - if($typesize<2) { - $typesize=2; - } - $internalsize=$typesize; - $typesize='int'.$typesize; -# $typename=lc('set_'.$table_name.'_'.$item[1]); - $typename=new_name('set_'.$table_name.'_'.$item[1],28); -# creating input type function - my $func_in=" -$typesize* $typename"."_in (char *str) { - $typesize* result; - char* token; - - if(str==NULL) - return NULL; - - result=($typesize*)palloc(sizeof($typesize)); - *result=0; - if(strcmp(str,\"\")==0) - return result; - for(token=strtok(str,\",\");token!=NULL;token=strtok(NULL,\",\")) {"; - for(my $i=0,my $j=1;$i<=$#item;$i++,$j*=2) { - $func_in.=" - if(strcmp(token,\"$item[$i]\")==0) { - *result|=$j; - continue; - }"; - } - $func_in.=" - } - - if(*result == 0) { - elog(ERROR,\"$typename"."_in: incorrect input value\"); - return NULL; - } - return (result); - -}\n"; - $types.="\n---"; - $types.="\n--- Types for table ".uc($table_name); - $types.="\n---\n"; - print LIBTYPES "\n/*"; - print LIBTYPES "\n * Types for table ".uc($table_name); - print LIBTYPES "\n */\n"; - - $types.="\nCREATE FUNCTION $typename"."_in (opaque) - RETURNS $typename - AS '$libtypename' - LANGUAGE 'c';\n"; - -# creating output function - my $func_out=" -char* $typename"."_out ($typesize *outvalue) { - char* result; - int i; - - if(outvalue==NULL) - return NULL; - - result=(char*)palloc($maxlen); - strcpy(result,\"\"); - for(i=1;i<=2 << (sizeof(int2)*8);i*=2) { - switch (*outvalue & i) {"; - for(my $i=0,$j=1;$i<=$#item;$i++,$j*=2) { - $func_out.=" - case $j:"; - if($item[$i] ne '') { - $func_out.="ADD_COMMA;"; - } - $func_out.="strcat(result,\"$item[$i]\"); - break;"; - } - $func_out.=" - default : - break; - } - } - - return result; -}\n"; - $func_out.="\nbool $typename"."_eq($typesize* a, $typesize* b) { - return (*a==*b); -} - -$typesize find_in_set($typesize *a, $typesize *b) { - int i; - - for(i=1;i<=sizeof($typesize)*8;i*=2) { - if(*a & *b) { - return 1; - } - } - return 0; -} - -\n"; - - $types.="\nCREATE FUNCTION $typename"."_out (opaque) - RETURNS opaque - AS '$libtypename' - LANGUAGE 'c';\n"; - - $types.="\nCREATE TYPE $typename ( - internallength = $internalsize, - input = $typename\_in, - output = $typename\_out -);\n"; - - $types.="\nCREATE FUNCTION $typename"."_eq ($typename,$typename) - RETURNS bool - AS '$libtypename' - LANGUAGE 'c'; - -CREATE FUNCTION find_in_set ($typename,$typename) - RETURNS bool - AS '$libtypename' - LANGUAGE 'c'; - -CREATE OPERATOR = ( - leftarg = $typename, - rightarg = $typename, - commutator = =, - procedure = $typename"."_eq -); - -CREATE OPERATOR <> ( - leftarg = $typename, - rightarg = $typename, - commutator = <>, - negator = =, - procedure = $typename"."_eq -); - -\n"; - - print LIBTYPES $func_in; - print LIBTYPES $func_out; - s/set\(.*?\)/$typename/i; - } - -# Change multy-field keys to multi-field indices -# MySQL Dump usually ends the CREATE TABLE statement like this: -# CREATE TABLE bids ( -# ... -# PRIMARY KEY (bids_id), -# KEY offer_id (offer_id,user_id,the_time), -# KEY bid_value (bid_value) -# ); -# We want to replace this with smth like -# CREATE TABLE bids ( -# ... -# PRIMARY KEY (bids_id), -# ); -# CREATE INDEX offer_id ON bids (offer_id,user_id,the_time); -# CREATE INDEX bid_value ON bids (bid_value); - if (s/CREATE TABLE (.*) /CREATE TABLE $dq$1$dq /i) { - if($oldtable ne $table_name) { - $oldtable=$table_name; - $j=-1; - $check=''; - - if($seq{$table_name} ne '') { - print "\n\n--"; - print "\n-- Sequences for table ".uc($table_name); - print "\n--\n"; - print "\nCREATE SEQUENCE ".$seq{$table_name}.";\n\n"; - } - - print $types; - $types=''; - $dump=~s/,\n\).*;/\n\);/gmi; -# removing table options after closing bracket: -# ) TYPE=ISAM PACK_KEYS=1; - $dump=~s/\n\).*/\n\);/gmi; - print $dump; - $dump=''; - } - $table_name=$1; - } - -# output CHECK constraints instead UNSIGNED modifiers - if(/PRIMARY KEY \((.*)\)/i) { - my $tmpfld=$1; - $tmpfld=~s/,/","/g if $dq; - $tmpfld=~s/ //g; - s/PRIMARY KEY (\(.*\))/PRIMARY KEY \($dq$tmpfld$dq\)/i; - s/(PRIMARY KEY \(.*\)).*/$1$check\n/i; - } - - if(/^\s*KEY ([\w\d_]+)\s*\((.*)\).*/i) { - my $tmpfld=$2; my $ky=$1; - $tmpfld=~s/\s*,\s*/","/g if $dq; - $index{$table_name}[++$j]="CREATE INDEX ${ky}_$table_name\_index ON $dq$table_name$dq ($dq$tmpfld$dq);"; - } - if(/^\s*UNIQUE.*?([\w\d_]+)\s*\((.*)\).*/i) { - my $tmpfld=$2; my $ky=$1; - $tmpfld=~s/,/","/g if $dq; - $index{$table_name}[++$j]="CREATE UNIQUE INDEX ${ky}_$table_name\_index ON $dq$table_name$dq ($dq$tmpfld$dq);"; - } - s/^\s*UNIQUE (.+).*(\(.*\)).*\n//i; - s/^\s*KEY (.+).*(\(.*\)).*\n//i; - - if($dq && !/^\s*(PRIMARY KEY|UNIQUE |KEY |CREATE TABLE |\);)/i){ - s/\s([A-Za-z_\d]+)\s/ $dq$+$dq /; - } - } ####if($tabledef)############################### - - if($dq && !s/INSERT INTO\s+?(.*?)\s+?/INSERT INTO $dq$1$dq /i) { -# Quote lowercase identifiers in double quotes - #while(!/^--/ && s/\s([A-Za-z_\d]+[a-z][A-Za-z_\d]*)\s/ $dq$+$dq /) {;} - } - -# Fix timestamps - s/'0000-00-00/'0001-01-01/g; -# may work wrong !!! - s/([,(])00000000000000([,)])/$1'00010101 000000'$2/g; - s/([,(])(\d{8})(\d{6})([,)])/$1'$2 $3'$4/g; - s/([,(])(\d{4})(\d{2})(\d{2})([,)])/$1'$2-$3-$4 00:00:00'$5/g; -# --------------------------------------------------- -# -------------------------------------------------- - $dump.=$_; -} - -if($seq{$table_name} ne '') { - print "\n\n--"; - print "\n-- Sequences for table ".uc($table_name); - print "\n--\n"; - print "\nCREATE SEQUENCE ".$seq{$table_name}.";\n\n"; -} -print $types; -$dump=~s/,\n\).*;/\n\);/gmi; -$dump=~s/\n\).*/\n\);/gmi; -print $dump; - -# Output indices for tables -while(my($table,$ind)=each(%index)) { - print "\n\n--"; - print "\n-- Indexes for table ".uc($table); - print "\n--\n"; - for(my $i=0;$i<=$#{$ind};$i++) { - print "\n$ind->[$i]"; - } - -} - -while(my($table,$s)=each(%seq)) { - print "\n\n--"; - print "\n-- Sequences for table ".uc($table); - print "\n--\n"; - - # setting SERIAL sequence values right - if($primary{$table} ne '') { - print "\nSELECT SETVAL('".$seq{$table}."',(select case when max($dq".$primary{$table}."$dq)>0 then max($dq".$primary{$table}."$dq)+1 else 1 end from $dq$table$dq));"; - } -} - -print("\n\nCOMMIT;\n"); -close(LIBTYPES); - -open(MAKE,">Makefile"); -print MAKE "# -# My2Pg \$Revision: 1.8 $ \translated dump -# Makefile -# - -all: libtypes.so - -libtypes.o: libtypes.c - gcc -c -fPIC -g -O libtypes.c -libtypes.so: libtypes.o - ld -Bshareable -o libtypes.so libtypes.o"; -close(MAKE); - -# -# Function generates unique identifier -# Args : template name, max length -# Globals: %identifier -# -sub new_name() { - my $name=lc(shift @_); - my $len=shift @_; - -# truncate long names - if(length($name)>$len) { - $name=~s/(.{$len}).*/$1/i; - } - -# find reserved identifiers - if($identifier{$name}!=1) { - $identifier{$name}=1; - return $name; - } - else { - for(my $i=1,my $tmpname=$name.$i;$identifier{$tmpname}!=1;) { - $tmpname=$name.$i - } - $identifier{$tmpname}=1; - return $tmpname; - } - - die "Error during unique identifier generation :-("; -} - -sub usage() { -print < -Copyright (c) 2000 Valentine Danilchuk - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -code source for license details. - -SYNTAX: - my2pg [-hnd] - -OPTIONS: - h - this help - n - convert *CHAR NOT NULL DEFAULT '' types to *CHAR NULL - d - double quotes around table and column names -EOF -; -} - - -=head1 NAME - -my2pg - MySQL -> PostgreSQL dump conversion utility. - -=head1 SYNTAX - - mysqldump db | ./my2pg.pl [-n] > pgsqldump.sql - vi libtypes.c - make - psql database < pgsqldump.txt -where - -=over 4 - -=item B - -- file suitable for loading into PostgreSQL. - -=item B - -- C source for emulated MySQL types (ENUM, SET) generated by B - -=back - -=head1 OVERVIEW - -B utility attempts to convert MySQL database dump to Postgres's one. -B performs such conversions: - -=over 4 - -=item Type conversion. - -It tries to find proper Postgres -type for each column. -Unknown types are silently pushing to output dump; -ENUM and SET types implemented via user types -(C source for such types can be found in -B file); - -=item Identifiers double-quotation. - -All column and table -names should be enclosed to double-quotes to prevent -interferension with reserved words; - -=item Converting - -AUTO_INCREMENT fields to SERIAL. Actually, creating the sequence and -setting default value to nextval('seq'), well, you know :) - -=item Converting - -KEY(field) to CREATE INDEX i_field on table (field); - -=item The same - -for UNIQUE keys; - -=item Indices - -are creating AFTER rows insertion (to speed up the load); - -=item Translates '#' - -MySQL comments to ANSI SQL '--' - -=back - -It encloses dump in transaction block to prevent single errors -during data load. - -=head1 COMMAND-LINE OPTIONS - -My2pg takes the following command-line options: - -=over 2 - -=item -n - -Convert *CHAR DEFAULT '' NOT NULL types to *CHAR NULL. -Postgres can't load empty '' strings in NOT NULL fields. - -=item -d - -Add double quotes around table and column names - -=item -h - -Show usage banner. - -=back - -=head1 SIDE EFFECTS - -=over 4 - -=item creates - -file B in current directory -overwriting existed file without any checks; - -=item the same - -for Makefile. - -=back - -=head1 BUGS - -This program is still beta. Testers wanted. -Known bugs are: - -=over 4 - -=item Poor doublequotation. - -All identifiers such as table and column names should be enclosed in double -quotes. Program can't handle upper-case identifiers, -like DBA. Lower-case identifiers are OK. - -=item SET type emulation is not full. LIKE operation on - -SETs, raw integer input values should be implemented - -=item B generated during output is -platform-dependent and surely works only on -Linux/gcc (FreeBSD/gcc probably works as well - not tested) - -=item Generated B contain line - - #include - -This file may be located not in standard compiler -include path, you need to check it before compiling. - -=back - -=head1 AUTHORS - -B<(c) 2000 Maxim V. Rudensky (fonin@ziet.zhitomir.ua)> -B<(c) 2000 Valentine V. Danilchuk (valdan@ziet.zhitomir.ua)> - -=head1 CREDITS - -Jeff Waugh -Joakim Lemström || -Yunliang Yu -Brad Hilton - -=head1 LICENSE - -B - -=cut diff --git a/contrib/mysql/mysql2pgsql b/contrib/mysql/mysql2pgsql deleted file mode 100755 index a51dfde53e..0000000000 --- a/contrib/mysql/mysql2pgsql +++ /dev/null @@ -1,283 +0,0 @@ -# -*- perl -*- -# mysql2pgsql -# Take a MySQL schema dump and turn it into SQL92 and PostgreSQL form. -# Thomas Lockhart, (c) 2000, PostgreSQL Inc. -# Thanks to Tim Perdue at SourceForge.Net for testing and feedback. -# - -eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' - & eval 'exec perl -S $0 $argv:q' - if 0; - -use IO::File; -use Getopt::Long; - -my $progname = "mysql2pgsql"; -my $version = "0.3"; - -GetOptions("debug!", "verbose!", "version", "path=s", "help", "data!"); - -my $debug = $opt_debug || 0; -my $verbose = $opt_verbose || 0; -my $pathfrom = $opt_path || ""; -my $nodata = (! $opt_data); - -$pathfrom = "$pathfrom/" if ($pathfrom =~ /.*[^\/]$/); - -print "$0: $progname version $version\n" - if ($opt_version || $opt_help); -print "\t(c) 2000 Thomas Lockhart PostgreSQL Inc.\n" - if ($opt_version && $opt_verbose || $opt_help); - -if ($opt_help) { - print "$0 --verbose --version --help --path=dir --nodata infile ...\n"; - exit; -} - -while (@ARGV) { - my $ostem; - my $oname; - my $pname; - my @xargs; - - $iname = shift @ARGV; - $ostem = $iname; - $ostem = $1 if ($ostem =~ /.+\/([^\/]+)$/); - $ostem = $1 if ($ostem =~ /(.+)[.][^.]*$/); - - $oname = "$ostem.sql92"; - $pname = "$ostem.init"; - - @xargs = ($iname, $oname); - push @xargs, $pname unless ($nodata); - - print "@xargs\n" if ($debug); - - TransformDumpFile($iname, $oname, $pname); -} - -exit; - -sub TransformDumpFile { - local ($iname, $oname, $pname) = @_; - local @dlines; - local @slines; - local @plines; - local @tables; # list of tables created - local %pkeys; - local %pseqs; - local %sequences; - - open(IN, "<$iname") || die "Unable to open file $iname"; - - while () { - chomp; - push @dlines, $_; - } - - print("Calling CreateSchema with $#dlines lines\n") if ($debug); - @slines = CreateSchema(@dlines); - - open(OUT, ">$oname") || die "Unable to open output file $oname"; - - foreach (@slines) { - print "> $_" if ($debug); - print OUT "$_"; - } - close(OUT); - - return if (! defined($pname)); - - @plines = PopulateSchema(@tables); - - open(OUT, ">$pname") || die "Unable to open output file $pname"; - - foreach (@plines) { - print "> $_" if ($debug); - print OUT "$_"; - } - close(OUT); -} - -sub PopulateSchema { - local @tables = @_; - local @out; - local $pkey; - local $pseq; - - foreach (@tables) { - $table = $_; - $tpath = "$pathfrom$table"; - - print "Table is $table\n" if ($debug); - push @out, "\n"; - push @out, "copy $table from '$tpath.txt';\n"; - if (defined($pkeys{$table})) { - foreach ($pkeys{$table}) { - $pkey = $_; - $pseq = $pseqs{$table}; - - print "Key for $table is $pkey on $pseq\n" if ($debug); - -# //push @out, "\$value = select max($pkey) from $table;\n"; - push @out, "select setval ('$pseq', (select max($pkey) from $table));\n"; - } - } - } - - return @out; -} - -sub CreateSchema { - local @lines = @_; - local @out; - -# undef $last; - local %knames; - - push @out, "--\n"; - push @out, "-- Generated from mysql2pgsql\n"; - push @out, "-- (c) 2000, Thomas Lockhart, PostgreSQL Inc.\n"; - push @out, "--\n"; - push @out, "\n"; - - while (@lines) { - $_ = shift @lines; - print "< $_\n" if ($debug); - # Replace hash comments with SQL9x standard syntax - $_ = "-- $1" if (/^[\#](.*)/); - - # Found a CREATE TABLE statement? - if (/(create\s+table)\s+(\w+)\s+([(])\s*$/i) { - $table = $2; - $table = "\"$1\"" if ($table =~ /^(user)$/); - push @tables, $table; - push @tabledef, "create table $table ("; -# push @out, "$_\n"; - - while (@lines) { - $_ = shift @lines; - print "< $_\n" if ($debug); - - # Replace int(11) with SQL9x standard syntax - while (/int\(\d*\)/gi) { - $_ = "$`integer$'"; - } - - # Replace float(10,2) with SQL9x standard syntax - while (/(float)\((\d+),\s*(\d+)\)/gi) { - $_ = "$`$1($2)$'"; - } - - # Replace smallinteger with SQL9x syntax - while (/smallinteger/gi) { - $_ = "$`integer$'"; - } - - # Replace mediumtext with PostgreSQL syntax - while (/(longtext|mediumtext|blob|largeblob)/gi) { - $_ = "$`text$'"; - } - - # Replace integer ... auto_increment with PostgreSQL syntax - while (/(\s*)(\w+)\s+integer\s+(.*)\s+auto_increment/gi) { - $serid = $table . "_pk_seq"; - push @out, "-- serial identifier $serid will likely be truncated\n" - if (length($serid) >= 32); - - if (length($serid) >= 32) { - $excess=(length($serid)-31); - $serid = substr($table,0,-($excess)) . "_pk_seq"; - push @out, "-- serial identifier $serid was truncated\n"; - } - push @out, "CREATE SEQUENCE $serid;\n\n"; - $pkeys{$table} = $2; - $pseqs{$table} = $serid; - push @out, "-- key is $pkeys{$table}, sequence is $pseqs{$table}\n" if ($debug); - $_ = "$`$1$2 integer default nextval('$serid') $3$'"; - } - - # Replace date with double-quoted name -# while (/^(\s*)(date|time)(\s+)/gi) { -# $_ = "$1\"$2\"$3$'"; -# } - - # Found "KEY"? Then remove it from the CREATE TABLE statement - # and instead write a CREATE INDEX statement. - if (/^\s*key\s+(\w+)\s*[(](\w[()\w\d,\s]*)[)][,]?/i) { - $iname = $1; - $column = $2; - $iname = $1 if ($iname =~ /^idx_(\w[\_\w\d]+)/); - # Sheesh, there can be upper bounds on index string sizes? - # Get rid of the length specifier (e.g. filename(45) -> filename) - while ($column =~ /(\w[\w\d])[(]\d+[)]/g) { - $column = "$`$1$'"; - } -# $column = $1 if ($column =~ /(\w+)[(]\d+[)]/); -# push @out, "Index on $table($column) is $iname\n"; - if (defined($knames{$iname})) { - push @out, "-- $iname already exists"; -# sprintf($iname, "idx_%_%s", $table, $iname); -# $iname = "idx_" . $table . "_" . $column; - # Do not bother with more to the name; it will be too big anyway - $iname = $table . "_" . $column; - push @out, "; use $iname instead\n"; - } - $knames{$iname} = $iname; - $keydef{$column} = $iname; -# push @out, "! $_\n"; -# $last = $tabledef[$#tabledef]; -# push @out, "? $#tabledef $last\n"; -# push @out, "match $1\n" if ($last =~ /(.*),\s*$/); - # Remove the trailing comma from the previous line, if necessary - $tabledef[$#tabledef] = $1 - if (($#tabledef > 0) && ($tabledef[$#tabledef] =~ /(.*),\s*$/)); -# push @out, "? $tabledef[$#tabledef]\n"; - - # If this is the end of the statement, save it and exit loop - } elsif (/^\s*[)]\;/) { - push @tabledef, $_; -# push @out, "< $_\n"; - last; - - # Otherwise, just save the line - } else { -# push @out, "$last\n" if (defined($last)); -# $last = $_; - push @tabledef, $_; -# push @out, "$_\n"; - } - } - - foreach $t (@tabledef) { - push @out, "$t\n"; - } - undef @tabledef; - - foreach $k (keys %keydef) { - push @out, "create index $keydef{$k} on $table ($k);\n"; - } - undef %keydef; - - } else { - push @out, "$_\n"; - } - } - -# push @out, "$last\n" if (defined($last)); - - foreach (keys %pkeys) { - my $val = $pkeys{$_}; - print "key is $val\n" if ($debug); - } - - return @out; -} - -sub StripComma { - local $line = shift @_; - - $line = "$1" if ($line =~ /(.*)[,]\s*$/); - - return $line; -} diff --git a/contrib/noupdate/Makefile b/contrib/noupdate/Makefile deleted file mode 100644 index 950db73891..0000000000 --- a/contrib/noupdate/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/noupdate/Attic/Makefile,v 1.9 2001/09/06 10:49:29 petere Exp $ - -subdir = contrib/noupdate -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -MODULES = noup -DATA_built = noup.sql -DOCS = README.noup - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/noupdate/README.noup b/contrib/noupdate/README.noup deleted file mode 100644 index 1c773dc778..0000000000 --- a/contrib/noupdate/README.noup +++ /dev/null @@ -1,20 +0,0 @@ - - -noupdate -~~~~~~~~ - - - trigger to prevent updates on single columns. - - -Example: -~~~~~~~ - -CREATE TABLE TEST ( COL1 INT, COL2 INT, COL3 INT ); - -CREATE TRIGGER BT BEFORE UPDATE ON TEST FOR EACH ROW - EXECUTE PROCEDURE - noup ('COL1'); - --- Now Try -INSERT INTO TEST VALUES (10,20,30); -UPDATE TEST SET COL1 = 5; diff --git a/contrib/noupdate/noup.c b/contrib/noupdate/noup.c deleted file mode 100644 index 3fac897742..0000000000 --- a/contrib/noupdate/noup.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * noup.c -- functions to remove update permission from a column - */ - -#include "executor/spi.h" /* this is what you need to work with SPI */ -#include "commands/trigger.h" /* -"- and triggers */ -#include /* tolower () */ - -extern Datum noup(PG_FUNCTION_ARGS); - -/* - * noup () -- revoke permission on column - * - * Though it's called without args You have to specify referenced - * table/column while creating trigger: - * EXECUTE PROCEDURE noup ('col'). - */ - -PG_FUNCTION_INFO_V1(noup); - -Datum -noup(PG_FUNCTION_ARGS) -{ - TriggerData *trigdata = (TriggerData *) fcinfo->context; - Trigger *trigger; /* to get trigger name */ - int nargs; /* # of args specified in CREATE TRIGGER */ - char **args; /* arguments: column names and table name */ - int nkeys; /* # of key columns (= nargs / 2) */ - Datum *kvals; /* key values */ - Relation rel; /* triggered relation */ - HeapTuple tuple = NULL; /* tuple to return */ - TupleDesc tupdesc; /* tuple description */ - bool isnull; /* to know is some column NULL or not */ - int ret; - int i; - - /* - * Some checks first... - */ - - /* Called by trigger manager ? */ - if (!CALLED_AS_TRIGGER(fcinfo)) - elog(ERROR, "noup: not fired by trigger manager"); - - /* Should be called for ROW trigger */ - if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) - elog(ERROR, "noup: can't process STATEMENT events"); - - /* Not should be called for INSERT */ - if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) - elog(ERROR, "noup: can't process INSERT events"); - - /* Not should be called for DELETE */ - else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) - elog(ERROR, "noup: can't process DELETE events"); - - /* check new Tuple */ - tuple = trigdata->tg_newtuple; - - trigger = trigdata->tg_trigger; - nargs = trigger->tgnargs; - args = trigger->tgargs; - - nkeys = nargs; - rel = trigdata->tg_relation; - tupdesc = rel->rd_att; - - /* Connect to SPI manager */ - if ((ret = SPI_connect()) < 0) - elog(ERROR, "noup: SPI_connect returned %d", ret); - - /* - * We use SPI plan preparation feature, so allocate space to place key - * values. - */ - kvals = (Datum *) palloc(nkeys * sizeof(Datum)); - - /* For each column in key ... */ - for (i = 0; i < nkeys; i++) - { - /* get index of column in tuple */ - int fnumber = SPI_fnumber(tupdesc, args[i]); - - /* Bad guys may give us un-existing column in CREATE TRIGGER */ - if (fnumber < 0) - elog(ERROR, "noup: there is no attribute %s in relation %s", - args[i], SPI_getrelname(rel)); - - /* Well, get binary (in internal format) value of column */ - kvals[i] = SPI_getbinval(tuple, tupdesc, fnumber, &isnull); - - /* - * If it's NOT NULL then cancel update - */ - if (!isnull) - { - - elog(WARNING, "%s: update not allowed", args[i]); - SPI_finish(); - return PointerGetDatum(NULL); - } - - } - - SPI_finish(); - return PointerGetDatum(tuple); -} diff --git a/contrib/noupdate/noup.sql.in b/contrib/noupdate/noup.sql.in deleted file mode 100644 index abf92837d1..0000000000 --- a/contrib/noupdate/noup.sql.in +++ /dev/null @@ -1,6 +0,0 @@ -DROP FUNCTION noup (); - -CREATE FUNCTION noup () - RETURNS opaque - AS 'MODULE_PATHNAME' - LANGUAGE 'C'; diff --git a/contrib/oid2name/Makefile b/contrib/oid2name/Makefile deleted file mode 100644 index c69083c57c..0000000000 --- a/contrib/oid2name/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/oid2name/Makefile,v 1.4 2001/09/06 10:49:29 petere Exp $ - -subdir = contrib/oid2name -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -PROGRAM = oid2name -OBJS = oid2name.o - -PG_CPPFLAGS = -I$(libpq_srcdir) -PG_LIBS = $(libpq) - -DOCS = README.oid2name - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/oid2name/README.oid2name b/contrib/oid2name/README.oid2name deleted file mode 100644 index 2e63ae31ff..0000000000 --- a/contrib/oid2name/README.oid2name +++ /dev/null @@ -1,129 +0,0 @@ -This utility allows administrators to view the file structure used by -PostgreSQL. Databases are placed in directories based on their OIDs in -pg_database, and the tables in that directory are named by their OIDs, -stored in pg_class.relfilenode. Oid2name connects to the database and -extracts the OID and table name information. - ---------------------------------------------------------------------------- - -It can be used in four ways: - - -oid2name - - This will connect to the template1 database and display all databases - in the system: - - $ oid2name - All databases: - --------------------------------- - 18720 = test1 - 1 = template1 - 18719 = template0 - 18721 = test - 18735 = postgres - 18736 = cssi - - -oid2name -d test [-x] - - This connects to the database test and shows all tables and their OIDs: - - $ oid2name -d test - All tables from database "test": - --------------------------------- - 18766 = dns - 18737 = ips - 18722 = testdate - - -oid2name -d test -o 18737 -oid2name -d test -t testdate - - This will connect to the database test and display the table name for oid - 18737 and the oid for table name testdate respectively: - - $ oid2name -d test -o 18737 - Tablename of oid 18737 from database "test": - --------------------------------- - 18737 = ips - - - $ oid2name -d test -t testdate - Oid of table testdate from database "test": - --------------------------------- - 18722 = testdate - ---------------------------------------------------------------------------- - -Sample session: - -$ cd /u/pg/data/base -$ oid2name -All databases: ---------------------------------- -16817 = test2 -16578 = x -16756 = test -1 = template1 -16569 = template0 -16818 = test3 -16811 = floattest - -$ cd 16756 -$ ls 1873* -18730 18731 18732 18735 18736 18737 18738 18739 - -$ oid2name -d test -o 18737 -Tablename of oid 18737 from database "test": ---------------------------------- -18737 = ips - -$ oid2name -d test -t ips -Oid of table ips from database "test": ---------------------------------- -18737 = ips - -$ # show disk space for every db object -$ du * | while read SIZE OID -> do -> echo "$SIZE `oid2name -q -d test -o $OID`" -> done -24 18737 = ips -36 18722 = cities -... - -$ # same as above, but sort by largest first -$ du * | while read SIZE OID -> do -> echo "$SIZE `oid2name -q -d test -o $OID`" -> done | -> sort -rn -2048 19324 = bigtable -1950 23903 = customers -... - -$ # show disk usage per database -$ cd /u/pg/data/base -$ du -s * | -> while read SIZE OID -> do -> echo "$SIZE `aspg oid2name -q | grep ^$OID' '`" -> done | -> sort -rn -2256 18721 = test -2135 18735 = postgres -.. - -This can be done in psql with: - -test=> SELECT relpages, relfilenode, relname FROM pg_class ORDER BY relpages DESC; - -Each page is typically 8k. Relpages is updated by VACUUM. - ---------------------------------------------------------------------------- - -Mail me with any problems or additions you would like to see. Clearing -house for the code will be at: http://www.crimelabs.net - -b. palmer, bpalmer@crimelabs.net diff --git a/contrib/oid2name/oid2name.c b/contrib/oid2name/oid2name.c deleted file mode 100644 index 6c3e7d420a..0000000000 --- a/contrib/oid2name/oid2name.c +++ /dev/null @@ -1,467 +0,0 @@ -/* - oid2name; a postgresql 7.1 (+?) app to map OIDs on the filesystem - to table and database names. - - b. palmer, bpalmer@crimelabs.net 1-17-2001 - - */ -#include "postgres_fe.h" - -#include -#ifdef HAVE_GETOPT_H -#include -#endif - -#include "libpq-fe.h" - -/* these are the opts structures for command line params */ -struct options -{ - int getdatabase; - int gettable; - int getoid; - - int quiet; - - int systables; - - int remotehost; - int remoteport; - int remoteuser; - int remotepass; - - int _oid; - char _dbname[128]; - char _tbname[128]; - - char _hostname[128]; - char _port[6]; - char _username[128]; - char _password[128]; -}; - -/* function prototypes */ -void get_opts(int, char **, struct options *); -PGconn *sql_conn(const char *, struct options *); -void sql_exec_error(int); -int sql_exec(PGconn *, const char *, int); -void sql_exec_dumpdb(PGconn *); -void sql_exec_dumptable(PGconn *, int); -void sql_exec_searchtable(PGconn *, const char *); -void sql_exec_searchoid(PGconn *, int); - -/* fuction to parse command line options and check for some usage errors. */ -void -get_opts(int argc, char **argv, struct options * my_opts) -{ - int c; - - /* set the defaults */ - my_opts->getdatabase = 0; - my_opts->gettable = 0; - my_opts->getoid = 0; - - my_opts->quiet = 0; - - my_opts->systables = 0; - - my_opts->remotehost = 0; - my_opts->remoteport = 0; - my_opts->remoteuser = 0; - my_opts->remotepass = 0; - - /* get opts */ - while ((c = getopt(argc, argv, "H:p:U:P:d:t:o:qxh?")) != -1) - { - switch (c) - { - /* specify the database */ - case 'd': - my_opts->getdatabase = 1; - sscanf(optarg, "%s", my_opts->_dbname); - break; - - /* specify the table name */ - case 't': - /* make sure we set the database first */ - if (!my_opts->getdatabase) - { - fprintf(stderr, "You must specify a database to dump from.\n"); - exit(1); - } - /* make sure we don't try to do a -o also */ - if (my_opts->getoid) - { - fprintf(stderr, "You can only specify either oid or table\n"); - exit(1); - } - - my_opts->gettable = 1; - sscanf(optarg, "%s", my_opts->_tbname); - - break; - - /* specify the oid int */ - case 'o': - /* make sure we set the database first */ - if (!my_opts->getdatabase) - { - fprintf(stderr, "You must specify a database to dump from.\n"); - exit(1); - } - /* make sure we don't try to do a -t also */ - if (my_opts->gettable) - { - fprintf(stderr, "You can only specify either oid or table\n"); - exit(1); - } - - my_opts->getoid = 1; - sscanf(optarg, "%i", &my_opts->_oid); - - break; - - case 'q': - my_opts->quiet = 1; - break; - - /* host to connect to */ - case 'H': - my_opts->remotehost = 1; - sscanf(optarg, "%s", my_opts->_hostname); - break; - - /* port to connect to on remote host */ - case 'p': - my_opts->remoteport = 1; - sscanf(optarg, "%s", my_opts->_port); - break; - - /* username */ - case 'U': - my_opts->remoteuser = 1; - sscanf(optarg, "%s", my_opts->_username); - break; - - /* password */ - case 'P': - my_opts->remotepass = 1; - sscanf(optarg, "%s", my_opts->_password); - break; - - /* display system tables */ - case 'x': - my_opts->systables = 1; - break; - - /* help! (ugly in code for easier editing) */ - case '?': - case 'h': - fprintf(stderr, "\ -Usage: pg_oid2name [-d database [-x] ] [-t table | -o oid]\n\ - default action display all databases\n\ - -d database database to oid2name\n\ - -x display system tables\n\ - -t table | -o oid search for table name (-t) or\n\ - oid (-o) in -d database\n\ - -q quiet\n\ - -H host connect to remote host\n\ - -p port host port to connect to\n\ - -U username username to connect with\n\ - -P password password for username\n\ -"); - exit(1); - break; - } - } -} - -/* establish connection with database. */ -PGconn * -sql_conn(const char *dbName, struct options * my_opts) -{ - char *pghost, - *pgport; - char *pgoptions, - *pgtty; - char *pguser, - *pgpass; - - PGconn *conn; - - pghost = NULL; - pgport = NULL; - pgoptions = NULL; /* special options to start up the backend - * server */ - pgtty = NULL; /* debugging tty for the backend server */ - pguser = NULL; - pgpass = NULL; - - /* override the NULLs with the user params if passed */ - if (my_opts->remotehost) - { - pghost = (char *) malloc(128); - sscanf(my_opts->_hostname, "%s", pghost); - } - - if (my_opts->remoteport) - { - pgport = (char *) malloc(6); - sscanf(my_opts->_port, "%s", pgport); - } - - if (my_opts->remoteuser) - { - pguser = (char *) malloc(128); - sscanf(my_opts->_username, "%s", pguser); - } - - if (my_opts->remotepass) - { - pgpass = (char *) malloc(128); - sscanf(my_opts->_password, "%s", pgpass); - } - - /* login */ - conn = PQsetdbLogin(pghost, pgport, pgoptions, pgtty, dbName, pguser, pgpass); - - /* deal with errors */ - if (PQstatus(conn) == CONNECTION_BAD) - { - fprintf(stderr, "Connection to database '%s' failed.\n", dbName); - fprintf(stderr, "%s", PQerrorMessage(conn)); - - PQfinish(conn); - exit(1); - } - - /* free data structures: not strictly necessary */ - if (pghost != NULL) - free(pghost); - if (pgport != NULL) - free(pgport); - if (pguser != NULL) - free(pguser); - if (pgpass != NULL) - free(pgpass); - - /* return the conn if good */ - return conn; -} - -/* If the sql_ command has an error, this function looks up the error number and prints it out. */ -void -sql_exec_error(int error_number) -{ - fprintf(stderr, "Error number %i.\n", error_number); - switch (error_number) - { - case 3: - fprintf(stderr, "Error: PGRES_COPY_OUT\n"); - break; - - case 4: - fprintf(stderr, "Error: PGRES_COPY_IN\n"); - break; - - case 5: - fprintf(stderr, "Error: PGRES_BAD_RESPONCE\n"); - break; - - case 6: - fprintf(stderr, "Error: PGRES_NONFATAL_ERROR\n"); - break; - - case 7: - fprintf(stderr, "Error: PGRES_FATAL_ERROR\n"); - break; - } -} - -/* actual code to make call to the database and print the output data */ -int -sql_exec(PGconn *conn, const char *todo, int match) -{ - PGresult *res; - - int numbfields; - int error_number; - int i, - len; - - /* make the call */ - res = PQexec(conn, todo); - - /* check and deal with errors */ - if (!res || PQresultStatus(res) > 2) - { - error_number = PQresultStatus(res); - fprintf(stderr, "There was an error in the SQL command:\n%s\n", todo); - sql_exec_error(error_number); - fprintf(stderr, "PQerrorMessage = %s\n", PQerrorMessage(conn)); - - PQclear(res); - PQfinish(conn); - exit(-1); - } - - /* get the number of fields */ - numbfields = PQntuples(res); - - /* if we only expect 1 and there mode than, return -2 */ - if (match == 1 && numbfields > 1) - return -2; - - /* return -1 if there aren't any returns */ - if (match == 1 && numbfields < 1) - return -1; - - /* for each row, dump the information */ - for (i = 0; i < numbfields; i++) - { - len = strlen(PQgetvalue(res, i, 0)); - - fprintf(stdout, "%-6s = %s\n", PQgetvalue(res, i, 0), PQgetvalue(res, i, 1)); - } - - /* clean the PGconn once done */ - PQclear(res); - - return 0; -} - -/* dump all databases known by the system table */ -void -sql_exec_dumpdb(PGconn *conn) -{ - char todo[1024]; - - /* get the oid and database name from the system pg_database table */ - sprintf(todo, "select oid,datname from pg_database"); - - sql_exec(conn, todo, 0); -} - -/* display all tables in whatever db we are connected to. don't display the - system tables by default */ -void -sql_exec_dumptable(PGconn *conn, int systables) -{ - char todo[1024]; - - /* don't exclude the systables if this is set */ - if (systables == 1) - sprintf(todo, "select relfilenode,relname from pg_class order by relname"); - else - sprintf(todo, "select relfilenode,relname from pg_class where relname not like 'pg_%%' order by relname"); - - sql_exec(conn, todo, 0); -} - -/* display the oid for a given tablename for whatever db we are connected - to. do we want to allow %bar% in the search? Not now. */ -void -sql_exec_searchtable(PGconn *conn, const char *tablename) -{ - int returnvalue; - char todo[1024]; - - /* get the oid and tablename where the name matches tablename */ - sprintf(todo, "select relfilenode,relname from pg_class where relname = '%s'", tablename); - - returnvalue = sql_exec(conn, todo, 1); - - /* deal with the return errors */ - if (returnvalue == -1) - printf("No tables with that name found\n"); - - if (returnvalue == -2) - printf("VERY scary: more than one table with that name found!!\n"); -} - -/* same as above */ -void -sql_exec_searchoid(PGconn *conn, int oid) -{ - int returnvalue; - char todo[1024]; - - sprintf(todo, "select relfilenode,relname from pg_class where oid = %i", oid); - - returnvalue = sql_exec(conn, todo, 1); - - if (returnvalue == -1) - printf("No tables with that oid found\n"); - - if (returnvalue == -2) - printf("VERY scary: more than one table with that oid found!!\n"); -} - -int -main(int argc, char **argv) -{ - struct options *my_opts; - PGconn *pgconn; - - my_opts = (struct options *) malloc(sizeof(struct options)); - - /* parse the opts */ - get_opts(argc, argv, my_opts); - - /* display all the tables in the database */ - if (my_opts->getdatabase & my_opts->gettable) - { - if (!my_opts->quiet) - { - printf("Oid of table %s from database \"%s\":\n", my_opts->_tbname, my_opts->_dbname); - printf("---------------------------------\n"); - } - pgconn = sql_conn(my_opts->_dbname, my_opts); - sql_exec_searchtable(pgconn, my_opts->_tbname); - PQfinish(pgconn); - - exit(1); - } - - /* search for the tablename of the given OID */ - if (my_opts->getdatabase & my_opts->getoid) - { - if (!my_opts->quiet) - { - printf("Tablename of oid %i from database \"%s\":\n", my_opts->_oid, my_opts->_dbname); - printf("---------------------------------\n"); - } - pgconn = sql_conn(my_opts->_dbname, my_opts); - sql_exec_searchoid(pgconn, my_opts->_oid); - PQfinish(pgconn); - - exit(1); - } - - /* search for the oid for the given tablename */ - if (my_opts->getdatabase) - { - if (!my_opts->quiet) - { - printf("All tables from database \"%s\":\n", my_opts->_dbname); - printf("---------------------------------\n"); - } - pgconn = sql_conn(my_opts->_dbname, my_opts); - sql_exec_dumptable(pgconn, my_opts->systables); - PQfinish(pgconn); - - exit(1); - } - - /* display all the databases for the server we are connected to.. */ - if (!my_opts->quiet) - { - printf("All databases:\n"); - printf("---------------------------------\n"); - } - pgconn = sql_conn("template1", my_opts); - sql_exec_dumpdb(pgconn); - PQfinish(pgconn); - - exit(0); -} diff --git a/contrib/oracle/CHANGES b/contrib/oracle/CHANGES deleted file mode 100644 index 34851ecb65..0000000000 --- a/contrib/oracle/CHANGES +++ /dev/null @@ -1,51 +0,0 @@ -2001 05 09 - Initial version 1.0 - -2001 05 09 - Version 1.1 - - Add table grant extraction based on group. Oracle ROLES are groups in PG - -2001 05 11 - Version 1.2 - - Views extraction is now really done with the option type=>'VIEW' - - Add indexes extraction on tables. - - Changes name of constraints, default is now used. - - Add debug printing to see that the process is running :-) - - Add extraction of only required tablename. - - Add extraction of only n to n table indice. Indices of extraction can be obtained - with the option showtableid set to 1. - - Fix print of NOT NULL field. - - Complete rewrite of the grant extraction - - Complete rewrite of most things - -2001 06 20 - Version 1.3 - - Grant/privilege extraction are now done separatly with the option type=>'GRANT' - - Sequence extraction with the option type=>'SEQUENCE' - - Trigger extraction with the option type=>'TRIGGER' - - Function extraction with the option type=>'FUNCTION' and type=>'PROCEDURE' - - Complete rewrite of the foreign key extraction - - Fix incorrect type translation and many other bug fix - - Add schema only extraction by option schema => 'MYSCHEM' - -2001 06 27 - Version 1.4 - - Add online Oracle data extraction and insertion into PG database. - - Data export as insert statement (type => DATA) - - Data export as copy from stdin statement (type => COPY) - -2001 12 28 - Version 1.5 - - Fix LongReadLen problem when exporting Oracle data on LONG and LOB types - Thanks to Stephane Schildknecht for reporting and testing the fix. - - Add more precision on NUMBER type conversion - - Add conversion of type LONG, LOB, FILE - - Fix a problem when extracting data, sometime table could need to be prefixed - by the schema name. - - Fix output of Oracle data extraction. It now require a call to the function - export_data(). -2002 01 07 - Version 1.6 - - Fix problem exporting NULL value. Thanks to Stephane Schildknecht. - -2002 02 14 - Version 1.7 - - Remove export of OUTLINE object type. Thanks to Jean-Paul ARGUDO. - -2002 03 05 - Version 1.8 - - Add Oracle type FLOAT conversion to float8. - - Add column alias extraction on view. Thanks to Jean-Francois RIPOUTEAU - - Add PACKAGE extraction (type => DATA). - diff --git a/contrib/oracle/Ora2Pg.pm b/contrib/oracle/Ora2Pg.pm deleted file mode 100644 index e2dabfc75b..0000000000 --- a/contrib/oracle/Ora2Pg.pm +++ /dev/null @@ -1,1931 +0,0 @@ -package Ora2Pg; -#------------------------------------------------------------------------------ -# Project : Oracle to PostgreSQL database schema converter -# Name : Ora2Pg.pm -# Language : 5.006 built for i686-linux -# OS : linux RedHat 6.2 kernel 2.2.14-5 -# Authors : Gilles Darold, gilles@darold.net -# Copyright: Copyright (c) 2000 : Gilles Darold - All rights reserved - -# Function : Main module used to export Oracle database schema to PostgreSQL -# Usage : See documentation in this file with perldoc. -#------------------------------------------------------------------------------ -# This program is free software; you can redistribute it and/or modify it under -# the same terms as Perl itself. -#------------------------------------------------------------------------------ - -#use strict; -use vars qw($VERSION $PSQL); -use Carp qw(confess); -use DBI; - -$VERSION = "1.8"; -$PSQL = "psql"; - -=head1 NAME - -Ora2Pg - Oracle to PostgreSQL database schema converter - - -=head1 SYNOPSIS - - BEGIN { - $ENV{ORACLE_HOME} = '/usr/local/oracle/oracle816'; - } - - use strict; - - use Ora2Pg; - - # Init the database connection - my $dbsrc = 'dbi:Oracle:host=testdb.samse.fr;sid=TEST;port=1521'; - my $dbuser = 'system'; - my $dbpwd = 'manager'; - - # Create an instance of the Ora2Pg perl module - my $schema = new Ora2Pg ( - datasource => $dbsrc, # Database DBD datasource - user => $dbuser, # Database user - password => $dbpwd, # Database password - { - PrintError => 0, - RaiseError => 1, - AutoCommit => 0 - } - ); - - # Create the POSTGRESQL representation of all objects in the database - $schema->export_schema("output.sql"); - - exit(0); - -or if you only want to extract some tables: - - # Create an instance of the Ora2Pg perl module - my @tables = ('tab1', 'tab2', 'tab3'); - my $schema = new Ora2Pg ( - datasource => $dbsrc, # Database DBD datasource - user => $dbuser, # Database user - password => $dbpwd, # Database password - tables => \@tables, - or # Tables to extract - tables => [('tab1','tab2')], - debug => 1 # To show somethings when running - ); - -or if you only want to extract the 10 first tables: - - # Create an instance of the Ora2Pg perl module - my $schema = new Ora2Pg ( - datasource => $dbsrc, # Database DBD datasource - user => $dbuser, # Database user - password => $dbpwd, # Database password - max => 10 # 10 first tables to extract - ); - -or if you only want to extract tables 10 to 20: - - # Create an instance of the Ora2Pg perl module - my $schema = new Ora2Pg ( - datasource => $dbsrc, # Database DBD datasource - user => $dbuser, # Database user - password => $dbpwd, # Database password - min => 10, # Begin extraction at indice 10 - max => 20 # End extraction at indice 20 - ); - -To choose a particular Oracle schema to export just set the following option -to your schema name: - - schema => 'APPS' - -This schema definition can also be needed when you want to export data. If export -failed and complain that the table doesn't exists use this to prefix the table name -by the schema name. - -To know at which indices tables can be found during extraction use the option: - - showtableid => 1 - -To extract all views set the type option as follow: - - type => 'VIEW' - -To extract all grants set the type option as follow: - - type => 'GRANT' - -To extract all sequences set the type option as follow: - - type => 'SEQUENCE' - -To extract all triggers set the type option as follow: - - type => 'TRIGGER' - -To extract all functions set the type option as follow: - - type => 'FUNCTION' - -To extract all procedures set the type option as follow: - - type => 'PROCEDURE' - -To extract all packages and body set the type option as follow: - - type => 'PACKAGE' - -Default is table extraction - - type => 'TABLE' - -To extract all data from table extraction as INSERT statement use: - - type => 'DATA' - -To extract all data from table extraction as COPY statement use: - - type => 'COPY' - -and data_limit => n to specify the max tuples to return. If you set -this options to 0 or nothing, no limitation are used. Additional option -'table', 'min' and 'max' can also be used. - -When use of COPY or DATA you can export data by calling method: - -$schema->export_data("output.sql"); - -Data are dumped to the given filename or to STDOUT with no argument. -You can also send these data directly to a PostgreSQL backend using - the following method: - -$schema->send_to_pgdb($destdatasrc,$destuser,$destpasswd); - -In this case you must call export_data() without argument after the -call to method send_to_pgdb(). - -If you set type to COPY and you want to dump data directly to a PG database, -you must call method send_to_pgdb but data will not be sent via DBD::Pg but -they will be load to the database using the psql command. Calling this method -is istill required to be able to extract database name, hostname and port -information. Edit the $PSQL variable to match the path of your psql -command (nothing to edit if psql is in your path). - - -=head1 DESCRIPTION - -Ora2Pg is a perl OO module used to export an Oracle database schema -to a PostgreSQL compatible schema. - -It simply connect to your Oracle database, extract its structure and -generate a SQL script that you can load into your PostgreSQL database. - -I'm not a Oracle DBA so I don't really know something about its internal -structure so you may find some incorrect things. Please tell me what is -wrong and what can be better. - -It currently dump the database schema (tables, views, sequences, indexes, grants), -with primary, unique and foreign keys into PostgreSQL syntax without editing the -SQL code generated. - -It now can dump Oracle data into PostgreSQL DB as online process. You can choose -what columns can be exported for each table. - -Functions, procedures and triggers PL/SQL code generated must be reviewed to match -the PostgreSQL syntax. Some usefull recommandation on porting Oracle to PostgreSQL -can be found at http://techdocs.postgresql.org/ under the "Converting from other -Databases to PostgreSQL" Oracle part. I just notice one thing more is that the -trunc() function in Oracle is the same for number or date so be carefull when -porting to PostgreSQL to use trunc() for number and date_trunc() for date. - - -=head1 ABSTRACT - -The goal of the Ora2Pg perl module is to cover all part needed to export -an Oracle database to a PostgreSQL database without other thing that provide -the connection parameters to the Oracle database. - -Features must include: - - - Database schema export (tables, views, sequences, indexes), - with unique, primary and foreign key. - - Grants/privileges export by user and group. - - Table selection (by name and max table) export. - - Predefined functions/triggers/procedures/packages export. - - Data export. - - Sql query converter (todo) - -My knowledge regarding database is really poor especially for Oracle -so contribution is welcome. - - -=head1 REQUIREMENT - -You just need the DBI, DBD::Pg and DBD::Oracle perl module to be installed - - - -=head1 PUBLIC METHODS - -=head2 new HASH_OPTIONS - -Creates a new Ora2Pg object. - -Supported options are: - - - datasource : DBD datasource (required) - - user : DBD user (optional with public access) - - password : DBD password (optional with public access) - - schema : Oracle internal schema to extract - - type : Type of data to extract, can be TABLE,VIEW,GRANT,SEQUENCE, - TRIGGER,FUNCTION,PROCEDURE,DATA,COPY,PACKAGE - - debug : Print the current state of the parsing - - tables : Extract only the given tables (arrayref) - - showtableid : Display only the table indice during extraction - - min : Indice to begin extraction. Default to 0 - - max : Indice to end extraction. Default to 0 mean no limits - - data_limit : Number max of tuples to return during data extraction (default 10) - -Attempt that this list should grow a little more because all initialization is -done by this way. - -=cut - -sub new -{ - my ($class, %options) = @_; - - # This create an OO perl object - my $self = {}; - bless ($self, $class); - - # Initialize this object - $self->_init(%options); - - # Return the instance - return($self); -} - - -=head2 export_data FILENAME - -Print SQL data output to a filename or -to STDOUT if no file is given. - -Must be used only if type option is set to DATA or COPY -=cut - -sub export_data -{ - my ($self, $outfile) = @_; - - $self->_get_sql_data($outfile); -} - - -=head2 export_sql FILENAME - -Print SQL conversion output to a filename or -simply return these data if no file is given. - -=cut - -sub export_schema -{ - my ($self, $outfile) = @_; - - if ($outfile) { - # Send output to the given file - open(FILE,">$outfile") or die "Can't open $outfile: $!"; - print FILE $self->_get_sql_data(); - close FILE; - return; - } - - # Return data as string - return $self->_get_sql_data(); - -} - - -=head2 send_to_pgdb DEST_DATASRC DEST_USER DEST_PASSWD - -Open a DB handle to a PostgreSQL database - -=cut - -sub send_to_pgdb -{ - my ($self, $destsrc, $destuser, $destpasswd) = @_; - - # Connect the database - $self->{dbhdest} = DBI->connect($destsrc, $destuser, $destpasswd); - - $destsrc =~ /dbname=([^;]*)/; - $self->{dbname} = $1; - $destsrc =~ /host=([^;]*)/; - $self->{dbhost} = $1; - $self->{dbhost} = 'localhost' if (!$self->{dbhost}); - $destsrc =~ /port=([^;]*)/; - $self->{dbport} = $1; - $self->{dbport} = 5432 if (!$self->{dbport}); - $self->{dbuser} = $destuser; - - # Check for connection failure - if (!$self->{dbhdest}) { - die "Error : $DBI::err ... $DBI::errstr\n"; - } - -} - - -=head2 modify_struct TABLE_NAME ARRAYOF_FIELDNAME - -Modify a table structure during export. Only given fieldname -will be exported. - -=cut - -sub modify_struct -{ - my ($self, $table, @fields) = @_; - - map { $_ = lc($_) } @fields; - $table = lc($table); - - push(@{$self->{modify}{$table}}, @fields); - -} - - - - -#### Private subroutines #### - -=head1 PRIVATE METHODS - -=head2 _init HASH_OPTIONS - -Initialize a Ora2Pg object instance with a connexion to the -Oracle database. - -=cut - -sub _init -{ - my ($self, %options) = @_; - - # Connect the database - $self->{dbh} = DBI->connect($options{datasource}, $options{user}, $options{password}); - - # Check for connection failure - if (!$self->{dbh}) { - die "Error : $DBI::err ... $DBI::errstr\n"; - } - - # Save the DB connection - $self->{datasource} = $options{datasource}; - $self->{user} = $options{user}; - $self->{password} = $options{password}; - - $self->{debug} = 0; - $self->{debug} = 1 if ($options{debug}); - - $self->{limited} = (); - $self->{limited} = $options{tables} if ($options{tables}); - - $self->{schema} = ''; - $self->{schema} = $options{schema} if ($options{schema}); - - $self->{min} = 0; - $self->{min} = $options{min} if ($options{min}); - - $self->{max} = 0; - $self->{max} = $options{max} if ($options{max}); - - $self->{showtableid} = 0; - $self->{showtableid} = $options{showtableid} if ($options{showtableid}); - - $self->{dbh}->{LongReadLen} = 0; - #$self->{dbh}->{LongTruncOk} = 1; - - $self->{data_limit} = 10; - $self->{data_current} = 0; - $self->{data_limit} = $options{data_limit} if (exists $options{data_limit}); - - # Retreive all table informations - if (!exists $options{type} || ($options{type} eq 'TABLE') || ($options{type} eq 'DATA') || ($options{type} eq 'COPY')) { - $self->_tables(); - } elsif ($options{type} eq 'VIEW') { - $self->{dbh}->{LongReadLen} = 100000; - $self->_views(); - } elsif ($options{type} eq 'GRANT') { - $self->_grants(); - } elsif ($options{type} eq 'SEQUENCE') { - $self->_sequences(); - } elsif ($options{type} eq 'TRIGGER') { - $self->{dbh}->{LongReadLen} = 100000; - $self->_triggers(); - } elsif (($options{type} eq 'FUNCTION') || ($options{type} eq 'PROCEDURE')) { - $self->{dbh}->{LongReadLen} = 100000; - $self->_functions($options{type}); - } elsif ($options{type} eq 'PACKAGE') { - $self->{dbh}->{LongReadLen} = 100000; - $self->_packages(); - } else { - die "type option must be TABLE, VIEW, GRANT, SEQUENCE, TRIGGER, PACKAGE, FUNCTION or PROCEDURE\n"; - } - $self->{type} = $options{type}; - - # Disconnect from the database - $self->{dbh}->disconnect() if ($self->{dbh}); - -} - - -# We provide a DESTROY method so that the autoloader doesn't -# bother trying to find it. We also close the DB connexion -sub DESTROY { } - - -=head2 _grants - -This function is used to retrieve all privilege information. - -It extract all Oracle's ROLES to convert them as Postgres groups -and search all users associated to these roles. - -Set the main hash $self->{groups}. -Set the main hash $self->{grantss}. - -=cut - -sub _grants -{ - my ($self) = @_; - -print STDERR "Retrieving groups/users information...\n" if ($self->{debug}); - $self->{users} = $self->_get_users(); - $self->{groups} = $self->_get_roles(); - $self->{grants} = $self->_get_all_grants(); - -} - - -=head2 _sequences - -This function is used to retrieve all sequences information. - -Set the main hash $self->{sequences}. - -=cut - -sub _sequences -{ - my ($self) = @_; - -print STDERR "Retrieving sequences information...\n" if ($self->{debug}); - $self->{sequences} = $self->_get_sequences(); - -} - - -=head2 _triggers - -This function is used to retrieve all triggers information. - -Set the main hash $self->{triggers}. - -=cut - -sub _triggers -{ - my ($self) = @_; - -print STDERR "Retrieving triggers information...\n" if ($self->{debug}); - $self->{triggers} = $self->_get_triggers(); - -} - - -=head2 _functions - -This function is used to retrieve all functions information. - -Set the main hash $self->{functions}. - -=cut - -sub _functions -{ - my ($self, $type) = @_; - -print STDERR "Retrieving functions information...\n" if ($self->{debug}); - $self->{functions} = $self->_get_functions($type); - -} - - -=head2 _packages - -This function is used to retrieve all packages information. - -Set the main hash $self->{packages}. - -=cut - -sub _packages -{ - my ($self) = @_; - -print STDERR "Retrieving packages information...\n" if ($self->{debug}); - $self->{packages} = $self->_get_packages(); - -} - - -=head2 _tables - -This function is used to retrieve all table information. - -Set the main hash of the database structure $self->{tables}. -Keys are the names of all tables retrieved from the current -database. Each table information compose an array associated -to the table_info key as array reference. In other way: - - $self->{tables}{$class_name}{table_info} = [(OWNER,TYPE)]; - -DBI TYPE can be TABLE, VIEW, SYSTEM TABLE, GLOBAL TEMPORARY, LOCAL TEMPORARY, -ALIAS, SYNONYM or a data source specific type identifier. This only extract -TABLE type. - -It also get the following informations in the DBI object to affect the -main hash of the database structure : - - $self->{tables}{$class_name}{field_name} = $sth->{NAME}; - $self->{tables}{$class_name}{field_type} = $sth->{TYPE}; - -It also call these other private subroutine to affect the main hash -of the database structure : - - @{$self->{tables}{$class_name}{column_info}} = $self->_column_info($class_name); - @{$self->{tables}{$class_name}{primary_key}} = $self->_primary_key($class_name); - @{$self->{tables}{$class_name}{unique_key}} = $self->_unique_key($class_name); - @{$self->{tables}{$class_name}{foreign_key}} = $self->_foreign_key($class_name); - -=cut - -sub _tables -{ - my ($self) = @_; - - # Get all tables information given by the DBI method table_info -print STDERR "Retrieving table information...\n" if ($self->{debug}); - - my $sth = $self->_table_info or die $self->{dbh}->errstr; - my @tables_infos = $sth->fetchall_arrayref(); - - if ($self->{showtableid}) { - foreach my $table (@tables_infos) { - for (my $i=0; $i<=$#{$table};$i++) { - print STDERR "[", $i+1, "] ${$table}[$i]->[2]\n"; - } - } - return; - } -my @done = (); - foreach my $table (@tables_infos) { - # Set the table information for each class found - my $i = 1; -print STDERR "Min table dump set to $self->{min}.\n" if ($self->{debug} && $self->{min}); -print STDERR "Max table dump set to $self->{max}.\n" if ($self->{debug} && $self->{max}); - foreach my $t (@$table) { - # Jump to desired extraction -if (grep(/^${@$t}[2]$/, @done)) { -print STDERR "Duplicate entry found: ${@$t}[0] - ${@$t}[1] - ${@$t}[2]\n"; -} else { -push(@done, ${@$t}[2]); -} - $i++, next if ($self->{min} && ($i < $self->{min})); - last if ($self->{max} && ($i > $self->{max})); - next if (($#{$self->{limited}} >= 0) && !grep(/^${@$t}[2]$/, @{$self->{limited}})); -print STDERR "[$i] " if ($self->{max} || $self->{min}); -print STDERR "Scanning ${@$t}[2] (@$t)...\n" if ($self->{debug}); - - # Check of uniqueness of the table - if (exists $self->{tables}{${@$t}[2]}{field_name}) { - print STDERR "Warning duplicate table ${@$t}[2], SYNONYME ? Skipped.\n"; - next; - } - - # usually OWNER,TYPE. QUALIFIER is omitted until I know what to do with that - $self->{tables}{${@$t}[2]}{table_info} = [(${@$t}[1],${@$t}[3])]; - # Set the fields information - my $sth = $self->{dbh}->prepare("SELECT * FROM ${@$t}[1].${@$t}[2] WHERE 1=0"); - if (!defined($sth)) { - warn "Can't prepare statement: $DBI::errstr"; - next; - } - $sth->execute; - if ($sth->err) { - warn "Can't execute statement: $DBI::errstr"; - next; - } - $self->{tables}{${@$t}[2]}{field_name} = $sth->{NAME}; - $self->{tables}{${@$t}[2]}{field_type} = $sth->{TYPE}; - - @{$self->{tables}{${@$t}[2]}{column_info}} = $self->_column_info(${@$t}[2]); - @{$self->{tables}{${@$t}[2]}{primary_key}} = $self->_primary_key(${@$t}[2]); - @{$self->{tables}{${@$t}[2]}{unique_key}} = $self->_unique_key(${@$t}[2]); - ($self->{tables}{${@$t}[2]}{foreign_link}, $self->{tables}{${@$t}[2]}{foreign_key}) = $self->_foreign_key(${@$t}[2]); - ($self->{tables}{${@$t}[2]}{uniqueness}, $self->{tables}{${@$t}[2]}{indexes}) = $self->_get_indexes(${@$t}[2]); - $i++; - } - } - -} - - -=head2 _views - -This function is used to retrieve all views information. - -Set the main hash of the views definition $self->{views}. -Keys are the names of all views retrieved from the current -database values are the text definition of the views. - -It then set the main hash as follow: - - # Definition of the view - $self->{views}{$table}{text} = $view_infos{$table}; - -=cut - -sub _views -{ - my ($self) = @_; - - # Get all views information -print STDERR "Retrieving views information...\n" if ($self->{debug}); - my %view_infos = $self->_get_views(); - - if ($self->{showtableid}) { - my $i = 1; - foreach my $table (sort keys %view_infos) { - print STDERR "[$i] $table\n"; - $i++; - } - return; - } - -print STDERR "Min view dump set to $self->{min}.\n" if ($self->{debug} && $self->{min}); -print STDERR "Max view dump set to $self->{max}.\n" if ($self->{debug} && $self->{max}); - my $i = 1; - foreach my $table (sort keys %view_infos) { - # Set the table information for each class found - # Jump to desired extraction - next if ($table =~ /\$/); - $i++, next if ($self->{min} && ($i < $self->{min})); - last if ($self->{max} && ($i > $self->{max})); - next if (($#{$self->{limited}} >= 0) && !grep(/^$table$/, @{$self->{limited}})); -print STDERR "[$i] " if ($self->{max} || $self->{min}); -print STDERR "Scanning $table...\n" if ($self->{debug}); - $self->{views}{$table}{text} = $view_infos{$table}; - ## Added JFR : 3/3/02 : Retrieve also aliases from views - $self->{views}{$table}{alias}= $view_infos{$table}{alias}; - $i++; - } - -} - - -=head2 _get_sql_data - -Returns a string containing the entire SQL Schema definition compatible with PostgreSQL - -=cut - -sub _get_sql_data -{ - my ($self, $outfile) = @_; - - my $sql_header = "-- Generated by Ora2Pg, the Oracle database Schema converter, version $VERSION\n"; - $sql_header .= "-- Copyright 2000 Gilles DAROLD. All rights reserved.\n"; - $sql_header .= "--\n"; - $sql_header .= "-- This program is free software; you can redistribute it and/or modify it under\n"; - $sql_header .= "-- the same terms as Perl itself.\n\n"; - $sql_header .= "BEGIN TRANSACTION;\n\n"; - - my $sql_output = ""; - - # Process view only - if ($self->{type} eq 'VIEW') { -print STDERR "Add views definition...\n" if ($self->{debug}); - foreach my $view (sort keys %{$self->{views}}) { - if (!@{$self->{views}{$view}{alias}}) { - $sql_output .= "CREATE VIEW \"\L$view\E\" AS $self->{views}{$view}{text};\n"; - } else { - $sql_output .= "CREATE VIEW \"\L$view\E\" ("; - my $count = 0; - foreach my $d (@{$self->{views}{$view}{alias}}) { - if ($count == 0) { - $count = 1; - } else { - $sql_output .= ", " - } - $sql_output .= "$d->[0]"; - } - $sql_output .= ") AS $self->{views}{$view}{text};\n"; - } - } - - if (!$sql_output) { - $sql_output = "-- Nothing found of type $self->{type}\n"; - } else { - $sql_output .= "\n"; - } - - return $sql_header . $sql_output . "\nEND TRANSACTION;\n"; - } - - # Process grant only - if ($self->{type} eq 'GRANT') { -print STDERR "Add groups/users privileges...\n" if ($self->{debug}); - # Add groups definition - my $groups = ''; - my @users = (); - my @grps = (); - foreach (@{$self->{users}}) { - next if (exists $self->{groups}{"$_"}); - next if ($self->{schema} && ($_ ne $self->{schema})); - $sql_header .= "CREATE USER $_ WITH PASSWORD 'secret';\n"; - } - foreach my $role (sort keys %{$self->{groups}}) { - push(@grps, $role); - $groups .= "CREATE GROUP $role WITH USER " . join(',', @{$self->{groups}{$role}}) . ";\n"; - } - $sql_header .= "\n" . $groups . "\n"; - - # Add privilege definition - my $grants = ''; - foreach my $table (sort keys %{$self->{grants}}) { - $grants .= "REVOKE ALL ON $table FROM PUBLIC;\n"; - foreach my $priv (sort keys %{$self->{grants}{$table}}) { - my $usr = ''; - my $grp = ''; - foreach my $user (@{$self->{grants}{$table}{$priv}}) { - if (grep(/^$user$/, @grps)) { - $grp .= "$user,"; - } else { - $usr .= "$user,"; - } - } - $grp =~ s/,$//; - $usr =~ s/,$//; - if ($grp) { - $grants .= "GRANT $priv ON $table TO GROUP $grp;\n"; - } else { - $grants .= "GRANT $priv ON $table TO $usr;\n"; - } - } - } - - if (!$grants) { - $$grants = "-- Nothing found of type $self->{type}\n"; - } - - $sql_output .= "\n" . $grants . "\n"; - - return $sql_header . $sql_output . "\nEND TRANSACTION;\n"; - } - - # Process sequences only - if ($self->{type} eq 'SEQUENCE') { -print STDERR "Add sequences definition...\n" if ($self->{debug}); - foreach my $seq (@{$self->{sequences}}) { - my $cache = 1; - $cache = $seq->[5] if ($seq->[5]); - my $cycle = ''; - $cycle = ' CYCLE' if ($seq->[6] eq 'Y'); - if ($seq->[2] > 2147483646) { - $seq->[2] = 2147483646; - } - if ($seq->[1] < -2147483647) { - $seq->[1] = -2147483647; - } - $sql_output .= "CREATE SEQUENCE \L$seq->[0]\E INCREMENT $seq->[3] MINVALUE $seq->[1] MAXVALUE $seq->[2] START $seq->[4] CACHE $cache$cycle;\n"; - } - - if (!$sql_output) { - $sql_output = "-- Nothing found of type $self->{type}\n"; - } - - return $sql_header . $sql_output . "\nEND TRANSACTION;\n"; - } - - # Process triggers only. PL/SQL code is pre-converted to PL/PGSQL following - # the recommendation of Roberto Mello, see http://techdocs.postgresql.org/ - # Oracle's PL/SQL to PostgreSQL PL/pgSQL HOWTO - if ($self->{type} eq 'TRIGGER') { -print STDERR "Add triggers definition...\n" if ($self->{debug}); - foreach my $trig (@{$self->{triggers}}) { - $trig->[1] =~ s/ EACH ROW//; - chop($trig->[4]); - chomp($trig->[4]); - # Check if it's a pg rule - if ($trig->[1] =~ /INSTEAD OF/) { - $sql_output .= "CREATE RULE \L$trig->[0]\E AS\n\tON \L$trig->[3]\E\n\tDO INSTEAD\n(\n\t$trig->[4]\n);\n\n"; - } else { - - #-------------------------------------------- - # PL/SQL to PL/PGSQL code conversion - #-------------------------------------------- - # Change NVL to COALESCE - #$trig->[4] =~ s/NVL\(/coalesce(/igs; - # Change trunc() to date_trunc('day', field) - # Trunc is replaced with date_trunc if we find date in the name of the value - # because Oracle have the same trunc function on number and date type :-((( - #$trig->[4] =~ s/trunc\(([^\)]*date[^\)]*)\)/date_trunc('day', $1)/igs; - # Change SYSDATE to 'now' - #$trig->[4] =~ s/SYSDATE/CURRENT_TIMESTAMP/igs; - # Change nextval on sequence - # Oracle's sequence grammar is sequence_name.nextval. - # Postgres's sequence grammar is nextval('sequence_name'). - #$trig->[4] =~ s/(\w+)\.nextval/nextval('$1')/isg; - # Escaping Single Quotes - #$trig->[4] =~ s/'/''/sg; - - $sql_output .= "CREATE FUNCTION pg_fct_\L$trig->[0]\E () RETURNS OPAQUE AS '\n$trig->[4]\n' LANGUAGE 'plpgsql'\n\n"; - $sql_output .= "CREATE TRIGGER \L$trig->[0]\E\n\t$trig->[1] $trig->[2] ON \L$trig->[3]\E FOR EACH ROW\n\tEXECUTE PROCEDURE pg_fct_\L$trig->[0]\E();\n\n"; - } - } - - if (!$sql_output) { - $sql_output = "-- Nothing found of type $self->{type}\n"; - } - - return $sql_header . $sql_output . "\nEND TRANSACTION;\n"; - } - - # Process functions only - if (($self->{type} eq 'FUNCTION') || ($self->{type} eq 'PROCEDURE')) { -print STDERR "Add functions definition...\n" if ($self->{debug}); - foreach my $fct (sort keys %{$self->{functions}}) { - my @tmp = (); - if ($self->{functions}{$fct} =~ /^[\s\t]*function/is) { - #$self->{functions}{$fct} =~ /function[\s\n\t]*$fct[\s\n\t]*\(([^\)]*)\)/is; - $self->{functions}{$fct} =~ /function[\s\n\t]*$fct[\s\n\t]*\(([^\)]*)\)[\s\n\t]*is/is; - @tmp = split(/\n/, $1); - } else { - #$self->{functions}{$fct} =~ /procedure[\s\n\t]*$fct[\s\n\t]*\(([^\)]*)\)/is; - $self->{functions}{$fct} =~ /procedure[\s\n\t]*$fct[\s\n\t]*\(([^\)]*)\)[\s\n\t]*is\W/is; - @tmp = split(/\n/, $1); - } - my @argu = split(/,/, join(' ', @tmp)); - map { s/^.* in //is } @argu; - map { s/^.* out //is } @argu; - map { $_ = $self->_sql_type(uc($_)) } @argu; - $self->{functions}{$fct} =~ /return ([^\s]*) is/is; - $self->{functions}{$fct} = "-- Oracle function declaration, please edit to match PostgreSQL syntax.\n$self->{functions}{$fct}"; - $sql_output .= "-- PostgreSQL possible function declaration, please edit to match your needs.\nCREATE FUNCTION \L$fct\E(" . join(',', @argu) . ") RETURNS " . $self->_sql_type(uc($1)) . " AS '\n$self->{functions}{$fct}\n' LANGUAGE 'sql'\n\n"; - } - - if (!$sql_output) { - $sql_output = "-- Nothing found of type $self->{type}\n"; - } - - return $sql_header . $sql_output . "\nEND TRANSACTION;\n"; - } - - # Process functions only - if ($self->{type} eq 'PACKAGE') { -print STDERR "Add packages definition...\n" if ($self->{debug}); - foreach my $pkg (sort keys %{$self->{packages}}) { - $sql_output .= "-- Oracle package '$pkg' declaration, please edit to match PostgreSQL syntax.\n"; - $sql_output .= "$self->{packages}{$pkg}\n"; - $sql_output .= "-- End of Oracle package '$pkg' declaration\n\n"; - } - - if (!$sql_output) { - $sql_output = "-- Nothing found of type $self->{type}\n"; - } - - return $sql_header . $sql_output . "\nEND TRANSACTION;\n"; - } - - - - # Extract data only - if (($self->{type} eq 'DATA') || ($self->{type} eq 'COPY')) { - # Connect the database - $self->{dbh} = DBI->connect($self->{datasource}, $self->{user}, $self->{password}); - # Check for connection failure - if (!$self->{dbh}) { - die "Error : $DBI::err ... $DBI::errstr\n"; - } - - if (!$self->{dbhdest}) { - if ($outfile) { - open(FILE,">$outfile") or die "Can't open $outfile: $!"; - print FILE $sql_header; - } else { - print $sql_header; - } - } else { - if ($self->{type} eq 'COPY') { - open(DBH, "| $PSQL -h $self->{dbhost} -p $self->{dbport} -d $self->{dbname}") or die "Can't open $PSQL command, $!\n"; - } - } - - foreach my $table (keys %{$self->{tables}}) { -print STDERR "Dumping table $table...\n" if ($self->{debug}); - my @tt = (); - my @nn = (); - my $s_out = "INSERT INTO \"\L$table\E\" ("; - if ($self->{type} eq 'COPY') { - $s_out = "COPY \"\L$table\E\" FROM stdin;\n"; - } - - foreach my $i ( 0 .. $#{$self->{tables}{$table}{field_name}} ) { - my $fieldname = ${$self->{tables}{$table}{field_name}}[$i]; - if (exists $self->{modify}{"\L$table\E"}) { - next if (!grep(/\L$fieldname\E/, @{$self->{modify}{"\L$table\E"}})); - } - foreach my $f (@{$self->{tables}{$table}{column_info}}) { - next if (${$f}[0] ne "$fieldname"); - my $type = $self->_sql_type(${$f}[1], ${$f}[2], ${$f}[5], ${$f}[6]); - $type = "${$f}[1], ${$f}[2]" if (!$type); - push(@tt, $type); - push(@nn, ${$f}[0]); - if ($self->{type} ne 'COPY') { - $s_out .= "\"\L${$f}[0]\E\","; - } - last; - } - } - - if ($self->{type} ne 'COPY') { - $s_out =~ s/,$//; - $s_out .= ") VALUES ("; - } - # Extract all data from the current table - $self->{data_current} = 0; - $self->{data_end} = 0; - while ( !$self->{data_end} ) { - my $sth = $self->_get_data($table, \@nn, \@tt); - $self->{data_end} = 1 if (!$self->{data_limit}); - my $count = 0; - my $sql = ''; - if ($self->{type} eq 'COPY') { - if ($self->{dbhdest}) { - $sql = $s_out; - } else { - if ($outfile) { - print FILE $s_out; - } else { - print $s_out; - } - } - } - while (my $row = $sth->fetch) { - if ($self->{type} ne 'COPY') { - if ($self->{dbhdest}) { - $sql .= $s_out; - } else { - if ($outfile) { - print FILE $s_out; - } else { - print $s_out; - } - } - } - for (my $i = 0; $i <= $#{$row}; $i++) { - if ($self->{type} ne 'COPY') { - if ($tt[$i] =~ /(char|date|time|text)/) { - $row->[$i] =~ s/'/''/gs; - if ($row->[$i]) { - $row->[$i] = "'$row->[$i]'"; - } else { - $row->[$i] = 'NULL'; - } - if ($self->{dbhdest}) { - $sql .= $row->[$i]; - } else { - if ($outfile) { - print FILE $row->[$i]; - } else { - print $row->[$i]; - } - } - } else { - if (!$row->[$i]) { - $row->[$i] = 'NULL'; - } - if ($self->{dbhdest}) { - $sql .= $row->[$i]; - } else { - if ($outfile) { - print FILE $row->[$i]; - } else { - print $row->[$i]; - } - } - } - if ($i < $#{$row}) { - if ($self->{dbhdest}) { - $sql .= ","; - } else { - if ($outfile) { - print FILE ","; - } else { - print ","; - } - } - } - } else { - if (!$row->[$i]) { - $row->[$i] = '\N'; - } - if ($self->{dbhdest}) { - $sql .= $row->[$i]; - } else { - if ($outfile) { - print FILE $row->[$i]; - } else { - print $row->[$i]; - } - } - if ($i < $#{$row}) { - if ($self->{dbhdest}) { - $sql .= "\t"; - } else { - if ($outfile) { - print FILE "\t"; - } else { - print "\t"; - } - } - } else { - if ($self->{dbhdest}) { - $sql .= "\n"; - } else { - if ($outfile) { - print FILE "\n"; - } else { - print "\n"; - } - } - } - } - } - if ($self->{type} ne 'COPY') { - if ($self->{dbhdest}) { - $sql .= ");\n"; - } else { - if ($outfile) { - print FILE ");\n"; - } else { - print ");\n"; - } - } - } - $count++; - } - if ($self->{type} eq 'COPY') { - if ($self->{dbhdest}) { - $sql .= "\\.\n"; - } else { - if ($outfile) { - print FILE "\\.\n"; - } else { - print "\\.\n"; - } - } - } - if ($self->{data_limit}) { - $self->{data_end} = 1 if ($count+1 < $self->{data_limit}); - } - # Insert data if we are in online processing mode - if ($self->{dbhdest}) { - if ($self->{type} ne 'COPY') { - my $s = $self->{dbhdest}->prepare($sql) or die $self->{dbhdest}->errstr . "\n"; - $s->execute or die $s->errstr . "\n"; - } else { - print DBH "$sql"; - } - } - } - } - - # Disconnect from the database - $self->{dbh}->disconnect() if ($self->{dbh}); - - if (!$self->{dbhdest}) { - if ($outfile) { - print FILE "\nEND TRANSACTION;\n"; - } else { - print "\nEND TRANSACTION;\n"; - } - } - - $self->{dbhdest}->disconnect() if ($self->{dbhdest}); - - if ($self->{type} eq 'COPY') { - close DBH; - } - - return; - } - - - # Dump the database structure - foreach my $table (keys %{$self->{tables}}) { -print STDERR "Dumping table $table...\n" if ($self->{debug}); - $sql_output .= "CREATE ${$self->{tables}{$table}{table_info}}[1] \"\L$table\E\" (\n"; - my $sql_ukey = ""; - my $sql_pkey = ""; - foreach my $i ( 0 .. $#{$self->{tables}{$table}{field_name}} ) { - foreach my $f (@{$self->{tables}{$table}{column_info}}) { - next if (${$f}[0] ne "${$self->{tables}{$table}{field_name}}[$i]"); - my $type = $self->_sql_type(${$f}[1], ${$f}[2], ${$f}[5], ${$f}[6]); - $type = "${$f}[1], ${$f}[2]" if (!$type); - $sql_output .= "\t\"\L${$f}[0]\E\" $type"; - # Set the primary key definition - foreach my $k (@{$self->{tables}{$table}{primary_key}}) { - next if ($k ne "${$f}[0]"); - $sql_pkey .= "\"\L$k\E\","; - last; - } - if (${$f}[4] ne "") { - $sql_output .= " DEFAULT ${$f}[4]"; - } elsif (!${$f}[3] || (${$f}[3] eq 'N')) { - $sql_output .= " NOT NULL"; - } - # Set the unique key definition - foreach my $k (@{$self->{tables}{$table}{unique_key}}) { - next if ( ($k ne "${$f}[0]") || (grep(/^$k$/, @{$self->{tables}{$table}{primary_key}})) ); - $sql_ukey .= "\"\L$k\E\","; - last; - } - $sql_output .= ",\n"; - last; - } - } - $sql_ukey =~ s/,$//; - $sql_pkey =~ s/,$//; - $sql_output .= "\tUNIQUE ($sql_ukey),\n" if ($sql_ukey); - $sql_output .= "\tPRIMARY KEY ($sql_pkey),\n" if ($sql_pkey); - - # Add constraint definition - my @done = (); - foreach my $h (@{$self->{tables}{$table}{foreign_key}}) { - next if (grep(/^$h->[0]$/, @done)); - my $desttable = ''; - foreach (keys %{$self->{tables}{$table}{foreign_link}{$h->[0]}{remote}}) { - $desttable .= "$_"; - } - push(@done, $h->[0]); - $sql_output .= "\tCONSTRAINT \L$h->[0]\E FOREIGN KEY (" . lc(join(',', @{$self->{tables}{$table}{foreign_link}{$h->[0]}{local}})) . ") REFERENCES \L$desttable\E (" . lc(join(',', @{$self->{tables}{$table}{foreign_link}{$h->[0]}{remote}{$desttable}})) . ")"; - $sql_output .= " MATCH $h->[2]" if ($h->[2]); - $sql_output .= " ON DELETE $h->[3]"; - $sql_output .= " $h->[4]"; - $sql_output .= " INITIALLY $h->[5],\n"; - - } - $sql_output =~ s/,$//; - $sql_output .= ");\n"; - foreach my $idx (keys %{$self->{tables}{$table}{indexes}}) { - map { s/^/"/ } @{$self->{tables}{$table}{indexes}{$idx}}; - map { s/$/"/ } @{$self->{tables}{$table}{indexes}{$idx}}; - my $columns = join(',', @{$self->{tables}{$table}{indexes}{$idx}}); - my $unique = ''; - $unique = ' UNIQUE' if ($self->{tables}{$table}{uniqueness}{$idx} eq 'UNIQUE'); - $sql_output .= "CREATE$unique INDEX \"\L$idx\E\" ON \"\L$table\E\" (\L$columns\E);\n"; - } - $sql_output .= "\n"; - } - - if (!$sql_output) { - $sql_output = "-- Nothing found of type TABLE\n"; - } - - return $sql_header . $sql_output . "\nEND TRANSACTION;\n"; -} - - -=head2 _get_data TABLE - -This function implements a Oracle-native data extraction. - -Return a list of array reference containing the data - -=cut - -sub _get_data -{ - my ($self, $table, $name, $type) = @_; - - my $str = "SELECT "; - my $tmp = "SELECT "; - for my $k (0 .. $#{$name}) { - if ( $type->[$k] =~ /(date|time)/) { - $str .= "to_char($name->[$k], 'YYYY-MM-DD'),"; - } else { - $str .= "$name->[$k],"; - } - $tmp .= "$name->[$k],"; - } - $str =~ s/,$//; - $tmp =~ s/,$//; - my $tmp2 = $tmp; - $tmp2 =~ s/SELECT /SELECT ROWNUM as noline,/; - - # Fix a problem when the table need to be prefixed by the schema - if ($self->{schema}) { - $table = "$self->{schema}.$table"; - } - if ($self->{data_limit}) { - $str = $tmp . " FROM ( $tmp2 FROM ( $tmp FROM $table) "; - $str .= " WHERE ROWNUM < ($self->{data_limit} + $self->{data_current})) "; - $str .= " WHERE noline >= $self->{data_current}"; - } else { - $str .= " FROM $table"; - } - $self->{data_current} += $self->{data_limit}; - - # Fix a problem when exporting type LONG and LOB - $self->{dbh}->{'LongReadLen'} = 1023*1024; - $self->{dbh}->{'LongTruncOk'} = 1; - - my $sth = $self->{dbh}->prepare($str) or die $sth->errstr . "\n"; - $sth->execute or die $sth->errstr . "\n"; - - return $sth; - -} - - -=head2 _sql_type INTERNAL_TYPE LENGTH PRECISION SCALE - -This function return the PostgreSQL datatype corresponding to the -Oracle internal type. - -=cut - -sub _sql_type -{ - my ($self, $type, $len, $precision, $scale) = @_; - - my %TYPE = ( - # Oracle only has one flexible underlying numeric type, NUMBER. - # Without precision and scale it is set to PG type float8 to match all needs - 'NUMBER' => 'float8', - # CHAR types limit of 2000 bytes with default to 1 if no length is given. - # PG char type has max length set to 8104 so it should match all needs - 'CHAR' => 'char', - 'NCHAR' => 'char', - # VARCHAR types the limit is 2000 bytes in Oracle 7 and 4000 in Oracle 8. - # PG varchar type has max length iset to 8104 so it should match all needs - 'VARCHAR' => 'varchar', - 'NVARCHAR' => 'varchar', - 'VARCHAR2' => 'varchar', - 'NVARCHAR2' => 'varchar', - # The DATE data type is used to store the date and time information. - # Pg type timestamp should match all needs - 'DATE' => 'timestamp', - # Type LONG is like VARCHAR2 but with up to 2Gb. - # PG type text should match all needs or if you want you could use blob - 'LONG' => 'text', # Character data of variable length - 'LONG RAW' => 'text', # Raw binary data of variable length - # Types LOB and FILE are like LONG but with up to 4Gb. - # PG type text should match all needs or if you want you could use blob (large object) - 'CLOB' => 'text', # A large object containing single-byte characters - 'NLOB' => 'text', # A large object containing national character set data - 'BLOB' => 'text', # Binary large object - 'BFILE' => 'text', # Locator for external large binary file - # The RAW type is presented as hexadecimal characters. The contents are treated as binary data. Limit of 2000 bytes - # Pg type text should match all needs or if you want you could use blob (large object) - 'RAW' => 'text', - 'ROWID' => 'oid', - 'LONG RAW' => 'binary', - 'FLOAT' => 'float8' - ); - - # Overide the length - $len = $precision if ( ($type eq 'NUMBER') && $precision ); - - if (exists $TYPE{$type}) { - if ($len) { - if ( ($type eq "CHAR") || ($type =~ /VARCHAR/) ) { - # Type CHAR have default length set to 1 - # Type VARCHAR(2) must have a given length - $len = 1 if (!$len && ($type eq "CHAR")); - return "$TYPE{$type}($len)"; - } elsif ($type eq "NUMBER") { - # This is an integer - if (!$scale) { - if ($precision) { - return "numeric($precision)"; - } - } else { - if ($precision) { - return "decimal($precision,$scale)"; - } - } - return "$TYPE{$type}"; - } else { - return "$TYPE{$type}"; - } - } else { - - return $TYPE{$type}; - } - } - - return; -} - - -=head2 _column_info TABLE - -This function implements a Oracle-native column information. - -Return a list of array reference containing the following informations -for each column the given a table - -[( - column name, - column type, - column length, - nullable column, - default value -)] - -=cut - -sub _column_info -{ - my ($self, $table) = @_; - - my $sth = $self->{dbh}->prepare(<{dbh}->errstr; -SELECT COLUMN_NAME, DATA_TYPE, DATA_LENGTH, NULLABLE, DATA_DEFAULT, DATA_PRECISION, DATA_SCALE -FROM DBA_TAB_COLUMNS -WHERE TABLE_NAME='$table' -END - $sth->execute or die $sth->errstr; - my $data = $sth->fetchall_arrayref(); -if ($self->{debug}) { - foreach my $d (@$data) { -print STDERR "\t$d->[0] => type:$d->[1] , length:$d->[2], precision:$d->[5], scale:$d->[6], nullable:$d->[3] , default:$d->[4]\n"; - } -} - - return @$data; - -} - - -=head2 _primary_key TABLE - -This function implements a Oracle-native primary key column -information. - -Return a list of all column name defined as primary key -for the given table. - -=cut - -sub _primary_key -{ - my($self, $table) = @_; - - my $sth = $self->{dbh}->prepare(<{dbh}->errstr; -select all_cons_columns.COLUMN_NAME -from all_constraints, all_cons_columns -where all_constraints.CONSTRAINT_TYPE='P' -and all_constraints.constraint_name=all_cons_columns.constraint_name -and all_constraints.STATUS='ENABLED' -and all_constraints.TABLE_NAME='$table' -order by all_cons_columns.position -END - $sth->execute or die $sth->errstr; - my @data = (); - while (my $row = $sth->fetch) { - push(@data, ${@$row}[0]) if (${@$row}[0] !~ /\$/); - } - return @data; -} - - -=head2 _unique_key TABLE - -This function implements a Oracle-native unique key column -information. - -Return a list of all column name defined as unique key -for the given table. - -=cut - -sub _unique_key -{ - my($self, $table) = @_; - - my $sth = $self->{dbh}->prepare(<{dbh}->errstr; -select all_cons_columns.COLUMN_NAME -from all_constraints, all_cons_columns -where all_constraints.CONSTRAINT_TYPE='U' -and all_constraints.constraint_name=all_cons_columns.constraint_name -and all_constraints.STATUS='ENABLED' -and all_constraints.TABLE_NAME='$table' -order by all_cons_columns.position -END - $sth->execute or die $sth->errstr; - - my @data = (); - while (my $row = $sth->fetch) { - push(@data, ${@$row}[0]) if (${@$row}[0] !~ /\$/); - } - return @data; -} - - -=head2 _foreign_key TABLE - -This function implements a Oracle-native foreign key reference -information. - -Return a list of hash of hash of array reference. Ouuf! Nothing very difficult. -The first hash is composed of all foreign key name. The second hash just have -two key known as 'local' and remote' corresponding to the local table where the -foreign key is defined and the remote table where the key refer. - -The foreign key name is composed as follow: - - 'local_table_name->remote_table_name' - -Foreign key data consist in two array representing at the same indice the local -field and the remote field where the first one refer to the second. -Just like this: - - @{$link{$fkey_name}{local}} = @local_columns; - @{$link{$fkey_name}{remote}} = @remote_columns; - -=cut - -sub _foreign_key -{ - my ($self, $table) = @_; - - my $str = "SELECT CONSTRAINT_NAME,R_CONSTRAINT_NAME,SEARCH_CONDITION,DELETE_RULE,DEFERRABLE,DEFERRED FROM DBA_CONSTRAINTS WHERE CONSTRAINT_TYPE='R' AND STATUS='ENABLED' AND TABLE_NAME='$table'"; - my $sth = $self->{dbh}->prepare($str) or die $self->{dbh}->errstr; - $sth->execute or die $sth->errstr; - - my @data = (); - my %link = (); - my @tab_done = (); - while (my $row = $sth->fetch) { - next if (grep(/^$row->[0]$/, @tab_done)); - push(@data, [ @$row ]); - push(@tab_done, $row->[0]); - my $sql = "SELECT DISTINCT COLUMN_NAME FROM DBA_CONS_COLUMNS WHERE CONSTRAINT_NAME='$row->[0]'"; - my $sth2 = $self->{dbh}->prepare($sql) or die $self->{dbh}->errstr; - $sth2->execute or die $sth2->errstr; - my @done = (); - while (my $r = $sth2->fetch) { - if (!grep(/^$r->[0]$/, @done)) { - push(@{$link{$row->[0]}{local}}, $r->[0]); - push(@done, $r->[0]); - } - } - $sql = "SELECT DISTINCT TABLE_NAME,COLUMN_NAME FROM DBA_CONS_COLUMNS WHERE CONSTRAINT_NAME='$row->[1]'"; - $sth2 = $self->{dbh}->prepare($sql) or die $self->{dbh}->errstr; - $sth2->execute or die $sth2->errstr; - @done = (); - while (my $r = $sth2->fetch) { - if (!grep(/^$r->[1]$/, @done)) { - push(@{$link{$row->[0]}{remote}{$r->[0]}}, $r->[1]); - push(@done, $r->[1]); - } - } - } - - return \%link, \@data; -} - - -=head2 _get_users - -This function implements a Oracle-native users information. - -Return a hash of all users as an array. - -=cut - -sub _get_users -{ - my($self) = @_; - - # Retrieve all USERS defined in this database - my $str = "SELECT USERNAME FROM DBA_USERS"; - if (!$self->{schema}) { - $str .= " WHERE USERNAME <> 'SYS' AND USERNAME <> 'SYSTEM' AND USERNAME <> 'DBSNMP' AND USERNAME <> 'OUTLN'"; - } else { - $str .= " WHERE USERNAME = '$self->{schema}'"; - } - $str .= " ORDER BY USERNAME"; - my $sth = $self->{dbh}->prepare($str) or die $self->{dbh}->errstr; - - $sth->execute or die $sth->errstr; - my @users = (); - while (my $row = $sth->fetch) { - push(@users, $row->[0]); - } - - return \@users; -} - - - -=head2 _get_roles - -This function implements a Oracle-native roles -information. - -Return a hash of all groups (roles) as an array of associated users. - -=cut - -sub _get_roles -{ - my($self) = @_; - - # Retrieve all ROLES defined in this database - my $str = "SELECT GRANTED_ROLE,GRANTEE FROM DBA_ROLE_PRIVS WHERE GRANTEE NOT IN (select distinct role from dba_roles)"; - if (!$self->{schema}) { - $str .= " AND GRANTEE <> 'SYS' AND GRANTEE <> 'SYSTEM' AND GRANTEE <> 'DBSNMP' AND GRANTEE <> 'OUTLN'"; - } else { - $str .= " AND GRANTEE = '$self->{schema}'"; - } - my $sth = $self->{dbh}->prepare($str) or die $self->{dbh}->errstr; - - $sth->execute or die $sth->errstr; - my %roles = (); - while (my $row = $sth->fetch) { - push(@{$roles{"$row->[0]"}}, $row->[1]); - } - - return \%roles; -} - - -=head2 _get_all_grants - -This function implements a Oracle-native user privilege -information. - -Return a hash of all tables grants as an array of associated users. - -=cut - -sub _get_all_grants -{ - my($self) = @_; - - my @PG_GRANTS = ('DELETE', 'INSERT', 'SELECT', 'UPDATE'); - - # Retrieve all ROLES defined in this database - my $str = "SELECT table_name,privilege,grantee FROM DBA_TAB_PRIVS"; - if ($self->{schema}) { - $str .= " WHERE GRANTEE = '$self->{schema}'"; - } else { - $str .= " WHERE GRANTEE <> 'SYS' AND GRANTEE <> 'SYSTEM' AND GRANTEE <> 'DBSNMP' AND GRANTEE <> 'OUTLN'"; - } - $str .= " ORDER BY TABLE_NAME"; - - my $sth = $self->{dbh}->prepare($str) or die $self->{dbh}->errstr; - - $sth->execute or die $sth->errstr; - my %grants = (); - while (my $row = $sth->fetch) { - push(@{$grants{"$row->[0]"}{"$row->[1]"}}, $row->[2]) if (grep(/$row->[1]/, @PG_GRANTS)); - } - - return \%grants; -} - - - -=head2 _get_indexes TABLE - -This function implements a Oracle-native indexes information. - -Return hash of array containing all unique index and a hash of -array of all indexes name which are not primary keys for the -given table. - -=cut - -sub _get_indexes -{ - my($self, $table) = @_; - - # Retrieve all indexes - my $str = "SELECT DISTINCT DBA_IND_COLUMNS.INDEX_NAME, DBA_IND_COLUMNS.COLUMN_NAME, DBA_INDEXES.UNIQUENESS FROM DBA_IND_COLUMNS, DBA_INDEXES WHERE DBA_IND_COLUMNS.TABLE_NAME='$table' AND DBA_INDEXES.INDEX_NAME=DBA_IND_COLUMNS.INDEX_NAME AND DBA_IND_COLUMNS.INDEX_NAME NOT IN (SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE TABLE_NAME='$table')"; - my $sth = $self->{dbh}->prepare($str) or die $self->{dbh}->errstr; - $sth->execute or die $sth->errstr; - - my %data = (); - my %unique = (); - while (my $row = $sth->fetch) { - $unique{$row->[0]} = $row->[2]; - push(@{$data{$row->[0]}}, $row->[1]); - } - - return \%unique, \%data; -} - - -=head2 _get_sequences - -This function implements a Oracle-native sequences -information. - -Return a hash of array of sequence name with MIN_VALUE, MAX_VALUE, -INCREMENT and LAST_NUMBER for the given table. - -=cut - -sub _get_sequences -{ - my($self) = @_; - - # Retrieve all indexes - my $str = "SELECT DISTINCT SEQUENCE_NAME, MIN_VALUE, MAX_VALUE, INCREMENT_BY, LAST_NUMBER, CACHE_SIZE, CYCLE_FLAG FROM DBA_SEQUENCES"; - if (!$self->{schema}) { - $str .= " WHERE SEQUENCE_OWNER <> 'SYS' AND SEQUENCE_OWNER <> 'SYSTEM' AND SEQUENCE_OWNER <> 'DBSNMP' AND SEQUENCE_OWNER <> 'OUTLN'"; - } else { - $str .= " WHERE SEQUENCE_OWNER = '$self->{schema}'"; - } - my $sth = $self->{dbh}->prepare($str) or die $self->{dbh}->errstr; - $sth->execute or die $sth->errstr; - - my @seqs = (); - while (my $row = $sth->fetch) { - push(@seqs, [ @$row ]); - } - - return \@seqs; -} - - -=head2 _get_views - -This function implements a Oracle-native views information. - -Return a hash of view name with the SQL query it is based on. - -=cut - -sub _get_views -{ - my($self) = @_; - - # Retrieve all views - my $str = "SELECT VIEW_NAME,TEXT FROM DBA_VIEWS"; - if (!$self->{schema}) { - $str .= " WHERE OWNER <> 'SYS' AND OWNER <> 'SYSTEM' AND OWNER <> 'DBSNMP' AND OWNER <> 'OUTLN'"; - } else { - $str .= " WHERE OWNER = '$self->{schema}'"; - } - my $sth = $self->{dbh}->prepare($str) or die $self->{dbh}->errstr; - $sth->execute or die $sth->errstr; - - my %data = (); - while (my $row = $sth->fetch) { - $data{$row->[0]} = $row->[1]; - @{$data{$row->[0]}{alias}} = $self->_alias_info ($row->[0]); - } - - return %data; -} - -=head2 _alias_info - -This function implements a Oracle-native column information. - -Return a list of array reference containing the following informations -for each alias of the given view - -[( - column name, - column id -)] - -=cut - -sub _alias_info -{ - my ($self, $view) = @_; - - my $sth = $self->{dbh}->prepare(<{dbh}->errstr; -SELECT COLUMN_NAME, COLUMN_ID -FROM DBA_TAB_COLUMNS -WHERE TABLE_NAME='$view' -END - $sth->execute or die $sth->errstr; - my $data = $sth->fetchall_arrayref(); - if ($self->{debug}) { - foreach my $d (@$data) { - print STDERR "\t$d->[0] => column id:$d->[1]\n"; - } - } - - return @$data; - -} - -=head2 _get_triggers - -This function implements a Oracle-native triggers information. - -Return an array of refarray of all triggers informations - -=cut - -sub _get_triggers -{ - my($self) = @_; - - # Retrieve all indexes - my $str = "SELECT TRIGGER_NAME, TRIGGER_TYPE, TRIGGERING_EVENT, TABLE_NAME, TRIGGER_BODY FROM DBA_TRIGGERS WHERE STATUS='ENABLED'"; - if (!$self->{schema}) { - $str .= " AND OWNER <> 'SYS' AND OWNER <> 'SYSTEM' AND OWNER <> 'DBSNMP' AND OWNER <> 'OUTLN'"; - } else { - $str .= " AND OWNER = '$self->{schema}'"; - } - my $sth = $self->{dbh}->prepare($str) or die $self->{dbh}->errstr; - $sth->execute or die $sth->errstr; - - my @triggers = (); - while (my $row = $sth->fetch) { - push(@triggers, [ @$row ]); - } - - return \@triggers; -} - - -=head2 _get_functions - -This function implements a Oracle-native functions information. - -Return a hash of all function name with their PLSQL code - -=cut - -sub _get_functions -{ - my($self, $type) = @_; - - # Retrieve all indexes - my $str = "SELECT DISTINCT OBJECT_NAME,OWNER FROM DBA_OBJECTS WHERE OBJECT_TYPE='$type' AND STATUS='VALID'"; - if (!$self->{schema}) { - $str .= " AND OWNER <> 'SYS' AND OWNER <> 'SYSTEM' AND OWNER <> 'DBSNMP' AND OWNER <> 'OUTLN'"; - } else { - $str .= " AND OWNER = '$self->{schema}'"; - } - my $sth = $self->{dbh}->prepare($str) or die $self->{dbh}->errstr; - $sth->execute or die $sth->errstr; - - my %functions = (); - my @fct_done = (); - while (my $row = $sth->fetch) { - next if (grep(/^$row->[0]$/, @fct_done)); - push(@fct_done, $row->[0]); - my $sql = "SELECT TEXT FROM DBA_SOURCE WHERE OWNER='$row->[1]' AND NAME='$row->[0]' ORDER BY LINE"; - my $sth2 = $self->{dbh}->prepare($sql) or die $self->{dbh}->errstr; - $sth2->execute or die $sth2->errstr; - while (my $r = $sth2->fetch) { - $functions{"$row->[0]"} .= $r->[0]; - } - } - - return \%functions; -} - - -=head2 _get_packages - -This function implements a Oracle-native packages information. - -Return a hash of all function name with their PLSQL code - -=cut - -sub _get_packages -{ - my ($self) = @_; - - # Retrieve all indexes - my $str = "SELECT DISTINCT OBJECT_NAME,OWNER FROM DBA_OBJECTS WHERE OBJECT_TYPE='PACKAGE' AND STATUS='VALID'"; - if (!$self->{schema}) { - $str .= " AND OWNER <> 'SYS' AND OWNER <> 'SYSTEM' AND OWNER <> 'DBSNMP' AND OWNER <> 'OUTLN'"; - } else { - $str .= " AND OWNER = '$self->{schema}'"; - } - - my $sth = $self->{dbh}->prepare($str) or die $self->{dbh}->errstr; - $sth->execute or die $sth->errstr; - - my %packages = (); - my @fct_done = (); - while (my $row = $sth->fetch) { -print STDERR "\tFound Package: $row->[0]\n" if ($self->{debug}); - next if (grep(/^$row->[0]$/, @fct_done)); - push(@fct_done, $row->[0]); - my $sql = "SELECT TEXT FROM DBA_SOURCE WHERE OWNER='$row->[1]' AND NAME='$row->[0]' ORDER BY LINE"; - my $sth2 = $self->{dbh}->prepare($sql) or die $self->{dbh}->errstr; - $sth2->execute or die $sth2->errstr; - while (my $r = $sth2->fetch) { - $packages{"$row->[0]"} .= $r->[0]; - } - } - - return \%packages; -} - - - -=head2 _table_info - -This function retrieve all Oracle-native tables information. - -Return a handle to a DB query statement - -=cut - - -sub _table_info -{ - my $self = shift; - - my $sql = "SELECT - NULL TABLE_CAT, - at.OWNER TABLE_SCHEM, - at.TABLE_NAME, - tc.TABLE_TYPE, - tc.COMMENTS REMARKS - from ALL_TABLES at, ALL_TAB_COMMENTS tc - where at.OWNER = tc.OWNER - and at.TABLE_NAME = tc.TABLE_NAME - "; - - if ($self->{schema}) { - $sql .= " and at.OWNER='$self->{schema}'"; - } else { - $sql .= "AND at.OWNER <> 'SYS' AND at.OWNER <> 'SYSTEM' AND at.OWNER <> 'DBSNMP' AND at.OWNER <> 'OUTLN'"; - } - $sql .= " order by tc.TABLE_TYPE, at.OWNER, at.TABLE_NAME"; - my $sth = $self->{dbh}->prepare( $sql ) or return undef; - $sth->execute or return undef; - $sth; -} - -1; - -__END__ - - -=head1 AUTHOR - -Gilles Darold - - -=head1 COPYRIGHT - -Copyright (c) 2001 Gilles Darold - All rights reserved. - -This program is free software; you can redistribute it and/or modify it under -the same terms as Perl itself. - - -=head1 BUGS - -This perl module is in the same state as my knowledge regarding database, -it can move and not be compatible with older version so I will do my best -to give you official support for Ora2Pg. Your volontee to help construct -it and your contribution are welcome. - - -=head1 SEE ALSO - -L, L, L - - -=head1 ACKNOWLEDGEMENTS - -Thanks to Jason Servetar who decided me to implement data extraction. - -=cut - - diff --git a/contrib/oracle/README.ora2pg b/contrib/oracle/README.ora2pg deleted file mode 100644 index 2d23f816af..0000000000 --- a/contrib/oracle/README.ora2pg +++ /dev/null @@ -1,480 +0,0 @@ -NAME - Ora2Pg - Oracle to PostgreSQL database schema converter - -SYNOPSIS - BEGIN { - $ENV{ORACLE_HOME} = '/usr/local/oracle/oracle816'; - } - - use strict; - - use Ora2Pg; - - # Init the database connection - my $dbsrc = 'dbi:Oracle:host=testdb.samse.fr;sid=TEST;port=1521'; - my $dbuser = 'system'; - my $dbpwd = 'manager'; - - # Create an instance of the Ora2Pg perl module - my $schema = new Ora2Pg ( - datasource => $dbsrc, # Database DBD datasource - user => $dbuser, # Database user - password => $dbpwd, # Database password - { - PrintError => 0, - RaiseError => 1, - AutoCommit => 0 - } - ); - - # Create the POSTGRESQL representation of all objects in the database - $schema->export_schema("output.sql"); - - exit(0); - - or if you only want to extract some tables: - - # Create an instance of the Ora2Pg perl module - my @tables = ('tab1', 'tab2', 'tab3'); - my $schema = new Ora2Pg ( - datasource => $dbsrc, # Database DBD datasource - user => $dbuser, # Database user - password => $dbpwd, # Database password - tables => \@tables, - or # Tables to extract - tables => [('tab1','tab2')], - debug => 1 # To show somethings when running - ); - - or if you only want to extract the 10 first tables: - - # Create an instance of the Ora2Pg perl module - my $schema = new Ora2Pg ( - datasource => $dbsrc, # Database DBD datasource - user => $dbuser, # Database user - password => $dbpwd, # Database password - max => 10 # 10 first tables to extract - ); - - or if you only want to extract tables 10 to 20: - - # Create an instance of the Ora2Pg perl module - my $schema = new Ora2Pg ( - datasource => $dbsrc, # Database DBD datasource - user => $dbuser, # Database user - password => $dbpwd, # Database password - min => 10, # Begin extraction at indice 10 - max => 20 # End extraction at indice 20 - ); - - To choose a particular Oracle schema to export just set the following - option to your schema name: - - schema => 'APPS' - - This schema definition can also be needed when you want to export data. - If export failed and complain that the table doesn't exists use this to - prefix the table name by the schema name. - - To know at which indices tables can be found during extraction use the - option: - - showtableid => 1 - - To extract all views set the type option as follow: - - type => 'VIEW' - - To extract all grants set the type option as follow: - - type => 'GRANT' - - To extract all sequences set the type option as follow: - - type => 'SEQUENCE' - - To extract all triggers set the type option as follow: - - type => 'TRIGGER' - - To extract all functions set the type option as follow: - - type => 'FUNCTION' - - To extract all procedures set the type option as follow: - - type => 'PROCEDURE' - - To extract all packages and body set the type option as follow: - - type => 'PACKAGE' - - Default is table extraction - - type => 'TABLE' - - To extract all data from table extraction as INSERT statement use: - - type => 'DATA' - - To extract all data from table extraction as COPY statement use: - - type => 'COPY' - - and data_limit => n to specify the max tuples to return. If you set this - options to 0 or nothing, no limitation are used. Additional option - 'table', 'min' and 'max' can also be used. - - When use of COPY or DATA you can export data by calling method: - - $schema->export_data("output.sql"); - - Data are dumped to the given filename or to STDOUT with no argument. You - can also send these data directly to a PostgreSQL backend using the - following method: - - $schema->send_to_pgdb($destdatasrc,$destuser,$destpasswd); - - In this case you must call export_data() without argument after the call - to method send_to_pgdb(). - - If you set type to COPY and you want to dump data directly to a PG - database, you must call method send_to_pgdb but data will not be sent - via DBD::Pg but they will be load to the database using the psql - command. Calling this method is istill required to be able to extract - database name, hostname and port information. Edit the $PSQL variable to - match the path of your psql command (nothing to edit if psql is in your - path). - -DESCRIPTION - Ora2Pg is a perl OO module used to export an Oracle database schema to a - PostgreSQL compatible schema. - - It simply connect to your Oracle database, extract its structure and - generate a SQL script that you can load into your PostgreSQL database. - - I'm not a Oracle DBA so I don't really know something about its internal - structure so you may find some incorrect things. Please tell me what is - wrong and what can be better. - - It currently dump the database schema (tables, views, sequences, - indexes, grants), with primary, unique and foreign keys into PostgreSQL - syntax without editing the SQL code generated. - - It now can dump Oracle data into PostgreSQL DB as online process. You - can choose what columns can be exported for each table. - - Functions, procedures and triggers PL/SQL code generated must be - reviewed to match the PostgreSQL syntax. Some usefull recommandation on - porting Oracle to PostgreSQL can be found at - http://techdocs.postgresql.org/ under the "Converting from other - Databases to PostgreSQL" Oracle part. I just notice one thing more is - that the trunc() function in Oracle is the same for number or date so be - carefull when porting to PostgreSQL to use trunc() for number and - date_trunc() for date. - -ABSTRACT - The goal of the Ora2Pg perl module is to cover all part needed to export - an Oracle database to a PostgreSQL database without other thing that - provide the connection parameters to the Oracle database. - - Features must include: - - - Database schema export (tables, views, sequences, indexes), - with unique, primary and foreign key. - - Grants/privileges export by user and group. - - Table selection (by name and max table) export. - - Predefined functions/triggers/procedures/packages export. - - Data export. - - Sql query converter (todo) - - My knowledge regarding database is really poor especially for Oracle so - contribution is welcome. - -REQUIREMENT - You just need the DBI, DBD::Pg and DBD::Oracle perl module to be - installed - -PUBLIC METHODS - new HASH_OPTIONS - - Creates a new Ora2Pg object. - - Supported options are: - - - datasource : DBD datasource (required) - - user : DBD user (optional with public access) - - password : DBD password (optional with public access) - - schema : Oracle internal schema to extract - - type : Type of data to extract, can be TABLE,VIEW,GRANT,SEQUENCE, - TRIGGER,FUNCTION,PROCEDURE,DATA,COPY,PACKAGE - - debug : Print the current state of the parsing - - tables : Extract only the given tables (arrayref) - - showtableid : Display only the table indice during extraction - - min : Indice to begin extraction. Default to 0 - - max : Indice to end extraction. Default to 0 mean no limits - - data_limit : Number max of tuples to return during data extraction (default 10) - - Attempt that this list should grow a little more because all - initialization is done by this way. - - export_data FILENAME - - Print SQL data output to a filename or to STDOUT if no file is given. - - Must be used only if type option is set to DATA or COPY =cut - - sub export_data { my ($self, $outfile) = @_; - - $self->_get_sql_data($outfile); - } - - export_sql FILENAME - - Print SQL conversion output to a filename or simply return these data if - no file is given. - - send_to_pgdb DEST_DATASRC DEST_USER DEST_PASSWD - - Open a DB handle to a PostgreSQL database - - modify_struct TABLE_NAME ARRAYOF_FIELDNAME - - Modify a table structure during export. Only given fieldname will be - exported. - -PRIVATE METHODS - _init HASH_OPTIONS - - Initialize a Ora2Pg object instance with a connexion to the Oracle - database. - - _grants - - This function is used to retrieve all privilege information. - - It extract all Oracle's ROLES to convert them as Postgres groups and - search all users associated to these roles. - - Set the main hash $self->{groups}. Set the main hash $self->{grantss}. - - _sequences - - This function is used to retrieve all sequences information. - - Set the main hash $self->{sequences}. - - _triggers - - This function is used to retrieve all triggers information. - - Set the main hash $self->{triggers}. - - _functions - - This function is used to retrieve all functions information. - - Set the main hash $self->{functions}. - - _packages - - This function is used to retrieve all packages information. - - Set the main hash $self->{packages}. - - _tables - - This function is used to retrieve all table information. - - Set the main hash of the database structure $self->{tables}. Keys are - the names of all tables retrieved from the current database. Each table - information compose an array associated to the table_info key as array - reference. In other way: - - $self->{tables}{$class_name}{table_info} = [(OWNER,TYPE)]; - - DBI TYPE can be TABLE, VIEW, SYSTEM TABLE, GLOBAL TEMPORARY, LOCAL - TEMPORARY, ALIAS, SYNONYM or a data source specific type identifier. - This only extract TABLE type. - - It also get the following informations in the DBI object to affect the - main hash of the database structure : - - $self->{tables}{$class_name}{field_name} = $sth->{NAME}; - $self->{tables}{$class_name}{field_type} = $sth->{TYPE}; - - It also call these other private subroutine to affect the main hash of - the database structure : - - @{$self->{tables}{$class_name}{column_info}} = $self->_column_info($class_name); - @{$self->{tables}{$class_name}{primary_key}} = $self->_primary_key($class_name); - @{$self->{tables}{$class_name}{unique_key}} = $self->_unique_key($class_name); - @{$self->{tables}{$class_name}{foreign_key}} = $self->_foreign_key($class_name); - - _views - - This function is used to retrieve all views information. - - Set the main hash of the views definition $self->{views}. Keys are the - names of all views retrieved from the current database values are the - text definition of the views. - - It then set the main hash as follow: - - # Definition of the view - $self->{views}{$table}{text} = $view_infos{$table}; - - _get_sql_data - - Returns a string containing the entire SQL Schema definition compatible - with PostgreSQL - - _get_data TABLE - - This function implements a Oracle-native data extraction. - - Return a list of array reference containing the data - - _sql_type INTERNAL_TYPE LENGTH PRECISION SCALE - - This function return the PostgreSQL datatype corresponding to the Oracle - internal type. - - _column_info TABLE - - This function implements a Oracle-native column information. - - Return a list of array reference containing the following informations - for each column the given a table - - [( column name, column type, column length, nullable column, default - value )] - - _primary_key TABLE - - This function implements a Oracle-native primary key column information. - - Return a list of all column name defined as primary key for the given - table. - - _unique_key TABLE - - This function implements a Oracle-native unique key column information. - - Return a list of all column name defined as unique key for the given - table. - - _foreign_key TABLE - - This function implements a Oracle-native foreign key reference - information. - - Return a list of hash of hash of array reference. Ouuf! Nothing very - difficult. The first hash is composed of all foreign key name. The - second hash just have two key known as 'local' and remote' corresponding - to the local table where the foreign key is defined and the remote table - where the key refer. - - The foreign key name is composed as follow: - - 'local_table_name->remote_table_name' - - Foreign key data consist in two array representing at the same indice - the local field and the remote field where the first one refer to the - second. Just like this: - - @{$link{$fkey_name}{local}} = @local_columns; - @{$link{$fkey_name}{remote}} = @remote_columns; - - _get_users - - This function implements a Oracle-native users information. - - Return a hash of all users as an array. - - _get_roles - - This function implements a Oracle-native roles information. - - Return a hash of all groups (roles) as an array of associated users. - - _get_all_grants - - This function implements a Oracle-native user privilege information. - - Return a hash of all tables grants as an array of associated users. - - _get_indexes TABLE - - This function implements a Oracle-native indexes information. - - Return hash of array containing all unique index and a hash of array of - all indexes name which are not primary keys for the given table. - - _get_sequences - - This function implements a Oracle-native sequences information. - - Return a hash of array of sequence name with MIN_VALUE, MAX_VALUE, - INCREMENT and LAST_NUMBER for the given table. - - _get_views - - This function implements a Oracle-native views information. - - Return a hash of view name with the SQL query it is based on. - - _alias_info - - This function implements a Oracle-native column information. - - Return a list of array reference containing the following informations - for each alias of the given view - - [( column name, column id )] - - _get_triggers - - This function implements a Oracle-native triggers information. - - Return an array of refarray of all triggers informations - - _get_functions - - This function implements a Oracle-native functions information. - - Return a hash of all function name with their PLSQL code - - _get_packages - - This function implements a Oracle-native packages information. - - Return a hash of all function name with their PLSQL code - - _table_info - - This function retrieve all Oracle-native tables information. - - Return a handle to a DB query statement - -AUTHOR - Gilles Darold - -COPYRIGHT - Copyright (c) 2001 Gilles Darold - All rights reserved. - - This program is free software; you can redistribute it and/or modify it - under the same terms as Perl itself. - -BUGS - This perl module is in the same state as my knowledge regarding - database, it can move and not be compatible with older version so I will - do my best to give you official support for Ora2Pg. Your volontee to - help construct it and your contribution are welcome. - -SEE ALSO - the DBI manpage, the DBD::Oracle manpage, the DBD::Pg manpage - -ACKNOWLEDGEMENTS - Thanks to Jason Servetar who decided me to implement data extraction. - diff --git a/contrib/oracle/TODO b/contrib/oracle/TODO deleted file mode 100644 index c9f4392170..0000000000 --- a/contrib/oracle/TODO +++ /dev/null @@ -1,10 +0,0 @@ -Add possible call to perl function for each field value exported -(data conversion on the fly before dump) - - - Fix problem regarding table/constraint output order. - -The following need your help : - - - SQL queries converter. - - PL/SQL code converter. - diff --git a/contrib/oracle/ora2pg.html b/contrib/oracle/ora2pg.html deleted file mode 100644 index 544ddcfae5..0000000000 --- a/contrib/oracle/ora2pg.html +++ /dev/null @@ -1,480 +0,0 @@ - - -Ora2Pg - Oracle to PostgreSQL database schema converter - - - - - - - - - - - -
-

-

NAME

-

Ora2Pg - Oracle to PostgreSQL database schema converter

-

-


-

SYNOPSIS

-
-        BEGIN {
-                $ENV{ORACLE_HOME} = '/usr/local/oracle/oracle816';
-        }
-
-        use strict;
-
-        use Ora2Pg;
-
-        # Init the database connection
-        my $dbsrc = 'dbi:Oracle:host=testdb.samse.fr;sid=TEST;port=1521';
-        my $dbuser = 'system';
-        my $dbpwd = 'manager';
-
-        # Create an instance of the Ora2Pg perl module
-        my $schema = new Ora2Pg (
-                datasource => $dbsrc,           # Database DBD datasource
-                user => $dbuser,                # Database user
-                password => $dbpwd,             # Database password
-                {
-                        PrintError => 0,
-                        RaiseError => 1,
-                        AutoCommit => 0
-                }
-        );
-
-        # Create the POSTGRESQL representation of all objects in the database
-        $schema->export_schema("output.sql");
-
-        exit(0);
-

or if you only want to extract some tables:

-
-        # Create an instance of the Ora2Pg perl module
-        my @tables = ('tab1', 'tab2', 'tab3');
-        my $schema = new Ora2Pg (
-                datasource => $dbsrc,           # Database DBD datasource
-                user => $dbuser,                # Database user
-                password => $dbpwd,             # Database password
-                tables => \@tables,
-        or                                      # Tables to extract
-                tables => [('tab1','tab2')],
-                debug => 1                      # To show somethings when running
-        );
-

or if you only want to extract the 10 first tables:

-
-        # Create an instance of the Ora2Pg perl module
-        my $schema = new Ora2Pg (
-                datasource => $dbsrc,           # Database DBD datasource
-                user => $dbuser,                # Database user
-                password => $dbpwd,             # Database password
-                max => 10                       # 10 first tables to extract
-        );
-

or if you only want to extract tables 10 to 20:

-
-        # Create an instance of the Ora2Pg perl module
-        my $schema = new Ora2Pg (
-                datasource => $dbsrc,           # Database DBD datasource
-                user => $dbuser,                # Database user
-                password => $dbpwd,             # Database password
-                min => 10,                      # Begin extraction at indice 10
-                max => 20                       # End extraction at indice 20
-        );
-

To choose a particular Oracle schema to export just set the following option -to your schema name:

-
-        schema => 'APPS'
-

This schema definition can also be needed when you want to export data. If export -failed and complain that the table doesn't exists use this to prefix the table name -by the schema name.

-

To know at which indices tables can be found during extraction use the option:

-
-        showtableid => 1
-

To extract all views set the type option as follow:

-
-        type => 'VIEW'
-

To extract all grants set the type option as follow:

-
-        type => 'GRANT'
-

To extract all sequences set the type option as follow:

-
-        type => 'SEQUENCE'
-

To extract all triggers set the type option as follow:

-
-        type => 'TRIGGER'
-

To extract all functions set the type option as follow:

-
-        type => 'FUNCTION'
-

To extract all procedures set the type option as follow:

-
-        type => 'PROCEDURE'
-

To extract all packages and body set the type option as follow:

-
-        type => 'PACKAGE'
-

Default is table extraction

-
-        type => 'TABLE'
-

To extract all data from table extraction as INSERT statement use:

-
-        type => 'DATA'
-

To extract all data from table extraction as COPY statement use:

-
-        type => 'COPY'
-

and data_limit => n to specify the max tuples to return. If you set -this options to 0 or nothing, no limitation are used. Additional option -'table', 'min' and 'max' can also be used.

-

When use of COPY or DATA you can export data by calling method:

-

$schema->export_data(``output.sql'');

-

Data are dumped to the given filename or to STDOUT with no argument. -You can also send these data directly to a PostgreSQL backend using - the following method:

-

$schema->send_to_pgdb($destdatasrc,$destuser,$destpasswd);

-

In this case you must call export_data() without argument after the -call to method send_to_pgdb().

-

If you set type to COPY and you want to dump data directly to a PG database, -you must call method send_to_pgdb but data will not be sent via DBD::Pg but -they will be load to the database using the psql command. Calling this method -is istill required to be able to extract database name, hostname and port -information. Edit the $PSQL variable to match the path of your psql -command (nothing to edit if psql is in your path).

-

-


-

DESCRIPTION

-

Ora2Pg is a perl OO module used to export an Oracle database schema -to a PostgreSQL compatible schema.

-

It simply connect to your Oracle database, extract its structure and -generate a SQL script that you can load into your PostgreSQL database.

-

I'm not a Oracle DBA so I don't really know something about its internal -structure so you may find some incorrect things. Please tell me what is -wrong and what can be better.

-

It currently dump the database schema (tables, views, sequences, indexes, grants), -with primary, unique and foreign keys into PostgreSQL syntax without editing the -SQL code generated.

-

It now can dump Oracle data into PostgreSQL DB as online process. You can choose -what columns can be exported for each table.

-

Functions, procedures and triggers PL/SQL code generated must be reviewed to match -the PostgreSQL syntax. Some usefull recommandation on porting Oracle to PostgreSQL -can be found at http://techdocs.postgresql.org/ under the ``Converting from other -Databases to PostgreSQL'' Oracle part. I just notice one thing more is that the -trunc() function in Oracle is the same for number or date so be carefull when -porting to PostgreSQL to use trunc() for number and date_trunc() for date.

-

-


-

ABSTRACT

-

The goal of the Ora2Pg perl module is to cover all part needed to export -an Oracle database to a PostgreSQL database without other thing that provide -the connection parameters to the Oracle database.

-

Features must include:

-
-        - Database schema export (tables, views, sequences, indexes),
-          with unique, primary and foreign key.
-        - Grants/privileges export by user and group.
-        - Table selection (by name and max table) export.
-        - Predefined functions/triggers/procedures/packages export.
-        - Data export.
-        - Sql query converter (todo)
-

My knowledge regarding database is really poor especially for Oracle -so contribution is welcome.

-

-


-

REQUIREMENT

-

You just need the DBI, DBD::Pg and DBD::Oracle perl module to be installed

-

-


-

PUBLIC METHODS

-

-

new HASH_OPTIONS

-

Creates a new Ora2Pg object.

-

Supported options are:

-
-        - datasource    : DBD datasource (required)
-        - user          : DBD user (optional with public access)
-        - password      : DBD password (optional with public access)
-        - schema        : Oracle internal schema to extract
-        - type          : Type of data to extract, can be TABLE,VIEW,GRANT,SEQUENCE,
-                          TRIGGER,FUNCTION,PROCEDURE,DATA,COPY,PACKAGE
-        - debug         : Print the current state of the parsing
-        - tables        : Extract only the given tables (arrayref)
-        - showtableid   : Display only the table indice during extraction
-        - min           : Indice to begin extraction. Default to 0
-        - max           : Indice to end extraction. Default to 0 mean no limits
-        - data_limit    : Number max of tuples to return during data extraction (default 10)
-

Attempt that this list should grow a little more because all initialization is -done by this way.

-

-

export_data FILENAME

-

Print SQL data output to a filename or -to STDOUT if no file is given.

-

Must be used only if type option is set to DATA or COPY -=cut

-

sub export_data -{ - my ($self, $outfile) = @_;

-
-        $self->_get_sql_data($outfile);
-}
-

-

export_sql FILENAME

-

Print SQL conversion output to a filename or -simply return these data if no file is given.

-

-

send_to_pgdb DEST_DATASRC DEST_USER DEST_PASSWD

-

Open a DB handle to a PostgreSQL database

-

-

modify_struct TABLE_NAME ARRAYOF_FIELDNAME

-

Modify a table structure during export. Only given fieldname -will be exported.

-

-


-

PRIVATE METHODS

-

-

_init HASH_OPTIONS

-

Initialize a Ora2Pg object instance with a connexion to the -Oracle database.

-

-

_grants

-

This function is used to retrieve all privilege information.

-

It extract all Oracle's ROLES to convert them as Postgres groups -and search all users associated to these roles.

-

Set the main hash $self->{groups}. -Set the main hash $self->{grantss}.

-

-

_sequences

-

This function is used to retrieve all sequences information.

-

Set the main hash $self->{sequences}.

-

-

_triggers

-

This function is used to retrieve all triggers information.

-

Set the main hash $self->{triggers}.

-

-

_functions

-

This function is used to retrieve all functions information.

-

Set the main hash $self->{functions}.

-

-

_packages

-

This function is used to retrieve all packages information.

-

Set the main hash $self->{packages}.

-

-

_tables

-

This function is used to retrieve all table information.

-

Set the main hash of the database structure $self->{tables}. -Keys are the names of all tables retrieved from the current -database. Each table information compose an array associated -to the table_info key as array reference. In other way:

-
-    $self->{tables}{$class_name}{table_info} = [(OWNER,TYPE)];
-

DBI TYPE can be TABLE, VIEW, SYSTEM TABLE, GLOBAL TEMPORARY, LOCAL TEMPORARY, -ALIAS, SYNONYM or a data source specific type identifier. This only extract -TABLE type.

-

It also get the following informations in the DBI object to affect the -main hash of the database structure :

-
-    $self->{tables}{$class_name}{field_name} = $sth->{NAME};
-    $self->{tables}{$class_name}{field_type} = $sth->{TYPE};
-

It also call these other private subroutine to affect the main hash -of the database structure :

-
-    @{$self->{tables}{$class_name}{column_info}} = $self->_column_info($class_name);
-    @{$self->{tables}{$class_name}{primary_key}} = $self->_primary_key($class_name);
-    @{$self->{tables}{$class_name}{unique_key}}  = $self->_unique_key($class_name);
-    @{$self->{tables}{$class_name}{foreign_key}} = $self->_foreign_key($class_name);
-

-

_views

-

This function is used to retrieve all views information.

-

Set the main hash of the views definition $self->{views}. -Keys are the names of all views retrieved from the current -database values are the text definition of the views.

-

It then set the main hash as follow:

-
-    # Definition of the view
-    $self->{views}{$table}{text} = $view_infos{$table};
-

-

_get_sql_data

-

Returns a string containing the entire SQL Schema definition compatible with PostgreSQL

-

-

_get_data TABLE

-

This function implements a Oracle-native data extraction.

-

Return a list of array reference containing the data

-

-

_sql_type INTERNAL_TYPE LENGTH PRECISION SCALE

-

This function return the PostgreSQL datatype corresponding to the -Oracle internal type.

-

-

_column_info TABLE

-

This function implements a Oracle-native column information.

-

Return a list of array reference containing the following informations -for each column the given a table

-

[( - column name, - column type, - column length, - nullable column, - default value -)]

-

-

_primary_key TABLE

-

This function implements a Oracle-native primary key column -information.

-

Return a list of all column name defined as primary key -for the given table.

-

-

_unique_key TABLE

-

This function implements a Oracle-native unique key column -information.

-

Return a list of all column name defined as unique key -for the given table.

-

-

_foreign_key TABLE

-

This function implements a Oracle-native foreign key reference -information.

-

Return a list of hash of hash of array reference. Ouuf! Nothing very difficult. -The first hash is composed of all foreign key name. The second hash just have -two key known as 'local' and remote' corresponding to the local table where the -foreign key is defined and the remote table where the key refer.

-

The foreign key name is composed as follow:

-
-    'local_table_name->remote_table_name'
-

Foreign key data consist in two array representing at the same indice the local -field and the remote field where the first one refer to the second. -Just like this:

-
-    @{$link{$fkey_name}{local}} = @local_columns;
-    @{$link{$fkey_name}{remote}} = @remote_columns;
-

-

_get_users

-

This function implements a Oracle-native users information.

-

Return a hash of all users as an array.

-

-

_get_roles

-

This function implements a Oracle-native roles -information.

-

Return a hash of all groups (roles) as an array of associated users.

-

-

_get_all_grants

-

This function implements a Oracle-native user privilege -information.

-

Return a hash of all tables grants as an array of associated users.

-

-

_get_indexes TABLE

-

This function implements a Oracle-native indexes information.

-

Return hash of array containing all unique index and a hash of -array of all indexes name which are not primary keys for the -given table.

-

-

_get_sequences

-

This function implements a Oracle-native sequences -information.

-

Return a hash of array of sequence name with MIN_VALUE, MAX_VALUE, -INCREMENT and LAST_NUMBER for the given table.

-

-

_get_views

-

This function implements a Oracle-native views information.

-

Return a hash of view name with the SQL query it is based on.

-

-

_alias_info

-

This function implements a Oracle-native column information.

-

Return a list of array reference containing the following informations -for each alias of the given view

-

[( - column name, - column id -)]

-

-

_get_triggers

-

This function implements a Oracle-native triggers information.

-

Return an array of refarray of all triggers informations

-

-

_get_functions

-

This function implements a Oracle-native functions information.

-

Return a hash of all function name with their PLSQL code

-

-

_get_packages

-

This function implements a Oracle-native packages information.

-

Return a hash of all function name with their PLSQL code

-

-

_table_info

-

This function retrieve all Oracle-native tables information.

-

Return a handle to a DB query statement

-

-


-

AUTHOR

-

Gilles Darold <gilles@darold.net>

-

-


-

COPYRIGHT

-

Copyright (c) 2001 Gilles Darold - All rights reserved.

-

This program is free software; you can redistribute it and/or modify it under -the same terms as Perl itself.

-

-


-

BUGS

-

This perl module is in the same state as my knowledge regarding database, -it can move and not be compatible with older version so I will do my best -to give you official support for Ora2Pg. Your volontee to help construct -it and your contribution are welcome.

-

-


-

SEE ALSO

-

DBI, the DBD::Oracle manpage, the DBD::Pg manpage

-

-


-

ACKNOWLEDGEMENTS

-

Thanks to Jason Servetar who decided me to implement data extraction.

- - - - diff --git a/contrib/oracle/ora2pg.pl b/contrib/oracle/ora2pg.pl deleted file mode 100755 index 3a15fb7bed..0000000000 --- a/contrib/oracle/ora2pg.pl +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/perl -#------------------------------------------------------------------------------ -# Project : Oracle2Postgresql -# Name : ora2pg.pl -# Language : 5.006 built for i686-linux -# OS : linux RedHat 6.2 kernel 2.2.14-5 -# Author : Gilles Darold, gilles@darold.net -# Copyright: Copyright (c) 2000 : Gilles Darold - All rights reserved - -# Function : Script used to convert Oracle Database schema to PostgreSQL -#------------------------------------------------------------------------------ -# Version : 1.1 -#------------------------------------------------------------------------------ - -BEGIN { - $ENV{ORACLE_HOME} = '/usr/local/oracle/oracle816'; -} - -use strict; - -use Ora2Pg; - -# Initialyze the database connection -my $dbsrc = 'dbi:Oracle:host=test.mydomain.com;sid=TEST;port=1521'; -my $dbuser = 'system'; -my $dbpwd = 'manager'; - -# Create an instance of the XSD::DBISchema perl module -my $schema = new Ora2Pg ( - datasource => $dbsrc, # Database DBD datasource - user => $dbuser, # Database user - password => $dbpwd, # Database password - debug => 1, # Verbose mode - schema => 'APPS', # Extract only APPS schema - type => 'TABLE', # Extract table -# type => 'PACKAGE', # Extract PACKAGE information -# type => 'DATA', # Extract data with output as INSERT statement -# type => 'COPY', # Extract data with output as COPY statement -# type => 'VIEW', # Extract views -# type => 'GRANT', # Extract privileges -# type => 'SEQUENCE', # Extract sequences -# type => 'TRIGGER', # Extract triggers -# type => 'FUNCTION', # Extract functions -# type => 'PROCEDURE', # Extract procedures -# tables => [('FND_USER_PREFERENCES')], # unique index + users -# tables => [('CUSTOMER_DATA')], # Unique and primary key -# tables => [('TX_DATA')], # simple indexes -# tables => [('NDW_BROWSER_ATTRIBUTES')], # view -# tables => [('TRIP_DATA')], # Foreign key -# showtableid => 1, # Display only table indice during extraction -# min => 1, # Extract begin at indice 3 -# max => 10, # Extract ended at indice 5 -# data_limit => 1000, # Extract all data by dump of 1000 tuples -# data_limit => 0, # Extract all data in one pass. Be sure to have enougth memory -); - -# Just export data of the following fields from table 's_txcot' -#$schema->modify_struct('s_txcot','dossier', 'rub', 'datapp'); - -# Function to use for extraction when type option is set to DATA or COPY - # Send exported data to a PostgreSQL database - #$schema->send_to_pgdb('dbi:Pg:dbname=template1;host=localhost;port=5432','test','test'); - - # Output the data extracted from Oracle DB to a file or to STDOUT if no argument. - # If you set the send_to_pgdb() method the output is given to PG database. See above - #$schema->export_data("output.sql"); - -# Function to use ifor extraction with other type - # Create the POSTGRESQL representation of all objects in the database - $schema->export_schema("output.sql"); - -exit(0); - diff --git a/contrib/pg_controldata/Makefile b/contrib/pg_controldata/Makefile deleted file mode 100644 index 80ffad854c..0000000000 --- a/contrib/pg_controldata/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/pg_controldata/Attic/Makefile,v 1.5 2001/09/06 10:49:29 petere Exp $ - -subdir = contrib/pg_controldata -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -PROGRAM = pg_controldata -OBJS = pg_controldata.o pg_crc.o $(SNPRINTF) - -pg_crc.c: $(top_srcdir)/src/backend/utils/hash/pg_crc.c - rm -f $@ && $(LN_S) $< . - -# this only gets done if configure finds system doesn't have snprintf() -snprintf.c: $(top_srcdir)/src/backend/port/snprintf.c - rm -f $@ && $(LN_S) $< . - -EXTRA_CLEAN = pg_crc.c snprintf.c - -DOCS = README.pg_controldata - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/pg_controldata/README.pg_controldata b/contrib/pg_controldata/README.pg_controldata deleted file mode 100644 index 85ca0e1467..0000000000 --- a/contrib/pg_controldata/README.pg_controldata +++ /dev/null @@ -1,32 +0,0 @@ -I had a need to read such things as the backend locale and the catalog -version number from the current database, and couldn't find any existing -program to do that. - -The attached utility produces output like this: - -$ pg_controldata -pg_control version number: 71 -Catalog version number: 200101061 -Database state: IN_PRODUCTION -pg_control last modified: Sat Mar 10 00:07:55 2001 -Current log file id: 0 -Next log file segment: 9 -Latest checkpoint location: 0/88CAA20 -Prior checkpoint location: 0/70A5D48 -Latest checkpoint's REDO location: 0/88CAA20 -Latest checkpoint's UNDO location: 0/0 -Latest checkpoint's StartUpID: 22 -Latest checkpoint's NextXID: 4711 -Latest checkpoint's NextOID: 444704 -Time of latest checkpoint: Sat Mar 10 00:07:52 2001 -Database block size: 8192 -Blocks per segment of large relation: 131072 -LC_COLLATE: C -LC_CTYPE: C - - -To access the pg_control file, the program must be run as the Postgres user, -and PGDATA must be set correctly in its environment. - --- -Oliver Elphick diff --git a/contrib/pg_controldata/pg_controldata.c b/contrib/pg_controldata/pg_controldata.c deleted file mode 100644 index 1cbd352caf..0000000000 --- a/contrib/pg_controldata/pg_controldata.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * pg_controldata - * - * reads the data from $PGDATA/global/pg_control - * - * copyright (c) Oliver Elphick , 2001; - * licence: BSD - * - * $Header: /cvsroot/pgsql/contrib/pg_controldata/Attic/pg_controldata.c,v 1.5 2001/10/25 05:49:19 momjian Exp $ - */ -#include "postgres.h" - -#include -#include -#include -#include -#include - -#include "catalog/pg_control.h" - - -static const char * -dbState(DBState state) -{ - switch (state) - { - case DB_STARTUP: - return "STARTUP"; - case DB_SHUTDOWNED: - return "SHUTDOWNED"; - case DB_SHUTDOWNING: - return "SHUTDOWNING"; - case DB_IN_RECOVERY: - return "IN_RECOVERY"; - case DB_IN_PRODUCTION: - return "IN_PRODUCTION"; - } - return "unrecognized status code"; -} - - -int -main(int argc, char *argv[]) -{ - ControlFileData ControlFile; - int fd; - char ControlFilePath[MAXPGPATH]; - char *DataDir; - crc64 crc; - char pgctime_str[32]; - char ckpttime_str[32]; - - if (argc > 1) - DataDir = argv[1]; - else - DataDir = getenv("PGDATA"); - if (DataDir == NULL) - { - fprintf(stderr, "no data directory specified\n"); - exit(1); - } - - snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir); - - if ((fd = open(ControlFilePath, O_RDONLY)) == -1) - { - perror("Failed to open $PGDATA/global/pg_control for reading"); - exit(2); - } - - if (read(fd, &ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData)) - { - perror("Failed to read $PGDATA/global/pg_control"); - exit(2); - } - close(fd); - - /* Check the CRC. */ - INIT_CRC64(crc); - COMP_CRC64(crc, - (char *) &ControlFile + sizeof(crc64), - sizeof(ControlFileData) - sizeof(crc64)); - FIN_CRC64(crc); - - if (!EQ_CRC64(crc, ControlFile.crc)) - printf("WARNING: Calculated CRC checksum does not match value stored in file.\n" - "Either the file is corrupt, or it has a different layout than this program\n" - "is expecting. The results below are untrustworthy.\n\n"); - - strftime(pgctime_str, 32, "%c", - localtime(&(ControlFile.time))); - strftime(ckpttime_str, 32, "%c", - localtime(&(ControlFile.checkPointCopy.time))); - - printf("pg_control version number: %u\n" - "Catalog version number: %u\n" - "Database state: %s\n" - "pg_control last modified: %s\n" - "Current log file id: %u\n" - "Next log file segment: %u\n" - "Latest checkpoint location: %X/%X\n" - "Prior checkpoint location: %X/%X\n" - "Latest checkpoint's REDO location: %X/%X\n" - "Latest checkpoint's UNDO location: %X/%X\n" - "Latest checkpoint's StartUpID: %u\n" - "Latest checkpoint's NextXID: %u\n" - "Latest checkpoint's NextOID: %u\n" - "Time of latest checkpoint: %s\n" - "Database block size: %u\n" - "Blocks per segment of large relation: %u\n" - "LC_COLLATE: %s\n" - "LC_CTYPE: %s\n", - - ControlFile.pg_control_version, - ControlFile.catalog_version_no, - dbState(ControlFile.state), - pgctime_str, - ControlFile.logId, - ControlFile.logSeg, - ControlFile.checkPoint.xlogid, - ControlFile.checkPoint.xrecoff, - ControlFile.prevCheckPoint.xlogid, - ControlFile.prevCheckPoint.xrecoff, - ControlFile.checkPointCopy.redo.xlogid, - ControlFile.checkPointCopy.redo.xrecoff, - ControlFile.checkPointCopy.undo.xlogid, - ControlFile.checkPointCopy.undo.xrecoff, - ControlFile.checkPointCopy.ThisStartUpID, - ControlFile.checkPointCopy.nextXid, - ControlFile.checkPointCopy.nextOid, - ckpttime_str, - ControlFile.blcksz, - ControlFile.relseg_size, - ControlFile.lc_collate, - ControlFile.lc_ctype); - - return (0); -} diff --git a/contrib/pg_dumplo/Makefile b/contrib/pg_dumplo/Makefile deleted file mode 100644 index f4be54a4a8..0000000000 --- a/contrib/pg_dumplo/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/Makefile,v 1.11 2001/09/06 10:49:30 petere Exp $ - -subdir = contrib/pg_dumplo -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -PROGRAM = pg_dumplo -OBJS = main.o lo_export.o lo_import.o utils.o - -PG_CPPFLAGS = -I$(libpq_srcdir) -PG_LIBS = $(libpq) - -DOCS = README.pg_dumplo - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/pg_dumplo/README.pg_dumplo b/contrib/pg_dumplo/README.pg_dumplo deleted file mode 100644 index 76ea0f819b..0000000000 --- a/contrib/pg_dumplo/README.pg_dumplo +++ /dev/null @@ -1,148 +0,0 @@ -$Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/README.pg_dumplo,v 1.2 2000/11/22 00:00:55 tgl Exp $ - -pg_dumplo - PostgreSQL large object dumper -========================================== - -By Karel Zak - - -Compilation: -=========== - - * run master ./configure in the PG source top directory - * gmake all - * gmake install - -THANKS: -====== - - - * option '--all' and pg_class usage - - Pavel Janík ml. - * HOWTO (the rest of this file) - - -How to use pg_dumplo? -===================== - -(c) 2000, Pavel Janík ml. - - -Q: How do you use pg_dumplo? -============================ - -A: This is a small demo of backing up the database table with Large Objects: - - -We will create a demo database and a small and useless table `lo' inside -it: - -SnowWhite:$ createdb test -CREATE DATABASE - -Ok, our database with the name 'test' is created. Now we should create demo -table which will contain only one column with the name 'id' which will hold -the OID number of a Large Object: - -SnowWhite:$ psql test -Welcome to psql, the PostgreSQL interactive terminal. - -Type: \copyright for distribution terms - \h for help with SQL commands - \? for help on internal slash commands - \g or terminate with semicolon to execute query - \q to quit - -test=# CREATE TABLE lo (id oid); -CREATE -test=# \lo_import /etc/aliases -lo_import 19338 -test=# INSERT INTO lo VALUES (19338); -INSERT 19352 1 -test=# select * from lo; - id -------- - 19338 -(1 row) - -test=# \q - -In the above example you can see that we have also imported one "Large -Object" - the file /etc/aliases. It has an oid of 19338 so we have inserted -this oid number to the database table lo to the column id. The final SELECT -shows that we have one record in the table. - -Now we can demonstrate the work of pg_dumplo. We will create a dump directory -which will contain the whole dump of large objects (/tmp/dump): - -mkdir -p /tmp/dump - -Now we can dump all large objects from the database `test' which have OIDs -stored in the column `id' in the table `lo': - -SnowWhite:$ pg_dumplo -s /tmp/dump -d test -l lo.id -pg_dumplo: dump lo.id (1 large obj) - -Voila, we have the dump of all Large Objects in our directory: - -SnowWhite:$ tree /tmp/dump/ -/tmp/dump/ -`-- test - |-- lo - | `-- id - | `-- 19338 - `-- lo_dump.index - -3 directories, 2 files -SnowWhite:$ - -In practice, we'd probably use - -SnowWhite:$ pg_dumplo -s /tmp/dump -d test -e - -to export all large objects that are referenced by any OID-type column -in the database. Calling out specific column(s) with -l is only needed -for a selective dump. - -For routine backup purposes, the dump directory could now be converted into -an archive file with tar and stored on tape. Notice that a single dump -directory can hold the dump of multiple databases. - -Now, how can we recreate the contents of the table lo and the Large Object -database when something went wrong? To do this, we expect that pg_dump is -also used to store the definition and contents of the regular tables in -the database. - -SnowWhite:$ pg_dump test >test.backup - -Now, if we lose the database: - -SnowWhite:$ dropdb test -DROP DATABASE - -we can recreate it and reload the regular tables from the dump file: - -SnowWhite:$ createdb test -CREATE DATABASE - -SnowWhite:$ psql test -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "pg_dumplo.h" - -extern int errno; - - -void -load_lolist(LODumpMaster * pgLO) -{ - LOlist *ll; - int i; - int n; - - /* - * Now find any candidate tables who have columns of type oid. - * - * NOTE: System tables including pg_largeobject will be ignored. - * Otherwise we'd end up dumping all LOs, referenced or not. - * - * NOTE: the system oid column is ignored, as it has attnum < 1. This - * shouldn't matter for correctness, but it saves time. - */ - pgLO->res = PQexec(pgLO->conn, - "SELECT c.relname, a.attname " - "FROM pg_class c, pg_attribute a, pg_type t " - "WHERE a.attnum > 0 " - " AND a.attrelid = c.oid " - " AND a.atttypid = t.oid " - " AND t.typname = 'oid' " - " AND c.relkind = 'r' " - " AND c.relname NOT LIKE 'pg_%'"); - - if (PQresultStatus(pgLO->res) != PGRES_TUPLES_OK) - { - fprintf(stderr, "%s: Failed to get LO OIDs:\n%s", progname, - PQerrorMessage(pgLO->conn)); - exit(RE_ERROR); - } - - if ((n = PQntuples(pgLO->res)) == 0) - { - fprintf(stderr, "%s: No OID columns in the database.\n", progname); - exit(RE_ERROR); - } - - pgLO->lolist = (LOlist *) malloc((n + 1) * sizeof(LOlist)); - - if (!pgLO->lolist) - { - fprintf(stderr, "%s: can't allocate memory\n", progname); - exit(RE_ERROR); - } - - for (i = 0, ll = pgLO->lolist; i < n; i++, ll++) - { - ll->lo_table = strdup(PQgetvalue(pgLO->res, i, 0)); - ll->lo_attr = strdup(PQgetvalue(pgLO->res, i, 1)); - } - ll->lo_table = ll->lo_attr = (char *) NULL; - - PQclear(pgLO->res); -} - -void -pglo_export(LODumpMaster * pgLO) -{ - LOlist *ll; - int tuples; - char path[BUFSIZ], - Qbuff[QUERY_BUFSIZ]; - - if (pgLO->action != ACTION_SHOW) - { - time_t t; - - time(&t); - fprintf(pgLO->index, "#\n# This is the PostgreSQL large object dump index\n#\n"); - fprintf(pgLO->index, "#\tDate: %s", ctime(&t)); - fprintf(pgLO->index, "#\tHost: %s\n", pgLO->host); - fprintf(pgLO->index, "#\tDatabase: %s\n", pgLO->db); - fprintf(pgLO->index, "#\tUser: %s\n", pgLO->user); - fprintf(pgLO->index, "#\n# oid\ttable\tattribut\tinfile\n#\n"); - } - - pgLO->counter = 0; - - for (ll = pgLO->lolist; ll->lo_table != NULL; ll++) - { - /* - * Query: find the LOs referenced by this column - */ - sprintf(Qbuff, "SELECT DISTINCT l.loid FROM \"%s\" x, pg_largeobject l WHERE x.\"%s\" = l.loid", - ll->lo_table, ll->lo_attr); - - /* puts(Qbuff); */ - - pgLO->res = PQexec(pgLO->conn, Qbuff); - - if (PQresultStatus(pgLO->res) != PGRES_TUPLES_OK) - { - fprintf(stderr, "%s: Failed to get LO OIDs:\n%s", progname, - PQerrorMessage(pgLO->conn)); - } - else if ((tuples = PQntuples(pgLO->res)) == 0) - { - if (!pgLO->quiet && pgLO->action == ACTION_EXPORT_ATTR) - printf("%s: no large objects in \"%s\".\"%s\"\n", - progname, ll->lo_table, ll->lo_attr); - } - else - { - - int t; - char *val; - - /* - * Create DIR/FILE - */ - if (pgLO->action != ACTION_SHOW) - { - - sprintf(path, "%s/%s/%s", pgLO->space, pgLO->db, - ll->lo_table); - - if (mkdir(path, DIR_UMASK) == -1) - { - if (errno != EEXIST) - { - perror(path); - exit(RE_ERROR); - } - } - - sprintf(path, "%s/%s/%s/%s", pgLO->space, pgLO->db, - ll->lo_table, ll->lo_attr); - - if (mkdir(path, DIR_UMASK) == -1) - { - if (errno != EEXIST) - { - perror(path); - exit(RE_ERROR); - } - } - - if (!pgLO->quiet) - printf("dump %s.%s (%d large obj)\n", - ll->lo_table, ll->lo_attr, tuples); - } - - pgLO->counter += tuples; - - for (t = 0; t < tuples; t++) - { - Oid lo; - - val = PQgetvalue(pgLO->res, t, 0); - - lo = atooid(val); - - if (pgLO->action == ACTION_SHOW) - { - printf("%s.%s: %u\n", ll->lo_table, ll->lo_attr, lo); - continue; - } - - sprintf(path, "%s/%s/%s/%s/%s", pgLO->space, - pgLO->db, ll->lo_table, ll->lo_attr, val); - - if (lo_export(pgLO->conn, lo, path) < 0) - fprintf(stderr, "%s: lo_export failed:\n%s", progname, - PQerrorMessage(pgLO->conn)); - - else - fprintf(pgLO->index, "%s\t%s\t%s\t%s/%s/%s/%s\n", val, - ll->lo_table, ll->lo_attr, pgLO->db, ll->lo_table, ll->lo_attr, val); - } - } - - PQclear(pgLO->res); - } -} diff --git a/contrib/pg_dumplo/lo_import.c b/contrib/pg_dumplo/lo_import.c deleted file mode 100644 index aec2aa0cee..0000000000 --- a/contrib/pg_dumplo/lo_import.c +++ /dev/null @@ -1,101 +0,0 @@ -/* ------------------------------------------------------------------------- - * pg_dumplo - * - * $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/lo_import.c,v 1.6 2001/10/25 05:49:19 momjian Exp $ - * - * Karel Zak 1999-2000 - * ------------------------------------------------------------------------- - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "pg_dumplo.h" - -extern int errno; - -void -pglo_import(LODumpMaster * pgLO) -{ - LOlist loa; - Oid new_oid; - char tab[MAX_TABLE_NAME], - attr[MAX_ATTR_NAME], - path[BUFSIZ], - lo_path[BUFSIZ], - Qbuff[QUERY_BUFSIZ]; - - while (fgets(Qbuff, QUERY_BUFSIZ, pgLO->index)) - { - - if (*Qbuff == '#') - continue; - - if (!pgLO->remove && !pgLO->quiet) - printf(Qbuff); - - sscanf(Qbuff, "%u\t%s\t%s\t%s\n", &loa.lo_oid, tab, attr, path); - loa.lo_table = tab; - loa.lo_attr = attr; - - sprintf(lo_path, "%s/%s", pgLO->space, path); - - /* - * Import LO - */ - if ((new_oid = lo_import(pgLO->conn, lo_path)) == 0) - { - - fprintf(stderr, "%s: %s\n", progname, PQerrorMessage(pgLO->conn)); - - PQexec(pgLO->conn, "ROLLBACK"); - fprintf(stderr, "\n%s: ROLLBACK\n", progname); - exit(RE_ERROR); - } - - if (pgLO->remove) - { - notice(pgLO, FALSE); - if (lo_unlink(pgLO->conn, loa.lo_oid) < 0) - fprintf(stderr, "%s: can't remove LO %u:\n%s", - progname, loa.lo_oid, PQerrorMessage(pgLO->conn)); - - else if (!pgLO->quiet) - printf("remove old %u and create new %u\n", - loa.lo_oid, new_oid); - notice(pgLO, TRUE); - } - - pgLO->counter++; - - /* - * UPDATE oid in tab - */ - sprintf(Qbuff, "UPDATE \"%s\" SET \"%s\"=%u WHERE \"%s\"=%u", - loa.lo_table, loa.lo_attr, new_oid, loa.lo_attr, loa.lo_oid); - - /* fprintf(stderr, Qbuff); */ - - pgLO->res = PQexec(pgLO->conn, Qbuff); - - if (PQresultStatus(pgLO->res) != PGRES_COMMAND_OK) - { - fprintf(stderr, "%s: %s\n", progname, PQerrorMessage(pgLO->conn)); - PQclear(pgLO->res); - PQexec(pgLO->conn, "ROLLBACK"); - fprintf(stderr, "\n%s: ROLLBACK\n", progname); - exit(RE_ERROR); - } - PQclear(pgLO->res); - } -} diff --git a/contrib/pg_dumplo/main.c b/contrib/pg_dumplo/main.c deleted file mode 100644 index 78456e1234..0000000000 --- a/contrib/pg_dumplo/main.c +++ /dev/null @@ -1,326 +0,0 @@ -/* ------------------------------------------------------------------------- - * pg_dumplo - * - * $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/main.c,v 1.10 2001/11/12 17:44:14 momjian Exp $ - * - * Karel Zak 1999-2000 - * ------------------------------------------------------------------------- - */ - -/* We import postgres_fe.h mostly to get the HAVE_GETOPT_LONG configure result. */ -#ifndef OUT_OF_PG -#include "postgres_fe.h" -#endif - -#include -#include -#include -#include -#include - -#include -#include - -#include "pg_dumplo.h" - -#ifdef HAVE_GETOPT_LONG -#include -#define no_argument 0 -#define required_argument 1 -#endif - -extern int errno; - -char *progname = NULL; - -int main(int argc, char **argv); -static void usage(void); -static void parse_lolist(LODumpMaster * pgLO); - - -/*----- - * The mother of all C functions - *----- - */ -int -main(int argc, char **argv) -{ - LODumpMaster _pgLO, - *pgLO = &_pgLO; - char *pwd = NULL; - - pgLO->argv = argv; - pgLO->argc = argc; - pgLO->action = 0; - pgLO->lolist = NULL; - pgLO->user = NULL; - pgLO->db = NULL; - pgLO->host = NULL; - pgLO->port = NULL; - pgLO->space = NULL; - pgLO->index = NULL; - pgLO->remove = FALSE; - pgLO->quiet = FALSE; - pgLO->counter = 0; - pgLO->lolist_start = 0; - - progname = argv[0]; - - /* - * Parse ARGV - */ - if (argc > 1) - { - int arg; - extern int optind; - -#ifdef HAVE_GETOPT_LONG - int l_index = 0; - static struct option l_opt[] = { - {"help", no_argument, 0, 'h'}, - {"user", required_argument, 0, 'u'}, - {"pwd", required_argument, 0, 'p'}, - {"db", required_argument, 0, 'd'}, - {"host", required_argument, 0, 'h'}, - {"port", required_argument, 0, 'o'}, - {"space", required_argument, 0, 's'}, - {"import", no_argument, 0, 'i'}, - {"export", no_argument, 0, 'e'}, - {"remove", no_argument, 0, 'r'}, - {"quiet", no_argument, 0, 'q'}, - {"all", no_argument, 0, 'a'}, - {"show", no_argument, 0, 'w'}, - {NULL, 0, 0, 0} - }; - - while ((arg = getopt_long(argc, argv, "?aeho:u:p:qd:l:t:irs:w", l_opt, &l_index)) != -1) - { -#else - while ((arg = getopt(argc, argv, "?aeho:u:p:qd:l:t:irs:w")) != -1) - { -#endif - switch (arg) - { - case '?': - case 'h': - usage(); - exit(RE_OK); - case 'u': - pgLO->user = strdup(optarg); - break; - case 't': - pgLO->host = strdup(optarg); - break; - case 'o': - pgLO->port = strdup(optarg); - break; - case 'p': - pwd = strdup(optarg); - break; - case 'd': - pgLO->db = strdup(optarg); - break; - case 's': - pgLO->space = strdup(optarg); - break; - case 'i': - pgLO->action = ACTION_IMPORT; - break; - case 'l': - pgLO->action = ACTION_EXPORT_ATTR; - pgLO->lolist_start = optind - 1; - parse_lolist(pgLO); - break; - case 'e': - case 'a': - pgLO->action = ACTION_EXPORT_ALL; - break; - case 'w': - pgLO->action = ACTION_SHOW; - break; - case 'r': - pgLO->remove = TRUE; - break; - case 'q': - pgLO->quiet = TRUE; - break; - default: - fprintf(stderr, "%s: bad arg -%c\n", progname, arg); - usage(); - exit(RE_ERROR); - } - } - } - else - { - usage(); - exit(RE_ERROR); - } - - /* - * Check space - */ - if (!pgLO->space && !pgLO->action == ACTION_SHOW) - { - if (!(pgLO->space = getenv("PWD"))) - { - fprintf(stderr, "%s: not set space for dump-tree (option '-s' or $PWD).\n", progname); - exit(RE_ERROR); - } - } - - if (!pgLO->action) - { - fprintf(stderr, "%s: What do you want - export or import?\n", progname); - exit(RE_ERROR); - } - - /* - * Make connection - */ - pgLO->conn = PQsetdbLogin(pgLO->host, pgLO->port, NULL, NULL, pgLO->db, - pgLO->user, pwd); - - if (PQstatus(pgLO->conn) == CONNECTION_BAD) - { - fprintf(stderr, "%s (connection): %s\n", progname, PQerrorMessage(pgLO->conn)); - exit(RE_ERROR); - } - pgLO->host = PQhost(pgLO->conn) ? PQhost(pgLO->conn) : "localhost"; - pgLO->db = PQdb(pgLO->conn); - pgLO->user = PQuser(pgLO->conn); - - - /* - * Init index file - */ - if (pgLO->action != ACTION_SHOW) - index_file(pgLO); - - PQexec(pgLO->conn, "BEGIN"); - - switch (pgLO->action) - { - - case ACTION_SHOW: - case ACTION_EXPORT_ALL: - load_lolist(pgLO); - /* FALL THROUGH */ - - case ACTION_EXPORT_ATTR: - pglo_export(pgLO); - if (!pgLO->quiet) - { - if (pgLO->action == ACTION_SHOW) - printf("\nDatabase '%s' contains %d large objects.\n\n", pgLO->db, pgLO->counter); - else - printf("\nExported %d large objects.\n\n", pgLO->counter); - } - break; - - case ACTION_IMPORT: - pglo_import(pgLO); - if (!pgLO->quiet) - printf("\nImported %d large objects.\n\n", pgLO->counter); - break; - } - - PQexec(pgLO->conn, "COMMIT"); - PQfinish(pgLO->conn); - - if (pgLO->action != ACTION_SHOW) - fclose(pgLO->index); - - exit(RE_OK); -} - -static void -parse_lolist(LODumpMaster * pgLO) -{ - LOlist *ll; - char **d, - *loc, - buff[MAX_TABLE_NAME + MAX_ATTR_NAME + 1]; - - pgLO->lolist = (LOlist *) malloc(pgLO->argc * sizeof(LOlist)); - - if (!pgLO->lolist) - { - fprintf(stderr, "%s: can't allocate memory\n", progname); - exit(RE_ERROR); - } - - for (d = pgLO->argv + pgLO->lolist_start, ll = pgLO->lolist; - *d != NULL; - d++, ll++) - { - - strncpy(buff, *d, MAX_TABLE_NAME + MAX_ATTR_NAME); - - if ((loc = strchr(buff, '.')) == NULL) - { - fprintf(stderr, "%s: '%s' is bad 'table.attr'\n", progname, buff); - exit(RE_ERROR); - } - *loc = '\0'; - ll->lo_table = strdup(buff); - ll->lo_attr = strdup(++loc); - } - ll++; - ll->lo_table = ll->lo_attr = (char *) NULL; -} - - -static void -usage() -{ - printf("\npg_dumplo %s - PostgreSQL large objects dump\n", VERSION); - puts("pg_dumplo [option]\n\n" - -#ifdef HAVE_GETOPT_LONG - - "-h --help this help\n" - "-u --user= username for connection to server\n" - "-p --password= password for connection to server\n" - "-d --db= database name\n" - "-t --host= server hostname\n" - "-o --port= database server port (default: 5432)\n" - "-s --space= directory with dump tree (for export/import)\n" - "-i --import import large obj dump tree to DB\n" - "-e --export export (dump) large obj to dump tree\n" - "-l dump attribute (columns) with LO to dump tree\n" - "-a --all dump all LO in DB (default)\n" - "-r --remove if is set '-i' try remove old LO\n" - "-q --quiet run quietly\n" - "-w --show not dump, but show all LO in DB\n" - ); /* puts() */ - -#else - "-h this help\n" - "-u username for connection to server\n" - "-p password for connection to server\n" - "-d database name\n" - "-t server hostname\n" - "-o database server port (default: 5432)\n" - "-s directory with dump tree (for export/import)\n" - "-i import large obj dump tree to DB\n" - "-e export (dump) large obj to dump tree\n" - "-l dump attribute (columns) with LO to dump tree\n" - "-a dump all LO in DB (default)\n" - "-r if is set '-i' try remove old LO\n" - "-q run quietly\n" - "-w not dump, but show all LO in DB\n" - ); /* puts() */ -#endif - - puts( - "Example (dump): pg_dumplo -d my_db -s /my_dump/dir -l t1.a t1.b t2.a\n" - " pg_dumplo -a -d my_db -s /my_dump/dir\n" - "Example (import): pg_dumplo -i -d my_db -s /my_dump/dir\n" - "Example (show): pg_dumplo -w -d my_db\n\n" - "Note: * option '-l' must be last option!\n" - " * option '-i' without option '-r' make new large obj in DB\n" - " not rewrite old, the '-i' UPDATE oid numbers in table.attr only!\n" - " * if is not set option -s, the pg_dumplo use $PWD\n" - ); /* puts() */ -} diff --git a/contrib/pg_dumplo/pg_dumplo.h b/contrib/pg_dumplo/pg_dumplo.h deleted file mode 100644 index 68a5e86061..0000000000 --- a/contrib/pg_dumplo/pg_dumplo.h +++ /dev/null @@ -1,83 +0,0 @@ -/* ------------------------------------------------------------------------- - * pg_dumplo - * - * $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/pg_dumplo.h,v 1.8 2001/11/12 17:44:14 momjian Exp $ - * - * Karel Zak 1999-2000 - * ------------------------------------------------------------------------- - */ - -#ifndef PG_DUMPLO_H -#define PG_DUMPLO_H - -#include "postgres_ext.h" - -#define VERSION "7.1.0" - -/* ---------- - * Define - * ---------- - */ -#define QUERY_BUFSIZ (8*1024) -#define DIR_UMASK 0755 -#define FILE_UMASK 0644 - -#define TRUE 1 -#define FALSE 0 -#define RE_OK 0 -#define RE_ERROR 1 - -#define MAX_TABLE_NAME 128 -#define MAX_ATTR_NAME 128 - -#define atooid(x) ((Oid) strtoul((x), NULL, 10)) - -/* ---------- - * LO struct - * ---------- - */ -typedef struct -{ - char *lo_table, - *lo_attr; - Oid lo_oid; -} LOlist; - -typedef struct -{ - int action; - LOlist *lolist; - char **argv, - *user, - *db, - *host, - *port, - *space; - FILE *index; - int counter, - argc, - lolist_start, - remove, - quiet; - PGresult *res; - PGconn *conn; -} LODumpMaster; - -typedef enum -{ - ACTION_NONE, - ACTION_SHOW, - ACTION_EXPORT_ATTR, - ACTION_EXPORT_ALL, - ACTION_IMPORT -} PGLODUMP_ACTIONS; - -extern char *progname; - -extern void notice(LODumpMaster * pgLO, int set); -extern void index_file(LODumpMaster * pgLO); -extern void load_lolist(LODumpMaster * pgLO); -extern void pglo_export(LODumpMaster * pgLO); -extern void pglo_import(LODumpMaster * pgLO); - -#endif /* PG_DUMPLO_H */ diff --git a/contrib/pg_dumplo/utils.c b/contrib/pg_dumplo/utils.c deleted file mode 100644 index d36ee4be08..0000000000 --- a/contrib/pg_dumplo/utils.c +++ /dev/null @@ -1,97 +0,0 @@ -/* ------------------------------------------------------------------------- - * pg_dumplo - * - * $Header: /cvsroot/pgsql/contrib/pg_dumplo/Attic/utils.c,v 1.4 2001/03/22 03:59:10 momjian Exp $ - * - * Karel Zak 1999-2000 - * ------------------------------------------------------------------------- - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "pg_dumplo.h" - -extern int errno; - -static void Dummy_NoticeProcessor(void *arg, const char *message); -static void Default_NoticeProcessor(void *arg, const char *message); - - -void -index_file(LODumpMaster * pgLO) -{ - char path[BUFSIZ]; - - if (pgLO->action == ACTION_SHOW) - return; - - sprintf(path, "%s/%s", pgLO->space, pgLO->db); - - if (pgLO->action == ACTION_EXPORT_ATTR || - pgLO->action == ACTION_EXPORT_ALL) - { - - if (mkdir(path, DIR_UMASK) == -1) - { - if (errno != EEXIST) - { - perror(path); - exit(RE_ERROR); - } - } - - sprintf(path, "%s/lo_dump.index", path); - - if ((pgLO->index = fopen(path, "w")) == NULL) - { - perror(path); - exit(RE_ERROR); - } - - } - else if (pgLO->action != ACTION_NONE) - { - - sprintf(path, "%s/lo_dump.index", path); - - if ((pgLO->index = fopen(path, "r")) == NULL) - { - perror(path); - exit(RE_ERROR); - } - } -} - -static -void -Dummy_NoticeProcessor(void *arg, const char *message) -{ - ; -} - -static -void -Default_NoticeProcessor(void *arg, const char *message) -{ - fprintf(stderr, "%s", message); -} - -void -notice(LODumpMaster * pgLO, int set) -{ - if (set) - PQsetNoticeProcessor(pgLO->conn, Default_NoticeProcessor, NULL); - else - PQsetNoticeProcessor(pgLO->conn, Dummy_NoticeProcessor, NULL); -} diff --git a/contrib/pg_logger/Makefile b/contrib/pg_logger/Makefile deleted file mode 100644 index 1a622bfe2a..0000000000 --- a/contrib/pg_logger/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/pg_logger/Attic/Makefile,v 1.2 2001/09/06 10:49:30 petere Exp $ - -subdir = contrib/pg_logger -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -PROGRAM = pg_logger -OBJS = pg_logger.o - -DOCS = README.pg_logger - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/pg_logger/README.pg_logger b/contrib/pg_logger/README.pg_logger deleted file mode 100644 index aaad73f508..0000000000 --- a/contrib/pg_logger/README.pg_logger +++ /dev/null @@ -1 +0,0 @@ -Stdin-to-syslog gateway for PostgreSQL diff --git a/contrib/pg_logger/pg_logger.c b/contrib/pg_logger/pg_logger.c deleted file mode 100644 index cb28bf5e7a..0000000000 --- a/contrib/pg_logger/pg_logger.c +++ /dev/null @@ -1,106 +0,0 @@ -/* pg_logger: stdin-to-syslog gateway for postgresql. - * - * Copyright 2001 by Nathan Myers - * This software is distributed free of charge with no warranty of any kind. - * You have permission to make copies for any purpose, provided that (1) - * this copyright notice is retained unchanged, and (2) you agree to - * absolve the author of all responsibility for all consequences arising - * from any use. - */ - -#include -#include -#include -#include - -struct -{ - const char *tag; - int size; - int priority; -} tags[] = - -{ - { - "", 0, LOG_NOTICE - }, - { - "emerg:", sizeof("emerg"), LOG_EMERG - }, - { - "alert:", sizeof("alert"), LOG_ALERT - }, - { - "crit:", sizeof("crit"), LOG_CRIT - }, - { - "err:", sizeof("err"), LOG_ERR - }, - { - "error:", sizeof("error"), LOG_ERR - }, - { - "warning:", sizeof("warning"), LOG_WARNING - }, - { - "notice:", sizeof("notice"), LOG_NOTICE - }, - { - "info:", sizeof("info"), LOG_INFO - }, - { - "debug:", sizeof("debug"), LOG_DEBUG - } -}; - -int -main() -{ - char buf[301]; - int c; - char *pos = buf; - const char *colon = 0; - -#ifndef DEBUG - openlog("postgresql", LOG_CONS, LOG_LOCAL1); -#endif - while ((c = getchar()) != EOF) - { - if (c == '\r') - continue; - if (c == '\n') - { - int level = sizeof(tags) / sizeof(*tags); - char *bol; - - if (colon == 0 || (size_t) (colon - buf) > sizeof("warning")) - level = 1; - *pos = 0; - while (--level) - { - if (pos - buf >= tags[level].size - && strncmp(buf, tags[level].tag, tags[level].size) == 0) - break; - } - bol = buf + tags[level].size; - if (bol > buf && *bol == ' ') - ++bol; - if (pos - bol > 0) - { -#ifndef DEBUG - syslog(tags[level].priority, "%s", bol); -#else - printf("%d/%s\n", tags[level].priority, bol); -#endif - } - pos = buf; - colon = (char const *) 0; - continue; - } - if (c == ':' && !colon) - colon = pos; - if ((size_t) (pos - buf) < sizeof(buf) - 1) - *pos++ = c; - } - return 0; -} diff --git a/contrib/pg_resetxlog/Makefile b/contrib/pg_resetxlog/Makefile deleted file mode 100644 index eee05b1eda..0000000000 --- a/contrib/pg_resetxlog/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/pg_resetxlog/Attic/Makefile,v 1.3 2001/09/06 10:49:30 petere Exp $ - -subdir = contrib/pg_resetxlog -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -PROGRAM = pg_resetxlog -OBJS = pg_resetxlog.o pg_crc.o $(SNPRINTF) - -pg_crc.c: $(top_srcdir)/src/backend/utils/hash/pg_crc.c - rm -f $@ && $(LN_S) $< . - -# this only gets done if configure finds system doesn't have snprintf() -snprintf.c: $(top_srcdir)/src/backend/port/snprintf.c - rm -f $@ && $(LN_S) $< . - -EXTRA_CLEAN = pg_crc.c snprintf.c - -DOCS = README.pg_resetxlog - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/pg_resetxlog/README.pg_resetxlog b/contrib/pg_resetxlog/README.pg_resetxlog deleted file mode 100644 index 9802cdddd3..0000000000 --- a/contrib/pg_resetxlog/README.pg_resetxlog +++ /dev/null @@ -1,42 +0,0 @@ -pg_resetxlog is a program to clear the WAL transaction log (stored in -$PGDATA/pg_xlog/), replacing whatever had been in it with just a dummy -shutdown-checkpoint record. It also regenerates the pg_control file -if necessary. - -THIS PROGRAM WILL DESTROY VALUABLE LOG DATA!!! Don't run it unless you -really need it!!! - -pg_resetxlog is primarily intended for disaster recovery --- that is, -if your pg_control and/or xlog are hosed badly enough that Postgres refuses -to start up, this program will get you past that problem and let you get to -your data files. But realize that without the xlog, your data files may be -corrupt due to partially-applied transactions, incomplete index-file -updates, etc. You should dump your data, check it for accuracy, then initdb -and reload. - -A secondary purpose is to cope with xlog format changes without requiring -initdb. To use pg_resetxlog for this purpose, just be sure that you have -cleanly shut down your old postmaster (if you're not sure, see the contrib -module pg_controldata and run it to be sure the DB state is SHUTDOWN). -Then run pg_resetxlog, and finally install and start the new version of -the database software. - -A tertiary purpose is its use by pg_upgrade to set the next transaction -id and checkpoint location in pg_control. - -To run the program, make sure your postmaster is not running, then -(as the Postgres admin user) do - - pg_resetxlog $PGDATA - -As a safety measure, the target data directory must be specified on the -command line, it cannot be defaulted. - -If pg_resetxlog complains that it can't reconstruct valid data for pg_control, -you can force it to invent plausible data values with - - pg_resetxlog -f $PGDATA - -If this turns out to be necessary then you *definitely* should plan on -immediate dump, initdb, reload --- any modifications you do to the database -after "pg_resetxlog -f" would be likely to corrupt things even worse. diff --git a/contrib/pg_resetxlog/pg_resetxlog.c b/contrib/pg_resetxlog/pg_resetxlog.c deleted file mode 100644 index cf1782d42e..0000000000 --- a/contrib/pg_resetxlog/pg_resetxlog.c +++ /dev/null @@ -1,611 +0,0 @@ -/*------------------------------------------------------------------------- - * - * pg_resetxlog.c - * A utility to "zero out" the xlog when it's corrupt beyond recovery. - * Can also rebuild pg_control if needed. - * - * The theory of operation is fairly simple: - * 1. Read the existing pg_control (which will include the last - * checkpoint record). If it is an old format then update to - * current format. - * 2. If pg_control is corrupt, attempt to intuit reasonable values, - * by scanning the old xlog if necessary. - * 3. Modify pg_control to reflect a "shutdown" state with a checkpoint - * record at the start of xlog. - * 4. Flush the existing xlog files and write a new segment with - * just a checkpoint record in it. The new segment is positioned - * just past the end of the old xlog, so that existing LSNs in - * data pages will appear to be "in the past". - * This is all pretty straightforward except for the intuition part of - * step 2 ... - * - * - * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * $Header: /cvsroot/pgsql/contrib/pg_resetxlog/Attic/pg_resetxlog.c,v 1.18 2002/06/20 20:29:24 momjian Exp $ - * - *------------------------------------------------------------------------- - */ -#include "postgres.h" - -#include -#include -#include -#include -#include -#include -#include -#ifdef USE_LOCALE -#include -#endif - -#include "access/xlog.h" -#include "catalog/catversion.h" -#include "catalog/pg_control.h" - - -/******************** stuff copied from xlog.c ********************/ - -/* Increment an xlogid/segment pair */ -#define NextLogSeg(logId, logSeg) \ - do { \ - if ((logSeg) >= XLogSegsPerFile-1) \ - { \ - (logId)++; \ - (logSeg) = 0; \ - } \ - else \ - (logSeg)++; \ - } while (0) - -#define XLogFileName(path, log, seg) \ - snprintf(path, MAXPGPATH, "%s/%08X%08X", \ - XLogDir, log, seg) - -/******************** end of stuff copied from xlog.c ********************/ - - -static char *DataDir; /* locations of important stuff */ -static char XLogDir[MAXPGPATH]; -static char ControlFilePath[MAXPGPATH]; - -static ControlFileData ControlFile; /* pg_control values */ -static uint32 newXlogId, - newXlogSeg; /* ID/Segment of new XLOG segment */ -static bool guessed = false; /* T if we had to guess at any values */ - - -/* - * Try to read the existing pg_control file. - * - * This routine is also responsible for updating old pg_control versions - * to the current format. - */ -static bool -ReadControlFile(void) -{ - int fd; - int len; - char *buffer; - crc64 crc; - - if ((fd = open(ControlFilePath, O_RDONLY)) < 0) - { - /* - * If pg_control is not there at all, or we can't read it, the - * odds are we've been handed a bad DataDir path, so give up. User - * can do "touch pg_control" to force us to proceed. - */ - perror("Failed to open $PGDATA/global/pg_control for reading"); - if (errno == ENOENT) - fprintf(stderr, "If you're sure the PGDATA path is correct, do\n" - " touch %s\n" - "and try again.\n", ControlFilePath); - exit(1); - } - - /* Use malloc to ensure we have a maxaligned buffer */ - buffer = (char *) malloc(BLCKSZ); - - len = read(fd, buffer, BLCKSZ); - if (len < 0) - { - perror("Failed to read $PGDATA/global/pg_control"); - exit(1); - } - close(fd); - - if (len >= sizeof(ControlFileData) && - ((ControlFileData *) buffer)->pg_control_version == PG_CONTROL_VERSION) - { - /* Check the CRC. */ - INIT_CRC64(crc); - COMP_CRC64(crc, - buffer + sizeof(crc64), - sizeof(ControlFileData) - sizeof(crc64)); - FIN_CRC64(crc); - - if (EQ_CRC64(crc, ((ControlFileData *) buffer)->crc)) - { - /* Valid data... */ - memcpy(&ControlFile, buffer, sizeof(ControlFile)); - return true; - } - - fprintf(stderr, "pg_control exists but has invalid CRC; proceed with caution.\n"); - /* We will use the data anyway, but treat it as guessed. */ - memcpy(&ControlFile, buffer, sizeof(ControlFile)); - guessed = true; - return true; - } - - /* Looks like it's a mess. */ - fprintf(stderr, "pg_control exists but is broken or unknown version; ignoring it.\n"); - return false; -} - - -/* - * Guess at pg_control values when we can't read the old ones. - */ -static void -GuessControlValues(void) -{ -#ifdef USE_LOCALE - char *localeptr; -#endif - - /* - * Set up a completely default set of pg_control values. - */ - guessed = true; - memset(&ControlFile, 0, sizeof(ControlFile)); - - ControlFile.pg_control_version = PG_CONTROL_VERSION; - ControlFile.catalog_version_no = CATALOG_VERSION_NO; - - ControlFile.checkPointCopy.redo.xlogid = 0; - ControlFile.checkPointCopy.redo.xrecoff = SizeOfXLogPHD; - ControlFile.checkPointCopy.undo = ControlFile.checkPointCopy.redo; - ControlFile.checkPointCopy.ThisStartUpID = 0; - ControlFile.checkPointCopy.nextXid = (TransactionId) 514; /* XXX */ - ControlFile.checkPointCopy.nextOid = BootstrapObjectIdData; - ControlFile.checkPointCopy.time = time(NULL); - - ControlFile.state = DB_SHUTDOWNED; - ControlFile.time = time(NULL); - ControlFile.logId = 0; - ControlFile.logSeg = 1; - ControlFile.checkPoint = ControlFile.checkPointCopy.redo; - - ControlFile.blcksz = BLCKSZ; - ControlFile.relseg_size = RELSEG_SIZE; -#ifdef USE_LOCALE - localeptr = setlocale(LC_COLLATE, ""); - if (!localeptr) - { - fprintf(stderr, "Invalid LC_COLLATE setting\n"); - exit(1); - } - StrNCpy(ControlFile.lc_collate, localeptr, LOCALE_NAME_BUFLEN); - localeptr = setlocale(LC_CTYPE, ""); - if (!localeptr) - { - fprintf(stderr, "Invalid LC_CTYPE setting\n"); - exit(1); - } - StrNCpy(ControlFile.lc_ctype, localeptr, LOCALE_NAME_BUFLEN); -#else - strcpy(ControlFile.lc_collate, "C"); - strcpy(ControlFile.lc_ctype, "C"); -#endif - - /* - * XXX eventually, should try to grovel through old XLOG to develop - * more accurate values for startupid, nextXID, and nextOID. - */ -} - - -/* - * Print the guessed pg_control values when we had to guess. - * - * NB: this display should be just those fields that will not be - * reset by RewriteControlFile(). - */ -static void -PrintControlValues(bool guessed) -{ - printf("%spg_control values:\n\n" - "pg_control version number: %u\n" - "Catalog version number: %u\n" - "Current log file id: %u\n" - "Next log file segment: %u\n" - "Latest checkpoint's StartUpID: %u\n" - "Latest checkpoint's NextXID: %u\n" - "Latest checkpoint's NextOID: %u\n" - "Database block size: %u\n" - "Blocks per segment of large relation: %u\n" - "LC_COLLATE: %s\n" - "LC_CTYPE: %s\n", - - (guessed ? "Guessed-at " : ""), - ControlFile.pg_control_version, - ControlFile.catalog_version_no, - ControlFile.logId, - ControlFile.logSeg, - ControlFile.checkPointCopy.ThisStartUpID, - ControlFile.checkPointCopy.nextXid, - ControlFile.checkPointCopy.nextOid, - ControlFile.blcksz, - ControlFile.relseg_size, - ControlFile.lc_collate, - ControlFile.lc_ctype); -} - - -/* - * Write out the new pg_control file. - */ -static void -RewriteControlFile(void) -{ - int fd; - char buffer[BLCKSZ]; /* need not be aligned */ - - /* - * Adjust fields as needed to force an empty XLOG starting at the next - * available segment. - */ - newXlogId = ControlFile.logId; - newXlogSeg = ControlFile.logSeg; - /* be sure we wrap around correctly at end of a logfile */ - NextLogSeg(newXlogId, newXlogSeg); - - ControlFile.checkPointCopy.redo.xlogid = newXlogId; - ControlFile.checkPointCopy.redo.xrecoff = - newXlogSeg * XLogSegSize + SizeOfXLogPHD; - ControlFile.checkPointCopy.undo = ControlFile.checkPointCopy.redo; - ControlFile.checkPointCopy.time = time(NULL); - - ControlFile.state = DB_SHUTDOWNED; - ControlFile.time = time(NULL); - ControlFile.logId = newXlogId; - ControlFile.logSeg = newXlogSeg + 1; - ControlFile.checkPoint = ControlFile.checkPointCopy.redo; - ControlFile.prevCheckPoint.xlogid = 0; - ControlFile.prevCheckPoint.xrecoff = 0; - - /* Contents are protected with a CRC */ - INIT_CRC64(ControlFile.crc); - COMP_CRC64(ControlFile.crc, - (char *) &ControlFile + sizeof(crc64), - sizeof(ControlFileData) - sizeof(crc64)); - FIN_CRC64(ControlFile.crc); - - /* - * We write out BLCKSZ bytes into pg_control, zero-padding the excess - * over sizeof(ControlFileData). This reduces the odds of - * premature-EOF errors when reading pg_control. We'll still fail - * when we check the contents of the file, but hopefully with a more - * specific error than "couldn't read pg_control". - */ - if (sizeof(ControlFileData) > BLCKSZ) - { - fprintf(stderr, "sizeof(ControlFileData) is too large ... fix xlog.c\n"); - exit(1); - } - - memset(buffer, 0, BLCKSZ); - memcpy(buffer, &ControlFile, sizeof(ControlFileData)); - - unlink(ControlFilePath); - - fd = open(ControlFilePath, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, S_IRUSR | S_IWUSR); - if (fd < 0) - { - perror("RewriteControlFile failed to create pg_control file"); - exit(1); - } - - errno = 0; - if (write(fd, buffer, BLCKSZ) != BLCKSZ) - { - /* if write didn't set errno, assume problem is no disk space */ - if (errno == 0) - errno = ENOSPC; - perror("RewriteControlFile failed to write pg_control file"); - exit(1); - } - - if (fsync(fd) != 0) - { - perror("fsync"); - exit(1); - } - - close(fd); -} - - -/* - * Remove existing XLOG files - */ -static void -KillExistingXLOG(void) -{ - DIR *xldir; - struct dirent *xlde; - char path[MAXPGPATH]; - - xldir = opendir(XLogDir); - if (xldir == NULL) - { - perror("KillExistingXLOG: cannot open $PGDATA/pg_xlog directory"); - exit(1); - } - - errno = 0; - while ((xlde = readdir(xldir)) != NULL) - { - if (strlen(xlde->d_name) == 16 && - strspn(xlde->d_name, "0123456789ABCDEF") == 16) - { - sprintf(path, "%s/%s", XLogDir, xlde->d_name); - if (unlink(path) < 0) - { - perror(path); - exit(1); - } - } - errno = 0; - } - if (errno) - { - perror("KillExistingXLOG: cannot read $PGDATA/pg_xlog directory"); - exit(1); - } - closedir(xldir); -} - - -/* - * Write an empty XLOG file, containing only the checkpoint record - * already set up in ControlFile. - */ -static void -WriteEmptyXLOG(void) -{ - char *buffer; - XLogPageHeader page; - XLogRecord *record; - crc64 crc; - char path[MAXPGPATH]; - int fd; - int nbytes; - - /* Use malloc() to ensure buffer is MAXALIGNED */ - buffer = (char *) malloc(BLCKSZ); - page = (XLogPageHeader) buffer; - - /* Set up the first page with initial record */ - memset(buffer, 0, BLCKSZ); - page->xlp_magic = XLOG_PAGE_MAGIC; - page->xlp_info = 0; - page->xlp_sui = ControlFile.checkPointCopy.ThisStartUpID; - page->xlp_pageaddr.xlogid = - ControlFile.checkPointCopy.redo.xlogid; - page->xlp_pageaddr.xrecoff = - ControlFile.checkPointCopy.redo.xrecoff - SizeOfXLogPHD; - record = (XLogRecord *) ((char *) page + SizeOfXLogPHD); - record->xl_prev.xlogid = 0; - record->xl_prev.xrecoff = 0; - record->xl_xact_prev = record->xl_prev; - record->xl_xid = InvalidTransactionId; - record->xl_len = sizeof(CheckPoint); - record->xl_info = XLOG_CHECKPOINT_SHUTDOWN; - record->xl_rmid = RM_XLOG_ID; - memcpy(XLogRecGetData(record), &ControlFile.checkPointCopy, - sizeof(CheckPoint)); - - INIT_CRC64(crc); - COMP_CRC64(crc, &ControlFile.checkPointCopy, sizeof(CheckPoint)); - COMP_CRC64(crc, (char *) record + sizeof(crc64), - SizeOfXLogRecord - sizeof(crc64)); - FIN_CRC64(crc); - record->xl_crc = crc; - - /* Write the first page */ - XLogFileName(path, newXlogId, newXlogSeg); - - unlink(path); - - fd = open(path, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, - S_IRUSR | S_IWUSR); - if (fd < 0) - { - perror(path); - exit(1); - } - - errno = 0; - if (write(fd, buffer, BLCKSZ) != BLCKSZ) - { - /* if write didn't set errno, assume problem is no disk space */ - if (errno == 0) - errno = ENOSPC; - perror("WriteEmptyXLOG: failed to write xlog file"); - exit(1); - } - - /* Fill the rest of the file with zeroes */ - memset(buffer, 0, BLCKSZ); - for (nbytes = BLCKSZ; nbytes < XLogSegSize; nbytes += BLCKSZ) - { - errno = 0; - if (write(fd, buffer, BLCKSZ) != BLCKSZ) - { - if (errno == 0) - errno = ENOSPC; - perror("WriteEmptyXLOG: failed to write xlog file"); - exit(1); - } - } - - if (fsync(fd) != 0) - { - perror("fsync"); - exit(1); - } - - close(fd); -} - - -static void -usage(void) -{ - fprintf(stderr, "Usage: pg_resetxlog [-f] [-n] [-x xid] [ -l fileid seg ] PGDataDirectory\n" - " -f\t\tforce update to be done\n" - " -n\t\tno update, just show extracted pg_control values (for testing)\n" - " -x xid\tset next transaction ID\n" - " -l fileid seg\tforce minimum WAL starting location for new xlog\n"); - exit(1); -} - - -int -main(int argc, char **argv) -{ - int argn; - bool force = false; - bool noupdate = false; - TransactionId set_xid = 0; - uint32 minXlogId = 0, - minXlogSeg = 0; - int fd; - char path[MAXPGPATH]; - - for (argn = 1; argn < argc; argn++) - { - if (argv[argn][0] != '-') - break; /* end of switches */ - if (strcmp(argv[argn], "-f") == 0) - force = true; - else if (strcmp(argv[argn], "-n") == 0) - noupdate = true; - else if (strcmp(argv[argn], "-x") == 0) - { - argn++; - if (argn == argc) - usage(); - set_xid = strtoul(argv[argn], NULL, 0); - if (set_xid == 0) - { - fprintf(stderr, "XID can not be 0.\n"); - exit(1); - } - } - else if (strcmp(argv[argn], "-l") == 0) - { - argn++; - if (argn == argc) - usage(); - minXlogId = strtoul(argv[argn], NULL, 0); - argn++; - if (argn == argc) - usage(); - minXlogSeg = strtoul(argv[argn], NULL, 0); - } - else - usage(); - } - - if (argn != argc - 1) /* one required non-switch argument */ - usage(); - - DataDir = argv[argn++]; - - snprintf(XLogDir, MAXPGPATH, "%s/pg_xlog", DataDir); - - snprintf(ControlFilePath, MAXPGPATH, "%s/global/pg_control", DataDir); - - /* - * Check for a postmaster lock file --- if there is one, refuse to - * proceed, on grounds we might be interfering with a live - * installation. - */ - snprintf(path, MAXPGPATH, "%s/postmaster.pid", DataDir); - - if ((fd = open(path, O_RDONLY)) < 0) - { - if (errno != ENOENT) - { - perror("Failed to open $PGDATA/postmaster.pid for reading"); - exit(1); - } - } - else - { - fprintf(stderr, "Lock file '%s' exists --- is a postmaster running?\n" - "If not, delete the lock file and try again.\n", - path); - exit(1); - } - - /* - * Attempt to read the existing pg_control file - */ - if (!ReadControlFile()) - GuessControlValues(); - - /* - * If we had to guess anything, and -f was not given, just print the - * guessed values and exit. Also print if -n is given. - */ - if ((guessed && !force) || noupdate) - { - PrintControlValues(guessed); - if (!noupdate) - { - printf("\nIf these values seem acceptable, use -f to force reset.\n"); - exit(1); - } - else - exit(0); - } - - /* - * Don't reset from a dirty pg_control without -f, either. - */ - if (ControlFile.state != DB_SHUTDOWNED && !force) - { - printf("The database was not shut down cleanly.\n" - "Resetting the xlog may cause data to be lost!\n" - "If you want to proceed anyway, use -f to force reset.\n"); - exit(1); - } - - /* - * Else, do the dirty deed. - * - * First adjust fields if required by switches. - */ - if (set_xid != 0) - ControlFile.checkPointCopy.nextXid = set_xid; - - if (minXlogId > ControlFile.logId || - (minXlogId == ControlFile.logId && minXlogSeg > ControlFile.logSeg)) - { - ControlFile.logId = minXlogId; - ControlFile.logSeg = minXlogSeg; - } - - RewriteControlFile(); - KillExistingXLOG(); - WriteEmptyXLOG(); - - printf("XLOG reset.\n"); - return 0; -} diff --git a/contrib/pg_upgrade/README b/contrib/pg_upgrade/README deleted file mode 100644 index d2f25bd56c..0000000000 --- a/contrib/pg_upgrade/README +++ /dev/null @@ -1,14 +0,0 @@ - pg_upgrade - -This is a version of pg_upgrade which will migrate a 7.1 database to -7.2, or allow a 7.2 to 7.2 migration if you need to perform an initdb. -It has been only lightly tested. Please report any problems to the -PostgreSQL lists. - -Read the manual page for more information. To view it: - - nroff -man pg_upgrade.1 | more - -Bruce Momjian - -2002-01-14 diff --git a/contrib/pg_upgrade/pg_upgrade b/contrib/pg_upgrade/pg_upgrade deleted file mode 100755 index ad1b3745c3..0000000000 --- a/contrib/pg_upgrade/pg_upgrade +++ /dev/null @@ -1,492 +0,0 @@ -#!/bin/sh -# -# pg_upgrade: update a database without needing a full dump/reload cycle. -# CAUTION: Read the manual page before trying to use this! - -# $Header: /cvsroot/pgsql/contrib/pg_upgrade/Attic/pg_upgrade,v 1.13 2002/04/09 18:07:24 momjian Exp $ -# -# To migrate this to newer versions of PostgreSQL: -# 1) Update the version numbers at the top of the file -# 2) Search for specific version mentions in the script and update -# accordingly. -# 3) Add changes for next version. - -#set -x - -# UPGRADE_VERSION is the expected old database version -UPGRADE_VERSION="7.2" -CUR_VERSION="7.3" - -# Set this to "Y" to enable this program -ENABLE="Y" - -if [ "$ENABLE" != "Y" ] -then - echo "Sorry, $0 cannot upgrade database version $SRC_VERSION to $DST_VERSION." 1>&2 - echo "The on-disk structure of tables has changed." 1>&2 - echo "You will need to dump and restore using pg_dumpall." 1>&2 - exit 1 -fi - - -trap "rm -f /tmp/$$.*" 0 1 2 3 15 - -BASENAME=`basename "$0"` -PHASE="" - -while [ "$#" -ne 0 ] -do - if [ "X$1" = "X-1" ] - then PHASE="1" - shift - elif [ "X$1" = "X-2" ] - then PHASE="2" - shift - elif [ "X$1" = "X-D" ] - then PGDATA="$2" - shift 2 - fi -done - -if [ "$PHASE" = "" ] -then echo "You must run $BASENAME in either mode 1 or mode 2." 1>&2 - echo "Usage: $BASENAME [-D datadir] -1 | -2" 1>&2 - exit 1 -fi - -if [ "$PGDATA" = "" ] -then echo "You must set the PGDATA environment variable or specify it with -D." 1>&2 - echo "Usage: $BASENAME [-D datadir] -1 | -2" 1>&2 - exit 1 -fi - -if [ ! -d "$PGDATA" ] -then echo "$PGDATA does not exist. Exiting." 1>&2 - if [ "$PHASE" -eq 2 ] - then echo "Perhaps you didn't run initdb." 1>&2 - fi - exit 1 -fi - -if [ "$USER" = "root" -o ! -r "$PGDATA"/PG_VERSION ] -then echo "You must run this as the PostgreSQL superuser. Exiting." 1>&2 - exit 1 -fi - -# Strip off the trailing directory name and store our data there -# in the hope we are in the same filesystem so 'mv 'works. - -INFODIR=`dirname "$PGDATA"`/pg_upgrade_info -SAVEDATA="$INFODIR"/data - -make_dbobjoidmap() -{ - psql -d template1 -At -c "SELECT datname FROM pg_database" | - grep -v '^template0$' | - while read DB - do - QUERY="SELECT relname, oid - FROM pg_class - WHERE relkind = 'r' OR - relkind = 'i' OR - relkind = 'S' OR - relkind = 't';" - - psql -d "$DB" -At -F' ' -c "$QUERY" | - while read RELNAME_OID - do - echo "$DB $RELNAME_OID" - done - done -} - - -make_dboidmap() -{ - psql -d template1 -At -F' ' -c \ - 'SELECT datname, oid FROM pg_database;' | - grep -v '^template0$' -} - - -move_objfiles() -{ - # Test to make sure there is a matching file in each place - - if [ ! -f "$SAVEDATA"/base/"$SRC_DBOID"/"$SRC_OID" -a \ - ! -h "$SAVEDATA"/base/"$SRC_DBOID"/"$SRC_OID" ] - then echo "Moving of database $DB, OID $SRC_OID, object $OBJ failed." 1>&2 - echo "File not found. Exiting." 1>&2 - return 1 - fi - - if [ ! -f "$PGDATA"/base/"$DST_DBOID"/"$DST_OID" -a \ - ! -h "$PGDATA"/base/"$DST_DBOID"/"$DST_OID" ] - then echo "Moving of database $DB, OID $DST_OID, object $OBJ failed." 1>&2 - echo "File not found. Exiting." 1>&2 - return 1 - fi - - # Move files - - mv -f "$SAVEDATA"/base/"$SRC_DBOID"/"$SRC_OID" "$PGDATA"/base/"$DST_DBOID"/"$DST_OID" - if [ "$?" -ne 0 ] - then echo "Moving of database $DB, OID $SRC_OID, object $OBJ" 1>&2 - echo "to $DST_OID failed. Exiting" 1>&2 - return 1 - fi - - # handle table extents - - ls "$SAVEDATA"/base/"$SRC_DBOID"/"$SRC_OID".* 2> /dev/null | while read FILE - do - EXT=`basename "$FILE" | sed 's/^.*\.\(.*\)$/\1/'` - mv -f "$FILE" "$PGDATA"/base/"$DST_DBOID"/"$DST_OID"."$EXT" - if [ "$?" -ne 0 ] - then echo "Moving of database $DB, OID $SRC_OID, object $OBJ" 1>&2 - echo "to $DST_OID failed. Exiting." 1>&2 - return 1 - fi - done -} - -if [ "$PHASE" -eq 1 ] -then - - ########################## - # Phase 1 starts here # - ########################## - - - if [ ! -d "$PGDATA"/base/1 ] - then echo "There is no database template1 in $PGDATA/base." 1>&2 - exit 1 - fi - - # get version - SRC_VERSION=`cat "$PGDATA"/PG_VERSION` - if [ "$SRC_VERSION" = "" ] - then echo "$BASENAME can not find the PostgreSQL version file" 1>&2 - echo "'$PGDATA/PG_VERSION'. Exiting." 1>&2 - exit 1 - fi - - if [ "$SRC_VERSION" != "$CUR_VERSION" -a \ - "$SRC_VERSION" != "$UPGRADE_VERSION" ] - then echo "$BASENAME supports versions $UPGRADE_VERSION and $CUR_VERSION only." 1>&2 - echo "However, your database is version $SRC_VERSION." 1>&2 - echo "You will need to dump and restore using pg_dumpall. Exiting." 1>&2 - exit 1 - fi - - # If server is down, start it so we can do some work. - if ! pg_ctl status | sed -n '1p' | grep "is running" > /dev/null 2>&1 - then pg_ctl -w start - if [ $? -ne 0 ] - then echo "Can not start server. Exiting." 1>&2 - exit 1 - fi - fi - - # create directory for our data - if ! rm -rf "$INFODIR" - then echo "Deletion of old pg_upgrade_info directory $INFODIR failed." 1>&2 - echo "Exiting." 1>&2 - exit 1 - fi - if ! mkdir "$INFODIR" - then echo "Creation of new pg_upgrade_info directory $INFODIR failed." 1>&2 - echo "Exiting." 1>&2 - exit 1 - fi - - if ! chmod og-rwx "$INFODIR" - then echo "Permission change on new pg_upgrade_info directory $INFODIR failed." 1>&2 - echo "Exiting." 1>&2 - exit 1 - fi - - - # Dump schema - pg_dumpall -s > "$INFODIR"/schema - if [ $? -ne 0 ] - then echo "Can not dump schema. Exiting." 1>&2 - exit 1 - fi - - # Generate mappings for database - make_dboidmap > "$INFODIR"/dboidmap || exit "$?" - make_dbobjoidmap > "$INFODIR"/dbobjoidmap || exit "$?" - - # Vacuum all databases to remove exipired rows. - # We will lose our transaction log file during the upgrade so we - # have to do this. - - vacuumdb -a - if [ $? -ne 0 ] - then echo "Can not vacuum server. Exiting." 1>&2 - exit 1 - fi - - # Stop server so we can move the directory. - pg_ctl -w stop - if [ $? -ne 0 ] - then echo "Can not stop server. Exiting." 1>&2 - exit 1 - fi - - # No matter what the directory name, call it data - mv "$PGDATA" "$INFODIR"/data - if [ $? -ne 0 ] - then echo "Can not move old $PGDATA out of the way. Exiting." 1>&2 - exit 1 - fi - echo - echo - echo "$BASENAME phase 1 completed." - echo "Continue with the steps outlined in the $BASENAME manual page." - exit 0 -fi - - - ########################## - # Phase 2 starts here # - ########################## - -# check things - -if [ ! -d "$INFODIR" ] -then echo "There is no '$INFODIR' directory from the phase 1 run of $BASENAME." 1>&2 - exit 1 -fi - -if [ ! -d "$SAVEDATA" ] -then echo "There is no '$SAVEDATA' directory from the phase 1 run of $BASENAME." 1>&2 - exit 1 -fi - -if [ ! -f "$SAVEDATA/PG_VERSION" ] -then echo "Cannot read '$SAVEDATA/PG_VERSION' --- something is wrong." 1>&2 - exit 1 -fi - -if [ ! -f "$PGDATA/PG_VERSION" ] -then echo "Cannot read '$PGDATA/PG_VERSION' --- something is wrong." 1>&2 - exit 1 -fi - -if [ ! -d "$PGDATA/base/1" ] -then echo "Cannot find database template1 in '$PGDATA/base'." 1>&2 - echo "Are you running $BASENAME as the postgres superuser?" 1>&2 - exit 1 -fi - -# Get the actual versions seen in the data dirs. - -SRC_VERSION=`cat "$SAVEDATA"/PG_VERSION` -DST_VERSION=`cat "$PGDATA"/PG_VERSION` - -# Check for version compatibility. -# This code will need to be updated/reviewed for each new PostgreSQL release. - -if [ "$DST_VERSION" != "$CUR_VERSION" ] -then echo "$BASENAME is for PostgreSQL version $CUR_VERSION" 1>&2 - echo "but $PGDATA/PG_VERSION contains $DST_VERSION." 1>&2 - echo "Did you run initdb for version $UPGRADE_VERSION by mistake?" 1>&2 - exit 1 -fi - -# Stop server for pg_resetxlog use - -if pg_ctl status | sed -n '1p' | grep "is running" > /dev/null 2>&1 -then pg_ctl -w stop - if [ $? -ne 0 ] - then echo "Can not start server. Exiting." 1>&2 - exit 1 - fi -fi - -# check for proper pg_resetxlog version - -pg_resetxlog 2> /dev/null -# file not found status is normally 127, not 1 -if [ "$?" -ne 1 ] -then echo "Unable to find pg_resetxlog in your path." 1>&2 - echo "Install it from pgsql/contrib/pg_resetxlog and continue. Exiting." 1>&2 - exit 1 -fi - -if ! pg_resetxlog -x 2>&1 | grep 'xid' > /dev/null 2>&1 -then echo "Old version of pg_resetxlog found in path." 1>&2 - echo "Install a newer version of pg_resetxlog from pgsql/contrib/pg_resetxlog." 1>&2 - echo "Exiting." 1>&2 - exit 1 -fi - -SRC_XID=`pg_resetxlog -n "$SAVEDATA" | grep "NextXID" | awk -F' *' '{print $4}'` -DST_XID=`pg_resetxlog -n "$PGDATA" | grep "NextXID" | awk -F' *' '{print $4}'` - -# compare locales to make sure they match - -pg_resetxlog -n "$SAVEDATA" | grep "^LC_" > /tmp/$$.0 -pg_resetxlog -n "$PGDATA" | grep "^LC_" > /tmp/$$.1 -if ! diff /tmp/$$.0 /tmp/$$.1 > /dev/null -then echo "Locales do not match between the two versions. Exiting." 1>&2 - exit 1 -fi - -# Restart postmaster - -pg_ctl -w start -if [ $? -ne 0 ] -then echo "Can not start server. Exiting." 1>&2 - exit 1 -fi - - -################################### -# Checking done. Ready to proceed. -################################### - - -# Execute the schema script to create everything - -psql template1 < "$INFODIR"/schema -if [ $? -ne 0 ] -then echo "There were errors in the input script. Exiting." 1>&2 - exit 1 -fi - -echo "Input script completed, fixing row commit statuses..." - -# Generate mappings for new database -make_dboidmap > /tmp/$$.dboidmap || exit "$?" -make_dbobjoidmap > /tmp/$$.dbobjoidmap || exit "$?" - -# we are done with SQL database access -# shutdown forces buffers to disk - -pg_ctl -w stop -if [ "$?" -ne 0 ] -then echo "Unable to stop database server. Exiting." 1>&2 - exit 1 -fi - -echo "Commit fixes complete, moving data files..." - -# Move table/index/sequence files - -cat "$INFODIR"/dbobjoidmap | while read LINE -do - DB=`echo "$LINE" | awk '{print $1}'` - OBJ=`echo "$LINE" | awk '{print $2}'` - - # Skip system tables, except for pg_largeobject - # pg_toast tables are handled later as part of the - # base table move - if [ `expr X"$OBJ" : X'pg_'` -eq 4 -a \ - `expr X"$OBJ" : X'pg_largeobject'` -ne 15 ] - then continue - fi - - SRC_OID=`echo "$LINE" | awk '{print $3}'` - SRC_DBOID=`grep "^$DB " "$INFODIR"/dboidmap | awk '{print $2}'` - DST_DBOID=`grep "^$DB " /tmp/$$.dboidmap | awk '{print $2}'` - DST_OID=`grep "^$DB $OBJ " /tmp/$$.dbobjoidmap | awk '{print $3}'` - - move_objfiles - - # Handle TOAST files if they exist - if grep "^$DB pg_toast_$SRC_OID " "$INFODIR"/dbobjoidmap \ - > /dev/null 2>&1 - then # toast heap - SAVE_SRC_OID="$SRC_OID" - SAVE_DST_OID="$DST_OID" - SRC_OID=`grep "^$DB pg_toast_$SAVE_SRC_OID " \ - "$INFODIR"/dbobjoidmap | awk '{print $3}'` - DST_OID=`grep "^$DB pg_toast_$SAVE_DST_OID " \ - /tmp/$$.dbobjoidmap | awk '{print $3}'` - move_objfiles - # toast index - SRC_OID=`grep "^$DB pg_toast_${SAVE_SRC_OID}_idx " \ - "$INFODIR"/dbobjoidmap | awk '{print $3}'` - DST_OID=`grep "^$DB pg_toast_${SAVE_DST_OID}_idx " \ - /tmp/$$.dbobjoidmap | awk '{print $3}'` - move_objfiles - fi -done - - -# Set this so future backends don't think these tuples are their own -# because it matches their own XID. -# Commit status already updated by vacuum above -# Set to maximum XID just in case SRC wrapped around recently and -# is lower than DST's database - -if [ "$SRC_XID" -gt "$DST_XID" ] -then MAX_XID="$SRC_XID" -else MAX_XID="$DST_XID" -fi - -pg_resetxlog -x "$MAX_XID" "$PGDATA" -if [ "$?" -ne 0 ] -then echo "Unable to set new XID. Exiting." 1>&2 - exit 1 -fi - -# Move over old WAL - -rm -r "$PGDATA"/pg_xlog -mv -f "$SAVEDATA"/pg_xlog "$PGDATA" - -# Move over old clog - -rm -r "$PGDATA"/pg_clog -mv -f "$SAVEDATA"/pg_clog "$PGDATA" - -# Set last log file id and segment from old database - -LOG_ID=`pg_resetxlog -n "$SAVEDATA" | grep "Current log file id:" | - awk -F' *' '{print $5}'` -if [ "$LOG_ID" = "" ] -then echo "Unable to get old log file id. Exiting." 1>&2 - exit 1 -fi -SEG_ID=`pg_resetxlog -n "$SAVEDATA" | grep "Next log file segment:" | - awk -F' *' '{print $5}'` -if [ "$SEG_ID" = "" ] -then echo "Unable to get old log segment id. Exiting." 1>&2 - exit 1 -fi - -# Set checkpoint location of new database - -pg_resetxlog -l "$LOG_ID" "$SEG_ID" "$PGDATA" -if [ "$?" -ne 0 ] -then echo "Unable to set new log file/segment id. Exiting." 1>&2 - exit 1 -fi - -# Restart server with moved data - -pg_ctl -w start -if [ "$?" -ne 0 ] -then echo "Unable to restart database server. Exiting." 1>&2 - exit 1 -fi - -# Now that we have moved the WAL/transaction log files, vacuum again to -# mark install rows with fixed transaction ids to prevent problems on xid -# wraparound. - -vacuumdb -a -if [ $? -ne 0 ] -then echo "There were errors during VACUUM. Exiting." 1>&2 - exit 1 -fi - -echo -echo -echo "$BASENAME phase 2 completed." -echo "You may remove the old database files with 'rm -r $INFODIR'." -exit 0 diff --git a/contrib/pg_upgrade/pg_upgrade.1 b/contrib/pg_upgrade/pg_upgrade.1 deleted file mode 100644 index e6b05b0a5d..0000000000 --- a/contrib/pg_upgrade/pg_upgrade.1 +++ /dev/null @@ -1,98 +0,0 @@ -.\" -.TH PG_UPGRADE 1 "PG_UPGRADE(1)" "14 Jan 2002" "PostgreSQL Client Applications" "" -.SH NAME -pg_upgrade \- upgrading from a previous release without reloading -.SH SYNOPSIS -pg_upgrade [-D \fIdata_dir\fP] -1 | -2 -.SH DESCRIPTION -\fBpg_upgrade\fP is a utility for upgrading from a previous PostgreSQL -release without reloading all the data. It can also be used as a data -recovery tool. -.LP -\fBpg_upgrade\fP must be run in two stages. In phase one you must run -\fBpg_upgrade\fP with your old database installation in place. In phase -two, \fBpg_upgrade\fP must be run on a freshly \fBinitdb\fP'ed server. -In both phases, the same newly installed \fBpg_upgrade\fP script must be -used. -.SH Upgrading PostgreSQL with pg_upgrade -.LP -1) Back up your existing data directory, preferably using -\fBpg_dumpall.\fP -.LP -2) Copy the program \fIpgsql/contrib/pg_upgrade/pg_upgrade\fP from the -current PostgreSQL distribution somewhere into your path. -.LP -3) Run phase one of \fBpg_upgrade:\fP -.LP -.B $ pg_upgrade -1 -.sp -to collect information about the old database needed for the upgrade. -You may use \fI-D\fP to specify the data directory. By default it uses -the environment variable \fIPGDATA.\fP -.LP -4) Do: -.LP -.B $ cd pgsql/src -.br -.B $ make install -.sp -to install the PostgreSQL binaries for the new release. -.LP -5) Do: -.LP -.B $ cd pgsql/contrib/pg_resetxlog -.br -.B $ make install -.sp -to install the \fIpg_resetxlog\fP utility, which is needed during phase -2 of \fBpg_upgrade\fP. -.LP -6) Run initdb to create a new template1 database containing the system -tables for the new release. Make sure you use settings similar to those -used in your previous version. -.LP -7) Start the new \fIpostmaster.\fP (Note: it is critical that no users -connect to the server until the upgrade is complete. You may wish to -start the postmaster without -i or alter pg_hba.conf temporarily.) -.LP -8) Run phase two of \fBpg_upgrade:\fP -.LP -.B $ pg_upgrade -2 -.sp -The program will do some checking to make sure everything is properly -configured, and will then recreate all your databases and tables, -but with no data. It will then physically move the data files -containing non-system tables and indexes into the proper -subdirectories. -.LP -9) Restore your old \fIpostmaster\fP flags or \fIpg_hba.conf\fP if -needed to allow user logins. -.sp -.LP -10) Carefully examine the contents of the upgraded databases. If you -detect problems, you'll need to recover by restoring from your full -\fBpg_dumpall\fP backup. You can delete the \fIpg_upgrade_info/\fP -directory when you are satisfied. -.LP -The upgraded databases will be in an un-vacuumed state. You will -probably want to run a \fIVACUUM ANALYZE\fP before beginning production -work. -.SH NOTES -While \fBpg_upgrade\fP is primarly an upgrade tool, it can also be used -for data recovery. During phase 1, \fBpg_upgrade\fP creates database -name / oid and database name / table name / oid mapping files in -\fIpg_upgrade_info/.\fP These files are tab-delimited. If your system is -too damaged, you may need to manually pull this information out of -\fBpg_database\fP and \fBpg_class\fP and create the files manually. -(Keep in mind most tables have \fBpg_toast_OID\fP and -\fBpg_toast_OID_idx\fP files that store very long values. These must be -recorded as well.) It also creates a schema-only \fBpg_dumpall.\fP In a -damaged installation, you may be able to make one of these from a recent -full \fBpg_dumpall.\fP -.LP -Phase 2 rebuilds each database with the schema from the old -installation. It then moves the physical data files from the old -installation and makes some modifications so the old data files work -properly in the new installation. -.SH SEE ALSO -initdb(1), postmaster(1), pg_dump(1), pg_dumpall(1), vacuumdb(1) diff --git a/contrib/pgbench/Makefile b/contrib/pgbench/Makefile deleted file mode 100644 index e52e577931..0000000000 --- a/contrib/pgbench/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/pgbench/Makefile,v 1.10 2001/09/06 10:49:30 petere Exp $ - -subdir = contrib/pgbench -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -PROGRAM = pgbench -OBJS = pgbench.o - -PG_CPPFLAGS = -I$(libpq_srcdir) -PG_LIBS = $(libpq) - -DOCS = README.pgbench README.pgbench_jis - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/pgbench/README.pgbench b/contrib/pgbench/README.pgbench deleted file mode 100644 index d052411ab2..0000000000 --- a/contrib/pgbench/README.pgbench +++ /dev/null @@ -1,170 +0,0 @@ -pgbench README 2001/10/24 Tatsuo Ishii (t-ishii@sra.co.jp) - -o What is pgbench? - - pgbench is a simple program to run a benchmark test sort of - "TPC-B". pgbench is a client application of PostgreSQL and runs - with PostgreSQL only. It performs lots of small and simple - transactions including select/update/insert operations then - calculates number of transactions successfully completed within a - second (transactions per second, tps). Targeting data includes a - table with at least 100k tuples. - - Example outputs from pgbench look like: - - number of clients: 4 - number of transactions per client: 100 - number of processed transactions: 400/400 - tps = 19.875015(including connections establishing) - tps = 20.098827(excluding connections establishing) - - Similar program called "JDBCBench" already exists, but it requires - Java that may not be available on every platform. Moreover some - people concerned about the overhead of Java that might lead - inaccurate results. So I decided to write in pure C, and named - it "pgbench." - -o features of pgbench - - - pgbench is written in C using libpq only. So it is very portable - and easy to install. - - - pgbench can simulate concurrent connections using asynchronous - capability of libpq. No threading is required. - -o How to install pgbench - - (1) Configure and build the standard Postgres distribution. - - You can get away with just running configure at the top level - and doing "make all" in src/interfaces/libpq. - - (2) Run make in this directory. - - You will see an executable file "pgbench". You can run it here, - or install it with the standard Postgres programs by doing - "make install". - -o How to use pgbench? - - (1) Initialize database by: - - pgbench -i - - where is the name of database. pgbench uses four tables - accounts, branches, history and tellers. These tables will be - destroyed. Be very careful if you have tables having same - names. Default test data contains: - - table # of tuples - ------------------------- - branches 1 - tellers 10 - accounts 100000 - history 0 - - You can increase the number of tuples by using -s option. See - below. - - (2) Run the benchmark test - - pgbench - - The default configuration is: - - number of clients: 1 - number of transactions per client: 10 - -o options - - pgbench has number of options. - - -h hostname - hostname where the backend is running. If this option - is omitted, pgbench will connect to the localhost via - Unix domain socket. - - -p port - the port number that the backend is accepting. default is - libpq's default, usually 5432. - - -c number_of_clients - Number of clients simulated. default is 1. - - -t number_of_transactions - Number of transactions each client runs. default is 10. - - -s scaling_factor - this should be used with -i (initialize) option. - number of tuples generated will be multiple of the - scaling factor. For example, -s 100 will imply 10M - (10,000,000) tuples in the accounts table. - default is 1. - - -U login - Specify db user's login name if it is different from - the Unix login name. - - -P password - Specify the db password. CAUTION: using this option - might be a security hole since ps command will - show the password. Use this for TESTING PURPOSE ONLY. - - -n - No vacuuming and cleaning the history table prior the - test is performed. - - -v - Do vacuuming before testing. This will take some time. - With neither -n nor -v, pgbench will vacuum tellers and - branches tables only. - - -S - Perform select only transactions instead of TPC-B. - - -C - Establish connection for each transaction, rather than - doing it just once at begining of pgbench in the normal - mode. This is usefull to measure the connection overhead. - - -d - debug option. - - -o What is the "transaction" actually performed in pgbench? - - (1) begin; - - (2) update accounts set abalance = abalance + :delta where aid = :aid; - - (3) select abalance from accounts where aid = :aid; - - (4) update tellers set tbalance = tbalance + :delta where tid = :tid; - - (5) update branches set bbalance = bbalance + :delta where bid = :bid; - - (6) insert into history(tid,bid,aid,delta) values(:tid,:bid,:aid,:delta); - - (7) end; - -o License? - -Basically it is same as BSD license. See pgbench.c for more details. - -o History - -2001/10/24 - * "time"->"mtime" - -2001/09/09 - * Add -U, -P, -C options - -2000/1/15 pgbench-1.2 contributed to PostgreSQL - * Add -v option - -1999/09/29 pgbench-1.1 released - * Apply cygwin patches contributed by Yutaka Tanida - * More robust when backends die - * Add -S option (select only) - -1999/09/04 pgbench-1.0 released diff --git a/contrib/pgbench/README.pgbench_jis b/contrib/pgbench/README.pgbench_jis deleted file mode 100644 index 6e310b9cd5..0000000000 --- a/contrib/pgbench/README.pgbench_jis +++ /dev/null @@ -1,211 +0,0 @@ -pgbench README 2002/02/24 Tatsuo Ishii (t-ishii@sra.co.jp) - -$B"#(Bpgbench $B$H$O!)(B - -pgbench $B$O(B TPC-B$B$K;w$?%Y%s%A%^!<%/%F%9%H$r9T$J$&%W%m%0%i%`$G$9!%:#$N$H(B -$B$3$m(B PostgreSQL $B@lMQ$G$9!%(B - -pgbench $B$O(B select/update/insert $B$r4^$`%H%i%s%6%/%7%g%s$r]$H$J$k%F!<%V%k$O%G%U%)(B -$B%k%H$G$O(B 10$BK|%?%W%k$N%G!<%?$r4^$_$^$9!%(B - -$B(B] - -$B$G$9!%%G!<%?%Y!<%9L>$r>JN,$9$k$H!$%f!<%6L>$HF1$8%G!<%?%Y!<%9$r;XDj$7$?(B -$B$b$N$H$_$J$7$^$9!%%G!<%?%Y!<%9$O8e=R$N(B -i $B%*%W%7%g%s$r;H$C$F$"$i$+$8$a(B -$B=i4|2=$7$F$*$/I,MW$,$"$j$^$9!%(B - -pgbench $B$K$O$$$m$$$m$J%*%W%7%g%s$,$"$j$^$9!%(B - --h $B%[%9%HL>(B PostgreSQL$B$N%G!<%?%Y!<%9%G!<%b%s(B postmaster $B$NF0(B - $B$$$F$$$k%[%9%HL>$r;XDj$7$^$9!%>JN,$9$k$H<+%[%9%H$K(B Unix domain - socket $B$G@\B3$7$^$9!%(B - --p $B%]!<%HHV9f(B postmaster $B$N;HMQ$9$k%]!<%HHV9f$r;XDj$7$^$9!%>JN,$9$k$H(B 5432 - $B$,;XDj$5$l$?$b$N$H$_$J$7$^$9!%(B - --c $B%/%i%$%"%s%H?t(B $BF1;~JN,;~$O(B - 1 $B$H$J$j$^$9!%(Bpgbench $B$OF1;~JN,;~$O(B 10 $B$H$J$j$^$9!%(B - --s $B%9%1!<%j%s%0%U%!%/%?!<(B - - -i $B%*%W%7%g%s$H0l=o$K;HMQ$7$^$9!%(B - $B%9%1!<%j%s%0%U%!%/%?!<$O(B1$B0J>e$N@0?t!%%9%1!<%j%s%0%U%!(B - $B%/%?!<$rJQ$($k$3$H$K$h$j!$%F%9%H$NBP>]$H$J$k%F!<%V%k$N(B - $BBg$-$5$,(B 10$BK|(B x [$B%9%1!<%j%s%0%U%!%/%?!<(B]$B$K$J$j$^$9!%(B - $B%G%U%)%k%H$N%9%1!<%j%s%0%U%!%/%?!<$O(B 1 $B$G$9!%(B - --U login DB$B%f!<%6$N%m%0%$%sL>$r;XDj$7$^$9!%(B - --P password $B%Q%9%o!<%I$r;XDj$7$^$9!%$J$*!$$3$N%*%W%7%g%s$r;H$&$H!$(B - $B%Q%9%o!<%I$r(Bps$B%3%^%s%I$G8+$i$l$k$J$I!$%;%-%e%j%F%#%[!<(B - $B%k$K$J$k2DG=@-$,$"$k$N$G!$%F%9%HMQ$K$N$_$*;H$$2<$5$$!%(B - --n $B$3$N%*%W%7%g%s$r;XDj$9$k$H!$%Y%s%A%^!<%/3+;OA0$K(B vacuum $B$H(B - history $B$N%/%j%"$r9T$J$$$^$;$s!%(B - --v $B$3$N%*%W%7%g%s$r;XDj$9$k$H!$%Y%s%A%^!<%/3+;OA0$K(B vacuum $B$H(B - history $B$N%/%j%"$r9T$J$$$^$9!%(B-v $B$H(B -n $B$r>JN,$9$k$H!$(B - $B:G>.8B$N(B vacuum $B$J$I$r9T$$$^$9!%$9$J$o$A!$(Bhistory $B$N:o=|!$(B - $B$H(B history, branches, history $B$N(B vacuum $B$r9T$$$^$9!%(B - $B$3$l$O!$(Bvacuum $B$N;~4V$r:G>.8B$K$7$J$,$i!$%Q%U%)!<%^%s%9$K(B - $B1F6A$9$k%4%_A]=|$r8z2LE*$K9T$$$^$9!%DL>o$O(B -v $B$H(B -n $B$r(B - $B>JN,$9$k$3$H$r$*$9$9$a$7$^$9!%(B - --S TPC-B$B$N%H%i%s%6%/%7%g%s$G$O$J$/!$8!:w$N$_$N%H%i%s%6%/%7%g%s$r(B - $BuBV$G$NB,Dj$r9T$$$^$9!%$7$?$,$C$F(BTPC-B$B$N%9%Z%C%/$K(B - $B$OE,9g$7$J$/$J$j$^$9$,!$$h$j8=uBV$G$NB,Dj$r9T$$$^$9!%$7$?$,$C$F(BTPC-B$B$N%9%Z%C%/$K(B - $B$OE,9g$7$J$/$J$j$^$9$,!$$h$j8=pJs$,I=<($5$l$^$9!%(B - -$B"#%G!<%?%Y!<%9$N=i4|2=(B - -pgbench $B$G%Y%s%A%^!<%/%F%9%H$r(B] - -$B$3$l$K$h$j0J2<$N%F!<%V%k$,:n$i$l$^$9(B($B%9%1!<%j%s%0%U%!%/%?!<(B == 1 $B$N>l9g(B)$B!%(B - -$B!vCm0U!v(B -$BF1$8L>A0$N%F!<%V%k$,$"$k$H:o=|$5$l$F$7$^$&$N$G$4Cm0U2<$5$$!*!*(B - -$B%F!<%V%kL>(B $B%?%W%k?t(B -------------------------- -branches 1 -tellers 10 -accounts 100000 -history 0 - -$B%9%1!<%j%s%0%U%!%/%?!<$r(B 10,100,1000 $B$J$I$KJQ99$9$k$H!$>e5-%?%W%k?t$O(B -$B$=$l$K1~$8$F(B10$BG\!$(B100$BG\!$(B1000$BG\$K$J$j$^$9!%$?$H$($P!$%9%1!<%j%s%0%U%!(B -$B%/%?!<$r(B 10 $B$H$9$k$H!$(B - -$B%F!<%V%kL>(B $B%?%W%k?t(B -------------------------- -branches 10 -tellers 100 -accounts 1000000 -history 0 - -$B$K$J$j$^$9!%(B - -$B"#!V%H%i%s%6%/%7%g%s!W$NDj5A(B - -pgbench $B$G$O!$0J2<$N%7!<%1%s%9$rA4It40N;$7$F(B1$B%H%i%s%6%/%7%g%s$H?t$($F(B -$B$$$^$9!%(B - -(1) begin; - -(2) update accounts set abalance = abalance + :delta where aid = :aid; - $B$3$3$G!$(B:delta$B$O(B1$B$+$i(B1000$B$^$G$NCM$r$l$3$N%H%i%s%6%/%7%g%s$N(B - $BCf$G$OF1$8CM$r;H$$$^$9!%(B - -(3) select abalance from accounts where aid = :aid; - $B$3$3$G$O(B1$B7o$@$18!:w$5$l$^$9!%(B - -(4) update tellers set tbalance = tbalance + :delta where tid = :tid; - $B$3$3$G(B :tid $B$O(B 1$B$+$i(B10$B$N4V$NCM$r$H$kMp?t$G$9!%(B - -(5) update branches set bbalance = bbalance + :delta where bid = :bid; - $B$3$3$G(B :bid $B$O(B 1 $B$+$i(B[$B%9%1%j%s%0%U%!%/%?!<(B]$B$N4V$NCM$rr7o(B - -pgbench $B$O@P0f(B $BC#IW$K$h$C$F=q$+$l$^$7$?!%%i%$%;%s%9>r7o$O(B pgbench.c $B$N(B -$BKAF,$K=q$$$F$"$j$^$9!%$3$N>r7o$r - -#ifdef WIN32 -#include "win32.h" -#else -#include -#include - -#ifdef HAVE_GETOPT_H -#include -#endif - -#ifdef HAVE_SYS_SELECT_H -#include -#endif - -/* for getrlimit */ -#include -#endif /* WIN32 */ - -/******************************************************************** - * some configurable parameters */ - -#define MAXCLIENTS 1024 /* max number of clients allowed */ - -int nclients = 1; /* default number of simulated clients */ -int nxacts = 10; /* default number of transactions per - * clients */ - -/* - * scaling factor. for example, tps = 10 will make 1000000 tuples of - * accounts table. - */ -int tps = 1; - -/* - * end of configurable parameters - *********************************************************************/ - -#define nbranches 1 -#define ntellers 10 -#define naccounts 100000 - -int remains; /* number of remained clients */ - -int is_connect; /* establish connection for each - * transactoin */ - -char *pghost = ""; -char *pgport = NULL; -char *pgoptions = NULL; -char *pgtty = NULL; -char *login = NULL; -char *pwd = NULL; -char *dbName; - -typedef struct -{ - PGconn *con; /* connection handle to DB */ - int state; /* state No. */ - int cnt; /* xacts count */ - int ecnt; /* error count */ - int listen; /* none 0 indicates that an async query - * has been sent */ - int aid; /* account id for this transaction */ - int bid; /* branch id for this transaction */ - int tid; /* teller id for this transaction */ - int delta; - int abalance; -} CState; - -static void -usage() -{ - fprintf(stderr, "usage: pgbench [-h hostname][-p port][-c nclients][-t ntransactions][-s scaling_factor][-n][-C][-v][-S][-N][-U login][-P password][-d][dbname]\n"); - fprintf(stderr, "(initialize mode): pgbench -i [-h hostname][-p port][-s scaling_factor][-U login][-P password][-d][dbname]\n"); -} - -/* random number generator */ -static int -getrand(int min, int max) -{ - return (min + (int) (max * 1.0 * rand() / (RAND_MAX + 1.0))); -} - -/* set up a connection to the backend */ -static PGconn * -doConnect() -{ - PGconn *con; - - con = PQsetdbLogin(pghost, pgport, pgoptions, pgtty, dbName, - login, pwd); - if (con == NULL) - { - fprintf(stderr, "Connection to database '%s' failed.\n", dbName); - fprintf(stderr, "Memory allocatin problem?\n"); - return (NULL); - } - - if (PQstatus(con) == CONNECTION_BAD) - { - fprintf(stderr, "Connection to database '%s' failed.\n", dbName); - - if (PQerrorMessage(con)) - fprintf(stderr, "%s", PQerrorMessage(con)); - else - fprintf(stderr, "No explanation from the backend\n"); - - return (NULL); - } - return (con); -} - -/* throw away response from backend */ -static void -discard_response(CState * state) -{ - PGresult *res; - - do - { - res = PQgetResult(state->con); - if (res) - PQclear(res); - } while (res); -} - -/* check to see if the SQL result was good */ -static int -check(CState * state, PGresult *res, int n, int good) -{ - CState *st = &state[n]; - - if (res && PQresultStatus(res) != good) - { - fprintf(stderr, "Client %d aborted in state %d: %s", n, st->state, PQerrorMessage(st->con)); - remains--; /* I've aborted */ - PQfinish(st->con); - st->con = NULL; - return (-1); - } - return (0); /* OK */ -} - -/* process a transaction */ -static void -doOne(CState * state, int n, int debug, int ttype) -{ - char sql[256]; - PGresult *res; - CState *st = &state[n]; - - if (st->listen) - { /* are we receiver? */ - if (debug) - fprintf(stderr, "client %d receiving\n", n); - while (PQisBusy(st->con) == TRUE) - { - if (!PQconsumeInput(st->con)) - { /* there's something wrong */ - fprintf(stderr, "Client %d aborted in state %d. Probably the backend died while processing.\n", n, st->state); - remains--; /* I've aborted */ - PQfinish(st->con); - st->con = NULL; - return; - } - } - - switch (st->state) - { - case 0: /* response to "begin" */ - res = PQgetResult(st->con); - if (check(state, res, n, PGRES_COMMAND_OK)) - return; - PQclear(res); - discard_response(st); - break; - case 1: /* response to "update accounts..." */ - res = PQgetResult(st->con); - if (check(state, res, n, PGRES_COMMAND_OK)) - return; - PQclear(res); - discard_response(st); - break; - case 2: /* response to "select abalance ..." */ - res = PQgetResult(st->con); - if (check(state, res, n, PGRES_TUPLES_OK)) - return; - PQclear(res); - discard_response(st); - break; - case 3: /* response to "update tellers ..." */ - res = PQgetResult(st->con); - if (check(state, res, n, PGRES_COMMAND_OK)) - return; - PQclear(res); - discard_response(st); - break; - case 4: /* response to "update branches ..." */ - res = PQgetResult(st->con); - if (check(state, res, n, PGRES_COMMAND_OK)) - return; - PQclear(res); - discard_response(st); - break; - case 5: /* response to "insert into history ..." */ - res = PQgetResult(st->con); - if (check(state, res, n, PGRES_COMMAND_OK)) - return; - PQclear(res); - discard_response(st); - break; - case 6: /* response to "end" */ - res = PQgetResult(st->con); - if (check(state, res, n, PGRES_COMMAND_OK)) - return; - PQclear(res); - discard_response(st); - - if (is_connect) - { - PQfinish(st->con); - st->con = NULL; - } - - if (++st->cnt >= nxacts) - { - remains--; /* I've done */ - if (st->con != NULL) - { - PQfinish(st->con); - st->con = NULL; - } - return; - } - break; - } - - /* increment state counter */ - st->state++; - if (st->state > 6) - st->state = 0; - } - - if (st->con == NULL) - { - if ((st->con = doConnect()) == NULL) - { - fprintf(stderr, "Client %d aborted in establishing connection.\n", - n); - remains--; /* I've aborted */ - PQfinish(st->con); - st->con = NULL; - return; - } - } - - switch (st->state) - { - case 0: /* about to start */ - strcpy(sql, "begin"); - st->aid = getrand(1, naccounts * tps); - st->bid = getrand(1, nbranches * tps); - st->tid = getrand(1, ntellers * tps); - st->delta = getrand(1, 1000); - break; - case 1: - sprintf(sql, "update accounts set abalance = abalance + %d where aid = %d\n", st->delta, st->aid); - break; - case 2: - sprintf(sql, "select abalance from accounts where aid = %d", st->aid); - break; - case 3: - if (ttype == 0) - { - sprintf(sql, "update tellers set tbalance = tbalance + %d where tid = %d\n", - st->delta, st->tid); - break; - } - case 4: - if (ttype == 0) - { - sprintf(sql, "update branches set bbalance = bbalance + %d where bid = %d", st->delta, st->bid); - break; - } - case 5: - sprintf(sql, "insert into history(tid,bid,aid,delta,mtime) values(%d,%d,%d,%d,'now')", - st->tid, st->bid, st->aid, st->delta); - break; - case 6: - strcpy(sql, "end"); - break; - } - - if (debug) - fprintf(stderr, "client %d sending %s\n", n, sql); - if (PQsendQuery(st->con, sql) == 0) - { - if (debug) - fprintf(stderr, "PQsendQuery(%s)failed\n", sql); - st->ecnt++; - } - else - { - st->listen++; /* flags that should be listned */ - } -} - -/* process a select only transaction */ -static void -doSelectOnly(CState * state, int n, int debug) -{ - char sql[256]; - PGresult *res; - CState *st = &state[n]; - - if (st->listen) - { /* are we receiver? */ - if (debug) - fprintf(stderr, "client %d receiving\n", n); - while (PQisBusy(st->con) == TRUE) - { - if (!PQconsumeInput(st->con)) - { /* there's something wrong */ - fprintf(stderr, "Client %d aborted in state %d. Probably the backend died while processing.\n", n, st->state); - remains--; /* I've aborted */ - PQfinish(st->con); - st->con = NULL; - return; - } - } - - switch (st->state) - { - case 0: /* response to "select abalance ..." */ - res = PQgetResult(st->con); - if (check(state, res, n, PGRES_TUPLES_OK)) - return; - PQclear(res); - discard_response(st); - - if (is_connect) - { - PQfinish(st->con); - st->con = NULL; - } - - if (++st->cnt >= nxacts) - { - remains--; /* I've done */ - if (st->con != NULL) - { - PQfinish(st->con); - st->con = NULL; - } - return; - } - break; - } - - /* increment state counter */ - st->state++; - if (st->state > 0) - st->state = 0; - } - - if (st->con == NULL) - { - if ((st->con = doConnect()) == NULL) - { - fprintf(stderr, "Client %d aborted in establishing connection.\n", - n); - remains--; /* I've aborted */ - PQfinish(st->con); - st->con = NULL; - return; - } - } - - switch (st->state) - { - case 0: - st->aid = getrand(1, naccounts * tps); - sprintf(sql, "select abalance from accounts where aid = %d", st->aid); - break; - } - - if (debug) - fprintf(stderr, "client %d sending %s\n", n, sql); - - if (PQsendQuery(st->con, sql) == 0) - { - if (debug) - fprintf(stderr, "PQsendQuery(%s)failed\n", sql); - st->ecnt++; - } - else - { - st->listen++; /* flags that should be listned */ - } -} - -/* discard connections */ -static void -disconnect_all(CState * state) -{ - int i; - - for (i = 0; i < nclients; i++) - { - if (state[i].con) - PQfinish(state[i].con); - } -} - -/* create tables and setup data */ -static void -init() -{ - PGconn *con; - PGresult *res; - static char *DDLs[] = { - "drop table branches", - "create table branches(bid int, primary key(bid),bbalance int,filler char(88))", - "drop table tellers", - "create table tellers(tid int, primary key(tid),bid int,tbalance int,filler char(84))", - "drop table accounts", - "create table accounts(aid int,primary key(aid),bid int,abalance int,filler char(84))", - "drop table history", - "create table history(tid int,bid int,aid int,delta int,mtime timestamp,filler char(22))"}; - char sql[256]; - - int i; - - if ((con = doConnect()) == NULL) - exit(1); - - for (i = 0; i < (sizeof(DDLs) / sizeof(char *)); i++) - { - res = PQexec(con, DDLs[i]); - if (strncmp(DDLs[i], "drop", 4) && PQresultStatus(res) != PGRES_COMMAND_OK) - { - fprintf(stderr, "%s", PQerrorMessage(con)); - exit(1); - } - PQclear(res); - } - - res = PQexec(con, "begin"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) - { - fprintf(stderr, "%s", PQerrorMessage(con)); - exit(1); - } - - for (i = 0; i < nbranches * tps; i++) - { - sprintf(sql, "insert into branches(bid,bbalance) values(%d,0)", i + 1); - res = PQexec(con, sql); - if (PQresultStatus(res) != PGRES_COMMAND_OK) - { - fprintf(stderr, "%s", PQerrorMessage(con)); - exit(1); - } - PQclear(res); - } - - for (i = 0; i < ntellers * tps; i++) - { - sprintf(sql, "insert into tellers(tid,bid,tbalance) values (%d,%d,0)" - ,i + 1, i / ntellers + 1); - res = PQexec(con, sql); - if (PQresultStatus(res) != PGRES_COMMAND_OK) - { - fprintf(stderr, "%s", PQerrorMessage(con)); - exit(1); - } - PQclear(res); - } - - res = PQexec(con, "end"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) - { - fprintf(stderr, "%s", PQerrorMessage(con)); - exit(1); - } - - - /* - * occupy accounts table with some data - */ - fprintf(stderr, "creating tables...\n"); - for (i = 0; i < naccounts * tps; i++) - { - int j = i + 1; - - if (j % 10000 == 1) - { - res = PQexec(con, "copy accounts from stdin"); - if (PQresultStatus(res) != PGRES_COPY_IN) - { - fprintf(stderr, "%s", PQerrorMessage(con)); - exit(1); - } - PQclear(res); - } - - sprintf(sql, "%d\t%d\t%d\t\n", j, j / naccounts, 0); - if (PQputline(con, sql)) - { - fprintf(stderr, "PQputline failed\n"); - exit(1); - } - - if (j % 10000 == 0) - { - /* - * every 10000 tuples, we commit the copy command. this should - * avoid generating too much WAL logs - */ - fprintf(stderr, "%d tuples done.\n", j); - if (PQputline(con, "\\.\n")) - { - fprintf(stderr, "very last PQputline failed\n"); - exit(1); - } - - if (PQendcopy(con)) - { - fprintf(stderr, "PQendcopy failed\n"); - exit(1); - } - -#ifdef NOT_USED - /* - * do a checkpoint to purge the old WAL logs - */ - res = PQexec(con, "checkpoint"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) - { - fprintf(stderr, "%s", PQerrorMessage(con)); - exit(1); - } -#endif /* NOT_USED */ - } - } - - /* vacuum */ - fprintf(stderr, "vacuum..."); - res = PQexec(con, "vacuum analyze"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) - { - fprintf(stderr, "%s", PQerrorMessage(con)); - exit(1); - } - fprintf(stderr, "done.\n"); - - PQfinish(con); -} - -/* print out results */ -static void -printResults( - int ttype, CState * state, - struct timeval * tv1, struct timeval * tv2, - struct timeval * tv3) -{ - double t1, - t2; - int i; - int normal_xacts = 0; - char *s; - - for (i = 0; i < nclients; i++) - normal_xacts += state[i].cnt; - - t1 = (tv3->tv_sec - tv1->tv_sec) * 1000000.0 + (tv3->tv_usec - tv1->tv_usec); - t1 = normal_xacts * 1000000.0 / t1; - - t2 = (tv3->tv_sec - tv2->tv_sec) * 1000000.0 + (tv3->tv_usec - tv2->tv_usec); - t2 = normal_xacts * 1000000.0 / t2; - - if (ttype == 0) - s = "TPC-B (sort of)"; - else if (ttype == 2) - s = "Update only accounts"; - else - s = "SELECT only"; - - printf("transaction type: %s\n", s); - printf("scaling factor: %d\n", tps); - printf("number of clients: %d\n", nclients); - printf("number of transactions per client: %d\n", nxacts); - printf("number of transactions actually processed: %d/%d\n", normal_xacts, nxacts * nclients); - printf("tps = %f(including connections establishing)\n", t1); - printf("tps = %f(excluding connections establishing)\n", t2); -} - - -int -main(int argc, char **argv) -{ - extern char *optarg; - extern int optind, - opterr, - optopt; - int c; - int is_init_mode = 0; /* initialize mode? */ - int is_no_vacuum = 0; /* no vacuum at all before - * testing? */ - int is_full_vacuum = 0; /* do full vacuum before testing? */ - int debug = 0; /* debug flag */ - int ttype = 0; /* transaction type. 0: TPC-B, 1: SELECT - * only - 2: skip updation of branches and tellers */ - - static CState state[MAXCLIENTS]; /* clients status */ - - struct timeval tv1; /* start up time */ - struct timeval tv2; /* after establishing all connections to - * the backend */ - struct timeval tv3; /* end time */ - - int i; - - fd_set input_mask; - int nsocks; /* return from select(2) */ - int maxsock; /* max socket number to be waited */ - -#ifndef __CYGWIN__ - struct rlimit rlim; -#endif - - PGconn *con; - PGresult *res; - - while ((c = getopt(argc, argv, "ih:nvp:dc:t:s:U:P:CNS")) != -1) - { - switch (c) - { - case 'i': - is_init_mode++; - break; - case 'h': - pghost = optarg; - break; - case 'n': - is_no_vacuum++; - break; - case 'v': - is_full_vacuum++; - break; - case 'p': - pgport = optarg; - break; - case 'd': - debug++; - break; - case 'S': - ttype = 1; - break; - case 'N': - ttype = 2; - break; - case 'c': - nclients = atoi(optarg); - if (nclients <= 0 || nclients > MAXCLIENTS) - { - fprintf(stderr, "wrong number of clients: %d\n", nclients); - exit(1); - } -#ifndef __CYGWIN__ -#ifdef RLIMIT_NOFILE /* most platform uses RLIMIT_NOFILE */ - if (getrlimit(RLIMIT_NOFILE, &rlim) == -1) - { -#else /* but BSD doesn't ... */ - if (getrlimit(RLIMIT_OFILE, &rlim) == -1) - { -#endif /* HAVE_RLIMIT_NOFILE */ - fprintf(stderr, "getrlimit failed. reason: %s\n", strerror(errno)); - exit(1); - } - if (rlim.rlim_cur <= (nclients + 2)) - { - fprintf(stderr, "You need at least %d open files resource but you are only allowed to use %ld.\n", nclients + 2, (long) rlim.rlim_cur); - fprintf(stderr, "Use limit/ulimt to increase the limit before using pgbench.\n"); - exit(1); - } -#endif /* #ifndef __CYGWIN__ */ - break; - case 'C': - is_connect = 1; - break; - case 's': - tps = atoi(optarg); - if (tps <= 0) - { - fprintf(stderr, "wrong scaling factor: %d\n", tps); - exit(1); - } - break; - case 't': - nxacts = atoi(optarg); - if (nxacts <= 0) - { - fprintf(stderr, "wrong number of transactions: %d\n", nxacts); - exit(1); - } - break; - case 'U': - login = optarg; - break; - case 'P': - pwd = optarg; - break; - default: - usage(); - exit(1); - break; - } - } - - if (argc > optind) - dbName = argv[optind]; - else - { - dbName = getenv("USER"); - if (dbName == NULL) - dbName = ""; - } - - if (is_init_mode) - { - init(); - exit(0); - } - - remains = nclients; - - if (debug) - { - printf("pghost: %s pgport: %s nclients: %d nxacts: %d dbName: %s\n", - pghost, pgport, nclients, nxacts, dbName); - } - - /* opening connection... */ - con = doConnect(); - if (con == NULL) - exit(1); - - if (PQstatus(con) == CONNECTION_BAD) - { - fprintf(stderr, "Connection to database '%s' failed.\n", dbName); - fprintf(stderr, "%s", PQerrorMessage(con)); - exit(1); - } - - /* - * get the scaling factor that should be same as count(*) from - * branches... - */ - res = PQexec(con, "select count(*) from branches"); - if (PQresultStatus(res) != PGRES_TUPLES_OK) - { - fprintf(stderr, "%s", PQerrorMessage(con)); - exit(1); - } - tps = atoi(PQgetvalue(res, 0, 0)); - if (tps < 0) - { - fprintf(stderr, "count(*) from branches invalid (%d)\n", tps); - exit(1); - } - PQclear(res); - - if (!is_no_vacuum) - { - fprintf(stderr, "starting vacuum..."); - res = PQexec(con, "vacuum branches"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) - { - fprintf(stderr, "%s", PQerrorMessage(con)); - exit(1); - } - PQclear(res); - - res = PQexec(con, "vacuum tellers"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) - { - fprintf(stderr, "%s", PQerrorMessage(con)); - exit(1); - } - PQclear(res); - - res = PQexec(con, "delete from history"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) - { - fprintf(stderr, "%s", PQerrorMessage(con)); - exit(1); - } - PQclear(res); - res = PQexec(con, "vacuum history"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) - { - fprintf(stderr, "%s", PQerrorMessage(con)); - exit(1); - } - PQclear(res); - - fprintf(stderr, "end.\n"); - - if (is_full_vacuum) - { - fprintf(stderr, "starting full vacuum..."); - res = PQexec(con, "vacuum analyze accounts"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) - { - fprintf(stderr, "%s", PQerrorMessage(con)); - exit(1); - } - PQclear(res); - fprintf(stderr, "end.\n"); - } - } - PQfinish(con); - - /* set random seed */ - gettimeofday(&tv1, 0); - srand((uint) tv1.tv_usec); - - /* get start up time */ - gettimeofday(&tv1, 0); - - if (is_connect == 0) - { - /* make connections to the database */ - for (i = 0; i < nclients; i++) - { - if ((state[i].con = doConnect()) == NULL) - exit(1); - } - } - - /* time after connections set up */ - gettimeofday(&tv2, 0); - - /* send start up quries in async manner */ - for (i = 0; i < nclients; i++) - { - if (ttype == 0 || ttype == 2) - doOne(state, i, debug, ttype); - else if (ttype == 1) - doSelectOnly(state, i, debug); - } - - for (;;) - { - if (remains <= 0) - { /* all done ? */ - disconnect_all(state); - /* get end time */ - gettimeofday(&tv3, 0); - printResults(ttype, state, &tv1, &tv2, &tv3); - exit(0); - } - - FD_ZERO(&input_mask); - - maxsock = 0; - for (i = 0; i < nclients; i++) - { - if (state[i].con) - { - int sock = PQsocket(state[i].con); - - if (sock < 0) - { - fprintf(stderr, "Client %d: PQsock failed\n", i); - disconnect_all(state); - exit(1); - } - FD_SET(sock, &input_mask); - if (maxsock < sock) - maxsock = sock; - } - } - - if ((nsocks = select(maxsock + 1, &input_mask, (fd_set *) NULL, - (fd_set *) NULL, (struct timeval *) NULL)) < 0) - { - if (errno == EINTR) - continue; - /* must be something wrong */ - disconnect_all(state); - fprintf(stderr, "select failed: %s\n", strerror(errno)); - exit(1); - } - else if (nsocks == 0) - { /* timeout */ - fprintf(stderr, "select timeout\n"); - for (i = 0; i < nclients; i++) - { - fprintf(stderr, "client %d:state %d cnt %d ecnt %d listen %d\n", - i, state[i].state, state[i].cnt, state[i].ecnt, state[i].listen); - } - exit(0); - } - - /* ok, backend returns reply */ - for (i = 0; i < nclients; i++) - { - if (state[i].con && FD_ISSET(PQsocket(state[i].con), &input_mask)) - { - if (ttype == 0 || ttype == 2) - doOne(state, i, debug, ttype); - else if (ttype == 1) - doSelectOnly(state, i, debug); - } - } - } -} diff --git a/contrib/pgcrypto/API b/contrib/pgcrypto/API deleted file mode 100644 index 6664caf8c1..0000000000 --- a/contrib/pgcrypto/API +++ /dev/null @@ -1,163 +0,0 @@ - -C API for pgcrypto -================== - - -UN*X crypt() -============ - -#include - -char * -px_crypt(const char *psw, const char *salt, char *buf, unsigned buflen); - - returns buf or NULL for error. - -unsigned px_gen_salt(const char *salt_type, char *dst, int rounds); - - returns salt size. dst should be PX_MAX_SALT_LEN bytes. - 'rounds' is algorithm specific. 0 means default for - that algorithm. - -Random -====== - -int px_get_random_bytes(uint8 *dst, int num) - - -Crypto "objects" -================ - -PX_MD - Message digest -PX_HMAC - HMAC (Hash MAC) -PX_Cipher - cipher+mode: provided by libs -PX_Combo - higher-level encryption -> padding, [MD] - -Objects are activated with following functions: - -int px_find_digest(const char *name, PX_MD **res); -int px_find_hmac(const char *name, PX_HMAC **res); -int px_find_cipher(const char *name, PX_Cipher **res); -int px_find_combo(const char *name, PX_Combo **res); - - returns 0 on success, < 0 on error. If successful, - *res contains pointer to new object. - -Message Digest -============== - -uint px_md_result_size(PX_MD *md) - - returns final result size in bytes - -void px_md_reset(PX_MD *md) - - resets md to clean state - -uint px_md_block_size(PX_MD *md) - - return algorithm block size in bytes - -void px_md_update(PX_MD *md, const uint8 *data, uint dlen) - - updates hash state with new data - -void px_md_finish(PX_MD *md, uint8 *buf) - - puts final hash state into buf. buf should have room - for px_md_result_size() bytes. - -void px_md_free(PX_MD *md) - - frees resources. - -HMAC (Hash Message Authentication Code) -======================================= - -int px_hmac_init(PX_HMAC *hmac, const uint8 *key, uint klen) - - initalized hmac state with key. - -uint px_hmac_result_size(PX_HMAC *md) - - returns final result size in bytes - -void px_hmac_reset(PX_HMAC *md) - - resets md to state after _init() - -uint px_hmac_block_size(PX_HMAC *md) - - return algorithm block size in bytes - -void px_hmac_update(PX_HMAC *md, const uint8 *data, uint dlen) - - updates hash state with new data - -void px_hmac_finish(PX_HMAC *md, uint8 *buf) - - puts final hash state into buf. buf should have room - for px_hmac_result_size() bytes. - -void px_hmac_free(PX_HMAC *md) - - frees resources. - - -Cipher -====== - -uint px_cipher_key_size(PX_Cipher *c) - - returns max key size in bytes - -uint px_cipher_block_size(PX_Cipher *c) - - returns cipher+mode block size in bytes. So blowfish - in CFB mode should return 1. - -uint px_cipher_iv_size(PX_Cipher *c) - - returns IV size in bytes. - -int px_cipher_init(PX_Cipher *c, uint8 *key, uint klen, uint8 *iv) - - initializes cipher with supplied key and iv. - -int px_cipher_encrypt(PX_Cipher *c, uint8 *data, uint dlen, uint8 *res) - - encrypts data. res must have room for dlen bytes. - data must be multiple of px_cipher_block_size(). - -int px_cipher_decrypt(PX_Cipher *c, uint8 *data, uint dlen, uint8 *res) - - decrypts data. res must have room for dlen bytes. - -void px_cipher_free(PX_Cipher *c) - - frees resources assiocated. - -PX_Combo -======== - -uint px_combo_encrypt_len(PX_Combo *c, uint dlen) - - calculates max result length for dlen of data. - -uint px_combo_decrypt_len(PX_Combo *c, uint dlen) - - calculates result length for dlen of data. - -int px_combo_init(PX_Combo *c, uint8 *key, uint klen, uint8 *iv, uint ivlen) - - initializes c with key and iv. If cipher uses fixed length keys, - key will be padded with zeroes to needed length. - -int px_combo_encrypt(PX_Combo *c, uint8 *data, uint dlen, uint8 *res, uint rlen) - -int px_combo_decrypt(PX_Combo *c, uint8 *data, uint dlen, uint8 *res, uint rlen) - -void px_combo_free(PX_Combo *c) - - frees resources assiocated. - diff --git a/contrib/pgcrypto/Makefile b/contrib/pgcrypto/Makefile deleted file mode 100644 index 823d4ff93c..0000000000 --- a/contrib/pgcrypto/Makefile +++ /dev/null @@ -1,84 +0,0 @@ -# -# $Header: /cvsroot/pgsql/contrib/pgcrypto/Makefile,v 1.9 2001/09/30 22:18:29 momjian Exp $ -# - -subdir = contrib/pgcrypto -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -# either 'builtin', 'mhash', 'openssl' -cryptolib = builtin - -# either 'builtin', 'system' -cryptsrc = builtin - -# Random source, preferred order: -# 'dev' - read from random device -# -# 'openssl' - use openssl PRNG. -# Note that currently pgcrypto does not do any -# entropy feeding to it -# This works ofcouse only with cryptolib = openssl -# -# 'silly' - use libc random() - very weak -random = silly -random_dev = \"/dev/urandom\" - -########################## - -ifeq ($(cryptolib), builtin) -CRYPTO_CFLAGS = -CRYPTO_LDFLAGS = -SRCS = md5.c sha1.c internal.c blf.c rijndael.c -endif - -ifeq ($(cryptolib), openssl) -CRYPTO_CFLAGS = -I/usr/include/openssl -CRYPTO_LDFLAGS = -lcrypto -SRCS = openssl.c -endif - -ifeq ($(cryptolib), mhash) -CRYPTO_CFLAGS = -I/usr/local/include -CRYPTO_LDFLAGS = -L/usr/local/lib -lmcrypt -lmhash -lltdl -SRCS = mhash.c -endif - -ifeq ($(cryptsrc), builtin) -SRCS += crypt-blowfish.c crypt-des.c crypt-md5.c -else -CRYPTO_CFLAGS += -DPX_SYSTEM_CRYPT -endif - -ifeq ($(random), dev) -CRYPTO_CFLAGS += -DRAND_DEV=$(random_dev) -endif -ifeq ($(random), openssl) -CRYPTO_CFLAGS += -DRAND_OPENSSL -endif -ifeq ($(random), silly) -CRYPTO_CFLAGS += -DRAND_SILLY -endif - -MODULE_big := pgcrypto -SRCS += pgcrypto.c px.c px-hmac.c px-crypt.c misc.c \ - crypt-gensalt.c random.c -OBJS := $(SRCS:.c=.o) -DOCS := README.pgcrypto -DATA_built := pgcrypto.sql -EXTRA_CLEAN := gen-rtab - -PG_CPPFLAGS := $(CRYPTO_CFLAGS) -I$(srcdir) -SHLIB_LINK := $(CRYPTO_LDFLAGS) - -REGRESS := init md5 sha1 hmac-md5 hmac-sha1 blowfish rijndael \ - crypt-des crypt-md5 crypt-blowfish crypt-xdes - -include $(top_srcdir)/contrib/contrib-global.mk - -rijndael.o: rijndael.tbl - -rijndael.tbl: - $(CC) $(CPPFLAGS) $(CFLAGS) -DPRINT_TABS rijndael.c -o gen-rtab - ./gen-rtab > rijndael.tbl - diff --git a/contrib/pgcrypto/README.pgcrypto b/contrib/pgcrypto/README.pgcrypto deleted file mode 100644 index 0480c4caff..0000000000 --- a/contrib/pgcrypto/README.pgcrypto +++ /dev/null @@ -1,219 +0,0 @@ - -pgcrypto 0.4 - cryptographic functions for PostgreSQL. -====================================================== -by Marko Kreen - - -INSTALLATION -============ - -Edit makefile, if you want to use any external library. - -NB! Default randomness source is libc random() function. This -is so only to get pgcrypto build everywhere. Randomness is -needed for gen_salt() function. So if you plan using it, you -should definitely change that by editing Makefile. You should -be using urandom device if your OS supports it, otherwise link -pgcrypto against OpenSSL library and use its PRNG. - -After editing Makefile: - -make -make install - -To run regression tests, install both PostgreSQL and pgcrypto -and then run - -make installcheck - -SQL FUNCTIONS -============= - - If any of arguments are NULL they return NULL. - -digest(data::bytea, type::text)::bytea - - Type is here the algorithm to use. E.g. 'md5', 'sha1', ... - Returns binary hash. - -digest_exists(type::text)::bool - - Returns BOOL whether given hash exists. - -hmac(data::bytea, key::bytea, type::text)::bytea - - Calculates Hashed MAC over data. type is the same as - in digest(). Returns binary hash. Similar to digest() - but noone can alter data and re-calculate hash without - knowing key. If the key is larger than hash blocksize - it will first hashed and the hash will be used as key. - - [ HMAC is described in RFC2104. ] - -hmac_exists(type::text)::bool - Returns BOOL. It is separate function because all hashes - cannot be used in HMAC. - -crypt(password::text, salt::text)::text - - Calculates UN*X crypt(3) style hash. Useful for storing - passwords. For generating salt you should use the - gen_salt() function. Usage: - - New password: - - UPDATE .. SET pswhash = crypt(new_psw, gen_salt('md5')); - - Authentication: - - SELECT pswhash = crypt(given_psw, pswhash) WHERE .. ; - - returns BOOL whether the given_psw is correct. DES crypt - has max key of 8 bytes, MD5 has max key at least 2^32-1 - bytes but may be larger on some platforms... - - Builtin crypt() supports DES, Extended DES, MD5 and Blowfish - (variant 2a) algorithms. - -gen_salt(type::text)::text - - Generates a new random salt for usage in crypt(). Type - - 'des' - Old UNIX, not recommended - 'md5' - md5-based crypt() - 'xdes' - 'Extended DES' - 'bf' - Blowfish-based, variant 2a - - When you use --enable-system-crypt then note that system - libcrypt may not support them all. - -gen_salt(type::text, rounds::int4)::text - - same as above, but lets user specify iteration count - for algorithm. Number is algotithm specific: - - type default min max - --------------------------------- - xdes 725 1 16777215 - bf 6 4 31 - - In case of xdes there is a additional limitation that the - count must be a odd number. - - The higher the count, the more time it takes to calculate - crypt and therefore the more time to break it. But beware! - With too high count it takes a _very_long_ time to - calculate it. - - For maximum security, you should choose the 'bf' crypt - and use maximum number of rounds you can still tolerate. - -encrypt(data::bytea, key::bytea, type::text)::bytea -decrypt(data::bytea, key::bytea, type::text)::bytea -encrypt_iv(data::bytea, key::bytea, iv::bytea, type::text)::bytea -decrypt_iv(data::bytea, key::bytea, iv::bytea, type::text)::bytea - - Encrypt/decrypt data with cipher, padding data if needed. - - Pseudo-noteup: - - algo ['-' mode] ['/pad:' padding] - - Supported algorithms: - - bf - Blowfish - aes, rijndael - Rijndael-128 - - Others depend on library and are not tested enough, so - play on your own risk. - - Modes: 'cbc' (default), 'ecb'. Again, library may support - more. - - Padding is 'pkcs' (default), 'none'. 'none' is mostly for - testing ciphers, you should not need it. - - So, example: - - encrypt(data, 'fooz', 'bf') - - is equal to - - encrypt(data, 'fooz', 'bf-cbc/pad:pkcs') - - IV is initial value for mode, defaults to all zeroes. - It is ignored for ECB. It is clipped or padded with zeroes - if not exactly block size. - - -ALGORITHMS -========== - -The standard functionality at the moment consist of - -Hashes: md5, sha1 -Ciphers: bf, aes -Modes: cbc, ecb - -TODO: write stardard names for optional ciphers too. - -LIBRARIES -========= - -* crypt() - - internal: des, xdes, md5, bf - - -lcrypt: ??? (whatever you have) - -* other: - -[ This only list of stuff libraries claim to support. So - pgcrypto may work with all of them. But ATM tested aree only the - standard ciphers. On others pgcrypto and library may mess something - up. You have been warned. ] - -internal (default): - Hashes: MD5, SHA1 - Ciphers: Blowfish, Rijndael-128 - - -OpenSSL (0.9.6): - Hashes: MD5, SHA1, RIPEMD160, MD2 - Ciphers: DES, DESX, DES3, RC5, RC4, RC2, IDEA, - Blowfish, CAST5 - License: BSD-like with strong advertisement - Url: http://www.openssl.org/ - - -mhash (0.8.9) + mcrypt (2.4.16): - Hashes: MD5, SHA1, CRC32, CRC32B, GOST, TIGER, RIPEMD160, - HAVAL(256,224,192,160,128) - Ciphers: DES, DES3, CAST-128(CAST5), CAST-256, xTEA, 3-way, - SKIPJACK, Blowfish, Twofish, LOKI97, RC2, RC4, RC6, - Rijndael-128/192/256, MARS, PANAMA, WAKE, Serpent, IDEA, GOST, - SAFER, SAFER+, Enigma - License: LGPL - Url: http://mcrypt.sourceforge.org/ - Url: http://mhash.sourceforge.org/ - -CREDITS -======= - -I have used code from following sources: - -DES crypt() by David Burren and others FreeBSD libcrypt -MD5 crypt() by Poul-Henning Kamp FreeBSD libcrypt -Blowfish crypt() by Solar Designer www.openwall.com -Blowfish cipher by Niels Provos OpenBSD sys/crypto -Rijndael cipher by Brian Gladman OpenBSD sys/crypto -MD5 and SHA1 by WIDE Project KAME kame/sys/crypto - -LEGALESE -======== - -* I owe a beer to Poul-Henning. - -* This product includes software developed by Niels Provos. - - diff --git a/contrib/pgcrypto/blf.c b/contrib/pgcrypto/blf.c deleted file mode 100644 index da2047b6cf..0000000000 --- a/contrib/pgcrypto/blf.c +++ /dev/null @@ -1,693 +0,0 @@ -/* $OpenBSD: blf.c,v 1.3 2000/06/17 23:36:22 provos Exp $ */ - -/* - * Blowfish block cipher for OpenBSD - * Copyright 1997 Niels Provos - * All rights reserved. - * - * Implementation advice by David Mazieres . - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Niels Provos. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This code is derived from section 14.3 and the given source - * in section V of Applied Cryptography, second edition. - * Blowfish is an unpatented fast block cipher designed by - * Bruce Schneier. - */ - -#include -#include "px.h" - -#include "blf.h" - -/* Function for Feistel Networks */ - -#define F(s, x) ((((s)[ (((x)>>24)&0xFF)] \ - + (s)[0x100 + (((x)>>16)&0xFF)]) \ - ^ (s)[0x200 + (((x)>> 8)&0xFF)]) \ - + (s)[0x300 + ( (x) &0xFF)]) - -#define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n]) - -void -Blowfish_encipher(blf_ctx * c, uint32 *x) -{ - uint32 Xl; - uint32 Xr; - uint32 *s = c->S[0]; - uint32 *p = c->P; - - Xl = x[0]; - Xr = x[1]; - - Xl ^= p[0]; - BLFRND(s, p, Xr, Xl, 1); - BLFRND(s, p, Xl, Xr, 2); - BLFRND(s, p, Xr, Xl, 3); - BLFRND(s, p, Xl, Xr, 4); - BLFRND(s, p, Xr, Xl, 5); - BLFRND(s, p, Xl, Xr, 6); - BLFRND(s, p, Xr, Xl, 7); - BLFRND(s, p, Xl, Xr, 8); - BLFRND(s, p, Xr, Xl, 9); - BLFRND(s, p, Xl, Xr, 10); - BLFRND(s, p, Xr, Xl, 11); - BLFRND(s, p, Xl, Xr, 12); - BLFRND(s, p, Xr, Xl, 13); - BLFRND(s, p, Xl, Xr, 14); - BLFRND(s, p, Xr, Xl, 15); - BLFRND(s, p, Xl, Xr, 16); - - x[0] = Xr ^ p[17]; - x[1] = Xl; -} - -void -Blowfish_decipher(blf_ctx * c, uint32 *x) -{ - uint32 Xl; - uint32 Xr; - uint32 *s = c->S[0]; - uint32 *p = c->P; - - Xl = x[0]; - Xr = x[1]; - - Xl ^= p[17]; - BLFRND(s, p, Xr, Xl, 16); - BLFRND(s, p, Xl, Xr, 15); - BLFRND(s, p, Xr, Xl, 14); - BLFRND(s, p, Xl, Xr, 13); - BLFRND(s, p, Xr, Xl, 12); - BLFRND(s, p, Xl, Xr, 11); - BLFRND(s, p, Xr, Xl, 10); - BLFRND(s, p, Xl, Xr, 9); - BLFRND(s, p, Xr, Xl, 8); - BLFRND(s, p, Xl, Xr, 7); - BLFRND(s, p, Xr, Xl, 6); - BLFRND(s, p, Xl, Xr, 5); - BLFRND(s, p, Xr, Xl, 4); - BLFRND(s, p, Xl, Xr, 3); - BLFRND(s, p, Xr, Xl, 2); - BLFRND(s, p, Xl, Xr, 1); - - x[0] = Xr ^ p[0]; - x[1] = Xl; -} - -void -Blowfish_initstate(blf_ctx * c) -{ - -/* P-box and S-box tables initialized with digits of Pi */ - - const blf_ctx initstate = - - {{ - { - 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, - 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, - 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, - 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, - 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, - 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, - 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, - 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, - 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, - 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, - 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, - 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, - 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, - 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, - 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, - 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, - 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, - 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, - 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, - 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, - 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, - 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, - 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, - 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, - 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, - 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, - 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, - 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, - 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, - 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, - 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, - 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, - 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, - 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, - 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, - 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, - 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, - 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, - 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, - 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, - 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, - 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, - 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, - 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, - 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, - 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, - 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, - 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, - 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, - 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, - 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, - 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, - 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, - 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, - 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, - 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, - 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, - 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, - 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, - 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, - 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, - 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, - 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, - 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a}, - { - 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, - 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, - 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, - 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, - 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, - 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, - 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, - 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, - 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, - 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, - 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, - 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, - 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, - 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, - 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, - 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, - 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, - 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, - 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, - 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, - 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, - 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, - 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, - 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, - 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, - 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, - 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, - 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, - 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, - 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, - 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, - 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, - 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, - 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, - 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, - 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, - 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, - 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, - 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, - 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, - 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, - 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, - 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, - 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, - 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, - 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, - 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, - 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, - 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, - 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, - 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, - 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, - 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, - 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, - 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, - 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, - 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, - 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, - 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, - 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, - 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, - 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, - 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, - 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7}, - { - 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, - 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, - 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, - 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, - 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, - 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, - 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, - 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, - 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, - 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, - 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, - 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, - 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, - 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, - 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, - 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, - 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, - 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, - 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, - 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, - 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, - 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, - 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, - 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, - 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, - 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, - 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, - 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, - 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, - 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, - 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, - 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, - 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, - 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, - 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, - 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, - 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, - 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, - 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, - 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, - 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, - 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, - 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, - 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, - 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, - 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, - 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, - 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, - 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, - 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, - 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, - 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, - 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, - 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, - 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, - 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, - 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, - 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, - 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, - 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, - 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, - 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, - 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, - 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0}, - { - 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, - 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, - 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, - 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, - 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, - 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, - 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, - 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, - 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, - 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, - 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, - 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, - 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, - 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, - 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, - 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, - 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, - 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, - 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, - 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, - 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, - 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, - 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, - 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, - 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, - 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, - 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, - 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, - 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, - 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, - 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, - 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, - 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, - 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, - 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, - 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, - 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, - 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, - 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, - 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, - 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, - 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, - 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, - 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, - 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, - 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, - 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, - 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, - 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, - 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, - 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, - 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, - 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, - 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, - 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, - 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, - 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, - 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, - 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, - 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, - 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, - 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, - 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, - 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6} - }, - { - 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, - 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, - 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, - 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, - 0x9216d5d9, 0x8979fb1b - }}; - - *c = initstate; - -} - -uint32 -Blowfish_stream2word(const uint8 *data, uint16 databytes, uint16 *current) -{ - uint8 i; - uint16 j; - uint32 temp; - - temp = 0x00000000; - j = *current; - - for (i = 0; i < 4; i++, j++) - { - if (j >= databytes) - j = 0; - temp = (temp << 8) | data[j]; - } - - *current = j; - return temp; -} - -void -Blowfish_expand0state(blf_ctx * c, const uint8 *key, uint16 keybytes) -{ - uint16 i; - uint16 j; - uint16 k; - uint32 temp; - uint32 data[2]; - - j = 0; - for (i = 0; i < BLF_N + 2; i++) - { - /* Extract 4 int8 to 1 int32 from keystream */ - temp = Blowfish_stream2word(key, keybytes, &j); - c->P[i] = c->P[i] ^ temp; - } - - j = 0; - data[0] = 0x00000000; - data[1] = 0x00000000; - for (i = 0; i < BLF_N + 2; i += 2) - { - Blowfish_encipher(c, data); - - c->P[i] = data[0]; - c->P[i + 1] = data[1]; - } - - for (i = 0; i < 4; i++) - { - for (k = 0; k < 256; k += 2) - { - Blowfish_encipher(c, data); - - c->S[i][k] = data[0]; - c->S[i][k + 1] = data[1]; - } - } -} - - -void -Blowfish_expandstate(blf_ctx * c, const uint8 *data, uint16 databytes, - const uint8 *key, uint16 keybytes) -{ - uint16 i; - uint16 j; - uint16 k; - uint32 temp; - uint32 d[2]; - - j = 0; - for (i = 0; i < BLF_N + 2; i++) - { - /* Extract 4 int8 to 1 int32 from keystream */ - temp = Blowfish_stream2word(key, keybytes, &j); - c->P[i] = c->P[i] ^ temp; - } - - j = 0; - d[0] = 0x00000000; - d[1] = 0x00000000; - for (i = 0; i < BLF_N + 2; i += 2) - { - d[0] ^= Blowfish_stream2word(data, databytes, &j); - d[1] ^= Blowfish_stream2word(data, databytes, &j); - Blowfish_encipher(c, d); - - c->P[i] = d[0]; - c->P[i + 1] = d[1]; - } - - for (i = 0; i < 4; i++) - { - for (k = 0; k < 256; k += 2) - { - d[0] ^= Blowfish_stream2word(data, databytes, &j); - d[1] ^= Blowfish_stream2word(data, databytes, &j); - Blowfish_encipher(c, d); - - c->S[i][k] = d[0]; - c->S[i][k + 1] = d[1]; - } - } - -} - -void -blf_key(blf_ctx * c, const uint8 *k, uint16 len) -{ - /* Initalize S-boxes and subkeys with Pi */ - Blowfish_initstate(c); - - /* Transform S-boxes and subkeys with key */ - Blowfish_expand0state(c, k, len); -} - -void -blf_enc(blf_ctx * c, uint32 *data, uint16 blocks) -{ - uint32 *d; - uint16 i; - - d = data; - for (i = 0; i < blocks; i++) - { - Blowfish_encipher(c, d); - d += 2; - } -} - -void -blf_dec(blf_ctx * c, uint32 *data, uint16 blocks) -{ - uint32 *d; - uint16 i; - - d = data; - for (i = 0; i < blocks; i++) - { - Blowfish_decipher(c, d); - d += 2; - } -} - -void -blf_ecb_encrypt(blf_ctx * c, uint8 *data, uint32 len) -{ - uint32 l, - r, - d[2]; - uint32 i; - - for (i = 0; i < len; i += 8) - { - l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; - r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; - d[0] = l; - d[1] = r; - Blowfish_encipher(c, d); - l = d[0]; - r = d[1]; - data[0] = l >> 24 & 0xff; - data[1] = l >> 16 & 0xff; - data[2] = l >> 8 & 0xff; - data[3] = l & 0xff; - data[4] = r >> 24 & 0xff; - data[5] = r >> 16 & 0xff; - data[6] = r >> 8 & 0xff; - data[7] = r & 0xff; - data += 8; - } -} - -void -blf_ecb_decrypt(blf_ctx * c, uint8 *data, uint32 len) -{ - uint32 l, - r, - d[2]; - uint32 i; - - for (i = 0; i < len; i += 8) - { - l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; - r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; - d[0] = l; - d[1] = r; - Blowfish_decipher(c, d); - l = d[0]; - r = d[1]; - data[0] = l >> 24 & 0xff; - data[1] = l >> 16 & 0xff; - data[2] = l >> 8 & 0xff; - data[3] = l & 0xff; - data[4] = r >> 24 & 0xff; - data[5] = r >> 16 & 0xff; - data[6] = r >> 8 & 0xff; - data[7] = r & 0xff; - data += 8; - } -} - -void -blf_cbc_encrypt(blf_ctx * c, uint8 *iv, uint8 *data, uint32 len) -{ - uint32 l, - r, - d[2]; - uint32 i, - j; - - for (i = 0; i < len; i += 8) - { - for (j = 0; j < 8; j++) - data[j] ^= iv[j]; - l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; - r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; - d[0] = l; - d[1] = r; - Blowfish_encipher(c, d); - l = d[0]; - r = d[1]; - data[0] = l >> 24 & 0xff; - data[1] = l >> 16 & 0xff; - data[2] = l >> 8 & 0xff; - data[3] = l & 0xff; - data[4] = r >> 24 & 0xff; - data[5] = r >> 16 & 0xff; - data[6] = r >> 8 & 0xff; - data[7] = r & 0xff; - iv = data; - data += 8; - } -} - -void -blf_cbc_decrypt(blf_ctx * c, uint8 *iva, uint8 *data, uint32 len) -{ - uint32 l, - r, - d[2]; - uint8 *iv; - uint32 i, - j; - - iv = data + len - 16; - data = data + len - 8; - for (i = len - 8; i >= 8; i -= 8) - { - l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; - r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; - d[0] = l; - d[1] = r; - Blowfish_decipher(c, d); - l = d[0]; - r = d[1]; - data[0] = l >> 24 & 0xff; - data[1] = l >> 16 & 0xff; - data[2] = l >> 8 & 0xff; - data[3] = l & 0xff; - data[4] = r >> 24 & 0xff; - data[5] = r >> 16 & 0xff; - data[6] = r >> 8 & 0xff; - data[7] = r & 0xff; - for (j = 0; j < 8; j++) - data[j] ^= iv[j]; - iv -= 8; - data -= 8; - } - l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]; - r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7]; - d[0] = l; - d[1] = r; - Blowfish_decipher(c, d); - l = d[0]; - r = d[1]; - data[0] = l >> 24 & 0xff; - data[1] = l >> 16 & 0xff; - data[2] = l >> 8 & 0xff; - data[3] = l & 0xff; - data[4] = r >> 24 & 0xff; - data[5] = r >> 16 & 0xff; - data[6] = r >> 8 & 0xff; - data[7] = r & 0xff; - for (j = 0; j < 8; j++) - data[j] ^= iva[j]; -} diff --git a/contrib/pgcrypto/blf.h b/contrib/pgcrypto/blf.h deleted file mode 100644 index 81159b13be..0000000000 --- a/contrib/pgcrypto/blf.h +++ /dev/null @@ -1,83 +0,0 @@ -/* $OpenBSD: blf.h,v 1.3 2001/05/15 02:40:35 deraadt Exp $ */ - -/* - * Blowfish - a fast block cipher designed by Bruce Schneier - * - * Copyright 1997 Niels Provos - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Niels Provos. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _BLF_H_ -#define _BLF_H_ - -/* Schneier states the maximum key length to be 56 bytes. - * The way how the subkeys are initalized by the key up - * to (N+2)*4 i.e. 72 bytes are utilized. - * Warning: For normal blowfish encryption only 56 bytes - * of the key affect all cipherbits. - */ - -#define BLF_N 16 /* Number of Subkeys */ -#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */ - -/* Blowfish context */ -typedef struct BlowfishContext -{ - uint32 S[4][256]; /* S-Boxes */ - uint32 P[BLF_N + 2]; /* Subkeys */ -} blf_ctx; - -/* Raw access to customized Blowfish - * blf_key is just: - * Blowfish_initstate( state ) - * Blowfish_expand0state( state, key, keylen ) - */ - -void Blowfish_encipher(blf_ctx *, uint32 *); -void Blowfish_decipher(blf_ctx *, uint32 *); -void Blowfish_initstate(blf_ctx *); -void Blowfish_expand0state(blf_ctx *, const uint8 *, uint16); -void Blowfish_expandstate - (blf_ctx *, const uint8 *, uint16, const uint8 *, uint16); - -/* Standard Blowfish */ - -void blf_key(blf_ctx *, const uint8 *, uint16); -void blf_enc(blf_ctx *, uint32 *, uint16); -void blf_dec(blf_ctx *, uint32 *, uint16); - -/* Converts uint8 to uint32 */ -uint32 Blowfish_stream2word(const uint8 *, uint16, uint16 *); - -void blf_ecb_encrypt(blf_ctx *, uint8 *, uint32); -void blf_ecb_decrypt(blf_ctx *, uint8 *, uint32); - -void blf_cbc_encrypt(blf_ctx *, uint8 *, uint8 *, uint32); -void blf_cbc_decrypt(blf_ctx *, uint8 *, uint8 *, uint32); - -#endif diff --git a/contrib/pgcrypto/crypt-blowfish.c b/contrib/pgcrypto/crypt-blowfish.c deleted file mode 100644 index 8e41771be9..0000000000 --- a/contrib/pgcrypto/crypt-blowfish.c +++ /dev/null @@ -1,740 +0,0 @@ -/* - * This code comes from John the Ripper password cracker, with reentrant - * and crypt(3) interfaces added, but optimizations specific to password - * cracking removed. - * - * Written by Solar Designer in 1998-2001, and placed - * in the public domain. - * - * There's absolutely no warranty. - * - * It is my intent that you should be able to use this on your system, - * as a part of a software package, or anywhere else to improve security, - * ensure compatibility, or for any other purpose. I would appreciate - * it if you give credit where it is due and keep your modifications in - * the public domain as well, but I don't require that in order to let - * you place this code and any modifications you make under a license - * of your choice. - * - * This implementation is compatible with OpenBSD bcrypt.c (version 2a) - * by Niels Provos , and uses some of his - * ideas. The password hashing algorithm was designed by David Mazieres - * . - * - * There's a paper on the algorithm that explains its design decisions: - * - * http://www.usenix.org/events/usenix99/provos.html - * - * Some of the tricks in BF_ROUND might be inspired by Eric Young's - * Blowfish library (I can't be sure if I would think of something if I - * hadn't seen his code). - */ - -#include "postgres.h" - -#include "px.h" -#include "px-crypt.h" - -#define __set_errno(v) - -#ifndef __set_errno -#define __set_errno(val) errno = (val) -#endif - -#ifdef __i386__ -#define BF_ASM 0 /* 1 */ -#define BF_SCALE 1 -#elif defined(__alpha__) -#define BF_ASM 0 -#define BF_SCALE 1 -#else -#define BF_ASM 0 -#define BF_SCALE 0 -#endif - -typedef unsigned int BF_word; - -/* Number of Blowfish rounds, this is also hardcoded into a few places */ -#define BF_N 16 - -typedef BF_word BF_key[BF_N + 2]; - -typedef struct -{ - BF_word S[4][0x100]; - BF_key P; -} BF_ctx; - -/* - * Magic IV for 64 Blowfish encryptions that we do at the end. - * The string is "OrpheanBeholderScryDoubt" on big-endian. - */ -static BF_word BF_magic_w[6] = { - 0x4F727068, 0x65616E42, 0x65686F6C, - 0x64657253, 0x63727944, 0x6F756274 -}; - -/* - * P-box and S-box tables initialized with digits of Pi. - */ -static BF_ctx BF_init_state = { - { - { - 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, - 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, - 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, - 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, - 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, - 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, - 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, - 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, - 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, - 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, - 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, - 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, - 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, - 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, - 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, - 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, - 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, - 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, - 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, - 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, - 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, - 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, - 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, - 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, - 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, - 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, - 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, - 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, - 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, - 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, - 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, - 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, - 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, - 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, - 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, - 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, - 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, - 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, - 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, - 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, - 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, - 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, - 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, - 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, - 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, - 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, - 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, - 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, - 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, - 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, - 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, - 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, - 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, - 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, - 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, - 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, - 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, - 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, - 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, - 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, - 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, - 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, - 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, - 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a - }, { - 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, - 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, - 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, - 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, - 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, - 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, - 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, - 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, - 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, - 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, - 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, - 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, - 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, - 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, - 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, - 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, - 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, - 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, - 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, - 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, - 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, - 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, - 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, - 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, - 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, - 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, - 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, - 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, - 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, - 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, - 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, - 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, - 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, - 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, - 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, - 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, - 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, - 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, - 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, - 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, - 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, - 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, - 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, - 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, - 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, - 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, - 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, - 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, - 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, - 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, - 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, - 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, - 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, - 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, - 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, - 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, - 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, - 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, - 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, - 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, - 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, - 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, - 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, - 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 - }, { - 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, - 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, - 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, - 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, - 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, - 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, - 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, - 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, - 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, - 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, - 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, - 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, - 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, - 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, - 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, - 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, - 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, - 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, - 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, - 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, - 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, - 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, - 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, - 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, - 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, - 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, - 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, - 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, - 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, - 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, - 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, - 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, - 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, - 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, - 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, - 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, - 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, - 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, - 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, - 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, - 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, - 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, - 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, - 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, - 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, - 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, - 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, - 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, - 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, - 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, - 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, - 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, - 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, - 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, - 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, - 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, - 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, - 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, - 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, - 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, - 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, - 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, - 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, - 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 - }, { - 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, - 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, - 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, - 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, - 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, - 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, - 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, - 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, - 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, - 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, - 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, - 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, - 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, - 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, - 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, - 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, - 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, - 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, - 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, - 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, - 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, - 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, - 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, - 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, - 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, - 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, - 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, - 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, - 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, - 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, - 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, - 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, - 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, - 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, - 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, - 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, - 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, - 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, - 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, - 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, - 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, - 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, - 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, - 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, - 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, - 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, - 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, - 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, - 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, - 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, - 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, - 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, - 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, - 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, - 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, - 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, - 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, - 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, - 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, - 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, - 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, - 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, - 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, - 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 - } - }, { - 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, - 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, - 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, - 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, - 0x9216d5d9, 0x8979fb1b - } -}; - -static unsigned char BF_itoa64[64 + 1] = -"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - -static unsigned char BF_atoi64[0x60] = { - 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, - 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, - 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 -}; - -#define BF_safe_atoi64(dst, src) \ -do { \ - tmp = (unsigned char)(src); \ - if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ - tmp = BF_atoi64[tmp]; \ - if (tmp > 63) return -1; \ - (dst) = tmp; \ -} while (0) - -static int -BF_decode(BF_word * dst, const char *src, int size) -{ - unsigned char *dptr = (unsigned char *) dst; - unsigned char *end = dptr + size; - unsigned char *sptr = (unsigned char *) src; - unsigned int tmp, - c1, - c2, - c3, - c4; - - do - { - BF_safe_atoi64(c1, *sptr++); - BF_safe_atoi64(c2, *sptr++); - *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); - if (dptr >= end) - break; - - BF_safe_atoi64(c3, *sptr++); - *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); - if (dptr >= end) - break; - - BF_safe_atoi64(c4, *sptr++); - *dptr++ = ((c3 & 0x03) << 6) | c4; - } while (dptr < end); - - return 0; -} - -static void -BF_encode(char *dst, const BF_word * src, int size) -{ - unsigned char *sptr = (unsigned char *) src; - unsigned char *end = sptr + size; - unsigned char *dptr = (unsigned char *) dst; - unsigned int c1, - c2; - - do - { - c1 = *sptr++; - *dptr++ = BF_itoa64[c1 >> 2]; - c1 = (c1 & 0x03) << 4; - if (sptr >= end) - { - *dptr++ = BF_itoa64[c1]; - break; - } - - c2 = *sptr++; - c1 |= c2 >> 4; - *dptr++ = BF_itoa64[c1]; - c1 = (c2 & 0x0f) << 2; - if (sptr >= end) - { - *dptr++ = BF_itoa64[c1]; - break; - } - - c2 = *sptr++; - c1 |= c2 >> 6; - *dptr++ = BF_itoa64[c1]; - *dptr++ = BF_itoa64[c2 & 0x3f]; - } while (sptr < end); -} - -static void -BF_swap(BF_word * x, int count) -{ - static int endianness_check = 1; - char *is_little_endian = (char *) &endianness_check; - BF_word tmp; - - if (*is_little_endian) - do - { - tmp = *x; - tmp = (tmp << 16) | (tmp >> 16); - *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); - } while (--count); -} - -#if BF_SCALE -/* Architectures which can shift addresses left by 2 bits with no extra cost */ -#define BF_ROUND(L, R, N) \ - tmp1 = L & 0xFF; \ - tmp2 = L >> 8; \ - tmp2 &= 0xFF; \ - tmp3 = L >> 16; \ - tmp3 &= 0xFF; \ - tmp4 = L >> 24; \ - tmp1 = data.ctx.S[3][tmp1]; \ - tmp2 = data.ctx.S[2][tmp2]; \ - tmp3 = data.ctx.S[1][tmp3]; \ - tmp3 += data.ctx.S[0][tmp4]; \ - tmp3 ^= tmp2; \ - R ^= data.ctx.P[N + 1]; \ - tmp3 += tmp1; \ - R ^= tmp3; -#else -/* Architectures with no complicated addressing modes supported */ -#define BF_INDEX(S, i) \ - (*((BF_word *)(((unsigned char *)S) + (i)))) -#define BF_ROUND(L, R, N) \ - tmp1 = L & 0xFF; \ - tmp1 <<= 2; \ - tmp2 = L >> 6; \ - tmp2 &= 0x3FC; \ - tmp3 = L >> 14; \ - tmp3 &= 0x3FC; \ - tmp4 = L >> 22; \ - tmp4 &= 0x3FC; \ - tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \ - tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \ - tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \ - tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \ - tmp3 ^= tmp2; \ - R ^= data.ctx.P[N + 1]; \ - tmp3 += tmp1; \ - R ^= tmp3; -#endif - -/* - * Encrypt one block, BF_N is hardcoded here. - */ -#define BF_ENCRYPT \ - L ^= data.ctx.P[0]; \ - BF_ROUND(L, R, 0); \ - BF_ROUND(R, L, 1); \ - BF_ROUND(L, R, 2); \ - BF_ROUND(R, L, 3); \ - BF_ROUND(L, R, 4); \ - BF_ROUND(R, L, 5); \ - BF_ROUND(L, R, 6); \ - BF_ROUND(R, L, 7); \ - BF_ROUND(L, R, 8); \ - BF_ROUND(R, L, 9); \ - BF_ROUND(L, R, 10); \ - BF_ROUND(R, L, 11); \ - BF_ROUND(L, R, 12); \ - BF_ROUND(R, L, 13); \ - BF_ROUND(L, R, 14); \ - BF_ROUND(R, L, 15); \ - tmp4 = R; \ - R = L; \ - L = tmp4 ^ data.ctx.P[BF_N + 1]; - -#if BF_ASM - -extern void _BF_body_r(BF_ctx * ctx); - -#define BF_body() \ - _BF_body_r(&data.ctx); - -#else - -#define BF_body() \ - L = R = 0; \ - ptr = data.ctx.P; \ - do { \ - ptr += 2; \ - BF_ENCRYPT; \ - *(ptr - 2) = L; \ - *(ptr - 1) = R; \ - } while (ptr < &data.ctx.P[BF_N + 2]); \ -\ - ptr = data.ctx.S[0]; \ - do { \ - ptr += 2; \ - BF_ENCRYPT; \ - *(ptr - 2) = L; \ - *(ptr - 1) = R; \ - } while (ptr < &data.ctx.S[3][0xFF]); -#endif - -static void -BF_set_key(const char *key, BF_key expanded, BF_key initial) -{ - const char *ptr = key; - int i, - j; - BF_word tmp; - - for (i = 0; i < BF_N + 2; i++) - { - tmp = 0; - for (j = 0; j < 4; j++) - { - tmp <<= 8; - tmp |= *ptr; - - if (!*ptr) - ptr = key; - else - ptr++; - } - - expanded[i] = tmp; - initial[i] = BF_init_state.P[i] ^ tmp; - } -} - -char * -_crypt_blowfish_rn(const char *key, const char *setting, - char *output, int size) -{ - struct - { - BF_ctx ctx; - BF_key expanded_key; - union - { - BF_word salt[4]; - BF_word output[6]; - } binary; - } data; - BF_word L, - R; - BF_word tmp1, - tmp2, - tmp3, - tmp4; - BF_word *ptr; - BF_word count; - int i; - - if (size < 7 + 22 + 31 + 1) - { - __set_errno(ERANGE); - return NULL; - } - - if (setting[0] != '$' || - setting[1] != '2' || - setting[2] != 'a' || - setting[3] != '$' || - setting[4] < '0' || setting[4] > '3' || - setting[5] < '0' || setting[5] > '9' || - setting[6] != '$') - { - __set_errno(EINVAL); - return NULL; - } - - count = (BF_word) 1 << ((setting[4] - '0') * 10 + (setting[5] - '0')); - if (count < 16 || BF_decode(data.binary.salt, &setting[7], 16)) - { - memset(data.binary.salt, 0, sizeof(data.binary.salt)); - __set_errno(EINVAL); - return NULL; - } - BF_swap(data.binary.salt, 4); - - BF_set_key(key, data.expanded_key, data.ctx.P); - - memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S)); - - L = R = 0; - for (i = 0; i < BF_N + 2; i += 2) - { - L ^= data.binary.salt[i & 2]; - R ^= data.binary.salt[(i & 2) + 1]; - BF_ENCRYPT; - data.ctx.P[i] = L; - data.ctx.P[i + 1] = R; - } - - ptr = data.ctx.S[0]; - do - { - ptr += 4; - L ^= data.binary.salt[(BF_N + 2) & 3]; - R ^= data.binary.salt[(BF_N + 3) & 3]; - BF_ENCRYPT; - *(ptr - 4) = L; - *(ptr - 3) = R; - - L ^= data.binary.salt[(BF_N + 4) & 3]; - R ^= data.binary.salt[(BF_N + 5) & 3]; - BF_ENCRYPT; - *(ptr - 2) = L; - *(ptr - 1) = R; - } while (ptr < &data.ctx.S[3][0xFF]); - - do - { - data.ctx.P[0] ^= data.expanded_key[0]; - data.ctx.P[1] ^= data.expanded_key[1]; - data.ctx.P[2] ^= data.expanded_key[2]; - data.ctx.P[3] ^= data.expanded_key[3]; - data.ctx.P[4] ^= data.expanded_key[4]; - data.ctx.P[5] ^= data.expanded_key[5]; - data.ctx.P[6] ^= data.expanded_key[6]; - data.ctx.P[7] ^= data.expanded_key[7]; - data.ctx.P[8] ^= data.expanded_key[8]; - data.ctx.P[9] ^= data.expanded_key[9]; - data.ctx.P[10] ^= data.expanded_key[10]; - data.ctx.P[11] ^= data.expanded_key[11]; - data.ctx.P[12] ^= data.expanded_key[12]; - data.ctx.P[13] ^= data.expanded_key[13]; - data.ctx.P[14] ^= data.expanded_key[14]; - data.ctx.P[15] ^= data.expanded_key[15]; - data.ctx.P[16] ^= data.expanded_key[16]; - data.ctx.P[17] ^= data.expanded_key[17]; - - BF_body(); - - tmp1 = data.binary.salt[0]; - tmp2 = data.binary.salt[1]; - tmp3 = data.binary.salt[2]; - tmp4 = data.binary.salt[3]; - data.ctx.P[0] ^= tmp1; - data.ctx.P[1] ^= tmp2; - data.ctx.P[2] ^= tmp3; - data.ctx.P[3] ^= tmp4; - data.ctx.P[4] ^= tmp1; - data.ctx.P[5] ^= tmp2; - data.ctx.P[6] ^= tmp3; - data.ctx.P[7] ^= tmp4; - data.ctx.P[8] ^= tmp1; - data.ctx.P[9] ^= tmp2; - data.ctx.P[10] ^= tmp3; - data.ctx.P[11] ^= tmp4; - data.ctx.P[12] ^= tmp1; - data.ctx.P[13] ^= tmp2; - data.ctx.P[14] ^= tmp3; - data.ctx.P[15] ^= tmp4; - data.ctx.P[16] ^= tmp1; - data.ctx.P[17] ^= tmp2; - - BF_body(); - } while (--count); - - for (i = 0; i < 6; i += 2) - { - L = BF_magic_w[i]; - R = BF_magic_w[i + 1]; - - count = 64; - do - { - BF_ENCRYPT; - } while (--count); - - data.binary.output[i] = L; - data.binary.output[i + 1] = R; - } - - memcpy(output, setting, 7 + 22 - 1); - output[7 + 22 - 1] = BF_itoa64[(int) - BF_atoi64[(int) setting[7 + 22 - 1] - 0x20] & 0x30]; - -/* This has to be bug-compatible with the original implementation, so - * only encode 23 of the 24 bytes. :-) */ - BF_swap(data.binary.output, 6); - BF_encode(&output[7 + 22], data.binary.output, 23); - output[7 + 22 + 31] = '\0'; - -/* Overwrite the most obvious sensitive data we have on the stack. Note - * that this does not guarantee there's no sensitive data left on the - * stack and/or in registers; I'm not aware of portable code that does. */ - memset(&data, 0, sizeof(data)); - - return output; -} diff --git a/contrib/pgcrypto/crypt-des.c b/contrib/pgcrypto/crypt-des.c deleted file mode 100644 index cadbcfd182..0000000000 --- a/contrib/pgcrypto/crypt-des.c +++ /dev/null @@ -1,768 +0,0 @@ -/* - * FreeSec: libcrypt for NetBSD - * - * Copyright (c) 1994 David Burren - * All rights reserved. - * - * Adapted for FreeBSD-2.0 by Geoffrey M. Rehmet - * this file should now *only* export crypt(), in order to make - * binaries of libcrypt exportable from the USA - * - * Adapted for FreeBSD-4.0 by Mark R V Murray - * this file should now *only* export crypt_des(), in order to make - * a module that can be optionally included in libcrypt. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the names of other contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD: src/secure/lib/libcrypt/crypt-des.c,v 1.12 1999/09/20 12:39:20 markm Exp $ - * - * This is an original implementation of the DES and the crypt(3) interfaces - * by David Burren . - * - * An excellent reference on the underlying algorithm (and related - * algorithms) is: - * - * B. Schneier, Applied Cryptography: protocols, algorithms, - * and source code in C, John Wiley & Sons, 1994. - * - * Note that in that book's description of DES the lookups for the initial, - * pbox, and final permutations are inverted (this has been brought to the - * attention of the author). A list of errata for this book has been - * posted to the sci.crypt newsgroup by the author and is available for FTP. - * - * ARCHITECTURE ASSUMPTIONS: - * It is assumed that the 8-byte arrays passed by reference can be - * addressed as arrays of uint32's (ie. the CPU is not picky about - * alignment). - */ - -#include "postgres.h" - -#include "px.h" -#include "px-crypt.h" - -/* for ntohl/htonl */ -#include - -#define _PASSWORD_EFMT1 '_' - -static uint8 IP[64] = { - 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 -}; - -static uint8 inv_key_perm[64]; -static uint8 u_key_perm[56]; -static uint8 key_perm[56] = { - 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, - 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 -}; - -static uint8 key_shifts[16] = { - 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 -}; - -static uint8 inv_comp_perm[56]; -static uint8 comp_perm[48] = { - 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, - 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, - 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, - 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 -}; - -/* - * No E box is used, as it's replaced by some ANDs, shifts, and ORs. - */ - -static uint8 u_sbox[8][64]; -static uint8 sbox[8][64] = { - { - 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, - 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, - 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, - 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 - }, - { - 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, - 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, - 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, - 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 - }, - { - 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, - 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, - 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, - 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 - }, - { - 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, - 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, - 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, - 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 - }, - { - 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, - 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, - 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, - 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 - }, - { - 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, - 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, - 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, - 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 - }, - { - 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, - 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, - 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, - 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 - }, - { - 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, - 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, - 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, - 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 - } -}; - -static uint8 un_pbox[32]; -static uint8 pbox[32] = { - 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, - 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 -}; - -static uint32 _crypt_bits32[32] = -{ - 0x80000000, 0x40000000, 0x20000000, 0x10000000, - 0x08000000, 0x04000000, 0x02000000, 0x01000000, - 0x00800000, 0x00400000, 0x00200000, 0x00100000, - 0x00080000, 0x00040000, 0x00020000, 0x00010000, - 0x00008000, 0x00004000, 0x00002000, 0x00001000, - 0x00000800, 0x00000400, 0x00000200, 0x00000100, - 0x00000080, 0x00000040, 0x00000020, 0x00000010, - 0x00000008, 0x00000004, 0x00000002, 0x00000001 -}; - -static uint8 _crypt_bits8[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; - -static uint32 saltbits; -static long old_salt; -static uint32 *bits28, - *bits24; -static uint8 init_perm[64], - final_perm[64]; -static uint32 en_keysl[16], - en_keysr[16]; -static uint32 de_keysl[16], - de_keysr[16]; -static int des_initialised = 0; -static uint8 m_sbox[4][4096]; -static uint32 psbox[4][256]; -static uint32 ip_maskl[8][256], - ip_maskr[8][256]; -static uint32 fp_maskl[8][256], - fp_maskr[8][256]; -static uint32 key_perm_maskl[8][128], - key_perm_maskr[8][128]; -static uint32 comp_maskl[8][128], - comp_maskr[8][128]; -static uint32 old_rawkey0, - old_rawkey1; - -static inline int -ascii_to_bin(char ch) -{ - if (ch > 'z') - return (0); - if (ch >= 'a') - return (ch - 'a' + 38); - if (ch > 'Z') - return (0); - if (ch >= 'A') - return (ch - 'A' + 12); - if (ch > '9') - return (0); - if (ch >= '.') - return (ch - '.'); - return (0); -} - -static void -des_init() -{ - int i, - j, - b, - k, - inbit, - obit; - uint32 *p, - *il, - *ir, - *fl, - *fr; - - old_rawkey0 = old_rawkey1 = 0L; - saltbits = 0L; - old_salt = 0L; - bits24 = (bits28 = _crypt_bits32 + 4) + 4; - - /* - * Invert the S-boxes, reordering the input bits. - */ - for (i = 0; i < 8; i++) - for (j = 0; j < 64; j++) - { - b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf); - u_sbox[i][j] = sbox[i][b]; - } - - /* - * Convert the inverted S-boxes into 4 arrays of 8 bits. Each will - * handle 12 bits of the S-box input. - */ - for (b = 0; b < 4; b++) - for (i = 0; i < 64; i++) - for (j = 0; j < 64; j++) - m_sbox[b][(i << 6) | j] = - (u_sbox[(b << 1)][i] << 4) | - u_sbox[(b << 1) + 1][j]; - - /* - * Set up the initial & final permutations into a useful form, and - * initialise the inverted key permutation. - */ - for (i = 0; i < 64; i++) - { - init_perm[final_perm[i] = IP[i] - 1] = i; - inv_key_perm[i] = 255; - } - - /* - * Invert the key permutation and initialise the inverted key - * compression permutation. - */ - for (i = 0; i < 56; i++) - { - u_key_perm[i] = key_perm[i] - 1; - inv_key_perm[key_perm[i] - 1] = i; - inv_comp_perm[i] = 255; - } - - /* - * Invert the key compression permutation. - */ - for (i = 0; i < 48; i++) - inv_comp_perm[comp_perm[i] - 1] = i; - - /* - * Set up the OR-mask arrays for the initial and final permutations, - * and for the key initial and compression permutations. - */ - for (k = 0; k < 8; k++) - { - for (i = 0; i < 256; i++) - { - *(il = &ip_maskl[k][i]) = 0L; - *(ir = &ip_maskr[k][i]) = 0L; - *(fl = &fp_maskl[k][i]) = 0L; - *(fr = &fp_maskr[k][i]) = 0L; - for (j = 0; j < 8; j++) - { - inbit = 8 * k + j; - if (i & _crypt_bits8[j]) - { - if ((obit = init_perm[inbit]) < 32) - *il |= _crypt_bits32[obit]; - else - *ir |= _crypt_bits32[obit - 32]; - if ((obit = final_perm[inbit]) < 32) - *fl |= _crypt_bits32[obit]; - else - *fr |= _crypt_bits32[obit - 32]; - } - } - } - for (i = 0; i < 128; i++) - { - *(il = &key_perm_maskl[k][i]) = 0L; - *(ir = &key_perm_maskr[k][i]) = 0L; - for (j = 0; j < 7; j++) - { - inbit = 8 * k + j; - if (i & _crypt_bits8[j + 1]) - { - if ((obit = inv_key_perm[inbit]) == 255) - continue; - if (obit < 28) - *il |= bits28[obit]; - else - *ir |= bits28[obit - 28]; - } - } - *(il = &comp_maskl[k][i]) = 0L; - *(ir = &comp_maskr[k][i]) = 0L; - for (j = 0; j < 7; j++) - { - inbit = 7 * k + j; - if (i & _crypt_bits8[j + 1]) - { - if ((obit = inv_comp_perm[inbit]) == 255) - continue; - if (obit < 24) - *il |= bits24[obit]; - else - *ir |= bits24[obit - 24]; - } - } - } - } - - /* - * Invert the P-box permutation, and convert into OR-masks for - * handling the output of the S-box arrays setup above. - */ - for (i = 0; i < 32; i++) - un_pbox[pbox[i] - 1] = i; - - for (b = 0; b < 4; b++) - for (i = 0; i < 256; i++) - { - *(p = &psbox[b][i]) = 0L; - for (j = 0; j < 8; j++) - { - if (i & _crypt_bits8[j]) - *p |= _crypt_bits32[un_pbox[8 * b + j]]; - } - } - - des_initialised = 1; -} - -static void -setup_salt(long salt) -{ - uint32 obit, - saltbit; - int i; - - if (salt == old_salt) - return; - old_salt = salt; - - saltbits = 0L; - saltbit = 1; - obit = 0x800000; - for (i = 0; i < 24; i++) - { - if (salt & saltbit) - saltbits |= obit; - saltbit <<= 1; - obit >>= 1; - } -} - -static int -des_setkey(const char *key) -{ - uint32 k0, - k1, - rawkey0, - rawkey1; - int shifts, - round; - - if (!des_initialised) - des_init(); - - rawkey0 = ntohl(*(uint32 *) key); - rawkey1 = ntohl(*(uint32 *) (key + 4)); - - if ((rawkey0 | rawkey1) - && rawkey0 == old_rawkey0 - && rawkey1 == old_rawkey1) - { - /* - * Already setup for this key. This optimisation fails on a zero - * key (which is weak and has bad parity anyway) in order to - * simplify the starting conditions. - */ - return (0); - } - old_rawkey0 = rawkey0; - old_rawkey1 = rawkey1; - - /* - * Do key permutation and split into two 28-bit subkeys. - */ - k0 = key_perm_maskl[0][rawkey0 >> 25] - | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f] - | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f] - | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f] - | key_perm_maskl[4][rawkey1 >> 25] - | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f] - | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f] - | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f]; - k1 = key_perm_maskr[0][rawkey0 >> 25] - | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f] - | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f] - | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f] - | key_perm_maskr[4][rawkey1 >> 25] - | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f] - | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f] - | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f]; - - /* - * Rotate subkeys and do compression permutation. - */ - shifts = 0; - for (round = 0; round < 16; round++) - { - uint32 t0, - t1; - - shifts += key_shifts[round]; - - t0 = (k0 << shifts) | (k0 >> (28 - shifts)); - t1 = (k1 << shifts) | (k1 >> (28 - shifts)); - - de_keysl[15 - round] = - en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f] - | comp_maskl[1][(t0 >> 14) & 0x7f] - | comp_maskl[2][(t0 >> 7) & 0x7f] - | comp_maskl[3][t0 & 0x7f] - | comp_maskl[4][(t1 >> 21) & 0x7f] - | comp_maskl[5][(t1 >> 14) & 0x7f] - | comp_maskl[6][(t1 >> 7) & 0x7f] - | comp_maskl[7][t1 & 0x7f]; - - de_keysr[15 - round] = - en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f] - | comp_maskr[1][(t0 >> 14) & 0x7f] - | comp_maskr[2][(t0 >> 7) & 0x7f] - | comp_maskr[3][t0 & 0x7f] - | comp_maskr[4][(t1 >> 21) & 0x7f] - | comp_maskr[5][(t1 >> 14) & 0x7f] - | comp_maskr[6][(t1 >> 7) & 0x7f] - | comp_maskr[7][t1 & 0x7f]; - } - return (0); -} - -static int -do_des(uint32 l_in, uint32 r_in, uint32 *l_out, uint32 *r_out, int count) -{ - /* - * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format. - */ - uint32 l, - r, - *kl, - *kr, - *kl1, - *kr1; - uint32 f, - r48l, - r48r; - int round; - - if (count == 0) - return (1); - else if (count > 0) - { - /* - * Encrypting - */ - kl1 = en_keysl; - kr1 = en_keysr; - } - else - { - /* - * Decrypting - */ - count = -count; - kl1 = de_keysl; - kr1 = de_keysr; - } - - /* - * Do initial permutation (IP). - */ - l = ip_maskl[0][l_in >> 24] - | ip_maskl[1][(l_in >> 16) & 0xff] - | ip_maskl[2][(l_in >> 8) & 0xff] - | ip_maskl[3][l_in & 0xff] - | ip_maskl[4][r_in >> 24] - | ip_maskl[5][(r_in >> 16) & 0xff] - | ip_maskl[6][(r_in >> 8) & 0xff] - | ip_maskl[7][r_in & 0xff]; - r = ip_maskr[0][l_in >> 24] - | ip_maskr[1][(l_in >> 16) & 0xff] - | ip_maskr[2][(l_in >> 8) & 0xff] - | ip_maskr[3][l_in & 0xff] - | ip_maskr[4][r_in >> 24] - | ip_maskr[5][(r_in >> 16) & 0xff] - | ip_maskr[6][(r_in >> 8) & 0xff] - | ip_maskr[7][r_in & 0xff]; - - while (count--) - { - /* - * Do each round. - */ - kl = kl1; - kr = kr1; - round = 16; - while (round--) - { - /* - * Expand R to 48 bits (simulate the E-box). - */ - r48l = ((r & 0x00000001) << 23) - | ((r & 0xf8000000) >> 9) - | ((r & 0x1f800000) >> 11) - | ((r & 0x01f80000) >> 13) - | ((r & 0x001f8000) >> 15); - - r48r = ((r & 0x0001f800) << 7) - | ((r & 0x00001f80) << 5) - | ((r & 0x000001f8) << 3) - | ((r & 0x0000001f) << 1) - | ((r & 0x80000000) >> 31); - - /* - * Do salting for crypt() and friends, and XOR with the - * permuted key. - */ - f = (r48l ^ r48r) & saltbits; - r48l ^= f ^ *kl++; - r48r ^= f ^ *kr++; - - /* - * Do sbox lookups (which shrink it back to 32 bits) and do - * the pbox permutation at the same time. - */ - f = psbox[0][m_sbox[0][r48l >> 12]] - | psbox[1][m_sbox[1][r48l & 0xfff]] - | psbox[2][m_sbox[2][r48r >> 12]] - | psbox[3][m_sbox[3][r48r & 0xfff]]; - - /* - * Now that we've permuted things, complete f(). - */ - f ^= l; - l = r; - r = f; - } - r = l; - l = f; - } - - /* - * Do final permutation (inverse of IP). - */ - *l_out = fp_maskl[0][l >> 24] - | fp_maskl[1][(l >> 16) & 0xff] - | fp_maskl[2][(l >> 8) & 0xff] - | fp_maskl[3][l & 0xff] - | fp_maskl[4][r >> 24] - | fp_maskl[5][(r >> 16) & 0xff] - | fp_maskl[6][(r >> 8) & 0xff] - | fp_maskl[7][r & 0xff]; - *r_out = fp_maskr[0][l >> 24] - | fp_maskr[1][(l >> 16) & 0xff] - | fp_maskr[2][(l >> 8) & 0xff] - | fp_maskr[3][l & 0xff] - | fp_maskr[4][r >> 24] - | fp_maskr[5][(r >> 16) & 0xff] - | fp_maskr[6][(r >> 8) & 0xff] - | fp_maskr[7][r & 0xff]; - return (0); -} - -static int -des_cipher(const char *in, char *out, long salt, int count) -{ - uint32 buffer[2]; - uint32 l_out, - r_out, - rawl, - rawr; - int retval; - - if (!des_initialised) - des_init(); - - setup_salt(salt); - - /* copy data to avoid assuming input is word-aligned */ - memcpy(buffer, in, sizeof(buffer)); - - rawl = ntohl(buffer[0]); - rawr = ntohl(buffer[1]); - - retval = do_des(rawl, rawr, &l_out, &r_out, count); - - buffer[0] = htonl(l_out); - buffer[1] = htonl(r_out); - - /* copy data to avoid assuming output is word-aligned */ - memcpy(out, buffer, sizeof(buffer)); - - return (retval); -} - -char * -px_crypt_des(const char *key, const char *setting) -{ - int i; - uint32 count, - salt, - l, - r0, - r1, - keybuf[2]; - uint8 *p, - *q; - static uint8 output[21]; - - if (!des_initialised) - des_init(); - - - /* - * Copy the key, shifting each character up by one bit and padding - * with zeros. - */ - q = (uint8 *) keybuf; - while (q - (uint8 *) keybuf - 8) - { - if ((*q++ = *key << 1)) - key++; - } - if (des_setkey((uint8 *) keybuf)) - return (NULL); - -#ifndef DISABLE_XDES - if (*setting == _PASSWORD_EFMT1) - { - /* - * "new"-style: setting - underscore, 4 bytes of count, 4 bytes of - * salt key - unlimited characters - */ - for (i = 1, count = 0L; i < 5; i++) - count |= ascii_to_bin(setting[i]) << (i - 1) * 6; - - for (i = 5, salt = 0L; i < 9; i++) - salt |= ascii_to_bin(setting[i]) << (i - 5) * 6; - - while (*key) - { - /* - * Encrypt the key with itself. - */ - if (des_cipher((uint8 *) keybuf, (uint8 *) keybuf, 0L, 1)) - return (NULL); - - /* - * And XOR with the next 8 characters of the key. - */ - q = (uint8 *) keybuf; - while (q - (uint8 *) keybuf - 8 && *key) - *q++ ^= *key++ << 1; - - if (des_setkey((uint8 *) keybuf)) - return (NULL); - } - strncpy(output, setting, 9); - - /* - * Double check that we weren't given a short setting. If we were, - * the above code will probably have created wierd values for - * count and salt, but we don't really care. Just make sure the - * output string doesn't have an extra NUL in it. - */ - output[9] = '\0'; - p = output + strlen(output); - } - else -#endif /* !DISABLE_XDES */ - { - /* - * "old"-style: setting - 2 bytes of salt key - up to 8 characters - */ - count = 25; - - salt = (ascii_to_bin(setting[1]) << 6) - | ascii_to_bin(setting[0]); - - output[0] = setting[0]; - - /* - * If the encrypted password that the salt was extracted from is - * only 1 character long, the salt will be corrupted. We need to - * ensure that the output string doesn't have an extra NUL in it! - */ - output[1] = setting[1] ? setting[1] : output[0]; - - p = output + 2; - } - setup_salt(salt); - - /* - * Do it. - */ - if (do_des(0L, 0L, &r0, &r1, count)) - return (NULL); - - /* - * Now encode the result... - */ - l = (r0 >> 8); - *p++ = _crypt_a64[(l >> 18) & 0x3f]; - *p++ = _crypt_a64[(l >> 12) & 0x3f]; - *p++ = _crypt_a64[(l >> 6) & 0x3f]; - *p++ = _crypt_a64[l & 0x3f]; - - l = (r0 << 16) | ((r1 >> 16) & 0xffff); - *p++ = _crypt_a64[(l >> 18) & 0x3f]; - *p++ = _crypt_a64[(l >> 12) & 0x3f]; - *p++ = _crypt_a64[(l >> 6) & 0x3f]; - *p++ = _crypt_a64[l & 0x3f]; - - l = r1 << 2; - *p++ = _crypt_a64[(l >> 12) & 0x3f]; - *p++ = _crypt_a64[(l >> 6) & 0x3f]; - *p++ = _crypt_a64[l & 0x3f]; - *p = 0; - - return (output); -} diff --git a/contrib/pgcrypto/crypt-gensalt.c b/contrib/pgcrypto/crypt-gensalt.c deleted file mode 100644 index c58e794789..0000000000 --- a/contrib/pgcrypto/crypt-gensalt.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Written by Solar Designer and placed in the public domain. - * See crypt_blowfish.c for more information. - * - * This file contains salt generation functions for the traditional and - * other common crypt(3) algorithms, except for bcrypt which is defined - * entirely in crypt_blowfish.c. - * - * Put bcrypt generator also here as crypt-blowfish.c - * may not be compiled always. -- marko - */ - -#include "postgres.h" - -#include "px.h" -#include "px-crypt.h" - -#include -#ifndef __set_errno -#define __set_errno(val) (errno = (val)) -#endif - -typedef unsigned int BF_word; - -unsigned char _crypt_itoa64[64 + 1] = -"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -char * -_crypt_gensalt_traditional_rn(unsigned long count, - const char *input, int size, char *output, int output_size) -{ - if (size < 2 || output_size < 2 + 1 || (count && count != 25)) - { - if (output_size > 0) - output[0] = '\0'; - __set_errno((output_size < 2 + 1) ? ERANGE : EINVAL); - return NULL; - } - - output[0] = _crypt_itoa64[(unsigned int) input[0] & 0x3f]; - output[1] = _crypt_itoa64[(unsigned int) input[1] & 0x3f]; - output[2] = '\0'; - - return output; -} - -char * -_crypt_gensalt_extended_rn(unsigned long count, - const char *input, int size, char *output, int output_size) -{ - unsigned long value; - -/* Even iteration counts make it easier to detect weak DES keys from a look - * at the hash, so they should be avoided */ - if (size < 3 || output_size < 1 + 4 + 4 + 1 || - (count && (count > 0xffffff || !(count & 1)))) - { - if (output_size > 0) - output[0] = '\0'; - __set_errno((output_size < 1 + 4 + 4 + 1) ? ERANGE : EINVAL); - return NULL; - } - - if (!count) - count = 725; - - output[0] = '_'; - output[1] = _crypt_itoa64[count & 0x3f]; - output[2] = _crypt_itoa64[(count >> 6) & 0x3f]; - output[3] = _crypt_itoa64[(count >> 12) & 0x3f]; - output[4] = _crypt_itoa64[(count >> 18) & 0x3f]; - value = (unsigned long) input[0] | - ((unsigned long) input[1] << 8) | - ((unsigned long) input[2] << 16); - output[5] = _crypt_itoa64[value & 0x3f]; - output[6] = _crypt_itoa64[(value >> 6) & 0x3f]; - output[7] = _crypt_itoa64[(value >> 12) & 0x3f]; - output[8] = _crypt_itoa64[(value >> 18) & 0x3f]; - output[9] = '\0'; - - return output; -} - -char * -_crypt_gensalt_md5_rn(unsigned long count, - const char *input, int size, char *output, int output_size) -{ - unsigned long value; - - if (size < 3 || output_size < 3 + 4 + 1 || (count && count != 1000)) - { - if (output_size > 0) - output[0] = '\0'; - __set_errno((output_size < 3 + 4 + 1) ? ERANGE : EINVAL); - return NULL; - } - - output[0] = '$'; - output[1] = '1'; - output[2] = '$'; - value = (unsigned long) input[0] | - ((unsigned long) input[1] << 8) | - ((unsigned long) input[2] << 16); - output[3] = _crypt_itoa64[value & 0x3f]; - output[4] = _crypt_itoa64[(value >> 6) & 0x3f]; - output[5] = _crypt_itoa64[(value >> 12) & 0x3f]; - output[6] = _crypt_itoa64[(value >> 18) & 0x3f]; - output[7] = '\0'; - - if (size >= 6 && output_size >= 3 + 4 + 4 + 1) - { - value = (unsigned long) input[3] | - ((unsigned long) input[4] << 8) | - ((unsigned long) input[5] << 16); - output[7] = _crypt_itoa64[value & 0x3f]; - output[8] = _crypt_itoa64[(value >> 6) & 0x3f]; - output[9] = _crypt_itoa64[(value >> 12) & 0x3f]; - output[10] = _crypt_itoa64[(value >> 18) & 0x3f]; - output[11] = '\0'; - } - - return output; -} - - - -static unsigned char BF_itoa64[64 + 1] = -"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - -static void -BF_encode(char *dst, const BF_word * src, int size) -{ - unsigned char *sptr = (unsigned char *) src; - unsigned char *end = sptr + size; - unsigned char *dptr = (unsigned char *) dst; - unsigned int c1, - c2; - - do - { - c1 = *sptr++; - *dptr++ = BF_itoa64[c1 >> 2]; - c1 = (c1 & 0x03) << 4; - if (sptr >= end) - { - *dptr++ = BF_itoa64[c1]; - break; - } - - c2 = *sptr++; - c1 |= c2 >> 4; - *dptr++ = BF_itoa64[c1]; - c1 = (c2 & 0x0f) << 2; - if (sptr >= end) - { - *dptr++ = BF_itoa64[c1]; - break; - } - - c2 = *sptr++; - c1 |= c2 >> 6; - *dptr++ = BF_itoa64[c1]; - *dptr++ = BF_itoa64[c2 & 0x3f]; - } while (sptr < end); -} - -char * -_crypt_gensalt_blowfish_rn(unsigned long count, - const char *input, int size, char *output, int output_size) -{ - if (size < 16 || output_size < 7 + 22 + 1 || - (count && (count < 4 || count > 31))) - { - if (output_size > 0) - output[0] = '\0'; - __set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL); - return NULL; - } - - if (!count) - count = 5; - - output[0] = '$'; - output[1] = '2'; - output[2] = 'a'; - output[3] = '$'; - output[4] = '0' + count / 10; - output[5] = '0' + count % 10; - output[6] = '$'; - - BF_encode(&output[7], (BF_word *) input, 16); - output[7 + 22] = '\0'; - - return output; -} diff --git a/contrib/pgcrypto/crypt-md5.c b/contrib/pgcrypto/crypt-md5.c deleted file mode 100644 index 7b45bb2151..0000000000 --- a/contrib/pgcrypto/crypt-md5.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * $FreeBSD: src/lib/libcrypt/crypt-md5.c,v 1.5 1999/12/17 20:21:45 peter Exp $ - * - */ -/* $Id: crypt-md5.c,v 1.2 2001/10/25 05:49:19 momjian Exp $ */ - -#include -#include "px.h" -#include "px-crypt.h" - -#define MD5_SIZE 16 -/* - * UNIX password - */ - -char * -px_crypt_md5(const char *pw, const char *salt, char *passwd, unsigned dstlen) -{ - static char *magic = "$1$"; /* This string is magic for this - * algorithm. Having it this way, we can - * get get better later on */ - static char *p; - static const char *sp, - *ep; - unsigned char final[MD5_SIZE]; - int sl, - pl, - i; - PX_MD *ctx, - *ctx1; - int err; - unsigned long l; - - if (!passwd || dstlen < 120) - return NULL; - - /* Refine the Salt first */ - sp = salt; - - /* If it starts with the magic string, then skip that */ - if (!strncmp(sp, magic, strlen(magic))) - sp += strlen(magic); - - /* It stops at the first '$', max 8 chars */ - for (ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++) - continue; - - /* get the length of the true salt */ - sl = ep - sp; - - /* */ - err = px_find_digest("md5", &ctx); - if (err) - return NULL; - err = px_find_digest("md5", &ctx1); - - /* The password first, since that is what is most unknown */ - px_md_update(ctx, pw, strlen(pw)); - - /* Then our magic string */ - px_md_update(ctx, magic, strlen(magic)); - - /* Then the raw salt */ - px_md_update(ctx, sp, sl); - - /* Then just as many characters of the MD5(pw,salt,pw) */ - px_md_update(ctx1, pw, strlen(pw)); - px_md_update(ctx1, sp, sl); - px_md_update(ctx1, pw, strlen(pw)); - px_md_finish(ctx1, final); - for (pl = strlen(pw); pl > 0; pl -= MD5_SIZE) - px_md_update(ctx, final, pl > MD5_SIZE ? MD5_SIZE : pl); - - /* Don't leave anything around in vm they could use. */ - memset(final, 0, sizeof final); - - /* Then something really weird... */ - for (i = strlen(pw); i; i >>= 1) - if (i & 1) - px_md_update(ctx, final, 1); - else - px_md_update(ctx, pw, 1); - - /* Now make the output string */ - strcpy(passwd, magic); - strncat(passwd, sp, sl); - strcat(passwd, "$"); - - px_md_finish(ctx, final); - - /* - * and now, just to make sure things don't run too fast On a 60 Mhz - * Pentium this takes 34 msec, so you would need 30 seconds to build a - * 1000 entry dictionary... - */ - for (i = 0; i < 1000; i++) - { - px_md_reset(ctx1); - if (i & 1) - px_md_update(ctx1, pw, strlen(pw)); - else - px_md_update(ctx1, final, MD5_SIZE); - - if (i % 3) - px_md_update(ctx1, sp, sl); - - if (i % 7) - px_md_update(ctx1, pw, strlen(pw)); - - if (i & 1) - px_md_update(ctx1, final, MD5_SIZE); - else - px_md_update(ctx1, pw, strlen(pw)); - px_md_finish(ctx1, final); - } - - p = passwd + strlen(passwd); - - l = (final[0] << 16) | (final[6] << 8) | final[12]; - _crypt_to64(p, l, 4); - p += 4; - l = (final[1] << 16) | (final[7] << 8) | final[13]; - _crypt_to64(p, l, 4); - p += 4; - l = (final[2] << 16) | (final[8] << 8) | final[14]; - _crypt_to64(p, l, 4); - p += 4; - l = (final[3] << 16) | (final[9] << 8) | final[15]; - _crypt_to64(p, l, 4); - p += 4; - l = (final[4] << 16) | (final[10] << 8) | final[5]; - _crypt_to64(p, l, 4); - p += 4; - l = final[11]; - _crypt_to64(p, l, 2); - p += 2; - *p = '\0'; - - /* Don't leave anything around in vm they could use. */ - memset(final, 0, sizeof final); - - px_md_free(ctx1); - px_md_free(ctx); - - return passwd; -} diff --git a/contrib/pgcrypto/expected/blowfish.out b/contrib/pgcrypto/expected/blowfish.out deleted file mode 100644 index e7fd632df2..0000000000 --- a/contrib/pgcrypto/expected/blowfish.out +++ /dev/null @@ -1,108 +0,0 @@ --- --- Blowfish cipher --- --- some standard Blowfish testvalues -select encode(encrypt( -decode('0000000000000000', 'hex'), -decode('0000000000000000', 'hex'), -'bf-ecb/pad:none'), 'hex'); - encode ------------------- - 4ef997456198dd78 -(1 row) - -select encode(encrypt( -decode('ffffffffffffffff', 'hex'), -decode('ffffffffffffffff', 'hex'), -'bf-ecb/pad:none'), 'hex'); - encode ------------------- - 51866fd5b85ecb8a -(1 row) - -select encode(encrypt( -decode('1000000000000001', 'hex'), -decode('3000000000000000', 'hex'), -'bf-ecb/pad:none'), 'hex'); - encode ------------------- - 7d856f9a613063f2 -(1 row) - -select encode(encrypt( -decode('1111111111111111', 'hex'), -decode('1111111111111111', 'hex'), -'bf-ecb/pad:none'), 'hex'); - encode ------------------- - 2466dd878b963c9d -(1 row) - -select encode(encrypt( -decode('0123456789abcdef', 'hex'), -decode('fedcba9876543210', 'hex'), -'bf-ecb/pad:none'), 'hex'); - encode ------------------- - 0aceab0fc6a0a28d -(1 row) - -select encode(encrypt( -decode('01a1d6d039776742', 'hex'), -decode('fedcba9876543210', 'hex'), -'bf-ecb/pad:none'), 'hex'); - encode ------------------- - 3273b8badc9e9e15 -(1 row) - -select encode(encrypt( -decode('ffffffffffffffff', 'hex'), -decode('0000000000000000', 'hex'), -'bf-ecb/pad:none'), 'hex'); - encode ------------------- - 014933e0cdaff6e4 -(1 row) - --- setkey -select encode(encrypt( -decode('fedcba9876543210', 'hex'), -decode('f0e1d2c3b4a5968778695a4b3c2d1e0f', 'hex'), -'bf-ecb/pad:none'), 'hex'); - encode ------------------- - 93142887ee3be15c -(1 row) - --- with padding -select encode(encrypt( -decode('01234567890123456789', 'hex'), -decode('33443344334433443344334433443344', 'hex'), -'bf-ecb'), 'hex'); - encode ----------------------------------- - 0d04a43a20456dee5ede6ed9e4dcaaa6 -(1 row) - --- cbc --- 28 bytes key -select encode(encrypt( -decode('6b77b4d63006dee605b156e27403979358deb9e7154616d959f1652bd5', 'hex'), -decode('37363534333231204e6f77206973207468652074696d6520666f7220', 'hex'), -'bf-cbc'), 'hex'); - encode ------------------------------------------------------------------- - 4f2beb748c4f689ec755edb9dc252a41b93a3786850b4c75d6a702b6a8e48825 -(1 row) - --- 29 bytes key -select encode(encrypt( -decode('6b77b4d63006dee605b156e27403979358deb9e7154616d959f1652bd5ff92cc', 'hex'), -decode('37363534333231204e6f77206973207468652074696d6520666f722000', 'hex'), -'bf-cbc'), 'hex'); - encode ----------------------------------------------------------------------------------- - 3ea6357a0ee7fad6d0c4b63464f2aafa40c2e91b4b7e1bba8114932fd92b5c8f111e7e50e7b2e541 -(1 row) - diff --git a/contrib/pgcrypto/expected/crypt-blowfish.out b/contrib/pgcrypto/expected/crypt-blowfish.out deleted file mode 100644 index 7910a4e02e..0000000000 --- a/contrib/pgcrypto/expected/crypt-blowfish.out +++ /dev/null @@ -1,26 +0,0 @@ --- --- crypt() and gen_salt(): bcrypt --- -select crypt('', '$2a$06$RQiOJ.3ELirrXwxIZY8q0O'); - crypt --------------------------------------------------------------- - $2a$06$RQiOJ.3ELirrXwxIZY8q0OlGbBEpDmx7IRZlNYvGJ1SHXwNi2cEKK -(1 row) - -select crypt('foox', '$2a$06$RQiOJ.3ELirrXwxIZY8q0O'); - crypt --------------------------------------------------------------- - $2a$06$RQiOJ.3ELirrXwxIZY8q0OR3CVJrAfda1z26CCHPnB6mmVZD8p0/C -(1 row) - -create table ctest (data text, res text, salt text); -insert into ctest values ('password', '', ''); -update ctest set salt = gen_salt('bf', 8); -update ctest set res = crypt(data, salt); -select res = crypt(data, res) as "worked" from ctest; - worked --------- - t -(1 row) - -drop table ctest; diff --git a/contrib/pgcrypto/expected/crypt-des.out b/contrib/pgcrypto/expected/crypt-des.out deleted file mode 100644 index 76a756eada..0000000000 --- a/contrib/pgcrypto/expected/crypt-des.out +++ /dev/null @@ -1,26 +0,0 @@ --- --- crypt() and gen_salt(): crypt-des --- -select crypt('', 'NB'); - crypt ---------------- - NBPx/38Y48kHg -(1 row) - -select crypt('foox', 'NB'); - crypt ---------------- - NB53EGGqrrb5E -(1 row) - -create table ctest (data text, res text, salt text); -insert into ctest values ('password', '', ''); -update ctest set salt = gen_salt('des'); -update ctest set res = crypt(data, salt); -select res = crypt(data, res) as "worked" from ctest; - worked --------- - t -(1 row) - -drop table ctest; diff --git a/contrib/pgcrypto/expected/crypt-md5.out b/contrib/pgcrypto/expected/crypt-md5.out deleted file mode 100644 index 4bd2f33a9f..0000000000 --- a/contrib/pgcrypto/expected/crypt-md5.out +++ /dev/null @@ -1,26 +0,0 @@ --- --- crypt() and gen_salt(): md5 --- -select crypt('', '$1$Szzz0yzz'); - crypt ------------------------------------- - $1$Szzz0yzz$To38XrR3BsbXQW2ZpfKjF1 -(1 row) - -select crypt('foox', '$1$Szzz0yzz'); - crypt ------------------------------------- - $1$Szzz0yzz$IYL49cd3t9bllsA7Jmz1M1 -(1 row) - -create table ctest (data text, res text, salt text); -insert into ctest values ('password', '', ''); -update ctest set salt = gen_salt('md5'); -update ctest set res = crypt(data, salt); -select res = crypt(data, res) as "worked" from ctest; - worked --------- - t -(1 row) - -drop table ctest; diff --git a/contrib/pgcrypto/expected/crypt-xdes.out b/contrib/pgcrypto/expected/crypt-xdes.out deleted file mode 100644 index d247b552b2..0000000000 --- a/contrib/pgcrypto/expected/crypt-xdes.out +++ /dev/null @@ -1,26 +0,0 @@ --- --- crypt() and gen_salt(): extended des --- -select crypt('', '_J9..j2zz'); - crypt ----------------------- - _J9..j2zzR/nIRDK3pPc -(1 row) - -select crypt('foox', '_J9..j2zz'); - crypt ----------------------- - _J9..j2zzAYKMvO2BYRY -(1 row) - -create table ctest (data text, res text, salt text); -insert into ctest values ('password', '', ''); -update ctest set salt = gen_salt('xdes', 1001); -update ctest set res = crypt(data, salt); -select res = crypt(data, res) as "worked" from ctest; - worked --------- - t -(1 row) - -drop table ctest; diff --git a/contrib/pgcrypto/expected/hmac-md5.out b/contrib/pgcrypto/expected/hmac-md5.out deleted file mode 100644 index 5cd55ce440..0000000000 --- a/contrib/pgcrypto/expected/hmac-md5.out +++ /dev/null @@ -1,72 +0,0 @@ --- --- HMAC-MD5 --- -select encode(hmac( -'Hi There', -decode('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'), -'md5'), 'hex'); - encode ----------------------------------- - 9294727a3638bb1c13f48ef8158bfc9d -(1 row) - --- 2 -select encode(hmac( -'Jefe', -'what do ya want for nothing?', -'md5'), 'hex'); - encode ----------------------------------- - 813aead7c4a34bff01a16d61368e7c13 -(1 row) - --- 3 -select encode(hmac( -decode('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', 'hex'), -decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), -'md5'), 'hex'); - encode ----------------------------------- - 56be34521d144c88dbb8c733f0e8b3f6 -(1 row) - --- 4 -select encode(hmac( -decode('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd', 'hex'), -decode('0102030405060708090a0b0c0d0e0f10111213141516171819', 'hex'), -'md5'), 'hex'); - encode ----------------------------------- - 697eaf0aca3a3aea3a75164746ffaa79 -(1 row) - --- 5 -select encode(hmac( -'Test With Truncation', -decode('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'), -'md5'), 'hex'); - encode ----------------------------------- - 56461ef2342edc00f9bab995690efd4c -(1 row) - --- 6 -select encode(hmac( -'Test Using Larger Than Block-Size Key - Hash Key First', -decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), -'md5'), 'hex'); - encode ----------------------------------- - 6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd -(1 row) - --- 7 -select encode(hmac( -'Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data', -decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), -'md5'), 'hex'); - encode ----------------------------------- - 6f630fad67cda0ee1fb1f562db3aa53e -(1 row) - diff --git a/contrib/pgcrypto/expected/hmac-sha1.out b/contrib/pgcrypto/expected/hmac-sha1.out deleted file mode 100644 index e4739fe5f3..0000000000 --- a/contrib/pgcrypto/expected/hmac-sha1.out +++ /dev/null @@ -1,72 +0,0 @@ --- --- HMAC-MD5 --- -select encode(hmac( -'Hi There', -decode('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'), -'sha1'), 'hex'); - encode ------------------------------------------- - 675b0b3a1b4ddf4e124872da6c2f632bfed957e9 -(1 row) - --- 2 -select encode(hmac( -'Jefe', -'what do ya want for nothing?', -'sha1'), 'hex'); - encode ------------------------------------------- - 156d4c35468a0339f3fa57a067bf47f814eb7a57 -(1 row) - --- 3 -select encode(hmac( -decode('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', 'hex'), -decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), -'sha1'), 'hex'); - encode ------------------------------------------- - d730594d167e35d5956fd8003d0db3d3f46dc7bb -(1 row) - --- 4 -select encode(hmac( -decode('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd', 'hex'), -decode('0102030405060708090a0b0c0d0e0f10111213141516171819', 'hex'), -'sha1'), 'hex'); - encode ------------------------------------------- - 4c9007f4026250c6bc8414f9bf50c86c2d7235da -(1 row) - --- 5 -select encode(hmac( -'Test With Truncation', -decode('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'), -'sha1'), 'hex'); - encode ------------------------------------------- - 37268b7e21e84da5720c53c4ba03ad1104039fa7 -(1 row) - --- 6 -select encode(hmac( -'Test Using Larger Than Block-Size Key - Hash Key First', -decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), -'sha1'), 'hex'); - encode ------------------------------------------- - aa4ae5e15272d00e95705637ce8a3b55ed402112 -(1 row) - --- 7 -select encode(hmac( -'Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data', -decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), -'sha1'), 'hex'); - encode ------------------------------------------- - e8e99d0f45237d786d6bbaa7965c7808bbff1a91 -(1 row) - diff --git a/contrib/pgcrypto/expected/init.out b/contrib/pgcrypto/expected/init.out deleted file mode 100644 index a7c95eb63c..0000000000 --- a/contrib/pgcrypto/expected/init.out +++ /dev/null @@ -1,17 +0,0 @@ --- --- init pgcrypto --- -\set ECHO none --- check for encoding fn's -select encode('foo', 'hex'); - encode --------- - 666f6f -(1 row) - -select decode('666f6f', 'hex'); - decode --------- - foo -(1 row) - diff --git a/contrib/pgcrypto/expected/md5.out b/contrib/pgcrypto/expected/md5.out deleted file mode 100644 index ec8368042e..0000000000 --- a/contrib/pgcrypto/expected/md5.out +++ /dev/null @@ -1,45 +0,0 @@ --- --- MD5 message digest --- -select encode(digest('', 'md5'), 'hex'); - encode ----------------------------------- - d41d8cd98f00b204e9800998ecf8427e -(1 row) - -select encode(digest('a', 'md5'), 'hex'); - encode ----------------------------------- - 0cc175b9c0f1b6a831c399e269772661 -(1 row) - -select encode(digest('abc', 'md5'), 'hex'); - encode ----------------------------------- - 900150983cd24fb0d6963f7d28e17f72 -(1 row) - -select encode(digest('message digest', 'md5'), 'hex'); - encode ----------------------------------- - f96b697d7cb7938d525a2f31aaf161d0 -(1 row) - -select encode(digest('abcdefghijklmnopqrstuvwxyz', 'md5'), 'hex'); - encode ----------------------------------- - c3fcd3d76192e4007dfb496cca67e13b -(1 row) - -select encode(digest('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 'md5'), 'hex'); - encode ----------------------------------- - d174ab98d277d9f5a5611c2c9f419d9f -(1 row) - -select encode(digest('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 'md5'), 'hex'); - encode ----------------------------------- - 57edf4a22be3c955ac49da2e2107b67a -(1 row) - diff --git a/contrib/pgcrypto/expected/rijndael.out b/contrib/pgcrypto/expected/rijndael.out deleted file mode 100644 index 2f64268944..0000000000 --- a/contrib/pgcrypto/expected/rijndael.out +++ /dev/null @@ -1,69 +0,0 @@ --- --- AES / Rijndael-128 cipher --- --- some standard Rijndael testvalues -select encode(encrypt( -decode('00112233445566778899aabbccddeeff', 'hex'), -decode('000102030405060708090a0b0c0d0e0f', 'hex'), -'aes-ecb/pad:none'), 'hex'); - encode ----------------------------------- - 69c4e0d86a7b0430d8cdb78070b4c55a -(1 row) - -select encode(encrypt( -decode('00112233445566778899aabbccddeeff', 'hex'), -decode('000102030405060708090a0b0c0d0e0f1011121314151617', 'hex'), -'aes-ecb/pad:none'), 'hex'); - encode ----------------------------------- - dda97ca4864cdfe06eaf70a0ec0d7191 -(1 row) - -select encode(encrypt( -decode('00112233445566778899aabbccddeeff', 'hex'), -decode('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', 'hex'), -'aes-ecb/pad:none'), 'hex'); - encode ----------------------------------- - 8ea2b7ca516745bfeafc49904b496089 -(1 row) - --- cbc -select encode(encrypt( -decode('00112233445566778899aabbccddeeff', 'hex'), -decode('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', 'hex'), -'aes-cbc/pad:none'), 'hex'); - encode ----------------------------------- - 8ea2b7ca516745bfeafc49904b496089 -(1 row) - --- key padding -select encode(encrypt( -decode('0011223344', 'hex'), -decode('000102030405', 'hex'), -'aes-cbc'), 'hex'); - encode ----------------------------------- - 189a28932213f017b246678dbc28655f -(1 row) - -select encode(encrypt( -decode('0011223344', 'hex'), -decode('000102030405060708090a0b0c0d0e0f10111213', 'hex'), -'aes-cbc'), 'hex'); - encode ----------------------------------- - 3b02279162d15580e069d3a71407a556 -(1 row) - -select encode(encrypt( -decode('0011223344', 'hex'), -decode('000102030405060708090a0b0c0d0e0f101112131415161718191a1b', 'hex'), -'aes-cbc'), 'hex'); - encode ----------------------------------- - 4facb6a041d53e0a5a73289170901fe7 -(1 row) - diff --git a/contrib/pgcrypto/expected/sha1.out b/contrib/pgcrypto/expected/sha1.out deleted file mode 100644 index 430c881a9f..0000000000 --- a/contrib/pgcrypto/expected/sha1.out +++ /dev/null @@ -1,45 +0,0 @@ --- --- SHA1 message digest --- -select encode(digest('', 'sha1'), 'hex'); - encode ------------------------------------------- - da39a3ee5e6b4b0d3255bfef95601890afd80709 -(1 row) - -select encode(digest('a', 'sha1'), 'hex'); - encode ------------------------------------------- - 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 -(1 row) - -select encode(digest('abc', 'sha1'), 'hex'); - encode ------------------------------------------- - a9993e364706816aba3e25717850c26c9cd0d89d -(1 row) - -select encode(digest('message digest', 'sha1'), 'hex'); - encode ------------------------------------------- - c12252ceda8be8994d5fa0290a47231c1d16aae3 -(1 row) - -select encode(digest('abcdefghijklmnopqrstuvwxyz', 'sha1'), 'hex'); - encode ------------------------------------------- - 32d10c7b8cf96570ca04ce37f2a19d84240d3a89 -(1 row) - -select encode(digest('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 'sha1'), 'hex'); - encode ------------------------------------------- - 761c457bf73b14d27e9e9265c46f4b4dda11f940 -(1 row) - -select encode(digest('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 'sha1'), 'hex'); - encode ------------------------------------------- - 50abf5706a150990a08b2c5ea40fa0e585554732 -(1 row) - diff --git a/contrib/pgcrypto/internal.c b/contrib/pgcrypto/internal.c deleted file mode 100644 index 9a983299e6..0000000000 --- a/contrib/pgcrypto/internal.c +++ /dev/null @@ -1,596 +0,0 @@ -/* - * internal.c - * Wrapper for builtin functions - * - * Copyright (c) 2001 Marko Kreen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: internal.c,v 1.11 2002/01/03 07:21:48 momjian Exp $ - */ - - -#include - -#include "px.h" - -#include "md5.h" -#include "sha1.h" -#include "blf.h" -#include "rijndael.h" - -#ifndef MD5_DIGEST_LENGTH -#define MD5_DIGEST_LENGTH 16 -#endif - -#ifndef SHA1_DIGEST_LENGTH -#ifdef SHA1_RESULTLEN -#define SHA1_DIGEST_LENGTH SHA1_RESULTLEN -#else -#define SHA1_DIGEST_LENGTH 20 -#endif -#endif - -#define SHA1_BLOCK_SIZE 64 -#define MD5_BLOCK_SIZE 64 - -static void init_md5(PX_MD * h); -static void init_sha1(PX_MD * h); - -static struct int_digest -{ - char *name; - void (*init) (PX_MD * h); -} int_digest_list[] = - -{ - { - "md5", init_md5 - }, - { - "sha1", init_sha1 - }, - { - NULL, NULL - } -}; - -/* MD5 */ - -static unsigned -int_md5_len(PX_MD * h) -{ - return MD5_DIGEST_LENGTH; -} - -static unsigned -int_md5_block_len(PX_MD * h) -{ - return MD5_BLOCK_SIZE; -} - -static void -int_md5_update(PX_MD * h, const uint8 *data, unsigned dlen) -{ - MD5_CTX *ctx = (MD5_CTX *) h->p.ptr; - - MD5Update(ctx, data, dlen); -} - -static void -int_md5_reset(PX_MD * h) -{ - MD5_CTX *ctx = (MD5_CTX *) h->p.ptr; - - MD5Init(ctx); -} - -static void -int_md5_finish(PX_MD * h, uint8 *dst) -{ - MD5_CTX *ctx = (MD5_CTX *) h->p.ptr; - - MD5Final(dst, ctx); -} - -static void -int_md5_free(PX_MD * h) -{ - MD5_CTX *ctx = (MD5_CTX *) h->p.ptr; - - px_free(ctx); - px_free(h); -} - -/* SHA1 */ - -static unsigned -int_sha1_len(PX_MD * h) -{ - return SHA1_DIGEST_LENGTH; -} - -static unsigned -int_sha1_block_len(PX_MD * h) -{ - return SHA1_BLOCK_SIZE; -} - -static void -int_sha1_update(PX_MD * h, const uint8 *data, unsigned dlen) -{ - SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; - - SHA1Update(ctx, data, dlen); -} - -static void -int_sha1_reset(PX_MD * h) -{ - SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; - - SHA1Init(ctx); -} - -static void -int_sha1_finish(PX_MD * h, uint8 *dst) -{ - SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; - - SHA1Final(dst, ctx); -} - -static void -int_sha1_free(PX_MD * h) -{ - SHA1_CTX *ctx = (SHA1_CTX *) h->p.ptr; - - px_free(ctx); - px_free(h); -} - -/* init functions */ - -static void -init_md5(PX_MD * md) -{ - MD5_CTX *ctx; - - ctx = px_alloc(sizeof(*ctx)); - - md->p.ptr = ctx; - - md->result_size = int_md5_len; - md->block_size = int_md5_block_len; - md->reset = int_md5_reset; - md->update = int_md5_update; - md->finish = int_md5_finish; - md->free = int_md5_free; - - md->reset(md); -} - -static void -init_sha1(PX_MD * md) -{ - SHA1_CTX *ctx; - - ctx = px_alloc(sizeof(*ctx)); - - md->p.ptr = ctx; - - md->result_size = int_sha1_len; - md->block_size = int_sha1_block_len; - md->reset = int_sha1_reset; - md->update = int_sha1_update; - md->finish = int_sha1_finish; - md->free = int_sha1_free; - - md->reset(md); -} - -/* - * ciphers generally - */ - -#define INT_MAX_KEY (512/8) -#define INT_MAX_IV (128/8) - -struct int_ctx -{ - uint8 keybuf[INT_MAX_KEY]; - uint8 iv[INT_MAX_IV]; - union - { - blf_ctx bf; - rijndael_ctx rj; - } ctx; - unsigned keylen; - int is_init; - int mode; -}; - -static void -intctx_free(PX_Cipher * c) -{ - struct int_ctx *cx = (struct int_ctx *) c->ptr; - - if (cx) - { - memset(cx, 0, sizeof *cx); - px_free(cx); - } - px_free(c); -} - -/* - * AES/rijndael - */ - -#define MODE_ECB 0 -#define MODE_CBC 1 - -static unsigned -rj_block_size(PX_Cipher * c) -{ - return 128 / 8; -} - -static unsigned -rj_key_size(PX_Cipher * c) -{ - return 256 / 8; -} - -static unsigned -rj_iv_size(PX_Cipher * c) -{ - return 128 / 8; -} - -static int -rj_init(PX_Cipher * c, const uint8 *key, unsigned klen, const uint8 *iv) -{ - struct int_ctx *cx = (struct int_ctx *) c->ptr; - - if (klen <= 128 / 8) - cx->keylen = 128 / 8; - else if (klen <= 192 / 8) - cx->keylen = 192 / 8; - else if (klen <= 256 / 8) - cx->keylen = 256 / 8; - else - return -1; - - memcpy(&cx->keybuf, key, klen); - - if (iv) - memcpy(cx->iv, iv, 128 / 8); - - return 0; -} - -static int -rj_real_init(struct int_ctx * cx, int dir) -{ - aes_set_key(&cx->ctx.rj, cx->keybuf, cx->keylen * 8, dir); - return 0; -} - -static int -rj_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) -{ - struct int_ctx *cx = (struct int_ctx *) c->ptr; - - if (!cx->is_init) - { - if (rj_real_init(cx, 1)) - return -1; - } - - if (dlen == 0) - return 0; - - if (dlen & 15) - return -1; - - memcpy(res, data, dlen); - - if (cx->mode == MODE_CBC) - { - aes_cbc_encrypt(&cx->ctx.rj, cx->iv, res, dlen); - memcpy(cx->iv, res + dlen - 16, 16); - } - else - aes_ecb_encrypt(&cx->ctx.rj, res, dlen); - - return 0; -} - -static int -rj_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) -{ - struct int_ctx *cx = (struct int_ctx *) c->ptr; - - if (!cx->is_init) - if (rj_real_init(cx, 0)) - return -1; - - if (dlen == 0) - return 0; - - if (dlen & 15) - return -1; - - memcpy(res, data, dlen); - - if (cx->mode == MODE_CBC) - { - aes_cbc_decrypt(&cx->ctx.rj, cx->iv, res, dlen); - memcpy(cx->iv, data + dlen - 16, 16); - } - else - aes_ecb_decrypt(&cx->ctx.rj, res, dlen); - - return 0; -} - -/* - * initializers - */ - -static PX_Cipher * -rj_load(int mode) -{ - PX_Cipher *c; - struct int_ctx *cx; - - c = px_alloc(sizeof *c); - memset(c, 0, sizeof *c); - - c->block_size = rj_block_size; - c->key_size = rj_key_size; - c->iv_size = rj_iv_size; - c->init = rj_init; - c->encrypt = rj_encrypt; - c->decrypt = rj_decrypt; - c->free = intctx_free; - - cx = px_alloc(sizeof *cx); - memset(cx, 0, sizeof *cx); - cx->mode = mode; - - c->ptr = cx; - return c; -} - -/* - * blowfish - */ - -static unsigned -bf_block_size(PX_Cipher * c) -{ - return 8; -} - -static unsigned -bf_key_size(PX_Cipher * c) -{ - return BLF_MAXKEYLEN; -} - -static unsigned -bf_iv_size(PX_Cipher * c) -{ - return 8; -} - -static int -bf_init(PX_Cipher * c, const uint8 *key, unsigned klen, const uint8 *iv) -{ - struct int_ctx *cx = (struct int_ctx *) c->ptr; - - blf_key(&cx->ctx.bf, key, klen); - if (iv) - memcpy(cx->iv, iv, 8); - - return 0; -} - -static int -bf_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) -{ - struct int_ctx *cx = (struct int_ctx *) c->ptr; - - if (dlen == 0) - return 0; - - if (dlen & 7) - return -1; - - memcpy(res, data, dlen); - switch (cx->mode) - { - case MODE_ECB: - blf_ecb_encrypt(&cx->ctx.bf, res, dlen); - break; - case MODE_CBC: - blf_cbc_encrypt(&cx->ctx.bf, cx->iv, res, dlen); - memcpy(cx->iv, res + dlen - 8, 8); - } - return 0; -} - -static int -bf_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) -{ - struct int_ctx *cx = (struct int_ctx *) c->ptr; - - if (dlen == 0) - return 0; - - if (dlen & 7) - return -1; - - memcpy(res, data, dlen); - switch (cx->mode) - { - case MODE_ECB: - blf_ecb_decrypt(&cx->ctx.bf, res, dlen); - break; - case MODE_CBC: - blf_cbc_decrypt(&cx->ctx.bf, cx->iv, res, dlen); - memcpy(cx->iv, data + dlen - 8, 8); - } - return 0; -} - -static PX_Cipher * -bf_load(int mode) -{ - PX_Cipher *c; - struct int_ctx *cx; - - c = px_alloc(sizeof *c); - memset(c, 0, sizeof *c); - - c->block_size = bf_block_size; - c->key_size = bf_key_size; - c->iv_size = bf_iv_size; - c->init = bf_init; - c->encrypt = bf_encrypt; - c->decrypt = bf_decrypt; - c->free = intctx_free; - - cx = px_alloc(sizeof *cx); - memset(cx, 0, sizeof *cx); - cx->mode = mode; - c->ptr = cx; - return c; -} - -/* ciphers */ - -static PX_Cipher * -rj_128_ecb() -{ - return rj_load(MODE_ECB); -} - -static PX_Cipher * -rj_128_cbc() -{ - return rj_load(MODE_CBC); -} - -static PX_Cipher * -bf_ecb_load() -{ - return bf_load(MODE_ECB); -} - -static PX_Cipher * -bf_cbc_load() -{ - return bf_load(MODE_CBC); -} - -static struct -{ - char *name; - PX_Cipher *(*load) (void); -} int_ciphers[] = - -{ - { - "bf-cbc", bf_cbc_load - }, - { - "bf-ecb", bf_ecb_load - }, - { - "aes-128-cbc", rj_128_cbc - }, - { - "aes-128-ecb", rj_128_ecb - }, - { - NULL, NULL - } -}; - -static PX_Alias int_aliases[] = { - {"bf", "bf-cbc"}, - {"blowfish", "bf-cbc"}, - {"aes", "aes-128-cbc"}, - {"aes-ecb", "aes-128-ecb"}, - {"aes-cbc", "aes-128-cbc"}, - {"aes-128", "aes-128-cbc"}, - {"rijndael", "aes-128-cbc"}, - {"rijndael-128", "aes-128-cbc"}, - {NULL, NULL} -}; - -/* PUBLIC FUNCTIONS */ - -int -px_find_digest(const char *name, PX_MD ** res) -{ - struct int_digest *p; - PX_MD *h; - - for (p = int_digest_list; p->name; p++) - if (!strcasecmp(p->name, name)) - { - h = px_alloc(sizeof(*h)); - p->init(h); - - *res = h; - - return 0; - } - return -1; -} - -int -px_find_cipher(const char *name, PX_Cipher ** res) -{ - int i; - PX_Cipher *c = NULL; - - name = px_resolve_alias(int_aliases, name); - - for (i = 0; int_ciphers[i].name; i++) - if (!strcmp(int_ciphers[i].name, name)) - { - c = int_ciphers[i].load(); - break; - } - - if (c == NULL) - return -1; - - *res = c; - return 0; -} diff --git a/contrib/pgcrypto/md5.c b/contrib/pgcrypto/md5.c deleted file mode 100644 index a44ea6f857..0000000000 --- a/contrib/pgcrypto/md5.c +++ /dev/null @@ -1,403 +0,0 @@ -/* $Id: md5.c,v 1.9 2001/11/29 19:40:37 momjian Exp $ */ -/* $KAME: md5.c,v 1.3 2000/02/22 14:01:17 itojun Exp $ */ - -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "postgres.h" -#include "px.h" - -#include "md5.h" - -#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s)))) - -#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z))) -#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z))) -#define H(X, Y, Z) ((X) ^ (Y) ^ (Z)) -#define I(X, Y, Z) ((Y) ^ ((X) | (~Z))) - -#define ROUND1(a, b, c, d, k, s, i) \ -do { \ - (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \ - (a) = SHIFT((a), (s)); \ - (a) = (b) + (a); \ -} while (0) - -#define ROUND2(a, b, c, d, k, s, i) \ -do { \ - (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \ - (a) = SHIFT((a), (s)); \ - (a) = (b) + (a); \ -} while (0) - -#define ROUND3(a, b, c, d, k, s, i) \ -do { \ - (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \ - (a) = SHIFT((a), (s)); \ - (a) = (b) + (a); \ -} while (0) - -#define ROUND4(a, b, c, d, k, s, i) \ -do { \ - (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \ - (a) = SHIFT((a), (s)); \ - (a) = (b) + (a); \ -} while (0) - -#define Sa 7 -#define Sb 12 -#define Sc 17 -#define Sd 22 - -#define Se 5 -#define Sf 9 -#define Sg 14 -#define Sh 20 - -#define Si 4 -#define Sj 11 -#define Sk 16 -#define Sl 23 - -#define Sm 6 -#define Sn 10 -#define So 15 -#define Sp 21 - -#define MD5_A0 0x67452301 -#define MD5_B0 0xefcdab89 -#define MD5_C0 0x98badcfe -#define MD5_D0 0x10325476 - -/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */ -static const uint32 T[65] = { - 0, - 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, - 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, - 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, - 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, - - 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, - 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8, - 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, - 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, - - 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, - 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, - 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05, - 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, - - 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, - 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, - 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, - 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, -}; - -static const uint8 md5_paddat[MD5_BUFLEN] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -}; - -static void md5_calc(uint8 *, md5_ctxt *); - -void -md5_init(md5_ctxt * ctxt) -{ - ctxt->md5_n = 0; - ctxt->md5_i = 0; - ctxt->md5_sta = MD5_A0; - ctxt->md5_stb = MD5_B0; - ctxt->md5_stc = MD5_C0; - ctxt->md5_std = MD5_D0; - bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf)); -} - -void -md5_loop(md5_ctxt * ctxt, const uint8 *input, unsigned len) -{ - unsigned int gap, - i; - - ctxt->md5_n += len * 8; /* byte to bit */ - gap = MD5_BUFLEN - ctxt->md5_i; - - if (len >= gap) - { - bcopy((void *) input, (void *) (ctxt->md5_buf + ctxt->md5_i), - gap); - md5_calc(ctxt->md5_buf, ctxt); - - for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) - md5_calc((uint8 *) (input + i), ctxt); - - ctxt->md5_i = len - i; - bcopy((void *) (input + i), (void *) ctxt->md5_buf, ctxt->md5_i); - } - else - { - bcopy((void *) input, (void *) (ctxt->md5_buf + ctxt->md5_i), - len); - ctxt->md5_i += len; - } -} - -void -md5_pad(md5_ctxt * ctxt) -{ - unsigned int gap; - - /* Don't count up padding. Keep md5_n. */ - gap = MD5_BUFLEN - ctxt->md5_i; - if (gap > 8) - { - bcopy((void *) md5_paddat, - (void *) (ctxt->md5_buf + ctxt->md5_i), - gap - sizeof(ctxt->md5_n)); - } - else - { - /* including gap == 8 */ - bcopy((void *) md5_paddat, (void *) (ctxt->md5_buf + ctxt->md5_i), - gap); - md5_calc(ctxt->md5_buf, ctxt); - bcopy((void *) (md5_paddat + gap), - (void *) ctxt->md5_buf, - MD5_BUFLEN - sizeof(ctxt->md5_n)); - } - - /* 8 byte word */ -#if BYTE_ORDER == LITTLE_ENDIAN - bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8); -#endif -#if BYTE_ORDER == BIG_ENDIAN - ctxt->md5_buf[56] = ctxt->md5_n8[7]; - ctxt->md5_buf[57] = ctxt->md5_n8[6]; - ctxt->md5_buf[58] = ctxt->md5_n8[5]; - ctxt->md5_buf[59] = ctxt->md5_n8[4]; - ctxt->md5_buf[60] = ctxt->md5_n8[3]; - ctxt->md5_buf[61] = ctxt->md5_n8[2]; - ctxt->md5_buf[62] = ctxt->md5_n8[1]; - ctxt->md5_buf[63] = ctxt->md5_n8[0]; -#endif - - md5_calc(ctxt->md5_buf, ctxt); -} - -void -md5_result(uint8 *digest, md5_ctxt * ctxt) -{ - /* 4 byte words */ -#if BYTE_ORDER == LITTLE_ENDIAN - bcopy(&ctxt->md5_st8[0], digest, 16); -#endif -#if BYTE_ORDER == BIG_ENDIAN - digest[0] = ctxt->md5_st8[3]; - digest[1] = ctxt->md5_st8[2]; - digest[2] = ctxt->md5_st8[1]; - digest[3] = ctxt->md5_st8[0]; - digest[4] = ctxt->md5_st8[7]; - digest[5] = ctxt->md5_st8[6]; - digest[6] = ctxt->md5_st8[5]; - digest[7] = ctxt->md5_st8[4]; - digest[8] = ctxt->md5_st8[11]; - digest[9] = ctxt->md5_st8[10]; - digest[10] = ctxt->md5_st8[9]; - digest[11] = ctxt->md5_st8[8]; - digest[12] = ctxt->md5_st8[15]; - digest[13] = ctxt->md5_st8[14]; - digest[14] = ctxt->md5_st8[13]; - digest[15] = ctxt->md5_st8[12]; -#endif -} - -#if BYTE_ORDER == BIG_ENDIAN -static uint32 X[16]; -#endif - -static void -md5_calc(uint8 *b64, md5_ctxt * ctxt) -{ - uint32 A = ctxt->md5_sta; - uint32 B = ctxt->md5_stb; - uint32 C = ctxt->md5_stc; - uint32 D = ctxt->md5_std; - -#if BYTE_ORDER == LITTLE_ENDIAN - uint32 *X = (uint32 *) b64; -#endif -#if BYTE_ORDER == BIG_ENDIAN - /* 4 byte words */ - /* what a brute force but fast! */ - uint8 *y = (uint8 *) X; - - y[0] = b64[3]; - y[1] = b64[2]; - y[2] = b64[1]; - y[3] = b64[0]; - y[4] = b64[7]; - y[5] = b64[6]; - y[6] = b64[5]; - y[7] = b64[4]; - y[8] = b64[11]; - y[9] = b64[10]; - y[10] = b64[9]; - y[11] = b64[8]; - y[12] = b64[15]; - y[13] = b64[14]; - y[14] = b64[13]; - y[15] = b64[12]; - y[16] = b64[19]; - y[17] = b64[18]; - y[18] = b64[17]; - y[19] = b64[16]; - y[20] = b64[23]; - y[21] = b64[22]; - y[22] = b64[21]; - y[23] = b64[20]; - y[24] = b64[27]; - y[25] = b64[26]; - y[26] = b64[25]; - y[27] = b64[24]; - y[28] = b64[31]; - y[29] = b64[30]; - y[30] = b64[29]; - y[31] = b64[28]; - y[32] = b64[35]; - y[33] = b64[34]; - y[34] = b64[33]; - y[35] = b64[32]; - y[36] = b64[39]; - y[37] = b64[38]; - y[38] = b64[37]; - y[39] = b64[36]; - y[40] = b64[43]; - y[41] = b64[42]; - y[42] = b64[41]; - y[43] = b64[40]; - y[44] = b64[47]; - y[45] = b64[46]; - y[46] = b64[45]; - y[47] = b64[44]; - y[48] = b64[51]; - y[49] = b64[50]; - y[50] = b64[49]; - y[51] = b64[48]; - y[52] = b64[55]; - y[53] = b64[54]; - y[54] = b64[53]; - y[55] = b64[52]; - y[56] = b64[59]; - y[57] = b64[58]; - y[58] = b64[57]; - y[59] = b64[56]; - y[60] = b64[63]; - y[61] = b64[62]; - y[62] = b64[61]; - y[63] = b64[60]; -#endif - - ROUND1(A, B, C, D, 0, Sa, 1); - ROUND1(D, A, B, C, 1, Sb, 2); - ROUND1(C, D, A, B, 2, Sc, 3); - ROUND1(B, C, D, A, 3, Sd, 4); - ROUND1(A, B, C, D, 4, Sa, 5); - ROUND1(D, A, B, C, 5, Sb, 6); - ROUND1(C, D, A, B, 6, Sc, 7); - ROUND1(B, C, D, A, 7, Sd, 8); - ROUND1(A, B, C, D, 8, Sa, 9); - ROUND1(D, A, B, C, 9, Sb, 10); - ROUND1(C, D, A, B, 10, Sc, 11); - ROUND1(B, C, D, A, 11, Sd, 12); - ROUND1(A, B, C, D, 12, Sa, 13); - ROUND1(D, A, B, C, 13, Sb, 14); - ROUND1(C, D, A, B, 14, Sc, 15); - ROUND1(B, C, D, A, 15, Sd, 16); - - ROUND2(A, B, C, D, 1, Se, 17); - ROUND2(D, A, B, C, 6, Sf, 18); - ROUND2(C, D, A, B, 11, Sg, 19); - ROUND2(B, C, D, A, 0, Sh, 20); - ROUND2(A, B, C, D, 5, Se, 21); - ROUND2(D, A, B, C, 10, Sf, 22); - ROUND2(C, D, A, B, 15, Sg, 23); - ROUND2(B, C, D, A, 4, Sh, 24); - ROUND2(A, B, C, D, 9, Se, 25); - ROUND2(D, A, B, C, 14, Sf, 26); - ROUND2(C, D, A, B, 3, Sg, 27); - ROUND2(B, C, D, A, 8, Sh, 28); - ROUND2(A, B, C, D, 13, Se, 29); - ROUND2(D, A, B, C, 2, Sf, 30); - ROUND2(C, D, A, B, 7, Sg, 31); - ROUND2(B, C, D, A, 12, Sh, 32); - - ROUND3(A, B, C, D, 5, Si, 33); - ROUND3(D, A, B, C, 8, Sj, 34); - ROUND3(C, D, A, B, 11, Sk, 35); - ROUND3(B, C, D, A, 14, Sl, 36); - ROUND3(A, B, C, D, 1, Si, 37); - ROUND3(D, A, B, C, 4, Sj, 38); - ROUND3(C, D, A, B, 7, Sk, 39); - ROUND3(B, C, D, A, 10, Sl, 40); - ROUND3(A, B, C, D, 13, Si, 41); - ROUND3(D, A, B, C, 0, Sj, 42); - ROUND3(C, D, A, B, 3, Sk, 43); - ROUND3(B, C, D, A, 6, Sl, 44); - ROUND3(A, B, C, D, 9, Si, 45); - ROUND3(D, A, B, C, 12, Sj, 46); - ROUND3(C, D, A, B, 15, Sk, 47); - ROUND3(B, C, D, A, 2, Sl, 48); - - ROUND4(A, B, C, D, 0, Sm, 49); - ROUND4(D, A, B, C, 7, Sn, 50); - ROUND4(C, D, A, B, 14, So, 51); - ROUND4(B, C, D, A, 5, Sp, 52); - ROUND4(A, B, C, D, 12, Sm, 53); - ROUND4(D, A, B, C, 3, Sn, 54); - ROUND4(C, D, A, B, 10, So, 55); - ROUND4(B, C, D, A, 1, Sp, 56); - ROUND4(A, B, C, D, 8, Sm, 57); - ROUND4(D, A, B, C, 15, Sn, 58); - ROUND4(C, D, A, B, 6, So, 59); - ROUND4(B, C, D, A, 13, Sp, 60); - ROUND4(A, B, C, D, 4, Sm, 61); - ROUND4(D, A, B, C, 11, Sn, 62); - ROUND4(C, D, A, B, 2, So, 63); - ROUND4(B, C, D, A, 9, Sp, 64); - - ctxt->md5_sta += A; - ctxt->md5_stb += B; - ctxt->md5_stc += C; - ctxt->md5_std += D; -} diff --git a/contrib/pgcrypto/md5.h b/contrib/pgcrypto/md5.h deleted file mode 100644 index feadee2e80..0000000000 --- a/contrib/pgcrypto/md5.h +++ /dev/null @@ -1,79 +0,0 @@ -/* $Id: md5.h,v 1.7 2001/11/05 17:46:23 momjian Exp $ */ -/* $KAME: md5.h,v 1.3 2000/02/22 14:01:18 itojun Exp $ */ - -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _NETINET6_MD5_H_ -#define _NETINET6_MD5_H_ - -#define MD5_BUFLEN 64 - -typedef struct -{ - union - { - uint32 md5_state32[4]; - uint8 md5_state8[16]; - } md5_st; - -#define md5_sta md5_st.md5_state32[0] -#define md5_stb md5_st.md5_state32[1] -#define md5_stc md5_st.md5_state32[2] -#define md5_std md5_st.md5_state32[3] -#define md5_st8 md5_st.md5_state8 - - union - { - uint64 md5_count64; - uint8 md5_count8[8]; - } md5_count; -#define md5_n md5_count.md5_count64 -#define md5_n8 md5_count.md5_count8 - - unsigned int md5_i; - uint8 md5_buf[MD5_BUFLEN]; -} md5_ctxt; - -extern void md5_init(md5_ctxt *); -extern void md5_loop(md5_ctxt *, const uint8 *, unsigned int); -extern void md5_pad(md5_ctxt *); -extern void md5_result(uint8 *, md5_ctxt *); - -/* compatibility */ -#define MD5_CTX md5_ctxt -#define MD5Init(x) md5_init((x)) -#define MD5Update(x, y, z) md5_loop((x), (y), (z)) -#define MD5Final(x, y) \ -do { \ - md5_pad((y)); \ - md5_result((x), (y)); \ -} while (0) - -#endif /* ! _NETINET6_MD5_H_ */ diff --git a/contrib/pgcrypto/mhash.c b/contrib/pgcrypto/mhash.c deleted file mode 100644 index d0be0a62d5..0000000000 --- a/contrib/pgcrypto/mhash.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * mhash.c - * Wrapper for mhash and mcrypt libraries. - * - * Copyright (c) 2001 Marko Kreen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: mhash.c,v 1.7 2001/11/20 18:54:07 momjian Exp $ - */ - -#include - -#include "px.h" - -#include -#include - -#define MAX_KEY_LENGTH 512 -#define MAX_IV_LENGTH 128 - -#define DEF_KEY_LEN 16 - - -/* DIGEST */ - -static unsigned -digest_result_size(PX_MD * h) -{ - MHASH mh = (MHASH) h->p.ptr; - hashid id = mhash_get_mhash_algo(mh); - - return mhash_get_block_size(id); -} - -static unsigned -digest_block_size(PX_MD * h) -{ - MHASH mh = (MHASH) h->p.ptr; - hashid id = mhash_get_mhash_algo(mh); - - return mhash_get_hash_pblock(id); -} - -static void -digest_reset(PX_MD * h) -{ - MHASH mh = (MHASH) h->p.ptr; - hashid id = mhash_get_mhash_algo(mh); - uint8 *res = mhash_end(mh); - - mhash_free(res); - mh = mhash_init(id); - h->p.ptr = mh; -} - -static void -digest_update(PX_MD * h, const uint8 *data, unsigned dlen) -{ - MHASH mh = (MHASH) h->p.ptr; - - mhash(mh, data, dlen); -} - -static void -digest_finish(PX_MD * h, uint8 *dst) -{ - MHASH mh = (MHASH) h->p.ptr; - unsigned hlen = digest_result_size(h); - hashid id = mhash_get_mhash_algo(mh); - uint8 *buf = mhash_end(mh); - - memcpy(dst, buf, hlen); - mhash_free(buf); - - mh = mhash_init(id); - h->p.ptr = mh; -} - -static void -digest_free(PX_MD * h) -{ - MHASH mh = (MHASH) h->p.ptr; - uint8 *buf = mhash_end(mh); - - mhash_free(buf); - - px_free(h); -} - -/* ENCRYPT / DECRYPT */ - -static unsigned -cipher_block_size(PX_Cipher * c) -{ - MCRYPT ctx = (MCRYPT) c->ptr; - - return mcrypt_enc_get_block_size(ctx); -} - -static unsigned -cipher_key_size(PX_Cipher * c) -{ - MCRYPT ctx = (MCRYPT) c->ptr; - - return mcrypt_enc_get_key_size(ctx); -} - -static unsigned -cipher_iv_size(PX_Cipher * c) -{ - MCRYPT ctx = (MCRYPT) c->ptr; - - return mcrypt_enc_mode_has_iv(ctx) - ? mcrypt_enc_get_iv_size(ctx) : 0; -} - -static int -cipher_init(PX_Cipher * c, const uint8 *key, unsigned klen, const uint8 *iv) -{ - int err; - MCRYPT ctx = (MCRYPT) c->ptr; - - err = mcrypt_generic_init(ctx, (char *) key, klen, (char *) iv); - if (err < 0) - elog(ERROR, "mcrypt_generic_init error: %s", mcrypt_strerror(err)); - - c->pstat = 1; - return 0; -} - -static int -cipher_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) -{ - int err; - MCRYPT ctx = (MCRYPT) c->ptr; - - memcpy(res, data, dlen); - - err = mcrypt_generic(ctx, res, dlen); - if (err < 0) - elog(ERROR, "mcrypt_generic error: %s", mcrypt_strerror(err)); - return 0; -} - -static int -cipher_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) -{ - int err; - MCRYPT ctx = (MCRYPT) c->ptr; - - memcpy(res, data, dlen); - - err = mdecrypt_generic(ctx, res, dlen); - if (err < 0) - elog(ERROR, "mdecrypt_generic error: %s", mcrypt_strerror(err)); - return 0; -} - - -static void -cipher_free(PX_Cipher * c) -{ - MCRYPT ctx = (MCRYPT) c->ptr; - - if (c->pstat) - mcrypt_generic_end(ctx); - else - mcrypt_module_close(ctx); - - px_free(c); -} - -/* Helper functions */ - -static int -find_hashid(const char *name) -{ - int res = -1; - size_t hnum, - b, - i; - char *mname; - - hnum = mhash_count(); - for (i = 0; i <= hnum; i++) - { - mname = mhash_get_hash_name(i); - if (mname == NULL) - continue; - b = strcasecmp(name, mname); - free(mname); - if (!b) - { - res = i; - break; - } - } - - return res; -} - -static char *modes[] = { - "ecb", "cbc", "cfb", "ofb", "nofb", "stream", - "ofb64", "cfb64", NULL -}; - -static PX_Alias aliases[] = { - {"bf", "blowfish"}, - {"3des", "tripledes"}, - {"des3", "tripledes"}, - {"aes", "rijndael-128"}, - {"rijndael", "rijndael-128"}, - {"aes-128", "rijndael-128"}, - {"aes-192", "rijndael-192"}, - {"aes-256", "rijndael-256"}, - {NULL, NULL} -}; - -static PX_Alias mode_aliases[] = { -#if 0 /* N/A */ - {"cfb", "ncfb"}, - {"ofb", "nofb"}, - {"cfb64", "ncfb"}, -#endif - /* { "ofb64", "nofb" }, not sure it works */ - {"cfb8", "cfb"}, - {"ofb8", "ofb"}, - {NULL, NULL} -}; - -static int -is_mode(char *s) -{ - char **p; - - if (*s >= '0' && *s <= '9') - return 0; - - for (p = modes; *p; p++) - if (!strcmp(s, *p)) - return 1; - - return 0; -} - -/* PUBLIC FUNCTIONS */ - -int -px_find_digest(const char *name, PX_MD ** res) -{ - PX_MD *h; - MHASH mh; - int i; - - i = find_hashid(name); - if (i < 0) - return -1; - - mh = mhash_init(i); - h = px_alloc(sizeof(*h)); - h->p.ptr = (void *) mh; - - h->result_size = digest_result_size; - h->block_size = digest_block_size; - h->reset = digest_reset; - h->update = digest_update; - h->finish = digest_finish; - h->free = digest_free; - - *res = h; - return 0; -} - - -int -px_find_cipher(const char *name, PX_Cipher ** res) -{ - char nbuf[PX_MAX_NAMELEN + 1]; - const char *mode = NULL; - char *p; - MCRYPT ctx; - - PX_Cipher *c; - - strcpy(nbuf, name); - - if ((p = strrchr(nbuf, '-')) != NULL) - { - if (is_mode(p + 1)) - { - mode = p + 1; - *p = 0; - } - } - - name = px_resolve_alias(aliases, nbuf); - - if (!mode) - { - mode = "cbc"; - - /* - * if (mcrypt_module_is_block_algorithm(name, NULL)) mode = "cbc"; - * else mode = "stream"; - */ - } - mode = px_resolve_alias(mode_aliases, mode); - - ctx = mcrypt_module_open((char *) name, NULL, (char *) mode, NULL); - if (ctx == (void *) MCRYPT_FAILED) - return -1; - - c = palloc(sizeof *c); - c->iv_size = cipher_iv_size; - c->key_size = cipher_key_size; - c->block_size = cipher_block_size; - c->init = cipher_init; - c->encrypt = cipher_encrypt; - c->decrypt = cipher_decrypt; - c->free = cipher_free; - c->ptr = ctx; - c->pstat = 0; - - *res = c; - return 0; -} diff --git a/contrib/pgcrypto/misc.c b/contrib/pgcrypto/misc.c deleted file mode 100644 index 5c803c0d5b..0000000000 --- a/contrib/pgcrypto/misc.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 1999 - * University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER - * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN - * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD: src/lib/libcrypt/misc.c,v 1.1 1999/09/20 12:45:49 markm Exp $ - * - */ - -#include "px-crypt.h" - -char px_crypt_a64[] = -"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -/* 0000000000111111111122222222223333333333444444444455555555556666 */ -/* 0123456789012345678901234567890123456789012345678901234567890123 */ - -void -px_crypt_to64(char *s, unsigned long v, int n) -{ - while (--n >= 0) - { - *s++ = px_crypt_a64[v & 0x3f]; - v >>= 6; - } -} diff --git a/contrib/pgcrypto/openssl.c b/contrib/pgcrypto/openssl.c deleted file mode 100644 index 1ea1778b9b..0000000000 --- a/contrib/pgcrypto/openssl.c +++ /dev/null @@ -1,460 +0,0 @@ -/* - * openssl.c - * Wrapper for OpenSSL library. - * - * Copyright (c) 2001 Marko Kreen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: openssl.c,v 1.10 2001/11/20 18:54:07 momjian Exp $ - */ - -#include - -#include "px.h" - -#include -#include - -static unsigned -digest_result_size(PX_MD * h) -{ - return EVP_MD_CTX_size((EVP_MD_CTX *) h->p.ptr); -} - -static unsigned -digest_block_size(PX_MD * h) -{ - return EVP_MD_CTX_block_size((EVP_MD_CTX *) h->p.ptr); -} - -static void -digest_reset(PX_MD * h) -{ - EVP_MD_CTX *ctx = (EVP_MD_CTX *) h->p.ptr; - const EVP_MD *md; - - md = EVP_MD_CTX_md(ctx); - - EVP_DigestInit(ctx, md); -} - -static void -digest_update(PX_MD * h, const uint8 *data, unsigned dlen) -{ - EVP_MD_CTX *ctx = (EVP_MD_CTX *) h->p.ptr; - - EVP_DigestUpdate(ctx, data, dlen); -} - -static void -digest_finish(PX_MD * h, uint8 *dst) -{ - EVP_MD_CTX *ctx = (EVP_MD_CTX *) h->p.ptr; - - EVP_DigestFinal(ctx, dst, NULL); -} - -static void -digest_free(PX_MD * h) -{ - EVP_MD_CTX *ctx = (EVP_MD_CTX *) h->p.ptr; - - px_free(ctx); - px_free(h); -} - -/* CIPHERS */ - -/* - * The problem with OpenSSL is that the EVP* family - * of functions does not allow enough flexibility - * and forces some of the parameters (keylen, - * padding) to SSL defaults. - */ - - -typedef struct -{ - union - { - struct - { - BF_KEY key; - int num; - } bf; - EVP_CIPHER_CTX evp_ctx; - } u; - const EVP_CIPHER *evp_ciph; - uint8 key[EVP_MAX_KEY_LENGTH]; - uint8 iv[EVP_MAX_IV_LENGTH]; - unsigned klen; - unsigned init; -} ossldata; - -/* generic EVP */ - -static unsigned -gen_evp_block_size(PX_Cipher * c) -{ - ossldata *od = (ossldata *) c->ptr; - - return EVP_CIPHER_block_size(od->evp_ciph); -} - -static unsigned -gen_evp_key_size(PX_Cipher * c) -{ - ossldata *od = (ossldata *) c->ptr; - - return EVP_CIPHER_key_length(od->evp_ciph); -} - -static unsigned -gen_evp_iv_size(PX_Cipher * c) -{ - unsigned ivlen; - ossldata *od = (ossldata *) c->ptr; - - ivlen = EVP_CIPHER_iv_length(od->evp_ciph); - return ivlen; -} - -static void -gen_evp_free(PX_Cipher * c) -{ - ossldata *od = (ossldata *) c->ptr; - - memset(od, 0, sizeof(*od)); - pfree(od); - pfree(c); -} - -/* fun */ - -static int -gen_evp_init(PX_Cipher * c, const uint8 *key, unsigned klen, const uint8 *iv) -{ - ossldata *od = (ossldata *) c->ptr; - unsigned bs = gen_evp_block_size(c); - - if (iv) - memcpy(od->iv, iv, bs); - else - memset(od->iv, 0, bs); - memcpy(od->key, key, klen); - od->klen = klen; - od->init = 0; - return 0; -} - -static void -_gen_init(PX_Cipher * c, int enc) -{ - ossldata *od = c->ptr; - - od->evp_ciph->init(&od->u.evp_ctx, od->key, od->iv, enc); - od->init = 1; - od->u.evp_ctx.encrypt = enc; -} - -static int -gen_evp_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) -{ - ossldata *od = c->ptr; - - if (!od->init) - _gen_init(c, 1); - od->evp_ciph->do_cipher(&od->u.evp_ctx, res, data, dlen); - return 0; -} - -static int -gen_evp_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) -{ - ossldata *od = c->ptr; - - if (!od->init) - _gen_init(c, 0); - od->evp_ciph->do_cipher(&od->u.evp_ctx, res, data, dlen); - return 0; -} - -/* Blowfish */ - -static int -bf_init(PX_Cipher * c, const uint8 *key, unsigned klen, const uint8 *iv) -{ - ossldata *od = c->ptr; - - BF_set_key(&od->u.bf.key, klen, key); - if (iv) - memcpy(od->iv, iv, BF_BLOCK); - else - memset(od->iv, 0, BF_BLOCK); - od->u.bf.num = 0; - return 0; -} - -static int -bf_ecb_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) -{ - unsigned bs = gen_evp_block_size(c), - i; - ossldata *od = c->ptr; - - for (i = 0; i < dlen / bs; i++) - BF_ecb_encrypt(data + i * bs, res + i * bs, &od->u.bf.key, BF_ENCRYPT); - return 0; -} - -static int -bf_ecb_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) -{ - unsigned bs = gen_evp_block_size(c), - i; - ossldata *od = c->ptr; - - for (i = 0; i < dlen / bs; i++) - BF_ecb_encrypt(data + i * bs, res + i * bs, &od->u.bf.key, BF_DECRYPT); - return 0; -} - -static int -bf_cbc_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) -{ - ossldata *od = c->ptr; - - BF_cbc_encrypt(data, res, dlen, &od->u.bf.key, od->iv, BF_ENCRYPT); - return 0; -} - -static int -bf_cbc_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) -{ - ossldata *od = c->ptr; - - BF_cbc_encrypt(data, res, dlen, &od->u.bf.key, od->iv, BF_DECRYPT); - return 0; -} - -static int -bf_cfb64_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) -{ - ossldata *od = c->ptr; - - BF_cfb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv, - &od->u.bf.num, BF_ENCRYPT); - return 0; -} - -static int -bf_cfb64_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) -{ - ossldata *od = c->ptr; - - BF_cfb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv, - &od->u.bf.num, BF_DECRYPT); - return 0; -} - -static int -bf_ofb64_encrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) -{ - ossldata *od = c->ptr; - - BF_ofb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv, &od->u.bf.num); - return 0; -} - -static int -bf_ofb64_decrypt(PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res) -{ - ossldata *od = c->ptr; - - BF_ofb64_encrypt(data, res, dlen, &od->u.bf.key, od->iv, &od->u.bf.num); - return 0; -} - -/* - * aliases - */ - -static PX_Alias ossl_aliases[] = { - {"bf", "bf-cbc"}, - {"blowfish", "bf-cbc"}, - {"blowfish-cbc", "bf-cbc"}, - {"blowfish-ecb", "bf-ecb"}, - {"blowfish-cfb", "bf-cfb"}, - {"blowfish-ofb", "bf-ofb"}, - {NULL} -}; - -/* -static PX_Alias ossl_mode_aliases [] = { - { "cfb64", "cfb" }, - { "ofb64", "ofb" }, - { NULL } -};*/ - -/* - * Special handlers - */ -struct -{ - char *name; - PX_Cipher cf; -} spec_types[] = - -{ - { - "bf-cbc", - { - gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size, - bf_init, bf_cbc_encrypt, bf_cbc_decrypt, gen_evp_free - } - }, - { - "bf-ecb", - { - gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size, - bf_init, bf_ecb_encrypt, bf_ecb_decrypt, gen_evp_free - } - }, - { - "bf-cfb", - { - gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size, - bf_init, bf_cfb64_encrypt, bf_cfb64_decrypt, gen_evp_free - } - }, - { - "bf-ofb", - { - gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size, - bf_init, bf_ofb64_encrypt, bf_ofb64_decrypt, gen_evp_free - } - }, - { - NULL - } -}; - -/* - * Generic EVP_* functions handler - */ -static PX_Cipher gen_evp_handler = { - gen_evp_block_size, gen_evp_key_size, gen_evp_iv_size, - gen_evp_init, gen_evp_encrypt, gen_evp_decrypt, gen_evp_free -}; - -static int px_openssl_initialized = 0; - -/* ATM not needed -static void *o_alloc(unsigned s) { return px_alloc(s); } -static void *o_realloc(void *p) { return px_realloc(p); } -static void o_free(void *p) { px_free(p); } -*/ - -/* PUBLIC functions */ - -int -px_find_digest(const char *name, PX_MD ** res) -{ - const EVP_MD *md; - EVP_MD_CTX *ctx; - PX_MD *h; - - if (!px_openssl_initialized) - { - px_openssl_initialized = 1; - /* CRYPTO_set_mem_functions(o_alloc, o_realloc, o_free); */ - OpenSSL_add_all_algorithms(); - } - - md = EVP_get_digestbyname(name); - if (md == NULL) - return -1; - - ctx = px_alloc(sizeof(*ctx)); - EVP_DigestInit(ctx, md); - - h = px_alloc(sizeof(*h)); - h->result_size = digest_result_size; - h->block_size = digest_block_size; - h->reset = digest_reset; - h->update = digest_update; - h->finish = digest_finish; - h->free = digest_free; - h->p.ptr = (void *) ctx; - - *res = h; - return 0; -} - - -int -px_find_cipher(const char *name, PX_Cipher ** res) -{ - unsigned i; - PX_Cipher *c = NULL, - *csrc; - ossldata *od; - - const EVP_CIPHER *evp_c; - - if (!px_openssl_initialized) - { - px_openssl_initialized = 1; - /* CRYPTO_set_mem_functions(o_alloc, o_realloc, o_free); */ - OpenSSL_add_all_algorithms(); - } - - name = px_resolve_alias(ossl_aliases, name); - evp_c = EVP_get_cipherbyname(name); - if (evp_c == NULL) - return -1; - - od = px_alloc(sizeof(*od)); - memset(od, 0, sizeof(*od)); - od->evp_ciph = evp_c; - - csrc = NULL; - - for (i = 0; spec_types[i].name; i++) - if (!strcmp(name, spec_types[i].name)) - { - csrc = &spec_types[i].cf; - break; - } - - if (csrc == NULL) - csrc = &gen_evp_handler; - - c = px_alloc(sizeof(*c)); - memcpy(c, csrc, sizeof(*c)); - c->ptr = od; - - *res = c; - return 0; -} diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c deleted file mode 100644 index d3dc36dc9a..0000000000 --- a/contrib/pgcrypto/pgcrypto.c +++ /dev/null @@ -1,568 +0,0 @@ -/* - * pgcrypto.c - * Various cryptographic stuff for PostgreSQL. - * - * Copyright (c) 2001 Marko Kreen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: pgcrypto.c,v 1.12 2001/12/30 23:09:41 tgl Exp $ - */ - -#include -#include -#include - -#include "px.h" -#include "px-crypt.h" -#include "pgcrypto.h" - -/* private stuff */ - -typedef int (*PFN) (const char *name, void **res); -static void * - find_provider(text *name, PFN pf, char *desc, int silent); - -/* SQL function: hash(text, text) returns text */ -PG_FUNCTION_INFO_V1(pg_digest); - -Datum -pg_digest(PG_FUNCTION_ARGS) -{ - bytea *arg; - text *name; - unsigned len, - hlen; - PX_MD *md; - bytea *res; - - if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) - PG_RETURN_NULL(); - - name = PG_GETARG_TEXT_P(1); - - /* will give error if fails */ - md = find_provider(name, (PFN) px_find_digest, "Digest", 0); - - hlen = px_md_result_size(md); - - res = (text *) palloc(hlen + VARHDRSZ); - VARATT_SIZEP(res) = hlen + VARHDRSZ; - - arg = PG_GETARG_BYTEA_P(0); - len = VARSIZE(arg) - VARHDRSZ; - - px_md_update(md, VARDATA(arg), len); - px_md_finish(md, VARDATA(res)); - px_md_free(md); - - PG_FREE_IF_COPY(arg, 0); - PG_FREE_IF_COPY(name, 1); - - PG_RETURN_BYTEA_P(res); -} - -/* check if given hash exists */ -PG_FUNCTION_INFO_V1(pg_digest_exists); - -Datum -pg_digest_exists(PG_FUNCTION_ARGS) -{ - text *name; - PX_MD *res; - - if (PG_ARGISNULL(0)) - PG_RETURN_NULL(); - - name = PG_GETARG_TEXT_P(0); - - res = find_provider(name, (PFN) px_find_digest, "Digest", 1); - - PG_FREE_IF_COPY(name, 0); - - if (res == NULL) - PG_RETURN_BOOL(false); - - res->free(res); - - PG_RETURN_BOOL(true); -} - -/* SQL function: hmac(data:text, key:text, type:text) */ -PG_FUNCTION_INFO_V1(pg_hmac); - -Datum -pg_hmac(PG_FUNCTION_ARGS) -{ - bytea *arg; - bytea *key; - text *name; - unsigned len, - hlen, - klen; - PX_HMAC *h; - bytea *res; - - if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2)) - PG_RETURN_NULL(); - - name = PG_GETARG_TEXT_P(2); - - /* will give error if fails */ - h = find_provider(name, (PFN) px_find_hmac, "HMAC", 0); - - hlen = px_hmac_result_size(h); - - res = (text *) palloc(hlen + VARHDRSZ); - VARATT_SIZEP(res) = hlen + VARHDRSZ; - - arg = PG_GETARG_BYTEA_P(0); - key = PG_GETARG_BYTEA_P(1); - len = VARSIZE(arg) - VARHDRSZ; - klen = VARSIZE(key) - VARHDRSZ; - - px_hmac_init(h, VARDATA(key), klen); - px_hmac_update(h, VARDATA(arg), len); - px_hmac_finish(h, VARDATA(res)); - px_hmac_free(h); - - PG_FREE_IF_COPY(arg, 0); - PG_FREE_IF_COPY(key, 1); - PG_FREE_IF_COPY(name, 2); - - PG_RETURN_BYTEA_P(res); -} - -/* check if given hmac type exists */ -PG_FUNCTION_INFO_V1(pg_hmac_exists); - -Datum -pg_hmac_exists(PG_FUNCTION_ARGS) -{ - text *name; - PX_HMAC *h; - - if (PG_ARGISNULL(0)) - PG_RETURN_NULL(); - - name = PG_GETARG_TEXT_P(0); - - h = find_provider(name, (PFN) px_find_hmac, "HMAC", 1); - - PG_FREE_IF_COPY(name, 0); - - if (h != NULL) - { - px_hmac_free(h); - PG_RETURN_BOOL(true); - } - PG_RETURN_BOOL(false); -} - - -/* SQL function: pg_gen_salt(text) returns text */ -PG_FUNCTION_INFO_V1(pg_gen_salt); - -Datum -pg_gen_salt(PG_FUNCTION_ARGS) -{ - text *arg0; - unsigned len; - text *res; - char buf[PX_MAX_SALT_LEN + 1]; - - if (PG_ARGISNULL(0)) - PG_RETURN_NULL(); - - arg0 = PG_GETARG_TEXT_P(0); - - len = VARSIZE(arg0) - VARHDRSZ; - len = len > PX_MAX_SALT_LEN ? PX_MAX_SALT_LEN : len; - memcpy(buf, VARDATA(arg0), len); - buf[len] = 0; - len = px_gen_salt(buf, buf, 0); - if (len == 0) - elog(ERROR, "No such crypt algorithm"); - - res = (text *) palloc(len + VARHDRSZ); - VARATT_SIZEP(res) = len + VARHDRSZ; - memcpy(VARDATA(res), buf, len); - - PG_FREE_IF_COPY(arg0, 0); - - PG_RETURN_TEXT_P(res); -} - -/* SQL function: pg_gen_salt(text, int4) returns text */ -PG_FUNCTION_INFO_V1(pg_gen_salt_rounds); - -Datum -pg_gen_salt_rounds(PG_FUNCTION_ARGS) -{ - text *arg0; - int rounds; - unsigned len; - text *res; - char buf[PX_MAX_SALT_LEN + 1]; - - if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) - PG_RETURN_NULL(); - - arg0 = PG_GETARG_TEXT_P(0); - rounds = PG_GETARG_INT32(1); - - len = VARSIZE(arg0) - VARHDRSZ; - len = len > PX_MAX_SALT_LEN ? PX_MAX_SALT_LEN : len; - memcpy(buf, VARDATA(arg0), len); - buf[len] = 0; - len = px_gen_salt(buf, buf, rounds); - if (len == 0) - elog(ERROR, "No such crypt algorithm or bad number of rounds"); - - res = (text *) palloc(len + VARHDRSZ); - VARATT_SIZEP(res) = len + VARHDRSZ; - memcpy(VARDATA(res), buf, len); - - PG_FREE_IF_COPY(arg0, 0); - - PG_RETURN_TEXT_P(res); -} - -/* SQL function: pg_crypt(psw:text, salt:text) returns text */ -PG_FUNCTION_INFO_V1(pg_crypt); - -Datum -pg_crypt(PG_FUNCTION_ARGS) -{ - text *arg0; - text *arg1; - unsigned len0, - len1, - clen; - char *buf0, - *buf1, - *cres, - *resbuf; - text *res; - - if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) - PG_RETURN_NULL(); - - arg0 = PG_GETARG_TEXT_P(0); - arg1 = PG_GETARG_TEXT_P(1); - len0 = VARSIZE(arg0) - VARHDRSZ; - len1 = VARSIZE(arg1) - VARHDRSZ; - - buf0 = palloc(len0 + 1); - buf1 = palloc(len1 + 1); - - memcpy(buf0, VARDATA(arg0), len0); - memcpy(buf1, VARDATA(arg1), len1); - - buf0[len0] = '\0'; - buf1[len1] = '\0'; - - resbuf = palloc(PX_MAX_CRYPT); - - memset(resbuf, 0, PX_MAX_CRYPT); - - cres = px_crypt(buf0, buf1, resbuf, PX_MAX_CRYPT); - - pfree(buf0); - pfree(buf1); - - if (cres == NULL) - elog(ERROR, "crypt(3) returned NULL"); - - clen = strlen(cres); - - res = (text *) palloc(clen + VARHDRSZ); - VARATT_SIZEP(res) = clen + VARHDRSZ; - memcpy(VARDATA(res), cres, clen); - pfree(resbuf); - - PG_FREE_IF_COPY(arg0, 0); - PG_FREE_IF_COPY(arg1, 1); - - PG_RETURN_TEXT_P(res); -} - -/* SQL function: pg_encrypt(text, text, text) returns text */ -PG_FUNCTION_INFO_V1(pg_encrypt); - -Datum -pg_encrypt(PG_FUNCTION_ARGS) -{ - int err; - bytea *data, - *key, - *res; - text *type; - PX_Combo *c; - unsigned dlen, - klen, - rlen; - - if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2)) - PG_RETURN_NULL(); - - type = PG_GETARG_TEXT_P(2); - c = find_provider(type, (PFN) px_find_combo, "Cipher", 0); - - data = PG_GETARG_BYTEA_P(0); - key = PG_GETARG_BYTEA_P(1); - dlen = VARSIZE(data) - VARHDRSZ; - klen = VARSIZE(key) - VARHDRSZ; - - rlen = px_combo_encrypt_len(c, dlen); - res = palloc(VARHDRSZ + rlen); - - err = px_combo_init(c, VARDATA(key), klen, NULL, 0); - if (!err) - err = px_combo_encrypt(c, VARDATA(data), dlen, VARDATA(res), &rlen); - px_combo_free(c); - - PG_FREE_IF_COPY(data, 0); - PG_FREE_IF_COPY(key, 1); - PG_FREE_IF_COPY(type, 2); - - if (err) - { - pfree(res); - elog(ERROR, "encrypt error: %d", err); - } - - VARATT_SIZEP(res) = VARHDRSZ + rlen; - PG_RETURN_BYTEA_P(res); -} - -/* SQL function: pg_decrypt(text, text, text) returns text */ -PG_FUNCTION_INFO_V1(pg_decrypt); - -Datum -pg_decrypt(PG_FUNCTION_ARGS) -{ - int err; - bytea *data, - *key, - *res; - text *type; - PX_Combo *c; - unsigned dlen, - klen, - rlen; - - if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2)) - PG_RETURN_NULL(); - - type = PG_GETARG_TEXT_P(2); - c = find_provider(type, (PFN) px_find_combo, "Cipher", 0); - - data = PG_GETARG_BYTEA_P(0); - key = PG_GETARG_BYTEA_P(1); - dlen = VARSIZE(data) - VARHDRSZ; - klen = VARSIZE(key) - VARHDRSZ; - - rlen = px_combo_decrypt_len(c, dlen); - res = palloc(VARHDRSZ + rlen); - - err = px_combo_init(c, VARDATA(key), klen, NULL, 0); - if (!err) - err = px_combo_decrypt(c, VARDATA(data), dlen, VARDATA(res), &rlen); - - px_combo_free(c); - - if (err) - elog(ERROR, "decrypt error: %d", err); - - VARATT_SIZEP(res) = VARHDRSZ + rlen; - - PG_FREE_IF_COPY(data, 0); - PG_FREE_IF_COPY(key, 1); - PG_FREE_IF_COPY(type, 2); - - PG_RETURN_BYTEA_P(res); -} - -/* SQL function: pg_encrypt(text, text, text) returns text */ -PG_FUNCTION_INFO_V1(pg_encrypt_iv); - -Datum -pg_encrypt_iv(PG_FUNCTION_ARGS) -{ - int err; - bytea *data, - *key, - *iv, - *res; - text *type; - PX_Combo *c; - unsigned dlen, - klen, - ivlen, - rlen; - - if (PG_ARGISNULL(0) || PG_ARGISNULL(1) - || PG_ARGISNULL(2) || PG_ARGISNULL(3)) - PG_RETURN_NULL(); - - type = PG_GETARG_TEXT_P(3); - c = find_provider(type, (PFN) px_find_combo, "Cipher", 0); - - data = PG_GETARG_BYTEA_P(0); - key = PG_GETARG_BYTEA_P(1); - iv = PG_GETARG_BYTEA_P(2); - dlen = VARSIZE(data) - VARHDRSZ; - klen = VARSIZE(key) - VARHDRSZ; - ivlen = VARSIZE(iv) - VARHDRSZ; - - rlen = px_combo_encrypt_len(c, dlen); - res = palloc(VARHDRSZ + rlen); - - err = px_combo_init(c, VARDATA(key), klen, VARDATA(iv), ivlen); - if (!err) - px_combo_encrypt(c, VARDATA(data), dlen, VARDATA(res), &rlen); - - px_combo_free(c); - - if (err) - elog(ERROR, "encrypt_iv error: %d", err); - - VARATT_SIZEP(res) = VARHDRSZ + rlen; - - PG_FREE_IF_COPY(data, 0); - PG_FREE_IF_COPY(key, 1); - PG_FREE_IF_COPY(iv, 2); - PG_FREE_IF_COPY(type, 3); - - PG_RETURN_BYTEA_P(res); -} - -/* SQL function: pg_decrypt_iv(text, text, text) returns text */ -PG_FUNCTION_INFO_V1(pg_decrypt_iv); - -Datum -pg_decrypt_iv(PG_FUNCTION_ARGS) -{ - int err; - bytea *data, - *key, - *iv, - *res; - text *type; - PX_Combo *c; - unsigned dlen, - klen, - rlen, - ivlen; - - if (PG_ARGISNULL(0) || PG_ARGISNULL(1) - || PG_ARGISNULL(2) || PG_ARGISNULL(3)) - PG_RETURN_NULL(); - - type = PG_GETARG_TEXT_P(3); - c = find_provider(type, (PFN) px_find_combo, "Cipher", 0); - - data = PG_GETARG_BYTEA_P(0); - key = PG_GETARG_BYTEA_P(1); - iv = PG_GETARG_BYTEA_P(2); - dlen = VARSIZE(data) - VARHDRSZ; - klen = VARSIZE(key) - VARHDRSZ; - ivlen = VARSIZE(iv) - VARHDRSZ; - - rlen = px_combo_decrypt_len(c, dlen); - res = palloc(VARHDRSZ + rlen); - - err = px_combo_init(c, VARDATA(key), klen, VARDATA(iv), ivlen); - if (!err) - px_combo_decrypt(c, VARDATA(data), dlen, VARDATA(res), &rlen); - - px_combo_free(c); - - if (err) - elog(ERROR, "decrypt_iv error: %d", err); - - VARATT_SIZEP(res) = VARHDRSZ + rlen; - - PG_FREE_IF_COPY(data, 0); - PG_FREE_IF_COPY(key, 1); - PG_FREE_IF_COPY(iv, 2); - PG_FREE_IF_COPY(type, 3); - - PG_RETURN_BYTEA_P(res); -} - -/* SQL function: pg_decrypt(text, text, text) returns text */ -PG_FUNCTION_INFO_V1(pg_cipher_exists); - -Datum -pg_cipher_exists(PG_FUNCTION_ARGS) -{ - text *arg; - PX_Combo *c; - - if (PG_ARGISNULL(0)) - PG_RETURN_NULL(); - - arg = PG_GETARG_TEXT_P(0); - - c = find_provider(arg, (PFN) px_find_combo, "Cipher", 1); - if (c != NULL) - px_combo_free(c); - - PG_RETURN_BOOL((c != NULL) ? true : false); -} - - -static void * -find_provider(text *name, - PFN provider_lookup, - char *desc, int silent) -{ - void *res; - char buf[PX_MAX_NAMELEN + 1], - *p; - unsigned len; - unsigned i; - int err; - - len = VARSIZE(name) - VARHDRSZ; - if (len > PX_MAX_NAMELEN) - { - if (silent) - return NULL; - elog(ERROR, "%s type does not exist (name too long)", desc); - } - - p = VARDATA(name); - for (i = 0; i < len; i++) - buf[i] = tolower((unsigned char) p[i]); - buf[len] = 0; - - err = provider_lookup(buf, &res); - - if (err && !silent) - elog(ERROR, "%s type does not exist: '%s'", desc, buf); - - return err ? NULL : res; -} diff --git a/contrib/pgcrypto/pgcrypto.h b/contrib/pgcrypto/pgcrypto.h deleted file mode 100644 index 0d8c1174f2..0000000000 --- a/contrib/pgcrypto/pgcrypto.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * pgcrypto.h - * Header file for pgcrypto. - * - * Copyright (c) 2000 Marko Kreen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: pgcrypto.h,v 1.7 2001/10/28 06:25:41 momjian Exp $ - */ - -#ifndef _PG_CRYPTO_H -#define _PG_CRYPTO_H - -/* exported functions */ -Datum pg_digest(PG_FUNCTION_ARGS); -Datum pg_digest_exists(PG_FUNCTION_ARGS); -Datum pg_hmac(PG_FUNCTION_ARGS); -Datum pg_hmac_exists(PG_FUNCTION_ARGS); -Datum pg_gen_salt(PG_FUNCTION_ARGS); -Datum pg_gen_salt_rounds(PG_FUNCTION_ARGS); -Datum pg_crypt(PG_FUNCTION_ARGS); -Datum pg_encrypt(PG_FUNCTION_ARGS); -Datum pg_decrypt(PG_FUNCTION_ARGS); -Datum pg_encrypt_iv(PG_FUNCTION_ARGS); -Datum pg_decrypt_iv(PG_FUNCTION_ARGS); -Datum pg_cipher_exists(PG_FUNCTION_ARGS); - -#endif diff --git a/contrib/pgcrypto/pgcrypto.sql.in b/contrib/pgcrypto/pgcrypto.sql.in deleted file mode 100644 index 3efb2ed969..0000000000 --- a/contrib/pgcrypto/pgcrypto.sql.in +++ /dev/null @@ -1,75 +0,0 @@ - --- drop function digest(text, text); --- drop function digest(bytea, text); --- drop function digest_exists(text); --- drop function hmac(text, text, text); --- drop function hmac(bytea, bytea, text); --- drop function hmac_exists(text); --- drop function crypt(text, text); --- drop function gen_salt(text); --- drop function gen_salt(text, int4); --- drop function encrypt(bytea, bytea, text); --- drop function decrypt(bytea, bytea, text); --- drop function encrypt_iv(bytea, bytea, bytea, text); --- drop function decrypt_iv(bytea, bytea, bytea, text); --- drop function cipher_exists(text); - - - -CREATE FUNCTION digest(text, text) RETURNS bytea - AS 'MODULE_PATHNAME', - 'pg_digest' LANGUAGE 'C'; - -CREATE FUNCTION digest(bytea, text) RETURNS bytea - AS 'MODULE_PATHNAME', - 'pg_digest' LANGUAGE 'C'; - -CREATE FUNCTION digest_exists(text) RETURNS bool - AS 'MODULE_PATHNAME', - 'pg_digest_exists' LANGUAGE 'C'; - -CREATE FUNCTION hmac(text, text, text) RETURNS bytea - AS 'MODULE_PATHNAME', - 'pg_hmac' LANGUAGE 'C'; - -CREATE FUNCTION hmac(bytea, bytea, text) RETURNS bytea - AS 'MODULE_PATHNAME', - 'pg_hmac' LANGUAGE 'C'; - -CREATE FUNCTION hmac_exists(text) RETURNS bool - AS 'MODULE_PATHNAME', - 'pg_hmac_exists' LANGUAGE 'C'; - -CREATE FUNCTION crypt(text, text) RETURNS text - AS 'MODULE_PATHNAME', - 'pg_crypt' LANGUAGE 'C'; - -CREATE FUNCTION gen_salt(text) RETURNS text - AS 'MODULE_PATHNAME', - 'pg_gen_salt' LANGUAGE 'C'; - -CREATE FUNCTION gen_salt(text, int4) RETURNS text - AS 'MODULE_PATHNAME', - 'pg_gen_salt_rounds' LANGUAGE 'C'; - -CREATE FUNCTION encrypt(bytea, bytea, text) RETURNS bytea - AS 'MODULE_PATHNAME', - 'pg_encrypt' LANGUAGE 'C'; - -CREATE FUNCTION decrypt(bytea, bytea, text) RETURNS bytea - AS 'MODULE_PATHNAME', - 'pg_decrypt' LANGUAGE 'C'; - -CREATE FUNCTION encrypt_iv(bytea, bytea, bytea, text) RETURNS bytea - AS 'MODULE_PATHNAME', - 'pg_encrypt_iv' LANGUAGE 'C'; - -CREATE FUNCTION decrypt_iv(bytea, bytea, bytea, text) RETURNS bytea - AS 'MODULE_PATHNAME', - 'pg_decrypt_iv' LANGUAGE 'C'; - -CREATE FUNCTION cipher_exists(text) RETURNS bool - AS 'MODULE_PATHNAME', - 'pg_cipher_exists' LANGUAGE 'C'; - - diff --git a/contrib/pgcrypto/px-crypt.c b/contrib/pgcrypto/px-crypt.c deleted file mode 100644 index 898fa8a5c7..0000000000 --- a/contrib/pgcrypto/px-crypt.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * px-crypt.c - * Wrapper for various crypt algorithms. - * - * Copyright (c) 2001 Marko Kreen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: px-crypt.c,v 1.6 2001/11/20 18:54:07 momjian Exp $ - */ - -#include -#include "px.h" -#include "px-crypt.h" - - -#ifndef PX_SYSTEM_CRYPT - -static char * -run_crypt_des(const char *psw, const char *salt, - char *buf, unsigned len) -{ - char *res; - - res = px_crypt_des(psw, salt); - if (strlen(res) > len - 1) - return NULL; - strcpy(buf, res); - return buf; -} - -static char * -run_crypt_md5(const char *psw, const char *salt, - char *buf, unsigned len) -{ - char *res; - - res = px_crypt_md5(psw, salt, buf, len); - return res; -} - -static char * -run_crypt_bf(const char *psw, const char *salt, - char *buf, unsigned len) -{ - char *res; - - res = _crypt_blowfish_rn(psw, salt, buf, len); - return res; -} - -static struct -{ - char *id; - unsigned id_len; - char *(*crypt) (const char *psw, const char *salt, - char *buf, unsigned len); -} px_crypt_list[] = - -{ - { - "$2a$", 4, run_crypt_bf - }, - { - "$2$", 3, NULL - }, /* N/A */ - { - "$1$", 3, run_crypt_md5 - }, - { - "_", 1, run_crypt_des - }, - { - "", 0, run_crypt_des - }, - { - NULL, 0, NULL - } -}; - -char * -px_crypt(const char *psw, const char *salt, char *buf, unsigned len) -{ - int i; - - for (i = 0; px_crypt_list[i].id; i++) - { - if (!px_crypt_list[i].id_len) - break; - if (!strncmp(salt, px_crypt_list[i].id, px_crypt_list[i].id_len)) - break; - } - - if (px_crypt_list[i].crypt == NULL) - return NULL; - - return px_crypt_list[i].crypt(psw, salt, buf, len); -} - -#else /* PX_SYSTEM_CRYPT */ - -extern char *crypt(const char *psw, const char *salt); - -char * -px_crypt(const char *psw, const char *salt, - char *buf, unsigned len) -{ - char *res; - - res = crypt(psw, salt); - if (!res || strlen(res) >= len) - return NULL; - strcpy(buf, res); - return buf; -} -#endif - -/* - * salt generators - */ - -struct generator -{ - char *name; - char *(*gen) (unsigned long count, const char *input, int size, - char *output, int output_size); - int input_len; - int def_rounds; - int min_rounds; - int max_rounds; -}; - -static struct generator gen_list[] = { - {"des", _crypt_gensalt_traditional_rn, 2, 0, 0, 0}, - {"md5", _crypt_gensalt_md5_rn, 6, 0, 0, 0}, - {"xdes", _crypt_gensalt_extended_rn, 3, PX_XDES_ROUNDS, 1, 0xFFFFFF}, - {"bf", _crypt_gensalt_blowfish_rn, 16, PX_BF_ROUNDS, 4, 31}, - {NULL, NULL, 0, 0, 0} -}; - -unsigned -px_gen_salt(const char *salt_type, char *buf, int rounds) -{ - int i, - res; - struct generator *g; - char *p; - char rbuf[16]; - - for (i = 0; gen_list[i].name; i++) - { - g = &gen_list[i]; - if (strcasecmp(g->name, salt_type) != 0) - continue; - - if (g->def_rounds) - { - if (rounds == 0) - rounds = g->def_rounds; - - if (rounds < g->min_rounds || rounds > g->max_rounds) - return 0; - } - - res = px_get_random_bytes(rbuf, g->input_len); - if (res != g->input_len) - return 0; - - p = g->gen(rounds, rbuf, g->input_len, buf, PX_MAX_SALT_LEN); - memset(rbuf, 0, sizeof(rbuf)); - - return p != NULL ? strlen(p) : 0; - } - - return 0; -} diff --git a/contrib/pgcrypto/px-crypt.h b/contrib/pgcrypto/px-crypt.h deleted file mode 100644 index 2c1bcbf4b6..0000000000 --- a/contrib/pgcrypto/px-crypt.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * px-crypt.h - * Header file for px_crypt(). - * - * Copyright (c) 2001 Marko Kreen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: px-crypt.h,v 1.5 2001/11/05 17:46:23 momjian Exp $ - */ - -#ifndef _PX_CRYPT_H -#define _PX_CRYPT_H - -/* max room for result */ -#define PX_MAX_CRYPT 128 - -/* max salt returned by gen_salt() */ -#define PX_MAX_SALT_LEN 128 - -/* default rounds for xdes salt */ -/* NetBSD bin/passwd/local_passwd.c has (29 * 25)*/ -#define PX_XDES_ROUNDS (29 * 25) - -/* default for blowfish salt */ -#define PX_BF_ROUNDS 6 - -/* - * main interface - */ -char *px_crypt(const char *psw, const char *salt, char *buf, unsigned buflen); -unsigned px_gen_salt(const char *salt_type, char *dst, int rounds); - -/* - * internal functions - */ - -/* misc.c */ -extern void px_crypt_to64(char *s, unsigned long v, int n); -extern char px_crypt_a64[]; - -/* avoid conflicts with system libs */ -#define _crypt_to64 px_crypt_to64 -#define _crypt_a64 px_crypt_a64 - -/* crypt-gensalt.c */ -char *_crypt_gensalt_traditional_rn(unsigned long count, - const char *input, int size, char *output, int output_size); -char *_crypt_gensalt_extended_rn(unsigned long count, - const char *input, int size, char *output, int output_size); -char *_crypt_gensalt_md5_rn(unsigned long count, - const char *input, int size, char *output, int output_size); -char *_crypt_gensalt_blowfish_rn(unsigned long count, - const char *input, int size, char *output, int output_size); - -#ifndef PX_SYSTEM_CRYPT - -/* disable 'extended DES crypt' */ -/* #define DISABLE_XDES */ - -/* crypt-blowfish.c */ -char *_crypt_blowfish_rn(const char *key, const char *setting, - char *output, int size); - -/* crypt-des.c */ -char *px_crypt_des(const char *key, const char *setting); - -/* crypt-md5.c */ -char *px_crypt_md5(const char *pw, const char *salt, - char *dst, unsigned dstlen); -#endif /* !PX_SYSTEM_CRYPT */ - -#endif /* _PX_CRYPT_H */ diff --git a/contrib/pgcrypto/px-hmac.c b/contrib/pgcrypto/px-hmac.c deleted file mode 100644 index fd4eb441df..0000000000 --- a/contrib/pgcrypto/px-hmac.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * px-hmac.c - * HMAC implementation. - * - * Copyright (c) 2001 Marko Kreen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: px-hmac.c,v 1.4 2001/11/20 18:54:07 momjian Exp $ - */ - - -#include - -#include "px.h" - -#define HMAC_IPAD 0x36 -#define HMAC_OPAD 0x5C - -static unsigned -hmac_result_size(PX_HMAC * h) -{ - return px_md_result_size(h->md); -} - -static unsigned -hmac_block_size(PX_HMAC * h) -{ - return px_md_block_size(h->md); -} - -static void -hmac_init(PX_HMAC * h, const uint8 *key, unsigned klen) -{ - unsigned bs, - hlen, - i; - uint8 *keybuf; - PX_MD *md = h->md; - - bs = px_md_block_size(md); - hlen = px_md_result_size(md); - keybuf = px_alloc(bs); - memset(keybuf, 0, bs); - - if (klen > bs) - { - px_md_update(md, key, klen); - px_md_finish(md, keybuf); - px_md_reset(md); - } - else - memcpy(keybuf, key, klen); - - for (i = 0; i < bs; i++) - { - h->p.ipad[i] = keybuf[i] ^ HMAC_IPAD; - h->p.opad[i] = keybuf[i] ^ HMAC_OPAD; - } - - memset(keybuf, 0, bs); - px_free(keybuf); - - px_md_update(md, h->p.ipad, bs); -} - -static void -hmac_reset(PX_HMAC * h) -{ - PX_MD *md = h->md; - unsigned bs = px_md_block_size(md); - - px_md_reset(md); - px_md_update(md, h->p.ipad, bs); -} - -static void -hmac_update(PX_HMAC * h, const uint8 *data, unsigned dlen) -{ - px_md_update(h->md, data, dlen); -} - -static void -hmac_finish(PX_HMAC * h, uint8 *dst) -{ - PX_MD *md = h->md; - unsigned bs, - hlen; - uint8 *buf; - - bs = px_md_block_size(md); - hlen = px_md_result_size(md); - - buf = px_alloc(hlen); - - px_md_finish(md, buf); - - px_md_reset(md); - px_md_update(md, h->p.opad, bs); - px_md_update(md, buf, hlen); - px_md_finish(md, dst); - - memset(buf, 0, hlen); - px_free(buf); -} - -static void -hmac_free(PX_HMAC * h) -{ - unsigned bs; - - bs = px_md_block_size(h->md); - px_md_free(h->md); - - memset(h->p.ipad, 0, bs); - memset(h->p.opad, 0, bs); - px_free(h->p.ipad); - px_free(h->p.opad); - px_free(h); -} - - -/* PUBLIC FUNCTIONS */ - -int -px_find_hmac(const char *name, PX_HMAC ** res) -{ - int err; - PX_MD *md; - PX_HMAC *h; - unsigned bs; - - err = px_find_digest(name, &md); - if (err) - return err; - - bs = px_md_block_size(md); - if (bs < 2) - { - px_md_free(md); - return -1; - } - - h = px_alloc(sizeof(*h)); - h->p.ipad = px_alloc(bs); - h->p.opad = px_alloc(bs); - h->md = md; - - h->result_size = hmac_result_size; - h->block_size = hmac_block_size; - h->reset = hmac_reset; - h->update = hmac_update; - h->finish = hmac_finish; - h->free = hmac_free; - h->init = hmac_init; - - *res = h; - - return 0; -} diff --git a/contrib/pgcrypto/px.c b/contrib/pgcrypto/px.c deleted file mode 100644 index ed7e330edc..0000000000 --- a/contrib/pgcrypto/px.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * px.c - * Various cryptographic stuff for PostgreSQL. - * - * Copyright (c) 2001 Marko Kreen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: px.c,v 1.7 2002/03/06 06:09:10 momjian Exp $ - */ - -#include - -#include "px.h" - - -const char * -px_resolve_alias(const PX_Alias * list, const char *name) -{ - while (list->name) - { - if (!strcasecmp(list->alias, name)) - return list->name; - list++; - } - return name; -} - -/* - * combo - cipher + padding (+ checksum) - */ - -static unsigned -combo_encrypt_len(PX_Combo * cx, unsigned dlen) -{ - return dlen + 512; -} - -static unsigned -combo_decrypt_len(PX_Combo * cx, unsigned dlen) -{ - return dlen; -} - -static int -combo_init(PX_Combo * cx, const uint8 *key, unsigned klen, - const uint8 *iv, unsigned ivlen) -{ - int err; - unsigned bs, - ks, - ivs; - PX_Cipher *c = cx->cipher; - uint8 *ivbuf = NULL; - uint8 *keybuf; - - bs = px_cipher_block_size(c); - ks = px_cipher_key_size(c); - - ivs = px_cipher_iv_size(c); - if (ivs > 0) - { - ivbuf = px_alloc(ivs); - memset(ivbuf, 0, ivs); - if (ivlen > ivs) - memcpy(ivbuf, iv, ivs); - else - memcpy(ivbuf, iv, ivlen); - } - - if (klen > ks) - klen = ks; - keybuf = px_alloc(ks); - memset(keybuf, 0, ks); - memcpy(keybuf, key, klen); - - err = px_cipher_init(c, keybuf, klen, ivbuf); - - if (ivbuf) - px_free(ivbuf); - px_free(keybuf); - - return err; -} - -static int -combo_encrypt(PX_Combo * cx, const uint8 *data, unsigned dlen, - uint8 *res, unsigned *rlen) -{ - int err = 0; - uint8 *bbuf; - unsigned bs, - maxlen, - bpos, - i, - pad; - - PX_Cipher *c = cx->cipher; - - bbuf = NULL; - maxlen = *rlen; - bs = px_cipher_block_size(c); - - /* encrypt */ - if (bs > 1) - { - bbuf = px_alloc(bs * 4); - bpos = dlen % bs; - *rlen = dlen - bpos; - memcpy(bbuf, data + *rlen, bpos); - - /* encrypt full-block data */ - if (*rlen) - { - err = px_cipher_encrypt(c, data, *rlen, res); - if (err) - goto out; - } - - /* bbuf has now bpos bytes of stuff */ - if (cx->padding) - { - pad = bs - (bpos % bs); - for (i = 0; i < pad; i++) - bbuf[bpos++] = pad; - } - else if (bpos % bs) - { - /* ERROR? */ - pad = bs - (bpos % bs); - for (i = 0; i < pad; i++) - bbuf[bpos++] = 0; - } - - /* encrypt the rest - pad */ - if (bpos) - { - err = px_cipher_encrypt(c, bbuf, bpos, res + *rlen); - *rlen += bpos; - } - } - else - { - /* stream cipher/mode - no pad needed */ - err = px_cipher_encrypt(c, data, dlen, res); - if (err) - goto out; - *rlen = dlen; - } -out: - if (bbuf) - px_free(bbuf); - - return err; -} - -static int -combo_decrypt(PX_Combo * cx, const uint8 *data, unsigned dlen, - uint8 *res, unsigned *rlen) -{ - unsigned bs, - i, - pad; - unsigned pad_ok; - - PX_Cipher *c = cx->cipher; - - bs = px_cipher_block_size(c); - if (bs > 1 && (dlen % bs) != 0) - goto block_error; - - /* decrypt */ - *rlen = dlen; - px_cipher_decrypt(c, data, dlen, res); - - /* unpad */ - if (bs > 1 && cx->padding) - { - pad = res[*rlen - 1]; - pad_ok = 0; - if (pad > 0 && pad <= bs && pad <= *rlen) - { - pad_ok = 1; - for (i = *rlen - pad; i < *rlen; i++) - if (res[i] != pad) - { - pad_ok = 0; - break; - } - } - - if (pad_ok) - *rlen -= pad; - } - - return 0; - - /* error reporting should be done in pgcrypto.c */ -block_error: - elog(WARNING, "Data not a multiple of block size"); - return -1; -} - -static void -combo_free(PX_Combo * cx) -{ - if (cx->cipher) - px_cipher_free(cx->cipher); - memset(cx, 0, sizeof(*cx)); - px_free(cx); -} - -/* PARSER */ - -static int -parse_cipher_name(char *full, char **cipher, char **pad) -{ - char *p, - *p2, - *q; - - *cipher = full; - *pad = NULL; - - p = strchr(full, '/'); - if (p != NULL) - *p++ = 0; - while (p != NULL) - { - if ((q = strchr(p, '/')) != NULL) - *q++ = 0; - - if (!*p) - { - p = q; - continue; - } - p2 = strchr(p, ':'); - if (p2 != NULL) - { - *p2++ = 0; - if (!strcmp(p, "pad")) - *pad = p2; - else - return -1; - } - else - return -1; - - p = q; - } - return 0; -} - -/* provider */ - -int -px_find_combo(const char *name, PX_Combo ** res) -{ - int err; - char *buf, - *s_cipher, - *s_pad; - - PX_Combo *cx; - - cx = px_alloc(sizeof(*cx)); - memset(cx, 0, sizeof(*cx)); - - buf = px_alloc(strlen(name) + 1); - strcpy(buf, name); - - err = parse_cipher_name(buf, &s_cipher, &s_pad); - if (err) - { - px_free(buf); - px_free(cx); - return err; - } - - err = px_find_cipher(s_cipher, &cx->cipher); - if (err) - goto err1; - - if (s_pad != NULL) - { - if (!strcmp(s_pad, "pkcs")) - cx->padding = 1; - else if (!strcmp(s_pad, "none")) - cx->padding = 0; - else - goto err1; - } - else - cx->padding = 1; - - cx->init = combo_init; - cx->encrypt = combo_encrypt; - cx->decrypt = combo_decrypt; - cx->encrypt_len = combo_encrypt_len; - cx->decrypt_len = combo_decrypt_len; - cx->free = combo_free; - - px_free(buf); - - *res = cx; - - return 0; - -err1: - if (cx->cipher) - px_cipher_free(cx->cipher); - px_free(cx); - px_free(buf); - return -1; -} diff --git a/contrib/pgcrypto/px.h b/contrib/pgcrypto/px.h deleted file mode 100644 index e000883d39..0000000000 --- a/contrib/pgcrypto/px.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - * px.h - * Header file for pgcrypto. - * - * Copyright (c) 2001 Marko Kreen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: px.h,v 1.7 2001/11/30 17:39:20 momjian Exp $ - */ - -#ifndef __PX_H -#define __PX_H - -#include -#ifdef HAVE_ENDIAN_H -#include -#endif - -#ifndef BYTE_ORDER -#error BYTE_ORDER must be defined as LITTLE_ENDIAN or BIG_ENDIAN -#endif - - -#if 1 - -#define px_alloc(s) palloc(s) -#define px_realloc(p, s) prealloc(p, s) -#define px_free(p) pfree(p) - -#else - -void *xalloc(size_t s); -void *xrealloc(void *p, size_t s); -void xfree(void *p); - -#define px_alloc(s) xalloc(s) -#define px_realloc(p, s) xrealloc(p, s) -#define px_free(p) xfree(p) -#endif - -/* max len of 'type' parms */ -#define PX_MAX_NAMELEN 128 - -/* max salt returned */ -#define PX_MAX_SALT_LEN 128 - - -typedef struct px_digest PX_MD; -typedef struct px_alias PX_Alias; -typedef struct px_hmac PX_HMAC; -typedef struct px_cipher PX_Cipher; -typedef struct px_combo PX_Combo; - -struct px_digest -{ - unsigned (*result_size) (PX_MD * h); - unsigned (*block_size) (PX_MD * h); - void (*reset) (PX_MD * h); - void (*update) (PX_MD * h, const uint8 *data, unsigned dlen); - void (*finish) (PX_MD * h, uint8 *dst); - void (*free) (PX_MD * h); - /* private */ - union - { - unsigned code; - const void *ptr; - } p; -}; - -struct px_alias -{ - char *alias; - char *name; -}; - -struct px_hmac -{ - unsigned (*result_size) (PX_HMAC * h); - unsigned (*block_size) (PX_HMAC * h); - void (*reset) (PX_HMAC * h); - void (*update) (PX_HMAC * h, const uint8 *data, unsigned dlen); - void (*finish) (PX_HMAC * h, uint8 *dst); - void (*free) (PX_HMAC * h); - void (*init) (PX_HMAC * h, const uint8 *key, unsigned klen); - - PX_MD *md; - /* private */ - struct - { - uint8 *ipad; - uint8 *opad; - } p; -}; - -struct px_cipher -{ - unsigned (*block_size) (PX_Cipher * c); - unsigned (*key_size) (PX_Cipher * c); /* max key len */ - unsigned (*iv_size) (PX_Cipher * c); - - int (*init) (PX_Cipher * c, const uint8 *key, unsigned klen, const uint8 *iv); - int (*encrypt) (PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res); - int (*decrypt) (PX_Cipher * c, const uint8 *data, unsigned dlen, uint8 *res); - void (*free) (PX_Cipher * c); - /* private */ - void *ptr; - int pstat; /* mcrypt uses it */ -}; - -struct px_combo -{ - int (*init) (PX_Combo * cx, const uint8 *key, unsigned klen, - const uint8 *iv, unsigned ivlen); - int (*encrypt) (PX_Combo * cx, const uint8 *data, unsigned dlen, - uint8 *res, unsigned *rlen); - int (*decrypt) (PX_Combo * cx, const uint8 *data, unsigned dlen, - uint8 *res, unsigned *rlen); - unsigned (*encrypt_len) (PX_Combo * cx, unsigned dlen); - unsigned (*decrypt_len) (PX_Combo * cx, unsigned dlen); - void (*free) (PX_Combo * cx); - - PX_Cipher *cipher; - unsigned padding; -}; - -int px_find_digest(const char *name, PX_MD ** res); -int px_find_hmac(const char *name, PX_HMAC ** res); -int px_find_cipher(const char *name, PX_Cipher ** res); -int px_find_combo(const char *name, PX_Combo ** res); - -int px_get_random_bytes(uint8 *dst, unsigned count); - -const char *px_resolve_alias(const PX_Alias * aliases, const char *name); - -#define px_md_result_size(md) (md)->result_size(md) -#define px_md_block_size(md) (md)->block_size(md) -#define px_md_reset(md) (md)->reset(md) -#define px_md_update(md, data, dlen) (md)->update(md, data, dlen) -#define px_md_finish(md, buf) (md)->finish(md, buf) -#define px_md_free(md) (md)->free(md) - -#define px_hmac_result_size(hmac) (hmac)->result_size(hmac) -#define px_hmac_block_size(hmac) (hmac)->block_size(hmac) -#define px_hmac_reset(hmac) (hmac)->reset(hmac) -#define px_hmac_init(hmac, key, klen) (hmac)->init(hmac, key, klen) -#define px_hmac_update(hmac, data, dlen) (hmac)->update(hmac, data, dlen) -#define px_hmac_finish(hmac, buf) (hmac)->finish(hmac, buf) -#define px_hmac_free(hmac) (hmac)->free(hmac) - - -#define px_cipher_key_size(c) (c)->key_size(c) -#define px_cipher_block_size(c) (c)->block_size(c) -#define px_cipher_iv_size(c) (c)->iv_size(c) -#define px_cipher_init(c, k, klen, iv) (c)->init(c, k, klen, iv) -#define px_cipher_encrypt(c, data, dlen, res) \ - (c)->encrypt(c, data, dlen, res) -#define px_cipher_decrypt(c, data, dlen, res) \ - (c)->decrypt(c, data, dlen, res) -#define px_cipher_free(c) (c)->free(c) - - -#define px_combo_encrypt_len(c, dlen) (c)->encrypt_len(c, dlen) -#define px_combo_decrypt_len(c, dlen) (c)->decrypt_len(c, dlen) -#define px_combo_init(c, key, klen, iv, ivlen) \ - (c)->init(c, key, klen, iv, ivlen) -#define px_combo_encrypt(c, data, dlen, res, rlen) \ - (c)->encrypt(c, data, dlen, res, rlen) -#define px_combo_decrypt(c, data, dlen, res, rlen) \ - (c)->decrypt(c, data, dlen, res, rlen) -#define px_combo_free(c) (c)->free(c) - -#endif /* __PX_H */ diff --git a/contrib/pgcrypto/random.c b/contrib/pgcrypto/random.c deleted file mode 100644 index ce5f838a0c..0000000000 --- a/contrib/pgcrypto/random.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * random.c - * Random functions. - * - * Copyright (c) 2001 Marko Kreen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Id: random.c,v 1.5 2001/11/05 17:46:23 momjian Exp $ - */ - - -#include - -#include "px.h" - - -#ifdef RAND_DEV - -#include -#include -#include - -static int -safe_read(int fd, void *buf, size_t count) -{ - int done = 0; - char *p = buf; - int res; - - while (count) - { - res = read(fd, p, count); - if (res <= 0) - { - if (errno == EINTR) - continue; - return -1; - } - p += res; - done += res; - count -= res; - } - return done; -} - -int -px_get_random_bytes(uint8 *dst, unsigned count) -{ - int fd; - int res; - - fd = open(RAND_DEV, O_RDONLY); - if (fd == -1) - return -1; - res = safe_read(fd, dst, count); - close(fd); - return res; -} -#endif /* RAND_DEV */ - -#ifdef RAND_SILLY - -int -px_get_random_bytes(uint8 *dst, unsigned count) -{ - int i; - - for (i = 0; i < count; i++) - *dst++ = random(); - return i; -} -#endif /* RAND_SILLY */ - -#ifdef RAND_OPENSSL - -#include -#include -#include -#include - -static int openssl_random_init = 0; - -int -px_get_random_bytes(uint8 *dst, unsigned count) -{ - int res; - - if (!openssl_random_init) - { - if (RAND_get_rand_method() == NULL) - RAND_set_rand_method(RAND_SSLeay()); - openssl_random_init = 1; - } - - /* - * OpenSSL random should re-feeded occasionally. From /dev/urandom - * preferrably. - */ - - res = RAND_bytes(dst, count); - if (res > 0) - return count; - - return -1; -} - -#endif /* RAND_OPENSSL */ diff --git a/contrib/pgcrypto/rijndael.c b/contrib/pgcrypto/rijndael.c deleted file mode 100644 index fd4572a8e9..0000000000 --- a/contrib/pgcrypto/rijndael.c +++ /dev/null @@ -1,669 +0,0 @@ -/* $OpenBSD: rijndael.c,v 1.6 2000/12/09 18:51:34 markus Exp $ */ - -/* This is an independent implementation of the encryption algorithm: */ -/* */ -/* RIJNDAEL by Joan Daemen and Vincent Rijmen */ -/* */ -/* which is a candidate algorithm in the Advanced Encryption Standard */ -/* programme of the US National Institute of Standards and Technology. */ -/* */ -/* Copyright in this implementation is held by Dr B R Gladman but I */ -/* hereby give permission for its free direct or derivative use subject */ -/* to acknowledgment of its origin and compliance with any conditions */ -/* that the originators of the algorithm place on its exploitation. */ -/* */ -/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */ - -/* Timing data for Rijndael (rijndael.c) - -Algorithm: rijndael (rijndael.c) - -128 bit key: -Key Setup: 305/1389 cycles (encrypt/decrypt) -Encrypt: 374 cycles = 68.4 mbits/sec -Decrypt: 352 cycles = 72.7 mbits/sec -Mean: 363 cycles = 70.5 mbits/sec - -192 bit key: -Key Setup: 277/1595 cycles (encrypt/decrypt) -Encrypt: 439 cycles = 58.3 mbits/sec -Decrypt: 425 cycles = 60.2 mbits/sec -Mean: 432 cycles = 59.3 mbits/sec - -256 bit key: -Key Setup: 374/1960 cycles (encrypt/decrypt) -Encrypt: 502 cycles = 51.0 mbits/sec -Decrypt: 498 cycles = 51.4 mbits/sec -Mean: 500 cycles = 51.2 mbits/sec - -*/ - -#include -#include "px.h" - -#include "rijndael.h" - -#define PRE_CALC_TABLES -#define LARGE_TABLES - -static void gen_tabs(void); - -/* 3. Basic macros for speeding up generic operations */ - -/* Circular rotate of 32 bit values */ - -#define rotr(x,n) (((x) >> ((int)(n))) | ((x) << (32 - (int)(n)))) -#define rotl(x,n) (((x) << ((int)(n))) | ((x) >> (32 - (int)(n)))) - -/* Invert byte order in a 32 bit variable */ - -#define bswap(x) ((rotl(x, 8) & 0x00ff00ff) | (rotr(x, 8) & 0xff00ff00)) - -/* Extract byte from a 32 bit quantity (little endian notation) */ - -#define byte(x,n) ((u1byte)((x) >> (8 * n))) - -#if BYTE_ORDER != LITTLE_ENDIAN -#define BYTE_SWAP -#endif - -#ifdef BYTE_SWAP -#define io_swap(x) bswap(x) -#else -#define io_swap(x) (x) -#endif - -#ifdef PRINT_TABS -#undef PRE_CALC_TABLES -#endif - -#ifdef PRE_CALC_TABLES - -#include "rijndael.tbl" -#define tab_gen 1 - -#else /* !PRE_CALC_TABLES */ - -static u1byte pow_tab[256]; -static u1byte log_tab[256]; -static u1byte sbx_tab[256]; -static u1byte isb_tab[256]; -static u4byte rco_tab[10]; -static u4byte ft_tab[4][256]; -static u4byte it_tab[4][256]; - -#ifdef LARGE_TABLES -static u4byte fl_tab[4][256]; -static u4byte il_tab[4][256]; -#endif - -static u4byte tab_gen = 0; -#endif /* !PRE_CALC_TABLES */ - -#define ff_mult(a,b) (a && b ? pow_tab[(log_tab[a] + log_tab[b]) % 255] : 0) - -#define f_rn(bo, bi, n, k) \ - bo[n] = ft_tab[0][byte(bi[n],0)] ^ \ - ft_tab[1][byte(bi[(n + 1) & 3],1)] ^ \ - ft_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ - ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n) - -#define i_rn(bo, bi, n, k) \ - bo[n] = it_tab[0][byte(bi[n],0)] ^ \ - it_tab[1][byte(bi[(n + 3) & 3],1)] ^ \ - it_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ - it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n) - -#ifdef LARGE_TABLES - -#define ls_box(x) \ - ( fl_tab[0][byte(x, 0)] ^ \ - fl_tab[1][byte(x, 1)] ^ \ - fl_tab[2][byte(x, 2)] ^ \ - fl_tab[3][byte(x, 3)] ) - -#define f_rl(bo, bi, n, k) \ - bo[n] = fl_tab[0][byte(bi[n],0)] ^ \ - fl_tab[1][byte(bi[(n + 1) & 3],1)] ^ \ - fl_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ - fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n) - -#define i_rl(bo, bi, n, k) \ - bo[n] = il_tab[0][byte(bi[n],0)] ^ \ - il_tab[1][byte(bi[(n + 3) & 3],1)] ^ \ - il_tab[2][byte(bi[(n + 2) & 3],2)] ^ \ - il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n) - -#else - -#define ls_box(x) \ - ((u4byte)sbx_tab[byte(x, 0)] << 0) ^ \ - ((u4byte)sbx_tab[byte(x, 1)] << 8) ^ \ - ((u4byte)sbx_tab[byte(x, 2)] << 16) ^ \ - ((u4byte)sbx_tab[byte(x, 3)] << 24) - -#define f_rl(bo, bi, n, k) \ - bo[n] = (u4byte)sbx_tab[byte(bi[n],0)] ^ \ - rotl(((u4byte)sbx_tab[byte(bi[(n + 1) & 3],1)]), 8) ^ \ - rotl(((u4byte)sbx_tab[byte(bi[(n + 2) & 3],2)]), 16) ^ \ - rotl(((u4byte)sbx_tab[byte(bi[(n + 3) & 3],3)]), 24) ^ *(k + n) - -#define i_rl(bo, bi, n, k) \ - bo[n] = (u4byte)isb_tab[byte(bi[n],0)] ^ \ - rotl(((u4byte)isb_tab[byte(bi[(n + 3) & 3],1)]), 8) ^ \ - rotl(((u4byte)isb_tab[byte(bi[(n + 2) & 3],2)]), 16) ^ \ - rotl(((u4byte)isb_tab[byte(bi[(n + 1) & 3],3)]), 24) ^ *(k + n) -#endif - -static void -gen_tabs(void) -{ -#ifndef PRE_CALC_TABLES - u4byte i, - t; - u1byte p, - q; - - /* log and power tables for GF(2**8) finite field with */ - /* 0x11b as modular polynomial - the simplest prmitive */ - /* root is 0x11, used here to generate the tables */ - - for (i = 0, p = 1; i < 256; ++i) - { - pow_tab[i] = (u1byte) p; - log_tab[p] = (u1byte) i; - - p = p ^ (p << 1) ^ (p & 0x80 ? 0x01b : 0); - } - - log_tab[1] = 0; - p = 1; - - for (i = 0; i < 10; ++i) - { - rco_tab[i] = p; - - p = (p << 1) ^ (p & 0x80 ? 0x1b : 0); - } - - /* note that the affine byte transformation matrix in */ - /* rijndael specification is in big endian format with */ - /* bit 0 as the most significant bit. In the remainder */ - /* of the specification the bits are numbered from the */ - /* least significant end of a byte. */ - - for (i = 0; i < 256; ++i) - { - p = (i ? pow_tab[255 - log_tab[i]] : 0); - q = p; - q = (q >> 7) | (q << 1); - p ^= q; - q = (q >> 7) | (q << 1); - p ^= q; - q = (q >> 7) | (q << 1); - p ^= q; - q = (q >> 7) | (q << 1); - p ^= q ^ 0x63; - sbx_tab[i] = (u1byte) p; - isb_tab[p] = (u1byte) i; - } - - for (i = 0; i < 256; ++i) - { - p = sbx_tab[i]; - -#ifdef LARGE_TABLES - - t = p; - fl_tab[0][i] = t; - fl_tab[1][i] = rotl(t, 8); - fl_tab[2][i] = rotl(t, 16); - fl_tab[3][i] = rotl(t, 24); -#endif - t = ((u4byte) ff_mult(2, p)) | - ((u4byte) p << 8) | - ((u4byte) p << 16) | - ((u4byte) ff_mult(3, p) << 24); - - ft_tab[0][i] = t; - ft_tab[1][i] = rotl(t, 8); - ft_tab[2][i] = rotl(t, 16); - ft_tab[3][i] = rotl(t, 24); - - p = isb_tab[i]; - -#ifdef LARGE_TABLES - - t = p; - il_tab[0][i] = t; - il_tab[1][i] = rotl(t, 8); - il_tab[2][i] = rotl(t, 16); - il_tab[3][i] = rotl(t, 24); -#endif - t = ((u4byte) ff_mult(14, p)) | - ((u4byte) ff_mult(9, p) << 8) | - ((u4byte) ff_mult(13, p) << 16) | - ((u4byte) ff_mult(11, p) << 24); - - it_tab[0][i] = t; - it_tab[1][i] = rotl(t, 8); - it_tab[2][i] = rotl(t, 16); - it_tab[3][i] = rotl(t, 24); - } - - tab_gen = 1; -#endif /* !PRE_CALC_TABLES */ -} - - -#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b) - -#define imix_col(y,x) \ - u = star_x(x); \ - v = star_x(u); \ - w = star_x(v); \ - t = w ^ (x); \ - (y) = u ^ v ^ w; \ - (y) ^= rotr(u ^ t, 8) ^ \ - rotr(v ^ t, 16) ^ \ - rotr(t,24) - -/* initialise the key schedule from the user supplied key */ - -#define loop4(i) \ -do { t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \ - t ^= e_key[4 * i]; e_key[4 * i + 4] = t; \ - t ^= e_key[4 * i + 1]; e_key[4 * i + 5] = t; \ - t ^= e_key[4 * i + 2]; e_key[4 * i + 6] = t; \ - t ^= e_key[4 * i + 3]; e_key[4 * i + 7] = t; \ -} while (0) - -#define loop6(i) \ -do { t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \ - t ^= e_key[6 * i]; e_key[6 * i + 6] = t; \ - t ^= e_key[6 * i + 1]; e_key[6 * i + 7] = t; \ - t ^= e_key[6 * i + 2]; e_key[6 * i + 8] = t; \ - t ^= e_key[6 * i + 3]; e_key[6 * i + 9] = t; \ - t ^= e_key[6 * i + 4]; e_key[6 * i + 10] = t; \ - t ^= e_key[6 * i + 5]; e_key[6 * i + 11] = t; \ -} while (0) - -#define loop8(i) \ -do { t = ls_box(rotr(t, 8)) ^ rco_tab[i]; \ - t ^= e_key[8 * i]; e_key[8 * i + 8] = t; \ - t ^= e_key[8 * i + 1]; e_key[8 * i + 9] = t; \ - t ^= e_key[8 * i + 2]; e_key[8 * i + 10] = t; \ - t ^= e_key[8 * i + 3]; e_key[8 * i + 11] = t; \ - t = e_key[8 * i + 4] ^ ls_box(t); \ - e_key[8 * i + 12] = t; \ - t ^= e_key[8 * i + 5]; e_key[8 * i + 13] = t; \ - t ^= e_key[8 * i + 6]; e_key[8 * i + 14] = t; \ - t ^= e_key[8 * i + 7]; e_key[8 * i + 15] = t; \ -} while (0) - -rijndael_ctx * -rijndael_set_key(rijndael_ctx * ctx, const u4byte * in_key, const u4byte key_len, - int encrypt) -{ - u4byte i, - t, - u, - v, - w; - u4byte *e_key = ctx->e_key; - u4byte *d_key = ctx->d_key; - - ctx->decrypt = !encrypt; - - if (!tab_gen) - gen_tabs(); - - ctx->k_len = (key_len + 31) / 32; - - e_key[0] = io_swap(in_key[0]); - e_key[1] = io_swap(in_key[1]); - e_key[2] = io_swap(in_key[2]); - e_key[3] = io_swap(in_key[3]); - - switch (ctx->k_len) - { - case 4: - t = e_key[3]; - for (i = 0; i < 10; ++i) - loop4(i); - break; - - case 6: - e_key[4] = io_swap(in_key[4]); - t = e_key[5] = io_swap(in_key[5]); - for (i = 0; i < 8; ++i) - loop6(i); - break; - - case 8: - e_key[4] = io_swap(in_key[4]); - e_key[5] = io_swap(in_key[5]); - e_key[6] = io_swap(in_key[6]); - t = e_key[7] = io_swap(in_key[7]); - for (i = 0; i < 7; ++i) - loop8(i); - break; - } - - if (!encrypt) - { - d_key[0] = e_key[0]; - d_key[1] = e_key[1]; - d_key[2] = e_key[2]; - d_key[3] = e_key[3]; - - for (i = 4; i < 4 * ctx->k_len + 24; ++i) - imix_col(d_key[i], e_key[i]); - } - - return ctx; -} - -/* encrypt a block of text */ - -#define f_nround(bo, bi, k) \ - f_rn(bo, bi, 0, k); \ - f_rn(bo, bi, 1, k); \ - f_rn(bo, bi, 2, k); \ - f_rn(bo, bi, 3, k); \ - k += 4 - -#define f_lround(bo, bi, k) \ - f_rl(bo, bi, 0, k); \ - f_rl(bo, bi, 1, k); \ - f_rl(bo, bi, 2, k); \ - f_rl(bo, bi, 3, k) - -void -rijndael_encrypt(rijndael_ctx * ctx, const u4byte * in_blk, u4byte * out_blk) -{ - u4byte k_len = ctx->k_len; - u4byte *e_key = ctx->e_key; - u4byte b0[4], - b1[4], - *kp; - - b0[0] = io_swap(in_blk[0]) ^ e_key[0]; - b0[1] = io_swap(in_blk[1]) ^ e_key[1]; - b0[2] = io_swap(in_blk[2]) ^ e_key[2]; - b0[3] = io_swap(in_blk[3]) ^ e_key[3]; - - kp = e_key + 4; - - if (k_len > 6) - { - f_nround(b1, b0, kp); - f_nround(b0, b1, kp); - } - - if (k_len > 4) - { - f_nround(b1, b0, kp); - f_nround(b0, b1, kp); - } - - f_nround(b1, b0, kp); - f_nround(b0, b1, kp); - f_nround(b1, b0, kp); - f_nround(b0, b1, kp); - f_nround(b1, b0, kp); - f_nround(b0, b1, kp); - f_nround(b1, b0, kp); - f_nround(b0, b1, kp); - f_nround(b1, b0, kp); - f_lround(b0, b1, kp); - - out_blk[0] = io_swap(b0[0]); - out_blk[1] = io_swap(b0[1]); - out_blk[2] = io_swap(b0[2]); - out_blk[3] = io_swap(b0[3]); -} - -/* decrypt a block of text */ - -#define i_nround(bo, bi, k) \ - i_rn(bo, bi, 0, k); \ - i_rn(bo, bi, 1, k); \ - i_rn(bo, bi, 2, k); \ - i_rn(bo, bi, 3, k); \ - k -= 4 - -#define i_lround(bo, bi, k) \ - i_rl(bo, bi, 0, k); \ - i_rl(bo, bi, 1, k); \ - i_rl(bo, bi, 2, k); \ - i_rl(bo, bi, 3, k) - -void -rijndael_decrypt(rijndael_ctx * ctx, const u4byte * in_blk, u4byte * out_blk) -{ - u4byte b0[4], - b1[4], - *kp; - u4byte k_len = ctx->k_len; - u4byte *e_key = ctx->e_key; - u4byte *d_key = ctx->d_key; - - b0[0] = io_swap(in_blk[0]) ^ e_key[4 * k_len + 24]; - b0[1] = io_swap(in_blk[1]) ^ e_key[4 * k_len + 25]; - b0[2] = io_swap(in_blk[2]) ^ e_key[4 * k_len + 26]; - b0[3] = io_swap(in_blk[3]) ^ e_key[4 * k_len + 27]; - - kp = d_key + 4 * (k_len + 5); - - if (k_len > 6) - { - i_nround(b1, b0, kp); - i_nround(b0, b1, kp); - } - - if (k_len > 4) - { - i_nround(b1, b0, kp); - i_nround(b0, b1, kp); - } - - i_nround(b1, b0, kp); - i_nround(b0, b1, kp); - i_nround(b1, b0, kp); - i_nround(b0, b1, kp); - i_nround(b1, b0, kp); - i_nround(b0, b1, kp); - i_nround(b1, b0, kp); - i_nround(b0, b1, kp); - i_nround(b1, b0, kp); - i_lround(b0, b1, kp); - - out_blk[0] = io_swap(b0[0]); - out_blk[1] = io_swap(b0[1]); - out_blk[2] = io_swap(b0[2]); - out_blk[3] = io_swap(b0[3]); -} - -/* - * conventional interface - * - * ATM it hopes all data is 4-byte aligned - which - * should be true for PX. -marko - */ - -void -aes_set_key(rijndael_ctx * ctx, const uint8 *key, unsigned keybits, int enc) -{ - uint32 *k; - - k = (uint32 *) key; - rijndael_set_key(ctx, k, keybits, enc); -} - -void -aes_ecb_encrypt(rijndael_ctx * ctx, uint8 *data, unsigned len) -{ - unsigned bs = 16; - uint32 *d; - - while (len >= bs) - { - d = (uint32 *) data; - rijndael_encrypt(ctx, d, d); - - len -= bs; - data += bs; - } -} - -void -aes_ecb_decrypt(rijndael_ctx * ctx, uint8 *data, unsigned len) -{ - unsigned bs = 16; - uint32 *d; - - while (len >= bs) - { - d = (uint32 *) data; - rijndael_decrypt(ctx, d, d); - - len -= bs; - data += bs; - } -} - -void -aes_cbc_encrypt(rijndael_ctx * ctx, uint8 *iva, uint8 *data, unsigned len) -{ - uint32 *iv = (uint32 *) iva; - uint32 *d = (uint32 *) data; - unsigned bs = 16; - - while (len >= bs) - { - d[0] ^= iv[0]; - d[1] ^= iv[1]; - d[2] ^= iv[2]; - d[3] ^= iv[3]; - - rijndael_encrypt(ctx, d, d); - - iv = d; - d += bs / 4; - len -= bs; - } -} - -void -aes_cbc_decrypt(rijndael_ctx * ctx, uint8 *iva, uint8 *data, unsigned len) -{ - uint32 *d = (uint32 *) data; - unsigned bs = 16; - uint32 buf[4], - iv[4]; - - memcpy(iv, iva, bs); - while (len >= bs) - { - buf[0] = d[0]; - buf[1] = d[1]; - buf[2] = d[2]; - buf[3] = d[3]; - - rijndael_decrypt(ctx, buf, d); - - d[0] ^= iv[0]; - d[1] ^= iv[1]; - d[2] ^= iv[2]; - d[3] ^= iv[3]; - - iv[0] = buf[0]; - iv[1] = buf[1]; - iv[2] = buf[2]; - iv[3] = buf[3]; - d += 4; - len -= bs; - } -} - -/* - * pre-calculate tables. - * - * On i386 lifts 17k from .bss to .rodata - * and avoids 1k code and setup time. - * -marko - */ -#ifdef PRINT_TABS - -static void -show256u8(char *name, uint8 *data) -{ - int i; - - printf("static const u1byte %s[256] = {\n ", name); - for (i = 0; i < 256;) - { - printf("%u", pow_tab[i++]); - if (i < 256) - printf(i % 16 ? ", " : ",\n "); - } - printf("\n};\n\n"); -} - - -static void -show4x256u32(char *name, uint32 data[4][256]) -{ - int i, - j; - - printf("static const u4byte %s[4][256] = {\n{\n ", name); - for (i = 0; i < 4; i++) - { - for (j = 0; j < 256;) - { - printf("0x%08x", data[i][j]); - j++; - if (j < 256) - printf(j % 4 ? ", " : ",\n "); - } - printf(i < 3 ? "\n}, {\n " : "\n}\n"); - } - printf("};\n\n"); -} - -int -main() -{ - int i; - char *hdr = "/* Generated by rijndael.c */\n\n"; - - gen_tabs(); - - printf(hdr); - show256u8("pow_tab", pow_tab); - show256u8("log_tab", log_tab); - show256u8("sbx_tab", sbx_tab); - show256u8("isb_tab", isb_tab); - - show4x256u32("ft_tab", ft_tab); - show4x256u32("it_tab", it_tab); -#ifdef LARGE_TABLES - show4x256u32("fl_tab", fl_tab); - show4x256u32("il_tab", il_tab); -#endif - printf("static const u4byte rco_tab[10] = {\n "); - for (i = 0; i < 10; i++) - { - printf("0x%08x", rco_tab[i]); - if (i < 9) - printf(", "); - if (i == 4) - printf("\n "); - } - printf("\n};\n\n"); - return 0; -} - -#endif diff --git a/contrib/pgcrypto/rijndael.h b/contrib/pgcrypto/rijndael.h deleted file mode 100644 index 41c1a2a122..0000000000 --- a/contrib/pgcrypto/rijndael.h +++ /dev/null @@ -1,57 +0,0 @@ -/* $OpenBSD: rijndael.h,v 1.3 2001/05/09 23:01:32 markus Exp $ */ - -/* This is an independent implementation of the encryption algorithm: */ -/* */ -/* RIJNDAEL by Joan Daemen and Vincent Rijmen */ -/* */ -/* which is a candidate algorithm in the Advanced Encryption Standard */ -/* programme of the US National Institute of Standards and Technology. */ -/* */ -/* Copyright in this implementation is held by Dr B R Gladman but I */ -/* hereby give permission for its free direct or derivative use subject */ -/* to acknowledgment of its origin and compliance with any conditions */ -/* that the originators of the algorithm place on its exploitation. */ -/* */ -/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */ - -#ifndef _RIJNDAEL_H_ -#define _RIJNDAEL_H_ - -/* 1. Standard types for AES cryptography source code */ - -typedef uint8 u1byte; /* an 8 bit unsigned character type */ -typedef uint16 u2byte; /* a 16 bit unsigned integer type */ -typedef uint32 u4byte; /* a 32 bit unsigned integer type */ - -typedef int8 s1byte; /* an 8 bit signed character type */ -typedef int16 s2byte; /* a 16 bit signed integer type */ -typedef int32 s4byte; /* a 32 bit signed integer type */ - -typedef struct _rijndael_ctx -{ - u4byte k_len; - int decrypt; - u4byte e_key[64]; - u4byte d_key[64]; -} rijndael_ctx; - - -/* 2. Standard interface for AES cryptographic routines */ - -/* These are all based on 32 bit unsigned values and will therefore */ -/* require endian conversions for big-endian architectures */ - -rijndael_ctx * - rijndael_set_key(rijndael_ctx *, const u4byte *, const u4byte, int); -void rijndael_encrypt(rijndael_ctx *, const u4byte *, u4byte *); -void rijndael_decrypt(rijndael_ctx *, const u4byte *, u4byte *); - -/* conventional interface */ - -void aes_set_key(rijndael_ctx * ctx, const uint8 *key, unsigned keybits, int enc); -void aes_ecb_encrypt(rijndael_ctx * ctx, uint8 *data, unsigned len); -void aes_ecb_decrypt(rijndael_ctx * ctx, uint8 *data, unsigned len); -void aes_cbc_encrypt(rijndael_ctx * ctx, uint8 *iva, uint8 *data, unsigned len); -void aes_cbc_decrypt(rijndael_ctx * ctx, uint8 *iva, uint8 *data, unsigned len); - -#endif /* _RIJNDAEL_H_ */ diff --git a/contrib/pgcrypto/rijndael.tbl b/contrib/pgcrypto/rijndael.tbl deleted file mode 100644 index bc0a3822cc..0000000000 --- a/contrib/pgcrypto/rijndael.tbl +++ /dev/null @@ -1,1139 +0,0 @@ -/* Generated by rijndael.c */ - -static const u1byte pow_tab[256] = { - 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, - 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, - 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, - 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, - 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, - 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, - 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, - 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, - 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, - 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, - 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, - 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, - 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, - 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, - 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, - 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1 -}; - -static const u1byte log_tab[256] = { - 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, - 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, - 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, - 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, - 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, - 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, - 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, - 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, - 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, - 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, - 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, - 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, - 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, - 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, - 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, - 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1 -}; - -static const u1byte sbx_tab[256] = { - 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, - 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, - 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, - 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, - 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, - 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, - 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, - 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, - 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, - 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, - 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, - 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, - 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, - 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, - 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, - 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1 -}; - -static const u1byte isb_tab[256] = { - 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53, - 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170, - 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49, - 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205, - 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136, - 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154, - 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163, - 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160, - 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65, - 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117, - 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128, - 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84, - 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202, - 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14, - 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23, - 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1 -}; - -static const u4byte ft_tab[4][256] = { -{ - 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, - 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, - 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, - 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, - 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, - 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, - 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, - 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, - 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, - 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, - 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, - 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, - 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, - 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, - 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, - 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, - 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, - 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, - 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, - 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, - 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, - 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, - 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, - 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, - 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, - 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, - 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, - 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, - 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, - 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, - 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, - 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, - 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, - 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, - 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, - 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, - 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, - 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, - 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, - 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, - 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, - 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, - 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, - 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, - 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, - 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, - 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, - 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, - 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, - 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, - 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, - 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, - 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, - 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, - 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, - 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, - 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, - 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, - 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, - 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, - 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, - 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, - 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, - 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c -}, { - 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, - 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, - 0x30306050, 0x01010203, 0x6767cea9, 0x2b2b567d, - 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, - 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, - 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, - 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, - 0x9c9c23bf, 0xa4a453f7, 0x7272e496, 0xc0c09b5b, - 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, - 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, - 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, - 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, - 0x0404080c, 0xc7c79552, 0x23234665, 0xc3c39d5e, - 0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5, - 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, - 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, - 0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, - 0x1b1b362d, 0x6e6edcb2, 0x5a5ab4ee, 0xa0a05bfb, - 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, - 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, - 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, - 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, - 0x6a6ad4be, 0xcbcb8d46, 0xbebe67d9, 0x3939724b, - 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, - 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, - 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, - 0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81, - 0x5050a0f0, 0x3c3c7844, 0x9f9f25ba, 0xa8a84be3, - 0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, - 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, - 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, - 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, - 0xcdcd814c, 0x0c0c1814, 0x13132635, 0xececc32f, - 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, - 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, - 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, - 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, - 0x22224466, 0x2a2a547e, 0x90903bab, 0x88880b83, - 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, - 0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, - 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, - 0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4, - 0xc2c29f5d, 0xd3d3bd6e, 0xacac43ef, 0x6262c4a6, - 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, - 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, - 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, - 0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, - 0x6565caaf, 0x7a7af48e, 0xaeae47e9, 0x08081018, - 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, - 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, - 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, - 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, - 0x7070e090, 0x3e3e7c42, 0xb5b571c4, 0x6666ccaa, - 0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12, - 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, - 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, - 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, - 0x6969d2bb, 0xd9d9a970, 0x8e8e0789, 0x949433a7, - 0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, - 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, - 0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, - 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, - 0x414182c3, 0x999929b0, 0x2d2d5a77, 0x0f0f1e11, - 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a -}, { - 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, - 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, - 0x30605030, 0x01020301, 0x67cea967, 0x2b567d2b, - 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, - 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, - 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, - 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, - 0x9c23bf9c, 0xa453f7a4, 0x72e49672, 0xc09b5bc0, - 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, - 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, - 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, - 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, - 0x04080c04, 0xc79552c7, 0x23466523, 0xc39d5ec3, - 0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a, - 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, - 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, - 0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, - 0x1b362d1b, 0x6edcb26e, 0x5ab4ee5a, 0xa05bfba0, - 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, - 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, - 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, - 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, - 0x6ad4be6a, 0xcb8d46cb, 0xbe67d9be, 0x39724b39, - 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, - 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, - 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, - 0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f, - 0x50a0f050, 0x3c78443c, 0x9f25ba9f, 0xa84be3a8, - 0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, - 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, - 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, - 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, - 0xcd814ccd, 0x0c18140c, 0x13263513, 0xecc32fec, - 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, - 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, - 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, - 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, - 0x22446622, 0x2a547e2a, 0x903bab90, 0x880b8388, - 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, - 0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, - 0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, - 0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c, - 0xc29f5dc2, 0xd3bd6ed3, 0xac43efac, 0x62c4a662, - 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, - 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, - 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, - 0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, - 0x65caaf65, 0x7af48e7a, 0xae47e9ae, 0x08101808, - 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, - 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, - 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, - 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, - 0x70e09070, 0x3e7c423e, 0xb571c4b5, 0x66ccaa66, - 0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e, - 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, - 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, - 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, - 0x69d2bb69, 0xd9a970d9, 0x8e07898e, 0x9433a794, - 0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, - 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, - 0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, - 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, - 0x4182c341, 0x9929b099, 0x2d5a772d, 0x0f1e110f, - 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16 -}, { - 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, - 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, - 0x60503030, 0x02030101, 0xcea96767, 0x567d2b2b, - 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, - 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, - 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, - 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, - 0x23bf9c9c, 0x53f7a4a4, 0xe4967272, 0x9b5bc0c0, - 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, - 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, - 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, - 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, - 0x080c0404, 0x9552c7c7, 0x46652323, 0x9d5ec3c3, - 0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a, - 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, - 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, - 0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, - 0x362d1b1b, 0xdcb26e6e, 0xb4ee5a5a, 0x5bfba0a0, - 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, - 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, - 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, - 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, - 0xd4be6a6a, 0x8d46cbcb, 0x67d9bebe, 0x724b3939, - 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, - 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, - 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, - 0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f, - 0xa0f05050, 0x78443c3c, 0x25ba9f9f, 0x4be3a8a8, - 0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f, - 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, - 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, - 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, - 0x814ccdcd, 0x18140c0c, 0x26351313, 0xc32fecec, - 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, - 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, - 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, - 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, - 0x44662222, 0x547e2a2a, 0x3bab9090, 0x0b838888, - 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, - 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, - 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, - 0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c, - 0x9f5dc2c2, 0xbd6ed3d3, 0x43efacac, 0xc4a66262, - 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, - 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, - 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, - 0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, - 0xcaaf6565, 0xf48e7a7a, 0x47e9aeae, 0x10180808, - 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, - 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, - 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, - 0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, - 0xe0907070, 0x7c423e3e, 0x71c4b5b5, 0xccaa6666, - 0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e, - 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, - 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, - 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, - 0xd2bb6969, 0xa970d9d9, 0x07898e8e, 0x33a79494, - 0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, - 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, - 0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, - 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, - 0x82c34141, 0x29b09999, 0x5a772d2d, 0x1e110f0f, - 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616 -} -}; - -static const u4byte it_tab[4][256] = { -{ - 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, - 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b, - 0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5, - 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, - 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, - 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, - 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, - 0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e, - 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, - 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, - 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, - 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, - 0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52, - 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, - 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3, - 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, - 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, - 0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4, - 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, - 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd, - 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, - 0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060, - 0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967, - 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, - 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, - 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, - 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, - 0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624, - 0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b, - 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, - 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, - 0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, - 0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3, - 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, - 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, - 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, - 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, - 0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177, - 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, - 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, - 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, - 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, - 0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54, - 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, - 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, - 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, - 0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83, - 0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef, - 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, - 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, - 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, - 0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117, - 0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4, - 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, - 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, - 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, - 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, - 0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a, - 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, - 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, - 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, - 0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff, - 0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664, - 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0 -}, { - 0xa7f45150, 0x65417e53, 0xa4171ac3, 0x5e273a96, - 0x6bab3bcb, 0x459d1ff1, 0x58faacab, 0x03e34b93, - 0xfa302055, 0x6d76adf6, 0x76cc8891, 0x4c02f525, - 0xd7e54ffc, 0xcb2ac5d7, 0x44352680, 0xa362b58f, - 0x5ab1de49, 0x1bba2567, 0x0eea4598, 0xc0fe5de1, - 0x752fc302, 0xf04c8112, 0x97468da3, 0xf9d36bc6, - 0x5f8f03e7, 0x9c921595, 0x7a6dbfeb, 0x595295da, - 0x83bed42d, 0x217458d3, 0x69e04929, 0xc8c98e44, - 0x89c2756a, 0x798ef478, 0x3e58996b, 0x71b927dd, - 0x4fe1beb6, 0xad88f017, 0xac20c966, 0x3ace7db4, - 0x4adf6318, 0x311ae582, 0x33519760, 0x7f536245, - 0x7764b1e0, 0xae6bbb84, 0xa081fe1c, 0x2b08f994, - 0x68487058, 0xfd458f19, 0x6cde9487, 0xf87b52b7, - 0xd373ab23, 0x024b72e2, 0x8f1fe357, 0xab55662a, - 0x28ebb207, 0xc2b52f03, 0x7bc5869a, 0x0837d3a5, - 0x872830f2, 0xa5bf23b2, 0x6a0302ba, 0x8216ed5c, - 0x1ccf8a2b, 0xb479a792, 0xf207f3f0, 0xe2694ea1, - 0xf4da65cd, 0xbe0506d5, 0x6234d11f, 0xfea6c48a, - 0x532e349d, 0x55f3a2a0, 0xe18a0532, 0xebf6a475, - 0xec830b39, 0xef6040aa, 0x9f715e06, 0x106ebd51, - 0x8a213ef9, 0x06dd963d, 0x053eddae, 0xbde64d46, - 0x8d5491b5, 0x5dc47105, 0xd406046f, 0x155060ff, - 0xfb981924, 0xe9bdd697, 0x434089cc, 0x9ed96777, - 0x42e8b0bd, 0x8b890788, 0x5b19e738, 0xeec879db, - 0x0a7ca147, 0x0f427ce9, 0x1e84f8c9, 0x00000000, - 0x86800983, 0xed2b3248, 0x70111eac, 0x725a6c4e, - 0xff0efdfb, 0x38850f56, 0xd5ae3d1e, 0x392d3627, - 0xd90f0a64, 0xa65c6821, 0x545b9bd1, 0x2e36243a, - 0x670a0cb1, 0xe757930f, 0x96eeb4d2, 0x919b1b9e, - 0xc5c0804f, 0x20dc61a2, 0x4b775a69, 0x1a121c16, - 0xba93e20a, 0x2aa0c0e5, 0xe0223c43, 0x171b121d, - 0x0d090e0b, 0xc78bf2ad, 0xa8b62db9, 0xa91e14c8, - 0x19f15785, 0x0775af4c, 0xdd99eebb, 0x607fa3fd, - 0x2601f79f, 0xf5725cbc, 0x3b6644c5, 0x7efb5b34, - 0x29438b76, 0xc623cbdc, 0xfcedb668, 0xf1e4b863, - 0xdc31d7ca, 0x85634210, 0x22971340, 0x11c68420, - 0x244a857d, 0x3dbbd2f8, 0x32f9ae11, 0xa129c76d, - 0x2f9e1d4b, 0x30b2dcf3, 0x52860dec, 0xe3c177d0, - 0x16b32b6c, 0xb970a999, 0x489411fa, 0x64e94722, - 0x8cfca8c4, 0x3ff0a01a, 0x2c7d56d8, 0x903322ef, - 0x4e4987c7, 0xd138d9c1, 0xa2ca8cfe, 0x0bd49836, - 0x81f5a6cf, 0xde7aa528, 0x8eb7da26, 0xbfad3fa4, - 0x9d3a2ce4, 0x9278500d, 0xcc5f6a9b, 0x467e5462, - 0x138df6c2, 0xb8d890e8, 0xf7392e5e, 0xafc382f5, - 0x805d9fbe, 0x93d0697c, 0x2dd56fa9, 0x1225cfb3, - 0x99acc83b, 0x7d1810a7, 0x639ce86e, 0xbb3bdb7b, - 0x7826cd09, 0x18596ef4, 0xb79aec01, 0x9a4f83a8, - 0x6e95e665, 0xe6ffaa7e, 0xcfbc2108, 0xe815efe6, - 0x9be7bad9, 0x366f4ace, 0x099fead4, 0x7cb029d6, - 0xb2a431af, 0x233f2a31, 0x94a5c630, 0x66a235c0, - 0xbc4e7437, 0xca82fca6, 0xd090e0b0, 0xd8a73315, - 0x9804f14a, 0xdaec41f7, 0x50cd7f0e, 0xf691172f, - 0xd64d768d, 0xb0ef434d, 0x4daacc54, 0x0496e4df, - 0xb5d19ee3, 0x886a4c1b, 0x1f2cc1b8, 0x5165467f, - 0xea5e9d04, 0x358c015d, 0x7487fa73, 0x410bfb2e, - 0x1d67b35a, 0xd2db9252, 0x5610e933, 0x47d66d13, - 0x61d79a8c, 0x0ca1377a, 0x14f8598e, 0x3c13eb89, - 0x27a9ceee, 0xc961b735, 0xe51ce1ed, 0xb1477a3c, - 0xdfd29c59, 0x73f2553f, 0xce141879, 0x37c773bf, - 0xcdf753ea, 0xaafd5f5b, 0x6f3ddf14, 0xdb447886, - 0xf3afca81, 0xc468b93e, 0x3424382c, 0x40a3c25f, - 0xc31d1672, 0x25e2bc0c, 0x493c288b, 0x950dff41, - 0x01a83971, 0xb30c08de, 0xe4b4d89c, 0xc1566490, - 0x84cb7b61, 0xb632d570, 0x5c6c4874, 0x57b8d042 -}, { - 0xf45150a7, 0x417e5365, 0x171ac3a4, 0x273a965e, - 0xab3bcb6b, 0x9d1ff145, 0xfaacab58, 0xe34b9303, - 0x302055fa, 0x76adf66d, 0xcc889176, 0x02f5254c, - 0xe54ffcd7, 0x2ac5d7cb, 0x35268044, 0x62b58fa3, - 0xb1de495a, 0xba25671b, 0xea45980e, 0xfe5de1c0, - 0x2fc30275, 0x4c8112f0, 0x468da397, 0xd36bc6f9, - 0x8f03e75f, 0x9215959c, 0x6dbfeb7a, 0x5295da59, - 0xbed42d83, 0x7458d321, 0xe0492969, 0xc98e44c8, - 0xc2756a89, 0x8ef47879, 0x58996b3e, 0xb927dd71, - 0xe1beb64f, 0x88f017ad, 0x20c966ac, 0xce7db43a, - 0xdf63184a, 0x1ae58231, 0x51976033, 0x5362457f, - 0x64b1e077, 0x6bbb84ae, 0x81fe1ca0, 0x08f9942b, - 0x48705868, 0x458f19fd, 0xde94876c, 0x7b52b7f8, - 0x73ab23d3, 0x4b72e202, 0x1fe3578f, 0x55662aab, - 0xebb20728, 0xb52f03c2, 0xc5869a7b, 0x37d3a508, - 0x2830f287, 0xbf23b2a5, 0x0302ba6a, 0x16ed5c82, - 0xcf8a2b1c, 0x79a792b4, 0x07f3f0f2, 0x694ea1e2, - 0xda65cdf4, 0x0506d5be, 0x34d11f62, 0xa6c48afe, - 0x2e349d53, 0xf3a2a055, 0x8a0532e1, 0xf6a475eb, - 0x830b39ec, 0x6040aaef, 0x715e069f, 0x6ebd5110, - 0x213ef98a, 0xdd963d06, 0x3eddae05, 0xe64d46bd, - 0x5491b58d, 0xc471055d, 0x06046fd4, 0x5060ff15, - 0x981924fb, 0xbdd697e9, 0x4089cc43, 0xd967779e, - 0xe8b0bd42, 0x8907888b, 0x19e7385b, 0xc879dbee, - 0x7ca1470a, 0x427ce90f, 0x84f8c91e, 0x00000000, - 0x80098386, 0x2b3248ed, 0x111eac70, 0x5a6c4e72, - 0x0efdfbff, 0x850f5638, 0xae3d1ed5, 0x2d362739, - 0x0f0a64d9, 0x5c6821a6, 0x5b9bd154, 0x36243a2e, - 0x0a0cb167, 0x57930fe7, 0xeeb4d296, 0x9b1b9e91, - 0xc0804fc5, 0xdc61a220, 0x775a694b, 0x121c161a, - 0x93e20aba, 0xa0c0e52a, 0x223c43e0, 0x1b121d17, - 0x090e0b0d, 0x8bf2adc7, 0xb62db9a8, 0x1e14c8a9, - 0xf1578519, 0x75af4c07, 0x99eebbdd, 0x7fa3fd60, - 0x01f79f26, 0x725cbcf5, 0x6644c53b, 0xfb5b347e, - 0x438b7629, 0x23cbdcc6, 0xedb668fc, 0xe4b863f1, - 0x31d7cadc, 0x63421085, 0x97134022, 0xc6842011, - 0x4a857d24, 0xbbd2f83d, 0xf9ae1132, 0x29c76da1, - 0x9e1d4b2f, 0xb2dcf330, 0x860dec52, 0xc177d0e3, - 0xb32b6c16, 0x70a999b9, 0x9411fa48, 0xe9472264, - 0xfca8c48c, 0xf0a01a3f, 0x7d56d82c, 0x3322ef90, - 0x4987c74e, 0x38d9c1d1, 0xca8cfea2, 0xd498360b, - 0xf5a6cf81, 0x7aa528de, 0xb7da268e, 0xad3fa4bf, - 0x3a2ce49d, 0x78500d92, 0x5f6a9bcc, 0x7e546246, - 0x8df6c213, 0xd890e8b8, 0x392e5ef7, 0xc382f5af, - 0x5d9fbe80, 0xd0697c93, 0xd56fa92d, 0x25cfb312, - 0xacc83b99, 0x1810a77d, 0x9ce86e63, 0x3bdb7bbb, - 0x26cd0978, 0x596ef418, 0x9aec01b7, 0x4f83a89a, - 0x95e6656e, 0xffaa7ee6, 0xbc2108cf, 0x15efe6e8, - 0xe7bad99b, 0x6f4ace36, 0x9fead409, 0xb029d67c, - 0xa431afb2, 0x3f2a3123, 0xa5c63094, 0xa235c066, - 0x4e7437bc, 0x82fca6ca, 0x90e0b0d0, 0xa73315d8, - 0x04f14a98, 0xec41f7da, 0xcd7f0e50, 0x91172ff6, - 0x4d768dd6, 0xef434db0, 0xaacc544d, 0x96e4df04, - 0xd19ee3b5, 0x6a4c1b88, 0x2cc1b81f, 0x65467f51, - 0x5e9d04ea, 0x8c015d35, 0x87fa7374, 0x0bfb2e41, - 0x67b35a1d, 0xdb9252d2, 0x10e93356, 0xd66d1347, - 0xd79a8c61, 0xa1377a0c, 0xf8598e14, 0x13eb893c, - 0xa9ceee27, 0x61b735c9, 0x1ce1ede5, 0x477a3cb1, - 0xd29c59df, 0xf2553f73, 0x141879ce, 0xc773bf37, - 0xf753eacd, 0xfd5f5baa, 0x3ddf146f, 0x447886db, - 0xafca81f3, 0x68b93ec4, 0x24382c34, 0xa3c25f40, - 0x1d1672c3, 0xe2bc0c25, 0x3c288b49, 0x0dff4195, - 0xa8397101, 0x0c08deb3, 0xb4d89ce4, 0x566490c1, - 0xcb7b6184, 0x32d570b6, 0x6c48745c, 0xb8d04257 -}, { - 0x5150a7f4, 0x7e536541, 0x1ac3a417, 0x3a965e27, - 0x3bcb6bab, 0x1ff1459d, 0xacab58fa, 0x4b9303e3, - 0x2055fa30, 0xadf66d76, 0x889176cc, 0xf5254c02, - 0x4ffcd7e5, 0xc5d7cb2a, 0x26804435, 0xb58fa362, - 0xde495ab1, 0x25671bba, 0x45980eea, 0x5de1c0fe, - 0xc302752f, 0x8112f04c, 0x8da39746, 0x6bc6f9d3, - 0x03e75f8f, 0x15959c92, 0xbfeb7a6d, 0x95da5952, - 0xd42d83be, 0x58d32174, 0x492969e0, 0x8e44c8c9, - 0x756a89c2, 0xf478798e, 0x996b3e58, 0x27dd71b9, - 0xbeb64fe1, 0xf017ad88, 0xc966ac20, 0x7db43ace, - 0x63184adf, 0xe582311a, 0x97603351, 0x62457f53, - 0xb1e07764, 0xbb84ae6b, 0xfe1ca081, 0xf9942b08, - 0x70586848, 0x8f19fd45, 0x94876cde, 0x52b7f87b, - 0xab23d373, 0x72e2024b, 0xe3578f1f, 0x662aab55, - 0xb20728eb, 0x2f03c2b5, 0x869a7bc5, 0xd3a50837, - 0x30f28728, 0x23b2a5bf, 0x02ba6a03, 0xed5c8216, - 0x8a2b1ccf, 0xa792b479, 0xf3f0f207, 0x4ea1e269, - 0x65cdf4da, 0x06d5be05, 0xd11f6234, 0xc48afea6, - 0x349d532e, 0xa2a055f3, 0x0532e18a, 0xa475ebf6, - 0x0b39ec83, 0x40aaef60, 0x5e069f71, 0xbd51106e, - 0x3ef98a21, 0x963d06dd, 0xddae053e, 0x4d46bde6, - 0x91b58d54, 0x71055dc4, 0x046fd406, 0x60ff1550, - 0x1924fb98, 0xd697e9bd, 0x89cc4340, 0x67779ed9, - 0xb0bd42e8, 0x07888b89, 0xe7385b19, 0x79dbeec8, - 0xa1470a7c, 0x7ce90f42, 0xf8c91e84, 0x00000000, - 0x09838680, 0x3248ed2b, 0x1eac7011, 0x6c4e725a, - 0xfdfbff0e, 0x0f563885, 0x3d1ed5ae, 0x3627392d, - 0x0a64d90f, 0x6821a65c, 0x9bd1545b, 0x243a2e36, - 0x0cb1670a, 0x930fe757, 0xb4d296ee, 0x1b9e919b, - 0x804fc5c0, 0x61a220dc, 0x5a694b77, 0x1c161a12, - 0xe20aba93, 0xc0e52aa0, 0x3c43e022, 0x121d171b, - 0x0e0b0d09, 0xf2adc78b, 0x2db9a8b6, 0x14c8a91e, - 0x578519f1, 0xaf4c0775, 0xeebbdd99, 0xa3fd607f, - 0xf79f2601, 0x5cbcf572, 0x44c53b66, 0x5b347efb, - 0x8b762943, 0xcbdcc623, 0xb668fced, 0xb863f1e4, - 0xd7cadc31, 0x42108563, 0x13402297, 0x842011c6, - 0x857d244a, 0xd2f83dbb, 0xae1132f9, 0xc76da129, - 0x1d4b2f9e, 0xdcf330b2, 0x0dec5286, 0x77d0e3c1, - 0x2b6c16b3, 0xa999b970, 0x11fa4894, 0x472264e9, - 0xa8c48cfc, 0xa01a3ff0, 0x56d82c7d, 0x22ef9033, - 0x87c74e49, 0xd9c1d138, 0x8cfea2ca, 0x98360bd4, - 0xa6cf81f5, 0xa528de7a, 0xda268eb7, 0x3fa4bfad, - 0x2ce49d3a, 0x500d9278, 0x6a9bcc5f, 0x5462467e, - 0xf6c2138d, 0x90e8b8d8, 0x2e5ef739, 0x82f5afc3, - 0x9fbe805d, 0x697c93d0, 0x6fa92dd5, 0xcfb31225, - 0xc83b99ac, 0x10a77d18, 0xe86e639c, 0xdb7bbb3b, - 0xcd097826, 0x6ef41859, 0xec01b79a, 0x83a89a4f, - 0xe6656e95, 0xaa7ee6ff, 0x2108cfbc, 0xefe6e815, - 0xbad99be7, 0x4ace366f, 0xead4099f, 0x29d67cb0, - 0x31afb2a4, 0x2a31233f, 0xc63094a5, 0x35c066a2, - 0x7437bc4e, 0xfca6ca82, 0xe0b0d090, 0x3315d8a7, - 0xf14a9804, 0x41f7daec, 0x7f0e50cd, 0x172ff691, - 0x768dd64d, 0x434db0ef, 0xcc544daa, 0xe4df0496, - 0x9ee3b5d1, 0x4c1b886a, 0xc1b81f2c, 0x467f5165, - 0x9d04ea5e, 0x015d358c, 0xfa737487, 0xfb2e410b, - 0xb35a1d67, 0x9252d2db, 0xe9335610, 0x6d1347d6, - 0x9a8c61d7, 0x377a0ca1, 0x598e14f8, 0xeb893c13, - 0xceee27a9, 0xb735c961, 0xe1ede51c, 0x7a3cb147, - 0x9c59dfd2, 0x553f73f2, 0x1879ce14, 0x73bf37c7, - 0x53eacdf7, 0x5f5baafd, 0xdf146f3d, 0x7886db44, - 0xca81f3af, 0xb93ec468, 0x382c3424, 0xc25f40a3, - 0x1672c31d, 0xbc0c25e2, 0x288b493c, 0xff41950d, - 0x397101a8, 0x08deb30c, 0xd89ce4b4, 0x6490c156, - 0x7b6184cb, 0xd570b632, 0x48745c6c, 0xd04257b8 -} -}; - -static const u4byte fl_tab[4][256] = { -{ - 0x00000063, 0x0000007c, 0x00000077, 0x0000007b, - 0x000000f2, 0x0000006b, 0x0000006f, 0x000000c5, - 0x00000030, 0x00000001, 0x00000067, 0x0000002b, - 0x000000fe, 0x000000d7, 0x000000ab, 0x00000076, - 0x000000ca, 0x00000082, 0x000000c9, 0x0000007d, - 0x000000fa, 0x00000059, 0x00000047, 0x000000f0, - 0x000000ad, 0x000000d4, 0x000000a2, 0x000000af, - 0x0000009c, 0x000000a4, 0x00000072, 0x000000c0, - 0x000000b7, 0x000000fd, 0x00000093, 0x00000026, - 0x00000036, 0x0000003f, 0x000000f7, 0x000000cc, - 0x00000034, 0x000000a5, 0x000000e5, 0x000000f1, - 0x00000071, 0x000000d8, 0x00000031, 0x00000015, - 0x00000004, 0x000000c7, 0x00000023, 0x000000c3, - 0x00000018, 0x00000096, 0x00000005, 0x0000009a, - 0x00000007, 0x00000012, 0x00000080, 0x000000e2, - 0x000000eb, 0x00000027, 0x000000b2, 0x00000075, - 0x00000009, 0x00000083, 0x0000002c, 0x0000001a, - 0x0000001b, 0x0000006e, 0x0000005a, 0x000000a0, - 0x00000052, 0x0000003b, 0x000000d6, 0x000000b3, - 0x00000029, 0x000000e3, 0x0000002f, 0x00000084, - 0x00000053, 0x000000d1, 0x00000000, 0x000000ed, - 0x00000020, 0x000000fc, 0x000000b1, 0x0000005b, - 0x0000006a, 0x000000cb, 0x000000be, 0x00000039, - 0x0000004a, 0x0000004c, 0x00000058, 0x000000cf, - 0x000000d0, 0x000000ef, 0x000000aa, 0x000000fb, - 0x00000043, 0x0000004d, 0x00000033, 0x00000085, - 0x00000045, 0x000000f9, 0x00000002, 0x0000007f, - 0x00000050, 0x0000003c, 0x0000009f, 0x000000a8, - 0x00000051, 0x000000a3, 0x00000040, 0x0000008f, - 0x00000092, 0x0000009d, 0x00000038, 0x000000f5, - 0x000000bc, 0x000000b6, 0x000000da, 0x00000021, - 0x00000010, 0x000000ff, 0x000000f3, 0x000000d2, - 0x000000cd, 0x0000000c, 0x00000013, 0x000000ec, - 0x0000005f, 0x00000097, 0x00000044, 0x00000017, - 0x000000c4, 0x000000a7, 0x0000007e, 0x0000003d, - 0x00000064, 0x0000005d, 0x00000019, 0x00000073, - 0x00000060, 0x00000081, 0x0000004f, 0x000000dc, - 0x00000022, 0x0000002a, 0x00000090, 0x00000088, - 0x00000046, 0x000000ee, 0x000000b8, 0x00000014, - 0x000000de, 0x0000005e, 0x0000000b, 0x000000db, - 0x000000e0, 0x00000032, 0x0000003a, 0x0000000a, - 0x00000049, 0x00000006, 0x00000024, 0x0000005c, - 0x000000c2, 0x000000d3, 0x000000ac, 0x00000062, - 0x00000091, 0x00000095, 0x000000e4, 0x00000079, - 0x000000e7, 0x000000c8, 0x00000037, 0x0000006d, - 0x0000008d, 0x000000d5, 0x0000004e, 0x000000a9, - 0x0000006c, 0x00000056, 0x000000f4, 0x000000ea, - 0x00000065, 0x0000007a, 0x000000ae, 0x00000008, - 0x000000ba, 0x00000078, 0x00000025, 0x0000002e, - 0x0000001c, 0x000000a6, 0x000000b4, 0x000000c6, - 0x000000e8, 0x000000dd, 0x00000074, 0x0000001f, - 0x0000004b, 0x000000bd, 0x0000008b, 0x0000008a, - 0x00000070, 0x0000003e, 0x000000b5, 0x00000066, - 0x00000048, 0x00000003, 0x000000f6, 0x0000000e, - 0x00000061, 0x00000035, 0x00000057, 0x000000b9, - 0x00000086, 0x000000c1, 0x0000001d, 0x0000009e, - 0x000000e1, 0x000000f8, 0x00000098, 0x00000011, - 0x00000069, 0x000000d9, 0x0000008e, 0x00000094, - 0x0000009b, 0x0000001e, 0x00000087, 0x000000e9, - 0x000000ce, 0x00000055, 0x00000028, 0x000000df, - 0x0000008c, 0x000000a1, 0x00000089, 0x0000000d, - 0x000000bf, 0x000000e6, 0x00000042, 0x00000068, - 0x00000041, 0x00000099, 0x0000002d, 0x0000000f, - 0x000000b0, 0x00000054, 0x000000bb, 0x00000016 -}, { - 0x00006300, 0x00007c00, 0x00007700, 0x00007b00, - 0x0000f200, 0x00006b00, 0x00006f00, 0x0000c500, - 0x00003000, 0x00000100, 0x00006700, 0x00002b00, - 0x0000fe00, 0x0000d700, 0x0000ab00, 0x00007600, - 0x0000ca00, 0x00008200, 0x0000c900, 0x00007d00, - 0x0000fa00, 0x00005900, 0x00004700, 0x0000f000, - 0x0000ad00, 0x0000d400, 0x0000a200, 0x0000af00, - 0x00009c00, 0x0000a400, 0x00007200, 0x0000c000, - 0x0000b700, 0x0000fd00, 0x00009300, 0x00002600, - 0x00003600, 0x00003f00, 0x0000f700, 0x0000cc00, - 0x00003400, 0x0000a500, 0x0000e500, 0x0000f100, - 0x00007100, 0x0000d800, 0x00003100, 0x00001500, - 0x00000400, 0x0000c700, 0x00002300, 0x0000c300, - 0x00001800, 0x00009600, 0x00000500, 0x00009a00, - 0x00000700, 0x00001200, 0x00008000, 0x0000e200, - 0x0000eb00, 0x00002700, 0x0000b200, 0x00007500, - 0x00000900, 0x00008300, 0x00002c00, 0x00001a00, - 0x00001b00, 0x00006e00, 0x00005a00, 0x0000a000, - 0x00005200, 0x00003b00, 0x0000d600, 0x0000b300, - 0x00002900, 0x0000e300, 0x00002f00, 0x00008400, - 0x00005300, 0x0000d100, 0x00000000, 0x0000ed00, - 0x00002000, 0x0000fc00, 0x0000b100, 0x00005b00, - 0x00006a00, 0x0000cb00, 0x0000be00, 0x00003900, - 0x00004a00, 0x00004c00, 0x00005800, 0x0000cf00, - 0x0000d000, 0x0000ef00, 0x0000aa00, 0x0000fb00, - 0x00004300, 0x00004d00, 0x00003300, 0x00008500, - 0x00004500, 0x0000f900, 0x00000200, 0x00007f00, - 0x00005000, 0x00003c00, 0x00009f00, 0x0000a800, - 0x00005100, 0x0000a300, 0x00004000, 0x00008f00, - 0x00009200, 0x00009d00, 0x00003800, 0x0000f500, - 0x0000bc00, 0x0000b600, 0x0000da00, 0x00002100, - 0x00001000, 0x0000ff00, 0x0000f300, 0x0000d200, - 0x0000cd00, 0x00000c00, 0x00001300, 0x0000ec00, - 0x00005f00, 0x00009700, 0x00004400, 0x00001700, - 0x0000c400, 0x0000a700, 0x00007e00, 0x00003d00, - 0x00006400, 0x00005d00, 0x00001900, 0x00007300, - 0x00006000, 0x00008100, 0x00004f00, 0x0000dc00, - 0x00002200, 0x00002a00, 0x00009000, 0x00008800, - 0x00004600, 0x0000ee00, 0x0000b800, 0x00001400, - 0x0000de00, 0x00005e00, 0x00000b00, 0x0000db00, - 0x0000e000, 0x00003200, 0x00003a00, 0x00000a00, - 0x00004900, 0x00000600, 0x00002400, 0x00005c00, - 0x0000c200, 0x0000d300, 0x0000ac00, 0x00006200, - 0x00009100, 0x00009500, 0x0000e400, 0x00007900, - 0x0000e700, 0x0000c800, 0x00003700, 0x00006d00, - 0x00008d00, 0x0000d500, 0x00004e00, 0x0000a900, - 0x00006c00, 0x00005600, 0x0000f400, 0x0000ea00, - 0x00006500, 0x00007a00, 0x0000ae00, 0x00000800, - 0x0000ba00, 0x00007800, 0x00002500, 0x00002e00, - 0x00001c00, 0x0000a600, 0x0000b400, 0x0000c600, - 0x0000e800, 0x0000dd00, 0x00007400, 0x00001f00, - 0x00004b00, 0x0000bd00, 0x00008b00, 0x00008a00, - 0x00007000, 0x00003e00, 0x0000b500, 0x00006600, - 0x00004800, 0x00000300, 0x0000f600, 0x00000e00, - 0x00006100, 0x00003500, 0x00005700, 0x0000b900, - 0x00008600, 0x0000c100, 0x00001d00, 0x00009e00, - 0x0000e100, 0x0000f800, 0x00009800, 0x00001100, - 0x00006900, 0x0000d900, 0x00008e00, 0x00009400, - 0x00009b00, 0x00001e00, 0x00008700, 0x0000e900, - 0x0000ce00, 0x00005500, 0x00002800, 0x0000df00, - 0x00008c00, 0x0000a100, 0x00008900, 0x00000d00, - 0x0000bf00, 0x0000e600, 0x00004200, 0x00006800, - 0x00004100, 0x00009900, 0x00002d00, 0x00000f00, - 0x0000b000, 0x00005400, 0x0000bb00, 0x00001600 -}, { - 0x00630000, 0x007c0000, 0x00770000, 0x007b0000, - 0x00f20000, 0x006b0000, 0x006f0000, 0x00c50000, - 0x00300000, 0x00010000, 0x00670000, 0x002b0000, - 0x00fe0000, 0x00d70000, 0x00ab0000, 0x00760000, - 0x00ca0000, 0x00820000, 0x00c90000, 0x007d0000, - 0x00fa0000, 0x00590000, 0x00470000, 0x00f00000, - 0x00ad0000, 0x00d40000, 0x00a20000, 0x00af0000, - 0x009c0000, 0x00a40000, 0x00720000, 0x00c00000, - 0x00b70000, 0x00fd0000, 0x00930000, 0x00260000, - 0x00360000, 0x003f0000, 0x00f70000, 0x00cc0000, - 0x00340000, 0x00a50000, 0x00e50000, 0x00f10000, - 0x00710000, 0x00d80000, 0x00310000, 0x00150000, - 0x00040000, 0x00c70000, 0x00230000, 0x00c30000, - 0x00180000, 0x00960000, 0x00050000, 0x009a0000, - 0x00070000, 0x00120000, 0x00800000, 0x00e20000, - 0x00eb0000, 0x00270000, 0x00b20000, 0x00750000, - 0x00090000, 0x00830000, 0x002c0000, 0x001a0000, - 0x001b0000, 0x006e0000, 0x005a0000, 0x00a00000, - 0x00520000, 0x003b0000, 0x00d60000, 0x00b30000, - 0x00290000, 0x00e30000, 0x002f0000, 0x00840000, - 0x00530000, 0x00d10000, 0x00000000, 0x00ed0000, - 0x00200000, 0x00fc0000, 0x00b10000, 0x005b0000, - 0x006a0000, 0x00cb0000, 0x00be0000, 0x00390000, - 0x004a0000, 0x004c0000, 0x00580000, 0x00cf0000, - 0x00d00000, 0x00ef0000, 0x00aa0000, 0x00fb0000, - 0x00430000, 0x004d0000, 0x00330000, 0x00850000, - 0x00450000, 0x00f90000, 0x00020000, 0x007f0000, - 0x00500000, 0x003c0000, 0x009f0000, 0x00a80000, - 0x00510000, 0x00a30000, 0x00400000, 0x008f0000, - 0x00920000, 0x009d0000, 0x00380000, 0x00f50000, - 0x00bc0000, 0x00b60000, 0x00da0000, 0x00210000, - 0x00100000, 0x00ff0000, 0x00f30000, 0x00d20000, - 0x00cd0000, 0x000c0000, 0x00130000, 0x00ec0000, - 0x005f0000, 0x00970000, 0x00440000, 0x00170000, - 0x00c40000, 0x00a70000, 0x007e0000, 0x003d0000, - 0x00640000, 0x005d0000, 0x00190000, 0x00730000, - 0x00600000, 0x00810000, 0x004f0000, 0x00dc0000, - 0x00220000, 0x002a0000, 0x00900000, 0x00880000, - 0x00460000, 0x00ee0000, 0x00b80000, 0x00140000, - 0x00de0000, 0x005e0000, 0x000b0000, 0x00db0000, - 0x00e00000, 0x00320000, 0x003a0000, 0x000a0000, - 0x00490000, 0x00060000, 0x00240000, 0x005c0000, - 0x00c20000, 0x00d30000, 0x00ac0000, 0x00620000, - 0x00910000, 0x00950000, 0x00e40000, 0x00790000, - 0x00e70000, 0x00c80000, 0x00370000, 0x006d0000, - 0x008d0000, 0x00d50000, 0x004e0000, 0x00a90000, - 0x006c0000, 0x00560000, 0x00f40000, 0x00ea0000, - 0x00650000, 0x007a0000, 0x00ae0000, 0x00080000, - 0x00ba0000, 0x00780000, 0x00250000, 0x002e0000, - 0x001c0000, 0x00a60000, 0x00b40000, 0x00c60000, - 0x00e80000, 0x00dd0000, 0x00740000, 0x001f0000, - 0x004b0000, 0x00bd0000, 0x008b0000, 0x008a0000, - 0x00700000, 0x003e0000, 0x00b50000, 0x00660000, - 0x00480000, 0x00030000, 0x00f60000, 0x000e0000, - 0x00610000, 0x00350000, 0x00570000, 0x00b90000, - 0x00860000, 0x00c10000, 0x001d0000, 0x009e0000, - 0x00e10000, 0x00f80000, 0x00980000, 0x00110000, - 0x00690000, 0x00d90000, 0x008e0000, 0x00940000, - 0x009b0000, 0x001e0000, 0x00870000, 0x00e90000, - 0x00ce0000, 0x00550000, 0x00280000, 0x00df0000, - 0x008c0000, 0x00a10000, 0x00890000, 0x000d0000, - 0x00bf0000, 0x00e60000, 0x00420000, 0x00680000, - 0x00410000, 0x00990000, 0x002d0000, 0x000f0000, - 0x00b00000, 0x00540000, 0x00bb0000, 0x00160000 -}, { - 0x63000000, 0x7c000000, 0x77000000, 0x7b000000, - 0xf2000000, 0x6b000000, 0x6f000000, 0xc5000000, - 0x30000000, 0x01000000, 0x67000000, 0x2b000000, - 0xfe000000, 0xd7000000, 0xab000000, 0x76000000, - 0xca000000, 0x82000000, 0xc9000000, 0x7d000000, - 0xfa000000, 0x59000000, 0x47000000, 0xf0000000, - 0xad000000, 0xd4000000, 0xa2000000, 0xaf000000, - 0x9c000000, 0xa4000000, 0x72000000, 0xc0000000, - 0xb7000000, 0xfd000000, 0x93000000, 0x26000000, - 0x36000000, 0x3f000000, 0xf7000000, 0xcc000000, - 0x34000000, 0xa5000000, 0xe5000000, 0xf1000000, - 0x71000000, 0xd8000000, 0x31000000, 0x15000000, - 0x04000000, 0xc7000000, 0x23000000, 0xc3000000, - 0x18000000, 0x96000000, 0x05000000, 0x9a000000, - 0x07000000, 0x12000000, 0x80000000, 0xe2000000, - 0xeb000000, 0x27000000, 0xb2000000, 0x75000000, - 0x09000000, 0x83000000, 0x2c000000, 0x1a000000, - 0x1b000000, 0x6e000000, 0x5a000000, 0xa0000000, - 0x52000000, 0x3b000000, 0xd6000000, 0xb3000000, - 0x29000000, 0xe3000000, 0x2f000000, 0x84000000, - 0x53000000, 0xd1000000, 0x00000000, 0xed000000, - 0x20000000, 0xfc000000, 0xb1000000, 0x5b000000, - 0x6a000000, 0xcb000000, 0xbe000000, 0x39000000, - 0x4a000000, 0x4c000000, 0x58000000, 0xcf000000, - 0xd0000000, 0xef000000, 0xaa000000, 0xfb000000, - 0x43000000, 0x4d000000, 0x33000000, 0x85000000, - 0x45000000, 0xf9000000, 0x02000000, 0x7f000000, - 0x50000000, 0x3c000000, 0x9f000000, 0xa8000000, - 0x51000000, 0xa3000000, 0x40000000, 0x8f000000, - 0x92000000, 0x9d000000, 0x38000000, 0xf5000000, - 0xbc000000, 0xb6000000, 0xda000000, 0x21000000, - 0x10000000, 0xff000000, 0xf3000000, 0xd2000000, - 0xcd000000, 0x0c000000, 0x13000000, 0xec000000, - 0x5f000000, 0x97000000, 0x44000000, 0x17000000, - 0xc4000000, 0xa7000000, 0x7e000000, 0x3d000000, - 0x64000000, 0x5d000000, 0x19000000, 0x73000000, - 0x60000000, 0x81000000, 0x4f000000, 0xdc000000, - 0x22000000, 0x2a000000, 0x90000000, 0x88000000, - 0x46000000, 0xee000000, 0xb8000000, 0x14000000, - 0xde000000, 0x5e000000, 0x0b000000, 0xdb000000, - 0xe0000000, 0x32000000, 0x3a000000, 0x0a000000, - 0x49000000, 0x06000000, 0x24000000, 0x5c000000, - 0xc2000000, 0xd3000000, 0xac000000, 0x62000000, - 0x91000000, 0x95000000, 0xe4000000, 0x79000000, - 0xe7000000, 0xc8000000, 0x37000000, 0x6d000000, - 0x8d000000, 0xd5000000, 0x4e000000, 0xa9000000, - 0x6c000000, 0x56000000, 0xf4000000, 0xea000000, - 0x65000000, 0x7a000000, 0xae000000, 0x08000000, - 0xba000000, 0x78000000, 0x25000000, 0x2e000000, - 0x1c000000, 0xa6000000, 0xb4000000, 0xc6000000, - 0xe8000000, 0xdd000000, 0x74000000, 0x1f000000, - 0x4b000000, 0xbd000000, 0x8b000000, 0x8a000000, - 0x70000000, 0x3e000000, 0xb5000000, 0x66000000, - 0x48000000, 0x03000000, 0xf6000000, 0x0e000000, - 0x61000000, 0x35000000, 0x57000000, 0xb9000000, - 0x86000000, 0xc1000000, 0x1d000000, 0x9e000000, - 0xe1000000, 0xf8000000, 0x98000000, 0x11000000, - 0x69000000, 0xd9000000, 0x8e000000, 0x94000000, - 0x9b000000, 0x1e000000, 0x87000000, 0xe9000000, - 0xce000000, 0x55000000, 0x28000000, 0xdf000000, - 0x8c000000, 0xa1000000, 0x89000000, 0x0d000000, - 0xbf000000, 0xe6000000, 0x42000000, 0x68000000, - 0x41000000, 0x99000000, 0x2d000000, 0x0f000000, - 0xb0000000, 0x54000000, 0xbb000000, 0x16000000 -} -}; - -static const u4byte il_tab[4][256] = { -{ - 0x00000052, 0x00000009, 0x0000006a, 0x000000d5, - 0x00000030, 0x00000036, 0x000000a5, 0x00000038, - 0x000000bf, 0x00000040, 0x000000a3, 0x0000009e, - 0x00000081, 0x000000f3, 0x000000d7, 0x000000fb, - 0x0000007c, 0x000000e3, 0x00000039, 0x00000082, - 0x0000009b, 0x0000002f, 0x000000ff, 0x00000087, - 0x00000034, 0x0000008e, 0x00000043, 0x00000044, - 0x000000c4, 0x000000de, 0x000000e9, 0x000000cb, - 0x00000054, 0x0000007b, 0x00000094, 0x00000032, - 0x000000a6, 0x000000c2, 0x00000023, 0x0000003d, - 0x000000ee, 0x0000004c, 0x00000095, 0x0000000b, - 0x00000042, 0x000000fa, 0x000000c3, 0x0000004e, - 0x00000008, 0x0000002e, 0x000000a1, 0x00000066, - 0x00000028, 0x000000d9, 0x00000024, 0x000000b2, - 0x00000076, 0x0000005b, 0x000000a2, 0x00000049, - 0x0000006d, 0x0000008b, 0x000000d1, 0x00000025, - 0x00000072, 0x000000f8, 0x000000f6, 0x00000064, - 0x00000086, 0x00000068, 0x00000098, 0x00000016, - 0x000000d4, 0x000000a4, 0x0000005c, 0x000000cc, - 0x0000005d, 0x00000065, 0x000000b6, 0x00000092, - 0x0000006c, 0x00000070, 0x00000048, 0x00000050, - 0x000000fd, 0x000000ed, 0x000000b9, 0x000000da, - 0x0000005e, 0x00000015, 0x00000046, 0x00000057, - 0x000000a7, 0x0000008d, 0x0000009d, 0x00000084, - 0x00000090, 0x000000d8, 0x000000ab, 0x00000000, - 0x0000008c, 0x000000bc, 0x000000d3, 0x0000000a, - 0x000000f7, 0x000000e4, 0x00000058, 0x00000005, - 0x000000b8, 0x000000b3, 0x00000045, 0x00000006, - 0x000000d0, 0x0000002c, 0x0000001e, 0x0000008f, - 0x000000ca, 0x0000003f, 0x0000000f, 0x00000002, - 0x000000c1, 0x000000af, 0x000000bd, 0x00000003, - 0x00000001, 0x00000013, 0x0000008a, 0x0000006b, - 0x0000003a, 0x00000091, 0x00000011, 0x00000041, - 0x0000004f, 0x00000067, 0x000000dc, 0x000000ea, - 0x00000097, 0x000000f2, 0x000000cf, 0x000000ce, - 0x000000f0, 0x000000b4, 0x000000e6, 0x00000073, - 0x00000096, 0x000000ac, 0x00000074, 0x00000022, - 0x000000e7, 0x000000ad, 0x00000035, 0x00000085, - 0x000000e2, 0x000000f9, 0x00000037, 0x000000e8, - 0x0000001c, 0x00000075, 0x000000df, 0x0000006e, - 0x00000047, 0x000000f1, 0x0000001a, 0x00000071, - 0x0000001d, 0x00000029, 0x000000c5, 0x00000089, - 0x0000006f, 0x000000b7, 0x00000062, 0x0000000e, - 0x000000aa, 0x00000018, 0x000000be, 0x0000001b, - 0x000000fc, 0x00000056, 0x0000003e, 0x0000004b, - 0x000000c6, 0x000000d2, 0x00000079, 0x00000020, - 0x0000009a, 0x000000db, 0x000000c0, 0x000000fe, - 0x00000078, 0x000000cd, 0x0000005a, 0x000000f4, - 0x0000001f, 0x000000dd, 0x000000a8, 0x00000033, - 0x00000088, 0x00000007, 0x000000c7, 0x00000031, - 0x000000b1, 0x00000012, 0x00000010, 0x00000059, - 0x00000027, 0x00000080, 0x000000ec, 0x0000005f, - 0x00000060, 0x00000051, 0x0000007f, 0x000000a9, - 0x00000019, 0x000000b5, 0x0000004a, 0x0000000d, - 0x0000002d, 0x000000e5, 0x0000007a, 0x0000009f, - 0x00000093, 0x000000c9, 0x0000009c, 0x000000ef, - 0x000000a0, 0x000000e0, 0x0000003b, 0x0000004d, - 0x000000ae, 0x0000002a, 0x000000f5, 0x000000b0, - 0x000000c8, 0x000000eb, 0x000000bb, 0x0000003c, - 0x00000083, 0x00000053, 0x00000099, 0x00000061, - 0x00000017, 0x0000002b, 0x00000004, 0x0000007e, - 0x000000ba, 0x00000077, 0x000000d6, 0x00000026, - 0x000000e1, 0x00000069, 0x00000014, 0x00000063, - 0x00000055, 0x00000021, 0x0000000c, 0x0000007d -}, { - 0x00005200, 0x00000900, 0x00006a00, 0x0000d500, - 0x00003000, 0x00003600, 0x0000a500, 0x00003800, - 0x0000bf00, 0x00004000, 0x0000a300, 0x00009e00, - 0x00008100, 0x0000f300, 0x0000d700, 0x0000fb00, - 0x00007c00, 0x0000e300, 0x00003900, 0x00008200, - 0x00009b00, 0x00002f00, 0x0000ff00, 0x00008700, - 0x00003400, 0x00008e00, 0x00004300, 0x00004400, - 0x0000c400, 0x0000de00, 0x0000e900, 0x0000cb00, - 0x00005400, 0x00007b00, 0x00009400, 0x00003200, - 0x0000a600, 0x0000c200, 0x00002300, 0x00003d00, - 0x0000ee00, 0x00004c00, 0x00009500, 0x00000b00, - 0x00004200, 0x0000fa00, 0x0000c300, 0x00004e00, - 0x00000800, 0x00002e00, 0x0000a100, 0x00006600, - 0x00002800, 0x0000d900, 0x00002400, 0x0000b200, - 0x00007600, 0x00005b00, 0x0000a200, 0x00004900, - 0x00006d00, 0x00008b00, 0x0000d100, 0x00002500, - 0x00007200, 0x0000f800, 0x0000f600, 0x00006400, - 0x00008600, 0x00006800, 0x00009800, 0x00001600, - 0x0000d400, 0x0000a400, 0x00005c00, 0x0000cc00, - 0x00005d00, 0x00006500, 0x0000b600, 0x00009200, - 0x00006c00, 0x00007000, 0x00004800, 0x00005000, - 0x0000fd00, 0x0000ed00, 0x0000b900, 0x0000da00, - 0x00005e00, 0x00001500, 0x00004600, 0x00005700, - 0x0000a700, 0x00008d00, 0x00009d00, 0x00008400, - 0x00009000, 0x0000d800, 0x0000ab00, 0x00000000, - 0x00008c00, 0x0000bc00, 0x0000d300, 0x00000a00, - 0x0000f700, 0x0000e400, 0x00005800, 0x00000500, - 0x0000b800, 0x0000b300, 0x00004500, 0x00000600, - 0x0000d000, 0x00002c00, 0x00001e00, 0x00008f00, - 0x0000ca00, 0x00003f00, 0x00000f00, 0x00000200, - 0x0000c100, 0x0000af00, 0x0000bd00, 0x00000300, - 0x00000100, 0x00001300, 0x00008a00, 0x00006b00, - 0x00003a00, 0x00009100, 0x00001100, 0x00004100, - 0x00004f00, 0x00006700, 0x0000dc00, 0x0000ea00, - 0x00009700, 0x0000f200, 0x0000cf00, 0x0000ce00, - 0x0000f000, 0x0000b400, 0x0000e600, 0x00007300, - 0x00009600, 0x0000ac00, 0x00007400, 0x00002200, - 0x0000e700, 0x0000ad00, 0x00003500, 0x00008500, - 0x0000e200, 0x0000f900, 0x00003700, 0x0000e800, - 0x00001c00, 0x00007500, 0x0000df00, 0x00006e00, - 0x00004700, 0x0000f100, 0x00001a00, 0x00007100, - 0x00001d00, 0x00002900, 0x0000c500, 0x00008900, - 0x00006f00, 0x0000b700, 0x00006200, 0x00000e00, - 0x0000aa00, 0x00001800, 0x0000be00, 0x00001b00, - 0x0000fc00, 0x00005600, 0x00003e00, 0x00004b00, - 0x0000c600, 0x0000d200, 0x00007900, 0x00002000, - 0x00009a00, 0x0000db00, 0x0000c000, 0x0000fe00, - 0x00007800, 0x0000cd00, 0x00005a00, 0x0000f400, - 0x00001f00, 0x0000dd00, 0x0000a800, 0x00003300, - 0x00008800, 0x00000700, 0x0000c700, 0x00003100, - 0x0000b100, 0x00001200, 0x00001000, 0x00005900, - 0x00002700, 0x00008000, 0x0000ec00, 0x00005f00, - 0x00006000, 0x00005100, 0x00007f00, 0x0000a900, - 0x00001900, 0x0000b500, 0x00004a00, 0x00000d00, - 0x00002d00, 0x0000e500, 0x00007a00, 0x00009f00, - 0x00009300, 0x0000c900, 0x00009c00, 0x0000ef00, - 0x0000a000, 0x0000e000, 0x00003b00, 0x00004d00, - 0x0000ae00, 0x00002a00, 0x0000f500, 0x0000b000, - 0x0000c800, 0x0000eb00, 0x0000bb00, 0x00003c00, - 0x00008300, 0x00005300, 0x00009900, 0x00006100, - 0x00001700, 0x00002b00, 0x00000400, 0x00007e00, - 0x0000ba00, 0x00007700, 0x0000d600, 0x00002600, - 0x0000e100, 0x00006900, 0x00001400, 0x00006300, - 0x00005500, 0x00002100, 0x00000c00, 0x00007d00 -}, { - 0x00520000, 0x00090000, 0x006a0000, 0x00d50000, - 0x00300000, 0x00360000, 0x00a50000, 0x00380000, - 0x00bf0000, 0x00400000, 0x00a30000, 0x009e0000, - 0x00810000, 0x00f30000, 0x00d70000, 0x00fb0000, - 0x007c0000, 0x00e30000, 0x00390000, 0x00820000, - 0x009b0000, 0x002f0000, 0x00ff0000, 0x00870000, - 0x00340000, 0x008e0000, 0x00430000, 0x00440000, - 0x00c40000, 0x00de0000, 0x00e90000, 0x00cb0000, - 0x00540000, 0x007b0000, 0x00940000, 0x00320000, - 0x00a60000, 0x00c20000, 0x00230000, 0x003d0000, - 0x00ee0000, 0x004c0000, 0x00950000, 0x000b0000, - 0x00420000, 0x00fa0000, 0x00c30000, 0x004e0000, - 0x00080000, 0x002e0000, 0x00a10000, 0x00660000, - 0x00280000, 0x00d90000, 0x00240000, 0x00b20000, - 0x00760000, 0x005b0000, 0x00a20000, 0x00490000, - 0x006d0000, 0x008b0000, 0x00d10000, 0x00250000, - 0x00720000, 0x00f80000, 0x00f60000, 0x00640000, - 0x00860000, 0x00680000, 0x00980000, 0x00160000, - 0x00d40000, 0x00a40000, 0x005c0000, 0x00cc0000, - 0x005d0000, 0x00650000, 0x00b60000, 0x00920000, - 0x006c0000, 0x00700000, 0x00480000, 0x00500000, - 0x00fd0000, 0x00ed0000, 0x00b90000, 0x00da0000, - 0x005e0000, 0x00150000, 0x00460000, 0x00570000, - 0x00a70000, 0x008d0000, 0x009d0000, 0x00840000, - 0x00900000, 0x00d80000, 0x00ab0000, 0x00000000, - 0x008c0000, 0x00bc0000, 0x00d30000, 0x000a0000, - 0x00f70000, 0x00e40000, 0x00580000, 0x00050000, - 0x00b80000, 0x00b30000, 0x00450000, 0x00060000, - 0x00d00000, 0x002c0000, 0x001e0000, 0x008f0000, - 0x00ca0000, 0x003f0000, 0x000f0000, 0x00020000, - 0x00c10000, 0x00af0000, 0x00bd0000, 0x00030000, - 0x00010000, 0x00130000, 0x008a0000, 0x006b0000, - 0x003a0000, 0x00910000, 0x00110000, 0x00410000, - 0x004f0000, 0x00670000, 0x00dc0000, 0x00ea0000, - 0x00970000, 0x00f20000, 0x00cf0000, 0x00ce0000, - 0x00f00000, 0x00b40000, 0x00e60000, 0x00730000, - 0x00960000, 0x00ac0000, 0x00740000, 0x00220000, - 0x00e70000, 0x00ad0000, 0x00350000, 0x00850000, - 0x00e20000, 0x00f90000, 0x00370000, 0x00e80000, - 0x001c0000, 0x00750000, 0x00df0000, 0x006e0000, - 0x00470000, 0x00f10000, 0x001a0000, 0x00710000, - 0x001d0000, 0x00290000, 0x00c50000, 0x00890000, - 0x006f0000, 0x00b70000, 0x00620000, 0x000e0000, - 0x00aa0000, 0x00180000, 0x00be0000, 0x001b0000, - 0x00fc0000, 0x00560000, 0x003e0000, 0x004b0000, - 0x00c60000, 0x00d20000, 0x00790000, 0x00200000, - 0x009a0000, 0x00db0000, 0x00c00000, 0x00fe0000, - 0x00780000, 0x00cd0000, 0x005a0000, 0x00f40000, - 0x001f0000, 0x00dd0000, 0x00a80000, 0x00330000, - 0x00880000, 0x00070000, 0x00c70000, 0x00310000, - 0x00b10000, 0x00120000, 0x00100000, 0x00590000, - 0x00270000, 0x00800000, 0x00ec0000, 0x005f0000, - 0x00600000, 0x00510000, 0x007f0000, 0x00a90000, - 0x00190000, 0x00b50000, 0x004a0000, 0x000d0000, - 0x002d0000, 0x00e50000, 0x007a0000, 0x009f0000, - 0x00930000, 0x00c90000, 0x009c0000, 0x00ef0000, - 0x00a00000, 0x00e00000, 0x003b0000, 0x004d0000, - 0x00ae0000, 0x002a0000, 0x00f50000, 0x00b00000, - 0x00c80000, 0x00eb0000, 0x00bb0000, 0x003c0000, - 0x00830000, 0x00530000, 0x00990000, 0x00610000, - 0x00170000, 0x002b0000, 0x00040000, 0x007e0000, - 0x00ba0000, 0x00770000, 0x00d60000, 0x00260000, - 0x00e10000, 0x00690000, 0x00140000, 0x00630000, - 0x00550000, 0x00210000, 0x000c0000, 0x007d0000 -}, { - 0x52000000, 0x09000000, 0x6a000000, 0xd5000000, - 0x30000000, 0x36000000, 0xa5000000, 0x38000000, - 0xbf000000, 0x40000000, 0xa3000000, 0x9e000000, - 0x81000000, 0xf3000000, 0xd7000000, 0xfb000000, - 0x7c000000, 0xe3000000, 0x39000000, 0x82000000, - 0x9b000000, 0x2f000000, 0xff000000, 0x87000000, - 0x34000000, 0x8e000000, 0x43000000, 0x44000000, - 0xc4000000, 0xde000000, 0xe9000000, 0xcb000000, - 0x54000000, 0x7b000000, 0x94000000, 0x32000000, - 0xa6000000, 0xc2000000, 0x23000000, 0x3d000000, - 0xee000000, 0x4c000000, 0x95000000, 0x0b000000, - 0x42000000, 0xfa000000, 0xc3000000, 0x4e000000, - 0x08000000, 0x2e000000, 0xa1000000, 0x66000000, - 0x28000000, 0xd9000000, 0x24000000, 0xb2000000, - 0x76000000, 0x5b000000, 0xa2000000, 0x49000000, - 0x6d000000, 0x8b000000, 0xd1000000, 0x25000000, - 0x72000000, 0xf8000000, 0xf6000000, 0x64000000, - 0x86000000, 0x68000000, 0x98000000, 0x16000000, - 0xd4000000, 0xa4000000, 0x5c000000, 0xcc000000, - 0x5d000000, 0x65000000, 0xb6000000, 0x92000000, - 0x6c000000, 0x70000000, 0x48000000, 0x50000000, - 0xfd000000, 0xed000000, 0xb9000000, 0xda000000, - 0x5e000000, 0x15000000, 0x46000000, 0x57000000, - 0xa7000000, 0x8d000000, 0x9d000000, 0x84000000, - 0x90000000, 0xd8000000, 0xab000000, 0x00000000, - 0x8c000000, 0xbc000000, 0xd3000000, 0x0a000000, - 0xf7000000, 0xe4000000, 0x58000000, 0x05000000, - 0xb8000000, 0xb3000000, 0x45000000, 0x06000000, - 0xd0000000, 0x2c000000, 0x1e000000, 0x8f000000, - 0xca000000, 0x3f000000, 0x0f000000, 0x02000000, - 0xc1000000, 0xaf000000, 0xbd000000, 0x03000000, - 0x01000000, 0x13000000, 0x8a000000, 0x6b000000, - 0x3a000000, 0x91000000, 0x11000000, 0x41000000, - 0x4f000000, 0x67000000, 0xdc000000, 0xea000000, - 0x97000000, 0xf2000000, 0xcf000000, 0xce000000, - 0xf0000000, 0xb4000000, 0xe6000000, 0x73000000, - 0x96000000, 0xac000000, 0x74000000, 0x22000000, - 0xe7000000, 0xad000000, 0x35000000, 0x85000000, - 0xe2000000, 0xf9000000, 0x37000000, 0xe8000000, - 0x1c000000, 0x75000000, 0xdf000000, 0x6e000000, - 0x47000000, 0xf1000000, 0x1a000000, 0x71000000, - 0x1d000000, 0x29000000, 0xc5000000, 0x89000000, - 0x6f000000, 0xb7000000, 0x62000000, 0x0e000000, - 0xaa000000, 0x18000000, 0xbe000000, 0x1b000000, - 0xfc000000, 0x56000000, 0x3e000000, 0x4b000000, - 0xc6000000, 0xd2000000, 0x79000000, 0x20000000, - 0x9a000000, 0xdb000000, 0xc0000000, 0xfe000000, - 0x78000000, 0xcd000000, 0x5a000000, 0xf4000000, - 0x1f000000, 0xdd000000, 0xa8000000, 0x33000000, - 0x88000000, 0x07000000, 0xc7000000, 0x31000000, - 0xb1000000, 0x12000000, 0x10000000, 0x59000000, - 0x27000000, 0x80000000, 0xec000000, 0x5f000000, - 0x60000000, 0x51000000, 0x7f000000, 0xa9000000, - 0x19000000, 0xb5000000, 0x4a000000, 0x0d000000, - 0x2d000000, 0xe5000000, 0x7a000000, 0x9f000000, - 0x93000000, 0xc9000000, 0x9c000000, 0xef000000, - 0xa0000000, 0xe0000000, 0x3b000000, 0x4d000000, - 0xae000000, 0x2a000000, 0xf5000000, 0xb0000000, - 0xc8000000, 0xeb000000, 0xbb000000, 0x3c000000, - 0x83000000, 0x53000000, 0x99000000, 0x61000000, - 0x17000000, 0x2b000000, 0x04000000, 0x7e000000, - 0xba000000, 0x77000000, 0xd6000000, 0x26000000, - 0xe1000000, 0x69000000, 0x14000000, 0x63000000, - 0x55000000, 0x21000000, 0x0c000000, 0x7d000000 -} -}; - -static const u4byte rco_tab[10] = { - 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, - 0x00000020, 0x00000040, 0x00000080, 0x0000001b, 0x00000036 -}; - diff --git a/contrib/pgcrypto/sha1.c b/contrib/pgcrypto/sha1.c deleted file mode 100644 index 4f9a1b3984..0000000000 --- a/contrib/pgcrypto/sha1.c +++ /dev/null @@ -1,350 +0,0 @@ -/* $Id: sha1.c,v 1.11 2001/11/29 19:40:37 momjian Exp $ */ -/* $KAME: sha1.c,v 1.3 2000/02/22 14:01:18 itojun Exp $ */ - -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * FIPS pub 180-1: Secure Hash Algorithm (SHA-1) - * based on: http://csrc.nist.gov/fips/fip180-1.txt - * implemented by Jun-ichiro itojun Itoh - */ - -#include "postgres.h" -#include "px.h" - -#include "sha1.h" - -/* sanity check */ -#if BYTE_ORDER != BIG_ENDIAN -#if BYTE_ORDER != LITTLE_ENDIAN -#define unsupported 1 -#endif -#endif - -#ifndef unsupported - -/* constant table */ -static uint32 _K[] = {0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6}; - -#define K(t) _K[(t) / 20] - -#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d))) -#define F1(b, c, d) (((b) ^ (c)) ^ (d)) -#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) -#define F3(b, c, d) (((b) ^ (c)) ^ (d)) - -#define S(n, x) (((x) << (n)) | ((x) >> (32 - n))) - -#define H(n) (ctxt->h.b32[(n)]) -#define COUNT (ctxt->count) -#define BCOUNT (ctxt->c.b64[0] / 8) -#define W(n) (ctxt->m.b32[(n)]) - -#define PUTBYTE(x) \ -do { \ - ctxt->m.b8[(COUNT % 64)] = (x); \ - COUNT++; \ - COUNT %= 64; \ - ctxt->c.b64[0] += 8; \ - if (COUNT % 64 == 0) \ - sha1_step(ctxt); \ -} while (0) - -#define PUTPAD(x) \ -do { \ - ctxt->m.b8[(COUNT % 64)] = (x); \ - COUNT++; \ - COUNT %= 64; \ - if (COUNT % 64 == 0) \ - sha1_step(ctxt); \ -} while (0) - -static void sha1_step(struct sha1_ctxt *); - -static void -sha1_step(struct sha1_ctxt * ctxt) -{ - uint32 a, - b, - c, - d, - e; - size_t t, - s; - uint32 tmp; - -#if BYTE_ORDER == LITTLE_ENDIAN - struct sha1_ctxt tctxt; - - bcopy(&ctxt->m.b8[0], &tctxt.m.b8[0], 64); - ctxt->m.b8[0] = tctxt.m.b8[3]; - ctxt->m.b8[1] = tctxt.m.b8[2]; - ctxt->m.b8[2] = tctxt.m.b8[1]; - ctxt->m.b8[3] = tctxt.m.b8[0]; - ctxt->m.b8[4] = tctxt.m.b8[7]; - ctxt->m.b8[5] = tctxt.m.b8[6]; - ctxt->m.b8[6] = tctxt.m.b8[5]; - ctxt->m.b8[7] = tctxt.m.b8[4]; - ctxt->m.b8[8] = tctxt.m.b8[11]; - ctxt->m.b8[9] = tctxt.m.b8[10]; - ctxt->m.b8[10] = tctxt.m.b8[9]; - ctxt->m.b8[11] = tctxt.m.b8[8]; - ctxt->m.b8[12] = tctxt.m.b8[15]; - ctxt->m.b8[13] = tctxt.m.b8[14]; - ctxt->m.b8[14] = tctxt.m.b8[13]; - ctxt->m.b8[15] = tctxt.m.b8[12]; - ctxt->m.b8[16] = tctxt.m.b8[19]; - ctxt->m.b8[17] = tctxt.m.b8[18]; - ctxt->m.b8[18] = tctxt.m.b8[17]; - ctxt->m.b8[19] = tctxt.m.b8[16]; - ctxt->m.b8[20] = tctxt.m.b8[23]; - ctxt->m.b8[21] = tctxt.m.b8[22]; - ctxt->m.b8[22] = tctxt.m.b8[21]; - ctxt->m.b8[23] = tctxt.m.b8[20]; - ctxt->m.b8[24] = tctxt.m.b8[27]; - ctxt->m.b8[25] = tctxt.m.b8[26]; - ctxt->m.b8[26] = tctxt.m.b8[25]; - ctxt->m.b8[27] = tctxt.m.b8[24]; - ctxt->m.b8[28] = tctxt.m.b8[31]; - ctxt->m.b8[29] = tctxt.m.b8[30]; - ctxt->m.b8[30] = tctxt.m.b8[29]; - ctxt->m.b8[31] = tctxt.m.b8[28]; - ctxt->m.b8[32] = tctxt.m.b8[35]; - ctxt->m.b8[33] = tctxt.m.b8[34]; - ctxt->m.b8[34] = tctxt.m.b8[33]; - ctxt->m.b8[35] = tctxt.m.b8[32]; - ctxt->m.b8[36] = tctxt.m.b8[39]; - ctxt->m.b8[37] = tctxt.m.b8[38]; - ctxt->m.b8[38] = tctxt.m.b8[37]; - ctxt->m.b8[39] = tctxt.m.b8[36]; - ctxt->m.b8[40] = tctxt.m.b8[43]; - ctxt->m.b8[41] = tctxt.m.b8[42]; - ctxt->m.b8[42] = tctxt.m.b8[41]; - ctxt->m.b8[43] = tctxt.m.b8[40]; - ctxt->m.b8[44] = tctxt.m.b8[47]; - ctxt->m.b8[45] = tctxt.m.b8[46]; - ctxt->m.b8[46] = tctxt.m.b8[45]; - ctxt->m.b8[47] = tctxt.m.b8[44]; - ctxt->m.b8[48] = tctxt.m.b8[51]; - ctxt->m.b8[49] = tctxt.m.b8[50]; - ctxt->m.b8[50] = tctxt.m.b8[49]; - ctxt->m.b8[51] = tctxt.m.b8[48]; - ctxt->m.b8[52] = tctxt.m.b8[55]; - ctxt->m.b8[53] = tctxt.m.b8[54]; - ctxt->m.b8[54] = tctxt.m.b8[53]; - ctxt->m.b8[55] = tctxt.m.b8[52]; - ctxt->m.b8[56] = tctxt.m.b8[59]; - ctxt->m.b8[57] = tctxt.m.b8[58]; - ctxt->m.b8[58] = tctxt.m.b8[57]; - ctxt->m.b8[59] = tctxt.m.b8[56]; - ctxt->m.b8[60] = tctxt.m.b8[63]; - ctxt->m.b8[61] = tctxt.m.b8[62]; - ctxt->m.b8[62] = tctxt.m.b8[61]; - ctxt->m.b8[63] = tctxt.m.b8[60]; -#endif - - a = H(0); - b = H(1); - c = H(2); - d = H(3); - e = H(4); - - for (t = 0; t < 20; t++) - { - s = t & 0x0f; - if (t >= 16) - W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t); - e = d; - d = c; - c = S(30, b); - b = a; - a = tmp; - } - for (t = 20; t < 40; t++) - { - s = t & 0x0f; - W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t); - e = d; - d = c; - c = S(30, b); - b = a; - a = tmp; - } - for (t = 40; t < 60; t++) - { - s = t & 0x0f; - W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t); - e = d; - d = c; - c = S(30, b); - b = a; - a = tmp; - } - for (t = 60; t < 80; t++) - { - s = t & 0x0f; - W(s) = S(1, W((s + 13) & 0x0f) ^ W((s + 8) & 0x0f) ^ W((s + 2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t); - e = d; - d = c; - c = S(30, b); - b = a; - a = tmp; - } - - H(0) = H(0) + a; - H(1) = H(1) + b; - H(2) = H(2) + c; - H(3) = H(3) + d; - H(4) = H(4) + e; - - bzero(&ctxt->m.b8[0], 64); -} - -/*------------------------------------------------------------*/ - -void -sha1_init(struct sha1_ctxt * ctxt) -{ - bzero(ctxt, sizeof(struct sha1_ctxt)); - H(0) = 0x67452301; - H(1) = 0xefcdab89; - H(2) = 0x98badcfe; - H(3) = 0x10325476; - H(4) = 0xc3d2e1f0; -} - -void -sha1_pad(struct sha1_ctxt * ctxt) -{ - size_t padlen; /* pad length in bytes */ - size_t padstart; - - PUTPAD(0x80); - - padstart = COUNT % 64; - padlen = 64 - padstart; - if (padlen < 8) - { - bzero(&ctxt->m.b8[padstart], padlen); - COUNT += padlen; - COUNT %= 64; - sha1_step(ctxt); - padstart = COUNT % 64; /* should be 0 */ - padlen = 64 - padstart; /* should be 64 */ - } - bzero(&ctxt->m.b8[padstart], padlen - 8); - COUNT += (padlen - 8); - COUNT %= 64; -#if BYTE_ORDER == BIG_ENDIAN - PUTPAD(ctxt->c.b8[0]); - PUTPAD(ctxt->c.b8[1]); - PUTPAD(ctxt->c.b8[2]); - PUTPAD(ctxt->c.b8[3]); - PUTPAD(ctxt->c.b8[4]); - PUTPAD(ctxt->c.b8[5]); - PUTPAD(ctxt->c.b8[6]); - PUTPAD(ctxt->c.b8[7]); -#else - PUTPAD(ctxt->c.b8[7]); - PUTPAD(ctxt->c.b8[6]); - PUTPAD(ctxt->c.b8[5]); - PUTPAD(ctxt->c.b8[4]); - PUTPAD(ctxt->c.b8[3]); - PUTPAD(ctxt->c.b8[2]); - PUTPAD(ctxt->c.b8[1]); - PUTPAD(ctxt->c.b8[0]); -#endif -} - -void -sha1_loop(struct sha1_ctxt * ctxt, const uint8 *input0, size_t len) -{ - const uint8 *input; - size_t gaplen; - size_t gapstart; - size_t off; - size_t copysiz; - - input = (const uint8 *) input0; - off = 0; - - while (off < len) - { - gapstart = COUNT % 64; - gaplen = 64 - gapstart; - - copysiz = (gaplen < len - off) ? gaplen : len - off; - bcopy(&input[off], &ctxt->m.b8[gapstart], copysiz); - COUNT += copysiz; - COUNT %= 64; - ctxt->c.b64[0] += copysiz * 8; - if (COUNT % 64 == 0) - sha1_step(ctxt); - off += copysiz; - } -} - -void -sha1_result(struct sha1_ctxt * ctxt, uint8 *digest0) -{ - uint8 *digest; - - digest = (uint8 *) digest0; - sha1_pad(ctxt); -#if BYTE_ORDER == BIG_ENDIAN - bcopy(&ctxt->h.b8[0], digest, 20); -#else - digest[0] = ctxt->h.b8[3]; - digest[1] = ctxt->h.b8[2]; - digest[2] = ctxt->h.b8[1]; - digest[3] = ctxt->h.b8[0]; - digest[4] = ctxt->h.b8[7]; - digest[5] = ctxt->h.b8[6]; - digest[6] = ctxt->h.b8[5]; - digest[7] = ctxt->h.b8[4]; - digest[8] = ctxt->h.b8[11]; - digest[9] = ctxt->h.b8[10]; - digest[10] = ctxt->h.b8[9]; - digest[11] = ctxt->h.b8[8]; - digest[12] = ctxt->h.b8[15]; - digest[13] = ctxt->h.b8[14]; - digest[14] = ctxt->h.b8[13]; - digest[15] = ctxt->h.b8[12]; - digest[16] = ctxt->h.b8[19]; - digest[17] = ctxt->h.b8[18]; - digest[18] = ctxt->h.b8[17]; - digest[19] = ctxt->h.b8[16]; -#endif -} - -#endif /* unsupported */ diff --git a/contrib/pgcrypto/sha1.h b/contrib/pgcrypto/sha1.h deleted file mode 100644 index 096a9a40ad..0000000000 --- a/contrib/pgcrypto/sha1.h +++ /dev/null @@ -1,75 +0,0 @@ -/* $Id: sha1.h,v 1.8 2001/11/05 17:46:23 momjian Exp $ */ -/* $KAME: sha1.h,v 1.4 2000/02/22 14:01:18 itojun Exp $ */ - -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ -/* - * FIPS pub 180-1: Secure Hash Algorithm (SHA-1) - * based on: http://csrc.nist.gov/fips/fip180-1.txt - * implemented by Jun-ichiro itojun Itoh - */ - -#ifndef _NETINET6_SHA1_H_ -#define _NETINET6_SHA1_H_ - -struct sha1_ctxt -{ - union - { - uint8 b8[20]; - uint32 b32[5]; - } h; - union - { - uint8 b8[8]; - uint64 b64[1]; - } c; - union - { - uint8 b8[64]; - uint32 b32[16]; - } m; - uint8 count; -}; - -extern void sha1_init(struct sha1_ctxt *); -extern void sha1_pad(struct sha1_ctxt *); -extern void sha1_loop(struct sha1_ctxt *, const uint8 *, size_t); -extern void sha1_result(struct sha1_ctxt *, uint8 *); - -/* compatibilty with other SHA1 source codes */ -typedef struct sha1_ctxt SHA1_CTX; - -#define SHA1Init(x) sha1_init((x)) -#define SHA1Update(x, y, z) sha1_loop((x), (y), (z)) -#define SHA1Final(x, y) sha1_result((y), (x)) - -#define SHA1_RESULTLEN (160/8) - -#endif /* _NETINET6_SHA1_H_ */ diff --git a/contrib/pgcrypto/sql/blowfish.sql b/contrib/pgcrypto/sql/blowfish.sql deleted file mode 100644 index e1fa7b1f49..0000000000 --- a/contrib/pgcrypto/sql/blowfish.sql +++ /dev/null @@ -1,66 +0,0 @@ --- --- Blowfish cipher --- - --- some standard Blowfish testvalues -select encode(encrypt( -decode('0000000000000000', 'hex'), -decode('0000000000000000', 'hex'), -'bf-ecb/pad:none'), 'hex'); - -select encode(encrypt( -decode('ffffffffffffffff', 'hex'), -decode('ffffffffffffffff', 'hex'), -'bf-ecb/pad:none'), 'hex'); - -select encode(encrypt( -decode('1000000000000001', 'hex'), -decode('3000000000000000', 'hex'), -'bf-ecb/pad:none'), 'hex'); - -select encode(encrypt( -decode('1111111111111111', 'hex'), -decode('1111111111111111', 'hex'), -'bf-ecb/pad:none'), 'hex'); - -select encode(encrypt( -decode('0123456789abcdef', 'hex'), -decode('fedcba9876543210', 'hex'), -'bf-ecb/pad:none'), 'hex'); - -select encode(encrypt( -decode('01a1d6d039776742', 'hex'), -decode('fedcba9876543210', 'hex'), -'bf-ecb/pad:none'), 'hex'); - -select encode(encrypt( -decode('ffffffffffffffff', 'hex'), -decode('0000000000000000', 'hex'), -'bf-ecb/pad:none'), 'hex'); - --- setkey -select encode(encrypt( -decode('fedcba9876543210', 'hex'), -decode('f0e1d2c3b4a5968778695a4b3c2d1e0f', 'hex'), -'bf-ecb/pad:none'), 'hex'); - --- with padding -select encode(encrypt( -decode('01234567890123456789', 'hex'), -decode('33443344334433443344334433443344', 'hex'), -'bf-ecb'), 'hex'); - --- cbc - --- 28 bytes key -select encode(encrypt( -decode('6b77b4d63006dee605b156e27403979358deb9e7154616d959f1652bd5', 'hex'), -decode('37363534333231204e6f77206973207468652074696d6520666f7220', 'hex'), -'bf-cbc'), 'hex'); - --- 29 bytes key -select encode(encrypt( -decode('6b77b4d63006dee605b156e27403979358deb9e7154616d959f1652bd5ff92cc', 'hex'), -decode('37363534333231204e6f77206973207468652074696d6520666f722000', 'hex'), -'bf-cbc'), 'hex'); - diff --git a/contrib/pgcrypto/sql/crypt-blowfish.sql b/contrib/pgcrypto/sql/crypt-blowfish.sql deleted file mode 100644 index 6b82fdff63..0000000000 --- a/contrib/pgcrypto/sql/crypt-blowfish.sql +++ /dev/null @@ -1,17 +0,0 @@ --- --- crypt() and gen_salt(): bcrypt --- - -select crypt('', '$2a$06$RQiOJ.3ELirrXwxIZY8q0O'); - -select crypt('foox', '$2a$06$RQiOJ.3ELirrXwxIZY8q0O'); - -create table ctest (data text, res text, salt text); -insert into ctest values ('password', '', ''); - -update ctest set salt = gen_salt('bf', 8); -update ctest set res = crypt(data, salt); -select res = crypt(data, res) as "worked" from ctest; - -drop table ctest; - diff --git a/contrib/pgcrypto/sql/crypt-des.sql b/contrib/pgcrypto/sql/crypt-des.sql deleted file mode 100644 index 2a2fbfb36c..0000000000 --- a/contrib/pgcrypto/sql/crypt-des.sql +++ /dev/null @@ -1,17 +0,0 @@ --- --- crypt() and gen_salt(): crypt-des --- - -select crypt('', 'NB'); - -select crypt('foox', 'NB'); - -create table ctest (data text, res text, salt text); -insert into ctest values ('password', '', ''); - -update ctest set salt = gen_salt('des'); -update ctest set res = crypt(data, salt); -select res = crypt(data, res) as "worked" from ctest; - -drop table ctest; - diff --git a/contrib/pgcrypto/sql/crypt-md5.sql b/contrib/pgcrypto/sql/crypt-md5.sql deleted file mode 100644 index 8ef8dbae0f..0000000000 --- a/contrib/pgcrypto/sql/crypt-md5.sql +++ /dev/null @@ -1,17 +0,0 @@ --- --- crypt() and gen_salt(): md5 --- - -select crypt('', '$1$Szzz0yzz'); - -select crypt('foox', '$1$Szzz0yzz'); - -create table ctest (data text, res text, salt text); -insert into ctest values ('password', '', ''); - -update ctest set salt = gen_salt('md5'); -update ctest set res = crypt(data, salt); -select res = crypt(data, res) as "worked" from ctest; - -drop table ctest; - diff --git a/contrib/pgcrypto/sql/crypt-xdes.sql b/contrib/pgcrypto/sql/crypt-xdes.sql deleted file mode 100644 index 6fd85b929a..0000000000 --- a/contrib/pgcrypto/sql/crypt-xdes.sql +++ /dev/null @@ -1,17 +0,0 @@ --- --- crypt() and gen_salt(): extended des --- - -select crypt('', '_J9..j2zz'); - -select crypt('foox', '_J9..j2zz'); - -create table ctest (data text, res text, salt text); -insert into ctest values ('password', '', ''); - -update ctest set salt = gen_salt('xdes', 1001); -update ctest set res = crypt(data, salt); -select res = crypt(data, res) as "worked" from ctest; - -drop table ctest; - diff --git a/contrib/pgcrypto/sql/hmac-md5.sql b/contrib/pgcrypto/sql/hmac-md5.sql deleted file mode 100644 index d3cd1f649d..0000000000 --- a/contrib/pgcrypto/sql/hmac-md5.sql +++ /dev/null @@ -1,46 +0,0 @@ --- --- HMAC-MD5 --- - -select encode(hmac( -'Hi There', -decode('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'), -'md5'), 'hex'); - --- 2 -select encode(hmac( -'Jefe', -'what do ya want for nothing?', -'md5'), 'hex'); - --- 3 -select encode(hmac( -decode('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', 'hex'), -decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), -'md5'), 'hex'); - --- 4 -select encode(hmac( -decode('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd', 'hex'), -decode('0102030405060708090a0b0c0d0e0f10111213141516171819', 'hex'), -'md5'), 'hex'); - --- 5 -select encode(hmac( -'Test With Truncation', -decode('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'), -'md5'), 'hex'); - --- 6 -select encode(hmac( -'Test Using Larger Than Block-Size Key - Hash Key First', -decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), -'md5'), 'hex'); - --- 7 -select encode(hmac( -'Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data', -decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), -'md5'), 'hex'); - - diff --git a/contrib/pgcrypto/sql/hmac-sha1.sql b/contrib/pgcrypto/sql/hmac-sha1.sql deleted file mode 100644 index f08c438963..0000000000 --- a/contrib/pgcrypto/sql/hmac-sha1.sql +++ /dev/null @@ -1,46 +0,0 @@ --- --- HMAC-MD5 --- - -select encode(hmac( -'Hi There', -decode('0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b', 'hex'), -'sha1'), 'hex'); - --- 2 -select encode(hmac( -'Jefe', -'what do ya want for nothing?', -'sha1'), 'hex'); - --- 3 -select encode(hmac( -decode('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', 'hex'), -decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), -'sha1'), 'hex'); - --- 4 -select encode(hmac( -decode('cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd', 'hex'), -decode('0102030405060708090a0b0c0d0e0f10111213141516171819', 'hex'), -'sha1'), 'hex'); - --- 5 -select encode(hmac( -'Test With Truncation', -decode('0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c', 'hex'), -'sha1'), 'hex'); - --- 6 -select encode(hmac( -'Test Using Larger Than Block-Size Key - Hash Key First', -decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), -'sha1'), 'hex'); - --- 7 -select encode(hmac( -'Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data', -decode('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', 'hex'), -'sha1'), 'hex'); - - diff --git a/contrib/pgcrypto/sql/init.sql b/contrib/pgcrypto/sql/init.sql deleted file mode 100644 index 8bddb73773..0000000000 --- a/contrib/pgcrypto/sql/init.sql +++ /dev/null @@ -1,12 +0,0 @@ --- --- init pgcrypto --- - -\set ECHO none -\i pgcrypto.sql -\set ECHO all - --- check for encoding fn's -select encode('foo', 'hex'); -select decode('666f6f', 'hex'); - diff --git a/contrib/pgcrypto/sql/md5.sql b/contrib/pgcrypto/sql/md5.sql deleted file mode 100644 index 78e4cfee0f..0000000000 --- a/contrib/pgcrypto/sql/md5.sql +++ /dev/null @@ -1,12 +0,0 @@ --- --- MD5 message digest --- - -select encode(digest('', 'md5'), 'hex'); -select encode(digest('a', 'md5'), 'hex'); -select encode(digest('abc', 'md5'), 'hex'); -select encode(digest('message digest', 'md5'), 'hex'); -select encode(digest('abcdefghijklmnopqrstuvwxyz', 'md5'), 'hex'); -select encode(digest('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 'md5'), 'hex'); -select encode(digest('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 'md5'), 'hex'); - diff --git a/contrib/pgcrypto/sql/rijndael.sql b/contrib/pgcrypto/sql/rijndael.sql deleted file mode 100644 index fbacdc6dfc..0000000000 --- a/contrib/pgcrypto/sql/rijndael.sql +++ /dev/null @@ -1,43 +0,0 @@ --- --- AES / Rijndael-128 cipher --- - --- some standard Rijndael testvalues -select encode(encrypt( -decode('00112233445566778899aabbccddeeff', 'hex'), -decode('000102030405060708090a0b0c0d0e0f', 'hex'), -'aes-ecb/pad:none'), 'hex'); - -select encode(encrypt( -decode('00112233445566778899aabbccddeeff', 'hex'), -decode('000102030405060708090a0b0c0d0e0f1011121314151617', 'hex'), -'aes-ecb/pad:none'), 'hex'); - -select encode(encrypt( -decode('00112233445566778899aabbccddeeff', 'hex'), -decode('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', 'hex'), -'aes-ecb/pad:none'), 'hex'); - --- cbc -select encode(encrypt( -decode('00112233445566778899aabbccddeeff', 'hex'), -decode('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', 'hex'), -'aes-cbc/pad:none'), 'hex'); - --- key padding - -select encode(encrypt( -decode('0011223344', 'hex'), -decode('000102030405', 'hex'), -'aes-cbc'), 'hex'); - -select encode(encrypt( -decode('0011223344', 'hex'), -decode('000102030405060708090a0b0c0d0e0f10111213', 'hex'), -'aes-cbc'), 'hex'); - -select encode(encrypt( -decode('0011223344', 'hex'), -decode('000102030405060708090a0b0c0d0e0f101112131415161718191a1b', 'hex'), -'aes-cbc'), 'hex'); - diff --git a/contrib/pgcrypto/sql/sha1.sql b/contrib/pgcrypto/sql/sha1.sql deleted file mode 100644 index 11ee5426cb..0000000000 --- a/contrib/pgcrypto/sql/sha1.sql +++ /dev/null @@ -1,12 +0,0 @@ --- --- SHA1 message digest --- - -select encode(digest('', 'sha1'), 'hex'); -select encode(digest('a', 'sha1'), 'hex'); -select encode(digest('abc', 'sha1'), 'hex'); -select encode(digest('message digest', 'sha1'), 'hex'); -select encode(digest('abcdefghijklmnopqrstuvwxyz', 'sha1'), 'hex'); -select encode(digest('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 'sha1'), 'hex'); -select encode(digest('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 'sha1'), 'hex'); - diff --git a/contrib/pgstattuple/Makefile b/contrib/pgstattuple/Makefile deleted file mode 100644 index 88f1b658d4..0000000000 --- a/contrib/pgstattuple/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -#------------------------------------------------------------------------- -# -# pgstattuple Makefile -# -# $Id: Makefile,v 1.1 2001/10/01 01:52:38 ishii Exp $ -# -#------------------------------------------------------------------------- - -subdir = contrib/pgstattuple -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -MODULE_big := pgstattuple -SRCS += pgstattuple.c -OBJS := $(SRCS:.c=.o) -DOCS := README.pgstattuple README.pgstattuple.euc_jp -DATA_built := pgstattuple.sql - -PG_CPPFLAGS := -SHLIB_LINK := - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/pgstattuple/README.pgstattuple b/contrib/pgstattuple/README.pgstattuple deleted file mode 100644 index 7237b9a4dc..0000000000 --- a/contrib/pgstattuple/README.pgstattuple +++ /dev/null @@ -1,47 +0,0 @@ -pgstattuple README 2001/10/01 Tatsuo Ishii - -1. What is pgstattuple? - - pgstattuple returns the percentage of the "dead" tuples of a - table. This will help users to judge if vacuum is needed. - - In addition, pgstattuple prints more detailed information using - NOTICE. - -test=# select pgstattuple('tellers'); -NOTICE: physical length: 0.08MB live tuples: 20 (0.00MB, 1.17%) dead tuples: 320 (0.01MB, 18.75%) free/reusable space: 0.01MB (18.06%) overhead: 62.02% - pgstattuple -------------- - 18.75 -(1 row) - - Above example shows tellers table includes 18.75% dead tuples. - - physical length physical size of the table in MB - live tuples information on the live tuples - dead tuples information on the dead tuples - free/reusable space available space - overhead overhead space - -2. Installing pgstattuple - - $ make - $ make install - $ psql -e -f /usr/local/pgsql/share/contrib/pgstattuple.sql test - -3. Using pgstattuple - - pgstattuple can be called as a function: - - pgstattuple(TEXT) RETURNS FLOAT8 - - The argument is the table name. pgstattuple returns the percentage - of the "dead" tuples of a table. - -4. Notes - - pgstattuple acquires only a read lock on the table. So concurrent - update may affect the result. - - pgstattuple judges a tuple is "dead" if HeapTupleSatisfiesNow() - returns false. diff --git a/contrib/pgstattuple/README.pgstattuple.euc_jp b/contrib/pgstattuple/README.pgstattuple.euc_jp deleted file mode 100644 index 5142e9b6a9..0000000000 --- a/contrib/pgstattuple/README.pgstattuple.euc_jp +++ /dev/null @@ -1,81 +0,0 @@ -$Id: README.pgstattuple.euc_jp,v 1.2 2001/12/20 01:56:08 ishii Exp $ - -pgstattuple README 2001/10/01 ÀаæÃ£É× - -1. pgstattuple¤È¤Ï - - pgstattuple¤Ï¡¤UPDATE¤äDELETE¤Çºî¤é¤ì¤¿¥Æ¡¼¥Ö¥ë¤Î¥´¥ßÎΰè¤ÎÂ礭¤µ¤ò¡¤ - ¥Æ¡¼¥Ö¥ë¼«ÂΤÎʪÍýŪ¤ÊÂ礭¤µ¤ËÂФ¹¤ë¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸¤ÇÊֵѤ·¤Þ¤¹¡¥¤Ä - ¤Þ¤ê¡¤ÊÖµÑÃͤ¬Â礭¤±¤ì¤Ð¡¤¤½¤ì¤À¤±¥´¥ß¤â¿¤¤¤Î¤Ç¡¤vacuum¤ò¤«¤±¤ëɬ - Íפ¬¤¢¤ë¤È¤¤¤¦È½ÃǤνõ¤±¤Ë¤Ê¤ë¤ï¤±¤Ç¤¹¡¥ - - ¤³¤ì¤À¤±¤Ç¤Ï¾ðÊóÎ̤¬¾¯¤Ê¤¤¤Î¤Ç¡¤NOTICE¥á¥Ã¥»¡¼¥¸¤Ç¤¤¤í¤ó¤Ê¾ðÊó¤ò¤Ä - ¤¤¤Ç¤Ë½ÐÎϤ·¤Þ¤¹¡¥ - -test=# select pgstattuple('tellers'); -NOTICE: physical length: 0.08MB live tuples: 20 (0.00MB, 1.17%) dead tuples: 320 (0.01MB, 18.75%) free/reusable space: 0.01MB (18.06%) overhead: 62.02% - pgstattuple -------------- - 18.75 -(1 row) - - ¤³¤Î¼Â¹ÔÎã¤Ç¤Ï¡¤19%¤Û¤É¤¬¥´¥ß¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤³¤È¤¬»Ç¤¨¤Þ¤¹¡¥NOTICE¥á¥Ã - ¥»¡¼¥¸¤Î¸«Êý¤â½ñ¤¤¤Æ¤ª¤­¤Þ¤¹¡¥ - - physical length ¥Æ¡¼¥Ö¥ë¤ÎʪÍýŪ¤Ê¥µ¥¤¥º¤òMBñ°Ì¤Çɽ¼¨ - live tuples ¥´¥ß¤Ç¤Ï¤Ê¤¤¥¿¥×¥ë¤Ë´Ø¤¹¤ë¾ðÊó¡¥¥¿¥×¥ë¿ô¡¤³Æ - ¥¿¥×¥ë¤¬Àê¤á¤ëÎΰè¤Î¹ç·×¡¤¥Æ¡¼¥Ö¥ëÁ´ÂΤËÂФ¹¤ë - ÈæÎ¨¤òɽ¼¨¤·¤Þ¤¹¡¥ - dead tuples ¥´¥ß¤Ë¤Ê¤Ã¤¿¥¿¥×¥ë¤Ë´Ø¤¹¤ë¾ðÊó¡¥ - free/reusable space ÍøÍѲÄǽ¤Ê̤»ÈÍÑÎΰè¤äºÆÍøÍѲÄǽÎΰè - overhead ´ÉÍý¤Î¤¿¤á¤ÎÎΰ褬¥Æ¡¼¥Ö¥ëÁ´ÂΤËÀê¤á¤ëÈæÎ¨ - -2. pgstattuple¤Î¥¤¥ó¥¹¥È¡¼¥ë - - PostgreSQL¤¬/usr/local/pgsql¤Ë¥¤¥ó¥¹¥È¡¼¥ëºÑ¤Ç¤¢¤ê¡¤test¥Ç¡¼¥¿¥Ù¡¼ - ¥¹¤Ëpgstattuple¤ò¥¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¾ì¹ç¤Î¼ê½ç¤ò¼¨¤·¤Þ¤¹¡¥ - - $ make - $ make install - - ¥æ¡¼¥¶ÄêµÁ´Ø¿ô¤òÅÐÏ¿¤·¤Þ¤¹¡¥ - - $ psql -e -f /usr/local/pgsql/share/contrib/pgstattuple.sql test - - -3. pgstattuple¤Î»È¤¤Êý - - pgstattuple¤Î¸Æ¤Ó½Ð¤··Á¼°¤Ï°Ê²¼¤Ç¤¹¡¥ - - pgstattuple(NAME) RETURNS FLOAT8 - - Âè°ì°ú¿ô: ¥Æ¡¼¥Ö¥ë̾ - - ´Ø¿ô¤ÎÌá¤ê¤ÏUPDATE¤äDELETE¤Çºî¤é¤ì¤¿¥Æ¡¼¥Ö¥ë¤Î¥´¥ßÎΰè¤ÎÂ礭¤µ¤Ç¡¤ - ¥Æ¡¼¥Ö¥ë¤ÎʪÍýŪ¤ÊÂ礭¤µ¤ËÂФ¹¤ë³ä¹ç(¥Ñ¡¼¥»¥ó¥È)¤ÇÊֵѤ·¤Þ¤¹¡¥ - - ¤Ê¤ª¡¤pgstattuple¤Ï¥Æ¡¼¥Ö¥ë¤ËAccessShareLock¤·¤«¤«¤±¤Ê¤¤¤Î¤Ç¡¤ - pgstattuple ¤ò¼Â¹ÔÃæ¤Ë³ºÅö¥Æ¡¼¥Ö¥ë¤Ë¹¹¿·¤äºï½ü¤¬È¯À¸¤¹¤ë¤È¡¤Àµ¤·¤¯ - ¤Ê¤¤·ë²Ì¤òÊÖ¤¹²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡¥ - - pgstattuple¤¬¥¿¥×¥ë¤ò¡Ö¥´¥ß¡×¤ÈȽÃǤ¹¤ë´ð½à¤Ï¡¤ - HeapTupleSatisfiesNow()¤¬µ¶¤òÊÖ¤·¤¿¤È¤­¤Ç¤¹¡¥ - -4. pgstattuple¤Î¥é¥¤¥»¥ó¥¹¾ò·ï¤Ë¤Ä¤¤¤Æ - - pgstattuple.c¤ÎËÁƬ¤Ë½ñ¤¤¤Æ¤¢¤ëÄ̤ê¤Ç¤¹¡¥¤Þ¤¿¡¤pgstattuple ¤Ï´°Á´¤Ë̵ÊÝ - ¾Ú¤Ç¤¹¡¥pgstattuple ¤ò»ÈÍѤ·¤¿¤³¤È¤Ë¤è¤Ã¤ÆÀ¸¤¸¤ë¤¤¤«¤Ê¤ë·ë²Ì¤Ë´Ø¤·¤Æ - ¤âÀÕǤ¤òÉ餤¤Þ¤»¤ó¡¥ - -5. ²þÄûÍúÎò - - 2001/12/20 Tom Lane¤Ë¤è¤ë½¤Àµ - - Fix pgstattuple to acquire a read lock on the target table. This - prevents embarassments such as having the table dropped or truncated - partway through the scan. Also, fix free space calculation to include - pages that currently contain no tuples. - - 2001/10/01 PostgreSQL 7.2 ÍÑcontrib module¤ËÅÐÏ¿ - - 2001/08/30 pgstattuple ¥Ð¡¼¥¸¥ç¥ó 0.1¥ê¥ê¡¼¥¹ diff --git a/contrib/pgstattuple/pgstattuple.c b/contrib/pgstattuple/pgstattuple.c deleted file mode 100644 index 498f820952..0000000000 --- a/contrib/pgstattuple/pgstattuple.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * $Header: /cvsroot/pgsql/contrib/pgstattuple/pgstattuple.c,v 1.6 2002/05/20 23:51:40 tgl Exp $ - * - * Copyright (c) 2001 Tatsuo Ishii - * - * 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 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 AUTHOR 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 HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, - * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - */ - -#include "postgres.h" - -#include "fmgr.h" -#include "access/heapam.h" -#include "access/transam.h" -#include "catalog/namespace.h" -#include "utils/builtins.h" - - -PG_FUNCTION_INFO_V1(pgstattuple); - -extern Datum pgstattuple(PG_FUNCTION_ARGS); - -/* ---------- - * pgstattuple: - * returns the percentage of dead tuples - * - * C FUNCTION definition - * pgstattuple(NAME) returns FLOAT8 - * ---------- - */ -Datum -pgstattuple(PG_FUNCTION_ARGS) -{ - text *relname = PG_GETARG_TEXT_P(0); - RangeVar *relrv; - Relation rel; - HeapScanDesc scan; - HeapTuple tuple; - BlockNumber nblocks; - BlockNumber block = 0; /* next block to count free space in */ - BlockNumber tupblock; - Buffer buffer; - double table_len; - uint64 tuple_len = 0; - uint64 dead_tuple_len = 0; - uint64 tuple_count = 0; - uint64 dead_tuple_count = 0; - double tuple_percent; - double dead_tuple_percent; - uint64 free_space = 0; /* free/reusable space in bytes */ - double free_percent; /* free/reusable space in % */ - - relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname, - "pgstattuple")); - rel = heap_openrv(relrv, AccessShareLock); - - nblocks = RelationGetNumberOfBlocks(rel); - scan = heap_beginscan(rel, SnapshotAny, 0, NULL); - - while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) - { - if (HeapTupleSatisfiesNow(tuple->t_data)) - { - tuple_len += tuple->t_len; - tuple_count++; - } - else - { - dead_tuple_len += tuple->t_len; - dead_tuple_count++; - } - - /* - * To avoid physically reading the table twice, try to do the - * free-space scan in parallel with the heap scan. However, - * heap_getnext may find no tuples on a given page, so we cannot - * simply examine the pages returned by the heap scan. - */ - tupblock = BlockIdGetBlockNumber(&tuple->t_self.ip_blkid); - - while (block <= tupblock) - { - buffer = ReadBuffer(rel, block); - free_space += PageGetFreeSpace((Page) BufferGetPage(buffer)); - ReleaseBuffer(buffer); - block++; - } - } - heap_endscan(scan); - - while (block < nblocks) - { - buffer = ReadBuffer(rel, block); - free_space += PageGetFreeSpace((Page) BufferGetPage(buffer)); - ReleaseBuffer(buffer); - block++; - } - - heap_close(rel, AccessShareLock); - - table_len = (double) nblocks *BLCKSZ; - - if (nblocks == 0) - { - tuple_percent = 0.0; - dead_tuple_percent = 0.0; - free_percent = 0.0; - } - else - { - tuple_percent = (double) tuple_len *100.0 / table_len; - dead_tuple_percent = (double) dead_tuple_len *100.0 / table_len; - free_percent = (double) free_space *100.0 / table_len; - } - - elog(DEBUG3, "physical length: %.2fMB live tuples: %.0f (%.2fMB, %.2f%%) dead tuples: %.0f (%.2fMB, %.2f%%) free/reusable space: %.2fMB (%.2f%%) overhead: %.2f%%", - - table_len / (1024 * 1024), /* physical length in MB */ - - (double) tuple_count, /* number of live tuples */ - (double) tuple_len / (1024 * 1024), /* live tuples in MB */ - tuple_percent, /* live tuples in % */ - - (double) dead_tuple_count, /* number of dead tuples */ - (double) dead_tuple_len / (1024 * 1024), /* dead tuples in MB */ - dead_tuple_percent, /* dead tuples in % */ - - (double) free_space / (1024 * 1024), /* free/available space in - * MB */ - - free_percent, /* free/available space in % */ - - /* overhead in % */ - (nblocks == 0) ? 0.0 : 100.0 - - tuple_percent - - dead_tuple_percent - - free_percent); - - PG_RETURN_FLOAT8(dead_tuple_percent); -} diff --git a/contrib/pgstattuple/pgstattuple.sql.in b/contrib/pgstattuple/pgstattuple.sql.in deleted file mode 100644 index b49a13483f..0000000000 --- a/contrib/pgstattuple/pgstattuple.sql.in +++ /dev/null @@ -1,4 +0,0 @@ -DROP FUNCTION pgstattuple(text); -CREATE FUNCTION pgstattuple(text) RETURNS float8 -AS 'MODULE_PATHNAME', 'pgstattuple' -LANGUAGE 'c' WITH (isstrict); diff --git a/contrib/retep/CHANGELOG b/contrib/retep/CHANGELOG deleted file mode 100644 index 188c40129e..0000000000 --- a/contrib/retep/CHANGELOG +++ /dev/null @@ -1,7 +0,0 @@ -Fri Mar 02 16:08:00 GMT 2001 peter@retep.org.uk - - Started importing in the rest of the retep tools. - -Tue Jan 23 10:19:00 GMT 2001 peter@retep.org.uk - - Finished the XML Export classes - - First of the test data suite now in CVS. - diff --git a/contrib/retep/Implementation b/contrib/retep/Implementation deleted file mode 100644 index b3125acf0e..0000000000 --- a/contrib/retep/Implementation +++ /dev/null @@ -1,116 +0,0 @@ -Retep Tools Implementation --------------------------- - - -The tools are designed to be put into a single jar file, but each one is -executable either individually or part of one single application. - -To run the big application, you can either: - - java -jar retepTools.jar - -or with the retepTools.jar in the classpath run: - - java uk.org.retep.tools.Main - -Windows users: For you you can also double click the retepTools.jar as windows -will automatically run javac for you. - -To run the individual tools, you must have the .jar file in your classpath and -then run the relevant Main class. - -Tool Type Class ------------------------------------------------------------------------------- -pg_hba.conf Editor/repairer Editor uk.org.retep.util.hba.Main -Properties Editor Editor uk.org.retep.util.proped.Main - - -Layout of the classes ---------------------- - -Simply, tools that work on property files (Java properties, resource files, -configuration settings - pg_hba.conf for example) go under uk.org.retep.util in -their own package. Other utility classes (like PropertyIO) go in to the -uk.org.retep.util.misc package except for certain ones where they are related. - -ie: TableModels. In swing you have JTable which uses a TableModel to display -(and possibly update) some data. These go under uk.org.retep.util.models where -you will find PropertiesTableModel for example. This one allows a Properties -object to be displayed & updated. - -Come core classes like Logger, ExceptionDialog etc go into the main -uk.org.retep.util package. - -Directory/Package Contents ------------------------------------------------------------------------------- -uk.org.retep Home of the tools.properties file -uk.org.retep.tools The main all-in-one application -uk.org.retep.dtu The Data Transform Unit -uk.org.retep.util Core utility classes -uk.org.retep.util.hba pg_hba.conf editor/repairer -uk.org.retep.util.misc Misc utility classes -uk.org.retep.util.models Swing table models -uk.org.retep.util.proped Property Editor -uk.org.retep.util.xml.core Basic XML Factory -uk.org.retep.util.xml.jdbc JDBC/XML interface -uk.org.retep.util.xml.parser Simple SAX parser - -Structure of a tool -------------------- - -Each tool has at least 2 base classes, and an entry in the tools.properties -file. For this example, I'll show you the Properties Editor: - -Base package uk.org.retep.util.proped -Main tool class uk.org.retep.util.proped.PropertyEditor -Standalone class uk.org.retep.util.proped.Main - -The main tool class is the entry point used by the main application. Because -they are used in a GUI, this class must extend javax.swing.JComponent and -implement the uk.org.retep.tools.Tool interface. (NB: You will find I always -use JPanel, but JComponent is used here so that any swing class can be used -you are not limited to JPanel.) - -The standalone class is a basic static class that implements the main method. -It should extend the uk.org.retep.misc.StandaloneApp class and be written along -the lines of the following example: - - import uk.org.retep.util.StandaloneApp; - import javax.swing.JComponent; - - public class Main extends StandaloneApp - { - public Main(String[] args) - throws Exception - { - super(args); - } - - public JComponent init() - throws Exception - { - // Your initialisation here. In this case the PropertyEditor - PropertyEditor panel = new PropertyEditor(); - - // do stuff here, ie load a file if supplied - - // return the tool - return panel; - } - - public static void main(String[] args) - throws Exception - { - Main main = new Main(args); - main.pack(); - main.setVisible(true); - } - } - -you will find a template in the uk.org.retep.util.Main class. Simply copy this -classes source, as it gives you the basic stub. Just add your own implementation -if init() like the one above. Look at the full Main class for the -PropertiesEditor to see how to get at the command line args. - -By convention, the standalone class is named Main. - diff --git a/contrib/retep/Makefile b/contrib/retep/Makefile deleted file mode 100644 index e5de9c7ac8..0000000000 --- a/contrib/retep/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -#------------------------------------------------------------------------- -# -# Makefile for contributed retep tools -# -# Copyright (c) 2001, PostgreSQL Global Development Group -# -# $Header: /cvsroot/pgsql/contrib/retep/Attic/Makefile,v 1.1 2001/07/06 23:07:20 petere Exp $ -# -#------------------------------------------------------------------------- - -subdir = contrib/retep -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -all: - $(ANT) -buildfile $(srcdir)/build.xml all - -install: installdirs - $(ANT) -buildfile $(srcdir)/build.xml install \ - -Dinstall.directory=$(javadir) - -installdirs: - $(mkinstalldirs) $(javadir) - -uninstall: - $(ANT) -buildfile $(srcdir)/build.xml uninstall \ - -Dinstall.directory=$(javadir) - -clean distclean maintainer-clean: - $(ANT) -buildfile $(srcdir)/build.xml clean diff --git a/contrib/retep/README b/contrib/retep/README deleted file mode 100644 index 5355c9d99f..0000000000 --- a/contrib/retep/README +++ /dev/null @@ -1,35 +0,0 @@ -Before you ask what retepTools are, they are my personal suite of utilities. -About 90% of them are JDBC related (either they use JDBC, or I use them in -developing the JDBC driver). - -Now, because of various reasons I won't go into now, in January 2001 I decided -to release the entire lot to the public. I could have used something like -SourceForge, but as they are mainly JDBC related I thought here is the best -place. - -Now all (bar retepPDF, see end-note) will over the next few months be going -into the /contrib/retep directory. They range from simple XML Inport/Export -classes to entire sub-systems that can be plugged into applications. - -All this lot were never released, so I'm placing them under PostgreSQL's -licence. - -Please refer to Implementation for details of what package does what. - -It all requires Java2SE (JDK1.2) as a minimum. I do have some plans for some -EJB tools later, so those will need Java2EE, but not yet ;-) - -Peter Mount -peter@retep.org.uk -March 2 2001 - -retepPDF: This is not included for two reasons: - -1: It's big and not really related in any way to PostgreSQL -2: More importantly, I (may be foolishly) released it some 3 years ago under - the LGPL. As a few people have added to it, it's not really possible to - change the licence, and I don't want to polute PostgreSQL's source tree ;-) - -retepGraph: This was an old graphics library. It's been obsolete for 3 years -now, so it's not going in. - diff --git a/contrib/retep/build.xml b/contrib/retep/build.xml deleted file mode 100644 index 04a8db5c2f..0000000000 --- a/contrib/retep/build.xml +++ /dev/null @@ -1,98 +0,0 @@ - - - - -]> - - - - - - - - - - - - - - - - - - - -*** WARNING: Contributed retep tools need jdk1.2 or later. -*** Compilation NOT done - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/contrib/retep/data/cds.dtd b/contrib/retep/data/cds.dtd deleted file mode 100644 index df542c3476..0000000000 --- a/contrib/retep/data/cds.dtd +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - diff --git a/contrib/retep/data/cds.xml b/contrib/retep/data/cds.xml deleted file mode 100644 index fb0203bda9..0000000000 --- a/contrib/retep/data/cds.xml +++ /dev/null @@ -1,2691 +0,0 @@ - - - - 01 - Kiling Time - 02 - Waiting To Die - 03 - Feel Good - 04 - Bartender - 05 - Crazy Legs - 06 - Pac Bell - 07 - I Got You - 08 - Boom (How You Like That) - 09 - Swan Dive - 10 - Stevie - 11 - Jesus (Of Nazareth) - 12 - The Meadow - - - - - jump for joy - - - 01 - No Limit - 02 - Tribal Dance - 03 - Mysterious - 04 - Faces - 05 - Maximum Overdrive - 06 - The Power Age - 07 - Break The Chain - 08 - Kiss Me Bliss Me - 09 - Thow The Groove Down - 10 - R.U.O.K - 11 - Let The Beat Control Your Body - 12 - Invinite Me To Trance - 13 - Where Are You Now - 14 - Shelter For A Rainy Day - 15 - Get Ready For This (WILDE MIX) - 16 - No Limit - (AUTOMATIC BREAKBEAT REMIX) - - - - - 01 - 2-Raum Wohnung - Wir trafen uns in einem Garten - 02 - 2-Raum Wohnung - Wir trafen uns in einem Garten (Inga Humpes Version) - 03 - 2-Raum Wohnung - Wir trafen uns in einem Garten mit Max - 04 - 2-Raum Wohnung - Wir trafen uns in einem Garten (i-oI - Remix) - - - - - 01 - Track 1 - 02 - Track 2 - 03 - Track 3 - 04 - Track 4 - 05 - Track 5 - 06 - Track 6 - 07 - Track 7 - 08 - Track 8 - 09 - Track 9 - 10 - Track 10 - 11 - Track 11 - 12 - Track 12 - 13 - Track 13 - - - - - 01 - Show me something good - 02 - Feel 'ya - 03 - Find Your Own Peace - 04 - Nourishing The Ocean - 05 - Walking - 06 - Bring Out Your Love - 07 - Primetime - 08 - Stormy - 09 - Philosophie - 10 - No - 11 - Dharma - 12 - Shine On - - - - - 01 - Ambitionz As A Ridah - 02 - All bout u - 03 - Skandalouz - 04 - Got My Mind Made Up - 05 - How Do You Want It - 06 - 2 Of Amerikaz Most Wanted - 07 - No More Pain - 08 - Heartz of Men - 09 - Life Goes On - 10 - Only God can judge me - 11 - Tradin War Stories - 12 - California Love(RMX) - 13 - I Ain't Mad At Cha - 14 - What'z Ya Phone Number - - - 01 - Radio Mix - 02 - Instrumental - 03 - Album Mix - - - 01 - Redemption - 02 - Open Fire - 03 - R U Still Down_ (Remeber Me) - 04 - Hellrazor - 05 - Thug Style - 06 - Where Do We Go From Here - 07 - I Wonder If Heaven Got A Ghetto - 08 - Nothing To Lose - 09 - I'm Gettin Money - 10 - Lie To Kick It - 11 - Fuck All Y'all - 12 - Let Them Thangs Go - 13 - Definition Of A Thug Nigga - - - 01 - Ready 4 Whatever - 02 - When I Get Free - 03 - Hold On Be Strong - 04 - I'm Losin It - 05 - Fake Ass Bitches - 06 - Do For Love - 07 - Enemies With Me - 08 - Nothin But Love - 09 - 16 On Death Row - 10 - I Wonder If Heaven Got A Ghetto (Hip-hop Version) - 11 - When I Get Free - 12 - Black Starry Night (Interlude) - 13 - Only Fear Of Death - - - - - 01 - Original Version - 02 - SNA Club Mix - 03 - Jack Daniel´s - - - - - 01-Loveless - 02-Golden Age of Life - 03-Planeteria - 04-Third Stream - 05-Escape That - 06-Cosmic Tree - 07-Spirits in Transit - 08-The Action - 09-Star Chasers - 10-Wishful Thinking - 11-Universal Reprise - - - 01-We who are not as others - 02-Humans - 03-In the shadows - 04-Mathmatical Probability - 05-Greys - 06-Pegasus 51 - 07-!$^^$% - 08-Wormholes - 09-Dauntless - - - 01-Planetaria (Hefner Remix) - 02-We Who Are Not As Others (Jazzaova Version) - 03-Mathematical Probability (Mustang Remix) - 04-Escape That (New Sector Movements Selekshan 2 Sector Rub Remix) - 05-Escape That (Off-World Remix) - 06-Dauntless (Restless Soul South Pacific Remix) - 07-Star Chasers (Masters at Work Main Mix) - 08-Star Chasers (Azymuth Remix) - 09-The Action (Shawn J Period Remix) - 10-We Who Are Not As Others (Alpha Omega Remix) - 11-We Who Are Not As Others (Sonar Circle Remix) - - - - - 01 - Train - 02 - Superfly - 03 - What's Up - 04 - Pleasantly Blue - 05 - Morphin & Chocolate - 06 - Spaceman - 07 - Old Mr. Heffer - 08 - Calling All The People - 09 - Dear Mr. President - 10 - Drifting - 11 - No Place Like Home - - - - - 01 - Owner Of A Lonely Heart - 02 - Hold On - 03 - It Can Happen - 04 - Changes - 05 - Cinema - 06 - Leave It - 07 - Our Song - 08 - City Of Love - 09 - Hearts - - - - - 01 - For Starters - 02 - Monkey Kong - 03 - A - 04 - Old Folks - 05 - Hopper Jonnus Fang - 06 - Summer On The Underground - 07 - Warning - 08 - If It Ain't Broke Fix It Anyway - 09 - I Love Lake Tahoe - 10 - Don't Be Punks - 11 - Down On The Floor - 12 - Jason's Addiction - 13 - Miles Away - 14 - Getting Around - - - - - 01-The Universe-A Guy Called Gerald - 02-The First Breath-A Guy Called Gerald - 03-Humanity-A Guy Called Gerald - 04-Multiplies-A Guy Called Gerald - 05-Fever (Or a Flame)-A Guy Called Gerald - 06-Could you Understand-A Guy Called Gerald - 07-Alien Report-A Guy Called Gerald - 08-Glow-A Guy Called Gerald - 09-Beaches & Deserts-A Guy Called Gerald - 10-Final Call-A Guy Called Gerald - 11-I Make It-A Guy Called Gerald - 12-Universal Spirit-A Guy Called Gerald - 13-Hurry To Go Easy-A Guy Called Gerald - 14-Scale Circle-A Guy Called Gerald - 15-Landed-A Guy Called Gerald - - - - - 01 A Teens - Mamma Mia - 03 A Teens - Super Trouper - 02 A Teens - gimme gimme gimme (a man after midnight) - 04 A Teens - One of us - 05 A Teens - Voulez vous - 06 A Teens - SOS - 07 A Teens - Dancing Queen - 08 A Teens - Take a chance on me - 09 A Teens - Lay all your love on me - 10 A Teens - The name of the game - 11 ATeens - Our last summer - - - - - 01 - Take On Me - 02 - Cry Wolf - 03 - Touchy - 04 - You Are The One - 05 - Manhattan Skyline - 06 - The Blood That Moves The Body - 07 - Early Morning - 08 - Hunting High And Low - 09 - Move To Memphis - 10 - I've Been Losing You - 11 - The Living Daylights - 12 - Crying In The Rain - 13 - I Call Your Name - 14 - Stay On These Roads - 15 - Train Of Thought - 16 - The Sun Always Shines On TV - - - 01 - Take on me - 02 - Train of Thought - 03 - Hunting High and Low - 04 - The Blue Sky - 05 - Living a Boy's Adventure Tale - 06 - The Sun Always Shines On TV - 07 - And You Tell Me - 08 - Love Is Reason - 09 - I Dream Myself Alive - 10 - Here I Stand and Face the Rain - - - 01 - minor earth major sky - 02 - little black heart - 03 - velvet - 04 - summer moved on - 05 - the sun never shone that day - 06 - to let you win - 07 - the company man - 08 - thought that it was you - 09 - i wish i cared - 10 - barely hanging on - 11 - you will never get over me - 12 - i wont forget here - 13 - mary ellen makes the moment count - - - - - 01 - Dancing Queen - 02 - Knowing Me, Knowing You - 03 - Take A Chance On Me - 04 - Mamma Mia - 05 - Lay All Your Love On Me - 06 - Super Trouper - 07 - I Have A Dream - 08 - The Winner Takes It All - 09 - Money, Money, Money - 10 - S.O.S - 11 - Chiquitita - 12 - Fernando - 13 - Voulez Vous - 14 - Gimme! Gimme! Gimme! - 15 - Does Your Mother Know - 16 - One Of Us - 17 - The Name Of The Game - 18 - Thank You For The Musik - 19 - Waterloo - - - 01 - Waterloo - 02 - Honey, Honey - 03 - So long - 04 - I do - 05 - SOS - 06 - Mamma mia - 07 - Fernando - 09 - Money, Money, Money - 10 - The name of the game - 11 - Take a chance on me - 12 - Chiquitita - 13 - I have a dream - 14 - The winner takes it all - 15 - Super trouper - 16 - Thank you for the music - - - 01 - Summer Night City - 02 - Angeleyes - 03 - The Day Before You Came - 04 - Eagle - 05 - I Do, I Do, I Do, I Do, I Do - 06 - So Long - 07 - Honey Honey - 08 - The Visitors - 09 - Our Last Summer - 10 - On & On - 11 - Ring Ring - 12 - I Wonder - 13 - Lovelight - 14 - Head Over Heels - 15 - When I Kissed The Teacher - 16 - I Am The City - 17 - Cassandra - 18 - Under Attack - 19 - When All Is Said And Done - 20 - The Way Old Friends Do - - - 01 - People Need Love - 02 - Ring Ring - 03 - Waterloo - 04 - Waterloo (German Version) - 05 - Honey Honey - 06 - So Long - 07 - I Do, I Do, I Do, I Do, I Do - 08 - S.O.S - 09 - Mamma Mia - 10 - Fernando - 11 - Dancing Queen - 12 - Money, Money, Money - 13 - Knowing Me, Knowing You - 14 - The Name Of The Game - 15 - Take A Chance On Me - 16 - Eagle - 17 - Thank You For The Music - 18 - Summer Night City - - - 01 - Chiquitita - 02 - Does Your Mother Know - 03 - Voulez-Vous - 04 - Gimme! Gimme! Gimme! (A Man After Midnight) - 05 - I Have A Dream - 06 - The Winner Takes It All - 07 - Super Trouper - 08 - Lay All Your Love On Me - 09 - One Of Us - 10 - Head Over Heels - 11 - The Day Before You Came - 12 - Under Attack - 13 - Ring Ring (German Version) - 14 - Happy New Year - 15 - Wer Im Wartesaal Der Liebe Steht - - - - - 01. Absolute Beginner - Das Boot - 02. Absolute Beginner - Hammerhart - 03. Absolute Beginner - Rock On - 04. Absolute Beginner - Liebeslied - 05. Absolute Beginner - Füchse - 06. Absolute Beginner - Fahr'n - 07. Absolute Beginner - Showmaster - 08. Absolute Beginner - Geht Was - 09. Absolute Beginner - Geh bitte - 10. Absolute Beginner - Nie Nett - 11. Absolute Beginner - Mikro in der Hand - 12. Absolute Beginner - Nicht Allein - 5Sterne Delux - Dein Herz schlägt schneller - - - - - 01-Zonenzombie - 02-Papier - 03-Friss den Stahl - 04-Charly - 05-Die Ballade von Karl Arsch - 06-Europa - 07-Terror und Schrott - 08-Küss mich - 09-Weit daneben gepisst - 10-Welt voll Harmonie - 11-Die Zeit - 12-Unfall - 13-Ich und die Wirklichkeit - 14Die Reise - - - - - 01 AC-DC - Riff Raff - 02 AC-DC - Let There Be Rock - 03 AC-DC - Whole Lotta Rosie - 04 AC-DC - Sin City - 05 AC-DC - Dirty Deeds Done Dirt Cheap - 06 AC-DC - Baby Please Don't Go - 07 AC-DC - Big Balls - 08 AC-DC - Walk All Over You - 09 AC-DC - Hard As Rock - 10 AC-DC - Hells Bells - 11 AC-DC - What Next To The Moon - 12 AC-DC - Shake Your Foundations - 13 AC-DC - Gone Shooting - 14 AC-DC - Thunderstuck - - - - - 01 - Life Is A Flower - 02 - Always Have, Always Will - 03 - Cruel Summer - 04 - Travel To Romantis - 05 - Adventures In Paradise - 06 - Dr. Sun - 07 - Cecilia - 08 - He Decides - 09 - I Pray - 10 - Tokyo Girl - 11 - Don't Go Away - 12 - Captain Nemo - 13 - Donnie - 14 - Cruel Summer (Big Bonus Mix) - - - 01 - Voules-Vous Dancer - 02 - All That She Wants - 03 - Münchhausen (Just Chaos) - 04 - Happy Nation - 05 - Waiting For Magic - 06 - Fashion Party - 07 - Wheel Of Fortune - 08 - Dancer In A Daydream - 09 - My Mind -Mindles Mix- - 10 - W.O.F. -Original Club Mix- - 11 - Dimension Of Depth - 12 - Young And Proud - 13 - A.T.S.W. -Banghra Version- - - - 01 - The sign (radio edit) - 02 - The sign (long version) - - - - - 01 - Made in Paradise - 02 - Auf der Rolltreppe - 03 - Kuddel Daddel Du - 04 - Die Zauberin - 06 - Sturmflut - 07 - Robert der Roboter - 08 - Melancholie - 09 - Karawane ins Glück - 10 - Das Lied von Susi und Johnny - 11 - Mein Herz ist ein Ufo - - - - - 01 - acid marathon 1 - 02 - acid marathon 2 - 03 - acid marathon 3 - 04 - washaa - 05 - acid marathon 4 - 06 - jing jang - 07 - in front of da outland - 08 - mondonon - 09 - clock seven - 10 - 4 degrees - 11 - balance - 12 - + + + acid - - - - - 01 - Intro - 02 - 73 - 03 - Metropolis - 04 - Music in my Mind - 05 - Jaxx - 06 - Mother Death - 07 - The Tree Knows Everything - 08 - Circles - 09 - Dirty Happy - 10 - F-Jam - 11 - Colours - 12 - Aromatherapy - - - - - 01 - Tiro Ao lvaro - 02 - Iracema - 03 - Trem Das Onze - 04 - Saudosa Maloca - 05 - O Samba Do Arnesto - 06 - Torresmo Milanesa - 07 - Viaduto Santa Efig nia - 08 - Bom Dia Tristeza - 09 - As Mariposas - 10 - Despejo Na Favela - 11 - Ag enta a M o, Jo o - 12 - Vide Verso Meu Endere o - 13 - Acende O Candieiro - 14 - No Morro Da Casa Verde - 15 - Vila Esperan a - 16 - Fica Mais Um Pouco Amor - 17 - Apaga O Fogo Man - - - - - 01 - Por que voc faz cinema- - 02 - A f brica do Poema - 03 - Bagatelas - 04 - Metade - 05 - Sudoeste - 06 - O verme e a estrela - 07 - Estrelas - 08 - Aconteceu - 09 - Cariocas - 10 - Morro dois irm os - 11 - Inverno - 12 - Roleta russa - 13 - Tema de Alice - 14 - Portrait of Gertrude - 15 - Minha m sica - - - - - Amazing - Boogie Man - Can't Stop Messin' - Crazy - Cryin' - Eat the Rich - Fever - Flesh - Get a Grip - Gotta Love It - Intro - Line Up - Livin' on the Edge - Shut Up And Dance - Walk On Down - - - 01 - Nine Lives - 02 - Falling In Love - 03 - Hole In My Soul - 04 - Taste Of India - 05 - Full Circle - 06 - Something's Gotta Give - 07 - Ain't That A Bitch - 08 - Take Me To The Farm - 09 - Crash - 10 - Kiss Your Past Good-bye - 11 - Pink - 12 - Falling Off - 13 - Attitude Adjustment - - - - - 01 - Amor Verdadero - 02 - Alto Songo - 03 - Habana Del Este - 04 - A Toda Cuba Le Gusta - 05 - Fiesta de la Rumba - 06 - Los Sitio' Asere - 07 - Pio Mentiroso - 08 - Maria Caracoles - 09 - Clasiqueando con Ruben - 10 - Elube Chango - - - - - 01 - Das Möbiusband - Zeychen und Wunder - 02 - Triebwerk - 03 - Felix - 04 - Kosmonauten - 05 - Fingerwalze - 06 - So sollte es nicht sein! - 07 - Küchenlied - 08 - Das Scheusal - 09 - Déjà vu (Snap Mix #2) - 10 - Hasensong - 11 - Schöner leben - 12 - Rohleder's - 13 - Maximale Gier - 14 - Nach Hause (instr.) - 15 - Gesichter - 16 - Stadt-Fisch - - - - - 01-Intro - 02-Cold Water Music - 03-The Force - 04-Sail - 05-Downstate - 06-Ain't Got Time To Waste - 07-Fat City (Interlude) - 08-True To Hip Hop - 09-Demonique - 10-A Tree, A Rock And A Cloud - 11-Journey To The End Of The Night - 12-From Here To Fame - - - - - 01 - Original mix - 02 - Sexy boy - 03 - Album version - 04 - Remember - - - 01 - La Femme D'Argent - 02 - Sexy Boy - 03 - All I Need - 04 - Kelly Watch The Stars - 05 - Talisman - 06 - Remember - 07 - You Make It Easy - 08 - Ce Matin La - 09 - New Star In The Sky - 10 - Le Voyage De Pénélope - - - 01 - Modular Mix - 02 - Casanova 70 - 03 - Les Professionnels - 04 - J'ai dormi sous l'Eau - 05 - Le Soleil est pres de Moi - 06 - Californie - 07 - Brakes On - - - 01 - playground love - 02 - clouds up - 03 - bathroom girl - 04 - cemetary party - 05 - dark messages - 06 - the word 'hurricane' - 07 - dirty trip - 08 - highschool lover - 09 - afternoon sister - 10 - ghost song - 11 - empty house - 12 - dead bodies - 13 - suicide underground - - - - - A Teens - Super Trouper - Aqua - Cartoon Heroes - Backstreet Boys - Show Me The Meaning Of Being Lonely - Bloodhound Gang - The Bad Touch - Die Toten Hosen - Unsterblich - Enrique Iglesias - Rhythm Divine - Highland - Bella Stella - HIM - Join me - Lene Marlin - Sitting Down Here - Madonna - American Pie - Marc Anthony - I Need To Know - Melanie C - Northern Star - Metallica - Nothing Else Matters - Modern Talking - China In Your Eyes (Ext.Version) - N'Sync - Bye Bye Bye - Natural Born Hippies - Am I Not Sweet - Oli.P - Niemals Mehr - Prezioso feat. Marvin- Tell Me Why - Santana - Maria Maria - Sash! - Adelante [Original Mix] - Stefan Raab - Wadde Hadde Dudde Da - Sting - Desert Rose - Thomas D. - Liebesbrief - Vengaboys - Shalala Lala - Yamboo - Come With Me - - - 01_Blank & Jones - The Nightfly - 02_Passion Fruit - Wonderland - 03_GIGI D'AGOSTINO - The Riddle - 04_Echt - Junimond - 05_Bon Jovi - It´s My Life - 06_Backstreet Boys - The One - 07_Venga Boys - Uncle John From Jamaica - 08_GIGI D'AGOSTINO - Another Way - 09_Ace Of Base - Hallo Hallo - 10_Melanie C - Never Be The Same Again - 11_Anton Aus Tirol Feat DJ Ötzi - Gemma Bier Trinken - 12_Britney Spears - Oops I Did It Again - 13_GIGI D'AGOSTINO - La Passion - 14_Reamonn - Supergirl - 15_John Davies - I Promised Myself - 16_Fools Garden - Suzy - 17_Bomfunk MC's - Freestyler - 18_Die Toten Hosen - Bayern - 19_Die Band Ohne Namen - Take My Heart - - - Anastacia - I'm Outta Love - Andreas Stenschke - Just When I Needed You Most - Antonia Feat. Sandra - ...Ich Bin Viel Schöner - Azuca - Este Chico (I Fall In Love With You) (Radio Mix) - Bastian Raagas - You Complete Me (Radio Dance Version) - Captain Jack - Only You - Celine Dion - I Want You To Need Me (Radio Edit) - Celine Dion - I Want You To Need Me (Thunderpuss Radio Mix) - Chayanne - Boom Boom (Spanglish Version) - Eskobar - Good Day For Dying (Radio Edit) - Hooverphonic - Mad About You (Radio Edit) - Madonna - Music (CD Version) - Monaco - I´ve Got A Feeling (Radio Edit) - Red Sector - Invasion Over Berlin (Short Energy Mix) - Senait - Aura (Radio Edit) - Sharon Williams - Life Is So Strong (Single Edit) - Sladdgo - Was Du Woll - Sonique - It Feels So Good - Sound Convoy - Hey Baby ( Radio Edit ) - Verena - Ist das alles - - - Berger - Zeig mir Dein Gesicht - Britney Spears - Lucky - Darude - Sandstorm - Marque - Electronic Lady - Mel C - I Turn To You - Mr President - Up´n Away 2k - N Sync 02 - It's Gonna Be Me - Orange Blue - She's Got That Light - Rednex - Hold Me (For A While) - Rednex - The Spirit Of The Hawk - Ronan Keating - Life is a Rollercoaster - Sasha - Owner Of My Heart - Tic Tac Toe - Ich liebe Disch - Toploader - Dancing in the Moonlight - Vanessa Amorosi - Absolutely Everybody - Whitney Houston & Enrique Iglesias - Could I Have This Kiss Forever - - - - - 01 - Che Angelo Sei (Amore Mio) - 02 - Tu Soltanto Tu (Mi Hai Fatto Innamorare) - 03 - Ci Sara - 04 - Imagini 77 - 05 - Canto Di Libertá - 06 - Abbandonati - 07 - Prima Notte D´amore - 08 - Sharazan - 09 - Felicitá - 10 - Meditando - 11 - Caro Gesú - 12 - E Fu Subito Amore - 13 - Angeli - 14 - Aria Pura - 15 - Lo Ti Cerco - 16 - Canzone Blu - - - - - 01 - All I Really Want - 02 - You Oughta Know - 03 - Perfect - 04 - Hand In My Pocket - 05 - Right Through You - 06 - Forgiven - 07 - You Learn - 08 - Head Over Feet - 09 - Mary Jane - 10 - Ironic - 11 - Not the Doctor - 12 - Wake Up - 13 - You Oughta Know (remix) - - - 01 - You Learn-1 - 01 - You Learn - 02 - Joining You - 03 - No Pressure Over Cappuccino - 04 - That I Would Be Good - 05 - Head Over Feet - 06 - Princes Familiar - 07 - I Was Hoping - 08 - Ironic - 09 - These R The Thoughts - 10 - King Of Pain - 11 - You Oughta Know - 12 - Uninvited - - - Alanis Morisette - 01 Front Row - Alanis Morisette - 02 Baba - Alanis Morisette - 03 Thank U - Alanis Morisette - 04 Are You Still Mad - Alanis Morisette - 05 Sympathetic Character - Alanis Morisette - 06 That I Would be Good - Alanis Morisette - 07 The Couch - Alanis Morisette - 08 Can't Not - - - - - 01 - Time - 02 - Tryin' - 03 - The Child - 04 - Ralph & Kathy - 05 - With U - 06 - You, my Baby & I - 07 - 06 10 98 - 08 - Party People - 09 - Consolidated - 10 - Quiet Storm - - - - - 01 - Feel the Sunshine - 02 - Jazz Master - 03 - Intro 1 - 04 - Acid Lab - 05 - Pulp Friction - 06 - Candles - 07 - Ibiza - 08 - Intro 2 - 09 - Out of Time - 10 - U R - - - - - 01 - Big In Japan - 02 - Sounds Like A Melody - 03 - Sensations - 04 - The Mysteries Of Love - 05 - Lassie Come Home - 06 - Jerusalem - 07 - Dance With Me - 08 - For A Million - 09 - A Victory Of Love - 10 - The Jet Set - 11 - Red Rose - 12 - Romeos - 13 - Summer Rain - 14 - Forever Young - 15 - Big In Japan [Culture Mix] - - - A Victory Of Love - Big In Japan - Fallen Angel - Forever Young - In The Mood - Lies - Sounds Like A Melody - Summer In Berlin - The Jet Set - To Germany With Love - - - - - 01 - Follow Me - 02 - Gold - 03 - Mother Look What They've Done To Me - 04 - Run Baby Run - 05 - Queen Of China Town - 06 - The Sphinx - 07 - Blood And Honey - 08 - Fashion Pack - 09 - Fabulous Lover Love Me - 10 - Diamonds - 11 - Egal - 12 - Fever - 13 - Never Trus A Pretty Face - 14 - Alphabet - 15 - Im A Photograph - 16 - Blue Tango - 17 - Tomorrow - 18 - The Lady In Black - 19 - I Need A Man - 20 - Nymphomania - - - - - 01 - Let it rain - 02 - Birmingham - 03 - Fall from grace - 04 - Dark Horse - 05 - Beautiful goodbye - 06 - Sitting on the top of the world - 07 - Last exit to eden - 08 - Trust me (This is love) - 09 - Let's got lost - 10 - Promises - - - 01 - Dark Horse - 02 - Let It Rain - 03 - Birmingham - - - 01 - Believe in you - 02 - Love lift me - 03 - Why don't you love me- - 04 - Too little, too late - 05 - If I didn't have you - 06 - Ride - 07 - Right here all along - 08 - Wishful thinking - 09 - Shades of grey - 10 - Give up giving in - 11 - Best of me - 12 - Never said goodbye - 13 - Out of bounds - - - - - 01 - Stoney Street - 02 - Easy Muffin - 03 - Yasawas - 04 - Creatures - 05 - Chomp Samba - 06 - The New York Editor - 07 - Defocus - 08 - The Nasty - 09 - Bitter & Twisted - 10 - Wires & Snakes - 11 - One Day In My Garden - 12 - Dream Sequence - 13 - One Small Step - 14 - Mission - - - 01 - Get Your Snack On - 02 - Four Ton Mantis - 03 - Slowly - 04 - Marine Machines - 05 - Golfer vrs Boxer - 06 - Deo - 07 - Precursor (feat. Quadraceptor) - 08 - Saboteur - 09 - Chocolate Lovely - 10 - Rhino Jockey - 11 - Keepin' It Steel (The Anvil Track) - 12 - Natureland - - - - - 01 - Not That Kind - 02 - I'm Outta Love - 03 - Cowboys & Kisses - 04 - Who's Gonna Stop The Rain - 05 - Love Is Alive - 06 - I Ask Of You - 07 - Wishing Well - 08 - Made For Lovin' You - 09 - Black Roses - 10 - Yo Trippin' - 11 - One More Chance - 12 - Some Old Story - - - - - 01 - Get you closer - 02 - Michael caine - 03 - Evil boys - 04 - Pimmelmann - 05 - Und wieder - 06 - Love & fingers - 07 - Pray - 08 - Men in uniform - 09 - Hypnotize - 10 - Der erste Schritt - - - 01 - Devil airlines - 02 - Second front - 03 - Metalhammer - 04 - Menschen - 05 - And one - 06 - Only one - 07 - Crimetime - 08 - Synthetik - 09 - Geld - 10 - Second voice - 11 - Exit - 12 - Anguish - 13 - Deliverance - 14 - Metalhammer (Heavy mix) - - - 01 - Get You Closer (Radio Mix) - 02 - Get You Closer (Club Mix) - 03 - Pimmelmann (Nixmix) - - - 01 - Ego - 02 - Murder murder - 03 - Driving with my darling - 04 - The only guest - 05 - Dein Duft - 06 - It happend last night - 07 - When the feet hurt - 08 - The secret - 09 - Fuer - 10 - Second day - 11 - Body nerv - 12 - Take some more - 13 - Deutschmaschine - 14 - Heart of stone - 15 - Ghama voodoo - 16 - Bonus - - - 01 - Nachtschicht in der hassfabrik - 02 - Teufel oder engel - 03 - Klon mich lieber nicht! - 04 - Maschinenstuermer - 05 - Bedienungsanleitungen - - - 01 - Und dafuer - 02 - Sometimes - 03 - Movie star - 04 - Uns geht's gut - 05 - My warrior - 06 - Creatures - 07 - Sweety sweety - 08 - Schluss mit lustig - 09 - Sitata tirulala - 10 - Friends in heaven - 11 - Mirror in your heart - 12 - Nordhausen - - - 01 - Sometimes (Radio Edit) - 02 - High (Bonus) - 03 - White Doves (Bonus) - 04 - Technoman (Live !) - 05 - Sometimes (Instr.) - 06 - Nordhausen (Album Mix) - - - 01 - Wild pain - 02 - Life isnt easy in germany - 03 - Consequence of time - 04 - Spontanverkehr - 05 - Friend of stars - 06 - Hall of souls - 07 - Recover you - 08 - Der erste Stein - 09 - Tanz der Arroganz - 10 - The and - 11 - Spot - 41 - Wild pain (maxi) - - - 01 - Virgin superstar - 02 - Wasted - 03 - You don't love me anymore - 04 - Goodbye Germany - 05 - Wet spot - 06 - Panzer Mensch - 07 - My story - 08 - Life to lose - 09 - Not the only one - 10 - Don't need the drugs - 11 - Mr Jenka - - - 01 - Wasted (Radio Edit) - 02 - Forever J (Bonus) - 03 - Wasted (Naghavi Mix) - 04 - Maschinenhimmel (Bonus) - 05 - Lawrence Of Arabia (Bonus) - - - - - 01-Track 1 - 02-Track 2 - 03-Track 3 - 04-Track 4 - 05-Track 5 - 06-Track 6 - 07-Track 7 - 08-Track 8 - 09-Track 9 - 10-Track 10 - 11-Track 11 - 12-Track 12 - 13-Track 13 - 14-Track 14 - 15-Track 15 - 16-Track 16 - 17-Track 17 - 18-Track 18 - - - - - 01 - lass uns brennen - 02 - girls in love - 03 - so ist das nun mal - 04 - ab - 05 - allein im park - 06 - das weisst nur du - 07 - du bist da - 08 - blaumeise yvonne - 09 - es ist nur der rauch - 10 - in mich selbst verliebt - 11 - wenn du menschen triffst - 12 - das maedchen auf dem foto - 13 - scheinzahm - - - 01 - girls in love (original version) - 02 - girls in love (grungerman remix) - 03 - girls in love (forever sweet remix) - 04 - singen hoeren - - - 01 - girls in love - 02 - ich weiss es nicht (tegel a23) - 03 - es ist nur der rauch - 04 - ich weiss es nicht - - - 01 - so ist das nun mal - 02 - linda - 03 - so ist das nun mal (mike ink mix) - 04 - so ist das nun mal (reinhard & tobias happy sundays mix) - - - - - 01 - Il giocatore di biliardo - 02 - La comica finale - 03 - Il dito e la luna - 04 - L'ultimo giorno del circo - 05 - Per ogni matematico - 06 - La parola ai mimi - 07 - L'uso dell'amore - 08 - Lamento di un uomo di neve - 09 - La regola del filo a piombo - 10 - Vita quotidana di uno spettro - 11 - La leggenda del collezionista - 12 - Confesso che ho vissuto - - - 01 - il ladro - 02 - Madame - 03 - bella faccia - 04 - uomini di passaggio - 05 - Ballerina - 06 - Amazzonia - 07 - il bambino dei topi - 08 - il tempo di partire - 09 - il grido - 10 - ai confini dell'asia - 11 - Festa - - - 01 - Il Cantico Delle Creature - 02 - Il Sultano Di Babilonia E La Prostituta - 03 - Il Lupo Di Gubbio - 04 - Audite Poverelle - 05 - Divina Commedia - Paradiso, Canto XI - 06 - Il Trattato Dei Miracoli - 07 - Nelle Paludi Di Venezia Francesco Si Fermò Per Pregare E Tutto Tacue - 08 - La Regola - 09 - La Predica Della Perfetta Letizia - 10 - La Morte Di Francesco - 11 - Salmo - - - - - 01 - Nothing at all - 02 - Weltschmerz - 03 - Killing time - 04 - True love tales - 05 - Self destruct - 06 - Out darkness - 07 - The sitting room - 08 - Swimming - 09 - An ordinary life - 10 - Shades - 11 - Short story - 12 - The power game - 13 - All we have to be thankful for - - - Letter Of Thanks To A Friend (club edit) - Letter Of Thanks To A Friend (instrumental edit) - Letter Of Thanks To A Friend (radio edit) - - - 01 - Hardfloor 97 Radio edit - 02 - Hardfloor 97 version - 03 - Total eclipse remix - - - 01 - Heaven - 02 - Red Sands - 03 - Alarm Call - 04 - Tide - 05 - The Interruption - 06 - The Power Game - 07 - World Without Warning - 08 - Bursting - 09 - Lovers Retreat - - - If I could - Our Darkness-2 - Our Darkness - - - At Midnight - Closed Circuit - Come In - Dedication - Echoes Remain Forever - Fragility - Improvisation - Interlude - Journey By Night - Killing Time - So Quiet Here - Swallow Song - That We Have Been Here - The Sitting Room - The Spinning Turning Of The Summer Earth - This Be The Verse - Unstill Life - Windmills Of Your Mind - World Without Warning - - - 01 - Up - 02 - Homecoming - 03 - Red sands - 04 - The power game - 05 - Cane hill - 06 - Leaving - 07 - Heaven - 08 - The last emotion - 09 - Killing time - 10 - Wallies - 11 - Out darkness - 12 - Now - 13 - This be the verse - 14 - Sleeper in metropolis - - - 01 - the sitting room - 02 - swimming - 03 - an ordinary live - 04 - shades - 06 - the power game - 07 - all we have to be thankful - 08 - contact - 09 - sleeper in metropolis - 10 - poem for a nuclear romance - 11 - wallies - 12 - the lovers audition - 13 - poets turmoil no 364 - 14 - echoes remain forever - 15 - all night party - 16 - pandoras box - 17 - feel - 18 - the last emotion - 19 - nothing at all - 20 - true love tales - 21 - self destruct - 23 - weltschmerz - 24 - our darkness remix 12 - x0 - killing time - y0 - for - - - Acropolis - Athens - Dream Made Real - Elegy For A Lost Summer - Letter Of Thanks To A Friend - Mundesley Beach - Painting - The Healing - The Key - Virtuality - - - 01 Anne Clark - Virtuality ( Global Youth Remix ) - 02 Anne Clark - The Healing ( Aural Float Treatment ) - 03 Anne Clark - Sleeper In Metropolis ( Hardfloor 97 Version ) - 04 Anne Clark - Letter Of Thanks To A Friend ( Radi Mate Mix By Mouse On Mars ) - 05 Anne Clark - Nida ( Saafi Bros. Remix ) - 06 Anne Clark - Our Darkness ( Hardfloor 97 Version ) - 07 Anne Clark - Homecoming ( Pascal F.E.O.S. Remix ) - 08 Anne Clark - Sleeper In Metropolis ( Sleepers Revenge Mix by Sven Väth & Ralf Hildenbeutel ) - 09 Anne Clark - Contact ( Contact 2017 Mix by the Mover ) - 10 Anne Clark - Wallies ( Night Of The Hunter Remix By Juno Reactor ) - 11 Anne Clark - Our Darkness ( Total Eclipse Remix ) - - - - - 01 - Radio edit - 02 - Album version - 03 - Instrumental - 04 - It is a shame - - - - - abe - barney2 - barney3 - bart - bfpvny - bush - cfuture - duffy - eckat - fett - feuerste - homer - homer2 - homer3 - homer4 - homer5 - krusty - moe - moe2 - nafzu - ned - nick - prfsimon - roehrich - sexchat - simpson - spd - spd2 - troymc - - - 0190maen - 0190weib - anonym - bettdecke - domina - hotline - otto - peppig - sexchat - sexshop - sigilive - susi3 - telsex - - - 3_schritte - abends - ali - anwalt - baby - bananen - beichte - bleib_ma_dran - boehme - butler - f-prinzp - franzoesisch - friedhof - geld - genervt - heller - hengst - horoskop - hypnose - indianer - inkasso - kind - klh-ende - klhradio - kontonr - lauter - mallorca - mamifix - maschine - maxmanu - mensch - mir - mkp - morgens - nervoes - omm - polizei - privater_anschiss - rezept4 - talent - toupet - versteigerung - werbung - y2kfrau - y2kmann - - - bayer - beatles - chanchan - delasoul - dtkuhn - feschajaga - george - helge2 - howard - kaktus - mouskour - python - python2 - raab - ringdong - ruehmann - schwein - spice - tmwywfm - - - 12oder3 - 24uhr - anschlu2 - arabia - assigned - cutoff - d1_1 - d2_3 - d2_4 - ende - erreicht - gehalten - geschaltet - importan - interoute - japan - kingcall1 - kingcall2 - maschendrahtzaun - mittagspause - nachrich - nica - talkline - tmobil - urlaub - vorwahl - - - bbecker - bbecker2 - brandt - bushkohl - cdu - coolman - faust - gerdschroeder - gerdschroeder2 - gerdschroeder3 - gerdschroeder4 - gott - grizmek3 - halrvord - helge4 - honikohl - kohl - kohl2 - kohl3 - kohl4 - kohlsingt - kork - lndnberg - loddar - loriot - michael - mission - moser - papst2 - ranicki - ranicki2 - scherz - supereh - susi3 - weihnachtsmann - wiebitte - wummwend - - - 3947 - borg - c3po - cluster - dsn - dukat - dukat2 - hansolo - holodoc - janeway - kim2 - kira - kirk - mib - nog - obrien - obrien2 - odo - picard - r2d2 - riker - schatten - sisko - sisko2 - spock - spock2 - tng - tos - uhura - voyager - worfdax - zimmerm - - - ab_lilo_5 - airforc2 - airforce - albundy - alf - alf2 - berti - bestofrichie - bond - bond2 - boning - bully - bvogts - clousea2 - clouseau - conan - ddf - delasoul - drebin - drebins - dtkuhn - duke - elaine - emil - erhardt - george - georgebush - ghostbusters - hartman - helge - helge2 - helge3 - krause - lector - lose - mulder - mulder2 - nypd - ohotte - osterwelle - python3 - python4 - python5 - raab - renegade - richie - richie2 - richie3 - richie4 - richie5 - rockfor2 - rockford - scully - scully2 - scully3 - seinfeld - seth - sigi - smeister - thejade - tnet-box - tooltime - twachter - venkman - ventura - ventura2 - verona - wallace - xfiles - - - - - 01 - Girl Boy (nls mix) - 02 - Milk Man - 03 - Inkey$ - 04 - Girl Boy [£18 snarerush mix] - 05 - Beetles - 06 - Girl Boy [redruth mix] - - - 01 - Acrid Avid Jamshred - 02 - The Waxen Pith - 03 - Wax the Nip - 04 - Icct Hedral (Edit) - 05 - Ventolin (Video Version) - 06 - Come On You Slags - 07 - Start As You Mean To Go On - 08 - Wet Tip Hen Ax - 09 - Mookid - 10 - Alberto Balsam - 11 - Cow Cud Is A Twin - 12 - Next Heap With - - - 01 - .215061 - 02 - .1993841 - 03 - .0180871R - 04 - .942937 - 05 - .0180871L - 06 - .000890569 - 07 - .55278037732581 - 08 - (CAT 00897-AA1) - 09 - (CAT 00897-A1) - 10 - AFX 6-B - 11 - (CD Only Track #1) - 12 - (CD Only Track #2) - 13 - (CAT 00897-A2) - - - 01 - Digeridoo - 02 - Flaphead - 03 - Phloam - 04 - Isopropanol - 05 - Polynomial-C - 06 - Tamphex (Hedphuq Mix) - 07 - Phlange Phace - 08 - Dodeccaheedron - 09 - Analogue Bubblebath 1 - 10 - Metapharstic - 11 - We have arrived (Aphex Twin QQT Mix) - 12 - We have arrived (Aphex Twin TTQ Mix) - 13 - Digeridoo (Live in Cornwall, 1990) - - - 01 - Come To Daddy, Pappy Mix - 02 - Flim - 03 - Come To Daddy, Little Lord Faulteroy Mix - 04 - Bucephalus Bouncing Ball - 05 - To Cure A Weakling Child, Contour Regard - 06 - Funny Little Man - 07 - Come To Daddy, Mummy Mix - 08 - IZ-US - - - 01 - Donkey Rhubarb - 02 - Vaz Deferenz - 03 - Icct Hedral (Philip Glass Orchestration) - 04 - Pancake Lizard - - - 01 - Mr. Frosty - 02 - Jelly Fish - 03 - Eggy Toast - 04 - Reg - 05 - Vodka - 06 - Winner Takes All - 07 - Giant Deflating Football - 08 - Upright Kangaroo - 09 - The Sound of Beady Eyes - 10 - Bu Bu Bu Ba - - - 01 - on - 02 - 73-yips - 03 - d-scape - 04 - xepha - - - 01 - d-scape mix - 02 - reload mix - 03 - mu-ziq mix - 04 - 28 mix - - - 01 - Quoth (Original) - 02 - Iketa - 03 - Quoth (Wooden Thump Mix) - 04 - Bike Pump Meets Bucket - 05 - (Unlisted) - - - 01 - Polygon Window - 02 - Audax Powder - 03 - Quoth - 04 - If It Really Is Me - 05 - Supremacy II - 06 - UT1 - dot - 07 - -no title- - 08 - Quixote - 09 - Quino-phec - - - 01 - 4 - 02 - Cornish Acid - 03 - Peek 824545201 - 04 - Fingerbib - 05 - Corn Mouth - 06 - To Cure A Weakling Child - 07 - Goon Gumpas - 08 - Yellow Calx - 09 - Girl-Boy Song - 10 - Logon Rock Witch - - - 01 - Xtal - 02 - Tha - 03 - Pulsewidth - 04 - Ageispolis - 05 - i - 06 - Green Calx - 07 - Heliosphan - 08 - We are the Music Makers - 09 - Schottkey 7th Path - 10 - Ptolemy - 11 - Hedphelym - 12 - Delphium - 13 - Actium - - - 01 - Cliffs - 02 - Radiator - 03 - Rhubarb - 04 - Hankie - 05 - Grass - 06 - Mold - 07 - Curtains - 08 - Blur - 09 - Weathered stone - 10 - Tree - 11 - Domino - 12 - White blur 1 - - - 01 - Ventolin (Salbutamol Mix) - 02 - Ventolin (Praze-An-Beeble Mix) - 03 - Ventolin (Marazanvose Mix) - 04 - Ventolin (Plain-An-Gwarry Mix) - 05 - Ventolin (The Coppice Mix) - 06 - Ventolin (Crowsmengegus Mix) - - - 01 - Ventolin (wheeze mix) - 02 - Ventolin CARHARRACK mix - 03 - Ventolin PROBUS mix - 04 - Ventolin (cylob mix) - 05 - Ventolin (deep gong mix) - 06 - Ventolin (asthma beats mix) - - - - - 01 (Aphrodite) - Aphromoods - 02 (Amazon II) - King Of The Beats - 03 (Aladdin) - Woman That Rolls! - 04 (Aphrodite) - Spice (Of The Gods Remix) - 05 (Aladdin) - Summer Breeze - 06 (Amazon II) - Music's Hypnotising - 07 (Aphrodite (Vortex Mix)) - Listen To The Rythm - 08 (Aphrodite) - Dub Moods (The Greatest Trick) - 09 (Aphrodite) - Style From The Dark Side - 10 (Aphrodite) - Tower Bass! - 11 (Aphrodite feat. Gail Mclean) - I Wanted It More And - 12 (Aphrodite) - Sweet Mind - - - - - 01 - Sealth Overture - 02 - Ain't Talkin' 'Bout Dub - 03 - Altamont Super-Highway Revisted - 04 - Electro Glide In Blue - 05 - Vanishing Point - 06 - Tears Of The Gods - 07 - Carrera Rapida - 08 - Krupa - 09 - White Man's Throat!s - 10 - Pain In Any Language - 11 - Stealth Mass In F#m!s - - - 01 - Are we a rock band or what - 02 - Stop the rock - 03 - Crazee Horse - 04 - Cold Rock the Mic - 05 - Lost in Space (Theme) - 06 - For forty days - 07 - Heart Go Boom - 08 - The Machine in the ghost - 09 - Blackbeat - 10 - Stadium parking lot - 11 - YO, Future - 12 - High on your own supply - 13 - The Perfect crime - - - 02 - Liquid Cool - 03 - Film Me And Finish Me Off - 04 - I Need Something Stronger - 05 - Pain Is A Close Up - 06 - Omega Point - 07 - Don't Fear The Reaper - 08 - Astral Amerika - 09 - Millennium Fever - 10 - Stealth Requiem - - - - - 01 - Love Never Dies, Part I - 02 - Mourn - 03 - Non-Stop Violence - 04 - 25 Cromwell St. - 05 - Rebel - 06 - Deep Red - 07 - Nearer - 08 - Half Asleep - 09 - Love Never Dies, Part II - - - 01_-_Kathy's_Song_(Ferry_Corsten_RMX) - 02_-_Kathy's_Song_(Single_version) - 03_-_Kathy's_Song_(Victoria_mix_by_VNV_Nation) - 04_-_Kathy's_Song_(Beborn_Beton_RMX) - 05_-_Kathy's_Song_(Ferry_Corsten_RMX)(12-_version) - 06_-_Kathy's_Song_(C-64_version) - - - 01 - Mourn (APB Remix) - 02 - Mourn (Ihrmx) - 03 - Mourn (Original Version) - 04 - Untitled Too (Sweep remix) - 05 - Ohm Sweet Ohm - 06 - Electricity - 07 - Snutt 7 - - - 01 - Non-Stop Violence [CNN version] - 02 - Near [Banilla Dream version] - 03 - Burnin' Heretic [Live] - - - 01 - Like Blood From The Beloved (part 1) - 02 - Bitch - 03 - Burnin Heretic (album version) - 04 - Stich - 05 - Walk With Me - 06 - Backdraft - 07 - Arp (808 edit) - 08 - Spiritual Reality - 09 - Skyscraping (schizophreniac) - 10 - All Tomorrows Parties - 11 - The Sentinel - 12 - Ashes To Ashes `93 - 13 - Like Blood From The Beloved (part 2) - - - 01 - Apb goes C-64 - 02 - Deep Red - 03 - Bitch - 04 - Stitch - 05 - Spiritual Reality - 06 - Electronic Warfare - 07 - All Tomorrows Parties - 08 - Arp - 09 - Burnin´ Heretic (Album version) - 10 - Ledelsens Mening - 11 - Backdraft - 12 - Ashes to Ashes (German Slam version) - 13 - The Approach of Death - 14 - Ashes to Ashes (Original 12- version) - 15 - Wrack´em to Pieces - 16 - Burning Heretics (Crisp version) - - - 01 - Everything We Know Is Wrong - 02 - Starsign - 03 - Eclipse - 04 - Help Me - 05 - Kathy's Song (Come Lie Next To Me) - 06 - Untiled 3 - 07 - Moment Of Tranquililty - 08 - Fade To Black - 09 - 64K - 10 - Paranoia - 11 - Soultaker - 12 - LNDP 3 - 13 - Time To Move On + Bonus (ABP Goes C-64 Again) - - - - - 01 Aretha Franklin - Freeway Of Love - 02 Aretha Franklin - I Knew You Were Waiting - 03 Aretha Franklin - Jump To It - 04 Aretha Franklin - Willing To Forgive - 05 Aretha Franklin - Doctor's Orders - 06 Aretha Franklin - United Together - 07 Aretha Franklin - Who's Zoomin' Who - 08 Aretha Franklin - A Deeper Love - 09 Aretha Franklin - Honey - 10 Aretha Franklin - Get It Right - 11 Aretha Franklin - Another Night - 12 Aretha Franklin - Ever Changing Times - 13 Aretha Franklin - Jimmy Lee - 14 Aretha Franklin - You Make Me Feel - 15 Aretha Franklin - I Dreamed A Dream - 16 Aretha Franklin - Jumpin' Jack Flash - - - - - SN1B6208B_Trk01A - SN1B6208B_Trk02A - SN1B6208B_Trk03A - SN1B6208B_Trk04A - SN1B6208B_Trk05A - SN1B6208B_Trk06A - SN1B6208B_Trk07A - SN1B6208B_Trk08A - SN1B6208B_Trk09A - SN1B6208B_Trk10A - SN1B6208B_Trk11A - SN1B6208B_Trk12A - SN1B6208B_Trk13A - SN1B6208B_Trk14A - - - - - 01 - Adoro - 02 - Somos novios - 03 - Cuando estoy contigo - 04 - Pensando en ti - 05- Contigo amor - 06 - Cariño mio - 07 - Yo te quiero - 08 - Esta tarde vi llover - 09 - Voy a apagar la luz - 10 - Contigo aprendi - 11 - No - 12 - Esperare - 13 - Pero te extraño - 14 - Me vas a recordar - 15 - Mia - - - - - (01).im.wagen.vor.mir - (02).ferien.auf.dem.bauernhof - (03).das.frivole.wiedersehen - (04).spermadin - - - 02 - No Man's Land - - - - - 16 - Poppen muss Spass machen - 19 - Der Ausdenker - 17 - Heiligabend - 15 - Drei Eier - 18 - Gertrud ist abgerissen - 12 - Einbruch bei Gertrud - In der Haseluenner Lubjanka - 13 - Einbruch bei Gertrud - Die Verhandlung - 14 - Oeffentlicher Nahverkehr - 10 - Ruesselwaesche - 11 - Einbruch bei Gertrud - Gertrud hat noch zu - 09 - Schneeraeumen am Arsch - 08 - Oedipus Kurt - 01 - Ferkel nervt - 02 - Arschkrampen im Krieg - Der Kessel von Goebelgrad - 03 - Arschkrampen im Krieg - Der 7 Mai 1945 - 04 - Arschkrampen im Krieg - Nacht ueber Gotenhafen - 05 - Es plaestert - 06 - Pflaumen pfluecken - 07 - Weitstrullen - - - 19 - Kampfruf des Negers - 02 - Die alte Kultur - 08 - Schwanzmessen - 20 - Die Leguane greifen an - 01 - Was hier denn los - 18 - Schluepfer rasseln in Fickstadt - 05 - Am Tag als der Leguan - 03 - Entfuehrer und Enthueller - 04 - Wie gehts eigentlich Praenki - 21 - Erste Kritik - 07 - Excusez-moi - 06 - Zu den Quellen des Amazonas - 09 - Gelegenheit zum Gespraech - 13 - Gehts Praenki besser - 16 - Praenki is kaputt - 14 - An den Ufern des Urinoko - 15 - Zicken her - 12 - Eckis Plattentip - 11 - Brettermeier duebelt - 10 - Goebelblanca - 17 - Feuchte BIRAFO - - - 04 - Brettermeier (Karaoke Version) - 03 - Brettermeier (Radio Version) - 02 - 18 Bier mit Tsatsiki - 01 - Brettermeier die Pottsau - - - 02 - Der kleine Pisser - 03 - Die Alpen - 01 - Damals in der Bretterpenne - 04 - Gedichte - 10 - Telephonsex - 09 - Bluemel und Laesch - 12 - Gurkenrost - 11 - Groehlen un Suppe - 16 - Jingle - Arschkrampenzeit - 15 - Arschregen - 14 - Kurtin - 13 - Cassette im Arsch - - - 01 - Ich bin ein Ferkelwaemser - 05 - Der Iwan is nich ohne - 03 - Allegorie ueber Stalingrad - 02 - Frauen stehen auf Macht - 04 - Der Negerueberfall - 06 - Hier Bretter-Control - 07 - Goebel-Solo - 08 - Kurt is in Kur - 20 - Absage - 17 - Kurt im Schrank - 19 - Gertrud hat zu - 09 - Guergen erinnert sich - 10 - Der Tomatenkopp - 16 - Ab inne Truhe - 12 - Der Gammel - 15 - Gesucht wird Albert Brettermeier - 11 - Kurt Kong - 13 - Bei Gertrud - 18 - Kurt hat Geburtstag - 14 - Wir fahn nach Wakaluba - - - 01 - Stracciatella - 22 - Die letzte Folge - 21 - Ferkels Schwester - 20 - Hier spricht Ramke - 16 - Wuggi baut um - 14 - Zasta Krockett der verwarzte Rochen - 15 - Die Ex-Verlobte - 17 - Robinson Kurt - 11 - dammte Pekinesenkotze - Telephon - 13 - Wischmeyer ruft an - 19 - Reingeroemert - 18 - Der grosse Hatti Mueller - 02 - The Making of Arschkrampen - 03 - Der Vollidiot - 04 - Geheimagent Ferkel - 05 - Die Hackfresse - 06 - Die Kimmen der Adler - 07 - Schrappige Zicken - 08 - Wie gehzn Wuggi - 09 - Kurt will heiraten 1 - Krissa die Hundekopffegerin - 10 - Kurt will heiraten 2 - Der Hochzeitstag - 12 - Kurt will heiraten 3 - Die Vermaehlung - - - - - 01 - Madagasca - 02 - Madagasca Cygnus X Remix - - - 01 - Breathe - 02 - Monsoon - 03 - The Hummer - 04 - Madagascar - 05 - Requiem - 06 - Dud UK - 07 - Easter Island - 08 - Stealth - 09 - Panorama - 10 - Voice Of Earth - - - - - 01 - Movin Too Fast - Radio Mix - 02 - Movin Too Fast - Bump & Flex Vocal - 03 - Movin Too Fast - Pussy 2000 Vocal - - - Re-Rewind - The artful dodger - - - 01 - woman trouble (radio edit) - 02 - woman trouble (original version radio edit) - 03 - woman trouble (sunkids future discotech edit) - 04 - woman trouble (wideboy's pickapocket or two radio edit) - - - - - 01 - The Dice Man - Polygon Window - 02 - Musicology - Telefone 529 - 03 - Autechre - Crystel - 04 - I.A.O - The Clan - 05 - Speedy J - De-Orbit - 06 - Musicology - Preminition - 07 - UP! - Spiritual High - 08 - Autechre - The Egg - 09 - Speedy J - Fill 3 - 10 - Dr Alex Paterson - Loving You Live - - - 01 - Mark Franklin - Release to the System - 02 - The Higher Intelligence Agency - Selinite - 03 - Link - Arcadian - 04 - B12 - Scriptures - 05 - Autechre - Chatter - 06 - Speedy J - Symmetry - 07 - Beaumont Hannant - Utuba - 08 - Richard H. Kirk - Reality Net - 09 - Balil - Parasight - 10 - Seefeel - Spangle - - - - - 01 - Sick And Beautiful Radio Edit - 02 - Sick And Beautiful Quick Fix Mix - 03 - My Heaven - - - - - 01 - Track 1 - 02 - Track 2 - 03 - Track 3 - 04 - Track 4 - 05 - Track 5 - 06 - Track 6 - 07 - Track 7 - 08 - Track 8 - 09 - Track 9 - 10 - Track 10 - 11 - Track 11 - 12 - Track 12 - - - 01 - Track 1 - 02 - Track 2 - 03 - Track 3 - 04 - Track 4 - 05 - Track 5 - 06 - Track 6 - 07 - Track 7 - 08 - Track 8 - 09 - Track 9 - 10 - Track 10 - 11 - Track 11 - 12 - Track 12 - 13 - Track 13 - 14 - Track 14 - 15 - Track 15 - 16 - Track 16 - 17 - Track 17 - 18 - Track 18 - - - - - 01 - naxalite - 02 - buzzin' - 03 - black white - 04 - assassin - 05 - hypocrite - 06 - charge - 07 - free satpal ram - 08 - dub mentality - 09 - culture move - 10 - operation eagle lie - 11 - change - 12 - tribute to john stevens - - - - - 01 - The Fields Of Love Airplay Mix - 02 - The Fields Of Love Original Club Mix - 03 - The Fields Of Love York Remix - 04 - The Fields Of Love Instrumental - - - 01 - Aiplay mix - 02 - Clubb mix - 03 - Instrumental clubb mix - 04 - Ibiza influence mix - - - - - AudioTrack 01 - AudioTrack 02 - AudioTrack 03 - AudioTrack 04 - AudioTrack 05 - AudioTrack 06 - AudioTrack 07 - AudioTrack 08 - AudioTrack 09 - AudioTrack 10 - AudioTrack 11 - AudioTrack 12 - - - AudioTrack 01 - AudioTrack 02 - AudioTrack 03 - AudioTrack 04 - AudioTrack 05 - AudioTrack 06 - AudioTrack 07 - AudioTrack 08 - AudioTrack 09 - AudioTrack 10 - AudioTrack 11 - AudioTrack 12 - AudioTrack 13 - AudioTrack 14 - AudioTrack 15 - - - AudioTrack 01 - AudioTrack 02 - AudioTrack 03 - AudioTrack 04 - AudioTrack 05 - AudioTrack 06 - AudioTrack 07 - AudioTrack 08 - AudioTrack 09 - AudioTrack 10 - AudioTrack 11 - AudioTrack 12 - AudioTrack 13 - AudioTrack 14 - AudioTrack 15 - AudioTrack 16 - AudioTrack 17 - AudioTrack 18 - - - AudioTrack 01 - AudioTrack 02 - AudioTrack 03 - AudioTrack 04 - AudioTrack 05 - AudioTrack 06 - AudioTrack 07 - AudioTrack 08 - AudioTrack 09 - AudioTrack 10 - AudioTrack 11 - - - AudioTrack 01 - AudioTrack 02 - AudioTrack 03 - AudioTrack 04 - AudioTrack 05 - AudioTrack 06 - AudioTrack 07 - AudioTrack 08 - AudioTrack 09 - AudioTrack 10 - AudioTrack 11 - AudioTrack 12 - AudioTrack 13 - AudioTrack 14 - AudioTrack 15 - AudioTrack 16 - AudioTrack 17 - AudioTrack 18 - - - AudioTrack 01 - AudioTrack 02 - AudioTrack 03 - AudioTrack 04 - AudioTrack 05 - AudioTrack 06 - AudioTrack 07 - AudioTrack 08 - AudioTrack 09 - AudioTrack 10 - - - AudioTrack 01 - AudioTrack 02 - AudioTrack 03 - AudioTrack 04 - AudioTrack 05 - AudioTrack 06 - AudioTrack 07 - AudioTrack 08 - AudioTrack 09 - AudioTrack 10 - - - AudioTrack 01 - AudioTrack 02 - AudioTrack 03 - AudioTrack 04 - AudioTrack 05 - AudioTrack 06 - AudioTrack 07 - AudioTrack 08 - AudioTrack 09 - AudioTrack 10 - AudioTrack 11 - - - AudioTrack 01 - AudioTrack 02 - AudioTrack 03 - AudioTrack 04 - AudioTrack 05 - AudioTrack 06 - AudioTrack 07 - AudioTrack 08 - - - - - 01 - Peel Session - 02 - Peel Sesion - 03 - Peel Sesion - - - - - 01 - Radio mix - 02 - Extended mix - 03 - Club mix - 04 - Atmosphere mix - - - - - (01) Radio Version - (02) Extended Mix - (03) Extended Track Masters Remix - (04) Original Instrumental - - - - - 01 - Riding With The King - 02 - Ten Long Years - 03 - Key To The Highway - 04 - Marry You - 05 - Three O'Clock Blues - 06 - Help The Poor - 07 - I Wanna Be - 08 - Worried Life Blues - 09 - Days Of Old - 10 - When My Heart Beats Like A Hammer - 11 - Hold On I'm Coming - 12 - Come Rain Or Come Shine - - - - - 01 - Animal Army - 02 - Spaceman - 03 - Zodiac Sign - 04 - Paris Green - 05 - Confused Art - 06 - Caffeine - 07 - The Boy With The X-Ray Eyes - 08 - Don't Feed The Animals - 09 - Fire Guided Light - 10 - Is Your Soul For Sale - 11 - I'm Cracking Up I Need A Pill - - - - - (There's) Always Something There To Remind Me - Sandie Shaw - (They Long To Be) Close To You - Isaac Hayes - A House Is Not A Home - Luther Vandross - Anyone Who Had A Heart - Luther Vandross - Arthur's Theme (Best That You Can Do) - Christopher Cross - I Just Don't Know What To Do With Myself - Dusty Springfield - I Say A Little Prayer - Aretha Franklin - I'll Never Fall In Love Again - Bobby Gentry - Make It Easy On Yourself - The Walker Brothers - Reach Out For Me - Dionne Warwick - The Look Of Love - Dusty Springfield - This Guy's In Love With You - Burt Bacharach - Trains And Boats And Planes - Billy J Kramer & The Dakotas - Walk On By - Dionne Warwick - What The World Needs Now Is Love - Jackie De Shannon - Windows Of The World - The Pretenders - You'll Never Get To Heaven (If You Break My Heart) - The Stylistics - - - - - 01 - Lady In Black (Radio Edit) - 02 - Come Back And Stay - 03 - Gimme, Gimme Your Lovin' (Little Lady) - 04 - Hungry For Love (Radio Edit) - 05 - Don't Walk Away, Suzanne - 06 - L.O.V.E. In My Car - 07 - You're A Woman - 08 - A World Without You (Michelle) - Radio Edit - 09 - I Wanna Hear Your Heartbeat (Sunday Girl) - 10 - Pretty Young Girl - 11 - Kisses And Tears (My One And Only) - 12 - Love Really Hurts Without You - 13 - Lovers In The Sand - 14 - Kiss You All Over, Baby (New Version) - 15 - Hot Girls - Bad Boys - 16 - One Night In Heaven - 17 - Baby I Love You - 18 - Love Is No Crime - 19 - Inside Of Me - - - - - 01 - The Gray Race - 02 - Them And Us - 03 - A Walk - 04 - Parallel - 05 - Punk Rock Song - 06 - Empty Causes - 07 - Nobody Listens - 08 - Pitty The Dead - 09 - Spirit Shine - 10 - The Streets Of America - 11 - Ten In 2010 - 12 - Victory - 13 - Drunk Sincerity - 14 - Come Join Us - 15 - Cease - 16 - Punk Rock Song (In German) - - - - - 01 - Weckruf - 02 - I want your Sex - 03 - Papa - 04 - Bako - 05 - Hassi Janes - 06 - Operation - 07 - In der Waschanlach - 08 - Sound - 09 - Was glaubst du - 10 - German Music - 11 - Papa - 12 - Immer schlimmer - 13 - Lichterkette - 14 - Thomas und Heidi - 15 - Dixi-Band - 16 - Bubblegum-Time - 17 - Richie und Headbanger - 18 - Schwarz und Weiß - 19 - 6,50 Sicherheitsgebühr - 20 - Gesang - 21 - Wahltag - 22 - Mabadaja Mabadaga ja - 23 - Megabreit Computerdeppen - 24 - Papa - 25 - Neschperblues - 26 - Revolte in der Schule - 27 - Bongo Karl - 28 - Babu - 29 - Gereizt - 30 - Parfüm - 31 - Halleluja - 32 - Papa - 33 - Superdepp - 34 - Dialog - 35 - Belgische Äpfel - 36 - Dressur - - - 01 - viel zu harmlos - 02 - handy song - 04 - tamagotchi - 05 - wetzlar - 06 - der erste kontakt - 07 - versprochen - 08 - gianni - 09 - pappa vol.17 - 10 - ying und yang - 11 - styling - 12 - kasperle gegen drogen - 13 - der spanische apotheker - 14 - gute argumente - 15 - session - 16 - nachdenklichkeit - 17 - naturschauspiel - 18 - schmusebär - 19 - hobbies - 20 - bali mach uff! - 21 - was war das... - 22 - der kunde ist könig - 23 - jazz - 24 - pappa vol.18 - 25 - die hochzeit - 26 - der neue star - 27 - route 66 - 28 - ziegenkäsegeschäft - 29 - mutter und tochter - 30 - alle jahre wieder - 31 - besorgt - 32 - kreuzworträtsel - 33 - sensibilität - 34 - die wahrscheinlichkeit - 35 - f.e.v.a - 36 - private geheimnisse - 37 - back for good (leider live) - - - 01 - Zarte Metzger - 02 - Jesu S. - 03 - Seelachs - 04 - Aufgespürt - 05 - Fitneß-Tom - 06 - Der Brautstrauß - 07 - Der Rollo - 08 - Pappa Vol. 15 - 09 - Zivilcourage - 10 - Kamm tugesser - 11 - Tobias - 12 - Radlacka - 13 - Kevin Costner - 14 - Moderne Väter - 15 - 0190634 . . . - 16 - Dabrauchemergarnetdrübberredde - 17 - Stones-Revival-Revival - 18 - Weichei - Das Musical 1. Akt - 19 - Themenabend - 20 - Song für Witta Pohl - 21 - Herr Seiler - 22 - Duell bei Hanau 1420 (Orginal-Aufnahme) - 23 - Pappa Vol. 16 - 24 - Kippen holen - 25 - Wie bei Axel - 26 - Die Demo - 27 - Sin kaa breetsche da - 28 - Natur - 29 - Die Gaby und Ich - 30 - Glück gehabt - 31 - Weichei - Das Musical 3. Akt - 32 - Der Wettkönig - 33 - Waldfest - 34 - Tierfreunde - 35 - Der australische Freund - 36 - Du - - - - - 01-Intro - 02-Word Play - 03-Spontaneity - 04-Rugged ruff - 05-Interlude - 06-I confess - 07-UKNOWHOWWEDU - 08-Interlude - 09-Total wreck - 10-Innovation - 11-Da jawn - 12-Interlude - 13-True honey buns (dat freak sht) - 14-3 tha hard way - 15-Biggest part of me - 16-Path to rhythm - - - - - 1 - Spirit of the forest - 2 - The man who danced too slowly - 3 - Ngombi - 4 - Baka play baka - 5 - Nahwia - 6 - Eeya be - 7 - Canya Jam - 8 - Bounaka - - - diff --git a/contrib/retep/retep.jpx b/contrib/retep/retep.jpx deleted file mode 100644 index dcf68ac8ce..0000000000 --- a/contrib/retep/retep.jpx +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/contrib/retep/uk/org/retep/dtu/DCollection.java b/contrib/retep/uk/org/retep/dtu/DCollection.java deleted file mode 100644 index e97fc067c4..0000000000 --- a/contrib/retep/uk/org/retep/dtu/DCollection.java +++ /dev/null @@ -1,228 +0,0 @@ -package uk.org.retep.dtu; - -import uk.org.retep.xml.core.XMLFactory; -import uk.org.retep.xml.core.XMLFactoryException; - -import java.io.IOException; -import java.util.Collection; -import java.util.Iterator; - -public class DCollection implements Collection -{ - protected int num,max,inc; - - protected DElement elements[]; - - public DCollection() - { - this(10); - } - - public DCollection(int aIncrement) - { - num=0; - max=0; - inc=aIncrement; - elements=null; - } - - protected void resize() - { - if(num>=max) { - max+=inc; - DElement n[] = new DElement[max]; - if(elements!=null) { - System.arraycopy(elements,0,n,0,elements.length); - } - elements=n; - } - } - - public int size() - { - return num; - } - - public boolean isEmpty() - { - return (num==0); - } - - /** - * Checks the list using it's XML id. - */ - public synchronized boolean contains(Object parm1) - { - if(parm1 instanceof DElement) { - DElement e = (DElement) parm1; - int ei = e.getID(); - - // out of range? - if(ei<0 || ei>=num) - return false; - - return elements[ei].equals(e); - } - - return false; - } - - public Iterator iterator() - { - return new iterator(this); - } - - /** - * Inner class to implement an Iterator - */ - protected class iterator implements Iterator - { - protected DCollection c; - protected int i; - - public iterator(DCollection aCollection) - { - c=aCollection; - i=0; - } - - public boolean hasNext() - { - return i-1) { - return false; - } - - // Add to the Collection - resize(); - e.setID(num); - elements[num++] = e; - return true; - } - return false; - } - - public synchronized boolean remove(Object parm1) - { - if(parm1 instanceof DElement) { - DElement e = (DElement) parm1; - int ei = e.getID(); - if(ei<0 || ei>=num) - return false; - - // Mark the node as parentless - e.setID(-1); - - // Now remove from the array by moving latter nodes, fixing their ids - // in the process - for(int j=ei,k=ei+1;k=num) - return null; - - return elements[id]; - } - - /** - * Repairs the collection, ensuring all id's are correct - */ - public synchronized void repair() - { - for(int i=0;iNB: args is volatile, so if you use it beyond the lifetime of - * this call, then you must make a copy of the HashMap (and not use simply - * store this HashMap). - * @param level The number of tags above this - * @param tag The tag name - * @param args A HashMap of any arguments - */ - public void tagStart(int level,String tag,HashMap args) - { - Logger.log(Logger.DEBUG,"DModuleXML.tagStart",tag); - - // Prefetch some common attributes - String sType = (String) args.get(DConstants.XML_TYPE); - String sX = (String) args.get(DConstants.XML_X); - String sY = (String) args.get(DConstants.XML_Y); - - int type=-1,x=-1,y=-1; - - if(sType!=null) { - type = Integer.parseInt(sType); - } - - if(sX!=null) { - y = Integer.parseInt(sX); - } - - if(sY!=null) { - x = Integer.parseInt(sY); - } - - // Match the tag against the tags array (used for switch() ) - int tagID=T_DEFAULT; - for(int i=0;iNB: content is volatile, so you must copy its contents if you use - * it beyond the lifetime of this call. - * @param content CharArrayWriter containing the content of the tag. - */ - public void tagContent(CharArrayWriter content) - { - // Ignore - } - - public void fixTransforms() - { - DNode to; - Iterator it = txmap.iterator(); - - while(it.hasNext()) { - tx x = (tx) it.next(); - - //Logger.log(Logger.DEBUG,"Fixing transform "+x.toID,x.transform,Integer.toString(x.node.getID()),Integer.toString(module.getNode(x.toID).getID())); - to = module.getNode(x.toID); - - x.transform.setFrom(x.node); - x.transform.setTo(to); - //to.setFrom(x.transform); - } - - } - - /** - * Parse an InputSource and return the contained module. - * @return DModule loaded, null if the xml file does not contain a module. - */ - public DModule parse(InputSource is) - throws IOException,SAXException - { - getTagHandler().parse(is); - fixTransforms(); - return module; - } - - /** - * Parse an uri and return the contained module. - * @return DModule loaded, null if the xml file does not contain a module. - */ - public DModule parse(String uri) - throws IOException,SAXException - { - getTagHandler().parse(uri); - fixTransforms(); - return module; - } - - /** - * Debug test - read xml from one file and save to another. - */ - public static void main(String args[]) throws Exception - { - if(args.length!=2) { - System.err.println("Syntax: java DModuleXML in-file out-file"); - System.exit(1); - } - - Logger.setLevel(Logger.DEBUG); - - Logger.log(Logger.INFO,"DModuleXML Read test1.xml"); - DModuleXML dm = new DModuleXML(); - DModule module = dm.parse(new InputSource(new FileInputStream(args[0]))); - - Logger.log(Logger.INFO,"Parse complete"); - - Logger.log(Logger.INFO,"DModuleXML Write XML"); - FileWriter fw = new FileWriter(args[1]); - module.saveXML(new XMLFactory(fw)); - fw.close(); - Logger.log(Logger.INFO,"Write complete"); - - DProcessor.run(module); - } -} \ No newline at end of file diff --git a/contrib/retep/uk/org/retep/dtu/DNode.java b/contrib/retep/uk/org/retep/dtu/DNode.java deleted file mode 100644 index 7a8321741c..0000000000 --- a/contrib/retep/uk/org/retep/dtu/DNode.java +++ /dev/null @@ -1,233 +0,0 @@ -package uk.org.retep.dtu; - -import uk.org.retep.util.Logger; -import uk.org.retep.xml.core.XMLFactory; -import uk.org.retep.xml.core.XMLFactoryException; - -import java.io.IOException; -import java.io.Serializable; -import java.util.Iterator; - -/** - * This is the base class for all nodes. - */ -public class DNode implements DElement, Serializable -{ - // The id of this node - protected int id; - - // The type of this node - protected int type; - - protected int x,y; - - public static final int OK = 0; // Node last ran fine - public static final int ERROR = 1; // Node failed on last run - - /** - * This type of node does nothing - */ - public static int NOP = 0; // No action - - public DNode() - { - this(NOP); - } - - public DNode(int aType) - { - id=-1; - type=aType; - - // Init the transform linkage - mf=mt=5; - nf=nt=0; - fn = new DTransform[mf]; - tn = new DTransform[mt]; - - Logger.log(Logger.DEBUG,"new DNode"); - } - - public int getID() - { - return id; - } - - public void setID(int aID) - { - id=aID; - Logger.log(Logger.DEBUG,"DNode.setID",aID); - } - - public int getType() - { - return type; - } - - public void setType(int aType) - { - type=aType; - Logger.log(Logger.DEBUG,"DNode.setType",aType); - } - - /** - */ - public void saveXML(XMLFactory aFactory) - throws IOException, XMLFactoryException - { - Logger.log(Logger.DEBUG,"DNode.saveXML start",this); - Iterator it; - - aFactory.startTag(DConstants.XML_NODE); - aFactory.addAttribute(DConstants.XML_ID,new Integer(getID())); - aFactory.addAttribute(DConstants.XML_TYPE,new Integer(getType())); - - // used for display only - aFactory.addAttribute(DConstants.XML_X,new Integer(getX())); - aFactory.addAttribute(DConstants.XML_Y,new Integer(getY())); - - // Save the transforms here (only the from list required) - for(int i=0;i=mf) { - mf+=5; - DTransform nn[] = new DTransform[mf]; - System.arraycopy(fn,0,nn,0,nf); - fn=nn; - } - fn[nf++]=aTransform; - } - - /** - * Adds a transform to this node (called by DTransform) - */ - protected synchronized void setTo(DTransform aTransform) - { - for(int i=0;i=mt) { - mt+=5; - DTransform nn[] = new DTransform[mt]; - System.arraycopy(tn,0,nn,0,nt); - tn=nn; - } - tn[nt++]=aTransform; - } - - /** - * Removes a transform (called by DTransform) - */ - protected synchronized void removeFrom(DTransform aTransform) - { - for(int i=0;i0) { - int numThreads = group.activeCount(); - Thread threads[] = new Thread[numThreads]; - cnt = group.enumerate(threads,false); - - //Logger.log(Logger.DEBUG,"Waiting on threads",cnt); - while(cnt>0) { - //Logger.log(Logger.DEBUG,"Waiting on thread",cnt); - threads[--cnt].join(timeout); - } - - Logger.log(Logger.DEBUG,"All threads appear to have died, retesting"); - } - } catch(InterruptedException ie) { - Logger.log(Logger.ERROR,"DProcessor, exception caught while waiting for threads to die",ie); - } - - // finally close any open datasources - Logger.log(Logger.DEBUG,"DProcessor cleanup"); - - Logger.log(Logger.DEBUG,"DProcessor finished"); - } - - class proc implements Runnable - { - protected DModule module; // The module being run - protected DNode pc; // current Program Counter - - protected DEnvironment env; // Shared environment - - // Used when launching new threads only - protected DTransform trans; // If not null, a transform to run first - protected int status; - - protected Thread thread; - - /** - * Start processing from DNode aNode. This is called by DProcessor at - * initialisation only. - */ - protected proc(ThreadGroup aGroup,DModule aModule,DNode aNode,DEnvironment aEnv) - { - // aGroup will be null when forking... - if(aGroup==null) { - thread = new Thread(this); - } else { - thread = new Thread(aGroup,this); - } - - module = aModule; - pc = aNode; - env = aEnv; - } - - /** - * Start processing the DTransform aTransform from aNode (does not execute - * the node). This is called by this inner class itself when forking new - * threads. - */ - protected proc(DModule aModule,DNode aNode,DEnvironment aEnv,DTransform aTransform,int aStatus) - { - this(null,aModule,aNode,aEnv); - trans = aTransform; - status = aStatus; - } - - /** - * Start this thread - */ - public void start() - { - thread.start(); - } - - public void run() - { - // Handle an initial transform first. It's used when a new Thread was created. - if(trans!=null) { - transform(trans,false,status); - trans=null; - } - - while(pc!=null) { - //Logger.log(Logger.DEBUG,"running node ",pc.getID()); - - // Process the node - int status = pc.run(env); - //Logger.log(Logger.DEBUG," status ",status); - - // Now the transforms. This thread continues with the first one that runs, - // but any others that will also run will do so in their own thread. - // If no transform runs (or there are none), then the thread will die. - int numTrans = pc.getToTransforms(); - boolean fork=false; - for(int i=0;i1) { - // Split the option at the first '=' char if any - int s = arg.startsWith("--") ? 2 : 1 ; // -- or - - int e = arg.indexOf("="); - String key,val; - if(e>s) { - // Format: -key=value - key=arg.substring(s,e-1); - val=arg.substring(e+1); - } else if(e>-1 && e<=s) { - // Can't have a property without a key! - throw new Exception("Invalid option -="); - } else { - key=arg.substring(s); - val=""; // can't be null - } - - if(key.equals("d")) { - // -d | --d is reserved to set the Logger level - int level=0; - if(!val.equals("")) { - level=Integer.parseInt(val); - } - Logger.setLevel(level); - } else { - // Add all other properties into the Properties object - props.put(key,val); - Logger.log(Logger.INFO,"Argument",key,val); - } - - } else { - // Just a - on its own? - System.out.println("Unknown option: -"); - } - } else { - // Add the argument to the array - args.add(arg); - } - } - } - -} \ No newline at end of file diff --git a/contrib/retep/uk/org/retep/util/Logger.java b/contrib/retep/uk/org/retep/util/Logger.java deleted file mode 100644 index c272f1d005..0000000000 --- a/contrib/retep/uk/org/retep/util/Logger.java +++ /dev/null @@ -1,150 +0,0 @@ -package uk.org.retep.util; - -import java.io.CharArrayWriter; -import java.io.PrintWriter; - -public class Logger -{ - protected static int level; - protected static PrintWriter logger; - - public static final int NONE = -1; - public static final int INFO = 0; - public static final int ERROR = 1; - public static final int DEBUG = 2; - public static final int ALL = 3; - - static { - level = NONE; - logger = null; - }; - - private static final String levels[] = { - "INFO :", - "ERROR:", - "DEBUG:", - "ALL :" - }; - - public static void setLevel(int aLevel) - { - // Incase we have not yet set a logger - if(logger==null) { - logger = new PrintWriter(System.out); - } - - if(aLevelALL) { - aLevel=ALL; - } - - level=aLevel; - - if(level>NONE) { - log(INFO,"Log level changed to",level,levels[level]); - } - } - - public static void setLogger(PrintWriter pw) - { - if(logger!=null) { - try { - logger.flush(); - logger.close(); - } catch(Exception ex) { - logger=pw; - log(ERROR,"Exception while closing logger",ex); - } - } - logger=pw; - } - - public static void log(String msg) - { - log(INFO,msg); - } - - public static void log(int aLevel,String msg) - { - write(aLevel,msg,null); - } - - public static void log(int aLevel,String msg,int arg1) - { - Object o[] = {new Integer(arg1)}; - write(aLevel,msg,o); - } - - public static void log(int aLevel,String msg,int arg1,Object arg2) - { - Object o[] = {new Integer(arg1),arg2}; - write(aLevel,msg,o); - } - - public static void log(int aLevel,String msg,double arg1) - { - Object o[] = {new Double(arg1)}; - write(aLevel,msg,o); - } - - public static void log(int aLevel,String msg,double arg1,Object arg2) - { - Object o[] = {new Double(arg1),arg2}; - write(aLevel,msg,o); - } - - public static void log(int aLevel,String msg,Object arg1) - { - Object o[] = {arg1}; - write(aLevel,msg,o); - } - - public static void log(int aLevel,String msg,Object arg1,Object arg2) - { - Object o[] = {arg1,arg2}; - write(aLevel,msg,o); - } - - public static void log(int aLevel,String msg,Object arg1,Object arg2,Object arg3) - { - Object o[] = {arg1,arg2,arg3}; - write(aLevel,msg,o); - } - - public static void log(int aLevel,String msg,Throwable t) - { - CharArrayWriter buffer = new CharArrayWriter(); - PrintWriter printWriter = new PrintWriter(buffer); - t.printStackTrace(printWriter); - Object o[] = {buffer.toString()}; - buffer.close(); - write(aLevel,msg,o); - } - - private static void write(int aLevel,String aMsg,Object args[]) - { - // Can't be above ALL - if(aLevel>ALL) { - aLevel=ALL; - } - - // Ignore if below or equal to NONE - if(aLevellevel) { - return; - } - - logger.print("Logger:"); - logger.print(levels[aLevel]); - logger.print(aMsg); - if(args!=null) { - for(int a=0;a0) { - editor.openFile(globals.getArgument(0)); - } - - return editor; - } - - public static void main(String[] args) - throws Exception - { - Main main = new Main(args); - main.pack(); - main.setVisible(true); - } -} diff --git a/contrib/retep/uk/org/retep/util/hba/Record.java b/contrib/retep/uk/org/retep/util/hba/Record.java deleted file mode 100644 index b91e6dc49d..0000000000 --- a/contrib/retep/uk/org/retep/util/hba/Record.java +++ /dev/null @@ -1,238 +0,0 @@ -package uk.org.retep.util.hba; - -import uk.org.retep.util.Logger; -import uk.org.retep.util.misc.IPAddress; -import uk.org.retep.util.misc.WStringTokenizer; - -/** - * Used to store the entries of a pg_hba.conf file - * @author - * @version 1.0 - */ - -public class Record -{ - int type; - String dbname; - IPAddress ip; - IPAddress mask; - int authType; - String authArg; - - public static final int TYPE_LOCAL = 0; - public static final int TYPE_HOST = 1; - public static final int TYPE_HOSTSSL = 2; - - public static final String types[] = { - "local","host","hostssl" - }; - - public static final int AUTH_TRUST = 0; - public static final int AUTH_PASSWORD = 1; - public static final int AUTH_CRYPT = 2; - public static final int AUTH_IDENT = 3; - public static final int AUTH_KRB4 = 4; - public static final int AUTH_KRB5 = 5; - public static final int AUTH_REJECT = 6; - - public static final String auths[] = { - "trust","password","crypt", - "ident", - "krb4","krb5", - "reject" - }; - - private static final String spc = " "; - - public Record() - { - } - - public int getType() - { - return type; - } - - public void setType(int aType) - { - type=aType; - } - - public String getDatabase() - { - return dbname; - } - - public void setDatabase(String aDB) - { - dbname=aDB; - } - - public int getAuthType() - { - return authType; - } - - public void setAuthType(int aType) - { - authType=aType; - } - - public String getAuthArgs() - { - return authArg; - } - - public void setAuthArgs(String aArg) - { - authArg=aArg; - } - - public IPAddress getIP() - { - return ip; - } - - public void setIP(String aArg) - { - setIP(new IPAddress(aArg)); - } - - public void setIP(IPAddress aArg) - { - ip=aArg; - } - - public IPAddress getMask() - { - return mask; - } - - public void setMask(String aArg) - { - setMask(new IPAddress(aArg)); - } - - public void setMask(IPAddress aArg) - { - mask=aArg; - } - - public String toString() - { - StringBuffer buf = new StringBuffer(); - write(buf); - return buf.toString(); - } - - public void write(StringBuffer buf) - { - buf.append(types[type]).append(spc); - - if(type==TYPE_HOST || type==TYPE_HOSTSSL) { - buf.append(getIP()).append(spc); - buf.append(getMask()).append(spc); - } - - buf.append(auths[authType]); - - // Now the authArg - switch(type) - { - // These have no authArgs - case AUTH_TRUST: - case AUTH_REJECT: - case AUTH_KRB4: - case AUTH_KRB5: - break; - - // These must have an arg - case AUTH_IDENT: - buf.append(spc).append(getAuthArgs()); - break; - - // These may have an optional arg - case AUTH_PASSWORD: - case AUTH_CRYPT: - if(!(authArg==null || authArg.equals(""))) - buf.append(spc).append(getAuthArgs()); - break; - } - } - - private static WStringTokenizer tok; - - public static Record parseLine(String s) - { - Record res = new Record(); - int type; - - if(s==null || s.equals("") || s.startsWith("#")) - return null; - - if(tok==null) - tok=new WStringTokenizer(); - - tok.setString(s); - - type=WStringTokenizer.matchToken(types,tok.nextToken()); - res.setType(type); - - res.setDatabase(tok.nextToken()); - - if(type==TYPE_HOST || type==TYPE_HOSTSSL) { - res.setIP(new IPAddress(tok.nextToken())); - res.setMask(new IPAddress(tok.nextToken())); - } - - res.setAuthType(WStringTokenizer.matchToken(auths,tok.nextToken())); - res.setAuthArgs(tok.nextToken()); - - return res; - } - - public static final int VALID = 0; - public static final int INVALID_TYPE = 1; - public static final int INVALID_IPREQUIRED = 2; - - /** - * Validates the record - */ - public int validate() - { - switch(type) - { - case TYPE_HOST: - case TYPE_HOSTSSL: - if(ip==null || ip.isInvalid()) { - Logger.log(Logger.INFO,"pg_hba.conf: IP missing or invalid - repairing"); - setMask("127.0.0.1"); - } - - if(mask==null || mask.isInvalid() || !ip.validateMask(mask)) { - Logger.log(Logger.INFO,"pg_hba.conf: IP address without mask - repairing"); - setMask(ip.getMask()); - } - - break; - - case TYPE_LOCAL: - break; - - default: - return INVALID_TYPE; - } - - return VALID; - } - - /* -# host all 192.168.54.1 255.255.255.255 reject -# host all 0.0.0.0 0.0.0.0 krb5 -# host all 192.168.0.0 255.255.0.0 ident omicron -# - -local all trust -host all 127.0.0.1 255.255.255.255 trust -*/ -} \ No newline at end of file diff --git a/contrib/retep/uk/org/retep/util/misc/IPAddress.java b/contrib/retep/uk/org/retep/util/misc/IPAddress.java deleted file mode 100644 index a04babde3a..0000000000 --- a/contrib/retep/uk/org/retep/util/misc/IPAddress.java +++ /dev/null @@ -1,125 +0,0 @@ -package uk.org.retep.util.misc; - -import java.util.StringTokenizer; - -/** - * Represent an IP address - * @author - * @version 1.0 - */ - -public class IPAddress -{ - protected long address; - protected long b[] = new long[4]; - protected boolean invalid=true; - - public IPAddress() - { - } - - public IPAddress(String s) - { - setAddress(s); - } - - public synchronized void setAddress(String s) - { - if(s==null || s.equals("")) { - invalid=true; - return; - } - - address=0; - StringTokenizer tok = new StringTokenizer(s,"."); - int i=0; - while(i<4 && tok.hasMoreElements()) { - b[i++] = Long.parseLong(tok.nextToken()); - } - while(i<4) { - b[i++]=0; - } - - invalid=false; - refresh(); - } - - public void refresh() - { - if(invalid) - return; - address = (b[0]<<24) | (b[1]<<16) | (b[2]<<8) | (b[3]); - } - - public boolean isInvalid() - { - refresh(); - return invalid; - } - - public String toString() - { - refresh(); - if(invalid) - return "*INVALID*"; - - return Long.toString(b[0])+"."+Long.toString(b[1])+"."+Long.toString(b[2])+"."+Long.toString(b[3]); - } - - public boolean equals(Object o) - { - if(o instanceof IPAddress) { - IPAddress ip = (IPAddress) o; - - refresh(); - ip.refresh(); - - if(ip.invalid == invalid) - return false; - - return address==ip.address; - } - return false; - } - - private static int gethoststart(long b) - { - if((b & 0x80)==0x00) return 1; // class A - if((b & 0xc0)==0x80) return 2; // class B - if((b & 0xe0)==0xc0) return 3; // class C - return 4; // class D - } - - public boolean validateMask(IPAddress mask) - { - // If were a network check the host mask - int i=gethoststart(b[0]); -System.out.println("Host start "+i); - while(i<4 && b[i]==0) { - if(mask.b[i++]>0) - return false; - } - - for(i=0;i<4;i++) { - if((b[i]&mask.b[i])!=b[i]) - return false; - } - - return true; - } - - public IPAddress getMask() - { - IPAddress mask = new IPAddress(); - int i=3; - while(i>-1 && b[i]==0) { - mask.b[i--]=0; - } - while(i>-1) { - mask.b[i--]=255; - } - mask.invalid=false; - mask.refresh(); - return mask; - } -} \ No newline at end of file diff --git a/contrib/retep/uk/org/retep/util/misc/PropertiesIO.java b/contrib/retep/uk/org/retep/util/misc/PropertiesIO.java deleted file mode 100644 index 7bed62c4d2..0000000000 --- a/contrib/retep/uk/org/retep/util/misc/PropertiesIO.java +++ /dev/null @@ -1,157 +0,0 @@ -package uk.org.retep.util.misc; - -import java.io.*; -import java.util.Date; -import java.util.Iterator; -import java.util.Properties; -import java.util.TreeMap; - -/** - * Misc Properties utilities.. - * @author - * @version 1.0 - */ - -public class PropertiesIO -{ - - public PropertiesIO() - { - } - - /** - * Builds a TreeMap based on the given Properties object. This is useful - * because the keys will be in sorted order. - */ - public static TreeMap getTreeMap(Properties p) - { - TreeMap map = new TreeMap(); - Iterator e = p.keySet().iterator(); - while(e.hasNext()) { - Object k = e.next(); - map.put(k,p.get(k)); - } - return map; - } - - /** - * Writes a Properties file to the writer. This is similar to Properties.save - * except you can pick the key/value separator - */ - public static synchronized void save(Properties p,OutputStream out,char sep,String header) - throws IOException - { - save(p,p.keySet().iterator(),out,sep,header); - } - - /** - * Writes a Properties file to the writer. This is similar to Properties.save - * except you can pick the key/value separator and the keys are written - * in a sorted manner - */ - public static synchronized void saveSorted(Properties p,OutputStream out,char sep,String header) - throws IOException - { - save(p,getTreeMap(p).keySet().iterator(),out,sep,header); - } - - /** - * This is the same as save, only the keys in the enumeration are written. - */ - public static synchronized void save(Properties p,Iterator e, OutputStream out,char sep,String header) - throws IOException - { - BufferedWriter w = new BufferedWriter(new OutputStreamWriter(out, "8859_1")); - - if (header != null) { - w.write('#'); - w.write(header); - w.newLine(); - } - - w.write('#'); - w.write(new Date().toString()); - w.newLine(); - - while(e.hasNext()) { - String key = (String)e.next(); - w.write(encode(key,true)); - w.write(sep); - w.write(encode((String)p.get(key),false)); - w.newLine(); - } - w.flush(); - } - - private static final String specialSaveChars = "=: \t\r\n\f#!"; - - /** - * Encodes a string in a way similar to the JDK's Properties method - */ - public static String encode(String s, boolean escapeSpace) - { - int l=s.length(); - StringBuffer buf = new StringBuffer(l<<1); - - for(int i=0;i0x7e)) { - buf.append('\\').append('u'); - buf.append(toHex((c >> 12) & 0xF)); - buf.append(toHex((c >> 8) & 0xF)); - buf.append(toHex((c >> 4) & 0xF)); - buf.append(toHex( c & 0xF)); - } else { - if (specialSaveChars.indexOf(c) != -1) - buf.append('\\'); - buf.append(c); - } - } - } - return buf.toString(); - } - - /** - * Convert a nibble to a hex character - * @param nibble the nibble to convert. - */ - public static char toHex(int n) { - return hd[(n & 0xF)]; - } - - /** A table of hex digits */ - private static final char[] hd = { - '0','1','2','3','4','5','6','7', - '8','9','A','B','C','D','E','F' - }; -} \ No newline at end of file diff --git a/contrib/retep/uk/org/retep/util/misc/WStringTokenizer.java b/contrib/retep/uk/org/retep/util/misc/WStringTokenizer.java deleted file mode 100644 index 763676cfb3..0000000000 --- a/contrib/retep/uk/org/retep/util/misc/WStringTokenizer.java +++ /dev/null @@ -1,102 +0,0 @@ -package uk.org.retep.util.misc; - -/** - * Similar to StringTokenizer but handles white spaces and multiple delimiters - * between tokens. It also handles quotes - * - * @author - * @version 1.0 - */ - -public class WStringTokenizer -{ - String string; - int pos,len; - - /** - * Constructor - */ - public WStringTokenizer() - { - } - - /** - * Constructor: set the initial string - * @param aString String to tokenise - */ - public WStringTokenizer(String aString) - { - setString(aString); - } - - /** - * @param aString String to tokenise - */ - public void setString(String aString) - { - string=aString; - pos=0; - len=string.length(); - } - - /** - * @return true if more tokens may be possible - */ - public boolean hasMoreTokens() - { - return !(string==null || pos==len); - } - - /** - * @return next token, null if complete. - */ - public String nextToken() - { - char c; - boolean q=false; - - if(!hasMoreTokens()) - return null; - - // find start of token - while(pos=keys.length || aColumn<0 || aColumn>=cols.length) - return null; - - Object key = keys[aRow]; - - switch(aColumn) - { - case 0: - return key; - - case 1: - return properties.get(key); - - default: - return null; - } - } - - public int getRowCount() - { - return keys.length; - } - - public String getColumnName(int aColumn) - { - return cols[aColumn]; - } - - public void setValueAt(Object aValue, int aRow, int aColumn) - { - if(aRow<0 || aRow>=keys.length || aColumn<0 || aColumn>=cols.length) - return; - - switch(aColumn) - { - // Rename the key (only if not already present). If already present - // the refresh() will replace with the old one anyhow... - case 0: - if(!properties.containsKey(aValue)) { - Object oldValue = get(keys[aRow]); - remove(keys[aRow]); - put(aValue,oldValue); - } - refresh(); - break; - - // Update the value... - case 1: - put(keys[aRow],aValue); - //refresh(); - break; - - default: - // Should never be called - Logger.log(Logger.ERROR,"PropertiesTableModel: Column range",aColumn); - } - } - - public boolean isCellEditable(int aRow, int aColumn) - { - return true; - } - -} diff --git a/contrib/retep/uk/org/retep/util/proped/Main.java b/contrib/retep/uk/org/retep/util/proped/Main.java deleted file mode 100644 index 6f2c73bc68..0000000000 --- a/contrib/retep/uk/org/retep/util/proped/Main.java +++ /dev/null @@ -1,53 +0,0 @@ -package uk.org.retep.util.proped; - -import uk.org.retep.util.ExceptionDialog; -import uk.org.retep.util.Globals; -import uk.org.retep.util.Logger; -import uk.org.retep.util.StandaloneApp; - -import java.io.IOException; -import java.util.Iterator; -import javax.swing.JComponent; - -/** - * Standalone entry point for the Properties editor - * - * $Id: Main.java,v 1.1 2001/03/05 09:15:38 peter Exp $ - */ - -public class Main extends StandaloneApp -{ - public Main(String[] args) - throws Exception - { - super(args); - } - - public JComponent init() - throws Exception - { - Globals globals = Globals.getInstance(); - - PropertyEditor panel = new PropertyEditor(); - - // Only handle 1 open at a time in standalone mode - if(globals.getArgumentCount()>0) { - try { - panel.openFile(globals.getArgument(0)); - } catch(IOException ioe) { - ExceptionDialog.displayException(ioe,"while loading "+globals.getArgument(0)); - throw (Exception) ioe.fillInStackTrace(); - } - } - - return panel; - } - - public static void main(String[] args) - throws Exception - { - Main main = new Main(args); - main.pack(); - main.setVisible(true); - } -} \ No newline at end of file diff --git a/contrib/retep/uk/org/retep/util/proped/PropertyEditor.java b/contrib/retep/uk/org/retep/util/proped/PropertyEditor.java deleted file mode 100644 index b5c19e1087..0000000000 --- a/contrib/retep/uk/org/retep/util/proped/PropertyEditor.java +++ /dev/null @@ -1,381 +0,0 @@ -package uk.org.retep.util.proped; - -import uk.org.retep.util.ExceptionDialog; -import uk.org.retep.util.misc.PropertiesIO; -import uk.org.retep.util.models.PropertiesTableModel; - -import java.awt.*; -import java.io.*; -import java.util.*; -import javax.swing.*; -import java.awt.event.*; - -/** - * A property file editor - * - * $Id: PropertyEditor.java,v 1.1 2001/03/05 09:15:38 peter Exp $ - * - * @author - * @version 1.0 - */ - -public class PropertyEditor -extends JPanel -implements uk.org.retep.tools.Tool -{ - BorderLayout borderLayout1 = new BorderLayout(); - - // The filename, null if not set - String filename; - File file; - - JScrollPane jScrollPane1 = new JScrollPane(); - JTable contentTable = new JTable(); - - PropertiesTableModel model = new PropertiesTableModel(); - - boolean standaloneMode; - - private static final String TITLE_PREFIX = "Retep PropertyEditor"; - JPopupMenu popupMenu = new JPopupMenu(); - JMenuItem newPopupItem = new JMenuItem(); - JMenuItem dupPopupItem = new JMenuItem(); - JMenuItem delPopupItem = new JMenuItem(); - JMenuBar menuBar = new JMenuBar(); - JMenu jMenu1 = new JMenu(); - JMenuItem jMenuItem4 = new JMenuItem(); - JMenuItem jMenuItem5 = new JMenuItem(); - JMenuItem jMenuItem6 = new JMenuItem(); - JMenuItem jMenuItem7 = new JMenuItem(); - JMenuItem jMenuItem8 = new JMenuItem(); - JMenuItem closeMenuItem = new JMenuItem(); - - public PropertyEditor() - { - try - { - jbInit(); - } - catch(Exception ex) - { - ex.printStackTrace(); - } - } - - /** - * @return the default menubar - */ - public JMenuBar getMenuBar() - { - return menuBar; - } - - /** - * @return the File menu - */ - public JMenu getMenu() - { - return jMenu1; - } - - /** - * @return the recomended title string for the parent JFrame/JInternalFrame - */ - public String getTitle() - { - if(filename==null) { - return TITLE_PREFIX; - } - return TITLE_PREFIX+": "+filename; - } - - /** - * Sets menus up to Standalone mode - */ - public void setStandaloneMode(boolean aMode) - { - standaloneMode=aMode; - if(aMode) { - closeMenuItem.setText("Exit"); - } else { - closeMenuItem.setText("Close"); - } - } - - public boolean isStandalone() - { - return standaloneMode; - } - - public void openFile(String aFile) - throws IOException - { - openFile(new File(aFile)); - } - - public void openFile(File aFile) - throws IOException - { - FileInputStream fis = new FileInputStream(aFile); - Properties p = new Properties(); - p.load(fis); - fis.close(); - model.setProperties(p); - - file=aFile; - filename = aFile.getAbsolutePath(); - } - - public void saveFile(File aFile) - throws IOException - { - FileOutputStream fis = new FileOutputStream(aFile); - PropertiesIO.save(model.getProperties(),fis,'=',"Written by "+TITLE_PREFIX); - fis.close(); - - filename = aFile.getAbsolutePath(); - file = aFile; - } - - void jbInit() throws Exception - { - this.setLayout(borderLayout1); - contentTable.setToolTipText(""); - contentTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); - contentTable.setModel(model); - contentTable.addMouseListener(new java.awt.event.MouseAdapter() - { - public void mouseClicked(MouseEvent e) - { - contentTable_mouseClicked(e); - } - public void mouseReleased(MouseEvent e) - { - contentTable_mouseReleased(e); - } - }); - newPopupItem.setText("New"); - newPopupItem.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(ActionEvent e) - { - newPopupItem_actionPerformed(e); - } - }); - dupPopupItem.setText("Duplicate"); - dupPopupItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(67, java.awt.event.KeyEvent.CTRL_MASK, false)); - dupPopupItem.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(ActionEvent e) - { - dupPopupItem_actionPerformed(e); - } - }); - delPopupItem.setText("Delete"); - delPopupItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(68, java.awt.event.KeyEvent.CTRL_MASK, false)); - delPopupItem.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(ActionEvent e) - { - delPopupItem_actionPerformed(e); - } - }); - jMenu1.setText("File"); - jMenuItem4.setText("Open"); - jMenuItem4.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(ActionEvent e) - { - jMenuItem4_actionPerformed(e); - } - }); - jMenuItem5.setText("Save"); - jMenuItem5.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(ActionEvent e) - { - jMenuItem5_actionPerformed(e); - } - }); - jMenuItem6.setText("Save As"); - jMenuItem6.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(ActionEvent e) - { - jMenuItem6_actionPerformed(e); - } - }); - jMenuItem7.setText("Revert"); - jMenuItem7.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(ActionEvent e) - { - jMenuItem7_actionPerformed(e); - } - }); - jMenuItem8.setText("Print"); - closeMenuItem.setText("Close"); - closeMenuItem.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(ActionEvent e) - { - closeMenuItem_actionPerformed(e); - } - }); - jMenu2.setText("Edit"); - jMenuItem1.setText("New"); - jMenuItem1.setAccelerator(javax.swing.KeyStroke.getKeyStroke(78, java.awt.event.KeyEvent.CTRL_MASK, false)); - jMenuItem1.addActionListener(new java.awt.event.ActionListener() - { - public void actionPerformed(ActionEvent e) - { - newPopupItem_actionPerformed(e); - } - }); - jMenuItem2.setText("Duplicate"); - jMenuItem3.setText("Delete"); - this.add(jScrollPane1, BorderLayout.CENTER); - jScrollPane1.getViewport().add(contentTable, null); - popupMenu.add(newPopupItem); - popupMenu.add(dupPopupItem); - popupMenu.add(delPopupItem); - menuBar.add(jMenu1); - menuBar.add(jMenu2); - jMenu1.add(jMenuItem4); - jMenu1.add(jMenuItem5); - jMenu1.add(jMenuItem6); - jMenu1.add(jMenuItem7); - jMenu1.addSeparator(); - jMenu1.add(jMenuItem8); - jMenu1.addSeparator(); - jMenu1.add(closeMenuItem); - jMenu2.add(jMenuItem1); - jMenu2.add(jMenuItem2); - jMenu2.add(jMenuItem3); - } - - Point popupPoint = new Point(); - JMenu jMenu2 = new JMenu(); - JMenuItem jMenuItem1 = new JMenuItem(); - JMenuItem jMenuItem2 = new JMenuItem(); - JMenuItem jMenuItem3 = new JMenuItem(); - void contentTable_mouseClicked(MouseEvent e) - { - if(e.isPopupTrigger()) { - popupPoint.setLocation(e.getX(),e.getY()); - popupMenu.show(contentTable,e.getX(),e.getY()); - } - } - - void contentTable_mouseReleased(MouseEvent e) - { - contentTable_mouseClicked(e); - } - - void jMenuItem4_actionPerformed(ActionEvent e) - { - JFileChooser fc = new JFileChooser(); - if(fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { - try { - openFile(fc.getSelectedFile()); - } catch(IOException ioe) { - ExceptionDialog.displayException(ioe); - } - } - } - - void closeMenuItem_actionPerformed(ActionEvent e) - { - if(standaloneMode) { - System.exit(0); - } else { - filename=""; - file=null; - model.setProperties(new Properties()); - } - } - - void newPopupItem_actionPerformed(ActionEvent e) - { - int y = contentTable.rowAtPoint(popupPoint); - - // create a new unique key based on the current one - String key=(String) model.getValueAt(y,0); - - if(key==null) { - key="new-key"; - } - - int uid=1; - while(model.containsKey(key+uid)) { - uid++; - } - - key=key+uid; - model.put(key,""); - contentTable.clearSelection(); - } - - void dupPopupItem_actionPerformed(ActionEvent e) - { - int y = contentTable.rowAtPoint(popupPoint); - - // create a new unique key based on the current one - String key=(String) model.getValueAt(y,0); - Object val=model.get(key); - - int uid=1; - while(model.containsKey(key+uid)) { - uid++; - } - - key=key+uid; - model.put(key,val); - contentTable.clearSelection(); - } - - void delPopupItem_actionPerformed(ActionEvent e) - { - int y = contentTable.rowAtPoint(popupPoint); - model.remove(model.getValueAt(y,0)); - } - - void jMenuItem6_actionPerformed(ActionEvent e) - { - JFileChooser fc = new JFileChooser(); - if(fc.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) { - try { - saveFile(fc.getSelectedFile()); - } catch(IOException ioe) { - ExceptionDialog.displayException(ioe); - } - } - } - - void jMenuItem5_actionPerformed(ActionEvent e) - { - if(filename==null) { - jMenuItem6_actionPerformed(e); - } else { - try { - saveFile(file); - } catch(IOException ioe) { - ExceptionDialog.displayException(ioe); - } - } - } - - void jMenuItem7_actionPerformed(ActionEvent e) - { - // add check here - if(file!=null) { - try { - openFile(file); - } catch(IOException ioe) { - ExceptionDialog.displayException(ioe); - } - } else { - jMenuItem4_actionPerformed(e); - } - } -} \ No newline at end of file diff --git a/contrib/retep/uk/org/retep/xml/core/XMLFactory.java b/contrib/retep/uk/org/retep/xml/core/XMLFactory.java deleted file mode 100644 index 09565b0011..0000000000 --- a/contrib/retep/uk/org/retep/xml/core/XMLFactory.java +++ /dev/null @@ -1,334 +0,0 @@ -package uk.org.retep.xml.core; - -import java.io.IOException; -import java.io.Writer; - -/** - * An XMLFactory is used to render XML Tags, accounting for nesting etc - */ -public class XMLFactory -{ - /** - * The lest level (ie, how many tags down the tree we are) - */ - protected int level; - - /** - * The size of our tag name cache - */ - protected int maxlevel; - - /** - * Our tag name cache - */ - protected String[] names; - - /** - * Used to keep track of how formatting is done - */ - protected boolean hascontent; - protected boolean[] contbuf; - - /** - * Scratch used by nest() - */ - private char[] nestbuf; - - /** - * The destination Writer - */ - protected Writer out; - - /** - * True if we are still within a tag - */ - protected boolean inTag; - - /** - * True if we have just created a tag so parameters are valid - */ - protected boolean inArg; - - /** - * Constructs an XMLFactory with no output Writer - */ - public XMLFactory() - { - this(10); - } - - /** - * Constructs an XMLFactory with no output Writer - * @param m Expected number of leaves in the XML Tree - */ - public XMLFactory(int m) - { - // Initialise the names cache - level=0; - maxlevel=m; - names=new String[maxlevel]; - contbuf=new boolean[maxlevel]; - - // This is used by nest() - nestbuf=new char[maxlevel]; - for(int i=0;i\n"); - } - - /** - * @return Writer the XML is being sent out on. - */ - public Writer getWriter() { - return out; - } - - /** - * This starts a tag - * @param name The tag name - */ - public void startTag(String name) - throws IOException - { - if(inTag && inArg) { - // Handles two startTag() calls in succession. - out.write(">"); - } - - nest(level); - out.write('<'); - out.write(name); - inTag=true; - inArg=true; - - // cache the current tag name - names[level]=name; - - // cache the current hascontent value & reset - contbuf[level]=hascontent; - hascontent=false; - - // increase the level and the cache's as necessary - level++; - if(level>maxlevel) { - maxlevel=maxlevel+10; - - String n[]=new String[maxlevel]; - System.arraycopy(names,0,n,0,level); - names=n; - - boolean b[] = new boolean[maxlevel]; - System.arraycopy(contbuf,0,b,0,level); - contbuf=b; - } - } - - /** - * This ends a tag - */ - public void endTag() - throws IOException, XMLFactoryException - { - if(level<1) - throw new XMLFactoryException("endTag called above root node"); - - level--; - - if(inArg) { - // We are still within the opening tag - out.write(" />"); - } else { - // We must have written some content or child tags - - // hascontent is true if addContent() was called. If it was never called - // to get here some child tags must have been written, so we call nest() - // so that the close tag is on it's own line, and everything looks neat - // and tidy. - if(!hascontent) - nest(level); - - out.write("'); - } - - inArg=false; // The parent tag must be told it now has content - inTag= level>0; // Are we still in a tag? - hascontent=contbuf[level]; // retrieve this level's hascontent value - } - - /** - * This completes the document releasing any open resources. - */ - public void close() - throws IOException, XMLFactoryException - { - while(level>0) - endTag(); - out.write('\n'); - out.flush(); - } - - /** - * This writes an attribute to the current tag. If the value is null, then no action is taken. - * @param name Name of the parameter - * @param value Value of the parameter - * @throw XMLFactoryException if out of context - */ - public void addAttribute(String name,Object value) - throws IOException, XMLFactoryException - { - if(value==null) - return; - - if(inArg) { - out.write(' '); - out.write(name); - out.write("=\""); - out.write(encode(value.toString())); - out.write("\""); - } else - throw new XMLFactoryException("Cannot add attribute outside of a tag"); - } - - /** - * This writes some content to the current tag. Once this has been called, - * you cannot add any more attributes to the current tag. Note, if c is null, - * no action is taken. - * @param c content to add. - */ - public void addContent(Object c) - throws IOException, XMLFactoryException - { - if(c==null) - return; - - if(inTag) { - if(inArg) { - // close the open tag - out.write('>'); - inArg=false; - } - out.write(c.toString()); - - // This is used by endTag() - hascontent=true; - } else - throw new XMLFactoryException("Cannot add content outside of a tag"); - } - - /** - * This adds a comment to the XML file. This is normally used at the start of - * any XML output. - * @parm c Comment to include - */ - public void addComment(Object c) - throws IOException, XMLFactoryException - { - if(inTag) - throw new XMLFactoryException("Cannot add comments within a tag"); - - out.write("\n"); - } - - /** - * Indents the output according to the level - * @param level The indent level to generate - */ - protected void nest(int level) - throws IOException - { - out.write('\n'); - while(level>nestbuf.length) { - out.write(nestbuf,0,nestbuf.length); - level-=nestbuf.length; - } - out.write(nestbuf,0,level); - } - - /** - * Encodes the string so that any XML tag chars are translated - */ - protected String encode(String s) { - return s; - } - -} \ No newline at end of file diff --git a/contrib/retep/uk/org/retep/xml/core/XMLFactoryException.java b/contrib/retep/uk/org/retep/xml/core/XMLFactoryException.java deleted file mode 100644 index 5f9d497209..0000000000 --- a/contrib/retep/uk/org/retep/xml/core/XMLFactoryException.java +++ /dev/null @@ -1,19 +0,0 @@ -package uk.org.retep.xml.core; - -/** - * Title: - * Description: - * Copyright: Copyright (c) 2001 - * Company: - * @author - * @version 1.0 - */ - -public class XMLFactoryException extends Exception -{ - - public XMLFactoryException(String s) - { - super(s); - } -} \ No newline at end of file diff --git a/contrib/retep/uk/org/retep/xml/jdbc/XMLDatabase.java b/contrib/retep/uk/org/retep/xml/jdbc/XMLDatabase.java deleted file mode 100644 index 50aaaa1d90..0000000000 --- a/contrib/retep/uk/org/retep/xml/jdbc/XMLDatabase.java +++ /dev/null @@ -1,237 +0,0 @@ -package uk.org.retep.xml.jdbc; - -import java.io.IOException; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import uk.org.retep.xml.core.XMLFactory; -import uk.org.retep.xml.core.XMLFactoryException; - -public class XMLDatabase -{ - /** - * The XMLFactory being used by this instance - */ - protected XMLFactory factory; - - /** - * Constructor. setXMLFactory() must be called if this method is used. - */ - public XMLDatabase() - { - } - - /** - * Constructor - * @param fac XMLFactory to use - */ - public XMLDatabase(XMLFactory fac) - { - this(); - setXMLFactory(fac); - } - - /** - * Sets the factory to use. - * @param factory XMLFactory to use - */ - public void setXMLFactory(XMLFactory factory) - { - this.factory=factory; - } - - /** - * @return the XMLFactory being used. - */ - public XMLFactory getXMLFactory() - { - return factory; - } - - /** - * Flushes all output to the Writer. - * @throw IOException from Writer - * @throw XMLFactoryException from XMLFactory - */ - public void close() - throws IOException, XMLFactoryException - { - factory.close(); - } - - /** - * writes the schema of a table. - * @param con Connection to database - * @param table Table name - * @throw IOException from Writer - * @throw SQLException from JDBC - * @throw XMLFactoryException from XMLFactory - */ - public void writeTable(Connection con,String table) - throws IOException,SQLException,XMLFactoryException - { - writeTable(con.getMetaData(),table); - } - - /** - * writes the schema of a table. - * @param db DatabaseMetaData for the database - * @param table Table name - * @throw IOException from Writer - * @throw SQLException from JDBC - * @throw XMLFactoryException from XMLFactory - */ - public void writeTable(DatabaseMetaData db,String table) - throws IOException,SQLException,XMLFactoryException - { - writeTable(db,null,null,table); - } - - /** - * writes the schema of a table. - * @param db DatabaseMetaData for the database - * @param table Table name - * @throw IOException from Writer - * @throw SQLException from JDBC - * @throw XMLFactoryException from XMLFactory - */ - public void writeTable(DatabaseMetaData db,String cat,String schem,String table) - throws IOException,SQLException,XMLFactoryException - { - ResultSet trs; - - factory.startTag("TABLE"); - factory.addAttribute("NAME",table); - // fetch the remarks for this table (if any) - trs = db.getTables(null,null,table,null); - if(trs!=null) { - if(trs.next()) { - String rem = trs.getString(5); - if(rem!=null) - factory.addContent(rem); - } - trs.close(); - } - - trs = db.getColumns(null,null,table,"%"); - if(trs!=null) { - while(trs.next()) { - factory.startTag("COLUMN"); - factory.addAttribute("NAME",trs.getString(4)); - factory.addAttribute("TYPE",trs.getString(6)); - factory.addAttribute("COLUMN_SIZE",trs.getString(7)); - factory.addAttribute("DECIMAL_DIGITS",trs.getString(9)); - factory.addAttribute("NUM_PREC_RADIX",trs.getString(10)); - factory.addAttribute("NULLABLE",trs.getString(11)); - factory.addAttribute("COLUMN_DEF",trs.getString(13)); - factory.addAttribute("CHAR_OCTET_LENGTH",trs.getString(16)); - factory.addAttribute("ORDINAL_POSITION",trs.getString(17)); - factory.addAttribute("IS_NULLABLE",trs.getString(18)); - factory.addAttribute("TABLE_CAT",trs.getString(1)); - factory.addAttribute("TABLE_SCHEM",trs.getString(2)); - String rem = trs.getString(12); - if(rem!=null) - factory.addContent(rem); - factory.endTag(); - } - trs.close(); - } - - factory.endTag(); - } - - /** - * This generates the schema of an entire database. - * @param db Connection to database - * @param table Table pattern - * @throw IOException from Writer - * @throw SQLException from JDBC - * @throw XMLFactoryException from XMLFactory - * @see java.sql.DatabaseMetaData.getTables() - */ - public void writeDatabase(Connection db,String table) - throws IOException, SQLException, XMLFactoryException - { - writeDatabase(db.getMetaData(),null,null,table); - } - - /** - * This generates the schema of an entire database. - * @param db DatabaseMetaData of database - * @param table Table pattern - * @throw IOException from Writer - * @throw SQLException from JDBC - * @throw XMLFactoryException from XMLFactory - * @see java.sql.DatabaseMetaData.getTables() - */ - public void writeDatabase(DatabaseMetaData db,String table) - throws IOException, SQLException, XMLFactoryException - { - writeDatabase(db,null,null,table); - } - - /** - * This generates the schema of an entire database. - * @param db DatabaseMetaData of database - * @param cat Catalog (may be null) - * @param schem Schema (may be null) - * @param table Table pattern - * @throw IOException from Writer - * @throw SQLException from JDBC - * @throw XMLFactoryException from XMLFactory - * @see java.sql.DatabaseMetaData.getTables() - */ - public void writeDatabase(Connection db) - throws IOException, SQLException, XMLFactoryException - { - writeDatabase(db.getMetaData(),null,null,"%"); - } - - /** - * This generates the schema of an entire database. - * @param db DatabaseMetaData of database - * @param cat Catalog (may be null) - * @param schem Schema (may be null) - * @param table Table pattern - * @throw IOException from Writer - * @throw SQLException from JDBC - * @throw XMLFactoryException from XMLFactory - * @see java.sql.DatabaseMetaData.getTables() - */ - public void writeDatabase(DatabaseMetaData db) - throws IOException, SQLException, XMLFactoryException - { - writeDatabase(db,null,null,"%"); - } - - /** - * This generates the schema of an entire database. - * @param db DatabaseMetaData of database - * @param cat Catalog (may be null) - * @param schem Schema (may be null) - * @param table Table pattern - * @throw IOException from Writer - * @throw SQLException from JDBC - * @throw XMLFactoryException from XMLFactory - * @see java.sql.DatabaseMetaData.getTables() - */ - public void writeDatabase(DatabaseMetaData db,String cat,String schem,String table) - throws IOException, SQLException, XMLFactoryException - { - ResultSet rs = db.getTables(cat,schem,table,null); - if(rs!=null) { - factory.startTag("DATABASE"); - factory.addAttribute("PRODUCT",db.getDatabaseProductName()); - factory.addAttribute("VERSION",db.getDatabaseProductVersion()); - - while(rs.next()) { - writeTable(db,rs.getString(1),rs.getString(2),rs.getString(3)); - } - - factory.endTag(); - rs.close(); - } - } - -} \ No newline at end of file diff --git a/contrib/retep/uk/org/retep/xml/jdbc/XMLResultSet.java b/contrib/retep/uk/org/retep/xml/jdbc/XMLResultSet.java deleted file mode 100644 index ee020df940..0000000000 --- a/contrib/retep/uk/org/retep/xml/jdbc/XMLResultSet.java +++ /dev/null @@ -1,505 +0,0 @@ -package uk.org.retep.xml.jdbc; - -import java.io.IOException; -import java.io.Writer; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.util.Properties; -import uk.org.retep.xml.core.XMLFactory; -import uk.org.retep.xml.core.XMLFactoryException; - -/** - * This class takes a java.sql.ResultSet object and generates an XML stream - * based on it's contents. - * - * $Id: XMLResultSet.java,v 1.1 2001/01/23 10:22:20 peter Exp $ - */ -public class XMLResultSet -{ - /** - * The current ResultSet to process - */ - protected ResultSet rs; - - /** - * The XMLFactory being used by this instance - */ - protected XMLFactory factory; - - /** - * The default properties used when none are supplied by the user - */ - protected static Properties defaults; - - /** - * The default property name for defining the tag name used to define a - * ResultSet - */ - public static String RESULTSET_NAME = "resultset.name"; - - /** - * The default tag name for a resultset - */ - public static String DEFAULT_RESULTSET_NAME = "RESULTSET"; - - /** - * The default property name for defining the tag name used to define a row - */ - public static String ROW_NAME = "row.name"; - - /** - * The default tag name for a row - */ - public static String DEFAULT_ROW_NAME = "RECORD"; - - /** - * The default tag name for a resultset - */ - public static String COLNAME = ".name"; - - /** - * The value of the property (named as its related column) used to define - * how the column is generated. This indicates that the columns data is - * enclosed within a pair of tags, ie: <id>1234</id> - */ - public static String CONTENT = "content"; - - /** - * The value of the property (named as its related column) used to define - * how the column is generated. This indicates that the columns data is - * an attribute in the columns tag. ie: - */ - public static String ATTRIBUTE = "attribute"; - - /** - * This is the default attribute name used when the ATTRIBUTE option is set. - */ - public static String DEFAULT_ATTRIBUTE = "VALUE"; - - /** - * The value of the property (named as its related column) used to define - * how the column is generated. This indicates that the columns data is - * an attribute in the parent's tag. ie: - */ - public static String ROW_ATTRIBUTE = "row"; - - /** - * This property name marks the begining row number within the ResultSet to - * start processing. - */ - public static String FIRST_ROW = "row.first"; - - /** - * This property name marks the last row number within the ResultSet to - * end processing. - */ - public static String LAST_ROW = "row.last"; - - /** - * Constructor - */ - public XMLResultSet() - { - factory = new XMLFactory(); - } - - /** - * Constructor - */ - public XMLResultSet(ResultSet rs) - { - this(); - setResultSet(rs); - } - - /** - * Sets the ResultSet to use - * @param rs ResultSet - */ - public void setResultSet(ResultSet rs) - { - this.rs=rs; - } - - /** - * @return the current ResultSet - * - */ - public ResultSet getResultSet() - { - return rs; - } - - /** - * Sets the Writer to send all output to - * @param out Writer - * @throws IOException from XMLFactory - * @see XMLFactory.setWriter - */ - public void setWriter(Writer out) - throws IOException - { - factory.setWriter(out); - } - - /** - * @return Writer output is going to - */ - public Writer getWriter() - { - return factory.getWriter(); - } - - /** - * @return XMLFactory being used - */ - public XMLFactory getXMLFactory() - { - return factory; - } - - /** - * Flushes all output to the Writer - * @throw IOException from Writer - * @throw XMLFactoryException from XMLFactory - */ - public void close() - throws IOException, XMLFactoryException - { - factory.close(); - } - - /** - * Returns the default properties used by translate() and buildDTD() - * @return Properties default property settings - */ - public static Properties getDefaultProperties() - { - if(defaults==null) { - defaults=new Properties(); - defaults.setProperty(RESULTSET_NAME,DEFAULT_RESULTSET_NAME); - defaults.setProperty(ROW_NAME,DEFAULT_ROW_NAME); - } - return defaults; - } - - /** - * This generates an XML version of a ResultSet sending it to the supplied - * Writer. - * @param rs ResultSet to convert - * @param p Properties for the conversion - * @param out Writer to send output to (replaces existing one) - * @throws XMLFactoryException from XMLFactory - * @throws IOException from Writer - * @throws SQLException from ResultSet - */ - public void translate(ResultSet rs,Properties p,Writer out) - throws XMLFactoryException, IOException, SQLException - { - factory.setWriter(out); - translate(rs,p); - } - - /** - * This generates an XML version of a ResultSet sending it to the supplied - * Writer using a default tag struct - * @param rs ResultSet to convert - * @param out Writer to send output to (replaces existing one) - * @throws XMLFactoryException from XMLFactory - * @throws IOException from Writer - * @throws SQLException from ResultSet - */ - public void translate(ResultSet rs,Writer out) - throws XMLFactoryException, IOException, SQLException - { - factory.setWriter(out); - translate(rs,(Properties)null); - } - - /** - * This generates an XML version of a ResultSet sending it to the current - * output stream using a default tag structure. - * @param rs ResultSet to convert - * @throws XMLFactoryException from XMLFactory - * @throws IOException from Writer - * @throws SQLException from ResultSet - */ - public void translate(ResultSet rs) - throws XMLFactoryException, IOException, SQLException - { - translate(rs,(Properties)null); - } - - /** - * This generates an XML version of a ResultSet sending it to the current - * output stream. - * @param rs ResultSet to convert - * @param p Properties for the conversion - * @throws XMLFactoryException from XMLFactory - * @throws IOException from Writer - * @throws SQLException from ResultSet - */ - public void translate(ResultSet rs,Properties p) - throws XMLFactoryException, IOException, SQLException - { - // if we don't pass any properties, create an empty one and cache it if - // further calls do the same - if(p==null) { - p=getDefaultProperties(); - } - - // Fetch some common values - String setName = p.getProperty(RESULTSET_NAME,DEFAULT_RESULTSET_NAME); - String rowName = p.getProperty(ROW_NAME,DEFAULT_ROW_NAME); - - ResultSetMetaData rsmd = rs.getMetaData(); - int numcols = rsmd.getColumnCount(); - - String colname[] = new String[numcols]; // field name cache - int coltype[] = new int[numcols]; // true to use attribute false content - String colattr[] = new String[numcols]; // Attribute name - - // These deal with when an attribute is to go into the row's tag parameters - int parentFields[] = getRowAttributes(numcols,colname,colattr,coltype,rsmd,p); // used to cache the id's - int numParents= parentFields==null ? 0 : parentFields.length; // number of parent fields - boolean haveParent= numParents>0; // true only if we need to us these - - // This allows some limiting of the output result - int firstRow = Integer.parseInt(p.getProperty(FIRST_ROW,"0")); - int lastRow = Integer.parseInt(p.getProperty(LAST_ROW,"0")); - int curRow=0; - - // Start the result set's tag - factory.startTag(setName); - - while(rs.next()) { - if(firstRow<=curRow && (lastRow==0 || curRowToDo:
    - *
  1. Add ability to have NULLABLE columns appear as optional (ie instead of - * x, have x? (DTD for Optional). Can't use + or * as that indicates more than - * 1 instance). - *
- * - * @param rs ResultSet - * @param p Properties defining tag types (as translate) - * @param out Writer to send output to - */ - public void buildDTD(ResultSet rs,Properties p,Writer out) - throws IOException, SQLException - { - // if we don't pass any properties, create an empty one and cache it if - // further calls do the same - if(p==null) { - p=getDefaultProperties(); - } - - // Fetch some common values - String setName = p.getProperty(RESULTSET_NAME,DEFAULT_RESULTSET_NAME); - String rowName = p.getProperty(ROW_NAME,DEFAULT_ROW_NAME); - - ResultSetMetaData rsmd = rs.getMetaData(); - int numcols = rsmd.getColumnCount(); - - String colname[] = new String[numcols]; // field name cache - int coltype[] = new int[numcols]; // true to use attribute false content - String colattr[] = new String[numcols]; // Attribute name - - // These deal with when an attribute is to go into the row's tag parameters - int parentFields[] = getRowAttributes(numcols,colname,colattr,coltype,rsmd,p); // used to cache the id's - int numParents= parentFields==null ? 0 : parentFields.length; // number of parent fields - boolean haveParent= numParents>0; // true only if we need to us these - - // Now the dtd defining the ResultSet - out.write("\n"); - - // Now the dtd defining each row - out.write("\n"); - - // Now handle any ROW_ATTRIBUTE's - if(haveParent) { - out.write("\n"); - } - - // Now add any CONTENT & ATTRIBUTE fields - for(int i=0;i\n"); - - // ATTRIBUTE - if(coltype[i]==1) { - out.write("\n"); - } - } - } - } - - /** - * Private method used by the core translate and buildDTD methods. - * @param numcols Number of columns in ResultSet - * @param colname Array of column names - * @param colattr Array of column attribute names - * @param coltype Array of column types - * @param rsmd ResultSetMetaData for ResultSet - * @param p Properties being used - * @return array containing field numbers which should appear as attributes - * within the rows tag. - * @throws SQLException from JDBC - */ - private int[] getRowAttributes(int numcols, - String colname[],String colattr[], - int coltype[], - ResultSetMetaData rsmd,Properties p) - throws SQLException - { - int pf[] = null; - int nf = 0; - - // Now we put a columns value as an attribute if the property - // fieldname=attribute (ie myname=attribute) - // and if the fieldname.name property exists, use it as the attribute name - for(int i=0;i0) { - int r[] = new int[nf]; - System.arraycopy(pf,0,r,0,nf); - return r; - } - - // Return null if no tags are to appear as attributes to the row's tag - return null; - } - -} \ No newline at end of file diff --git a/contrib/retep/uk/org/retep/xml/parser/TagHandler.java b/contrib/retep/uk/org/retep/xml/parser/TagHandler.java deleted file mode 100644 index 78deb0ec0a..0000000000 --- a/contrib/retep/uk/org/retep/xml/parser/TagHandler.java +++ /dev/null @@ -1,201 +0,0 @@ -package uk.org.retep.xml.parser; - -import java.io.CharArrayWriter; -import java.io.IOException; -import java.util.List; -import java.util.Iterator; -import java.util.HashSet; -import java.util.ArrayList; -import java.util.HashMap; -import org.xml.sax.AttributeList; -import org.xml.sax.HandlerBase; -import org.xml.sax.InputSource; -import org.xml.sax.Parser; -import org.xml.sax.SAXException; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -/** - * This class implements the base of the XML handler. You create an instance, - * register classes (who implement TagListener) that are interested in the tags - * and pass it to SAX. - * - *

Or you create an instance, register the TagListeners and use the getParser() - * method to create a Parser. Then start parsing by calling it's parse() method. - */ - -public class TagHandler extends HandlerBase { - - /** - * The current active level - */ - private int level; - - /** - * cache used to handle nesting of tags - */ - private List contents; - - /** - * cache used to handle nesting of tags - */ - private List tags; - - /** - * cache used to handle nesting of tags - */ - private List args; - - // Current active content writer - private CharArrayWriter content; - - // List of TagListener's who want to be fed data - private HashSet tagListeners; - - /** - * default constructor - */ - public TagHandler() { - level=0; - contents = new ArrayList(); - tags = new ArrayList(); - args = new ArrayList(); - tagListeners = new HashSet(); - } - - /** - * Called by SAX when a tag is begun. This simply creates a new level in the - * cache and stores the parameters and tag name in there. - */ - public void startElement(String p0, AttributeList p1) throws SAXException { - - // Now move up and fetch a CharArrayWriter from the cache - // creating if this is the first time at this level - if(contents.size()<=level) { - contents.add(new CharArrayWriter()); - tags.add(p0); - args.add(new HashMap()); - } - - content=(CharArrayWriter) contents.get(level); - content.reset(); - - // Also cache the tag's text and argument list - tags.set(level,p0); - - HashMap h = (HashMap) args.get(level); - h.clear(); - for(int i=p1.getLength()-1;i>-1;i--) { - h.put(p1.getName(i),p1.getValue(i)); - } - - // Now notify any TagListeners - Iterator it = tagListeners.iterator(); - while(it.hasNext()) - ( (TagListener) it.next() ).tagStart(level,p0,h); - - // Now move up a level - level++; - } - - /** - * This is called by SAX at the end of a tag. This calls handleTag() and then - * raises the level, so that the previous parent tag may continue. - */ - public void endElement(String p0) throws SAXException { - // move up a level retrieving that level's current content - // Now this exception should never occur as the underlying parser should - // actually trap it. - if(level<1) - throw new SAXException("Already at top level?"); - level--; - - // Now notify any TagListeners - Iterator it = tagListeners.iterator(); - while(it.hasNext()) - ( (TagListener) it.next() ).tagContent(content); - - // allows large content to be released early - content.reset(); - - // Now reset content to the previous level - content=(CharArrayWriter) contents.get(level); - } - - /** - * Called by SAX so that content between the start and end tags are captured. - */ - public void characters(char[] p0, int p1, int p2) throws SAXException { - content.write(p0,p1,p2); - } - - /** - * Adds a TagListener so that it is notified of tags as they are processed. - * @param handler TagListener to add - */ - public void addTagListener(TagListener h) { - tagListeners.add(h); - } - - /** - * Removes the TagListener so it no longer receives notifications of tags - */ - public void removeTagListener(TagListener h) { - tagListeners.remove(h); - } - - /** - * This method returns a org.xml.sax.Parser object that will parse the - * contents of a URI. - * - *

Normally you would call this method, then call the parse(uri) method of - * the returned object. - * @return org.xml.sax.Parser object - */ - public Parser getParser() - throws SAXException - { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - - String validation = System.getProperty ("javax.xml.parsers.validation", "false"); - if (validation.equalsIgnoreCase("true")) - spf.setValidating (true); - - SAXParser sp = spf.newSAXParser(); - Parser parser = sp.getParser (); - - parser.setDocumentHandler(this); - - return(parser); - } catch(ParserConfigurationException pce) { - throw new SAXException(pce.toString()); - } - } - - /** - * This method will parse the specified URI. - * - *

Internally this is the same as getParser().parse(uri); - * @param uri The URI to parse - */ - public void parse(String uri) - throws IOException, SAXException - { - getParser().parse(uri); - } - - /** - * This method will parse the specified InputSource. - * - *

Internally this is the same as getParser().parse(is); - * @param is The InputSource to parse - */ - public void parse(InputSource is) - throws IOException, SAXException - { - getParser().parse(is); - } - -} \ No newline at end of file diff --git a/contrib/retep/uk/org/retep/xml/parser/TagListener.java b/contrib/retep/uk/org/retep/xml/parser/TagListener.java deleted file mode 100644 index 24146b3e24..0000000000 --- a/contrib/retep/uk/org/retep/xml/parser/TagListener.java +++ /dev/null @@ -1,30 +0,0 @@ -package uk.org.retep.xml.parser; - -import java.util.HashMap; -import java.io.CharArrayWriter; - -/** - * This interface defines the methods a class needs to implement if it wants the - * xml parser to notify it of any xml tags. - */ - -public interface TagListener { - /** - * This is called when a tag has just been started. - *

NB: args is volatile, so if you use it beyond the lifetime of - * this call, then you must make a copy of the HashMap (and not use simply - * store this HashMap). - * @param level The number of tags above this - * @param tag The tag name - * @param args A HashMap of any arguments - */ - public void tagStart(int level,String tag,HashMap args); - /** - * This method is called by ContHandler to process a tag once it has been - * fully processed. - *

NB: content is volatile, so you must copy its contents if you use - * it beyond the lifetime of this call. - * @param content CharArrayWriter containing the content of the tag. - */ - public void tagContent(CharArrayWriter content); -} \ No newline at end of file diff --git a/contrib/retep/uk/org/retep/xml/test/XMLExport.java b/contrib/retep/uk/org/retep/xml/test/XMLExport.java deleted file mode 100644 index 116f250906..0000000000 --- a/contrib/retep/uk/org/retep/xml/test/XMLExport.java +++ /dev/null @@ -1,191 +0,0 @@ -package uk.org.retep.xml.test; - -import java.lang.Exception; -import java.io.*; -import java.sql.*; -import java.util.Properties; -import uk.org.retep.xml.core.XMLFactoryException; -import uk.org.retep.xml.jdbc.XMLDatabase; -import uk.org.retep.xml.jdbc.XMLResultSet; - -/** - * This "test" class is a fully functional tool in its own right. It utilises - * the xml classes to query and export to XML, or to dump database structures - * into XML. - */ - -public class XMLExport -{ - /** - * The current Database Connection - */ - protected Connection conn; - protected Statement stat; - protected String drvr,url,table; - - protected XMLResultSet xrs; - protected XMLDatabase xdb; - protected Properties prop; - protected boolean outXML; - protected boolean outDTD; - protected boolean outTAB; - protected int maxRows=0; - - public XMLExport(String[] args) - throws IOException,SQLException,XMLFactoryException,ClassNotFoundException - { - xrs = new XMLResultSet(); - xrs.setWriter(new OutputStreamWriter(System.out)); - //Properties p = new Properties(xrs.getDefaultProperties()); - prop = (Properties) xrs.getDefaultProperties().clone(); - - xdb = new XMLDatabase(xrs.getXMLFactory()); - - for(int i=0;i2) { - String table=arg.substring(2); - System.out.println("Generating XML Schema of table "+table); - xdb.writeTable(conn,table); - xdb.close(); - } else { - System.out.println("Generating XML Schema of database"); - xdb.writeDatabase(conn); - xdb.close(); - } - } else if(arg.equals("-V")) { - // Select table output - outXML=outDTD=false; - } else if(arg.equals("-X")) { - // Select XML output - outXML=true; - outDTD=outTAB=false; - } else if(arg.equals("-Y")) { - // Select DTD output - outXML=outTAB=false; - outDTD=true; - } else if(arg.startsWith("-")) { - System.err.println("Unknown argument: "+arg); - System.exit(1); - } else { - // Ok, anything not starting with "-" are queries - if(stat==null) - stat=conn.createStatement(); - - System.out.println("Executing "+arg); - ResultSet rs = stat.executeQuery(arg); - if(rs!=null) { - if(outXML) { - xrs.translate(rs,prop); - xrs.close(); - } else if(outDTD) { - // Output the DTD - xrs.buildDTD(rs,prop); - xrs.close(); - } else { - // Normal resultset output - int rc=0; - - ResultSetMetaData rsmd = rs.getMetaData(); - int nc = rsmd.getColumnCount(); - boolean us=false; - for(int c=0;c 0) -{ - printf STDERR "Snapshot applied\n"; -} -elsif ($res != 0) -{ - printf STDERR "ERROR\n"; - exit(1); -} - -exit(0); diff --git a/contrib/rserv/CleanLog.in b/contrib/rserv/CleanLog.in deleted file mode 100644 index f15baea0b1..0000000000 --- a/contrib/rserv/CleanLog.in +++ /dev/null @@ -1,49 +0,0 @@ -# -*- perl -*- -# CleanLog -# Vadim Mikheev, (c) 2000, PostgreSQL Inc. - -eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' - & eval 'exec perl -S $0 $argv:q' - if 0; - -use lib "@LIBDIR@"; - -use Getopt::Long; -use RServ; - -$| = 1; - -$result = GetOptions("debug!", "verbose!", "help", "snapshot=s", - "host=s", "user=s", "password=s"); - -my $debug = $opt_debug || 0; -my $verbose = $opt_verbose || 0; -my $snapshot = $opt_snapshot || "__Snapshot"; - -if (defined($opt_help) || (scalar(@ARGV) < 2) || ($ARGV[1] !~ /^\d+$/)) { - print "Usage: $PROGRAM_NAME --host=name --user=name --password=string masterdb syncid\n"; - exit ((scalar(@ARGV) < 2)? 1: 0); -} - -my $dbname = $ARGV[0]; -my $howold = $ARGV[1]; - -my $minfo = "dbname=$dbname"; -$minfo = "$minfo host=$opt_host" if (defined($opt_host)); -$minfo = "$minfo user=$opt_user" if (defined($opt_user)); -$minfo = "$minfo password=$opt_password" if (defined($opt_password)); - -print "Master connection is $minfo\n" if ($debug); -print "Slave connection is $sinfo\n" if ($debug); - -my $conn = Pg::connectdb($minfo); - -$RServ::quiet = !$verbose; - -$res = CleanLog($conn, $howold); - -exit(1) if $res < 0; - -printf STDERR "Deleted %d log records\n", $res if $res > 0; - -exit(0); diff --git a/contrib/rserv/GetSyncID.in b/contrib/rserv/GetSyncID.in deleted file mode 100644 index 10f4a93e47..0000000000 --- a/contrib/rserv/GetSyncID.in +++ /dev/null @@ -1,57 +0,0 @@ -# -*- perl -*- -# GetSyncID -# Vadim Mikheev, (c) 2000, PostgreSQL Inc. - -eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' - & eval 'exec perl -S $0 $argv:q' - if 0; - -use lib "@LIBDIR@"; - -use Pg; -use Getopt::Long; -use RServ; - -$| = 1; - -my $verbose = 1; - -$result = GetOptions("debug!", "verbose!", "help", - "host=s", "user=s", "password=s"); - -my $debug = $opt_debug || 0; -my $verbose = $opt_verbose if (defined($opt_verbose)); - -if (defined($opt_help) || (scalar(@ARGV) < 1)) { - print "Usage: $0 --host=name --user=name --password=string slavedb\n"; - exit ((scalar(@ARGV) < 1)? 1: 0); -} - -my $dbname = $ARGV[0]; - -my $sinfo = "dbname=$dbname"; -$sinfo = "$sinfo host=$opt_host" if (defined($opt_host)); -$sinfo = "$sinfo user=$opt_user" if (defined($opt_user)); -$sinfo = "$sinfo password=$opt_password" if (defined($opt_password)); - -print("Connecting to '$sinfo'\n") if ($debug || $verbose); -my $conn = Pg::connectdb($sinfo); - -$RServ::quiet = !$verbose; - -$res = GetSyncID($conn); - -die "ERROR\n" if $res < 0; - -if (! defined $res) -{ - printf STDERR "No SyncID found\n"; -} -else -{ - print("Last SyncID applied: ") if ($verbose); - printf "%d", $res; - print("\n") if ($verbose); -} - -exit(0); diff --git a/contrib/rserv/InitRservTest.in b/contrib/rserv/InitRservTest.in deleted file mode 100644 index 414744c6c0..0000000000 --- a/contrib/rserv/InitRservTest.in +++ /dev/null @@ -1,259 +0,0 @@ -#!/bin/sh -# InitRservTest -# erServer demonstration implementation -# (c) 2000 Vadim Mikheev, PostgreSQL Inc. - -[ -n "$RSERV_PERL" ] || RSERV_PERL=@LIBDIR@ -[ -n "$RSERV_SQL" ] || RSERV_SQL=@SQLDIR@ -[ -n "$RSERV_BIN" ] || RSERV_BIN=@BINDIR@ -export RSERV_PERL -export RSERV_SQL -export RSERV_BIN - -pargs= - -while [[ $1 == -* ]]; do - case "$1" in - --user) - shift - pargs="$pargs -U $1" - ;; - --host) - shift - pargs="$pargs -h $1" - ;; - *) - echo "Usage: $0 --user name --host name masterdb slavedb" - exit 1 - ;; - esac - shift -done - -masterdb=$1 -slavedb=$2 - -[ "${masterdb}" != "" ] || masterdb=master -[ "${slavedb}" != "" ] || slavedb=slave - -echo "Master -> $masterdb" -echo "Slave -> $slavedb" - -############################################################################ - -fill() -{ - table="create table test (i text, k int, l int); -copy test from stdin; -Line: 1 1 1 -Line: 2 2 2 -Line: 3 3 3 -Line: 4 4 4 -Line: 5 5 5 -Line: 6 6 6 -Line: 7 7 7 -Line: 8 8 8 -Line: 9 9 9 -Line: 10 10 10 -Line: 11 11 11 -Line: 12 12 12 -Line: 13 13 13 -Line: 14 14 14 -Line: 15 15 15 -Line: 16 16 16 -Line: 17 17 17 -Line: 18 18 18 -Line: 19 19 19 -Line: 20 20 20 -Line: 21 21 21 -Line: 22 22 22 -Line: 23 23 23 -Line: 24 24 24 -Line: 25 25 25 -Line: 26 26 26 -Line: 27 27 27 -Line: 28 28 28 -Line: 29 29 29 -Line: 30 30 30 -Line: 31 31 31 -Line: 32 32 32 -Line: 33 33 33 -Line: 34 34 34 -Line: 35 35 35 -Line: 36 36 36 -Line: 37 37 37 -Line: 38 38 38 -Line: 39 39 39 -Line: 40 40 40 -Line: 41 41 41 -Line: 42 42 42 -Line: 43 43 43 -Line: 44 44 44 -Line: 45 45 45 -Line: 46 46 46 -Line: 47 47 47 -Line: 48 48 48 -Line: 49 49 49 -Line: 50 50 50 -Line: 51 51 51 -Line: 52 52 52 -Line: 53 53 53 -Line: 54 54 54 -Line: 55 55 55 -Line: 56 56 56 -Line: 57 57 57 -Line: 58 58 58 -Line: 59 59 59 -Line: 60 60 60 -Line: 61 61 61 -Line: 62 62 62 -Line: 63 63 63 -Line: 64 64 64 -Line: 65 65 65 -Line: 66 66 66 -Line: 67 67 67 -Line: 68 68 68 -Line: 69 69 69 -Line: 70 70 70 -Line: 71 71 71 -Line: 72 72 72 -Line: 73 73 73 -Line: 74 74 74 -Line: 75 75 75 -Line: 76 76 76 -Line: 77 77 77 -Line: 78 78 78 -Line: 79 79 79 -Line: 80 80 80 -Line: 81 81 81 -Line: 82 82 82 -Line: 83 83 83 -Line: 84 84 84 -Line: 85 85 85 -Line: 86 86 86 -Line: 87 87 87 -Line: 88 88 88 -Line: 89 89 89 -Line: 90 90 90 -Line: 91 91 91 -Line: 92 92 92 -Line: 93 93 93 -Line: 94 94 94 -Line: 95 95 95 -Line: 96 96 96 -Line: 97 97 97 -Line: 98 98 98 -Line: 99 99 99 -Line: 100 100 100 -\\."; - echo "$table" | psql $pargs $1 || exit - if [ "$1" = "$masterdb" ] - then - rm -rf __tmpf__ - psql $pargs -c "select * into table testoid from test" $1 || exit - psql $pargs -c "copy testoid with oids to '`pwd`/__tmpf__'" $1 || exit - psql $pargs -c "select * into table teststr from test" $1 || exit - else - psql $pargs -c "select * into table testoid from test where k < 0" $1 || exit - psql $pargs -c "copy testoid with oids from '`pwd`/__tmpf__'" $1 || exit - psql $pargs -c "select * into table teststr from test" $1 || exit - rm -rf __tmpf__ - fi - psql $pargs -c "create unique index i_test on test (k)" $1 || exit - psql $pargs -c "create unique index i_testoid on testoid (oid)" $1 || exit - psql $pargs -c "create unique index i_teststr on teststr (i)" $1 || exit - psql $pargs -c vacuum $1 || exit -} - -############################################################################ - -echo -echo -echo ' ATTENTION' -echo -echo This script will destroy databases with names MASTER and SLAVE -echo -echo -n "Are you going to continue ? [Y/N] " - -read answ - -case $answ in - Y*|y*) - ;; - *) - exit - ;; -esac - -echo -echo - -sql="drop database $masterdb" -echo $sql -psql $pargs -c "$sql" template1 -sql="create database $masterdb" -echo $sql -psql $pargs -c "$sql" template1 || exit - -echo Setup master system -psql $pargs $masterdb < $RSERV_SQL/master.sql || exit - -echo Wait for template1 to become available... -sleep 1 - -sql="drop database $slavedb" -echo $sql -psql $pargs -c "$sql" template1 -sql="create database $slavedb" -echo $sql -psql $pargs -c "$sql" template1 || exit - -echo Setup slave system -psql $pargs $slavedb < $RSERV_SQL/slave.sql || exit - -echo Create and fill test, testoid and teststr tables in master db -fill $masterdb -echo -echo Register test, testoid and teststr tables for replication on master -echo -$RSERV_BIN/MasterAddTable $masterdb test k -$RSERV_BIN/MasterAddTable $masterdb testoid oid -$RSERV_BIN/MasterAddTable $masterdb teststr i - -echo Create and fill test, testoid and teststr tables in slave db -fill $slavedb -echo -echo Register test, testoid and teststr tables for replication on slave -echo -$RSERV_BIN/SlaveAddTable $slavedb test k -$RSERV_BIN/SlaveAddTable $slavedb testoid oid -$RSERV_BIN/SlaveAddTable $slavedb teststr i - -echo -echo -echo -echo -echo -echo -echo -echo -echo " Now make changes in $masterdb db and run" -echo -echo " Replicate $masterdb $slavedb" -echo -echo " to replicate the master on the slave." -echo -echo " You may also use the RservTest tcl utility" -echo " to demonstrate this functionality." -echo -echo -echo -echo -echo -echo -echo -echo - -exit - -############################################################################ diff --git a/contrib/rserv/Makefile b/contrib/rserv/Makefile deleted file mode 100644 index 2725119746..0000000000 --- a/contrib/rserv/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -# Makefile for erServer demonstration implementation -# (c) 2000 Vadim Mikheev, PostgreSQL Inc. - -subdir = contrib/rserv -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -NAME = rserv -SONAME = $(NAME)$(DLSUFFIX) -SQLS = master.sql slave.sql -TCLS = RservTest -PERLS = MasterInit MasterAddTable Replicate MasterSync CleanLog -PERLS += SlaveInit SlaveAddTable GetSyncID -PERLS += PrepareSnapshot ApplySnapshot -SCRIPTS = InitRservTest - -override CPPFLAGS := -I$(srcdir) $(CPPFLAGS) -override CFLAGS += $(CFLAGS_SL) -override DLLLIBS := $(BE_DLLLIBS) $(DLLLIBS) - - -all: $(SQLS) $(TCLS) $(PERLS) $(SCRIPTS) $(SONAME) - -%.sql: %.sql.in - sed 's,@MODULE_FILENAME@,$$libdir/$(NAME),g' $< >$@ - -$(PERLS) $(TCLS) $(SCRIPTS): %: %.in - sed -e 's,@MODULE_FILENAME@,$$libdir/$(NAME),g' \ - -e 's:@SQLDIR@:$(datadir)/contrib:g' \ - -e 's:@BINDIR@:$(bindir):g' \ - -e 's:@LIBDIR@:$(datadir)/contrib:g' $< >$@ - chmod a+x $@ - - -install: all installdirs - for file in $(SQLS); do \ - $(INSTALL_DATA) $$file $(DESTDIR)$(datadir)/contrib || exit ; \ - done - for file in $(TCLS) $(PERLS) $(SCRIPTS); do \ - $(INSTALL_SCRIPT) $$file $(DESTDIR)$(bindir) || exit ; \ - done - $(INSTALL_DATA) $(srcdir)/RServ.pm $(DESTDIR)$(datadir)/contrib - $(INSTALL_SHLIB) $(SONAME) $(DESTDIR)$(pkglibdir) - $(INSTALL_DATA) $(srcdir)/README.$(NAME) $(DESTDIR)$(docdir)/contrib - -installdirs: - $(mkinstalldirs) $(DESTDIR)$(bindir) $(DESTDIR)$(datadir)/contrib \ - $(DESTDIR)$(pkglibdir) $(DESTDIR)$(docdir)/contrib - - -clean distclean maintainer-clean: - rm -f $(SQLS) $(TCLS) $(PERLS) $(SCRIPTS) $(SONAME) $(NAME).o diff --git a/contrib/rserv/MasterAddTable.in b/contrib/rserv/MasterAddTable.in deleted file mode 100644 index 3d92b47cbd..0000000000 --- a/contrib/rserv/MasterAddTable.in +++ /dev/null @@ -1,61 +0,0 @@ -# -*- perl -*- -# MasterAddTable -# Vadim Mikheev, (c) 2000, PostgreSQL Inc. - -eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' - & eval 'exec perl -S $0 $argv:q' - if 0; - -use Pg; -use Getopt::Long; - -$| = 1; - -$result = GetOptions("debug!", "verbose!", "help", - "host=s", "user=s", "password=s"); - -my $debug = $opt_debug || 0; -my $verbose = $opt_verbose || 0; - -if (defined($opt_help) || (scalar(@ARGV) < 3)) { - print "Usage: $0 --host=name --user=name --password=string masterdb table column\n"; - exit ((scalar(@ARGV) < 3)? 1: 0); -} - -my $dbname = $ARGV[0]; -my $table = $ARGV[1]; -my $keyname = $ARGV[2]; - -my $minfo = "dbname=$dbname"; -$minfo = "$minfo host=$opt_host" if (defined($opt_host)); -$minfo = "$minfo user=$opt_user" if (defined($opt_user)); -$minfo = "$minfo password=$opt_password" if (defined($opt_password)); - -my $conn = Pg::connectdb($minfo); - -my $result = $conn->exec("BEGIN"); -die $conn->errorMessage if $result->resultStatus ne PGRES_COMMAND_OK; - -$result = $conn->exec("select pgc.oid, pga.attnum from pg_class pgc" . - ", pg_attribute pga where pgc.relname = '$table'" . - " and pgc.oid = pga.attrelid" . - " and pga.attname = '$keyname'"); -die $conn->errorMessage if $result->resultStatus ne PGRES_TUPLES_OK; - -my @row = $result->fetchrow; -die "Can't find table/key\n" if ! defined $row[0] || ! defined $row[1]; - -$result = $conn->exec("create trigger _RSERV_TRIGGER_T_ after" . - " insert or update or delete on $table" . - " for each row execute procedure" . - " _rserv_log_('$row[1]')"); -die $conn->errorMessage if $result->resultStatus ne PGRES_COMMAND_OK; - -$result = $conn->exec("insert into _RSERV_TABLES_ (tname, cname, reloid, key)" . - " values ('$table', '$keyname', $row[0], $row[1])"); -die $conn->errorMessage if $result->resultStatus ne PGRES_COMMAND_OK; - -$result = $conn->exec("COMMIT"); -die $conn->errorMessage if $result->resultStatus ne PGRES_COMMAND_OK; - -exit(0); diff --git a/contrib/rserv/MasterInit.in b/contrib/rserv/MasterInit.in deleted file mode 100644 index 68854c743a..0000000000 --- a/contrib/rserv/MasterInit.in +++ /dev/null @@ -1,107 +0,0 @@ -# -*- perl -*- -# MasterInit -# Vadim Mikheev, (c) 2000, PostgreSQL Inc. - -eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' - & eval 'exec perl -S $0 $argv:q' - if 0; - -use Pg; -use Getopt::Long; - -$| = 1; - -$result = GetOptions("debug!", "verbose!", "help", - "host=s", "user=s", "password=s"); - -my $debug = $opt_debug || 0; -my $verbose = $opt_verbose || 0; - -if (defined($opt_help) || (scalar(@ARGV) < 1)) { - print "Usage: $0 --host=name --user=name --password=string masterdb\n"; - exit ((scalar(@ARGV) < 1)? 1:0); -} - -my $master = $ARGV[0] || "master"; - -my $minfo = "dbname=$master"; -$minfo = "$minfo host=$opt_host" if (defined($opt_host)); -$minfo = "$minfo user=$opt_user" if (defined($opt_user)); -$minfo = "$minfo password=$opt_password" if (defined($opt_password)); - -sub RollbackAndQuit { - $conn = shift @_; - - print STDERR "Error in query: ", $conn->errorMessage; - $conn->exec("ROLLBACK"); - exit (-1); -} - -my $conn = Pg::connectdb($minfo); -if ($conn->status != PGRES_CONNECTION_OK) { - print STDERR "Failed opening $minfo\n"; - exit 1; -} - -my $result = $conn->exec("BEGIN"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -$result = $conn->exec("set transaction isolation level serializable"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -# List of slave servers -$result = $conn->exec("create table _RSERV_SERVERS_" . - " (server serial, host text, post int4, dbase text)"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -# List of replicated tables -$result = $conn->exec("create table _RSERV_TABLES_" . - " (tname name, cname name, reloid oid, key int4)"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -# Bookkeeping log for row replication -$result = $conn->exec("create table _RSERV_LOG_" . - " (reloid oid, logid int4, logtime timestamp, deleted int4, key text)"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -# This is to speedup lookup of deleted tuples -$result = $conn->exec("create index _RSERV_LOG_INDX_DLT_ID_ on _RSERV_LOG_ (deleted, logid)"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -# This is to speedup cleanup -$result = $conn->exec("create index _RSERV_LOG_INDX_TM_ID_ on _RSERV_LOG_ (logtime, logid)"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -# This is to speedup trigger and lookup of updated tuples -$result = $conn->exec("create index _RSERV_LOG_INDX_REL_KEY_ on _RSERV_LOG_ (reloid, key)"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -# Sync point for each slave server -$result = $conn->exec("create table _RSERV_SYNC_" . - " (server int4, syncid int4, synctime timestamp" . - ", status int4, minid int4, maxid int4, active text)"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -$result = $conn->exec("create index _RSERV_SYNC_INDX_SRV_ID_ on _RSERV_SYNC_ (server, syncid)"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -# Sync point reference numbers -$result = $conn->exec("create sequence _rserv_sync_seq_"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -$result = $conn->exec("CREATE FUNCTION _rserv_log_() RETURNS opaque" . - " AS '@MODULE_FILENAME@' LANGUAGE 'c'"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -$result = $conn->exec("CREATE FUNCTION _rserv_sync_(int4) RETURNS int4" . - " AS '@MODULE_FILENAME@' LANGUAGE 'c'"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -$result = $conn->exec("CREATE FUNCTION _rserv_debug_(int4) RETURNS int4" . - " AS '@MODULE_FILENAME@' LANGUAGE 'c'"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -$result = $conn->exec("COMMIT"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -exit (0); diff --git a/contrib/rserv/MasterSync.in b/contrib/rserv/MasterSync.in deleted file mode 100644 index 8328d78cc1..0000000000 --- a/contrib/rserv/MasterSync.in +++ /dev/null @@ -1,50 +0,0 @@ -# -*- perl -*- -# MasterSync -# Vadim Mikheev, (c) 2000, PostgreSQL Inc. - -eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' - & eval 'exec perl -S $0 $argv:q' - if 0; - -use lib "@LIBDIR@"; - -use Getopt::Long; -use RServ; - -$| = 1; - -$result = GetOptions("debug!", "verbose!", "quiet!", "help", - "host=s", "user=s", "password=s"); - -my $debug = $opt_debug || 0; -my $verbose = $opt_verbose || 0; -my $quiet = $opt_quiet || 0; - -if (defined($opt_help) || (scalar(@ARGV) < 2) || ($ARGV[1] !~ /^\d+$/)) { - print "Usage: $0 --host=name --user=name --password=string masterdb syncid\n"; - exit ((scalar(@ARGV) < 2)? 1:0); -} - -my $master = $ARGV[0] || "master"; -my $server = 0; -my $syncid = $ARGV[1] || die "SyncID not specified"; - -my $minfo = "dbname=$master"; -$minfo = "$minfo host=$opt_host" if (defined($opt_host)); -$minfo = "$minfo user=$opt_user" if (defined($opt_user)); -$minfo = "$minfo password=$opt_password" if (defined($opt_password)); - -my $conn = Pg::connectdb($minfo); - -$RServ::quiet = !$verbose; - -$res = SyncSyncID($conn, $server, $syncid); - -if ($res == 0) -{ - printf STDERR "SyncID updated on $master\n" if ($verbose); - exit(0); -} - -printf STDERR "ERROR\n" unless ($quiet); -exit(1); diff --git a/contrib/rserv/PrepareSnapshot.in b/contrib/rserv/PrepareSnapshot.in deleted file mode 100644 index bd0fa237dc..0000000000 --- a/contrib/rserv/PrepareSnapshot.in +++ /dev/null @@ -1,58 +0,0 @@ -# -*- perl -*- -# PrepareSnapshot -# Vadim Mikheev, (c) 2000, PostgreSQL Inc. - -eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' - & eval 'exec perl -S $0 $argv:q' - if 0; - -use lib "@LIBDIR@"; - -use IO::File; -use Getopt::Long; -use RServ; - -$| = 1; - -$result = GetOptions("debug!", "verbose!", "help", "snapshot=s", - "host=s", "user=s", "password=s"); - -my $debug = $opt_debug || 0; -my $verbose = $opt_verbose || 0; -my $snapshot = $opt_snapshot || "__Snapshot"; - -if (defined($opt_help) || (scalar(@ARGV) < 1)) { - print "Usage: $0 --snapshot=file --host=name --user=name --password=string masterdb\n"; - exit ((scalar(@ARGV) < 1)? 1:0); -} - -my $master = $ARGV[0] || "master"; -my $server = 0; - -my $minfo = "dbname=$master"; -$minfo = "$minfo host=$opt_host" if (defined($opt_host)); -$minfo = "$minfo user=$opt_user" if (defined($opt_user)); -$minfo = "$minfo password=$opt_password" if (defined($opt_password)); - -my $conn = Pg::connectdb($minfo); - -my $outf = new IO::File; -$outf = STDOUT; - -$RServ::quiet = !$verbose; - -$res = PrepareSnapshot ($conn, $outf, $server); - -if ($res == 0) -{ - printf STDERR "Sync-ed\n"; - exit(0); -} -if ($res > 0) -{ - printf STDERR "Snapshot dumped to STDOUT\n"; - exit(0); -} - -printf STDERR "ERROR\n"; -exit(1); diff --git a/contrib/rserv/README.rserv b/contrib/rserv/README.rserv deleted file mode 100644 index 1a61fefd2d..0000000000 --- a/contrib/rserv/README.rserv +++ /dev/null @@ -1,133 +0,0 @@ -erServer demonstration implementation -(c) 2000, Vadim Mikheev and Thomas Lockhart, PostgreSQL Inc. - -Version 0.1: - Replicates a master database to a single slave database. - Tested under Linux (Mandrake 7.2). - -Requirements: - -- PostgreSQL >= 7.0.X - A separate Makefile is required for PostgreSQL 7.0.x and earlier -- Perl5 and the PostgreSQL perl interface -- TCL and the PostgreSQL tcl interface (for demo only) - - -How to compile: - -- make all -- make install - -Scripts and libraries are installed in places which are consistant -with the way other contrib/ code is installed; underneath the core -items in a contrib/ directory. - - -The toolset: - -MasterInit dbname - sets up structures and user-defined functions for a master - database. - -SlaveInit dbname - sets up structures for a slave database. Does not include triggers, - but only bookkeeping tables. - -MasterAddTable dbname table column - sets up triggers for the specified table and column. Note that this - column must be updated for replication to occur. - -SlaveAddTable dbname table column - sets up bookkeeping for the specified table and column. - -Replicate masterdb slavedb - actually replicate changes from a master to single slave. Note that - this must be repeated to replicate to multiple slaves, but the - bookkeeping for each slave is handled separately so each can be - updated at different times and with different sets of changes. - -GetSyncID [--noverbose] slavedb - returns the last syncid the specified slave has seen. May be used - in conjunction with SyncSyncID and CleanLog using the --noverbose - option. - -MasterSync masterdb syncid - registers a syncid with the specified master database. Used to - propagate replication success back to the master database. - -CleanLog masterdb syncid - removes obsolete entries in the master database replication log - table up to the specified replication sequence number. - -Other utilities: - -PrepareSnapshot - build a file of replication information from the specified masterdb. - -ApplySnapshot - use a file of replication information to apply to the specified - slavedb. - - -How to run a demo: - -Run the InitRservTest script. It will create two local databases -'master' & 'slave' with table 'test' in them. It accepts the following -arguments: - --help - Print a usage message and quit. - --user name - Access the database with another username. - --host name - Access a remote database. Note that the shared library *must* be - visible in the same path as installed on the build machine. - masterdb - slavedb - Names of test databases. Defaults to 'master' and 'slave', - respectively. - -Once the test databases are set up, simply updating the master table -is sufficient to log a replication event. You can update the table -test then run "Replicate master slave", or you can use the demo -program RservTest. - -Run the tcl/tk GUI demo program, RservTest. It has a single window, -which has four buttons and three data entry boxes. - - -------------------------------------------------- - | PostgreSQL Asynchronous Replication | - | Master Slave | - | < master > < slave > | - | | - | [ Update ] < > | - | [ Replicate ] | - | [ Show ] ____________ | - | | - | [ Quit ] | - | | - -------------------------------------------------- - -The demo has the following behaviors: - -If you enter a string into the data entry field to the right of -[Update], then that string will be used to either update the master -database or to query the slave database. - -If you click [Update], then the string in the data entry box will be -entered into the master database. - -If you click [Replicate], then all changes since the last replication -will be propagated to the slave database. - -If you click [Show], then the slave database will be queried to find -the string in the data entry box to the right of the [Update] -button. If the string does not (yet) exist in the slave database, then -"n/a" will appear to the right of the [Show] button. If the string -does exist in the slave database, then it will be printed to the right -of the [Show] button. - - -Todo: -1. Support for multiple slave servers. -2. Explicit support for master/slave failover. -3. More docs. diff --git a/contrib/rserv/RServ.pm b/contrib/rserv/RServ.pm deleted file mode 100644 index de0f037cbe..0000000000 --- a/contrib/rserv/RServ.pm +++ /dev/null @@ -1,761 +0,0 @@ -# -*- perl -*- -# RServ.pm -# Vadim Mikheev, (c) 2000, PostgreSQL Inc. - -package RServ; - -require Exporter; -@ISA = qw(Exporter); -@EXPORT = qw(PrepareSnapshot ApplySnapshot GetSyncID SyncSyncID CleanLog); -@EXPORT_OK = qw(); - -use Pg; - -$debug = 0; -$quiet = 1; - -my %Mtables = (); -my %Stables = (); - -sub PrepareSnapshot -{ - my ($conn, $outf, $server) = @_; # (@_[0], @_[1], @_[2]); - - my $result = $conn->exec("BEGIN"); - if ($result->resultStatus ne PGRES_COMMAND_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - $result = $conn->exec("set transaction isolation level serializable"); - if ($result->resultStatus ne PGRES_COMMAND_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - - # MAP oid --> tabname, keyname - $result = $conn->exec("select pgc.oid, pgc.relname, pga.attname" . - " from _RSERV_TABLES_ rt, pg_class pgc, pg_attribute pga" . - " where pgc.oid = rt.reloid and pga.attrelid = rt.reloid" . - " and pga.attnum = rt.key"); - if ($result->resultStatus ne PGRES_TUPLES_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - - my @row; - while (@row = $result->fetchrow) - { - # printf "$row[0], $row[1], $row[2]\n"; - push @{$Mtables{$row[0]}}, $row[1], $row[2]; - } - - # Read last succeeded sync - $sql = "select syncid, synctime, minid, maxid, active from _RSERV_SYNC_" . - " where server = $server and syncid = (select max(syncid) from" . - " _RSERV_SYNC_ where server = $server and status > 0)"; - - printf "$sql\n" if $debug; - - $result = $conn->exec($sql); - if ($result->resultStatus ne PGRES_TUPLES_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - - my @lastsync = $result->fetchrow; - - my $sinfo = ""; - if ($lastsync[3] ne '') # sync info - { - $sinfo = "and (l.logid >= $lastsync[3]"; - $sinfo .= " or l.logid in ($lastsync[4])" if $lastsync[4] ne ''; - $sinfo .= ")"; - } - - my $havedeal = 0; - - # DELETED rows - $sql = "select l.reloid, l.key from _RSERV_LOG_ l" . - " where l.deleted = 1 $sinfo order by l.reloid"; - - printf "$sql\n" if $debug; - - $result = $conn->exec($sql); - if ($result->resultStatus ne PGRES_TUPLES_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - - $lastoid = ''; - while (@row = $result->fetchrow) - { - next unless exists $Mtables{$row[0]}; - if ($lastoid != $row[0]) - { - if ($lastoid eq '') - { - my $syncid = GetSYNCID($conn, $outf); - return($syncid) if $syncid < 0; - $havedeal = 1; - } - else - { - printf $outf "\\.\n"; - } - printf $outf "-- DELETE $Mtables{$row[0]}[0]\n"; - $lastoid = $row[0]; - } - if (! defined $row[1]) - { - print STDERR "NULL key\n" unless ($quiet); - $conn->exec("ROLLBACK"); - return(-2); - } - printf $outf "%s\n", OutputValue($row[1]); - } - printf $outf "\\.\n" if $lastoid ne ''; - - # UPDATED rows - - my ($taboid, $tabname, $tabkey); - foreach $taboid (keys %Mtables) - { - ($tabname, $tabkey) = @{$Mtables{$taboid}}; - my $oidkey = ($tabkey eq 'oid') ? "_$tabname.oid," : ''; - $sql = sprintf "select $oidkey _$tabname.* from _RSERV_LOG_ l," . - " $tabname _$tabname where l.reloid = $taboid and l.deleted = 0 $sinfo" . - " and l.key = _$tabname.${tabkey}::text"; - - printf "$sql\n" if $debug; - - $result = $conn->exec($sql); - if ($result->resultStatus ne PGRES_TUPLES_OK) - { - printf $outf "-- ERROR\n" if $havedeal; - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - next if $result->ntuples <= 0; - if (! $havedeal) - { - my $syncid = GetSYNCID($conn, $outf); - return($syncid) if $syncid < 0; - $havedeal = 1; - } - printf $outf "-- UPDATE $tabname\n"; - while (@row = $result->fetchrow) - { - for ($i = 0; $i <= $#row; $i++) - { - printf $outf " " if $i; - printf $outf "%s", OutputValue($row[$i]); - } - printf $outf "\n"; - } - printf $outf "\\.\n"; - } - - unless ($havedeal) - { - $conn->exec("ROLLBACK"); - return(0); - } - - # Remember this snapshot info - $result = $conn->exec("select _rserv_sync_($server)"); - if ($result->resultStatus ne PGRES_TUPLES_OK) - { - printf $outf "-- ERROR\n"; - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - - $result = $conn->exec("COMMIT"); - if ($result->resultStatus ne PGRES_COMMAND_OK) - { - printf $outf "-- ERROR\n"; - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - printf $outf "-- OK\n"; - - return(1); - -} - -sub OutputValue -{ - my ($val) = @_; # @_[0]; - - return("\\N") unless defined $val; - - $val =~ s/\\/\\\\/g; - $val =~ s/ /\\011/g; - $val =~ s/\n/\\012/g; - $val =~ s/\'/\\047/g; - - return($val); -} - -# Get syncid for new snapshot -sub GetSYNCID -{ - my ($conn, $outf) = @_; # (@_[0], @_[1]); - - my $result = $conn->exec("select nextval('_rserv_sync_seq_')"); - if ($result->resultStatus ne PGRES_TUPLES_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - - my @row = $result->fetchrow; - - printf $outf "-- SYNCID $row[0]\n"; - return($row[0]); -} - - -sub CleanLog -{ - my ($conn, $howold) = @_; # (@_[0], @_[1]); - - my $result = $conn->exec("BEGIN"); - if ($result->resultStatus ne PGRES_COMMAND_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - - my $sql = "select rs.maxid, rs.active from _RSERV_SYNC_ rs" . - " where rs.syncid = (select max(rs2.syncid) from _RSERV_SYNC_ rs2" . - " where rs2.server = rs.server and rs2.status > 0) order by rs.maxid"; - - printf "$sql\n" if $debug; - - $result = $conn->exec($sql); - if ($result->resultStatus ne PGRES_TUPLES_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - return(-1); - } - my $maxid = ''; - my %active = (); - while (my @row = $result->fetchrow) - { - $maxid = $row[0] if $maxid eq ''; - last if $row[0] > $maxid; - my @ids = split(/[ ]+,[ ]+/, $row[1]); - foreach $aid (@ids) - { - $active{$aid} = 1 unless exists $active{$aid}; - } - } - if ($maxid eq '') - { - print STDERR "No Sync IDs\n" unless ($quiet); - return(0); - } - my $alist = join(',', keys %active); - my $sinfo = "logid < $maxid"; - $sinfo .= " and logid not in ($alist)" if $alist ne ''; - - $sql = "delete from _RSERV_LOG_ where " . - "logtime < now() - '$howold second'::interval and $sinfo"; - - printf "$sql\n" if $debug; - - $result = $conn->exec($sql); - if ($result->resultStatus ne PGRES_COMMAND_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - $maxid = $result->cmdTuples; - - $result = $conn->exec("COMMIT"); - if ($result->resultStatus ne PGRES_COMMAND_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - - return($maxid); -} - -sub ApplySnapshot -{ - my ($conn, $inpf) = @_; # (@_[0], @_[1]); - - my $result = $conn->exec("BEGIN"); - if ($result->resultStatus ne PGRES_COMMAND_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - - $result = $conn->exec("SET CONSTRAINTS ALL DEFERRED"); - if ($result->resultStatus ne PGRES_COMMAND_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - - # MAP name --> oid, keyname, keynum - my $sql = "select pgc.oid, pgc.relname, pga.attname, rt.key" . - " from _RSERV_SLAVE_TABLES_ rt, pg_class pgc, pg_attribute pga" . - " where pgc.oid = rt.reloid and pga.attrelid = rt.reloid" . - " and pga.attnum = rt.key"; - $result = $conn->exec($sql); - if ($result->resultStatus ne PGRES_TUPLES_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - - while (@row = $result->fetchrow) - { - # printf " %s %s\n", $row[1], $row[0]; - push @{$Stables{$row[1]}}, $row[0], $row[2], $row[3]; - } - - my $ok = 0; - my $syncid = ''; - while(<$inpf>) - { - $_ =~ s/\n//; - my ($cmt, $cmd, $prm) = split (/[ ]+/, $_, 3); - if ($cmt ne '--') - { - printf STDERR "Invalid format\n" unless ($quiet); - $conn->exec("ROLLBACK"); - return(-2); - } - if ($cmd eq 'DELETE') - { - if ($syncid eq '') - { - printf STDERR "Sync ID unspecified\n" unless ($quiet); - $conn->exec("ROLLBACK"); - return(-2); - } - $result = DoDelete($conn, $inpf, $prm); - if ($result) - { - $conn->exec("ROLLBACK"); - return($result); - } - } - elsif ($cmd eq 'UPDATE') - { - if ($syncid eq '') - { - printf STDERR "Sync ID unspecified\n" unless ($quiet); - $conn->exec("ROLLBACK"); - return(-2); - } - $result = DoUpdate($conn, $inpf, $prm); - if ($result) - { - $conn->exec("ROLLBACK"); - return($result); - } - } - elsif ($cmd eq 'SYNCID') - { - if ($syncid ne '') - { - printf STDERR "Second Sync ID ?!\n" unless ($quiet); - $conn->exec("ROLLBACK"); - return(-2); - } - if ($prm !~ /^\d+$/) - { - printf STDERR "Invalid Sync ID $prm\n" unless ($quiet); - $conn->exec("ROLLBACK"); - return(-2); - } - $syncid = $prm; - - printf STDERR "Sync ID $syncid\n" unless ($quiet); - - $result = $conn->exec("select syncid, synctime from " . - "_RSERV_SLAVE_SYNC_ where syncid = " . - "(select max(syncid) from _RSERV_SLAVE_SYNC_)"); - if ($result->resultStatus ne PGRES_TUPLES_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - my @row = $result->fetchrow; - if (! defined $row[0]) - { - $result = $conn->exec("insert into" . - " _RSERV_SLAVE_SYNC_(syncid, synctime) values ($syncid, now())"); - } - elsif ($row[0] >= $prm) - { - printf STDERR "Sync-ed to ID $row[0] ($row[1])\n" unless ($quiet); - $conn->exec("ROLLBACK"); - return(0); - } - else - { - $result = $conn->exec("update _RSERV_SLAVE_SYNC_" . - " set syncid = $syncid, synctime = now()"); - } - if ($result->resultStatus ne PGRES_COMMAND_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - } - elsif ($cmd eq 'OK') - { - $ok = 1; - last; - } - elsif ($cmd eq 'ERROR') - { - printf STDERR "ERROR signaled\n" unless ($quiet); - $conn->exec("ROLLBACK"); - return(-2); - } - else - { - printf STDERR "Unknown command $cmd\n" unless ($quiet); - $conn->exec("ROLLBACK"); - return(-2); - } - } - - if (! $ok) - { - printf STDERR "No OK flag in input\n" unless ($quiet); - $conn->exec("ROLLBACK"); - return(-2); - } - - $result = $conn->exec("COMMIT"); - if ($result->resultStatus ne PGRES_COMMAND_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - - return(1); -} - -sub DoDelete -{ - my ($conn, $inpf, $tabname) = @_; # (@_[0], @_[1], @_[2]); - - my $ok = 0; - while(<$inpf>) - { - if ($_ !~ /\n$/) - { - printf STDERR "Invalid format\n" unless ($quiet); - return(-2); - } - my $key = $_; - $key =~ s/\n//; - if ($key eq '\.') - { - $ok = 1; - last; - } - - my $sql = "delete from $tabname where $Stables{$tabname}->[1] = '$key'"; - - printf "$sql\n" if $debug; - - my $result = $conn->exec($sql); - if ($result->resultStatus ne PGRES_COMMAND_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - return(-1); - } - } - - if (! $ok) - { - printf STDERR "No end of input in DELETE section\n" unless ($quiet); - return(-2); - } - - return(0); -} - - -sub DoUpdate -{ - my ($conn, $inpf, $tabname) = @_; # (@_[0], @_[1], @_[2]); - my $oidkey = ($Stables{$tabname}->[2] < 0) ? 1 : 0; - - my @CopyBuf = (); - my $CBufLen = 0; - my $CBufMax = 16 * 1024 * 1024; # max size of buf for copy - - my $sql = "select attnum, attname from pg_attribute" . - " where attrelid = $Stables{$tabname}->[0] and attnum > 0"; - - my $result = $conn->exec($sql); - if ($result->resultStatus ne PGRES_TUPLES_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - return(-1); - } - - my @anames = (); - while (@row = $result->fetchrow) - { - $anames[$row[0]] = $row[1]; - } - - my $istring; - my $ok = 0; - while(<$inpf>) - { - if ($_ !~ /\n$/) - { - printf STDERR "Invalid format\n" unless ($quiet); - return(-2); - } - $istring = $_; - $istring =~ s/\n//; - if ($istring eq '\.') - { - $ok = 1; - last; - } - my @vals = split(/ /, $istring); - if ($oidkey) - { - if ($vals[0] !~ /^\d+$/ || $vals[0] <= 0) - { - printf STDERR "Invalid OID\n" unless ($quiet); - return(-2); - } - $oidkey = $vals[0]; - } - else - { - unshift @vals, ''; - } - - $sql = "update $tabname set "; - my $ocnt = 0; - for (my $i = 1; $i <= $#anames; $i++) - { - if ($vals[$i] eq '\N') - { - if ($i == $Stables{$tabname}->[2]) - { - printf STDERR "NULL key\n" unless ($quiet); - return(-2); - } - $vals[$i] = 'null'; - } - else - { - $vals[$i] = "'" . $vals[$i] . "'"; - next if $i == $Stables{$tabname}->[2]; - } - $ocnt++; - $sql .= ', ' if $ocnt > 1; - $sql .= "$anames[$i] = $vals[$i]"; - } - if ($oidkey) - { - $sql .= " where $Stables{$tabname}->[1] = $oidkey"; - } - else - { - $sql .= " where $Stables{$tabname}->[1] = $vals[$Stables{$tabname}->[2]]"; - } - - printf "$sql\n" if $debug; - - $result = $conn->exec($sql); - if ($result->resultStatus ne PGRES_COMMAND_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - return(-1); - } - next if $result->cmdTuples == 1; # updated - - if ($result->cmdTuples > 1) - { - printf STDERR "Duplicate keys\n" unless ($quiet); - return(-2); - } - - # no key - copy - push @CopyBuf, "$istring\n"; - $CBufLen += length($istring); - - if ($CBufLen >= $CBufMax) - { - $result = DoCopy($conn, $tabname, $oidkey, \@CopyBuf); - return($result) if $result; - @CopyBuf = (); - $CBufLen = 0; - } - } - - if (! $ok) - { - printf STDERR "No end of input in UPDATE section\n" unless ($quiet); - return(-2); - } - - if ($CBufLen) - { - $result = DoCopy($conn, $tabname, $oidkey, \@CopyBuf); - return($result) if $result; - } - - return(0); -} - - -sub DoCopy -{ - my ($conn, $tabname, $withoids, $CBuf) = @_; # (@_[0], @_[1], @_[2], @_[3]); - - my $sql = "COPY $tabname " . (($withoids) ? "WITH OIDS " : '') . -"FROM STDIN"; - my $result = $conn->exec($sql); - if ($result->resultStatus ne PGRES_COPY_IN) - { - print STDERR $conn->errorMessage unless ($quiet); - return(-1); - } - - foreach $str (@{$CBuf}) - { - $conn->putline($str); - } - - $conn->putline("\\.\n"); - - if ($conn->endcopy) - { - print STDERR $conn->errorMessage unless ($quiet); - return(-1); - } - - return(0); - -} - - -# -# Returns last SyncID applied on Slave -# -sub GetSyncID -{ - my ($conn) = @_; # (@_[0]); - - my $result = $conn->exec("select max(syncid) from _RSERV_SLAVE_SYNC_"); - if ($result->resultStatus ne PGRES_TUPLES_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - return(-1); - } - my @row = $result->fetchrow; - return(undef) unless defined $row[0]; # null - return($row[0]); -} - -# -# Updates _RSERV_SYNC_ on Master with Slave SyncID -# -sub SyncSyncID -{ - my ($conn, $server, $syncid) = @_; # (@_[0], @_[1], @_[2]); - - my $result = $conn->exec("BEGIN"); - if ($result->resultStatus ne PGRES_COMMAND_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - - $result = $conn->exec("select synctime, status from _RSERV_SYNC_" . - " where server = $server and syncid = $syncid" . - " for update"); - if ($result->resultStatus ne PGRES_TUPLES_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - my @row = $result->fetchrow; - if (! defined $row[0]) - { - printf STDERR "No SyncID $syncid found for server $server\n" unless ($quiet); - $conn->exec("ROLLBACK"); - return(0); - } - if ($row[1] > 0) - { - printf STDERR "SyncID $syncid for server $server already updated\n" unless ($quiet); - $conn->exec("ROLLBACK"); - return(0); - } - $result = $conn->exec("update _RSERV_SYNC_" . - " set synctime = now(), status = 1" . - " where server = $server and syncid = $syncid"); - if ($result->resultStatus ne PGRES_COMMAND_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - $result = $conn->exec("delete from _RSERV_SYNC_" . - " where server = $server and syncid < $syncid"); - if ($result->resultStatus ne PGRES_COMMAND_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - - $result = $conn->exec("COMMIT"); - if ($result->resultStatus ne PGRES_COMMAND_OK) - { - print STDERR $conn->errorMessage unless ($quiet); - $conn->exec("ROLLBACK"); - return(-1); - } - - return(1); -} - -1; diff --git a/contrib/rserv/Replicate.in b/contrib/rserv/Replicate.in deleted file mode 100644 index bd7c089a59..0000000000 --- a/contrib/rserv/Replicate.in +++ /dev/null @@ -1,102 +0,0 @@ -# -*- perl -*- -# Replicate -# Vadim Mikheev, (c) 2000, PostgreSQL Inc. - -eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' - & eval 'exec perl -S $0 $argv:q' - if 0; - -use lib "@LIBDIR@"; - -use IO::File; -use Getopt::Long; -use RServ; - -$| = 1; - -$result = GetOptions("debug!", "verbose!", "help", "snapshot=s", - "masterhost=s", "slavehost=s", "host=s", - "masteruser=s", "slaveuser=s", "user=s", - "masterpassword=s", "slavepassword=s", "password=s"); - -my $debug = $opt_debug || 0; -my $verbose = $opt_verbose || 0; -my $snapshot = $opt_snapshot || "__Snapshot"; - -if (defined($opt_help) || (scalar(@ARGV) < 2)) { - print "Usage: $0 --snapshot=file --host=name --user=name --password=string masterdb slavedb\n"; - print "\t--masterhost=name --masteruser=name --masterpassword=string\n"; - print "\t--slavehost=name --slaveuser=name --slavepassword=string\n"; - exit ((scalar(@ARGV) < 2)? 1:0); -} - -my $master = $ARGV[0] || "master"; -my $slave = $ARGV[1] || "slave"; -my $server = 0; - -my $minfo = "dbname=$master"; -$minfo = "$minfo host=$opt_masterhost" if (defined($opt_masterhost)); -$minfo = "$minfo user=$opt_masteruser" if (defined($opt_masteruser)); -$minfo = "$minfo password=$opt_masterpassword" if (defined($opt_masterpassword)); -my $sinfo = "dbname=$slave"; -$sinfo = "$sinfo host=$opt_slavehost" if (defined($opt_slavehost)); -$sinfo = "$sinfo user=$opt_slaveuser" if (defined($opt_slaveuser)); -$sinfo = "$sinfo password=$opt_slavepassword" if (defined($opt_slavepassword)); - -print "Master connection is $minfo\n" if ($debug); -print "Slave connection is $sinfo\n" if ($debug); - -my $mconn = Pg::connectdb($minfo); -my $sconn = Pg::connectdb($sinfo); - -$RServ::quiet = !$verbose; - -SyncSync($mconn, $sconn); - -my $outf = new IO::File; -open $outf, ">$snapshot"; -print "\n>>>>>>>>>>>>> Prepare Snapshot\n\n" if ($verbose); -$res = PrepareSnapshot($mconn, $outf, $server); -close $outf; -die "\n>>>>>>>>>>>>> ERROR\n" if $res < 0; -if ($res == 0) -{ - print "\n>>>>>>>>>>>>> DBases are sync-ed\n" if ($verbose); - exit(0); -} - -my $inpf = new IO::File; -open $inpf, "<$snapshot"; -print "\n>>>>>>>>>>>>> Apply Snapshot\n\n" if ($verbose); -$res = ApplySnapshot($sconn, $inpf); -close $inpf; -die "\n>>>>>>>>>>>>> ERROR\n" if $res < 0; - -if ($res > 0) -{ - print "Snapshot applied\n" if ($verbose); - unlink $snapshot unless ($debug); - SyncSync($mconn, $sconn); -} - -exit(0); - -########################################################################### - -sub SyncSync -{ - ($mconn, $sconn) = @_; - - print "\n>>>>>>>>>>>>> Sync SyncID\n\n" if ($verbose); - print "Get last SyncID from Slave DB\n" if ($verbose); - $syncid = GetSyncID($sconn); - if ($syncid > 0) - { - print "Last SyncID applied: $syncid\n" if ($verbose); - print "Sync SyncID\n" if ($verbose); - - $res = SyncSyncID($mconn, $server, $syncid); - - print "Succeeded\n" if (($res > 0) && ($verbose)); - } -} diff --git a/contrib/rserv/RservTest.in b/contrib/rserv/RservTest.in deleted file mode 100644 index 252c3226e1..0000000000 --- a/contrib/rserv/RservTest.in +++ /dev/null @@ -1,313 +0,0 @@ -#!/bin/sh -# pgserv.tcl -# (c) 2000 Thomas Lockhart, PostgreSQL Inc. -# The next line will reinvoke as wish *DO NOT REMOVE OR ALTER* \ -exec wish "$0" "$@" - -puts "Starting Replication Server demo" - -set RSERV_BIN "@BINDIR@" - -# Bring in the interfaces we will be using... - -#package require Pgtcl -load libpgtcl[info sharedlibextension] - -# elog -# Information or error log and exit handler -proc {elog} {level message} { - global show - switch -exact -- $level { - DEBUG { - if {$show(debug)} { - puts "DEBUG $message" - } - } - ERROR { - if {$show(error)} { - puts "ERROR $message" - } - FATAL { - if ($show(error)} { - puts "FATAL $message" - } - exit 1 - } - default { - puts "INFO $message" - } - } -} - -proc {ShowUsage} {} { - global argv0 - puts "Usage: $argv0 --host name --user name --password string masterdb slavedb" - puts "\t--masterhost name --masteruser name --masterpassword string" - puts "\t--slavehost name --slaveuser name --slavepassword string" -} - -# Initial values for database access -# master, slave variables are tied to text input boxes, -# and will be updated on user input -proc {SetDbInfo} {db name {host ""} {user ""} {pass ""}} { - global dbinfo - set dbinfo($db,name) $name - set dbinfo($db,host) $host - set dbinfo($db,user) $user - set dbinfo($db,pass) $pass -} - -# ConnInfo -# Connection information for pgtcl library -proc {ConnInfo} {{db master}} { - global dbinfo - set ci "dbname=$dbinfo($db,name)" - if {[string length $dbinfo($db,host)] > 0} { - set ci "$ci host=$dbinfo($db,host)" - } - if {[string length $dbinfo($db,user)] > 0} { - set ci "$ci user=$dbinfo($db,user)" - } - if {[string length $dbinfo($db,pass)] > 0} { - set ci "$ci password=$dbinfo($db,pass)" - } -# puts "Construct conninfo $ci" - return $ci -} - -# ConnInfoParams -# Connection information for (perl) callable programs -proc {ConnInfoParams} {{db master}} { - global dbinfo - set ci "" - if {[string length $dbinfo($db,host)] > 0} { - set ci "$ci --host=$dbinfo($db,host)" - } - if {[string length $dbinfo($db,user)] > 0} { - set ci "$ci --user=$dbinfo($db,user)" - } - if {[string length $dbinfo($db,pass)] > 0} { - set ci "$ci --password=$dbinfo($db,pass)" - } -# puts "Construct conninfo $ci" - return $ci -} - -# ConnInfoMaster -# Connection information for (perl) callable programs -proc {ConnInfoMaster} {{db master}} { - global dbinfo - set ci $dbinfo($db,name) - if {[string length $dbinfo($db,host)] > 0} { - set ci "$ci --masterhost=$dbinfo($db,host)" - } - if {[string length $dbinfo($db,user)] > 0} { - set ci "$ci --masteruser=$dbinfo($db,user)" - } - if {[string length $dbinfo($db,pass)] > 0} { - set ci "$ci --masterpassword=$dbinfo($db,pass)" - } -# puts "Construct conninfo $ci" - return $ci -} - -# ConnInfoSlave -# Connection information for (perl) callable programs -proc {ConnInfoSlave} {{db slave}} { - global dbinfo - set ci $dbinfo($db,name) - if {[string length $dbinfo($db,host)] > 0} { - set ci "$ci --slavehost=$dbinfo($db,host)" - } - if {[string length $dbinfo($db,user)] > 0} { - set ci "$ci --slaveuser=$dbinfo($db,user)" - } - if {[string length $dbinfo($db,pass)] > 0} { - set ci "$ci --slavepassword=$dbinfo($db,pass)" - } -# puts "Construct conninfo $ci" - return $ci -} - - -SetDbInfo master master localhost -SetDbInfo slave slave localhost -set dbinfo(snapshot,name) "__Snapshot" - -set update "" - -set show(debug) 1 -set show(error) 1 - -set argi 0 -while {$argi < $argc} { -# puts "argi is $argi; argc is $argc" - set arg [lindex $argv $argi] - switch -glob -- $arg { - -h - - --host { - incr argi - set dbinfo(master,host) [lindex $argv $argi] - set dbinfo(slave,host) [lindex $argv $argi] - } - --masterhost { - incr argi - set dbinfo(master,host) [lindex $argv $argi] - } - --slavehost { - incr argi - set dbinfo(slave,host) [lindex $argv $argi] - } - -u - - --user { - incr argi - set dbinfo(master,user) [lindex $argv $argi] - set dbinfo(slave,user) [lindex $argv $argi] - } - --masteruser { - incr argi - set dbinfo(master,user) [lindex $argv $argi] - } - --slaveuser { - incr argi - set dbinfo(slave,user) [lindex $argv $argi] - } - -s - - --snapshot { - incr argi - set dbinfo(snapshot,name) [lindex $argv $argi] - } - -* { - elog ERROR "$argv0: invalid parameter '$arg'" - ShowUsage - exit 1 - } - default { - break - } - } - incr argi -} - -if {$argi < $argc} { - set dbinfo(master,name) [lindex $argv $argi] - incr argi -} -if {$argi < $argc} { - set dbinfo(slave,name) [lindex $argv $argi] - incr argi -} -if {$argi < $argc} { - elog "$argv0: too many parameters" - ShowUsage - exit 1 -} - -elog DEBUG "User is $dbinfo(master,user) $dbinfo(slave,user)" -elog DEBUG "Host is $dbinfo(master,host) $dbinfo(slave,host)" - -# -# TK layout -# - -wm title . "Async Replication" - -wm geom . 400x400 - -proc {CreateResultFrame} {b l w} { - pack [frame $b -borderwidth 10] -fill x - pack [button $b.run -text $l -command $l -width $w] -side left -# pack [entry $b.e -textvariable NewRow] -side left -} - -set t .top -pack [frame $t -borderwidth 10] -fill x -pack [frame $t.h -borderwidth 10] -fill x -pack [label $t.h.h -text "PostgreSQL Async Replication Server"] - -set b .b -pack [frame $b -borderwidth 10] -fill x -pack [frame $b.l -borderwidth 10] -fill x -pack [label $b.l.ml -text "Master"] -side left -pack [label $b.l.sl -text "Slave"] -side right -pack [entry $b.m -textvariable dbinfo(master,name) -width 25] -side left -pack [entry $b.s -textvariable dbinfo(slave,name) -width 25] -side right - -set b .u -pack [frame $b -borderwidth 10] -fill x -pack [button $b.run -text update -command Update -width 10] -side left -pack [entry $b.e -textvariable update -width 50] -side left - -set r [CreateResultFrame .r Replicate 10] - -set b .s -pack [frame $b -borderwidth 10] -fill x -pack [button $b.b -text Show -command Show -width 10] -side left -pack [label $b.e -text ""] -side left - -set b .button -pack [frame $b -borderwidth 10] -fill x - -pack [button $b.quit -text "Quit" -command Shutdown] - -# -# Functions mapped to buttons -# - -proc {Update} {} { - global dbinfo - global update - - elog DEBUG "Opening database [ConnInfo master]..." - set res [catch {set db [pg_connect -conninfo "[ConnInfo master]"]} msg] - if {$res} { - elog ERROR "Database '$dbinfo(master,name)' is not available: $res ($msg)" - } else { - elog DEBUG "Insert $update into database $dbinfo(master,name)..." - set res [pg_exec $db "insert into test select '$update', max(k)+1, max(l)+1 from test"] - elog DEBUG [pg_result $res -status] - catch {pg_disconnect $db} - } -} - -proc {Replicate} {} { - global dbinfo - global RSERV_BIN - - elog DEBUG "Replicating [ConnInfoCmd master]..." - exec "$RSERV_BIN/Replicate" --snapshot=$dbinfo(snapshot,name) [ConnInfoParams] [ConnInfoMaster] [ConnInfoSlave] -} - -proc {Show} {} { - global dbinfo - global update - - elog DEBUG "Opening database [ConnInfo slave]..." - set res [catch {set db [pg_connect -conninfo "[ConnInfo slave]"]} msg] - if {$res} { - elog ERROR "DB $dbinfo(slave,name) not available: $res ($msg)" - } else { - elog DEBUG "Select $update from database $dbinfo(slave,name)..." - set res [pg_exec $db "select i from test where i='$update'"] - if {[pg_result $res -status] != "PGRES_TUPLES_OK"} { - .s.e config -text "n/a" - } else { - set ntups [pg_result $res -numTuples] - if {$ntups <= 0} { - .s.e config -text "n/a" - } else { - for {set i 0} {$i < $ntups} {incr i} { - set val [pg_result $res -getTuple $i] - .s.e config -text $val - } - } - pg_result $res -clear - } - catch {pg_disconnect $db} - } -} - -proc {Shutdown} {} { - global dbinfo - exit -} diff --git a/contrib/rserv/SlaveAddTable.in b/contrib/rserv/SlaveAddTable.in deleted file mode 100644 index 432e922aa2..0000000000 --- a/contrib/rserv/SlaveAddTable.in +++ /dev/null @@ -1,59 +0,0 @@ -# -*- perl -*- -# SlaveAddTable -# Vadim Mikheev, (c) 2000, PostgreSQL Inc. - -eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' - & eval 'exec perl -S $0 $argv:q' - if 0; - -use Pg; -use Getopt::Long; - -$| = 1; - -$result = GetOptions("debug!", "verbose!", "help", - "host=s", "user=s", "password=s"); - -my $debug = $opt_debug || 0; -my $verbose = $opt_verbose || 0; - -if (defined($opt_help) || (scalar(@ARGV) < 3)) { - print "Usage: $0 --host=name --user=name --password=string slavedb table column\n"; - exit ((scalar(@ARGV) < 3)? 1: 0); -} - -my $dbname = $ARGV[0]; -my $table = $ARGV[1]; -my $keyname = $ARGV[2]; - -my $sinfo = "dbname=$dbname"; -$sinfo = "$sinfo host=$opt_host" if (defined($opt_host)); -$sinfo = "$sinfo user=$opt_user" if (defined($opt_user)); -$sinfo = "$sinfo password=$opt_password" if (defined($opt_password)); - -my $dbname = $ARGV[0]; -my $table = $ARGV[1]; -my $keyname = $ARGV[2]; - -my $conn = Pg::connectdb($sinfo); - -my $result = $conn->exec("BEGIN"); -die $conn->errorMessage if $result->resultStatus ne PGRES_COMMAND_OK; - -$result = $conn->exec("select pgc.oid, pga.attnum from pg_class pgc" . - ", pg_attribute pga" . - " where pgc.relname = '$table' and pgc.oid = pga.attrelid" . - " and pga.attname = '$keyname'"); -die $conn->errorMessage if $result->resultStatus ne PGRES_TUPLES_OK; - -my @row = $result->fetchrow; -die "Can't find table/key\n" if ! defined $row[0] || ! defined $row[1]; - -$result = $conn->exec("insert into _RSERV_SLAVE_TABLES_ (tname, cname, reloid, key)" . - " values ('$table', '$keyname', $row[0], $row[1])"); -die $conn->errorMessage if $result->resultStatus ne PGRES_COMMAND_OK; - -$result = $conn->exec("COMMIT"); -die $conn->errorMessage if $result->resultStatus ne PGRES_COMMAND_OK; - -exit(0); diff --git a/contrib/rserv/SlaveInit.in b/contrib/rserv/SlaveInit.in deleted file mode 100644 index bbe152fe8e..0000000000 --- a/contrib/rserv/SlaveInit.in +++ /dev/null @@ -1,65 +0,0 @@ -# -*- perl -*- -# SlaveInit -# Vadim Mikheev, (c) 2000, PostgreSQL Inc. - -eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' - & eval 'exec perl -S $0 $argv:q' - if 0; - -use Pg; -use Getopt::Long; - -$| = 1; - -$result = GetOptions("debug!", "verbose!", "quiet!", "help", - "host=s", "user=s", "password=s"); - -my $debug = $opt_debug || 0; -my $verbose = $opt_verbose || 0; -my $quiet = $opt_quiet || 0; - -if (defined($opt_help) || (scalar(@ARGV) < 1)) { - print "Usage: $0 --host=name --user=name --password=string slavedb\n"; - exit ((scalar(@ARGV) < 1)? 1:0); -} - -my $slave = $ARGV[0] || "slave"; - -my $sinfo = "dbname=$slave"; -$sinfo = "$sinfo host=$opt_host" if (defined($opt_host)); -$sinfo = "$sinfo user=$opt_user" if (defined($opt_user)); -$sinfo = "$sinfo password=$opt_password" if (defined($opt_password)); - -sub RollbackAndQuit { - my $conn = shift @_; - - print STDERR $conn->errorMessage; - $conn->exec("ROLLBACK"); - exit (-1); -} - -print("Connecting to $sinfo\n") if ($debug || $verbose); -my $conn = Pg::connectdb($sinfo); -if ($conn->status != PGRES_CONNECTION_OK) { - print STDERR "Failed opening $sinfo\n"; - exit 1; -} - -my $result = $conn->exec("BEGIN"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -$result = $conn->exec("set transaction isolation level serializable"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -$result = $conn->exec("create table _RSERV_SLAVE_TABLES_" . - " (tname name, cname name, reloid oid, key int4)"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -$result = $conn->exec("create table _RSERV_SLAVE_SYNC_" . - " (syncid int4, synctime timestamp)"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -$result = $conn->exec("COMMIT"); -RollbackAndQuit($conn) if ($result->resultStatus ne PGRES_COMMAND_OK); - -exit (0); diff --git a/contrib/rserv/master.sql.in b/contrib/rserv/master.sql.in deleted file mode 100644 index f8d37148b9..0000000000 --- a/contrib/rserv/master.sql.in +++ /dev/null @@ -1,101 +0,0 @@ --- erServer --- Master server setup for erServer demonstration implementation --- (c) 2000 Vadim Mikheev, PostgreSQL Inc. --- - --- --- Slave servers --- -drop table _RSERV_SERVERS_; - -create table _RSERV_SERVERS_ -( - server int4, -- slave server id - host text, -- server' host - port int4, -- server' port - dbase text -- db name -); - - --- --- Tables to sync --- -drop table _RSERV_TABLES_; - -create table _RSERV_TABLES_ -( - tname name, -- table name - cname name, -- column name - reloid oid, -- table oid - key int4 -- key attnum -); - - --- --- Log for inserts/updates/deletes to sync-ed tables --- -drop table _RSERV_LOG_; - -create table _RSERV_LOG_ -( - reloid oid, - logid int4, -- xid of last update xaction - logtime timestamp, -- last update xaction start time - deleted int4, -- deleted or inserted/updated - key text -- -); - --- This is to speedup lookup deleted tuples -create index _RSERV_LOG_INDX_DLT_ID_ on _RSERV_LOG_ (deleted, logid); - --- This is to speedup cleanup -create index _RSERV_LOG_INDX_TM_ID_ on _RSERV_LOG_ (logtime, logid); - --- This is to speedup trigger and lookup updated tuples -create index _RSERV_LOG_INDX_REL_KEY_ on _RSERV_LOG_ (reloid, key); - - --- --- How much each slave servers are sync-ed --- -drop table _RSERV_SYNC_; - -create table _RSERV_SYNC_ -( - server int4, - syncid int4, -- from _rserv_sync_seq_ - synctime timestamp, -- - status int4, -- prepared (0) | applied - minid int4, -- min xid from serializable snapshot - maxid int4, -- max xid from serializable snapshot - active text -- list of active xactions -); - -create index _RSERV_SYNC_INDX_SRV_ID_ on _RSERV_SYNC_ (server, syncid); - -drop sequence _rserv_sync_seq_; -create sequence _rserv_sync_seq_; - -drop function _rserv_log_(); - -CREATE FUNCTION _rserv_log_() - RETURNS opaque - AS '@MODULE_FILENAME@' - LANGUAGE 'c' -; - -drop function _rserv_sync_(int4); - -CREATE FUNCTION _rserv_sync_(int4) - RETURNS int4 - AS '@MODULE_FILENAME@' - LANGUAGE 'c' -; - -drop function _rserv_debug_(int4); - -CREATE FUNCTION _rserv_debug_(int4) - RETURNS int4 - AS '@MODULE_FILENAME@' - LANGUAGE 'c' -; diff --git a/contrib/rserv/regress.sh b/contrib/rserv/regress.sh deleted file mode 100755 index 96ca481934..0000000000 --- a/contrib/rserv/regress.sh +++ /dev/null @@ -1,32 +0,0 @@ -# regress.sh -# rserv regression test script -# (c) 2000 Thomas Lockhart, PostgreSQL Inc. - -dropdb master -dropdb slave - -createdb master -createdb slave - -MasterInit master -SlaveInit slave - -psql -c "create table t1 (i int, t text, d timestamp default text 'now');" master -MasterAddTable master t1 d - -psql -c "create table t1 (i int, t text, d timestamp default text 'now');" slave -SlaveAddTable slave t1 d - -psql -c "insert into t1 values (1, 'one');" master -psql -c "insert into t1 values (2, 'two');" master - -Replicate master slave -MasterSync master `GetSyncID --noverbose slave` - -psql -c "insert into t1 values (3, 'three');" master -psql -c "insert into t1 values (4, 'four');" master - -Replicate master slave -MasterSync master `GetSyncID --noverbose slave` - -exit diff --git a/contrib/rserv/rserv.c b/contrib/rserv/rserv.c deleted file mode 100644 index 401cc5fd9c..0000000000 --- a/contrib/rserv/rserv.c +++ /dev/null @@ -1,329 +0,0 @@ -/* rserv.c - * Support functions for erServer replication. - * (c) 2000 Vadim Mikheev, PostgreSQL Inc. - */ - -#include "executor/spi.h" /* this is what you need to work with SPI */ -#include "commands/trigger.h" /* -"- and triggers */ -#include "utils/tqual.h" /* -"- and SnapshotData */ -#include /* tolower () */ - -#ifdef PG_FUNCTION_INFO_V1 -#define CurrentTriggerData ((TriggerData *) fcinfo->context) -#endif - -#ifdef PG_FUNCTION_INFO_V1 -PG_FUNCTION_INFO_V1(_rserv_log_); -PG_FUNCTION_INFO_V1(_rserv_sync_); -PG_FUNCTION_INFO_V1(_rserv_debug_); -Datum _rserv_log_(PG_FUNCTION_ARGS); -Datum _rserv_sync_(PG_FUNCTION_ARGS); -Datum _rserv_debug_(PG_FUNCTION_ARGS); - -#else -HeapTuple _rserv_log_(void); -int32 _rserv_sync_(int32); -int32 _rserv_debug_(int32); -#endif - -static int debug = 0; - -static char *OutputValue(char *key, char *buf, int size); - -#ifdef PG_FUNCTION_INFO_V1 -Datum -_rserv_log_(PG_FUNCTION_ARGS) -#else -HeapTuple -_rserv_log_() -#endif -{ - Trigger *trigger; /* to get trigger name */ - int nargs; /* # of args specified in CREATE TRIGGER */ - char **args; /* argument: argnum */ - Relation rel; /* triggered relation */ - HeapTuple tuple; /* tuple to return */ - HeapTuple newtuple = NULL; /* tuple to return */ - TupleDesc tupdesc; /* tuple description */ - int keynum; - char *key; - char *okey; - char *newkey = NULL; - int deleted; - char sql[8192]; - char outbuf[8192]; - char oidbuf[64]; - int ret; - - /* Called by trigger manager ? */ - if (!CurrentTriggerData) - elog(ERROR, "_rserv_log_: triggers are not initialized"); - - /* Should be called for ROW trigger */ - if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event)) - elog(ERROR, "_rserv_log_: can't process STATEMENT events"); - - tuple = CurrentTriggerData->tg_trigtuple; - - trigger = CurrentTriggerData->tg_trigger; - nargs = trigger->tgnargs; - args = trigger->tgargs; - - if (nargs != 1) /* odd number of arguments! */ - elog(ERROR, "_rserv_log_: need in *one* argument"); - - keynum = atoi(args[0]); - - if (keynum < 0 && keynum != ObjectIdAttributeNumber) - elog(ERROR, "_rserv_log_: invalid keynum %d", keynum); - - rel = CurrentTriggerData->tg_relation; - tupdesc = rel->rd_att; - - deleted = (TRIGGER_FIRED_BY_DELETE(CurrentTriggerData->tg_event)) ? - 1 : 0; - - if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event)) - newtuple = CurrentTriggerData->tg_newtuple; - -#ifndef PG_FUNCTION_INFO_V1 - - /* - * Setting CurrentTriggerData to NULL prevents direct calls to trigger - * functions in queries. Normally, trigger functions have to be called - * by trigger manager code only. - */ - CurrentTriggerData = NULL; -#endif - - /* Connect to SPI manager */ - if ((ret = SPI_connect()) < 0) - elog(ERROR, "_rserv_log_: SPI_connect returned %d", ret); - - if (keynum == ObjectIdAttributeNumber) - { - sprintf(oidbuf, "%u", tuple->t_data->t_oid); - key = oidbuf; - } - else - key = SPI_getvalue(tuple, tupdesc, keynum); - - if (key == NULL) - elog(ERROR, "_rserv_log_: key must be not null"); - - if (newtuple && keynum != ObjectIdAttributeNumber) - { - newkey = SPI_getvalue(newtuple, tupdesc, keynum); - if (newkey == NULL) - elog(ERROR, "_rserv_log_: key must be not null"); - if (strcmp(newkey, key) == 0) - newkey = NULL; - else - deleted = 1; /* old key was deleted */ - } - - if (strpbrk(key, "\\ \n'")) - okey = OutputValue(key, outbuf, sizeof(outbuf)); - else - okey = key; - - sprintf(sql, "update _RSERV_LOG_ set logid = %d, logtime = now(), " - "deleted = %d where reloid = %u and key = '%s'", - GetCurrentTransactionId(), deleted, rel->rd_id, okey); - - if (debug) - elog(DEBUG3, sql); - - ret = SPI_exec(sql, 0); - - if (ret < 0) - elog(ERROR, "_rserv_log_: SPI_exec(update) returned %d", ret); - - /* - * If no tuple was UPDATEd then do INSERT... - */ - if (SPI_processed > 1) - elog(ERROR, "_rserv_log_: duplicate tuples"); - else if (SPI_processed == 0) - { - sprintf(sql, "insert into _RSERV_LOG_ " - "(reloid, logid, logtime, deleted, key) " - "values (%u, %d, now(), %d, '%s')", - rel->rd_id, GetCurrentTransactionId(), - deleted, okey); - - if (debug) - elog(DEBUG3, sql); - - ret = SPI_exec(sql, 0); - - if (ret < 0) - elog(ERROR, "_rserv_log_: SPI_exec(insert) returned %d", ret); - } - - if (okey != key && okey != outbuf) - pfree(okey); - - if (newkey) - { - if (strpbrk(newkey, "\\ \n'")) - okey = OutputValue(newkey, outbuf, sizeof(outbuf)); - else - okey = newkey; - - sprintf(sql, "insert into _RSERV_LOG_ " - "(reloid, logid, logtime, deleted, key) " - "values (%u, %d, now(), 0, '%s')", - rel->rd_id, GetCurrentTransactionId(), okey); - - if (debug) - elog(DEBUG3, sql); - - ret = SPI_exec(sql, 0); - - if (ret < 0) - elog(ERROR, "_rserv_log_: SPI_exec returned %d", ret); - - if (okey != newkey && okey != outbuf) - pfree(okey); - } - - SPI_finish(); - -#ifdef PG_FUNCTION_INFO_V1 - return (PointerGetDatum(tuple)); -#else - return (tuple); -#endif -} - -#ifdef PG_FUNCTION_INFO_V1 -Datum -_rserv_sync_(PG_FUNCTION_ARGS) -#else -int32 -_rserv_sync_(int32 server) -#endif -{ -#ifdef PG_FUNCTION_INFO_V1 - int32 server = PG_GETARG_INT32(0); -#endif - char sql[8192]; - char buf[8192]; - char *active = buf; - uint32 xcnt; - int ret; - - if (SerializableSnapshot == NULL) - elog(ERROR, "_rserv_sync_: SerializableSnapshot is NULL"); - - buf[0] = 0; - for (xcnt = 0; xcnt < SerializableSnapshot->xcnt; xcnt++) - { - sprintf(buf + strlen(buf), "%s%u", (xcnt) ? ", " : "", - SerializableSnapshot->xip[xcnt]); - } - - if ((ret = SPI_connect()) < 0) - elog(ERROR, "_rserv_sync_: SPI_connect returned %d", ret); - - sprintf(sql, "insert into _RSERV_SYNC_ " - "(server, syncid, synctime, status, minid, maxid, active) " - "values (%u, currval('_rserv_sync_seq_'), now(), 0, %d, %d, '%s')", - server, SerializableSnapshot->xmin, SerializableSnapshot->xmax, active); - - ret = SPI_exec(sql, 0); - - if (ret < 0) - elog(ERROR, "_rserv_sync_: SPI_exec returned %d", ret); - - SPI_finish(); - - return (0); -} - -#ifdef PG_FUNCTION_INFO_V1 -Datum -_rserv_debug_(PG_FUNCTION_ARGS) -#else -int32 -_rserv_debug_(int32 newval) -#endif -{ -#ifdef PG_FUNCTION_INFO_V1 - int32 newval = PG_GETARG_INT32(0); -#endif - int32 oldval = debug; - - debug = newval; - - return (oldval); -} - -#define ExtendBy 1024 - -static char * -OutputValue(char *key, char *buf, int size) -{ - int i = 0; - char *out = buf; - char *subst = NULL; - int slen = 0; - - size--; - for (;;) - { - switch (*key) - { - case '\\': - subst = "\\\\"; - slen = 2; - break; - case ' ': - subst = "\\011"; - slen = 4; - break; - case '\n': - subst = "\\012"; - slen = 4; - break; - case '\'': - subst = "\\047"; - slen = 4; - break; - case '\0': - out[i] = 0; - return (out); - default: - slen = 1; - break; - } - - if (i + slen >= size) - { - if (out == buf) - { - out = (char *) palloc(size + ExtendBy); - strncpy(out, buf, i); - size += ExtendBy; - } - else - { - out = (char *) repalloc(out, size + ExtendBy); - size += ExtendBy; - } - } - - if (slen == 1) - out[i++] = *key; - else - { - memcpy(out + i, subst, slen); - i += slen; - } - key++; - } - - return (out); - -} diff --git a/contrib/rserv/slave.sql.in b/contrib/rserv/slave.sql.in deleted file mode 100644 index 93ac5caced..0000000000 --- a/contrib/rserv/slave.sql.in +++ /dev/null @@ -1,22 +0,0 @@ --- erServer --- Slave server setup for erServer demonstration implementation --- (c) 2000 Vadim Mikheev, PostgreSQL Inc. --- - -drop table _RSERV_SLAVE_TABLES_; - -create table _RSERV_SLAVE_TABLES_ -( - tname name, -- table name - cname name, -- column name - reloid oid, -- table oid - key int4 -- key attnum -); - -drop table _RSERV_SLAVE_SYNC_; - -create table _RSERV_SLAVE_SYNC_ -( - syncid int4, - synctime timestamp -); diff --git a/contrib/rtree_gist/Makefile b/contrib/rtree_gist/Makefile deleted file mode 100644 index 7cb8767942..0000000000 --- a/contrib/rtree_gist/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/rtree_gist/Attic/Makefile,v 1.3 2001/09/06 10:49:30 petere Exp $ - -subdir = contrib/rtree_gist -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -MODULES = rtree_gist -DATA_built = rtree_gist.sql -DOCS = README.rtree_gist -REGRESS = rtree_gist - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/rtree_gist/README.rtree_gist b/contrib/rtree_gist/README.rtree_gist deleted file mode 100644 index bcc6a8ed66..0000000000 --- a/contrib/rtree_gist/README.rtree_gist +++ /dev/null @@ -1,98 +0,0 @@ -This is R-Tree implementation using GiST. -Code (for PG95) are taken from http://s2k-ftp.cs.berkeley.edu:8000/gist/pggist/ -and changed according to new version of GiST (7.1 and above) - -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. - -CHANGES: - Oct 10 MSD 2001 - - 1. Implemented new linear algorithm for picksplit - ref. ( 'New Linear Node Splitting Algorithm for R-tree', - C.H.Ang and T.C.Tan ) - - Tue May 29 17:04:16 MSD 2001 - - 1. Small fixes in polygon code - Thanks to Dave Blasby - - Mon May 28 19:42:14 MSD 2001 - - 1. Full implementation of R-tree using GiST - gist_box_ops,gist_poly_ops - 2. gist_poly_ops is lossy - 3. NULLs support - 4. works with multi-key GiST - -NOTICE: - This version will works only with postgresql version 7.1 and above - because of changes in interface of function calling. - -INSTALLATION: - - gmake - gmake install - -- load functions - psql < rtree_gist.sql - -REGRESSION TEST: - - gmake installcheck - -EXAMPLE USAGE: - - create table boxtmp (b box); - -- create index - create index bix on boxtmp using gist (b gist_box_ops); - -- query - select * from boxtmp where b && '(1000,1000,0,0)'::box; - - -BENCHMARKS: - - subdirectory bench contains benchmark suite. - Prerequisities: perl, DBI, DBD:Pg, Time::HiRes - - cd ./bench - 1. createdb TEST - 2. psql TEST < ../box.sql - 3. ./create_test.pl | psql TEST - -- change $NUM - number of rows in test dataset - 4. ./bench.pl - perl script to benchmark queries. - Run script without arguments to see available options. - - a)test without GiST index, using built-in R-Tree - ./bench.pl -d TEST - b)test R-Tree using GiST index - ./bench.pl -d TEST -g - - -RESULTS: - -1. One interesting thing is that insertion time for built-in R-Tree is - about 8 times more than ones for GiST implementation of R-Tree !!! -2. Postmaster requires much more memory for built-in R-Tree -3. Search time depends on dataset. In our case we got: - +------------+-----------+--------------+ - |Number boxes|R-tree, sec|R-tree using | - | | | GiST, sec | - +------------+-----------+--------------+ - | 10| 0.002| 0.002| - +------------+-----------+--------------+ - | 100| 0.002| 0.002| - +------------+-----------+--------------+ - | 1000| 0.002| 0.002| - +------------+-----------+--------------+ - | 10000| 0.015| 0.025| - +------------+-----------+--------------+ - | 20000| 0.029| 0.048| - +------------+-----------+--------------+ - | 40000| 0.055| 0.092| - +------------+-----------+--------------+ - | 80000| 0.113| 0.178| - +------------+-----------+--------------+ - | 160000| 0.338| 0.337| - +------------+-----------+--------------+ - | 320000| 0.674| 0.673| - +------------+-----------+--------------+ diff --git a/contrib/rtree_gist/bench/bench.pl b/contrib/rtree_gist/bench/bench.pl deleted file mode 100755 index e6bc1332cf..0000000000 --- a/contrib/rtree_gist/bench/bench.pl +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/perl -w - -use strict; -# make sure we are in a sane environment. -use DBI(); -use DBD::Pg(); -use Time::HiRes qw( usleep ualarm gettimeofday tv_interval ); -use Getopt::Std; -my %opt; -getopts('d:b:gv', \%opt); - -if ( !( scalar %opt ) ) { - print <connect('DBI:Pg:dbname='.$opt{d}) || die "Couldn't connect DB: $opt{d} !\n"; - -my $sql; -my $notice; -my $sss = '(3000,3000,2990,2990)'; -if ( $opt{g} ) { - $notice = "Testing GiST implementation of R-Tree"; - $sql = "select count(*) from boxtmp where b && '$sss'::box;"; -} else { - $notice = "Testing built-in implementation of R-Tree"; - $sql = "select count(*) from boxtmp2 where b && '$sss'::box;"; -} - -my $t0 = [gettimeofday]; -my $count=0; -my $b=$opt{b}; - -$b ||=1; -foreach ( 1..$b ) { - my @a=exec_sql($dbi,$sql); - $count=$#a; -} -my $elapsed = tv_interval ( $t0, [gettimeofday]); -print "$notice:\n"; -print "$sql\n" if ( $opt{v} ); -print "Done\n"; -print sprintf("total: %.02f sec; number: %d; for one: %.03f sec; found %d docs\n", $elapsed, $b, $elapsed/$b, $count+1 ); -$dbi -> disconnect; - -sub exec_sql { - my ($dbi, $sql, @keys) = @_; - my $sth=$dbi->prepare($sql) || die; - $sth->execute( @keys ) || die; - my $r; - my @row; - while ( defined ( $r=$sth->fetchrow_hashref ) ) { - push @row, $r; - } - $sth->finish; - return @row; -} - diff --git a/contrib/rtree_gist/bench/create_test.pl b/contrib/rtree_gist/bench/create_test.pl deleted file mode 100755 index 1c06b6863d..0000000000 --- a/contrib/rtree_gist/bench/create_test.pl +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/perl -use strict; - -my $NUM = 20000; -print "drop table boxtmp;\n"; -print "drop table boxtmp2;\n"; - -print "create table boxtmp (b box);\n"; -print "create table boxtmp2 (b box);\n"; - -srand(1); -open(DAT,">bbb.dat") || die; -foreach ( 1..$NUM ) { - #print DAT '(',int( 500+500*rand() ),',',int( 500+500*rand() ),',',int( 500*rand() ),',',int( 500*rand() ),")\n"; - my ( $x1,$y1, $x2,$y2 ) = ( - 10000*rand(), - 10000*rand(), - 10000*rand(), - 10000*rand() - ); - print DAT '(', - max($x1,$x2),',', - max($y1,$y2),',', - min($x1,$x2),',', - min($y1,$y2),")\n"; -} -close DAT; - -print "copy boxtmp from stdin;\n"; -open(DAT,"bbb.dat") || die; -while() { print; } -close DAT; -print "\\.\n"; - -print "copy boxtmp2 from stdin;\n"; -open(DAT,"bbb.dat") || die; -while() { print; } -close DAT; -print "\\.\n"; - -print "create index bix on boxtmp using gist (b gist_box_ops);\n"; -print "create index bix2 on boxtmp2 using rtree (b box_ops);\n"; - - -sub min { - return ( $_[0] < $_[1] ) ? $_[0] : $_[1]; -} -sub max { - return ( $_[0] > $_[1] ) ? $_[0] : $_[1]; -} diff --git a/contrib/rtree_gist/data/test_box.data b/contrib/rtree_gist/data/test_box.data deleted file mode 100644 index e32b6fe251..0000000000 --- a/contrib/rtree_gist/data/test_box.data +++ /dev/null @@ -1,3378 +0,0 @@ -(12699,9028,12654,8987) -(22689,4680,22614,4626) -(43263,47296,43217,47217) -(6184,8397,6182,8379) -(863,28537,788,28456) -(33783,4733,33746,4693) -(40456,47134,40426,47087) -(45950,8153,45887,8060) -(33433,36474,33399,36460) -(41106,22017,41086,21962) -(19214,36781,19179,36767) -(11582,40823,11498,40737) -(35565,5404,35546,5360) -(26489,17387,26405,17356) -(30874,13849,30796,13814) -(38255,1619,38227,1593) -(4445,32006,4405,31914) -(3923,32921,3876,32913) -(36054,39464,36032,39434) -(46540,6780,46524,6758) -(12184,45811,12118,45787) -(13198,17090,13143,17051) -(30939,44578,30865,44486) -(12502,4939,12431,4902) -(3250,1108,3169,1063) -(34029,41240,33976,41180) -(47057,44018,46967,43927) -(699,10114,686,10058) -(5925,26020,5845,25979) -(9462,39388,9382,39388) -(270,32616,226,32607) -(3959,49145,3861,49115) -(207,40886,179,40879) -(48480,43312,48412,43233) -(37183,37209,37161,37110) -(13576,13505,13521,13487) -(5877,1037,5818,1036) -(6777,16694,6776,16692) -(49362,13905,49299,13845) -(29356,14606,29313,14562) -(5492,6976,5441,6971) -(288,49588,204,49571) -(36698,37213,36682,37158) -(718,41336,645,41272) -(8725,23369,8660,23333) -(40115,9894,40025,9818) -(40051,41181,40015,41153) -(5739,1740,5715,1731) -(25120,27935,25054,27876) -(27475,46084,27447,46003) -\N -(33197,3252,33161,3245) -(10892,15691,10869,15662) -(39012,44712,38995,44640) -(4506,6484,4458,6459) -(13970,26316,13964,26236) -(28009,28104,27968,28030) -(5991,27613,5906,27607) -(23649,6338,23610,6314) -(25942,10008,25911,9928) -(25651,29943,25590,29906) -\N -(24555,40334,24546,40330) -(46870,43762,46789,43709) -\N -(20030,2752,19945,2687) -(30758,26754,30718,26678) -\N -(4320,44673,4286,44625) -\N -(1011,15576,939,15574) -(41936,40699,41854,40655) -(20594,19002,20561,18995) -(9388,41056,9325,41042) -(34771,46693,34751,46645) -(49398,46359,49332,46357) -\N -(23115,35380,23036,35306) -(46305,34840,46283,34765) -(16768,21692,16691,21647) -(28695,3128,28654,3112) -(22182,7107,22107,7074) -(14567,1210,14468,1139) -(14156,37139,14136,37119) -(33500,38351,33477,38286) -(39983,41981,39944,41954) -(26773,20824,26719,20813) -(42516,22947,42460,22932) -(26127,10701,26044,10650) -(17808,13803,17724,13710) -(14913,49873,14849,49836) -(37013,820,36955,736) -(39071,1399,39022,1381) -\N -(9785,42546,9687,42540) -(13423,14066,13354,14052) -(3417,14558,3336,14478) -(25212,46368,25128,46316) -(10124,39848,10027,39820) -(39722,39226,39656,39162) -(6298,28101,6250,28076) -(45852,5846,45809,5750) -(48292,4885,48290,4841) -(18905,4454,18894,4424) -(18965,43474,18902,43444) -(39843,28239,39761,28199) -(18087,44660,18019,44632) -(33886,10382,33794,10286) -(38383,13163,38362,13092) -(18861,25050,18842,24965) -(29887,14326,29806,14274) -(18733,11644,18698,11644) -(5119,37952,5089,37950) -(16191,34884,16149,34864) -(29544,1104,29496,1062) -(27740,41555,27701,41540) -(4672,4087,4633,4060) -(45441,38994,45377,38958) -(3272,1176,3232,1146) -(12820,26606,12790,26575) -(30910,7590,30877,7512) -(42476,39152,42377,39127) -(6562,38490,6542,38447) -(30046,20332,29988,20259) -(40723,15950,40671,15949) -(4945,46857,4908,46817) -(47986,16882,47963,16877) -(9842,22339,9805,22305) -(29831,23169,29818,23122) -(12322,34404,12250,34312) -(22846,11091,22759,10992) -(47627,2424,47603,2397) -(18375,43632,18347,43577) -(40441,974,40394,965) -(34260,10573,34194,10522) -(32914,9549,32828,9503) -(49023,37827,48978,37799) -(22183,10691,22111,10669) -\N -(38036,15828,38014,15759) -(34604,16801,34508,16746) -(26737,29997,26675,29976) -(47375,40298,47293,40210) -(771,2661,732,2649) -(28514,25659,28504,25577) -(13438,46494,13376,46455) -(7187,17877,7125,17786) -(49957,43390,49897,43384) -(26543,20067,26482,20057) -(16416,29803,16385,29724) -(36353,7484,36286,7414) -(26498,3377,26415,3358) -(28990,32205,28936,32193) -(45005,3842,45001,3816) -(21672,23566,21603,23566) -(33360,43465,33302,43429) -\N -(29884,9544,29838,9520) -\N -(5599,15012,5596,14930) -(22396,21481,22344,21422) -(24810,14955,24780,14887) -(47114,18866,47081,18784) -(39013,39245,38953,39237) -(12863,40534,12803,40529) -(351,37068,310,37019) -\N -(12916,34327,12891,34240) -\N -(49191,2694,49170,2628) -(24127,38407,24050,38325) -(3264,23053,3213,23007) -(8172,30385,8144,30336) -(19630,35716,19573,35640) -(42554,5148,42521,5117) -(42168,33453,42136,33426) -(17732,32093,17666,32057) -(1039,16626,1037,16587) -(21287,7757,21265,7679) -(47063,8260,47039,8225) -(38645,16238,38561,16204) -(18258,25358,18196,25341) -(30458,1742,30458,1695) -(35147,9273,35121,9233) -(7670,16625,7642,16545) -(49503,23432,49484,23383) -(31089,23146,31062,23093) -(47758,2734,47670,2703) -\N -(35276,1027,35259,972) -(26337,17603,26313,17579) -(35649,16777,35626,16777) -(42454,5105,42362,5101) -(21682,24951,21646,24920) -\N -(48383,25174,48303,25156) -(14672,3532,14601,3460) -(22570,22587,22515,22512) -(23566,25623,23484,25573) -(9530,24542,9504,24459) -(41271,451,41236,401) -(5556,37528,5502,37527) -(12479,25042,12447,24991) -(16568,22916,16499,22864) -(42700,13084,42676,12992) -\N -(35523,40973,35504,40932) -(32948,16962,32857,16901) -(7808,13469,7712,13469) -(13920,35203,13870,35131) -(22731,31563,22658,31557) -\N -(22909,43956,22900,43857) -(33077,35080,33074,35030) -(48064,29307,48022,29280) -(20232,46682,20212,46613) -(29949,16790,29867,16711) -(30260,32029,30180,31979) -(17184,34503,17110,34482) -(16066,42687,16039,42648) -(2947,19819,2857,19788) -(4900,47934,4818,47894) -(27193,19014,27174,18976) -\N -(15597,27948,15590,27939) -(11090,28623,11002,28589) -(26956,18651,26920,18620) -(3107,47753,3103,47711) -(6745,24151,6711,24083) -(43923,19213,43871,19124) -(33451,23578,33370,23534) -(8944,20605,8862,20601) -(14905,7536,14892,7441) -(2412,18357,2383,18354) -(37060,1443,36974,1366) -(15501,6230,15429,6190) -\N -(30333,50,30273,6) -(35567,9965,35482,9912) -(49847,7128,49798,7067) -\N -(27685,36396,27668,36384) -(43832,18491,43825,18431) -(36849,34600,36785,34589) -(2348,47938,2307,47902) -\N -(20473,22131,20445,22113) -(38486,4293,38471,4288) -(30611,30451,30553,30400) -(3883,21299,3819,21260) -(7696,37555,7644,37534) -(22399,7913,22317,7911) -(42565,38605,42500,38598) -(36595,12151,36500,12106) -(587,35217,571,35123) -(5764,15300,5764,15231) -(12003,21265,11983,21210) -(42564,4803,42470,4737) -(42359,36834,42271,36746) -(44700,14680,44658,14670) -(19690,5627,19620,5607) -(17780,43602,17714,43565) -(45073,3491,45041,3434) -(35043,2136,35017,2084) -\N -(39653,19215,39646,19198) -(23970,25560,23935,25502) -(28698,49233,28600,49223) -(30266,3605,30245,3540) -(25538,7857,25500,7791) -(17711,1757,17708,1756) -(5248,594,5190,587) -(2730,32454,2671,32436) -(1722,49089,1635,49067) -(40954,5743,40921,5722) -\N -(21382,4426,21298,4331) -(7885,18629,7872,18605) -(42838,6459,42748,6451) -(8217,19894,8207,19845) -(20489,18524,20433,18520) -(17383,23559,17309,23515) -(38952,38968,38934,38913) -(44665,18137,44636,18051) -(22416,41220,22383,41213) -(9901,664,9818,646) -(23475,21981,23449,21973) -(41875,17991,41818,17988) -(36517,47731,36509,47713) -(37595,49849,37581,49834) -(38771,32720,38748,32684) -(810,38523,736,38452) -(29695,14942,29665,14907) -(31911,15168,31906,15113) -(3454,36839,3438,36831) -(4832,47554,4820,47473) -\N -(11590,8292,11539,8272) -(8193,33323,8106,33317) -(16043,14799,16001,14710) -(19574,11395,19514,11316) -(26290,41424,26224,41342) -(22844,12516,22807,12471) -\N -(15709,49580,15655,49553) -(13387,28084,13379,28066) -(2780,38807,2690,38711) -(22031,32458,22028,32377) -(13511,3351,13440,3297) -(14648,26473,14614,26383) -(17798,19885,17726,19852) -(32355,27940,32324,27861) -(43773,21031,43767,20985) -(15419,45759,15403,45666) -(770,38863,729,38806) -(21221,35619,21183,35596) -(38924,31021,38894,30961) -(7395,32439,7345,32416) -(2324,25118,2268,25074) -(2958,15089,2935,15087) -(2424,160,2424,81) -(12123,18644,12099,18616) -(7459,30276,7422,30218) -(15847,45488,15814,45428) -(26409,29897,26389,29863) -(12336,34322,12279,34322) -(9440,23550,9396,23466) -(4991,30850,4905,30768) -(47262,11940,47201,11939) -(30584,42868,30555,42838) -(23144,24089,23056,24067) -\N -(35930,11609,35847,11573) -(7812,17271,7789,17203) -(17946,37554,17878,37480) -(27356,32869,27298,32813) -(29971,47783,29933,47697) -(26075,46494,25988,46451) -(39314,41366,39289,41269) -(31708,42900,31688,42865) -(4510,10231,4439,10203) -(43806,8482,43758,8446) -(45990,49694,45927,49617) -(48815,27640,48782,27573) -(41675,26733,41622,26723) -(23229,7709,23175,7693) -(48976,17733,48962,17731) -(10686,41470,10597,41434) -(18053,27059,17989,27012) -\N -(35495,25950,35459,25912) -(41896,45014,41881,44999) -(22654,41896,22572,41801) -(18581,7087,18524,6988) -\N -(14697,22406,14681,22311) -(40092,28122,40043,28030) -(35844,24243,35816,24238) -(1254,25653,1250,25644) -(1603,21730,1556,21640) -(33048,21779,32991,21763) -(29979,1632,29916,1592) -(8620,633,8580,620) -(22992,27035,22932,27008) -(21409,29315,21390,29309) -(3610,44748,3547,44699) -(20402,9318,20343,9267) -(31001,8709,30908,8658) -(46840,47640,46773,47551) -(49173,4705,49143,4630) -(5339,31657,5251,31622) -(8644,49668,8630,49648) -(45387,2893,45309,2885) -(47641,31020,47584,30941) -(40238,10636,40208,10568) -(19247,36924,19227,36924) -(917,19957,827,19887) -(40967,17841,40870,17820) -(15850,4109,15794,4085) -(20181,30916,20085,30870) -(161,24465,107,24374) -(21737,49690,21667,49663) -(10328,20911,10232,20852) -(24187,49823,24128,49768) -(36084,4578,36007,4501) -(38771,31741,38673,31674) -(2202,30102,2111,30006) -(27322,16074,27228,16039) -(6843,17280,6765,17248) -(16972,39744,16912,39700) -(10608,38741,10553,38708) -\N -(4917,34801,4828,34766) -(39281,33659,39268,33618) -(31706,7119,31645,7063) -(3427,44006,3422,44004) -\N -(10134,42608,10044,42599) -(26294,32080,26200,32068) -(21777,34680,21769,34606) -(23373,25957,23314,25915) -(10710,8401,10681,8400) -(42062,19458,42019,19394) -(26530,43036,26458,43004) -(3394,46081,3360,46077) -(38743,33953,38677,33924) -(32438,8226,32345,8160) -(9210,27333,9118,27301) -(19594,1600,19568,1551) -(10003,12278,9952,12255) -(31737,7206,31650,7146) -(16594,15821,16502,15759) -(28208,30296,28189,30278) -(30602,46237,30555,46185) -(20715,5155,20697,5140) -(48892,35271,48793,35210) -(3175,5590,3113,5525) -(34220,27947,34132,27865) -(35105,39792,35011,39727) -(21919,27314,21839,27286) -\N -(23963,3723,23917,3699) -(16312,14078,16236,14045) -(19233,49824,19185,49794) -(1447,11768,1356,11699) -(17311,17709,17224,17653) -(11962,31709,11871,31627) -(21355,40131,21355,40085) -(33750,35273,33724,35180) -(38896,25539,38879,25524) -(39569,44899,39569,44893) -(11075,41547,11039,41500) -(3215,12202,3199,12127) -(46215,33458,46132,33455) -(15121,38012,15083,37974) -(44448,18726,44412,18690) -(3899,38263,3870,38262) -(13854,13353,13786,13298) -(8252,5402,8191,5320) -(46849,37968,46820,37897) -(16422,13957,16376,13897) -(47369,7665,47353,7629) -(11982,40874,11956,40806) -\N -(9552,27580,9496,27562) -(32247,19399,32176,19337) -(32704,2169,32635,2091) -(7471,44213,7411,44130) -(48433,7096,48379,7089) -(37357,6543,37338,6452) -(30460,29624,30433,29535) -(20350,28794,20341,28705) -(6326,32360,6267,32317) -(1711,47519,1654,47430) -(49540,16510,49521,16426) -\N -(26975,618,26908,579) -(24118,30880,24020,30821) -(3675,15477,3625,15418) -(44953,9577,44953,9530) -(38323,7965,38235,7910) -(6629,36482,6579,36448) -(33953,16460,33878,16408) -(49222,16790,49186,16695) -(17308,16951,17274,16904) -(14135,6888,14077,6833) -(38617,47768,38603,47760) -(7345,10992,7290,10914) -(35261,42152,35176,42096) -(28586,4809,28544,4735) -(37521,25299,37495,25217) -(41941,17954,41912,17915) -(1209,46863,1171,46863) -(20103,34947,20048,34896) -(32716,33816,32656,33769) -(11113,6531,11036,6467) -(48635,7321,48563,7262) -(28435,37059,28349,37014) -(12311,17208,12232,17112) -(1466,48010,1379,48008) -(11226,11997,11223,11925) -(46896,32540,46821,32510) -(32661,31255,32632,31187) -(37739,20376,37655,20306) -(44002,43326,43920,43257) -(30337,1023,30271,968) -(34436,23357,34432,23345) -\N -(21367,8168,21353,8091) -(36370,21611,36369,21569) -(4152,36488,4080,36476) -(17696,13924,17664,13853) -(34252,19395,34159,19316) -(12574,3072,12573,2975) -(3995,21243,3943,21167) -(44553,30126,44513,30108) -\N -(4599,45275,4552,45254) -(33191,11404,33176,11348) -\N -(14245,18633,14177,18540) -(32457,20705,32393,20700) -(40052,10499,40016,10457) -(29824,44065,29785,44037) -(31613,12565,31557,12543) -(42692,29000,42652,28996) -\N -(40680,22219,40603,22140) -\N -(33575,27661,33488,27644) -(46194,1385,46184,1355) -(38442,48501,38407,48426) -(25305,21544,25236,21523) -(15562,8226,15561,8208) -\N -(20844,43614,20752,43558) -(22566,30541,22554,30532) -(2760,47802,2672,47789) -(25515,30745,25433,30675) -(48382,45134,48382,45093) -(9940,27094,9871,27087) -\N -(48690,44361,48610,44338) -(18992,11585,18899,11582) -(21551,49983,21492,49885) -(46778,29113,46770,29071) -(43219,9593,43212,9548) -(40291,1248,40224,1190) -(12687,22225,12635,22219) -(49372,38790,49306,38721) -(49503,46808,49411,46798) -(24745,5162,24732,5138) -(5046,26517,5023,26424) -(5583,46538,5495,46531) -(6084,35950,6079,35895) -(3503,23096,3437,23024) -\N -(45275,8420,45244,8418) -(13514,45251,13491,45249) -(42112,2748,42047,2668) -\N -(7810,21907,7806,21878) -(48378,36029,48303,35979) -(32568,48605,32510,48563) -(859,18915,810,18915) -(41963,17950,41939,17915) -\N -(42723,8031,42685,7955) -\N -(19587,5965,19556,5961) -(8713,33083,8629,32996) -(21243,7769,21226,7740) -(43752,43026,43720,42944) -(7883,41311,7859,41242) -(10178,47874,10157,47826) -(32177,48725,32093,48646) -(22960,2784,22953,2774) -(25101,49159,25087,49090) -(32142,48915,32086,48850) -(6636,44887,6590,44825) -(37814,11606,37769,11578) -(2870,23198,2820,23121) -(21025,16364,20947,16271) -(31341,36137,31269,36114) -(38921,7906,38888,7831) -(6966,17259,6922,17199) -(32426,13344,32401,13253) -(8084,30572,8078,30572) -(42230,47674,42150,47603) -(20724,44854,20724,44830) -(27471,38453,27454,38430) -(24590,37973,24544,37941) -(45832,26077,45772,26031) -(9589,24239,9582,24156) -(37484,49472,37409,49432) -(30044,19340,30004,19333) -(16966,14632,16936,14572) -(9439,40491,9403,40482) -(28945,5814,28913,5805) -(43788,41302,43746,41231) -(33631,43451,33614,43354) -(17590,49396,17510,49324) -(15173,32572,15109,32507) -(1912,23580,1840,23504) -(38165,16185,38076,16154) -(6729,1179,6637,1177) -\N -(6994,45406,6983,45325) -(2912,21327,2908,21305) -(14678,14244,14659,14222) -(29944,14959,29898,14900) -(47432,35658,47407,35610) -(25542,39243,25466,39149) -(5330,7206,5304,7165) -(24790,27196,24695,27118) -(38806,1961,38795,1906) -(23290,4487,23212,4416) -\N -(35035,24337,34990,24297) -(5549,38948,5549,38891) -(24558,15492,24501,15425) -(4636,3011,4574,2933) -(26522,39986,26451,39940) -(33486,18424,33410,18366) -(36638,14324,36625,14287) -(35115,41236,35055,41191) -(31927,16896,31841,16806) -(5796,43937,5697,43886) -(25681,41645,25663,41608) -(10962,42777,10894,42732) -(32715,11026,32672,10991) -(45803,20406,45710,20371) -(34730,17672,34658,17606) -(8809,6323,8798,6232) -\N -(39471,23837,39390,23749) -\N -(34078,17435,33987,17433) -(9133,4544,9041,4509) -(47274,29126,47242,29060) -(6404,28488,6403,28475) -(48894,49751,48846,49694) -(17324,43023,17301,42972) -(15599,8433,15557,8386) -(48575,10202,48488,10175) -(27638,24428,27608,24378) -(45277,47456,45240,47422) -(26482,46607,26482,46570) -(41400,33898,41397,33802) -\N -(49853,18504,49848,18503) -(11528,25165,11476,25080) -(49902,41752,49818,41746) -(1956,47506,1922,47424) -(21834,22058,21802,21964) -\N -(19414,21842,19386,21822) -(34801,13722,34744,13681) -(13924,29243,13835,29160) -(47749,21986,47664,21894) -(47051,39582,46974,39489) -(31287,49923,31236,49913) -(47429,8625,47337,8585) -(46987,44364,46901,44277) -(16158,27510,16099,27467) -(41184,6400,41148,6317) -(1847,42471,1829,42426) -\N -(14409,48602,14320,48555) -\N -(38137,42951,38045,42918) -(42875,2312,42832,2243) -(27242,30617,27181,30535) -(24882,44559,24812,44548) -(22021,1596,22015,1581) -(24300,1523,24250,1443) -(43946,35909,43869,35868) -(816,15988,776,15967) -(25243,9401,25237,9332) -(27967,25958,27928,25949) -(6575,33949,6484,33900) -(44812,35980,44800,35913) -(37577,13064,37495,13019) -\N -(30891,29967,30814,29884) -(15829,28836,15753,28807) -(11128,34180,11126,34117) -(9834,12537,9801,12508) -(4899,29069,4809,29024) -(29370,38459,29276,38382) -(40743,46653,40647,46559) -(9618,2723,9578,2631) -(32542,26837,32515,26769) -(5625,13409,5576,13355) -(47490,19229,47472,19203) -(48118,40275,48063,40203) -(19245,20549,19227,20546) -(25312,22243,25280,22164) -(18797,28934,18723,28881) -(31609,49393,31512,49366) -(26183,32888,26135,32824) -(46198,26153,46180,26149) -\N -(45383,16904,45353,16888) -(7132,11408,7091,11338) -(48262,43227,48236,43159) -(31722,12861,31675,12810) -\N -(41695,48924,41691,48921) -(48318,12877,48287,12802) -(12069,32241,11978,32231) -(8395,2694,8380,2661) -(19552,34590,19550,34497) -(12203,26166,12187,26143) -(35745,9571,35654,9542) -(22384,22535,22352,22439) -(21459,28189,21360,28189) -(7418,7203,7343,7182) -(39497,48412,39413,48318) -(1058,11132,979,11051) -(45623,31417,45548,31381) -\N -(23887,31921,23876,31891) -(7797,1244,7785,1155) -(23679,43650,23594,43644) -(21891,30561,21833,30485) -(4069,6870,4019,6785) -(5134,25117,5103,25034) -(36101,41895,36085,41810) -(39617,39211,39544,39191) -(37437,6604,37434,6585) -\N -(7749,32601,7740,32515) -(26203,34991,26159,34946) -(31856,39006,31783,39003) -(45828,24767,45788,24723) -\N -(49836,35965,49757,35871) -(44113,49024,44033,48995) -(38237,22326,38187,22253) -(45235,19087,45190,19005) -(1588,45285,1520,45254) -(46628,8701,46552,8665) -(47707,18258,47668,18250) -(9377,26162,9325,26079) -(28331,16766,28302,16731) -(15792,27875,15727,27809) -(16454,1972,16415,1967) -(21012,15828,20972,15784) -(27465,30603,27390,30560) -(39256,7697,39225,7604) -(25908,32801,25854,32770) -(25215,40109,25201,40106) -\N -(23280,4613,23190,4596) -(32440,30879,32405,30807) -(49156,4224,49126,4126) -(20005,40423,19911,40370) -(20978,8226,20930,8170) -(32127,22611,32126,22579) -(21764,26509,21701,26455) -\N -(32923,2834,32914,2830) -(7499,25331,7426,25300) -(6163,36942,6107,36908) -(41118,14583,41034,14486) -(21211,33369,21208,33331) -(7899,27682,7853,27603) -(16546,48436,16535,48400) -(24898,40195,24855,40174) -(43029,982,43004,952) -(26266,7962,26252,7950) -\N -(11308,44367,11210,44322) -(8902,28402,8808,28334) -(11671,19619,11665,19549) -(47202,23593,47153,23505) -(21981,40220,21905,40160) -(46721,2514,46687,2471) -(3450,33839,3424,33811) -(41854,45864,41762,45792) -(40183,47816,40114,47742) -(26119,33910,26077,33816) -(3430,16518,3365,16500) -(40063,32176,40005,32166) -(38702,15253,38679,15187) -(17719,12291,17658,12257) -(46131,30669,46068,30587) -(42738,10952,42731,10907) -(8721,45155,8650,45076) -(45317,26123,45244,26113) -(42694,11561,42614,11490) -(10043,12479,10009,12391) -(27584,2345,27578,2257) -(30889,8253,30866,8167) -\N -(5176,48928,5107,48838) -(9781,21023,9745,20976) -(32430,27908,32404,27859) -(3984,7391,3973,7352) -(18904,8094,18842,8091) -(20573,5508,20482,5496) -(7806,44368,7753,44297) -(18875,41452,18817,41376) -(6632,12142,6566,12079) -(33066,17865,33055,17854) -(45726,19628,45714,19589) -(26971,18459,26941,18423) -(26554,23641,26515,23592) -(45503,1325,45441,1231) -(11898,20164,11880,20115) -(27868,22837,27843,22776) -(34931,8206,34855,8144) -(42375,33603,42350,33539) -(3184,8308,3129,8238) -(26667,15813,26661,15785) -\N -(5760,49617,5730,49546) -(794,27001,777,26992) -(13518,45289,13459,45235) -\N -(34430,29754,34363,29736) -(37912,24574,37880,24543) -(8130,2270,8083,2258) -\N -(26930,21516,26848,21455) -(3634,33511,3592,33489) -(33080,5036,33035,4972) -(48389,13942,48316,13915) -(9231,5298,9150,5232) -(1357,10601,1321,10548) -\N -(35175,15295,35091,15269) -(33917,36863,33879,36784) -(8279,12052,8239,12021) -(11868,19083,11862,19034) -(24019,30777,24006,30703) -(44619,6959,44618,6938) -(28610,2626,28523,2582) -(29579,41801,29482,41775) -(23448,37609,23396,37534) -(40676,11252,40670,11191) -(39656,14077,39564,13999) -(33060,31042,33033,30950) -(11720,6816,11654,6792) -(13775,28873,13730,28868) -(47851,39121,47802,39084) -(30923,40255,30860,40199) -(44169,15070,44085,15015) -(42574,28664,42558,28590) -(8993,43487,8941,43460) -(40782,11648,40763,11631) -(18516,10143,18423,10137) -(39068,551,39005,491) -\N -(39672,12000,39575,11913) -(18508,37761,18464,37712) -(19083,35318,19079,35280) -(30286,13736,30222,13672) -(7223,9164,7132,9069) -(20764,29286,20700,29210) -(5733,8063,5699,8058) -(8566,43873,8549,43797) -(22126,27444,22062,27366) -(15105,8717,15078,8660) -(43987,33145,43940,33083) -\N -(46833,38652,46755,38612) -(47768,27202,47681,27169) -(22792,1183,22731,1152) -(25650,43310,25562,43247) -(37084,20116,37045,20057) -(47461,32556,47423,32555) -\N -(41225,18124,41215,18117) -(17623,25218,17553,25158) -(13770,21703,13770,21700) -(48958,35441,48870,35388) -(2976,1808,2892,1802) -(45118,22318,45049,22224) -(42287,26616,42281,26560) -(25525,6327,25468,6244) -\N -(40756,31634,40713,31568) -(23105,26565,23078,26565) -(48268,39862,48265,39827) -(41656,26254,41567,26243) -(28062,17920,28045,17825) -(6443,17321,6402,17238) -(10191,45466,10151,45447) -(18097,39706,18043,39649) -(37592,3244,37569,3197) -(29809,5978,29762,5950) -(12145,11251,12130,11202) -(37507,42999,37446,42956) -(10820,2866,10782,2830) -(36440,42904,36421,42832) -(38370,3386,38279,3311) -(9345,17279,9313,17197) -(20477,14864,20395,14807) -(37147,37769,37110,37729) -(15325,36135,15284,36053) -(29034,32897,29009,32854) -(2116,22274,2037,22216) -(15078,38330,15048,38251) -(7968,33600,7914,33573) -(832,23851,770,23786) -(38669,4348,38594,4344) -(8521,48573,8425,48564) -(1060,43320,969,43289) -(26170,10150,26144,10069) -(32324,8539,32285,8506) -(13121,18044,13109,18021) -(1597,9383,1594,9367) -(49539,35164,49505,35065) -(39464,10295,39409,10261) -(8921,37898,8825,37803) -(31171,47076,31093,47039) -(7178,41397,7108,41304) -(16240,34832,16162,34761) -(2829,20119,2782,20091) -(45854,21265,45810,21250) -(6382,12106,6315,12030) -(22301,46291,22291,46274) -(34142,14181,34078,14158) -(11258,29748,11198,29742) -\N -(37450,6943,37398,6882) -(41675,27207,41643,27130) -(13578,49562,13573,49479) -(37132,37397,37081,37301) -(49404,37193,49332,37170) -(33536,31809,33444,31735) -(45990,42751,45893,42708) -(38852,20510,38802,20509) -(27453,15836,27391,15802) -(9347,29004,9284,28946) -(44871,27727,44778,27668) -(14978,19646,14970,19644) -(23243,47091,23166,47080) -(45204,21431,45167,21370) -(14082,22316,14078,22235) -(42778,22694,42744,22606) -(4834,25241,4760,25196) -(20497,18110,20494,18038) -(45738,35524,45706,35496) -(21575,5151,21493,5092) -(2194,10052,2172,9960) -\N -(47735,24472,47682,24460) -(46740,35700,46695,35609) -(24647,42807,24568,42779) -(18000,30576,17975,30506) -(48638,46630,48544,46628) -(48508,33600,48477,33578) -(38703,45408,38670,45313) -(21712,15015,21625,14956) -(5840,42007,5768,41992) -(44011,11138,43953,11117) -(3899,33262,3897,33238) -(30142,23967,30096,23927) -(36950,13226,36908,13141) -(13130,26915,13071,26873) -(38576,35408,38539,35392) -(16776,46244,16700,46176) -(38251,25969,38168,25948) -\N -(3512,32256,3417,32242) -(31923,31225,31832,31197) -(5144,4969,5124,4937) -(34499,46164,34430,46162) -\N -(39432,31907,39388,31828) -(17316,24606,17221,24533) -(20751,49352,20709,49323) -(41673,30418,41623,30377) -(29026,24400,28971,24345) -(21929,30617,21894,30598) -(35539,12421,35536,12355) -(24938,45583,24870,45525) -\N -(27442,33090,27353,33064) -(23949,12046,23949,12036) -(11399,377,11360,294) -(47099,9989,47023,9942) -(641,33118,639,33084) -(13687,41308,13682,41290) -\N -(3682,17727,3645,17660) -(13262,19396,13185,19357) -(18791,389,18774,366) -(12489,45384,12403,45369) -\N -(12065,6364,12015,6325) -\N -(32705,23886,32619,23827) -\N -(7004,37333,6911,37240) -(28594,38078,28530,38050) -(5805,21797,5710,21701) -(41145,18905,41058,18873) -(35599,10002,35591,9956) -(5387,39087,5326,38994) -(11703,14003,11671,13912) -(4093,10472,4091,10470) -\N -(14110,49740,14063,49695) -(4170,470,4097,463) -(22219,17296,22164,17221) -(2505,20879,2446,20842) -\N -(47235,24744,47151,24667) -(30035,23234,30013,23197) -(3489,11659,3461,11607) -(38435,46322,38429,46230) -(12315,32880,12277,32854) -(33350,35297,33317,35263) -(18845,37671,18836,37589) -(24855,23554,24783,23520) -(48251,44461,48188,44408) -(17695,43353,17605,43286) -(4964,21292,4893,21270) -(33919,29907,33852,29878) -(29139,40010,29084,39957) -(41611,37750,41572,37741) -(41773,34717,41682,34700) -(8225,7424,8221,7363) -(1785,28248,1771,28219) -(21553,36307,21505,36257) -(7552,18199,7527,18119) -\N -(14410,30977,14349,30944) -\N -(20940,49142,20901,49069) -(36892,5522,36810,5478) -(40192,20926,40179,20926) -(44702,15182,44641,15117) -(43431,4921,43337,4827) -(41129,21654,41084,21642) -(6205,42785,6113,42722) -(23714,10224,23666,10205) -(9318,35175,9274,35139) -(40698,12676,40618,12627) -(49954,1340,49905,1294) -(32774,33062,32763,33062) -(4336,22183,4241,22157) -(10241,47657,10151,47592) -(6746,16718,6666,16634) -(26842,49694,26839,49680) -(34870,47437,34820,47347) -(26365,22266,26326,22183) -(39859,932,39829,840) -(33995,10888,33902,10793) -(32972,22342,32951,22340) -\N -(19951,10161,19932,10111) -(26779,45188,26745,45151) -(11235,13593,11184,13589) -(27334,20968,27288,20953) -(9586,43102,9488,43085) -(43935,49759,43925,49680) -(10548,37032,10474,36955) -(9326,14927,9295,14848) -(41340,11312,41311,11303) -(6500,44553,6454,44515) -\N -(8198,26841,8104,26749) -(47761,34183,47702,34140) -(43637,17912,43577,17910) -(17623,11138,17590,11122) -(48122,13132,48077,13060) -(27911,39796,27908,39777) -(1108,7918,1080,7832) -(18776,24329,18699,24326) -(1171,37901,1075,37871) -(38437,33948,38364,33907) -(1913,11593,1817,11533) -(22684,266,22656,181) -(13299,17075,13241,17074) -(6924,30196,6851,30113) -\N -(4367,13150,4298,13053) -(37381,6101,37380,6046) -(10307,28383,10270,28349) -(12283,8636,12256,8610) -(20230,32775,20144,32723) -(32942,12812,32905,12714) -(46140,7138,46140,7047) -(37235,29436,37161,29425) -(42486,25454,42478,25444) -(47860,46973,47842,46961) -(41760,21026,41662,20955) -(29663,20088,29566,20026) -(19167,33241,19101,33235) -(12306,37845,12301,37803) -(11288,873,11203,857) -(30309,5120,30282,5060) -(46927,19737,46856,19687) -(16664,20052,16649,19989) -(7330,8675,7296,8613) -(45067,45724,44991,45631) -(45317,10862,45218,10842) -(15012,47009,14998,46956) -(47882,10146,47813,10099) -(31571,46215,31511,46148) -(32257,2619,32187,2531) -(38924,41305,38872,41285) -(49981,34876,49898,34786) -(30501,35099,30418,35011) -\N -(45862,41438,45854,41434) -(38448,31878,38391,31822) -(8278,43463,8274,43378) -(5883,30629,5878,30564) -(49501,40346,49447,40275) -(31651,43116,31560,43106) -(44244,32940,44244,32926) -\N -(17941,18079,17938,18035) -(9518,32524,9470,32511) -(30707,43469,30686,43457) -(3284,46542,3187,46477) -(43423,29642,43393,29602) -(19940,16825,19877,16736) -(26194,47446,26194,47407) -(30386,24675,30333,24652) -(42707,44466,42688,44456) -\N -(43395,18525,43320,18467) -(28346,32259,28276,32196) -(45106,40786,45026,40767) -(36734,20414,36722,20363) -(37140,11569,37099,11475) -(8967,6409,8882,6341) -(31036,27923,30993,27890) -(22442,47682,22347,47663) -(32511,24029,32482,23970) -(22593,34444,22519,34399) -(41534,15495,41518,15455) -\N -(35862,19997,35818,19928) -(31419,8323,31404,8285) -(31036,19023,30978,19000) -(46900,15192,46891,15102) -(12774,9651,12765,9604) -(49985,6436,49927,6338) -(7184,47344,7089,47285) -(12792,45021,12740,45011) -(15019,27192,14940,27096) -(35415,23106,35381,23095) -(42129,14283,42095,14245) -(29375,45807,29347,45743) -(21763,24916,21700,24889) -(47656,8794,47579,8774) -(6139,49571,6059,49472) -(44492,45607,44483,45532) -(22699,4301,22628,4240) -(27407,24241,27335,24158) -\N -(38424,34460,38403,34458) -(46572,48456,46554,48402) -(39676,29056,39643,28981) -(4202,33076,4107,33010) -(32499,10592,32482,10575) -(22504,45417,22459,45378) -(49619,40322,49619,40268) -(14463,9305,14426,9224) -(10070,20300,10035,20211) -(35060,28561,34965,28553) -(23970,47522,23887,47428) -(46803,19155,46790,19131) -\N -(46151,49848,46058,49830) -(45266,40766,45209,40738) -(31041,32195,31007,32110) -(41401,17245,41334,17224) -(37445,654,37435,602) -(45568,31904,45508,31857) -(29326,7923,29285,7896) -(27078,34643,27027,34606) -(34492,43443,34437,43345) -(34109,4307,34083,4265) -(2755,45325,2727,45312) -(12571,24218,12536,24195) -(41224,2454,41149,2445) -(711,34828,655,34788) -(9104,18865,9036,18850) -(3508,26816,3456,26771) -(20159,16212,20116,16160) -(36871,7425,36777,7421) -(2751,45244,2734,45222) -(35867,28071,35769,28052) -(46878,35730,46850,35725) -(20610,35086,20513,35037) -(3903,32612,3887,32517) -(9330,40226,9289,40169) -(6338,28242,6329,28184) -(35668,18344,35606,18304) -(29892,48927,29878,48879) -(26999,646,26932,612) -(36377,38898,36338,38847) -(40289,31459,40236,31436) -(30377,1164,30306,1069) -(7642,12183,7590,12112) -(40325,1716,40296,1662) -(36412,38787,36318,38691) -(3967,33268,3923,33261) -(33914,40774,33873,40763) -(45978,41431,45963,41332) -(39195,12546,39120,12520) -(29962,30878,29941,30846) -(9365,10732,9310,10726) -(28801,23943,28740,23885) -(28934,38858,28928,38807) -(22126,45897,22068,45803) -(2923,33832,2918,33751) -(25116,2276,25083,2272) -(31174,14546,31144,14460) -(11728,9072,11658,9004) -(19804,49195,19730,49125) -(23090,28826,23010,28787) -(33989,27553,33947,27486) -(39702,47613,39641,47553) -(31397,3607,31304,3519) -(5835,9262,5791,9226) -(40112,37022,40038,36926) -(12346,29356,12282,29344) -(28503,9623,28469,9591) -(38449,43143,38378,43066) -(36950,37311,36905,37265) -(34824,5729,34818,5706) -(9288,26969,9225,26900) -(2535,42176,2478,42159) -(29098,49051,29085,49031) -(44759,33326,44727,33230) -(42849,2970,42821,2919) -(46014,27193,45985,27151) -(14506,13713,14417,13626) -(19342,44905,19332,44895) -(38178,37003,38147,36925) -(29179,27310,29084,27288) -(42713,10158,42671,10060) -(43336,38389,43290,38326) -(41260,34410,41245,34327) -(27907,2695,27830,2596) -(16309,44972,16222,44966) -(6230,22262,6214,22249) -\N -(9266,39458,9175,39447) -(33120,33548,33087,33538) -(43659,11416,43599,11375) -(49707,39258,49702,39159) -(23520,22140,23486,22072) -(24736,46502,24668,46412) -(7826,16851,7730,16807) -(39114,6048,39056,5965) -(11859,8753,11764,8701) -(42254,48367,42240,48328) -(26136,49185,26056,49175) -(38395,11209,38334,11137) -(33249,9425,33209,9348) -(22131,38502,22112,38460) -(5306,24344,5267,24268) -(30292,1198,30233,1149) -(9903,10896,9850,10806) -(25568,22911,25487,22868) -(22048,43391,22043,43362) -(20852,25827,20851,25766) -(35204,17119,35114,17093) -(5575,43431,5554,43410) -(17727,13623,17678,13560) -(14721,29520,14709,29461) -(40317,42220,40267,42166) -(31435,31012,31386,30931) -(40655,10103,40645,10006) -(35783,17802,35773,17763) -(34874,10210,34856,10200) -(3694,14279,3610,14239) -(27854,5493,27799,5433) -(34913,7234,34894,7220) -(15758,26445,15738,26421) -(23710,7272,23705,7270) -\N -(33679,13468,33628,13415) -\N -(31271,40495,31178,40461) -(759,187,662,163) -(14419,40434,14402,40381) -(45879,42933,45814,42872) -(167,17214,92,17184) -(9964,12210,9958,12195) -(35834,46257,35817,46211) -(26077,5629,25978,5621) -(46177,44640,46082,44544) -(44780,28753,44707,28692) -(35491,24729,35425,24690) -(33914,34190,33914,34131) -(17709,33253,17668,33227) -(45516,11888,45423,11848) -(24497,24752,24411,24710) -(30333,5952,30331,5886) -(444,12587,430,12497) -(7592,22353,7541,22287) -\N -(13387,37414,13329,37318) -\N -(21504,35227,21449,35210) -(18533,12909,18438,12848) -(41049,27148,41048,27088) -(18205,12222,18151,12140) -(18026,5164,18026,5156) -(34104,29862,34006,29815) -(18520,49686,18454,49602) -(37000,41493,36920,41424) -(43025,25711,42986,25687) -(38620,47018,38535,46934) -(24119,36813,24023,36739) -(48887,26359,48879,26302) -(47827,14625,47810,14609) -(10792,30746,10776,30716) -(30384,40672,30318,40582) -(48417,22790,48358,22746) -(14854,5819,14785,5798) -(19142,44414,19085,44406) -(31179,27081,31145,27005) -\N -(19692,8711,19659,8642) -(39689,14082,39603,14051) -(11181,39091,11119,39002) -(46015,23374,45936,23328) -(12517,49702,12427,49690) -(21926,21137,21841,21111) -(31956,12509,31870,12494) -(5895,2030,5851,2020) -(27094,5447,27014,5377) -(35781,8717,35780,8618) -(14012,12023,13972,12015) -(1702,12442,1696,12419) -(28549,5251,28462,5248) -(26441,21007,26360,20925) -(49820,7990,49771,7967) -(26424,29698,26339,29693) -(35146,6820,35071,6817) -\N -(15438,18788,15435,18729) -(47115,5235,47096,5143) -(33982,9002,33915,8925) -(14206,37041,14174,36955) -(24300,36616,24232,36613) -(44658,1788,44580,1769) -\N -(31539,43550,31463,43464) -\N -(16722,9673,16633,9652) -(44813,20573,44733,20544) -\N -(42114,32559,42040,32552) -(41561,36244,41477,36241) -(39589,33796,39548,33716) -(20365,26770,20329,26709) -(28511,208,28479,114) -(10010,25524,9930,25508) -\N -(1549,45666,1512,45621) -(16193,1927,16166,1869) -(34486,11500,34421,11401) -(14048,37944,13994,37901) -(21692,9594,21617,9496) -(2568,37899,2557,37811) -(4360,24503,4278,24443) -(50027,49230,49951,49214) -(44849,14867,44836,14813) -(16695,34896,16683,34840) -(12600,35217,12593,35129) -(23113,24009,23030,23962) -(49907,30225,49810,30158) -(18026,25208,17970,25208) -(49711,39844,49651,39790) -(5427,42682,5357,42637) -(23901,14221,23802,14184) -(15470,12185,15376,12163) -(47302,34023,47292,34001) -(24336,17418,24315,17393) -(13948,17043,13903,16970) -(8555,8986,8530,8953) -(48830,6038,48743,5986) -(48720,40687,48623,40610) -(21161,30970,21146,30896) -(9507,36316,9411,36261) -\N -(36643,18136,36614,18106) -(1858,7457,1851,7402) -(24452,44306,24372,44252) -\N -(3292,807,3205,806) -(6845,30694,6792,30627) -(21333,25786,21237,25751) -(23008,22574,22999,22511) -(8790,8893,8772,8806) -(43333,47968,43264,47900) -(5377,24103,5302,24076) -(18410,23993,18329,23907) -(24752,19126,24713,19069) -(49772,11378,49696,11293) -(3468,12920,3396,12873) -(1746,40342,1736,40333) -(49187,29737,49139,29681) -(27657,44952,27581,44917) -\N -(35407,30177,35345,30151) -(4071,40568,4058,40544) -(25998,30513,25965,30452) -(8195,45403,8097,45310) -(8276,41689,8183,41670) -\N -(48435,28550,48355,28455) -\N -(8139,25449,8136,25380) -(20302,25574,20297,25531) -\N -(22055,46659,22034,46567) -(3531,49962,3463,49934) -(46828,46938,46739,46902) -(42294,786,42212,739) -(8779,3292,8761,3275) -(48146,46170,48082,46151) -(21571,10000,21531,9919) -(35526,26029,35450,25945) -(38893,22225,38865,22197) -(22189,37520,22132,37497) -(810,43261,751,43198) -(10352,39144,10290,39093) -(8740,35435,8720,35432) -(31657,13551,31583,13484) -(39803,4019,39755,4014) -(46353,7853,46312,7824) -(30078,48975,30021,48970) -(2847,32036,2819,31966) -(25250,10147,25165,10140) -\N -(15643,38953,15585,38947) -(40792,29798,40731,29731) -(43249,26858,43215,26835) -(47229,2199,47201,2134) -(10052,23601,9958,23570) -(38981,21615,38892,21604) -(3651,45004,3570,44917) -(21503,8261,21409,8166) -(13518,34201,13465,34105) -(13899,25117,13836,25114) -(18327,17403,18301,17349) -(19503,13648,19483,13607) -(3554,19487,3529,19466) -(41102,43355,41070,43314) -(4663,45858,4583,45765) -(3971,3023,3931,2975) -(37124,7061,37080,6993) -(48530,47172,48459,47160) -(14575,29843,14509,29750) -(43443,23124,43357,23038) -(8864,48290,8857,48263) -(41597,39852,41577,39791) -(35610,33392,35556,33353) -(36415,17906,36328,17846) -(24919,43933,24839,43883) -(7457,14056,7395,14051) -(43851,4090,43801,4080) -(43567,18468,43471,18388) -(16711,6084,16652,6055) -(45888,45934,45846,45880) -(45630,9313,45585,9248) -(27119,25969,27094,25884) -(36155,11420,36120,11405) -(41880,47111,41808,47049) -\N -(17554,20379,17482,20374) -(38848,5936,38763,5869) -(28324,31019,28276,30944) -(43257,17152,43176,17091) -(42717,24613,42691,24527) -(16786,41486,16763,41403) -(19259,28780,19160,28711) -(25843,28265,25760,28171) -(48645,34816,48546,34755) -(7004,49289,6976,49236) -(30261,21833,30181,21776) -(5290,46672,5219,46661) -(21237,31901,21188,31849) -(23340,38537,23253,38472) -(17269,3682,17183,3586) -\N -(48200,15377,48110,15369) -(16546,22195,16477,22142) -(21436,8460,21378,8449) -\N -(46598,17235,46577,17138) -\N -(30212,36184,30152,36092) -(18037,155,17941,109) -(4945,29201,4933,29184) -(32835,18782,32770,18750) -(34160,33104,34120,33007) -(5151,26989,5149,26909) -(1801,15549,1710,15461) -(48988,34819,48951,34764) -(20904,32547,20856,32497) -\N -(32654,35183,32606,35144) -(14336,11763,14328,11712) -(30546,23808,30463,23773) -(6813,21006,6781,20924) -\N -(14199,22030,14185,21934) -(3783,14709,3747,14658) -(49428,47052,49422,46973) -(29551,27682,29470,27654) -(29170,37260,29151,37181) -(48924,24689,48894,24680) -(48497,34052,48453,33966) -\N -(21263,8203,21242,8176) -(46537,3797,46462,3735) -(18406,14579,18393,14563) -\N -(11583,16529,11536,16471) -(10564,46257,10478,46228) -(49769,34513,49761,34458) -\N -(9202,6482,9138,6391) -(40387,37411,40357,37360) -(11966,11802,11888,11751) -(15551,47438,15486,47406) -(12017,43288,11969,43230) -(9717,22574,9701,22495) -\N -(35083,49443,35075,49355) -(33857,9320,33813,9269) -(32106,10581,32012,10560) -(14345,12485,14273,12424) -(24187,46416,24175,46402) -(43854,42159,43808,42129) -(35399,40707,35359,40646) -(29585,25576,29493,25556) -(24919,7829,24911,7753) -\N -(17049,48390,17022,48304) -(25224,35012,25217,34922) -(47397,20853,47346,20779) -(17221,16558,17181,16516) -(8669,16491,8645,16486) -(23502,44241,23484,44164) -(36169,37046,36072,37010) -(44775,32394,44763,32357) -(30685,36871,30662,36792) -(21783,47642,21714,47630) -(34847,27467,34761,27372) -(43925,49912,43888,49878) -(16455,27861,16364,27813) -(38406,18310,38329,18309) -(5408,9461,5319,9426) -(41856,36900,41784,36854) -(23723,4460,23646,4448) -(18454,40138,18430,40046) -(17505,36822,17418,36763) -(36686,33534,36641,33476) -(11347,9454,11289,9436) -\N -(27816,34752,27745,34736) -(44213,8559,44162,8461) -(45359,26789,45315,26776) -(31249,19475,31224,19421) -(25917,44239,25819,44149) -(47313,40691,47264,40685) -(40577,33848,40513,33794) -(9606,45253,9582,45174) -(30005,24521,29910,24496) -(49332,35375,49309,35299) -\N -(12164,33871,12075,33820) -(19598,43327,19593,43314) -\N -(3818,28584,3815,28504) -\N -(35579,8611,35541,8604) -(8811,20986,8750,20954) -(16139,44777,16128,44686) -(35550,41501,35534,41458) -(43180,11927,43109,11891) -(45798,8465,45711,8460) -(18196,6886,18126,6845) -(1774,32167,1701,32073) -(7030,40790,7029,40711) -(11676,23009,11665,22915) -(33990,22561,33953,22474) -\N -(30366,9447,30284,9353) -(37626,32913,37596,32853) -(7730,42561,7665,42470) -(49347,8403,49315,8387) -(6874,3499,6812,3458) -(44189,16999,44169,16964) -(6312,30167,6231,30083) -(18932,6611,18909,6518) -(32262,13076,32223,13057) -(45989,249,45910,222) -(42710,855,42692,796) -(25562,9849,25535,9802) -(13348,46719,13260,46689) -(30022,42196,30005,42160) -\N -(22263,45954,22243,45950) -(18918,18890,18820,18795) -(31918,12003,31852,11989) -(12252,39453,12211,39398) -(40208,9789,40194,9759) -(35943,21767,35914,21693) -(18439,10706,18383,10618) -(2803,18999,2778,18925) -(14953,27444,14875,27397) -(12587,22025,12545,21928) -(33930,21090,33918,21009) -(10444,2606,10407,2553) -(28700,29782,28665,29703) -\N -(1402,13497,1397,13465) -\N -(24155,3075,24083,3062) -(38378,1864,38339,1849) -(29261,49910,29247,49818) -(38139,37073,38098,37057) -\N -(24468,41130,24418,41053) -(9989,1015,9959,939) -(47001,33561,46994,33518) -(47058,16030,46983,16012) -(35509,1814,35426,1748) -(3630,48019,3597,47923) -(47781,12986,47741,12947) -(16364,9908,16356,9882) -(17290,41508,17287,41410) -(42423,26477,42349,26434) -(10039,920,9952,833) -(16851,21338,16846,21314) -\N -(23104,7700,23062,7688) -(5619,2079,5611,2075) -(31471,49632,31375,49549) -(25793,12526,25783,12456) -(3935,29528,3866,29513) -\N -(5957,1646,5947,1595) -(2467,22376,2429,22349) -(43715,32673,43664,32595) -(6726,13093,6636,12994) -(31477,18347,31421,18299) -(34232,36635,34200,36552) -(49061,14516,49008,14442) -(43996,6129,43955,6074) -(7728,33802,7670,33703) -\N -(6131,36766,6053,36749) -(35791,16361,35696,16329) -(45759,8935,45675,8886) -(43634,2029,43537,1940) -(4916,32233,4844,32181) -(46701,23508,46623,23477) -(29590,4893,29552,4871) -(38647,4423,38574,4396) -(7593,25845,7497,25751) -(8510,43552,8432,43492) -(18791,39181,18730,39162) -(7462,2956,7454,2858) -(1394,26795,1392,26780) -(16707,21993,16609,21932) -(26838,10866,26803,10836) -(31642,29842,31585,29760) -(21891,3502,21863,3406) -(13258,587,13250,507) -(6072,47397,6021,47369) -(16605,49730,16579,49659) -(42830,40981,42791,40981) -(12975,3706,12913,3637) -(30925,21660,30826,21649) -(1455,14229,1410,14156) -\N -(17583,16486,17562,16474) -(33377,3387,33333,3381) -(784,6177,750,6095) -(22111,44110,22106,44013) -(1444,403,1346,344) -(4010,46220,3982,46212) -(17932,8150,17861,8127) -(38685,31466,38636,31416) -(14257,11549,14242,11522) -(14990,15217,14904,15211) -(21395,21533,21307,21520) -\N -(31948,33725,31885,33694) -(433,49033,390,48961) -(45205,609,45173,523) -(25065,35494,25003,35455) -(33265,6677,33224,6611) -(18179,22345,18133,22256) -(3916,13759,3820,13732) -(1696,13478,1604,13436) -(47203,25980,47130,25907) -(24913,13361,24868,13268) -(13824,40177,13792,40130) -(25671,13555,25585,13494) -\N -(20133,37769,20105,37679) -\N -(26368,16734,26288,16726) -(30545,35438,30458,35376) -(48816,22926,48812,22831) -(48807,31389,48739,31330) -(11003,10859,10950,10765) -(17288,8570,17247,8485) -(38377,31415,38331,31379) -\N -(19085,23425,19059,23326) -(40059,17068,40052,17006) -(18811,13493,18734,13394) -(36319,17197,36225,17181) -(14939,38780,14863,38714) -(49539,17656,49479,17629) -(42530,45951,42466,45854) -(27318,26654,27233,26610) -(49980,35004,49937,34963) -(18326,32558,18322,32502) -(45951,28555,45896,28481) -(12104,33531,12014,33501) -(22311,41113,22215,41066) -(25073,18721,25047,18656) -\N -(14524,13486,14510,13390) -(40040,36688,40000,36599) -(21594,11473,21563,11436) -(44031,22274,43938,22187) -(729,30683,668,30601) -(14114,20873,14102,20803) -(28239,41377,28222,41308) -(26404,11922,26317,11843) -(41660,34586,41585,34501) -\N -(21128,2384,21101,2368) -(30209,16952,30156,16858) -(39078,24963,39045,24898) -(5598,1348,5499,1294) -\N -(38474,7436,38450,7364) -(15117,45734,15024,45693) -\N -(23909,39853,23888,39780) -(24292,30183,24282,30148) -(48871,17661,48868,17637) -(918,18752,847,18708) -\N -(43615,16162,43606,16104) -(33763,47410,33751,47409) -(4798,6485,4773,6388) -\N -(18524,41539,18433,41518) -(47745,42449,47651,42364) -(38936,21237,38864,21204) -\N -(5251,3516,5194,3475) -(22269,36269,22183,36228) -(18736,40983,18685,40947) -(38393,15444,38356,15363) -(38134,29898,38103,29862) -(37789,39557,37732,39474) -(31906,23005,31838,23003) -(10647,40094,10560,40040) -(9914,41547,9867,41545) -(44221,443,44125,433) -(41479,10936,41381,10847) -(42586,6301,42563,6235) -(2504,17588,2449,17554) -(7045,18782,7028,18764) -(41840,32018,41768,31938) -(38416,17158,38330,17060) -\N -(8605,39015,8605,38933) -(5764,43548,5719,43496) -\N -(20789,29902,20696,29843) -\N -(36104,47896,36079,47816) -(31736,13834,31722,13832) -(32617,19701,32597,19684) -(1671,18997,1622,18945) -(36007,26545,36005,26535) -(31864,17494,31820,17455) -(27346,28388,27303,28289) -(8191,9653,8133,9589) -(7501,21616,7405,21536) -(35450,9580,35368,9563) -(29281,37276,29247,37255) -(6225,17192,6200,17135) -\N -(43689,8119,43670,8028) -(41917,49601,41835,49563) -(44295,13116,44205,13078) -(22721,44772,22667,44748) -(32640,11107,32636,11050) -(20639,28851,20613,28839) -\N -(32479,10159,32446,10061) -(27251,16978,27196,16959) -(41401,33148,41339,33074) -\N -(49001,8538,48989,8444) -(37958,35843,37874,35802) -(46969,41229,46903,41138) -(18541,8876,18541,8870) -(4080,31634,4061,31627) -(8097,35240,8040,35152) -(18470,21414,18463,21412) -(20914,17897,20838,17869) -(42688,11681,42666,11641) -(47525,25005,47443,24907) -(32439,14438,32397,14400) -\N -(39667,19626,39622,19542) -(1212,44525,1169,44516) -(29766,4433,29668,4401) -(25847,49657,25813,49605) -(33859,17356,33827,17263) -(28989,45953,28904,45854) -(37211,30830,37113,30819) -\N -(45220,26382,45219,26340) -(12312,43250,12234,43246) -(37775,41504,37762,41421) -(45889,33499,45822,33411) -(49461,22601,49369,22553) -(39857,33844,39816,33824) -(46102,15822,46030,15778) -(46605,31239,46598,31170) -(23925,5856,23862,5808) -(15459,4262,15407,4241) -(12019,4907,12015,4818) -(38258,17973,38229,17923) -(40575,29566,40477,29521) -\N -(29715,45919,29697,45891) -(11694,9510,11670,9490) -(7053,44257,7012,44231) -(16465,8603,16391,8505) -(29170,15592,29098,15527) -(20400,37354,20345,37328) -(5281,10265,5252,10184) -(6084,48782,6058,48727) -(11006,6889,10971,6796) -(16299,19461,16286,19411) -(13718,29192,13642,29106) -(3999,2965,3963,2903) -(18509,12235,18430,12208) -(49542,38575,49537,38534) -(15093,41715,15071,41634) -(6802,8385,6714,8300) -(15127,17507,15097,17424) -(36921,3025,36835,2995) -(32117,24327,32101,24262) -(27244,24151,27165,24104) -(36339,42360,36313,42358) -(47288,46252,47245,46184) -(37867,6649,37818,6565) -(14886,22103,14865,22089) -(39611,17952,39513,17951) -(37329,31436,37298,31436) -(5715,39115,5698,39099) -(13266,7364,13203,7296) -(16076,10945,16006,10942) -(7197,41509,7126,41413) -(14411,40868,14330,40772) -(12872,33481,12862,33454) -(17786,19616,17758,19560) -(1052,37358,996,37311) -(42825,12643,42762,12625) -(20007,49858,19921,49778) -(27155,6355,27072,6257) -(14117,40208,14022,40155) -(47280,34069,47279,34028) -(17551,15803,17482,15763) -(1725,6673,1676,6649) -(43984,31128,43961,31105) -(43772,47042,43731,47038) -(46901,47317,46817,47228) -(19877,14179,19837,14168) -(20691,19989,20675,19935) -(4011,18914,3963,18817) -(1023,23378,933,23317) -(30051,46118,29966,46039) -(43499,46488,43496,46409) -\N -(43531,2412,43447,2396) -\N -(16034,32285,15976,32220) -(12817,21365,12740,21298) -(7607,47293,7585,47293) -(32512,12218,32463,12170) -(1848,21496,1839,21439) -(17567,23073,17478,23046) -(35813,31847,35807,31792) -\N -(563,30859,540,30842) -(13145,15488,13063,15433) -(36754,37479,36731,37411) -(1125,26069,1057,25997) -(4539,20676,4519,20618) -(8476,34721,8409,34681) -(7794,25691,7727,25656) -(23842,514,23800,473) -(47678,41396,47668,41365) -(6837,25974,6799,25892) -(13355,11174,13304,11161) -\N -(37243,25548,37158,25471) -(12528,30208,12441,30205) -(14929,1672,14886,1607) -(27263,49026,27263,49010) -(15892,21645,15835,21642) -(29446,48978,29360,48967) -(41304,9892,41211,9825) -(37418,49393,37338,49296) -(41146,32178,41120,32165) -(28738,13326,28722,13266) -(14899,36595,14873,36559) -(1973,31435,1921,31426) -(19485,17742,19421,17661) -(33072,20995,32980,20903) -(47091,30055,47080,30037) -(45753,12998,45686,12992) -\N -(11528,7826,11509,7794) -(21104,13921,21060,13836) -(16768,15491,16747,15470) -(13279,20396,13249,20326) -(4342,49518,4339,49446) -(20413,15476,20349,15447) -(45532,5649,45484,5627) -(18647,27196,18619,27115) -(1326,17473,1261,17400) -(47646,19644,47588,19609) -(35088,1813,35080,1732) -(38461,34839,38410,34838) -(34358,11540,34285,11506) -\N -(26969,7078,26953,6989) -(12629,40352,12617,40264) -(33800,7037,33731,6992) -(24462,13518,24392,13486) -(33164,47357,33096,47329) -(15422,18451,15413,18376) -(19643,12916,19567,12912) -(40860,42125,40770,42050) -(49103,29614,49039,29606) -(36319,35582,36222,35528) -(8924,36083,8873,36018) -(49603,44022,49505,44021) -(7783,40633,7702,40618) -(25388,49107,25346,49042) -(28375,38947,28306,38919) -(47324,22672,47321,22660) -(2287,8808,2266,8719) -(44343,16339,44248,16318) -(2374,28839,2336,28798) -(22913,40710,22819,40688) -\N -(47747,684,47658,627) -(16043,46011,16021,45984) -(34958,32168,34903,32092) -(4840,49328,4752,49258) -(24341,2087,24330,2009) -(18378,19374,18327,19358) -(48165,7217,48156,7141) -(14232,6044,14182,6004) -(23080,4196,22983,4191) -(259,1850,175,1820) -(270,29508,264,29440) -(45088,11375,45050,11295) -(29666,39386,29656,39302) -(8712,8782,8660,8713) -(15900,6650,15855,6561) -(28946,28348,28917,28347) -(32544,25845,32538,25779) -(44047,6957,43951,6942) -(36465,588,36382,503) -\N -(28167,26679,28150,26673) -(16065,4268,15975,4180) -(12950,23494,12893,23494) -(30145,24679,30056,24654) -(3027,16162,3001,16071) -(8259,34537,8202,34484) -(41447,1515,41427,1454) -(18407,28362,18309,28303) -(21393,41872,21328,41816) -(46040,26497,45996,26408) -\N -(49944,25163,49902,25153) -\N -(16195,11843,16159,11831) -(44257,15270,44254,15214) -(49760,4791,49699,4713) -(22558,33709,22519,33681) -(28375,10003,28336,9938) -(18179,24310,18106,24256) -(707,30688,664,30669) -(5851,26118,5822,26037) -(4266,1292,4221,1217) -(16516,11331,16432,11248) -(32374,38277,32313,38245) -(21939,8015,21927,7952) -(34322,32051,34242,32003) -(6262,35977,6260,35953) -(16717,38594,16622,38498) -(14564,3433,14535,3425) -(21078,1000,20994,974) -(28584,956,28575,868) -(5538,9962,5465,9870) -(34183,44102,34175,44085) -\N -(42507,10289,42441,10288) -(12671,19936,12594,19920) -(24835,12179,24770,12173) -(15664,11538,15598,11494) -(28892,24446,28821,24350) -(41654,26720,41570,26632) -(36583,387,36503,357) -(10842,34824,10795,34788) -(11518,42588,11429,42565) -(12577,40322,12486,40266) -(2453,4045,2439,3956) -(31837,33705,31803,33681) -(24403,27711,24383,27705) -(4431,2748,4337,2656) -\N -(3036,2887,3014,2826) -(37664,16118,37615,16022) -(8606,18063,8587,18038) -(24738,25458,24656,25362) -(45756,34022,45671,33948) -(34079,15236,33981,15171) -(9251,22488,9228,22470) -(25136,2809,25126,2717) -(5548,47695,5543,47685) -(13765,40800,13707,40754) -(25216,30678,25144,30677) -(22441,17169,22392,17106) -(1091,4770,1054,4734) -(36311,50073,36258,49987) -(22461,33163,22457,33128) -(35873,28907,35845,28867) -(42907,15848,42904,15785) -(6549,24897,6540,24861) -(21928,37764,21891,37681) -(21237,41132,21139,41086) -(12207,24266,12173,24235) -(40643,49770,40574,49687) -(32833,35686,32815,35674) -\N -(14545,18143,14541,18098) -(33892,42783,33884,42707) -(33933,8381,33921,8369) -(12450,19044,12403,19002) -(10176,45158,10088,45145) -(35828,12080,35732,12022) -(28102,13694,28061,13666) -(49432,31744,49340,31711) -(16192,37743,16162,37697) -(46830,867,46756,790) -(9200,28048,9159,27986) -(13397,19369,13340,19288) -(30879,43562,30785,43545) -(21995,48224,21920,48143) -\N -(11871,47569,11809,47568) -(29366,22196,29280,22154) -(26243,28176,26203,28116) -(28995,35031,28906,35014) -(29384,39276,29352,39183) -(8497,13798,8471,13789) -(7412,27226,7334,27220) -(25403,47678,25363,47654) -(11599,5556,11574,5502) -(44056,5123,44008,5111) -(49603,30877,49579,30840) -(32261,45876,32206,45865) -(35104,41659,35048,41587) -\N -(5457,35844,5376,35782) -(29423,3977,29354,3959) -(18059,3001,17965,2961) -(8509,5691,8463,5620) -\N -(27118,5762,27083,5747) -(2991,48605,2939,48559) -(44482,3484,44425,3459) -(45143,16439,45046,16365) -(2236,37531,2147,37530) -(41561,3217,41490,3210) -\N -(6270,27200,6171,27166) -(49195,24871,49138,24798) -\N -(46985,38881,46897,38845) -(37486,23522,37404,23441) -(26907,14490,26900,14391) -(30829,16111,30756,16056) -(3644,17291,3587,17262) -(20508,49775,20472,49680) -\N -(43279,8972,43198,8936) -(33744,7470,33734,7439) -(46303,20538,46284,20498) -(10365,48246,10291,48154) -(12636,24987,12545,24933) -(40998,46992,40989,46916) -(30536,6073,30531,6018) -(22102,9643,22051,9594) -(18616,34348,18530,34332) -(8222,8907,8123,8848) -(45698,28860,45698,28770) -(26958,1748,26924,1726) -\N -(26735,35073,26659,35025) -(48370,40813,48293,40737) -(13140,993,13108,934) -(10588,22893,10528,22883) -(23645,40789,23567,40698) -(49548,12374,49546,12329) -(41135,39626,41100,39602) -(41374,10856,41328,10769) -(12234,5765,12146,5674) -(12832,46941,12764,46917) -(47886,34532,47851,34500) -(23777,10549,23735,10495) -(1291,16913,1194,16873) -\N -(29239,30554,29202,30500) -\N -(36485,30007,36454,29924) -(7067,11320,7045,11229) -(16939,30482,16904,30462) -(27423,34386,27379,34303) -(35170,32021,35155,31979) -(42570,36477,42474,36457) -(19695,679,19682,594) -(47537,39450,47446,39450) -(19410,22942,19375,22922) -(34216,40166,34152,40158) -(37000,24351,36972,24299) -(24989,1681,24954,1672) -(54,38679,3,38602) -(41461,40693,41411,40599) -(7576,46054,7545,45963) -(35505,28262,35413,28222) -(1158,16976,1145,16927) -(23494,42291,23437,42229) -(32894,32519,32880,32485) -(604,13413,509,13401) -(18396,19712,18355,19646) -\N -(26657,28234,26597,28191) -(24240,47211,24154,47191) -(41778,10741,41766,10730) -(44022,43776,44010,43677) -(35967,30055,35906,29969) -(28878,18042,28806,18027) -(31507,27302,31428,27267) -(13267,21935,13265,21872) -(122,46832,64,46762) -(10348,45916,10306,45844) -(22962,12644,22927,12607) -(6320,22290,6284,22247) -(2297,11372,2216,11298) -(29366,36660,29325,36654) -(13962,39307,13921,39220) -(11094,19151,11092,19143) -(32289,23776,32258,23760) -\N -(36044,17356,35956,17273) -(46304,38692,46232,38675) -(10934,42999,10922,42909) -(4271,21177,4207,21093) -(7837,19926,7747,19905) -(25537,36605,25477,36584) -(22161,14999,22079,14962) -(5127,31243,5074,31213) -\N -(14904,40664,14838,40593) -(29308,8480,29268,8438) -(17731,7410,17699,7352) -(44840,29293,44797,29248) -(15523,31519,15505,31485) -(34429,38479,34421,38478) -(3530,23456,3440,23390) -(4699,6889,4603,6796) -(47405,48524,47389,48514) -\N -(23357,43160,23305,43156) -(16923,1995,16860,1937) -(47592,33853,47537,33758) -(31624,37490,31595,37473) -(42321,13380,42303,13337) -(3088,16094,3079,16060) -(22884,2955,22856,2857) -(17784,23073,17724,23044) -(32638,45577,32553,45512) -(13876,44091,13801,44000) -(27844,24384,27758,24330) -(28178,10225,28155,10167) -(39910,14277,39857,14241) -(30372,19524,30301,19514) -(38732,43151,38724,43151) -(32628,2068,32547,2068) -(13950,28652,13932,28566) -(38996,41070,38919,40993) -(31759,45246,31676,45215) -\N -(5424,34145,5382,34106) -(14727,45600,14699,45547) -\N -(31429,21537,31414,21499) -(14740,3420,14650,3323) -(21793,39498,21743,39471) -(18102,25924,18037,25868) -(33299,683,33213,594) -(45882,48765,45809,48721) -(49215,4098,49180,4067) -(49698,33743,49614,33663) -(21532,5215,21514,5151) -(24840,26877,24826,26808) -(32680,28433,32631,28364) -(20661,27511,20584,27414) -(28048,30385,28009,30315) -(45403,42533,45389,42464) -(46531,36947,46531,36850) -(36943,32817,36865,32737) -\N -(37984,43763,37888,43748) -(20593,10650,20557,10610) -(5387,40595,5326,40585) -(34412,10600,34352,10539) -(7237,47546,7206,47451) -(39931,26644,39915,26598) -(29843,4734,29800,4669) -(37503,8867,37406,8821) -(2583,2373,2570,2294) -(29275,46433,29256,46350) -(3332,45620,3287,45581) -(22472,39287,22472,39257) -(36786,18907,36708,18884) -(45503,28576,45482,28494) -(33262,28386,33163,28365) -(3606,49757,3538,49697) -(2082,49380,1991,49281) -(12065,3734,11983,3663) -(15606,9048,15596,9028) -(14687,19309,14637,19263) -(4568,15461,4499,15428) -\N -(43938,7429,43923,7391) -\N -(2168,50012,2108,49914) -(16022,8934,15963,8928) -(24567,39147,24561,39102) -\N -(42781,14149,42765,14088) -(39501,21084,39468,21078) -(6697,29628,6693,29584) -(11441,16164,11364,16125) -(39946,1920,39868,1844) -\N -(18138,45512,18111,45438) -\N -(20799,41217,20718,41138) -(30264,16697,30240,16639) -\N -(30746,50040,30727,49992) -(37429,43273,37423,43205) -(22854,28863,22789,28810) -(11380,48298,11287,48242) -(16471,37273,16439,37223) -(32737,39842,32661,39811) -(30959,3447,30949,3357) -(36396,13263,36348,13187) -(29607,14625,29531,14619) -(7851,43399,7824,43334) -(38515,14575,38496,14492) -(29125,3289,29086,3264) -(6866,10476,6839,10424) -(318,31489,235,31404) -(1140,7007,1113,6945) -(36574,9291,36484,9275) -\N -(40320,40937,40246,40866) -(588,25849,552,25801) -(6728,42539,6645,42507) -(12180,6185,12123,6123) -(32913,44123,32899,44037) -(25464,16803,25441,16749) -(23711,5829,23695,5750) -(31424,34930,31377,34906) -(42171,8298,42124,8222) -(451,31104,375,31083) -(39996,3278,39943,3260) -(25816,40396,25735,40362) -(34471,28587,34399,28547) -(45344,21540,45297,21496) -(27269,16787,27246,16763) -(18070,4469,18022,4423) -\N -(12668,16367,12645,16295) -(13823,17276,13730,17251) -(20555,45544,20511,45498) -(35893,42189,35861,42177) -(37081,45730,37076,45705) -(17270,15651,17201,15552) -(48690,46034,48667,45945) -(456,16088,368,16023) -(48707,12416,48670,12363) -(29692,11509,29614,11483) -(7005,3668,6981,3574) -(12162,389,12103,309) -(12371,24983,12366,24964) -(6886,48414,6868,48327) -(10653,26234,10624,26142) -(8526,48205,8517,48117) -(10521,31892,10480,31798) -(43353,1086,43281,1071) -(21007,35650,20998,35649) -(2343,4396,2310,4320) -(29379,12895,29284,12891) -(27662,17407,27570,17313) -(9845,29346,9807,29321) -(43855,38669,43790,38599) -\N -(20461,44189,20397,44158) -(11627,17368,11581,17289) -(2971,38855,2938,38807) -(43204,47082,43128,47018) -(9930,46902,9909,46871) -(30561,48461,30536,48365) -(44059,7591,44038,7563) -(46260,16898,46162,16886) -(27491,2891,27396,2814) -(36512,26034,36455,25941) -(31193,20022,31100,19942) -(17057,13643,16960,13621) -(26897,3399,26844,3318) -(1760,5504,1683,5431) -(29347,5511,29346,5450) -(38761,42083,38688,41999) -(11226,4089,11165,4068) -(46427,42983,46361,42970) -(12958,30737,12912,30712) -(44432,46521,44333,46443) -(16124,2948,16113,2852) -\N -(24704,25422,24635,25340) -(30833,46152,30790,46122) -(4487,37006,4473,36968) -(41047,23376,41036,23327) -(16312,49392,16298,49330) -(30081,14687,30042,14660) -(11160,13954,11103,13938) -(33207,23246,33143,23168) -(14872,7635,14860,7585) -(20139,23987,20059,23955) -(10946,49757,10923,49746) -(39438,36158,39426,36134) -(35502,2385,35464,2327) -(17073,42173,16987,42130) -(6079,17258,6068,17195) -(40458,15752,40364,15728) -(23340,7879,23313,7806) -\N -(31819,15096,31762,15059) -(31159,40864,31158,40780) -(26975,32144,26915,32113) -(34530,10378,34440,10298) -(18855,49577,18780,49528) -(16787,16625,16723,16586) -(32330,26538,32314,26458) -(34270,28674,34265,28595) -(10022,16026,10006,15962) -(23143,1479,23095,1469) -(33676,4483,33583,4408) -(31066,22074,31059,22035) -(21603,47121,21563,47082) -(30051,4244,30021,4157) -(30634,39478,30615,39446) -(34404,48724,34393,48724) -(31103,21414,31039,21380) -(22945,47397,22849,47313) -(18133,32025,18073,31941) -(4053,25759,3977,25667) -(39185,39091,39102,39068) -(43287,7407,43225,7314) -(13137,31188,13112,31182) -(46264,1438,46258,1389) -(22804,43892,22769,43822) -(7542,1044,7487,983) -(33022,8321,32925,8267) -(384,39161,286,39073) -(28205,24401,28142,24382) -(31708,39086,31696,39026) -(36626,15708,36560,15690) -(17099,16924,17079,16924) -(10817,6989,10747,6955) -(24338,19293,24291,19277) -(27566,17576,27544,17545) -(23041,38384,22970,38320) -\N -(12786,8485,12702,8435) -(13876,49473,13813,49448) -(31585,46998,31490,46929) -\N -(30227,8768,30206,8715) -(32062,39306,32023,39292) -(25003,35753,24921,35687) -(3281,6758,3232,6704) -\N -(11395,30299,11376,30220) -(5088,15275,5007,15203) -(31100,39538,31003,39444) -(2741,17877,2726,17793) -(42897,48620,42860,48537) -(4230,15778,4181,15776) -(17835,27530,17815,27431) -(34189,10933,34135,10921) -(7537,39974,7494,39973) -(21554,3507,21528,3476) -(9350,32326,9273,32275) -(16455,8874,16420,8793) -\N -(7346,34235,7330,34224) -(16417,48134,16352,48066) -\N -(41916,4971,41849,4886) -(15856,1522,15807,1521) -(41549,40218,41494,40144) -\N -(9978,16226,9972,16181) -(14856,13312,14808,13283) -(38490,41641,38428,41583) -(25828,7438,25807,7378) -(21876,30633,21796,30587) -(1908,14279,1825,14247) -\N -(32207,10251,32121,10184) -(370,9493,328,9441) -(42072,17634,41974,17600) -\N -(47298,9910,47235,9846) -(17856,11266,17782,11225) -(35009,21400,34956,21396) -(18337,11145,18335,11133) -\N -(25425,9139,25381,9085) -(35642,27783,35621,27782) -(3629,33164,3575,33163) -(17151,41255,17115,41204) -(17417,5835,17402,5751) -(33407,14226,33329,14141) -(1930,29955,1889,29931) -(41101,10942,41065,10844) -(36333,27288,36281,27233) -(21423,36868,21367,36825) -(36385,19566,36341,19510) -(27073,38301,27066,38232) -(43989,34187,43984,34174) -(48366,7488,48316,7483) -(37497,36075,37415,36043) -(46917,9891,46887,9870) -(37179,657,37103,634) -(3877,44736,3811,44684) -(30556,2975,30547,2962) -(7629,11447,7547,11416) -(45687,48147,45591,48088) -(5635,7184,5571,7146) -(9611,47327,9541,47246) -(7119,48224,7117,48152) -(15233,26480,15138,26430) -(37468,1526,37466,1513) -\N -(20855,2786,20828,2711) -(30538,44084,30480,44061) -(42231,41527,42149,41454) -(14963,13239,14952,13146) -(26819,43996,26745,43934) -(42172,35953,42086,35928) -(28785,12611,28710,12534) -(14089,1704,14047,1629) -(4343,26242,4341,26169) -(20327,42244,20231,42212) -(33671,12700,33666,12630) -(42144,32642,42128,32569) -(26590,19483,26503,19442) -(21741,46259,21723,46226) -(8822,34700,8760,34693) -\N -(2710,33521,2675,33505) -(26067,19998,26026,19989) -(12244,34509,12202,34489) -\N -(47162,598,47119,499) -(33093,49382,33068,49359) -(35170,26340,35153,26264) -(22552,35785,22490,35735) -(36791,23032,36781,22976) -(22857,10857,22833,10797) -\N -(47207,37405,47138,37365) -(21867,2836,21854,2811) -(3387,31487,3311,31456) -(47174,48121,47167,48101) -(24415,22232,24366,22224) -(7970,29251,7959,29211) -(18635,31294,18539,31221) -(8403,13380,8370,13372) -(738,18097,737,18054) -(37238,19195,37218,19114) -(582,47934,570,47897) -(12359,4635,12350,4619) -(43272,2013,43195,1958) -(47568,27149,47521,27088) -(24695,12827,24661,12796) -(26259,14077,26168,14019) -\N -(48478,36135,48425,36092) -(5230,39250,5206,39174) -(3488,18562,3423,18489) -(39502,16331,39460,16275) -(18296,1478,18233,1471) -\N -(28627,12430,28559,12410) -(25257,21981,25206,21954) -\N -(2410,41192,2325,41142) -(43681,9631,43587,9538) -\N -(15086,45309,15064,45270) -(13824,40807,13759,40787) -(7090,2207,7062,2159) -(3685,2480,3630,2391) -(14810,38335,14801,38275) -(26668,38018,26581,38012) -(45562,1517,45506,1424) -(11001,32481,10962,32402) -(27743,25245,27673,25161) -(15952,10598,15948,10535) -(12705,13308,12694,13232) -(31992,21195,31975,21118) -(25834,16652,25745,16626) -(21022,43625,20990,43576) -(45094,27254,45000,27240) -(9688,42601,9643,42533) -(17746,24659,17694,24616) -(1509,38859,1503,38809) -(2067,20438,2041,20369) -(7885,44528,7839,44444) -(27432,33052,27422,32987) -(26577,17157,26563,17142) -(10815,35985,10734,35908) -(44891,24067,44794,23979) -(48626,1900,48595,1850) -\N -(40659,35541,40659,35489) -(22231,26628,22210,26579) -(37408,23016,37375,22919) -(5920,15916,5906,15895) -\N -(33125,9952,33037,9880) -(12142,29705,12141,29670) -(3672,20995,3649,20899) -(39147,31967,39101,31907) -\N -(33812,48458,33748,48399) -(25038,14639,24978,14586) -(3859,16010,3857,15994) -(31926,39496,31889,39417) -(49300,28064,49297,28026) -(24121,38305,24048,38256) -(9252,4205,9155,4149) -(36124,30451,36056,30395) -(28809,49557,28794,49533) -(30500,44504,30471,44476) -(26866,42395,26822,42332) -(48195,1784,48101,1734) -(46201,14109,46112,14097) -\N -(2415,9975,2354,9914) -(30485,9581,30415,9558) -(6385,36838,6305,36838) -(2799,11189,2723,11095) -(21998,20503,21923,20406) -(29151,10714,29090,10671) -(28850,29276,28757,29207) -(43386,48845,43305,48834) -(25173,8310,25101,8294) -(34244,32352,34204,32342) -(35595,23728,35533,23672) -(1122,13581,1119,13538) -\N -(388,21716,296,21678) -(48782,11064,48701,11005) -(40293,12997,40213,12927) -\N -(28194,46428,28113,46414) -(4791,18118,4708,18105) -(471,29808,448,29775) -(3536,37803,3447,37737) -(1336,28416,1275,28392) -(16484,48478,16422,48454) -(25846,19320,25811,19296) -(48669,27703,48575,27615) -(24032,44217,24029,44127) -(12236,5019,12233,4986) -(1179,29838,1113,29778) -(33893,22049,33867,21955) -(16718,19462,16700,19440) -(17992,49438,17894,49433) -(35163,39941,35081,39885) -(33897,8362,33853,8328) -(2480,6640,2456,6599) -(28011,19729,27937,19679) -(15819,41516,15809,41440) -(29818,9136,29747,9089) -(28551,37016,28529,36941) -(36406,26879,36374,26872) -(16821,48925,16758,48914) -(23692,48163,23595,48160) -\N -(4803,10619,4759,10522) -(46600,33581,46553,33518) -(41349,11767,41310,11710) -(20856,29642,20799,29562) -(16559,46161,16504,46131) -(23041,1300,23003,1287) -(16630,44902,16554,44853) -(43065,14299,43013,14274) -(24818,22397,24796,22348) -(22282,24949,22218,24921) -(36668,28538,36631,28456) -(8080,1220,8018,1146) -(47282,34302,47277,34269) -(35603,33558,35557,33495) -(44764,32189,44700,32175) -\N -(46488,23965,46449,23868) -(46314,15047,46216,15013) -(6348,25381,6286,25363) -(3871,49288,3819,49251) -(462,38894,398,38867) -(23196,29214,23136,29169) -(29024,9775,29016,9759) -(42016,18555,41934,18472) -(8772,45981,8692,45973) -(11028,1351,10986,1278) -(26684,21668,26641,21656) -\N -(37262,26005,37260,25947) -(14899,44069,14814,44066) -\N -(39635,18701,39587,18698) -(28528,22948,28457,22857) -(7755,36528,7681,36454) -(32461,1172,32427,1106) -\N -(18775,27359,18736,27329) -(15379,20031,15337,19934) -(45888,33592,45881,33544) -(44013,24694,43962,24645) -\N -(43347,10699,43343,10699) -(49999,27218,49908,27176) -(13698,17326,13630,17317) -(34850,44313,34775,44302) -(38076,49235,37983,49214) -(35570,40218,35500,40136) -(40062,28973,40032,28878) -(3567,39847,3523,39781) -(498,2442,480,2401) -(29660,43620,29577,43561) -(10946,47356,10878,47351) -(8073,44233,8005,44144) -(9720,13473,9710,13462) -(3643,38014,3598,37932) -(16887,1408,16810,1375) -(7559,27914,7508,27874) -(30356,18573,30275,18569) -(12193,48176,12130,48116) -(11884,7756,11819,7731) -(18293,33272,18227,33234) -(46697,47874,46696,47828) -(35788,32517,35760,32446) -(33877,36987,33821,36958) -(31253,22819,31184,22808) -(7744,23115,7729,23103) -(21291,39817,21219,39778) -(13877,43379,13861,43290) -(42955,1406,42876,1382) -(49232,15950,49210,15880) -(48419,32001,48326,31902) -(18940,43246,18860,43150) -(32317,38240,32310,38201) -(11307,48298,11304,48222) -(38015,18190,38000,18176) -(27821,1177,27818,1131) -(18935,26757,18865,26682) -(42659,48284,42562,48244) -(30185,23350,30146,23291) -\N -(16496,11970,16441,11919) -(162,26040,120,25963) -(24238,47784,24185,47746) -(32326,8612,32274,8568) -(26141,13423,26051,13407) -(40132,22815,40089,22812) -(21151,48794,21056,48740) -\N -(22044,28358,22031,28334) -(6680,14746,6605,14669) -(40686,25139,40632,25070) -(22823,27549,22816,27507) -(2513,22841,2427,22811) -(36316,27787,36218,27728) -(554,35489,540,35441) -(536,30674,534,30609) -\N -(25385,38468,25295,38416) -(19467,47386,19437,47317) -(22425,38591,22387,38536) -(32493,17321,32396,17298) -(40115,47315,40109,47235) -(25002,2107,24963,2104) -(3901,9790,3898,9706) -\N -(40316,1721,40315,1658) -(40089,3454,40074,3443) -(793,17897,761,17897) -(6490,43552,6434,43522) -(10825,487,10820,405) -(47703,36067,47641,36011) -\N -(4480,11671,4468,11653) -(37713,10642,37711,10615) -(12315,5302,12273,5203) -\N -(8709,6617,8647,6557) -(24467,30535,24455,30494) -(40440,32757,40369,32668) -(49449,42447,49426,42428) -(44867,11197,44792,11137) -(39173,33241,39143,33187) -(43836,2212,43803,2184) -(23819,47613,23739,47575) -(20583,2134,20485,2042) -(48922,6169,48889,6111) -(5230,44613,5131,44604) -(37060,8051,37032,7975) -(19148,36711,19112,36704) -(36305,4216,36243,4118) -(6329,39089,6302,39047) -(36703,26367,36623,26307) -(44753,19721,44701,19631) -(42094,43310,42094,43285) -(4276,22377,4241,22352) -(30329,18906,30327,18815) -(21970,19605,21871,19590) -(23722,41924,23709,41861) -(30965,39775,30908,39692) -(32394,37895,32351,37890) -(23968,42162,23873,42095) -(1776,2621,1732,2548) -(24951,47758,24900,47679) -(32917,35771,32847,35753) -(5428,27773,5343,27769) -\N -(19650,142,19630,51) -(39769,17276,39743,17229) -(5171,24562,5119,24470) -(32976,35249,32917,35199) -\N -(4174,24603,4099,24504) -(38565,36960,38535,36926) -(39084,4328,39031,4301) -(32153,38043,32070,37990) -(38085,30640,38041,30603) -(14269,18426,14185,18422) -(42941,30850,42892,30788) -(32403,25999,32339,25960) -(16906,191,16816,139) -(3456,48722,3418,48721) -(3050,18287,3022,18243) -(6331,8439,6234,8364) -(5331,20797,5319,20793) -(39225,37408,39216,37348) -(34510,19838,34488,19810) -(45789,33873,45770,33786) -(369,1457,278,1409) -(16531,43785,16482,43729) -(11974,14789,11973,14730) -(23128,6811,23094,6798) -(43962,33659,43944,33599) -(20967,3115,20947,3079) -(39257,38606,39241,38595) -(22431,8246,22381,8235) -(26007,14672,25996,14593) -(24762,4261,24675,4261) -(35402,32077,35343,31988) -(5141,16476,5139,16393) -(16439,17564,16344,17472) -(36983,46663,36903,46567) -(35170,14144,35162,14048) -(22290,7841,22283,7810) -(22414,38398,22404,38319) -(9011,18177,8932,18150) -\N -(154,4019,138,3990) -(20447,4998,20383,4970) -(38867,35757,38795,35659) -(32322,15845,32227,15804) -\N -(29889,12142,29852,12055) -(36235,36918,36217,36897) -(41620,6581,41568,6581) -(24758,38504,24731,38483) -(42524,12904,42473,12895) -(17954,49975,17865,49915) -(1938,39019,1927,39013) -(4864,33279,4817,33258) -(45373,41967,45313,41885) -(28786,19028,28782,18978) -(41913,44950,41911,44908) -(33408,14698,33392,14681) -(27602,3460,27576,3419) -(3336,3728,3334,3715) -(9099,910,9080,813) -(34141,6403,34071,6367) -(48270,17216,48252,17130) -(2549,16546,2461,16474) -(27802,33669,27735,33642) -(48419,1682,48323,1583) -(5094,41211,5002,41123) -(11192,6217,11190,6146) -(6979,18503,6959,18421) -(41210,48187,41140,48143) -(15303,29527,15273,29441) -(12326,45572,12267,45570) -(29293,5861,29212,5826) -(23847,37241,23761,37178) -(44656,23926,44653,23831) -(30043,16194,29977,16105) -(902,9358,879,9339) -(23850,46501,23834,46494) -(42333,13300,42287,13246) -(25226,18086,25169,18005) -(40252,12082,40183,12038) -(49275,18076,49216,18055) -(8255,28878,8238,28862) -(11325,41286,11320,41235) -(16948,18588,16926,18528) -(31394,1099,31374,1038) -(30705,35772,30637,35766) -(3858,39131,3771,39125) -(17565,24892,17515,24808) -(9221,49715,9216,49661) -(44945,25769,44875,25722) -(33408,13563,33310,13527) -(48505,4407,48408,4373) -(21859,37217,21763,37217) -(39393,14422,39335,14364) -\N -(19905,1154,19841,1098) -(25946,10388,25906,10366) -(10104,13748,10027,13746) -(5822,24629,5820,24599) -(38194,11287,38127,11252) -(15694,46757,15625,46716) -(326,18837,285,18817) -(49611,47078,49533,47052) -(48233,18850,48150,18842) -\N -(29239,9962,29208,9875) -(40062,44554,39973,44460) -(19135,20729,19059,20643) -(31969,40664,31896,40643) -\N -(3725,9191,3711,9095) -(44280,40158,44264,40108) -(37236,42756,37160,42694) -(27958,19055,27888,18959) -(45270,17661,45187,17601) -(12115,39546,12061,39525) -(10227,32295,10168,32231) -(39264,31123,39226,31085) -(6566,40000,6532,39904) -(30058,6975,30012,6903) -(49631,6909,49597,6823) -(42168,10926,42134,10905) -(44892,30042,44858,29970) -(19540,19803,19495,19788) -(18403,25454,18371,25404) -(22929,26795,22841,26722) -(16648,30213,16626,30174) -(3440,7495,3429,7468) -(30708,49028,30643,48998) -(26258,14164,26255,14151) -(44206,31653,44121,31637) -(1510,15179,1426,15130) -(6986,30496,6887,30416) -(7192,43403,7138,43339) -(39921,22071,39866,21976) -(45870,17011,45796,16919) -(15939,9563,15917,9539) -(23728,24737,23691,24725) -(6444,40416,6363,40375) -(21899,23861,21857,23765) -(20610,36765,20533,36742) -(46520,33082,46433,32983) -(21406,20902,21311,20895) -\N -(37913,42300,37814,42269) -(18216,8177,18161,8173) -(32967,8258,32899,8244) -(14978,40230,14971,40149) -(30343,39152,30266,39101) -(25917,5835,25843,5806) -\N -(5169,45366,5141,45314) -\N -(16221,20898,16209,20875) -(13151,19869,13145,19811) -(44399,2801,44337,2713) -\N -(10959,48311,10957,48230) -(4794,11711,4732,11661) -(764,10149,762,10091) -(15985,46067,15898,46028) -(41434,22870,41342,22867) -(43769,23796,43743,23756) -(10017,18440,9919,18384) -(21141,43119,21097,43112) -(7782,13424,7694,13398) -(25088,36224,25059,36150) -(46325,48722,46241,48631) -\N -(11042,33125,11011,33071) -(22347,13460,22290,13375) -(3508,20538,3483,20536) -(5331,42945,5272,42875) -\N -(2368,15537,2339,15503) -(45314,31830,45254,31817) -(34358,2649,34319,2589) -\N -(17576,30407,17572,30323) -(29836,41324,29746,41287) -(21036,39996,21014,39899) -(26886,6460,26787,6400) -(15709,5625,15627,5558) -(37415,15979,37414,15911) -(47761,16860,47728,16813) -(35814,48252,35755,48173) -\N -(28559,20810,28496,20715) -(12034,11921,12002,11905) -(1818,27450,1805,27406) -(33810,45499,33806,45413) -(17376,18175,17323,18138) -(34106,28135,34049,28106) -(44947,23165,44919,23091) -(37670,41904,37616,41840) -(12614,15027,12555,14969) -(43301,75,43227,43) -\N -(27526,15096,27450,15088) -(26947,33409,26853,33333) -(1537,43572,1471,43499) -\N -(21607,35452,21605,35375) -(24869,46565,24818,46531) -(4774,30335,4723,30257) -(11615,18316,11579,18310) -(18444,15819,18354,15763) -(47267,22574,47203,22518) -(22287,49538,22203,49511) -(43010,16270,43010,16202) -\N -(1623,8350,1578,8254) -(21220,43808,21137,43748) -(40397,16471,40358,16434) -\N -(34839,1377,34744,1327) -(17096,5730,17090,5637) -\N -(28156,37782,28155,37723) -(3672,5686,3586,5638) -(21856,48656,21840,48638) -(6907,7791,6892,7761) -(17952,21370,17862,21350) -(37793,13461,37784,13381) -(14740,49655,14709,49604) -(21690,6337,21593,6289) -\N -(10423,33548,10364,33498) -\N -(39187,23274,39136,23197) -\N -(21882,37247,21835,37167) -\N -(11343,16957,11281,16914) -(38279,43400,38264,43352) -(23167,30271,23086,30224) -(46278,6037,46180,5964) -(28626,31165,28605,31095) -\N -(31018,367,30946,333) -(23541,12541,23530,12523) -(49741,14535,49691,14511) -(31444,12702,31425,12612) -\N -(22406,26536,22316,26534) -(6807,9761,6758,9723) -(15698,1941,15687,1848) -(49310,4625,49295,4584) -(21345,18939,21269,18887) -(31433,30493,31411,30439) -(44980,12400,44950,12372) -(25054,13949,24984,13949) -(40538,7253,40483,7212) -(16967,8627,16936,8604) -(26872,3646,26804,3594) -(24575,42883,24530,42883) -(11823,5755,11771,5721) -\N -(2553,46189,2513,46174) -(24993,14552,24898,14470) -(28453,1719,28419,1665) -(8925,22603,8878,22589) -(47635,15380,47546,15378) -(35378,18112,35324,18058) -(27347,22264,27293,22200) -\N -(44323,29044,44273,28958) -(41538,38324,41484,38290) -(19128,49932,19112,49849) -(17904,12548,17867,12503) -(35103,14426,35092,14336) -(29807,10142,29714,10052) -(44507,22903,44462,22847) -(11419,13324,11399,13251) -(8573,42221,8562,42123) -(46798,45843,46765,45765) -(12028,31783,11967,31749) -(10635,45300,10604,45251) -(9626,8248,9587,8194) -(18290,741,18246,732) -(39949,44672,39932,44641) -(7897,11692,7893,11637) -(20165,42246,20112,42168) -(4341,48390,4285,48338) -(30126,28913,30088,28869) -(40565,1733,40472,1721) -(9981,30147,9915,30133) -(47292,25511,47217,25462) -(20137,24489,20104,24392) -(2385,28283,2381,28189) -(20429,10052,20357,10009) -(8395,38568,8348,38480) -(17381,36112,17349,36038) -(37845,30953,37759,30926) -(27452,12732,27411,12652) -(38196,32186,38114,32116) -\N -(6527,49356,6508,49315) -(43891,29789,43856,29723) -(6146,37192,6085,37107) -\N -(42012,28897,41939,28808) -\N -(14909,13815,14846,13757) -(11120,24095,11035,24049) -(3132,41545,3053,41526) -(40084,40315,39994,40261) -(39671,17445,39576,17361) -(47135,35853,47085,35831) -(39297,1941,39290,1911) -(47143,35898,47072,35880) -(16017,6711,15989,6686) -(47110,30305,47087,30213) -(38102,27639,38091,27602) -(17954,22544,17863,22453) -(39891,11791,39815,11739) -(13996,20290,13922,20278) -(22284,23143,22190,23081) -(25345,24019,25313,24017) -(47134,44803,47055,44761) -(41360,16573,41326,16503) -(10464,1071,10457,998) -\N -(23515,47517,23451,47499) -(9308,8452,9238,8392) -(28695,5657,28671,5644) -(45104,9913,45077,9871) -(337,455,240,359) -(11562,45479,11472,45428) -(11952,18466,11931,18425) -\N -(35789,5154,35775,5128) -(19024,18299,18979,18230) -(43056,38113,42975,38067) -(10075,26847,10064,26806) -(3065,8107,3029,8038) -(24766,19059,24749,18985) -(14438,24805,14413,24708) -(9523,3058,9485,2998) -(24516,31262,24478,31204) -(49513,26044,49434,26035) -(14110,38528,14103,38461) -(31679,35618,31619,35618) -(10029,20258,10008,20248) -(39269,37586,39233,37539) -(12343,8197,12247,8113) -(11155,44223,11111,44134) -(25437,20606,25338,20534) -(46604,16156,46570,16131) -(4636,14004,4592,13941) -(15975,29628,15912,29556) -(49887,24274,49805,24184) -(11812,13440,11723,13418) -(21589,38179,21531,38085) -(32255,44463,32219,44454) -(15023,12698,14989,12687) -(28906,48630,28818,48568) -(28886,38905,28861,38832) -(34786,22285,34740,22240) -\N -(46513,46780,46425,46780) -\N -(26626,31759,26551,31677) -(19792,25967,19763,25933) -(20432,14394,20388,14365) -(27092,7301,27052,7278) -(22283,987,22198,928) -(6197,24363,6112,24311) -(46601,49259,46551,49231) -(12392,48052,12363,48038) -(46116,31386,46067,31356) -(7354,16855,7289,16778) -(47501,42808,47495,42761) -(16461,25487,16391,25398) -(42678,18798,42678,18756) -(9466,18207,9419,18185) -(17467,14177,17416,14097) -(28533,31886,28487,31832) -(13225,38472,13188,38395) -(5180,40970,5173,40902) -(83,10271,15,10265) -(2111,6784,2016,6690) -(41835,11064,41798,10995) -(29273,48585,29181,48536) -(29066,21615,28985,21543) -(19805,44143,19727,44128) -(48919,21468,48875,21467) -(28790,34287,28721,34251) -(10911,33074,10869,32989) -(6111,16519,6032,16489) -(43889,33838,43837,33768) -(32323,21685,32304,21644) -(9552,27819,9539,27753) -(38266,49852,38233,49844) -(37672,48362,37663,48277) -(32550,47029,32529,46931) -(46307,6620,46272,6616) -(23192,46608,23105,46566) -(30399,48330,30335,48239) -(36268,25058,36235,24984) -(19181,8120,19089,8098) -(24376,19983,24294,19925) -(18297,18375,18202,18292) -\N -(31608,6215,31575,6168) -(12788,49510,12784,49468) -(46071,13013,46035,12991) -(27647,8218,27582,8201) -(49580,11076,49537,11050) -\N -(35501,33782,35501,33687) -(19969,3148,19964,3082) -(37728,49153,37726,49152) -(5322,48440,5321,48435) -(48003,10096,47904,10005) -(39361,22318,39348,22236) -(30488,7456,30437,7430) -(18533,39476,18481,39394) -(39462,23701,39433,23604) -(26701,18300,26686,18235) -(17405,35577,17387,35517) -(33971,29928,33953,29919) -(6328,10241,6276,10217) -(32459,44259,32453,44217) -(1715,42385,1647,42357) -(48113,6960,48103,6872) -(30561,4255,30476,4240) -(38907,43619,38827,43553) -(29149,20773,29070,20698) -(17006,1543,16970,1497) -\N -(11737,18808,11714,18788) -(13019,30534,13005,30481) -(39224,31729,39191,31683) -(4942,41680,4907,41596) -(12287,37187,12188,37172) -(30758,29579,30725,29531) -\N -(16604,17963,16581,17912) -(19459,15888,19409,15812) -(34696,24783,34600,24725) -(21621,14159,21558,14110) -(12193,46149,12145,46096) -(37781,4715,37692,4635) -(41854,44125,41807,44040) -(23604,23585,23571,23533) -(7853,36967,7797,36908) -(2755,13279,2720,13206) -(4314,15424,4283,15383) -(29584,12685,29493,12594) -(25138,33726,25042,33691) -(38393,10270,38326,10185) -(4247,12615,4225,12567) -(36100,33156,36100,33107) -(20024,40796,20016,40708) -(3927,44892,3914,44843) -(10317,43168,10226,43096) -(22057,3419,22042,3334) -(37097,21814,37025,21811) -(32084,21564,31996,21491) -(34079,39921,34058,39911) -(23078,47459,23018,47373) -(38109,616,38082,568) -(11862,40382,11764,40292) -(33403,33320,33389,33289) -(36639,24829,36623,24829) -(12995,45080,12992,45040) -(16545,19981,16532,19891) -(26155,10659,26154,10634) -(24423,255,24360,213) -(823,22487,781,22442) -(12823,20064,12735,20040) -(19688,11710,19681,11654) -(2892,20452,2836,20424) -(15533,10807,15464,10711) -(46994,41143,46955,41082) -(18155,2421,18069,2392) -(2628,12688,2605,12602) -(35128,8396,35044,8365) -(44765,49615,44758,49524) -(11226,44529,11178,44515) -(31334,32463,31291,32456) -(43224,23387,43168,23364) -(30882,10414,30798,10395) -(29139,967,29139,923) -(29959,45244,29877,45223) -(19946,217,19941,118) -(49732,22033,49642,22012) -(32914,15360,32879,15290) -(47825,21097,47747,21030) -(10788,5131,10746,5086) -\N -(15497,9698,15481,9678) -(10617,47195,10601,47117) -(42392,10583,42340,10550) -(10753,33520,10669,33509) -(5553,21580,5521,21527) -(36840,12336,36817,12320) -(49785,12554,49702,12553) -(17737,38349,17639,38277) -(48000,7823,47956,7814) -(5019,3184,4931,3160) -(30120,3524,30063,3492) -(37044,2016,37001,1942) -(23496,38566,23469,38528) -(17255,48957,17200,48903) -(27815,2138,27808,2090) -(40440,11129,40368,11105) -(35305,21772,35272,21717) -(41308,45065,41229,44973) -(14893,28807,14817,28789) -(30776,45824,30731,45772) -(742,40724,652,40672) -(5985,41133,5927,41097) -(9576,10226,9540,10218) -(21407,23207,21323,23160) -(44880,34228,44877,34169) -(29146,49694,29143,49682) -(28502,34886,28471,34832) -\N -(30662,5584,30604,5528) -(12612,26081,12552,26001) -(17166,49308,17098,49270) -(9586,14116,9488,14104) -(37323,47576,37264,47482) -(48009,49713,48004,49614) -(49308,23780,49297,23760) -(8667,32342,8592,32294) -(37826,48560,37822,48485) -\N -(24493,18653,24486,18616) -(17914,3850,17887,3775) -(34270,43873,34231,43826) -(7753,44715,7660,44651) -(44328,36364,44265,36350) -(10146,3030,10111,2975) -(35273,40106,35269,40062) -\N -(38566,43846,38547,43760) -(12400,41394,12377,41378) -(45196,38286,45153,38250) -(48511,14972,48428,14883) -(25939,36328,25886,36277) -(38997,11007,38979,10917) -(30342,518,30244,453) -(6876,7468,6867,7454) -(17566,27575,17566,27480) -(18869,28538,18858,28475) -(16825,33309,16726,33255) -(14585,26111,14490,26035) -(28743,49392,28664,49349) -(26652,23359,26618,23297) -\N -(40129,33653,40102,33584) -(41074,26393,41038,26389) -(3869,33564,3869,33536) -(28455,14205,28364,14163) -(13866,45603,13770,45543) -(21666,30586,21578,30544) -(29978,11931,29893,11868) -(1594,1043,1517,971) -(948,1201,907,1156) -(27547,13692,27545,13677) -(13661,38184,13566,38154) -(2389,40026,2317,39938) -(35481,46379,35481,46320) -\N -(26917,45698,26864,45689) -(23933,41617,23909,41539) -(8912,8471,8862,8401) -(9625,4747,9558,4692) -(34743,35056,34721,34969) -(39544,21762,39475,21717) -\N -(11741,26330,11656,26293) -(39015,1315,38966,1285) -(13418,44237,13326,44202) -(2107,17672,2093,17616) -(42448,28844,42370,28764) -(49843,5175,49808,5145) -(6536,23000,6467,22958) -(11114,5822,11027,5739) -(48457,11074,48384,11024) -(12343,23110,12310,23074) -(17300,24847,17276,24825) -(8823,8253,8793,8238) -(3449,171,3354,108) -\N -(21650,23955,21605,23883) -(13260,3234,13193,3214) -(25361,10896,25305,10806) -(25051,25042,25011,25001) -(25044,25088,25015,25005) -\N -(25007,25061,25002,25013) -(25066,25105,25003,25007) -(25028,25012,25015,25011) -(25031,25057,25006,25018) -(25015,25042,25004,25012) -(25091,25049,25019,25019) -(25023,25011,25000,25004) -\N -(25053,25104,25010,25012) -(25058,25001,25018,25000) -(25059,25051,25008,25016) -(25043,25069,25007,25004) -(25006,25101,25002,25002) -(25095,25012,25014,25007) -(25054,25052,25019,25013) -(25108,25077,25009,25018) -(25007,25023,25003,25002) -\N -(25076,25098,25002,25016) -(25030,25077,25012,25006) diff --git a/contrib/rtree_gist/expected/rtree_gist.out b/contrib/rtree_gist/expected/rtree_gist.out deleted file mode 100644 index 74ac7e640d..0000000000 --- a/contrib/rtree_gist/expected/rtree_gist.out +++ /dev/null @@ -1,45 +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 boxtmp (b box); -\copy boxtmp from 'data/test_box.data' -select count(*) from boxtmp where b && '(1000,1000,0,0)'::box; - count -------- - 2 -(1 row) - -create index bix on boxtmp using rtree (b); -select count(*) from boxtmp where b && '(1000,1000,0,0)'::box; - count -------- - 2 -(1 row) - -drop index bix; -create index bix on boxtmp using gist (b); -select count(*) from boxtmp where b && '(1000,1000,0,0)'::box; - count -------- - 2 -(1 row) - -create table polytmp (p polygon); -\copy polytmp from 'data/test_box.data' -create index pix on polytmp using rtree (p); -select count(*) from polytmp where p && '(1000,1000),(0,0)'::polygon; - count -------- - 2 -(1 row) - -drop index pix; -create index pix on polytmp using gist (p); -select count(*) from polytmp where p && '(1000,1000),(0,0)'::polygon; - count -------- - 2 -(1 row) - diff --git a/contrib/rtree_gist/rtree_gist.c b/contrib/rtree_gist/rtree_gist.c deleted file mode 100644 index 580ca6427f..0000000000 --- a/contrib/rtree_gist/rtree_gist.c +++ /dev/null @@ -1,578 +0,0 @@ -/*------------------------------------------------------------------------- - * - * rtree_gist.c - * pg_amproc entries for GiSTs over 2-D boxes. - * This gives R-tree behavior, with Guttman's poly-time split algorithm. - * - * - * - * IDENTIFICATION - * $Header: /cvsroot/pgsql/contrib/rtree_gist/Attic/rtree_gist.c,v 1.5 2002/05/28 15:24:53 tgl Exp $ - * - *------------------------------------------------------------------------- - */ -#include "postgres.h" - -#include "access/gist.h" -#include "access/itup.h" -#include "access/rtree.h" -#include "utils/palloc.h" -#include "utils/geo_decls.h" -#include "utils/elog.h" - -typedef Datum (*RDF) (PG_FUNCTION_ARGS); -typedef Datum (*BINARY_UNION) (Datum, Datum, int *); -typedef float (*SIZE_BOX) (Datum); - -/* -** box ops -*/ -PG_FUNCTION_INFO_V1(gbox_compress); -PG_FUNCTION_INFO_V1(gbox_union); -PG_FUNCTION_INFO_V1(gbox_picksplit); -PG_FUNCTION_INFO_V1(gbox_consistent); -PG_FUNCTION_INFO_V1(gbox_penalty); -PG_FUNCTION_INFO_V1(gbox_same); - -Datum gbox_compress(PG_FUNCTION_ARGS); -Datum gbox_union(PG_FUNCTION_ARGS); -Datum gbox_picksplit(PG_FUNCTION_ARGS); -Datum gbox_consistent(PG_FUNCTION_ARGS); -Datum gbox_penalty(PG_FUNCTION_ARGS); -Datum gbox_same(PG_FUNCTION_ARGS); - -static bool gbox_leaf_consistent(BOX *key, BOX *query, StrategyNumber strategy); -static float size_box(Datum box); - -/* -** Polygon ops -*/ -PG_FUNCTION_INFO_V1(gpoly_compress); -PG_FUNCTION_INFO_V1(gpoly_consistent); - -Datum gpoly_compress(PG_FUNCTION_ARGS); -Datum gpoly_consistent(PG_FUNCTION_ARGS); - -/* -** Common rtree-function (for all ops) -*/ -static bool rtree_internal_consistent(BOX *key, BOX *query, StrategyNumber strategy); - -PG_FUNCTION_INFO_V1(rtree_decompress); - -Datum rtree_decompress(PG_FUNCTION_ARGS); - -/************************************************** - * Box ops - **************************************************/ - -/* -** The GiST Consistent method for boxes -** Should return false if for all data items x below entry, -** the predicate x op query == FALSE, where op is the oper -** corresponding to strategy in the pg_amop table. -*/ -Datum -gbox_consistent(PG_FUNCTION_ARGS) -{ - GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); - BOX *query = (BOX *) PG_GETARG_POINTER(1); - StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); - - /* - * * if entry is not leaf, use gbox_internal_consistent, * else use - * gbox_leaf_consistent - */ - if (!(DatumGetPointer(entry->key) != NULL && query)) - PG_RETURN_BOOL(FALSE); - - if (GIST_LEAF(entry)) - PG_RETURN_BOOL(gbox_leaf_consistent((BOX *) DatumGetPointer(entry->key), query, strategy)); - else - PG_RETURN_BOOL(rtree_internal_consistent((BOX *) DatumGetPointer(entry->key), query, strategy)); -} - - -/* -** The GiST Union method for boxes -** returns the minimal bounding box that encloses all the entries in entryvec -*/ -Datum -gbox_union(PG_FUNCTION_ARGS) -{ - bytea *entryvec = (bytea *) PG_GETARG_POINTER(0); - int *sizep = (int *) PG_GETARG_POINTER(1); - int numranges, - i; - BOX *cur, - *pageunion; - - numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY); - pageunion = (BOX *) palloc(sizeof(BOX)); - cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[0].key); - memcpy((void *) pageunion, (void *) cur, sizeof(BOX)); - - for (i = 1; i < numranges; i++) - { - cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[i].key); - if (pageunion->high.x < cur->high.x) - pageunion->high.x = cur->high.x; - if (pageunion->low.x > cur->low.x) - pageunion->low.x = cur->low.x; - if (pageunion->high.y < cur->high.y) - pageunion->high.y = cur->high.y; - if (pageunion->low.y > cur->low.y) - pageunion->low.y = cur->low.y; - } - *sizep = sizeof(BOX); - - PG_RETURN_POINTER(pageunion); -} - -/* -** GiST Compress methods for boxes -** do not do anything. -*/ -Datum -gbox_compress(PG_FUNCTION_ARGS) -{ - PG_RETURN_POINTER(PG_GETARG_POINTER(0)); -} - -/* -** The GiST Penalty method for boxes -** As in the R-tree paper, we use change in area as our penalty metric -*/ -Datum -gbox_penalty(PG_FUNCTION_ARGS) -{ - GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); - GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1); - float *result = (float *) PG_GETARG_POINTER(2); - Datum ud; - float tmp1; - - ud = DirectFunctionCall2(rt_box_union, origentry->key, newentry->key); - tmp1 = size_box(ud); - if (DatumGetPointer(ud) != NULL) - pfree(DatumGetPointer(ud)); - - *result = tmp1 - size_box(origentry->key); - PG_RETURN_POINTER(result); -} - -typedef struct { - BOX *key; - int pos; -} KBsort; - -static int -compare_KB(const void* a, const void* b) { - BOX *abox = ((KBsort*)a)->key; - BOX *bbox = ((KBsort*)b)->key; - float sa = (abox->high.x - abox->low.x) * (abox->high.y - abox->low.y); - float sb = (bbox->high.x - bbox->low.x) * (bbox->high.y - bbox->low.y); - - if ( sa==sb ) return 0; - return ( sa>sb ) ? 1 : -1; -} - -/* -** The GiST PickSplit method -** New linear algorithm, see 'New Linear Node Splitting Algorithm for R-tree', -** C.H.Ang and T.C.Tan -*/ -Datum -gbox_picksplit(PG_FUNCTION_ARGS) -{ - bytea *entryvec = (bytea *) PG_GETARG_POINTER(0); - GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); - OffsetNumber i; - OffsetNumber *listL, - *listR, - *listB, - *listT; - BOX *unionL, - *unionR, - *unionB, - *unionT; - int posL, - posR, - posB, - posT; - BOX pageunion; - BOX *cur; - char direction = ' '; - bool allisequal = true; - OffsetNumber maxoff; - int nbytes; - - posL = posR = posB = posT = 0; - maxoff = ((VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY)) - 1; - - cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[FirstOffsetNumber].key); - memcpy((void *) &pageunion, (void *) cur, sizeof(BOX)); - - /* find MBR */ - for (i = OffsetNumberNext(FirstOffsetNumber); i <= maxoff; i = OffsetNumberNext(i)) - { - cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[i].key); - if ( allisequal == true && ( - pageunion.high.x != cur->high.x || - pageunion.high.y != cur->high.y || - pageunion.low.x != cur->low.x || - pageunion.low.y != cur->low.y - ) ) - allisequal = false; - - if (pageunion.high.x < cur->high.x) - pageunion.high.x = cur->high.x; - if (pageunion.low.x > cur->low.x) - pageunion.low.x = cur->low.x; - if (pageunion.high.y < cur->high.y) - pageunion.high.y = cur->high.y; - if (pageunion.low.y > cur->low.y) - pageunion.low.y = cur->low.y; - } - - nbytes = (maxoff + 2) * sizeof(OffsetNumber); - listL = (OffsetNumber *) palloc(nbytes); - listR = (OffsetNumber *) palloc(nbytes); - unionL = (BOX *) palloc(sizeof(BOX)); - unionR = (BOX *) palloc(sizeof(BOX)); - if (allisequal) - { - cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[OffsetNumberNext(FirstOffsetNumber)].key); - if (memcmp((void *) cur, (void *) &pageunion, sizeof(BOX)) == 0) - { - v->spl_left = listL; - v->spl_right = listR; - v->spl_nleft = v->spl_nright = 0; - memcpy((void *) unionL, (void *) &pageunion, sizeof(BOX)); - memcpy((void *) unionR, (void *) &pageunion, sizeof(BOX)); - - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) - { - if (i <= (maxoff - FirstOffsetNumber + 1) / 2) - { - v->spl_left[v->spl_nleft] = i; - v->spl_nleft++; - } - else - { - v->spl_right[v->spl_nright] = i; - v->spl_nright++; - } - } - v->spl_ldatum = BoxPGetDatum(unionL); - v->spl_rdatum = BoxPGetDatum(unionR); - - PG_RETURN_POINTER(v); - } - } - - listB = (OffsetNumber *) palloc(nbytes); - listT = (OffsetNumber *) palloc(nbytes); - unionB = (BOX *) palloc(sizeof(BOX)); - unionT = (BOX *) palloc(sizeof(BOX)); - -#define ADDLIST( list, unionD, pos, num ) do { \ - if ( pos ) { \ - if ( unionD->high.x < cur->high.x ) unionD->high.x = cur->high.x; \ - if ( unionD->low.x > cur->low.x ) unionD->low.x = cur->low.x; \ - if ( unionD->high.y < cur->high.y ) unionD->high.y = cur->high.y; \ - if ( unionD->low.y > cur->low.y ) unionD->low.y = cur->low.y; \ - } else { \ - memcpy( (void*)unionD, (void*) cur, sizeof( BOX ) ); \ - } \ - list[pos] = num; \ - (pos)++; \ -} while(0) - - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) - { - cur = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[i].key); - if (cur->low.x - pageunion.low.x < pageunion.high.x - cur->high.x) - ADDLIST(listL, unionL, posL,i); - else - ADDLIST(listR, unionR, posR,i); - if (cur->low.y - pageunion.low.y < pageunion.high.y - cur->high.y) - ADDLIST(listB, unionB, posB,i); - else - ADDLIST(listT, unionT, posT,i); - } - - /* bad disposition, sort by ascending and resplit */ - if ( (posR==0 || posL==0) && (posT==0 || posB==0) ) { - KBsort *arr = (KBsort*)palloc( sizeof(KBsort) * maxoff ); - posL = posR = posB = posT = 0; - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { - arr[i-1].key = DatumGetBoxP(((GISTENTRY *) VARDATA(entryvec))[i].key); - arr[i-1].pos = i; - } - qsort( arr, maxoff, sizeof(KBsort), compare_KB ); - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { - cur = arr[i-1].key; - if (cur->low.x - pageunion.low.x < pageunion.high.x - cur->high.x) - ADDLIST(listL, unionL, posL,arr[i-1].pos); - else if ( cur->low.x - pageunion.low.x == pageunion.high.x - cur->high.x ) { - if ( posL>posR ) - ADDLIST(listR, unionR, posR,arr[i-1].pos); - else - ADDLIST(listL, unionL, posL,arr[i-1].pos); - } else - ADDLIST(listR, unionR, posR,arr[i-1].pos); - - if (cur->low.y - pageunion.low.y < pageunion.high.y - cur->high.y) - ADDLIST(listB, unionB, posB,arr[i-1].pos); - else if ( cur->low.y - pageunion.low.y == pageunion.high.y - cur->high.y ) { - if ( posB>posT ) - ADDLIST(listT, unionT, posT,arr[i-1].pos); - else - ADDLIST(listB, unionB, posB,arr[i-1].pos); - } else - ADDLIST(listT, unionT, posT,arr[i-1].pos); - } - pfree(arr); - } - - /* which split more optimal? */ - if (Max(posL, posR) < Max(posB, posT)) - direction = 'x'; - else if (Max(posL, posR) > Max(posB, posT)) - direction = 'y'; - else - { - Datum interLR = DirectFunctionCall2(rt_box_inter, - BoxPGetDatum(unionL), - BoxPGetDatum(unionR)); - Datum interBT = DirectFunctionCall2(rt_box_inter, - BoxPGetDatum(unionB), - BoxPGetDatum(unionT)); - float sizeLR, - sizeBT; - - sizeLR = size_box(interLR); - sizeBT = size_box(interBT); - - if (sizeLR < sizeBT) - direction = 'x'; - else - direction = 'y'; - } - - if (direction == 'x') - { - pfree(unionB); - pfree(listB); - pfree(unionT); - pfree(listT); - - v->spl_left = listL; - v->spl_right = listR; - v->spl_nleft = posL; - v->spl_nright = posR; - v->spl_ldatum = BoxPGetDatum(unionL); - v->spl_rdatum = BoxPGetDatum(unionR); - } - else - { - pfree(unionR); - pfree(listR); - pfree(unionL); - pfree(listL); - - v->spl_left = listB; - v->spl_right = listT; - v->spl_nleft = posB; - v->spl_nright = posT; - v->spl_ldatum = BoxPGetDatum(unionB); - v->spl_rdatum = BoxPGetDatum(unionT); - } - - PG_RETURN_POINTER(v); -} - -/* -** Equality method -*/ -Datum -gbox_same(PG_FUNCTION_ARGS) -{ - BOX *b1 = (BOX *) PG_GETARG_POINTER(0); - BOX *b2 = (BOX *) PG_GETARG_POINTER(1); - bool *result = (bool *) PG_GETARG_POINTER(2); - - if (b1 && b2) - *result = DatumGetBool(DirectFunctionCall2(box_same, PointerGetDatum(b1), PointerGetDatum(b2))); - else - *result = (b1 == NULL && b2 == NULL) ? TRUE : FALSE; - PG_RETURN_POINTER(result); -} - -/* -** SUPPORT ROUTINES for boxes -*/ -static bool -gbox_leaf_consistent(BOX *key, - BOX *query, - StrategyNumber strategy) -{ - bool retval; - - switch (strategy) - { - case RTLeftStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_left, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTOverLeftStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_overleft, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTOverlapStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_overlap, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTOverRightStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_overright, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTRightStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_right, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTSameStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_same, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTContainsStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_contain, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTContainedByStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_contained, PointerGetDatum(key), PointerGetDatum(query))); - break; - default: - retval = FALSE; - } - return (retval); -} - -static float -size_box(Datum box) -{ - if (DatumGetPointer(box) != NULL) - { - float size; - - DirectFunctionCall2(rt_box_size, - box, PointerGetDatum(&size)); - return size; - } - else - return 0.0; -} - -/************************************************** - * Polygon ops - **************************************************/ - -Datum -gpoly_compress(PG_FUNCTION_ARGS) -{ - GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); - GISTENTRY *retval; - - if (entry->leafkey) - { - retval = palloc(sizeof(GISTENTRY)); - if (DatumGetPointer(entry->key) != NULL) - { - POLYGON *in; - BOX *r; - - in = (POLYGON *) PG_DETOAST_DATUM(entry->key); - r = (BOX *) palloc(sizeof(BOX)); - memcpy((void *) r, (void *) &(in->boundbox), sizeof(BOX)); - if (in != (POLYGON *) DatumGetPointer(entry->key)) - pfree(in); - - gistentryinit(*retval, PointerGetDatum(r), - entry->rel, entry->page, - entry->offset, sizeof(BOX), FALSE); - - } - else - { - gistentryinit(*retval, (Datum) 0, - entry->rel, entry->page, - entry->offset, 0, FALSE); - } - } - else - retval = entry; - PG_RETURN_POINTER(retval); -} - -Datum -gpoly_consistent(PG_FUNCTION_ARGS) -{ - GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); - POLYGON *query = (POLYGON *) PG_DETOAST_DATUM(PG_GETARG_POINTER(1)); - StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); - bool result; - - /* - * * if entry is not leaf, use gbox_internal_consistent, * else use - * gbox_leaf_consistent - */ - if (!(DatumGetPointer(entry->key) != NULL && query)) - PG_RETURN_BOOL(FALSE); - - result = rtree_internal_consistent((BOX *) DatumGetPointer(entry->key), - &(query->boundbox), strategy); - - PG_FREE_IF_COPY(query, 1); - PG_RETURN_BOOL(result); -} - -/***************************************** - * Common rtree-function (for all ops) - *****************************************/ - -static bool -rtree_internal_consistent(BOX *key, - BOX *query, - StrategyNumber strategy) -{ - bool retval; - - switch (strategy) - { - case RTLeftStrategyNumber: - case RTOverLeftStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_overleft, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTOverlapStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_overlap, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTOverRightStrategyNumber: - case RTRightStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_right, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTSameStrategyNumber: - case RTContainsStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_contain, PointerGetDatum(key), PointerGetDatum(query))); - break; - case RTContainedByStrategyNumber: - retval = DatumGetBool(DirectFunctionCall2(box_overlap, PointerGetDatum(key), PointerGetDatum(query))); - break; - default: - retval = FALSE; - } - return (retval); -} - -/* -** GiST DeCompress methods -** do not do anything. -*/ -Datum -rtree_decompress(PG_FUNCTION_ARGS) -{ - PG_RETURN_POINTER(PG_GETARG_POINTER(0)); -} diff --git a/contrib/rtree_gist/rtree_gist.sql.in b/contrib/rtree_gist/rtree_gist.sql.in deleted file mode 100644 index 0d1770381f..0000000000 --- a/contrib/rtree_gist/rtree_gist.sql.in +++ /dev/null @@ -1,342 +0,0 @@ -begin transaction; --- --- --- --- BOX ops --- --- --- --- define the GiST support methods -create function gbox_consistent(opaque,box,int4) returns bool as 'MODULE_PATHNAME' language 'C'; - -create function gbox_compress(opaque) returns opaque as 'MODULE_PATHNAME' language 'C'; - -create function rtree_decompress(opaque) returns opaque as 'MODULE_PATHNAME' language 'C'; - -create function gbox_penalty(opaque,opaque,opaque) returns opaque as 'MODULE_PATHNAME' language 'C' with (isstrict); - -create function gbox_picksplit(opaque, opaque) returns opaque as 'MODULE_PATHNAME' language 'C'; - -create function gbox_union(bytea, opaque) returns box as 'MODULE_PATHNAME' language 'C'; - -create function gbox_same(box, box, 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_box_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 = 'box'), - true, - 0); - --- get the comparators for boxes and store them in a tmp table -SELECT o.oid AS opoid, o.oprname -INTO TEMP TABLE rt_ops_tmp -FROM pg_operator o, pg_type t -WHERE o.oprleft = t.oid - and t.typname = 'box'; - --- using the tmp table, generate the amop entries --- box_left -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 1, false, c.opoid - FROM pg_opclass opcl, rt_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_box_ops' - and c.oprname = '<<'; - --- box_overleft -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 2, false, c.opoid - FROM pg_opclass opcl, rt_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_box_ops' - and c.oprname = '&<'; - --- box_overlap -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 3, false, c.opoid - FROM pg_opclass opcl, rt_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_box_ops' - and c.oprname = '&&'; - --- box_overright -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 4, false, c.opoid - FROM pg_opclass opcl, rt_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_box_ops' - and c.oprname = '&>'; - --- box_right -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 5, false, c.opoid - FROM pg_opclass opcl, rt_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_box_ops' - and c.oprname = '>>'; - --- box_same -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 6, false, c.opoid - FROM pg_opclass opcl, rt_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_box_ops' - and c.oprname = '~='; - --- box_contains -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 7, false, c.opoid - FROM pg_opclass opcl, rt_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_box_ops' - and c.oprname = '~'; - --- box_contained -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 8, false, c.opoid - FROM pg_opclass opcl, rt_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_box_ops' - and c.oprname = '@'; - -DROP table rt_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_box_ops' - and proname = 'gbox_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_box_ops' - and proname = 'gbox_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_box_ops' - and proname = 'gbox_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_box_ops' - and proname = 'rtree_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_box_ops' - and proname = 'gbox_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_box_ops' - and proname = 'gbox_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_box_ops' - and proname = 'gbox_same'; - --- --- --- --- POLYGON ops --- --- --- --- define the GiST support methods -create function gpoly_consistent(opaque,polygon,int4) returns bool as 'MODULE_PATHNAME' language 'C'; - -create function gpoly_compress(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_poly_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 = 'polygon'), - true, - (SELECT oid FROM pg_type WHERE typname = 'box')); - --- get the comparators for polygons and store them in a tmp table --- hack for 757 (poly_contain_pt) Teodor -SELECT o.oid AS opoid, o.oprname -INTO TEMP TABLE rt_ops_tmp -FROM pg_operator o, pg_type t -WHERE o.oprleft = t.oid and o.oid <> 757 - and t.typname = 'polygon'; - --- using the tmp table, generate the amop entries --- poly_left -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 1, true, c.opoid - FROM pg_opclass opcl, rt_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_poly_ops' - and c.oprname = '<<'; - --- poly_overleft -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 2, true, c.opoid - FROM pg_opclass opcl, rt_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_poly_ops' - and c.oprname = '&<'; - --- poly_overlap -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 3, true, c.opoid - FROM pg_opclass opcl, rt_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_poly_ops' - and c.oprname = '&&'; - --- poly_overright -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 4, true, c.opoid - FROM pg_opclass opcl, rt_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_poly_ops' - and c.oprname = '&>'; - --- poly_right -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 5, true, c.opoid - FROM pg_opclass opcl, rt_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_poly_ops' - and c.oprname = '>>'; - --- poly_same -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 6, true, c.opoid - FROM pg_opclass opcl, rt_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_poly_ops' - and c.oprname = '~='; - --- poly_contains -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 7, true, c.opoid - FROM pg_opclass opcl, rt_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_poly_ops' - and c.oprname = '~'; - --- poly_contained -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 8, true, c.opoid - FROM pg_opclass opcl, rt_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_poly_ops' - and c.oprname = '@'; - -DROP table rt_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_poly_ops' - and proname = 'gpoly_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_poly_ops' - and proname = 'gbox_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_poly_ops' - and proname = 'gpoly_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_poly_ops' - and proname = 'rtree_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_poly_ops' - and proname = 'gbox_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_poly_ops' - and proname = 'gbox_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_poly_ops' - and proname = 'gbox_same'; - -end transaction; - diff --git a/contrib/rtree_gist/sql/rtree_gist.sql b/contrib/rtree_gist/sql/rtree_gist.sql deleted file mode 100644 index 7a2a7faf85..0000000000 --- a/contrib/rtree_gist/sql/rtree_gist.sql +++ /dev/null @@ -1,38 +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 rtree_gist.sql -\set ECHO all - -create table boxtmp (b box); - -\copy boxtmp from 'data/test_box.data' - -select count(*) from boxtmp where b && '(1000,1000,0,0)'::box; - -create index bix on boxtmp using rtree (b); - -select count(*) from boxtmp where b && '(1000,1000,0,0)'::box; - -drop index bix; - -create index bix on boxtmp using gist (b); - -select count(*) from boxtmp where b && '(1000,1000,0,0)'::box; - -create table polytmp (p polygon); - -\copy polytmp from 'data/test_box.data' - -create index pix on polytmp using rtree (p); - -select count(*) from polytmp where p && '(1000,1000),(0,0)'::polygon; - -drop index pix; - -create index pix on polytmp using gist (p); - -select count(*) from polytmp where p && '(1000,1000),(0,0)'::polygon; - diff --git a/contrib/seg/Makefile b/contrib/seg/Makefile deleted file mode 100644 index ac9b543d83..0000000000 --- a/contrib/seg/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/seg/Makefile,v 1.6 2001/11/16 16:32:33 petere Exp $ - -subdir = contrib/seg -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -MODULE_big = seg -OBJS = seg.o segparse.o segscan.o buffer.o -DATA_built = seg.sql -DOCS = README.seg -REGRESS = seg - - -segparse.c: segparse.h ; - -segparse.h: segparse.y -ifdef YACC - $(YACC) -d $(YFLAGS) -p seg_yy $< - mv -f y.tab.c segparse.c - mv -f y.tab.h segparse.h -else - @$(missing) bison $< $@ -endif - -segscan.c: segscan.l -ifdef FLEX - $(FLEX) $(FLEXFLAGS) -Pseg_yy -o'$@' $< -else - @$(missing) flex $< $@ -endif - -EXTRA_CLEAN = segparse.c segparse.h segscan.c y.tab.c y.tab.h - - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/seg/README.seg b/contrib/seg/README.seg deleted file mode 100644 index 5c80ebcd5c..0000000000 --- a/contrib/seg/README.seg +++ /dev/null @@ -1,326 +0,0 @@ -This directory contains the code for the user-defined type, -SEG, representing laboratory measurements as floating point -intervals. - -RATIONALE -========= - -The geometry of measurements is usually more complex than that of a -point in a numeric continuum. A measurement is usually a segment of -that continuum with somewhat fuzzy limits. The measurements come out -as intervals because of uncertainty and randomness, as well as because -the value being measured may naturally be an interval indicating some -condition, such as the temperature range of stability of a protein. - -Using just common sense, it appears more convenient to store such data -as intervals, rather than pairs of numbers. In practice, it even turns -out more efficient in most applications. - -Further along the line of common sense, the fuzziness of the limits -suggests that the use of traditional numeric data types leads to a -certain loss of information. Consider this: your instrument reads -6.50, and you input this reading into the database. What do you get -when you fetch it? Watch: - -test=> select 6.50 as "pH"; - pH ---- -6.5 -(1 row) - -In the world of measurements, 6.50 is not the same as 6.5. It may -sometimes be critically different. The experimenters usually write -down (and publish) the digits they trust. 6.50 is actually a fuzzy -interval contained within a bigger and even fuzzier interval, 6.5, -with their center points being (probably) the only common feature they -share. We definitely do not want such different data items to appear the -same. - -Conclusion? It is nice to have a special data type that can record the -limits of an interval with arbitrarily variable precision. Variable in -a sense that each data element records its own precision. - -Check this out: - -test=> select '6.25 .. 6.50'::seg as "pH"; - pH ------------- -6.25 .. 6.50 -(1 row) - - -FILES -===== - -Makefile building instructions for the shared library - -README.seg the file you are now reading - -buffer.c global variables and buffer access utilities - shared between the parser (segparse.y) and the - scanner (segscan.l) - -buffer.h function prototypes for buffer.c - -seg.c the implementation of this data type in c - -seg.sql.in SQL code needed to register this type with postgres - (transformed to seg.sql by make) - -segdata.h the data structure used to store the segments - -segparse.y the grammar file for the parser (used by seg_in() in seg.c) - -segscan.l scanner rules (used by seg_yyparse() in segparse.y) - -seg-validate.pl a simple input validation script. It is probably a - little stricter than the type itself: for example, - it rejects '22 ' because of the trailing space. Use - as a filter to discard bad values from a single column; - redirect to /dev/null to see the offending input - -sort-segments.pl a script to sort the tables having a SEG type column - - -INSTALLATION -============ - -To install the type, run - - make - make install - -For this to work, make sure that: - -. the seg 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 < seg.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 external representation of an interval is formed using one or two -floating point numbers joined by the range operator ('..' or '...'). -Optional certainty indicators (<, > and ~) are ignored by the internal -logics, but are retained in the data. - -Grammar -------- - -rule 1 seg -> boundary PLUMIN deviation -rule 2 seg -> boundary RANGE boundary -rule 3 seg -> boundary RANGE -rule 4 seg -> RANGE boundary -rule 5 seg -> boundary -rule 6 boundary -> FLOAT -rule 7 boundary -> EXTENSION FLOAT -rule 8 deviation -> FLOAT - -Tokens ------- - -RANGE (\.\.)(\.)? -PLUMIN \'\+\-\' -integer [+-]?[0-9]+ -real [+-]?[0-9]+\.[0-9]+ -FLOAT ({integer}|{real})([eE]{integer})? -EXTENSION [<>~] - - -Examples of valid SEG representations: --------------------------------------- - -Any number (rules 5,6) -- creates a zero-length segment (a point, - if you will) - -~5.0 (rules 5,7) -- creates a zero-length segment AND records - '~' in the data. This notation reads 'approximately 5.0', - but its meaning is not recognized by the code. It is ignored - until you get the value back. View it is a short-hand comment. - -<5.0 (rules 5,7) -- creates a point at 5.0; '<' is ignored but - is preserved as a comment - ->5.0 (rules 5,7) -- creates a point at 5.0; '>' is ignored but - is preserved as a comment - -5(+-)0.3 -5'+-'0.3 (rules 1,8) -- creates an interval '4.7..5.3'. As of this - writing (02/09/2000), this mechanism isn't completely accurate - in determining the number of significant digits for the - boundaries. For example, it adds an extra digit to the lower - boundary if the resulting interval includes a power of ten: - - template1=> select '10(+-)1'::seg as seg; - seg - --------- - 9.0 .. 11 -- should be: 9 .. 11 - - Also, the (+-) notation is not preserved: 'a(+-)b' will - always be returned as '(a-b) .. (a+b)'. The purpose of this - notation is to allow input from certain data sources without - conversion. - -50 .. (rule 3) -- everything that is greater than or equal to 50 - -.. 0 (rule 4) -- everything that is less than or equal to 0 - -1.5e-2 .. 2E-2 (rule 2) -- creates an interval (0.015 .. 0.02) - -1 ... 2 The same as 1...2, or 1 .. 2, or 1..2 (space is ignored). - Because of the widespread use of '...' in the data sources, - I decided to stick to is as a range operator. This, and - also the fact that the white space around the range operator - is ignored, creates a parsing conflict with numeric constants - starting with a decimal point. - - -Examples of invalid SEG input: ------------------------------- - -.1e7 should be: 0.1e7 -.1 .. .2 should be: 0.1 .. 0.2 -2.4 E4 should be: 2.4E4 - -The following, although it is not a syntax error, is disallowed to improve -the sanity of the data: - -5 .. 2 should be: 2 .. 5 - - -PRECISION -========= - -The segments are stored internally as pairs of 32-bit floating point -numbers. It means that the numbers with more than 7 significant digits -will be truncated. - -The numbers with less than or exactly 7 significant digits retain their -original precision. That is, if your query returns 0.00, you will be -sure that the trailing zeroes are not the artifacts of formatting: they -reflect the precision of the original data. The number of leading -zeroes does not affect precision: the value 0.0067 is considered to -have just 2 significant digits. - - -USAGE -===== - -The access method for SEG is a GiST (gist_seg_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/cube). - -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 segment [a, b] overlaps the segment [c, d] in such a way - that a <= c <= b and b <= d - -[a, b] &> [c, d] Over right - - The segment [a, b] overlaps the segment [c, d] in such a way - that a > c and b <= c <= d - -[a, b] = [c, d] Same as - - The segments [a, b] and [c, d] are identical, that is, a == b - and c == d - -[a, b] @ [c, d] Contains - - The segment [a, b] contains the segment [c, d], that is, - a <= c and b >= d - -[a, b] @ [c, d] Contained in - - The segment [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 seg.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/seg.sql - -NOTE: The performance of an R-tree index can largely depend on the -order of input values. It may be very helpful to sort the input table -on the SEG column (see the script sort-segments.pl for an example) - - -CREDITS -======= - -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/). 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 - diff --git a/contrib/seg/buffer.c b/contrib/seg/buffer.c deleted file mode 100644 index baeba5e515..0000000000 --- a/contrib/seg/buffer.c +++ /dev/null @@ -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 seg_flush_scanner_buffer(void); /* defined in segscan.l */ - -void -set_parse_buffer(char *s) -{ - PARSE_BUFFER = s; - PARSE_BUFFER_SIZE = strlen(s); - if (PARSE_BUFFER_SIZE == 0) - elog(ERROR, "seg_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; - seg_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; -} diff --git a/contrib/seg/buffer.h b/contrib/seg/buffer.h deleted file mode 100644 index eef9124dac..0000000000 --- a/contrib/seg/buffer.h +++ /dev/null @@ -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); diff --git a/contrib/seg/data/test_seg.data b/contrib/seg/data/test_seg.data deleted file mode 100644 index dba9ac9045..0000000000 --- a/contrib/seg/data/test_seg.data +++ /dev/null @@ -1,2577 +0,0 @@ -...10.3 -...10.5 -...3.5 -...3.9 -...4.9 -...40 -...5.6 -...5.8 -...6.0 -...6.6 -...6.7 -...6.75 -...7.0 -...7.2 -...7.3 -...7.5 -...7.6 -...7.8 -...8.0 -...8.5 -...8.6 -...8.8 -...8.9 -...9.0 -...9.2 -...9.3 -...9.5 -...9.6 -...90 -...<3.0 -...<5.8 -...<7 -...<7.0 -...<8.0 -...<8.2 -...<8.9 -...>10 -...>7.2 -...>7.7 -...>8.0 -...>82 -...>9.0 -< 1.0...3.8 -< 1.5...4.1 -< 1.5...4.15 -< 10...>11.6 -< 2...>4 -< 2.0...3.4 -< 2.0...4.2 -< 2.0...>8.0 -< 2.5...4.7 -< 2.5...5.5 -< 2.5...>8.5 -< 3...>5 -< 3.0... -< 3.0...4.5 -< 3.0...6.0 -< 3.0...6.5 -< 3.0...9.0 -< 3.0...>10 -< 3.0...>11.0 -< 3.0...>8.0 -< 3.0...>9.0 -< 3.0...>9.5 -< 3.5 -< 3.5...4.3 -< 3.5...5.3 -< 3.5...5.6 -< 3.5...6.0 -< 3.5...8.4 -< 3.6...>6.5 -< 3.7...5.4 -< 4...9.5 -< 4...>5 -< 4...>6.0 -< 4.0... -< 4.0...10.5 -< 4.0...5.3 -< 4.0...5.75 -< 4.0...6.0 -< 4.0...7.3 -< 4.0...7.5 -< 4.0...7.7 -< 4.0...8.5 -< 4.0...>12 -< 4.0...>5.0 -< 4.0...>6.0 -< 4.0...>7.5 -< 4.0...>8.0 -< 4.0...>8.1 -< 4.0...>9.0 -< 4.2...5.2 -< 4.2...5.3 -< 4.2...5.4 -< 4.2...6.2 -< 4.3...>9.0 -< 4.4 -< 4.4...6.0 -< 4.4...<6.0 -< 4.5...6.3 -< 4.5...7.2 -< 4.5...>12 -< 4.5...>5.0 -< 4.5...>5.5 -< 4.5...>6 -< 4.5...>7.5 -< 4.5...>8 -< 4.5...>9.5 -< 4.7...>9.3 -< 4.8...>6.4 -< 5...7.5 -< 5...7.7 -< 5...>7 -< 5...>8 -< 5...>8.0 -< 5.0 -< 5.0...10 -< 5.0...6.3 -< 5.0...7.4 -< 5.0...7.7 -< 5.0...8.1 -< 5.0...8.3 -< 5.0...8.5 -< 5.0...8.8 -< 5.0...9.5 -< 5.0...<9.0 -< 5.0...>10 -< 5.0...>10.0 -< 5.0...>10.5 -< 5.0...>11 -< 5.0...>6.0 -< 5.0...>6.6 -< 5.0...>7.5 -< 5.0...>8.0 -< 5.0...>8.5 -< 5.0...>8.6 -< 5.0...>9.0 -< 5.2...7.3 -< 5.2...8.2 -< 5.2...8.5 -< 5.2...>5.8 -< 5.2...>7.6 -< 5.3 -< 5.3...6.5 -< 5.3...7.5 -< 5.3...7.8 -< 5.4...6.35 -< 5.5...10 -< 5.5...6.3 -< 5.5...7.0 -< 5.5...7.5 -< 5.5...8.4 -< 5.5...8.5 -< 5.5...>10 -< 5.5...>10.0 -< 5.5...>10.5 -< 5.5...>6.5 -< 5.5...>7 -< 5.5...>7.5 -< 5.5...>8 -< 5.5...>8.0 -< 5.5...>8.5 -< 5.5...>8.7 -< 5.5...>8.9 -< 5.5...>9.0 -< 5.6...6.75 -< 5.75...>9.0 -< 5.8...7.8 -< 5.8...>11 -< 5.8...>8.2 -< 5.9...>8.0 -< 6...>10.5 -< 6...>8 -< 6...>9.5 -< 6.0 -< 6.0...6.8 -< 6.0...7.15 -< 6.0...7.6 -< 6.0...7.7 -< 6.0...8.0 -< 6.0...8.2 -< 6.0...8.5 -< 6.0...9.0 -< 6.0...9.5 -< 6.0...>10 -< 6.0...>10.0 -< 6.0...>11 -< 6.0...>7.0 -< 6.0...>8.0 -< 6.0...>8.2 -< 6.0...>8.5 -< 6.0...>8.6 -< 6.0...>9.0 -< 6.0...>9.6 -< 6.3...9.5 -< 6.3...>6.7 -< 6.3...>7.8 -< 6.35...>7.7 -< 6.4...>8.0 -< 6.4...>8.7 -< 6.5...11 -< 6.5...7.25 -< 6.5...8.0 -< 6.5...8.2 -< 6.5...8.4 -< 6.5...8.5 -< 6.5...9.7 -< 6.5...>10.0 -< 6.5...>10.5 -< 6.5...>7.5 -< 6.5...>8.0 -< 6.5...>8.5 -< 6.5...>8.6 -< 6.5...>8.7 -< 6.5...>9.0 -< 6.5...>9.5 -< 6.6...>7.5 -< 6.6...>8.5 -< 6.8...7.8 -< 6.8...9.5 -< 6.8...>7.5 -< 6.8...>8.6 -< 6.8...>9.0 -< 6.9...9.0 -< 7...9.2 -< 7...>11 -< 7...>7.5 -< 7...>9.5 -< 7.0 -< 7.0...10 -< 7.0...10.5 -< 7.0...11.0 -< 7.0...8.2 -< 7.0...8.3 -< 7.0...8.4 -< 7.0...8.55 -< 7.0...8.7 -< 7.0...8.8 -< 7.0...9.0 -< 7.0...<8.0 -< 7.0...>10.5 -< 7.0...>11 -< 7.0...>11.0 -< 7.0...>7.0 -< 7.0...>7.3 -< 7.0...>7.4 -< 7.0...>7.5 -< 7.0...>7.75 -< 7.0...>7.8 -< 7.0...>8.0 -< 7.0...>8.2 -< 7.0...>8.5 -< 7.0...>8.6 -< 7.0...>8.9 -< 7.0...>9.0 -< 7.0...>9.5 -< 7.2...8.3 -< 7.2...>7.5 -< 7.2...>7.8 -< 7.2...>8.0 -< 7.2...>8.2 -< 7.2...>8.6 -< 7.2...>8.8 -< 7.4...>7.8 -< 7.4...>8.0 -< 7.4...>8.1 -< 7.4...>8.6 -< 7.4...>8.8 -< 7.5...9.0 -< 7.5...>10 -< 7.5...>8.0 -< 7.5...>8.5 -< 7.5...>8.7 -< 7.5...>9 -< 7.5...>9.0 -< 7.5...>9.5 -< 7.6...>7.8 -< 7.6...>8.0 -< 7.6...>8.5 -< 7.6...>8.6 -< 7.6...>8.9 -< 7.8...>9.0 -< 7.9...>8.3 -< 8.0 -< 8.0...>10.0 -< 8.0...>8.5 -< 8.0...>9.0 -< 8.0...>9.4 -< 8.0...>9.5 -< 8.2...9.8 -< 8.2...>8.6 -< 8.5...>10.5 -< 8.5...>11 -< 8.5...>9.5 -< 9...10.5 -<1.0...3.5 -<1.0...3.7 -<1.0...4.0 -<1.0...>13.0 -<1.0...>5.5 -<10.5...11.5 -<12.0...12.5 -<2...10 -<2...>4 -<2.0 -<2.0...11 -<2.0...3.5 -<2.0...5.7 -<2.0...6.0 -<2.0...6.8 -<2.0...9.7 -<2.0...>6.5 -<2.0...>9.0 -<2.3... -<2.3...>11.0 -<2.4...6.8 -<2.5...7.7 -<2.5...>8.0 -<2.8...>8.0 -<3.0...4.6 -<3.0...5.5 -<3.0...6.0 -<3.0...6.3 -<3.0...6.4 -<3.0...6.8 -<3.0...7.0 -<3.0...7.5 -<3.0...8.3 -<3.0...>10.5 -<3.0...>5.0 -<3.0...>7.0 -<3.0...>7.2 -<3.0...>8.5 -<3.0...>8.7 -<3.0...>9.0 -<3.5...6.0 -<3.5...8.0 -<3.5...<7.0 -<3.5...>10.0 -<3.55...5.3 -<3.7...4.9 -<3.7...5.0 -<4...6.5 -<4.0...10.0 -<4.0...10.5 -<4.0...6.1 -<4.0...6.3 -<4.0...6.5 -<4.0...7.7 -<4.0...8.2 -<4.0...<9.0 -<4.0...>10 -<4.0...>10.0 -<4.0...>10.5 -<4.0...>6.0 -<4.0...>8.0 -<4.0...>9.0 -<4.1...>8.0 -<4.3...7.6 -<4.5...6.3 -<4.5...6.5 -<4.5...>6.5 -<4.5...>9.5 -<4.8...>7.4 -<4.9...>9.5 -<5...>6 -<5...>6.0 -<5...>8 -<5.0...10.0 -<5.0...6.0 -<5.0...6.6 -<5.0...6.8 -<5.0...7.0 -<5.0...7.5 -<5.0...8.2 -<5.0...9.5 -<5.0...>11.0 -<5.0...>5.5 -<5.0...>7.0 -<5.0...>8.0 -<5.0...>9.0 -<5.2...7.5 -<5.2...>6.8 -<5.2...>8.0 -<5.3...10.2 -<5.3...>10.5 -<5.4...8.0 -<5.4...8.5 -<5.4...>8.2 -<5.4...>9.1 -<5.5...6.5 -<5.5...7.0 -<5.5...7.5 -<5.5...8.2 -<5.5...8.3 -<5.5...8.5 -<5.5...8.6 -<5.5...>10.0 -<5.5...>7.0 -<5.5...>7.5 -<5.5...>8.0 -<5.5...>8.5 -<5.5...>9.0 -<5.6...7.5 -<5.6...>6.4 -<5.6...>7.4 -<5.6...>8.0 -<5.6...>8.5 -<5.7...>7.1 -<5.8...7.4 -<5.8...>6.7 -<5.8...>6.8 -<5.8...>7.0 -<5.8...>7.8 -<5.8...>8.8 -<5.85...>9.5 -<6...>9 -<6.0...10.0 -<6.0...6.8 -<6.0...7.1 -<6.0...7.2 -<6.0...7.7 -<6.0...8.0 -<6.0...8.2 -<6.0...8.4 -<6.0...8.5 -<6.0...8.6 -<6.0...9.1 -<6.0...9.2 -<6.0...9.3 -<6.0...9.5 -<6.0...>10 -<6.0...>11.0 -<6.0...>7.0 -<6.0...>7.5 -<6.0...>7.6 -<6.0...>7.9 -<6.0...>8.0 -<6.0...>8.3 -<6.0...>8.5 -<6.0...>8.6 -<6.0...>9.0 -<6.0...>9.2 -<6.0...>9.5 -<6.1...8.4 -<6.1...>6.6 -<6.1...>8.1 -<6.2 -<6.2...6.9 -<6.2...8.3 -<6.2...>7.5 -<6.2...>8.5 -<6.2...>8.7 -<6.3...10.0 -<6.3...7.4 -<6.3...9.6 -<6.3...>7.0 -<6.3...>8.0 -<6.4...7.6 -<6.4...8.5 -<6.4...>8.5 -<6.4...>9.0 -<6.5...7.8 -<6.5...8.2 -<6.5...9.2 -<6.5...>7.0 -<6.5...>7.5 -<6.5...>8.0 -<6.5...>8.5 -<6.5...>8.7 -<6.5...>9.0 -<6.5...>9.5 -<6.6 -<6.6...8.0 -<6.8...8.0 -<6.8...8.2 -<6.8...>7.5 -<6.8...>8.5 -<6.8...>9.5 -<7...9 -<7...>10 -<7.0...7.5 -<7.0...9.0 -<7.0...9.0 -<7.0...9.4 -<7.0...9.5 -<7.0...9.5 -<7.0...>10 -<7.0...>10.0 -<7.0...>11.5 -<7.0...>7.5 -<7.0...>8.0 -<7.0...>8.3 -<7.0...>8.4 -<7.0...>8.5 -<7.0...>9.0 -<7.2...8.8 -<7.2...9.0 -<7.2...>8.2 -<7.2...>8.8 -<7.2...>9.5 -<7.3...>8.0 -<7.4...8.8 -<7.4...9.6 -<7.4...>8.5 -<7.4...>8.7 -<7.5...8.5 -<7.5...<9.0 -<7.5...>8.0 -<7.5...>8.5 -<7.5...>9.5 -<7.6...>8.4 -<7.6...>9.4 -<7.8...>10.2 -<7.8...>8.2 -<8.0 -<8.0...10.0 -<8.0...>8.5 -<8.0...>8.8 -<8.0...>9.0 -<8.2...>10.2 -<8.5...9.6 -<8.5...>9.0 -<8.5...>9.5 -<8.6...>10.6 -<9.1...10.3 -<9.2...>11.0 -<9.5...12 -<9.5...>12.2 -> 11.0 -> 3.0...<7.0 -> 4.0...<10.0 -> 4.0...<9.0 -> 4.5...<9.0 -> 5.0 -> 5.0...<10.0 -> 5.0...<11 -> 5.5... -> 5.6 -> 5.9...<9.5 -> 6.0...8.0 -> 6.0...<11.5 -> 6.0...<8.0 -> 6.0...>10.0 -> 6.2...<7.4 -> 7.0...<10 -> 7.0...>8.5 -> 7.0...>8.6 -> 7.0...>8.7 -> 7.15... -> 8.0 -> 8.7 -> 9.3 -> 9.5 ->10.5 ->120 ->2.3... ->3.0...<7.0 ->3.8...<8.0 ->4.0...<10 ->5.0...<7.0 ->5.0...>8.0 ->5.0...>9.2 ->5.25...6.5 ->5.5...>9.3 ->5.6...<8.2 ->6.0...>11.0 ->6.5...>8.0 ->6.6...<7.3 ->6.8...>8.5 ->6.9...>8.0 ->7.0 ->7.0...<9.0 ->7.0...<9.5 ->7.3... ->7.5...<10.5 ->8.0 ->8.4 ->8.5 ->9.0 ->9.4 ->9.5 ->95 -~10 -~23 -~5.0...>9.0 -~6.0 -~6.4...~8.5 -~6.8 -~7.0 -~7.5 -~8.0 -~8.0...~10.0 -1.0 -1.0...4.0 -1.0...5.0 -1.1 -1.1...3.6 -1.2...3.2 -1.2...3.5 -1.3...12.0 -1.4...2.0 -1.4...8.2 -1.5 -1.5...10.5 -1.5...4.2 -1.5...4.5 -1.6...3.8 -1.6...7.2 -1.7 -1.7...2.4 -1.7...3.2 -1.7...5.0 -1.7...5.7 -1.8 -1.8...3.8 -1.8...>9.0 -1.9...3.6 -2 -2.0 -2.0...10.0 -2.0...11.0 -2.0...11.5 -2.0...2.5 -2.0...3.2 -2.0...3.5 -2.0...4.0 -2.0...4.3 -2.0...4.4 -2.0...4.6 -2.0...4.75 -2.0...4.8 -2.0...5.0 -2.0...5.5 -2.0...6.5 -2.0...7.0 -2.0...7.5 -2.0...8.0 -2.0...9.0 -2.0...>10 -2.0...>4.0 -2.0...>5.5 -2.1 -2.1...11.8 -2.1...4.2 -2.2 -2.2...11.2 -2.2...4.1 -2.2...4.2 -2.2...5.9 -2.2...6.4 -2.2...6.8 -2.3...10.6 -2.3...4.1 -2.3...4.3 -2.3...4.5 -2.3...4.7 -2.3...6.0 -2.4 -2.4...11.3 -2.4...4.5 -2.4...5.6 -2.4...5.7 -2.4...6.3 -2.5 -2.5...11 -2.5...11.2 -2.5...11.5 -2.5...11.8 -2.5...3.0 -2.5...3.7 -2.5...4.1 -2.5...4.5 -2.5...4.6 -2.5...5.0 -2.5...5.1 -2.5...5.5 -2.5...6.0 -2.5...6.3 -2.5...7.0 -2.5...9.0 -2.5...>3.5 -2.5...>4.0 -2.52 -2.56 -2.6... -2.6...10.0 -2.6...9.3 -2.6...>4.0 -2.6...>9.4 -2.62 -2.7 -2.7...12.0 -2.7...3.7 -2.7...3.8 -2.7...4.5 -2.7...4.7 -2.7...6.0 -2.7...6.4 -2.7...7.0 -2.7...8.0 -2.75...5.25 -2.79 -2.8 -2.8...11.0 -2.8...3.4 -2.8...4.0 -2.8...7.0 -2.8...8.0 -2.8...9.0 -2.8...9.7 -2.9...3.7 -2.9...4.5 -2.9...5.0 -2.9...5.6 -2.9...6.1 -2.9...7.6 -2.9...9.0 -2.97 -3 -3...10.0 -3...10.5 -3...5.5 -3...58 -3...6 -3...8 -3.0 -3.0...10 -3.0...10.0 -3.0...10.5 -3.0...11.0 -3.0...3.5 -3.0...4.0 -3.0...4.5 -3.0...4.9 -3.0...5.0 -3.0...5.4 -3.0...5.6 -3.0...5.65 -3.0...6.0 -3.0...6.3 -3.0...6.5 -3.0...6.7 -3.0...6.9 -3.0...7.0 -3.0...7.2 -3.0...7.5 -3.0...8.0 -3.0...8.5 -3.0...8.7 -3.0...9.0 -3.0...9.7 -3.0...>10 -3.0...>10.0 -3.0...>8.0 -3.00...5.0 -3.1 -3.1...11.5 -3.1...5.2 -3.1...5.8 -3.1...6.8 -3.1...7.8 -3.15...7.25 -3.2 -3.2...10.0 -3.2...4.2 -3.2...4.6 -3.2...5.4 -3.2...5.8 -3.2...6.25 -3.2...6.8 -3.2...8.1 -3.2...>8.0 -3.2...>9.9 -3.22 -3.3 -3.3...4.7 -3.3...5.3 -3.3...5.5 -3.3...5.6 -3.3...6.0 -3.3...6.5 -3.3...6.7 -3.3...7.2 -3.3...7.4 -3.3...7.5 -3.3...7.8 -3.3...9.0 -3.4 -3.4...4.1 -3.4...4.7 -3.4...5.5 -3.4...6.2 -3.4...6.4 -3.4...8.2 -3.4...>8.0 -3.5 -3.5...10 -3.5...10.0 -3.5...10.5 -3.5...10.8 -3.5...11.0 -3.5...11.5 -3.5...12.2 -3.5...4.0 -3.5...4.4 -3.5...4.5 -3.5...5.0 -3.5...5.3 -3.5...5.5 -3.5...5.6 -3.5...6 -3.5...6.0 -3.5...6.3 -3.5...6.4 -3.5...6.5 -3.5...6.6 -3.5...6.7 -3.5...7.0 -3.5...7.2 -3.5...7.3 -3.5...7.5 -3.5...8.5 -3.5...8.6 -3.5...8.7 -3.5...9.0 -3.5...9.5 -3.5...>11.0 -3.5...>5.0 -3.5...>8.5 -3.5...>9.0 -3.6 -3.6...3.8 -3.6...4.55 -3.6...4.6 -3.6...4.8 -3.6...5.4 -3.6...5.5 -3.6...6 -3.6...6.0 -3.6...6.6 -3.6...6.8 -3.6...7.0 -3.6...7.7 -3.6...8.6 -3.6...8.7 -3.6...8.8 -3.7 -3.7...10.0 -3.7...10.6 -3.7...4.6 -3.7...5.3 -3.7...6.2 -3.7...6.3 -3.7...6.5 -3.7...6.7 -3.7...8.2 -3.7...8.3 -3.7...9.1 -3.7...>10 -3.7...>11 -3.75...5.7 -3.8 -3.8...10 -3.8...4.0 -3.8...4.5 -3.8...4.8 -3.8...5.5 -3.8...5.8 -3.8...5.9 -3.8...6.2 -3.8...7.7 -3.8...8.3 -3.8...8.7 -3.9 -3.9...5.5 -3.9...6.8 -3.9...7.8 -3.9...>7.5 -3.9...>8.5 -3.9...>9.0 -3.95 -4 -4...10 -4...11.0 -4...12 -4...5 -4...6.9 -4...7 -4...7.5 -4...8 -4...9 -4...>11 -4...>8 -4.0 -4.0... -4.0...10 -4.0...10.0 -4.0...10.4 -4.0...10.5 -4.0...11.0 -4.0...11.7 -4.0...12.5 -4.0...13.0 -4.0...4.4 -4.0...4.5 -4.0...4.8 -4.0...5.0 -4.0...5.1 -4.0...5.2 -4.0...5.5 -4.0...5.7 -4.0...5.75 -4.0...5.8 -4.0...6.0 -4.0...6.1 -4.0...6.2 -4.0...6.3 -4.0...6.5 -4.0...60 -4.0...7.0 -4.0...7.2 -4.0...7.3 -4.0...7.5 -4.0...7.7 -4.0...7.9 -4.0...8.0 -4.0...8.1 -4.0...8.2 -4.0...8.3 -4.0...8.5 -4.0...8.8 -4.0...9.0 -4.0...9.4 -4.0...>10 -4.0...>11 -4.0...>9.0 -4.1 -4.1...10.5 -4.1...5.6 -4.1...5.8 -4.1...6.0 -4.1...7.2 -4.1...8.0 -4.1...9.1 -4.15...5.25 -4.15...6.25 -4.15...6.5 -4.2 -4.2...11.0 -4.2...11.5 -4.2...11.7 -4.2...5.0 -4.2...5.3 -4.2...5.35 -4.2...5.4 -4.2...5.6 -4.2...5.7 -4.2...6.0 -4.2...6.3 -4.2...6.4 -4.2...6.7 -4.2...7.1 -4.2...7.2 -4.2...7.3 -4.2...8.0 -4.2...8.4 -4.2...9.5 -4.2...>7.0 -4.2...>7.3 -4.2...>9.0 -4.2...>9.5 -4.25 -4.25...5.00 -4.25...9.75 -4.3 -4.3...10.3 -4.3...5.3 -4.3...5.7 -4.3...5.8 -4.3...6.0 -4.3...6.3 -4.3...6.5 -4.3...6.8 -4.3...7.0 -4.3...7.2 -4.3...7.3 -4.3...7.5 -4.3...7.6 -4.3...8 -4.3...8.2 -4.3...8.5 -4.3...8.6 -4.3...>5.0 -4.3...>6.0 -4.3...>7.0 -4.3...>8.0 -4.35 -4.4 -4.4...10.7 -4.4...4.6 -4.4...4.8 -4.4...6.0 -4.4...6.2 -4.4...6.4 -4.4...6.6 -4.4...6.7 -4.4...7.0 -4.4...7.2 -4.4...7.5 -4.4...7.6 -4.4...8.5 -4.4...9.3 -4.5 -4.5...10 -4.5...10.0 -4.5...10.5 -4.5...11.0 -4.5...11.5 -4.5...115 -4.5...12.5 -4.5...4.8 -4.5...5.0 -4.5...5.2 -4.5...5.5 -4.5...5.7 -4.5...5.8 -4.5...6.0 -4.5...6.2 -4.5...6.4 -4.5...6.5 -4.5...6.8 -4.5...7 -4.5...7.0 -4.5...7.1 -4.5...7.3 -4.5...7.5 -4.5...7.6 -4.5...7.7 -4.5...7.8 -4.5...7.9 -4.5...8.0 -4.5...8.3 -4.5...8.5 -4.5...8.6 -4.5...8.7 -4.5...8.8 -4.5...8.9 -4.5...9.0 -4.5...9.3 -4.5...9.4 -4.5...9.5 -4.5...<12 -4.5...>10 -4.5...>12 -4.5...>6.0 -4.5...>7.0 -4.5...>7.5 -4.5...>8.0 -4.5...>8.5 -4.5...>9.0 -4.6 -4.6 -4.6...4.8 -4.6...5.0 -4.6...5.2 -4.6...6.3 -4.6...6.4 -4.6...6.5 -4.6...6.6 -4.6...7.0 -4.6...7.2 -4.6...7.4 -4.6...7.5 -4.6...8.2 -4.6...8.5 -4.6...8.6 -4.6...8.7 -4.6...<6.5 -4.6...>10 -4.6...>11 -4.6...>7.4 -4.6...>8.0 -4.6...~7.0 -4.7 -4.7...10.8 -4.7...11 -4.7...11.8 -4.7...5.6 -4.7...6.0 -4.7...6.2 -4.7...6.3 -4.7...6.6 -4.7...6.7 -4.7...7.0 -4.7...7.4 -4.7...7.5 -4.7...7.7 -4.7...7.8 -4.7...8.0 -4.7...8.3 -4.7...8.4 -4.7...8.5 -4.7...9.3 -4.7...9.5 -4.7...9.6 -4.7...9.7 -4.7...>10 -4.7...>10.0 -4.7...>10.5 -4.7...>6.5 -4.7...>8.0 -4.75 -4.8 -4.8... -4.8...10.3 -4.8...11.5 -4.8...11.6 -4.8...12.5 -4.8...5.2 -4.8...5.9 -4.8...6.0 -4.8...6.2 -4.8...6.3 -4.8...7.0 -4.8...7.3 -4.8...7.4 -4.8...7.5 -4.8...7.6 -4.8...7.7 -4.8...7.75 -4.8...8.0 -4.8...8.2 -4.8...8.4 -4.8...8.6 -4.8...9.0 -4.8...9.3 -4.8...9.7 -4.8...>10.0 -4.8...>8.0 -4.8...>9.0 -4.85 -4.9 -4.9... -4.9...6.5 -4.9...7.2 -4.9...7.8 -4.9...8.2 -4.9...8.3 -4.9...9.0 -4.9...9.5 -4.9...<6.0 -4.9...>12 -4.9...>7.5 -4.9...>9.5 -5 -5...10.0 -5...10.5 -5...11 -5...11.5 -5...12 -5...30 -5...6 -5...6.6 -5...7 -5...8 -5...8.5 -5...9 -5...9.5 -5.0 -5.0...10 -5.0...10.0 -5.0...10.2 -5.0...10.3 -5.0...10.5 -5.0...11 -5.0...11.0 -5.0...11.2 -5.0...11.4 -5.0...11.5 -5.0...11.6 -5.0...11.7 -5.0...12.0 -5.0...5.5 -5.0...5.7 -5.0...6.0 -5.0...6.1 -5.0...6.2 -5.0...6.4 -5.0...6.5 -5.0...6.6 -5.0...6.8 -5.0...6.9 -5.0...7.0 -5.0...7.2 -5.0...7.3 -5.0...7.4 -5.0...7.5 -5.0...7.6 -5.0...7.7 -5.0...7.8 -5.0...8.0 -5.0...8.2 -5.0...8.3 -5.0...8.4 -5.0...8.5 -5.0...8.6 -5.0...8.7 -5.0...9.0 -5.0...9.0 -5.0...9.2 -5.0...9.5 -5.0...>10 -5.0...>10.0 -5.0...>11 -5.0...>12 -5.0...>12.0 -5.0...>7.0 -5.0...>8.0 -5.0...>8.4 -5.0...>8.5 -5.0...>9.0 -5.02...6.74 -5.1 -5.1...5.3 -5.1...5.4 -5.1...6.2 -5.1...6.3 -5.1...6.4 -5.1...6.6 -5.1...6.8 -5.1...7.0 -5.1...7.2 -5.1...7.3 -5.1...7.8 -5.1...8.0 -5.1...8.3 -5.1...8.7 -5.1...>7.0 -5.15 -5.2 -5.2...10.0 -5.2...10.8 -5.2...11.5 -5.2...5.3 -5.2...5.5 -5.2...5.7 -5.2...6.0 -5.2...6.2 -5.2...6.4 -5.2...6.7 -5.2...6.8 -5.2...6.9 -5.2...7.0 -5.2...7.3 -5.2...7.4 -5.2...7.5 -5.2...7.6 -5.2...7.7 -5.2...7.9 -5.2...8.0 -5.2...8.2 -5.2...8.4 -5.2...8.5 -5.2...8.7 -5.2...8.8 -5.2...9.0 -5.2...9.5 -5.2...9.6 -5.2...9.7 -5.2...9.9 -5.2...>10.0 -5.2...>11 -5.2...>12 -5.2...>6.5 -5.2...>7.0 -5.2...>7.5 -5.2...>8 -5.2...>8.0 -5.25...7.5 -5.25...8.5 -5.25...>12 -5.3 -5.3... -5.3...10.0 -5.3...10.1 -5.3...10.2 -5.3...10.5 -5.3...10.6 -5.3...11.5 -5.3...13 -5.3...5.5 -5.3...5.8 -5.3...7.0 -5.3...7.2 -5.3...7.4 -5.3...7.5 -5.3...7.6 -5.3...7.8 -5.3...8.0 -5.3...8.2 -5.3...8.3 -5.3...8.6 -5.3...8.7 -5.3...8.8 -5.3...8.9 -5.3...9.0 -5.3...9.3 -5.3...9.5 -5.3...9.7 -5.3...9.9 -5.3...>7.8 -5.3...>9.0 -5.3...>90 -5.35 -5.4 -5.4... -5.4...10 -5.4...10.5 -5.4...5.8 -5.4...6.8 -5.4...7.0 -5.4...7.1 -5.4...7.2 -5.4...7.3 -5.4...7.7 -5.4...7.8 -5.4...8.2 -5.4...8.5 -5.4...9.4 -5.4...>10.0 -5.4...>11.0 -5.4...>9.0 -5.45 -5.5 -5.5... -5.5...10.0 -5.5...10.2 -5.5...10.5 -5.5...11 -5.5...11.5 -5.5...11.7 -5.5...12 -5.5...12.5 -5.5...13.5 -5.5...5.6 -5.5...5.7 -5.5...5.8 -5.5...6 -5.5...6.0 -5.5...6.2 -5.5...6.3 -5.5...6.5 -5.5...6.7 -5.5...6.8 -5.5...7.0 -5.5...7.1 -5.5...7.2 -5.5...7.3 -5.5...7.4 -5.5...7.5 -5.5...7.6 -5.5...7.7 -5.5...7.9 -5.5...8.0 -5.5...8.1 -5.5...8.2 -5.5...8.5 -5.5...8.6 -5.5...8.7 -5.5...9.0 -5.5...9.1 -5.5...9.3 -5.5...9.5 -5.5...9.7 -5.5...<6.8 -5.5...>10 -5.5...>10.0 -5.5...>11 -5.5...>11.0 -5.5...>12 -5.5...>7.0 -5.5...>8.0 -5.5...>9.0 -5.5...>9.5 -5.55 -5.55...7.8 -5.56 -5.6 -5.6...10 -5.6...10.1 -5.6...6.0 -5.6...6.2 -5.6...6.4 -5.6...6.6 -5.6...7.0 -5.6...7.1 -5.6...7.2 -5.6...7.3 -5.6...7.4 -5.6...7.5 -5.6...7.6 -5.6...7.7 -5.6...8.0 -5.6...8.3 -5.6...8.4 -5.6...8.5 -5.6...8.75 -5.6...8.8 -5.6...9 -5.6...9.0 -5.6...9.4 -5.6...9.5 -5.6...9.6 -5.6...>11 -5.6...>7.0 -5.6...>7.5 -5.6...>8.0 -5.6...>9.0 -5.65 -5.7 -5.7... -5.7...10 -5.7...10.0 -5.7...11 -5.7...6.0 -5.7...6.2 -5.7...6.3 -5.7...6.5 -5.7...6.8 -5.7...7.0 -5.7...7.2 -5.7...7.3 -5.7...7.5 -5.7...7.6 -5.7...7.65 -5.7...7.7 -5.7...7.8 -5.7...7.9 -5.7...8.0 -5.7...8.4 -5.7...8.5 -5.7...8.7 -5.7...8.9 -5.7...9.0 -5.7...9.2 -5.7...9.4 -5.7...9.7 -5.7...>10.0 -5.7...>11 -5.7...>6.6 -5.7...>7.2 -5.7...>8.5 -5.7...>9.0 -5.73 -5.75 -5.75...7.3 -5.8 -5.8...10.0 -5.8...11 -5.8...6.0 -5.8...6.2 -5.8...6.5 -5.8...6.7 -5.8...6.8 -5.8...6.9 -5.8...7.0 -5.8...7.2 -5.8...7.3 -5.8...7.4 -5.8...7.5 -5.8...7.6 -5.8...7.7 -5.8...7.8 -5.8...8.0 -5.8...8.1 -5.8...8.2 -5.8...8.3 -5.8...8.4 -5.8...8.5 -5.8...8.6 -5.8...8.8 -5.8...9.0 -5.8...9.2 -5.8...9.3 -5.8...9.8 -5.8...>10.5 -5.8...>11 -5.8...>6.7 -5.8...>6.8 -5.8...>8.0 -5.8...>9.0 -5.85 -5.87 -5.9 -5.9... -5.9...10.2 -5.9...6.0 -5.9...6.5 -5.9...7.3 -5.9...7.5 -5.9...7.7 -5.9...8.0 -5.9...8.2 -5.9...8.3 -5.9...8.4 -5.9...8.5 -5.9...8.7 -5.9...9.0 -5.9...>7.0 -5.9...>8.5 -5.92 -5.95...8.0 -6 -6...10 -6...11 -6...11.5 -6...6.5 -6...8 -6...8.0 -6...8.5 -6...9 -6...9.2 -6...9.3 -6...>10 -6...>12 -6...>7.2 -6...>8 -6.0 -6.0 -6.0...10 -6.0...10.0 -6.0...10.2 -6.0...10.3 -6.0...10.4 -6.0...10.5 -6.0...11 -6.0...11.0 -6.0...11.5 -6.0...13 -6.0...6.2 -6.0...6.3 -6.0...6.4 -6.0...6.5 -6.0...6.6 -6.0...6.7 -6.0...6.8 -6.0...7.0 -6.0...7.2 -6.0...7.3 -6.0...7.4 -6.0...7.5 -6.0...7.6 -6.0...7.7 -6.0...7.8 -6.0...8.0 -6.0...8.1 -6.0...8.2 -6.0...8.3 -6.0...8.4 -6.0...8.5 -6.0...8.5 -6.0...8.6 -6.0...8.7 -6.0...8.9 -6.0...9.0 -6.0...9.1 -6.0...9.2 -6.0...9.3 -6.0...9.4 -6.0...9.5 -6.0...9.7 -6.0...9.8 -6.0...9.9 -6.0...>10.0 -6.0...>10.5 -6.0...>11 -6.0...>7.0 -6.0...>7.5 -6.0...>8.0 -6.0...>8.2 -6.0...>8.5 -6.0...>8.7 -6.0...>9.0 -6.0...>9.5 -6.01 -6.1 -6.1... -6.1...10 -6.1...10.8 -6.1...6.2 -6.1...6.6 -6.1...6.8 -6.1...6.9 -6.1...7.0 -6.1...7.2 -6.1...7.5 -6.1...7.6 -6.1...7.7 -6.1...7.8 -6.1...7.9 -6.1...8.0 -6.1...8.2 -6.1...8.5 -6.1...8.7 -6.1...8.9 -6.1...9.0 -6.1...9.3 -6.1...9.4 -6.1...>12 -6.1...>8.0 -6.1...>8.2 -6.1...>8.5 -6.1...>9.0 -6.1...>9.5 -6.15 -6.18 -6.2 -6.2...10 -6.2...10.0 -6.2...10.5 -6.2...11 -6.2...6.4 -6.2...6.5 -6.2...6.8 -6.2...6.9 -6.2...7.0 -6.2...7.2 -6.2...7.4 -6.2...7.5 -6.2...7.6 -6.2...7.7 -6.2...7.8 -6.2...8.0 -6.2...8.1 -6.2...8.2 -6.2...8.3 -6.2...8.4 -6.2...8.5 -6.2...8.6 -6.2...8.7 -6.2...8.8 -6.2...9.0 -6.2...9.1 -6.2...9.2 -6.2...9.5 -6.2...9.7 -6.2...9.8 -6.2...>10.5 -6.2...>11.5 -6.2...>7.1 -6.2...>7.8 -6.2...>8.0 -6.2...>9.0 -6.2...>9.5 -6.23...8.07 -6.24 -6.25 -6.25...7.5 -6.25...>9.0 -6.3 -6.3... -6.3...10.0 -6.3...10.2 -6.3...10.4 -6.3...10.5 -6.3...6.4 -6.3...6.5 -6.3...6.6 -6.3...6.7 -6.3...6.8 -6.3...7.3 -6.3...7.5 -6.3...7.7 -6.3...7.8 -6.3...7.9 -6.3...8.0 -6.3...8.2 -6.3...8.3 -6.3...8.5 -6.3...8.6 -6.3...8.7 -6.3...8.9 -6.3...9.0 -6.3...9.1 -6.3...9.2 -6.3...9.3 -6.3...9.4 -6.3...9.5 -6.3...9.7 -6.3...9.8 -6.3...>10.0 -6.3...>11 -6.3...>7.5 -6.3...>7.8 -6.3...>8.0 -6.3...>8.1 -6.3...>8.3 -6.3...>8.5 -6.3...>9.0 -6.3...>9.2 -6.35 -6.4 -6.4...7.7 -6.4...10 -6.4...10.8 -6.4...6.7 -6.4...6.8 -6.4...7.0 -6.4...7.2 -6.4...7.4 -6.4...7.5 -6.4...7.6 -6.4...7.7 -6.4...7.8 -6.4...8.0 -6.4...8.1 -6.4...8.2 -6.4...8.3 -6.4...8.4 -6.4...8.6 -6.4...8.7 -6.4...8.8 -6.4...9.0 -6.4...9.3 -6.4...>10 -6.4...>11.0 -6.4...>7.8 -6.4...>8.0 -6.4...>8.5 -6.4...>8.6 -6.4...>9.0 -6.4...>9.1 -6.4...>9.2 -6.4...>9.5 -6.42 -6.5 -6.5 -6.5... -6.5...10 -6.5...10.0 -6.5...10.2 -6.5...10.3 -6.5...10.5 -6.5...11 -6.5...11.0 -6.5...11.5 -6.5...12.0 -6.5...6.7 -6.5...6.75 -6.5...6.8 -6.5...6.9 -6.5...7.0 -6.5...7.1 -6.5...7.3 -6.5...7.4 -6.5...7.5 -6.5...7.6 -6.5...7.7 -6.5...7.8 -6.5...7.9 -6.5...8.0 -6.5...8.1 -6.5...8.2 -6.5...8.25 -6.5...8.3 -6.5...8.4 -6.5...8.5 -6.5...8.6 -6.5...8.7 -6.5...8.8 -6.5...8.9 -6.5...9 -6.5...9.0 -6.5...9.2 -6.5...9.3 -6.5...9.5 -6.5...9.7 -6.5...9.8 -6.5...>10 -6.5...>10.0 -6.5...>11 -6.5...>11.0 -6.5...>12.0 -6.5...>7.0 -6.5...>7.9 -6.5...>8.0 -6.5...>8.3 -6.5...>8.5 -6.5...>8.7 -6.5...>8.8 -6.5...>9.0 -6.5...>9.5 -6.51 -6.55 -6.6 -6.6... -6.6...7.0 -6.6...7.1 -6.6...7.3 -6.6...7.4 -6.6...7.5 -6.6...7.9 -6.6...8.3 -6.6...8.4 -6.6...8.5 -6.6...8.6 -6.6...8.7 -6.6...8.8 -6.6...8.9 -6.6...9.0 -6.6...9.4 -6.6...9.7 -6.6...9.8 -6.6...>10.0 -6.6...>10.3 -6.6...>11 -6.6...>9.0 -6.6...>9.5 -6.65...8.6 -6.67 -6.7 -6.7... -6.7...10.2 -6.7...11.5 -6.7...6.8 -6.7...6.9 -6.7...7.0 -6.7...7.3 -6.7...7.4 -6.7...7.5 -6.7...7.6 -6.7...7.8 -6.7...8.0 -6.7...8.1 -6.7...8.2 -6.7...8.3 -6.7...8.5 -6.7...8.6 -6.7...8.7 -6.7...8.8 -6.7...8.9 -6.7...9.0 -6.7...9.1 -6.7...9.2 -6.7...9.5 -6.7...9.7 -6.7...9.8 -6.7...>10 -6.7...>7.0 -6.7...>7.5 -6.7...>8.0 -6.7...>8.5 -6.7...>8.6 -6.7...>9 -6.7...>9.0 -6.7...>9.3 -6.74...8.0 -6.75 -6.75... -6.75...9.5 -6.75...>9 -6.75...>9.0 -6.75...>9.5 -6.76...8.10 -6.8 -6.8... -6.8...10 -6.8...10.0 -6.8...10.5 -6.8...6.9 -6.8...7.0 -6.8...7.1 -6.8...7.2 -6.8...7.3 -6.8...7.5 -6.8...7.6 -6.8...7.7 -6.8...7.8 -6.8...7.9 -6.8...8.0 -6.8...8.2 -6.8...8.25 -6.8...8.3 -6.8...8.5 -6.8...8.6 -6.8...8.7 -6.8...8.8 -6.8...8.9 -6.8...9.0 -6.8...9.1 -6.8...9.3 -6.8...9.4 -6.8...9.5 -6.8...9.6 -6.8...9.9 -6.8...>10.0 -6.8...>7.9 -6.8...>8.0 -6.8...>8.1 -6.8...>8.5 -6.8...>9.0 -6.8...>9.1 -6.80...>8.5 -6.81...7.53 -6.85 -6.86 -6.88 -6.9 -6.9... -6.9...10.4 -6.9...12.2 -6.9...7.0 -6.9...7.1 -6.9...7.3 -6.9...7.6 -6.9...7.9 -6.9...8.0 -6.9...8.2 -6.9...8.4 -6.9...8.5 -6.9...8.6 -6.9...8.7 -6.9...8.8 -6.9...9.0 -6.9...9.1 -6.9...9.2 -6.9...9.5 -6.9...9.7 -6.9...>7.1 -6.9...>8 -6.9...>8.5 -6.9...>9 -6.9...>9.0 -6.9...>9.3 -6.9...>9.5 -6.9...>90 -7 -7...10 -7...10.5 -7...11 -7...7.5 -7...8 -7...8.5 -7...8.8 -7...9 -7...>10 -7...>10.5 -7...>9.5 -7.0 -7.0 -7.0... -7.0...10 -7.0...10.0 -7.0...10.2 -7.0...10.3 -7.0...10.5 -7.0...10.7 -7.0...11 -7.0...11.0 -7.0...11.5 -7.0...7.2 -7.0...7.2 -7.0...7.3 -7.0...7.4 -7.0...7.5 -7.0...7.6 -7.0...7.8 -7.0...7.9 -7.0...8.0 -7.0...8.1 -7.0...8.2 -7.0...8.3 -7.0...8.4 -7.0...8.5 -7.0...8.6 -7.0...8.67 -7.0...8.7 -7.0...8.8 -7.0...8.9 -7.0...9.0 -7.0...9.1 -7.0...9.2 -7.0...9.3 -7.0...9.4 -7.0...9.5 -7.0...9.7 -7.0...9.75 -7.0...9.8 -7.0...9.9 -7.0...<8.0 -7.0...>10 -7.0...>10.0 -7.0...>10.5 -7.0...>11 -7.0...>11.5 -7.0...>7.8 -7.0...>8.5 -7.0...>8.7 -7.0...>9 -7.0...>9.0 -7.0...>9.5 -7.00 -7.01 -7.03 -7.05 -7.07 -7.1 -7.1...10.1 -7.1...10.3 -7.1...7.9 -7.1...8.1 -7.1...8.2 -7.1...8.3 -7.1...8.4 -7.1...8.6 -7.1...8.7 -7.1...8.9 -7.1...9.0 -7.1...9.2 -7.1...9.3 -7.1...9.4 -7.1...9.8 -7.1...>8.3 -7.1...>8.5 -7.1...>9.0 -7.1...>9.5 -7.10 -7.15 -7.15...8.3 -7.2 -7.2...10.0 -7.2...10.2 -7.2...10.5 -7.2...13.5 -7.2...7.3 -7.2...7.4 -7.2...7.5 -7.2...7.6 -7.2...7.8 -7.2...8.0 -7.2...8.2 -7.2...8.3 -7.2...8.6 -7.2...8.7 -7.2...8.8 -7.2...8.9 -7.2...9.0 -7.2...9.1 -7.2...9.2 -7.2...9.3 -7.2...9.5 -7.2...9.6 -7.2...9.7 -7.2...9.8 -7.2...>10 -7.2...>10.0 -7.2...>11 -7.2...>8.0 -7.2...>8.5 -7.2...>8.7 -7.2...>9.0 -7.2...>9.1 -7.2...>9.2 -7.2...>9.5 -7.24 -7.25 -7.25...7.75 -7.25...8.1 -7.25...8.25 -7.25...8.4 -7.25...8.6 -7.25...8.7 -7.25...9.25 -7.25...>10.0 -7.25...>8.0 -7.25...>8.25 -7.25...>9.0 -7.26 -7.3 -7.3... -7.3...10.2 -7.3...10.5 -7.3...11 -7.3...7.5 -7.3...7.6 -7.3...7.8 -7.3...7.9 -7.3...8.0 -7.3...8.2 -7.3...8.3 -7.3...8.4 -7.3...8.5 -7.3...8.6 -7.3...8.8 -7.3...8.9 -7.3...9.0 -7.3...9.15 -7.3...9.2 -7.3...9.4 -7.3...9.5 -7.3...9.8 -7.3...9.9 -7.3...>10 -7.3...>10.0 -7.3...>10.5 -7.3...>7.8 -7.3...>8.0 -7.3...>8.3 -7.3...>9.0 -7.3...>9.2 -7.3...>9.3 -7.3...>9.5 -7.3...>9.75 -7.3...>90 -7.32 -7.35 -7.4 -7.4... -7.4...10 -7.4...10.0 -7.4...12.1 -7.4...7.6 -7.4...7.8 -7.4...8.0 -7.4...8.2 -7.4...8.3 -7.4...8.4 -7.4...8.5 -7.4...8.6 -7.4...8.7 -7.4...8.8 -7.4...9.0 -7.4...9.2 -7.4...9.3 -7.4...9.6 -7.4...9.7 -7.4...9.8 -7.4...>10.0 -7.4...>8 -7.4...>8.5 -7.4...>8.6 -7.4...>8.7 -7.4...>9.0 -7.45 -7.5 -7.5 -7.5... -7.5...10 -7.5...10.0 -7.5...10.1 -7.5...10.2 -7.5...10.3 -7.5...10.5 -7.5...10.8 -7.5...11 -7.5...11.0 -7.5...11.5 -7.5...12.0 -7.5...7.6 -7.5...7.8 -7.5...8 -7.5...8.0 -7.5...8.1 -7.5...8.2 -7.5...8.4 -7.5...8.5 -7.5...8.6 -7.5...8.7 -7.5...9.0 -7.5...9.1 -7.5...9.2 -7.5...9.3 -7.5...9.4 -7.5...9.5 -7.5...9.6 -7.5...9.7 -7.5...9.8 -7.5...>10 -7.5...>10.0 -7.5...>10.5 -7.5...>11.0 -7.5...>8.3 -7.5...>8.5 -7.5...>8.7 -7.5...>8.75 -7.5...>9 -7.5...>9.0 -7.5...>9.2 -7.5...>9.5 -7.54 -7.55 -7.6 -7.6 -7.6...10.3 -7.6...10.5 -7.6...7.8 -7.6...7.9 -7.6...8.0 -7.6...8.2 -7.6...8.3 -7.6...8.4 -7.6...8.5 -7.6...8.6 -7.6...8.8 -7.6...9.0 -7.6...9.2 -7.6...9.3 -7.6...9.4 -7.6...9.5 -7.6...9.7 -7.6...>10.0 -7.6...>10.3 -7.6...>10.5 -7.6...>11 -7.6...>8.25 -7.6...>8.8 -7.6...>9.0 -7.6...>9.5 -7.65 -7.7... -7.7...10 -7.7...10.0 -7.7...10.3 -7.7...10.5 -7.7...11.0 -7.7...11.5 -7.7...7.8 -7.7...8.0 -7.7...8.3 -7.7...8.5 -7.7...8.7 -7.7...9.0 -7.7...9.25 -7.7...9.4 -7.7...9.5 -7.7...9.8 -7.7...>10.5 -7.7...>8.5 -7.7...>8.6 -7.7...>9.0 -7.7...>9.5 -7.72...8.7 -7.75 -7.75... -7.75...8.1 -7.78 -7.8 -7.8...10.2 -7.8...7.9 -7.8...8.0 -7.8...8.1 -7.8...8.2 -7.8...8.4 -7.8...8.5 -7.8...8.7 -7.8...8.8 -7.8...8.9 -7.8...9.0 -7.8...9.2 -7.8...9.3 -7.8...9.4 -7.8...9.6 -7.8...<9.8 -7.8...>10.0 -7.8...>8.8 -7.8...>8.9 -7.8...>9.0 -7.8...>9.1 -7.8...>9.4 -7.80 -7.85 -7.9 -7.9...10.9 -7.9...8.1 -7.9...8.2 -7.9...8.3 -7.9...8.5 -7.9...8.6 -7.9...8.9 -7.9...9.0 -7.9...9.3 -7.96 -8 -8...10 -8...10.2 -8...10.5 -8...11.0 -8...8.5 -8...9 -8...>10 -8...>11 -8.0 -8.0...10 -8.0...10.0 -8.0...10.2 -8.0...10.3 -8.0...10.5 -8.0...10.8 -8.0...11.0 -8.0...11.2 -8.0...11.7 -8.0...12.0 -8.0...8.5 -8.0...8.12 -8.0...8.2 -8.0...8.4 -8.0...8.5 -8.0...8.6 -8.0...8.7 -8.0...8.8 -8.0...8.9 -8.0...9.0 -8.0...9.2 -8.0...9.4 -8.0...9.5 -8.0...9.7 -8.0...>10 -8.0...>10.0 -8.0...>10.5 -8.0...>11 -8.0...>13.0 -8.0...>8.75 -8.0...>9.0 -8.0...>9.2 -8.0...>9.5 -8.1 -8.1...10.5 -8.1...10.9 -8.1...8.2 -8.1...8.3 -8.1...8.4 -8.1...8.6 -8.1...8.7 -8.1...8.75 -8.1...8.9 -8.1...9.1 -8.1...9.9 -8.1...>9.5 -8.13 -8.15 -8.2 -8.2... -8.2...10.2 -8.2...10.4 -8.2...8.4 -8.2...8.5 -8.2...8.8 -8.2...8.9 -8.2...9.0 -8.2...9.6 -8.2...9.8 -8.2...>10 -8.2...>10.5 -8.2...>11 -8.2...>11.0 -8.2...>8.8 -8.2...>9.3 -8.20 -8.25 -8.25...10.2 -8.27 -8.27...10 -8.28 -8.3 -8.3... -8.3...10.2 -8.3...10.3 -8.3...10.8 -8.3...8.4 -8.3...8.5 -8.3...8.6 -8.3...8.8 -8.3...9.6 -8.3...9.9 -8.3...>9.5 -8.3...>9.8 -8.35 -8.4 -8.4...10.1 -8.4...8.5 -8.4...8.6 -8.4...8.7 -8.4...8.8 -8.4...8.9 -8.4...9.0 -8.4...9.2 -8.4...9.5 -8.4...<9.8 -8.4...>10.0 -8.4...>10.5 -8.4...>9.8 -8.48 -8.5 -8.5... -8.5...10.0 -8.5...10.3 -8.5...10.5 -8.5...10.7 -8.5...10.8 -8.5...11 -8.5...11.0 -8.5...12.5 -8.5...8.6 -8.5...8.8 -8.5...9.0 -8.5...9.1 -8.5...9.2 -8.5...9.3 -8.5...9.4 -8.5...9.5 -8.5...9.9 -8.5...>10 -8.5...>11 -8.5...>11.5 -8.5...>9.5 -8.6 -8.6...10.2 -8.6...10.3 -8.6...11 -8.6...8.7 -8.6...8.8 -8.6...8.9 -8.6...9.4 -8.6...>11 -8.6...>99 -8.65 -8.7 -8.7...10.6 -8.7...11.2 -8.7...11.3 -8.7...11.7 -8.7...8.9 -8.7...9.1 -8.7...9.6 -8.7...9.8 -8.75 -8.8 -8.8...10.3 -8.8...10.7 -8.8...9.0 -8.8...9.2 -8.8...9.8 -8.8...>9.8 -8.9 -8.9...10.3 -8.9...10.4 -8.9...10.9 -8.9...11.5 -8.9...9.2 -9 -9.8 -9...10 -9...11 -9...>12 -9.0 -9.0... -9.0...10 -9.0...10.0 -9.0...10.5 -9.0...10.7 -9.0...11 -9.0...11.0 -9.0...11.1 -9.0...11.2 -9.0...11.3 -9.0...11.5 -9.0...12 -9.0...9.2 -9.0...9.5 -9.0...>10.7 -9.0...>11.0 -9.1 -9.1...10 -9.1...10.1 -9.1...9.5 -9.15 -9.2 -9.2...10 -9.2...10.8 -9.2...12 -9.2...9.3 -9.2...9.4 -9.2...9.5 -9.2...9.6 -9.25 -9.3 -9.4 -9.4...10 -9.4...12.2 -9.4...9.7 -9.5 -9.5... -9.5...10 -9.5...10.0 -9.5...10.4 -9.5...10.5 -9.5...10.6 -9.5...11.2 -9.5...9.8 -9.5...>10.2 -9.5...>10.5 -9.55 -9.6 -9.6...10 -9.6...10.2 -9.6...11.5 -9.6...>11.2 -9.63 -9.7 -9.7...11 -9.7...11.5 -9.7...9.8 -9.7...>12 -9.75 -9.76 -9.8 -9.8...10.0 -9.8...10.1 -9.8...>12.5 -9.9 -9.99 -10 -10...10.5 -10...11 -10.0 -10.0...10.4 -10.0...10.5 -10.0...11.25 -10.0...11.5 -10.0...12.5 -10.0...>12.5 -10.2 -10.2...11.8 -10.25 -10.3 -10.32 -10.4 -10.45 -10.5 -10.5...11.0 -10.5...11.5 -10.5...<13.5 -10.6 -10.7 -10.7...12.3 -10.70 -10.75 -10.8 -11 -11 -11.0 -11.3 -11.5 -11.5...12.5 -11.75 -12 -12.0 -12.2 -14 -15 -16 -16.7 -17 -18 -19 -19.8 -20 -20.0 -22 -22 -22.9 -23 -23...25 -23.7 -24 -24.0 diff --git a/contrib/seg/expected/seg.out b/contrib/seg/expected/seg.out deleted file mode 100644 index 9abfdc2ecb..0000000000 --- a/contrib/seg/expected/seg.out +++ /dev/null @@ -1,1064 +0,0 @@ --- --- Test seg datatype --- --- --- first, define the datatype. Turn off echoing so that expected file --- does not depend on contents of seg.sql. --- -\set ECHO none --- --- testing the input and output functions --- --- Any number -SELECT '1'::seg AS seg; - seg ------ - 1 -(1 row) - -SELECT '-1'::seg AS seg; - seg ------ - -1 -(1 row) - -SELECT '1.0'::seg AS seg; - seg ------ - 1.0 -(1 row) - -SELECT '-1.0'::seg AS seg; - seg ------- - -1.0 -(1 row) - -SELECT '1e7'::seg AS seg; - seg -------- - 1e+07 -(1 row) - -SELECT '-1e7'::seg AS seg; - seg --------- - -1e+07 -(1 row) - -SELECT '1.0e7'::seg AS seg; - seg ---------- - 1.0e+07 -(1 row) - -SELECT '-1.0e7'::seg AS seg; - seg ----------- - -1.0e+07 -(1 row) - -SELECT '1e+7'::seg AS seg; - seg -------- - 1e+07 -(1 row) - -SELECT '-1e+7'::seg AS seg; - seg --------- - -1e+07 -(1 row) - -SELECT '1.0e+7'::seg AS seg; - seg ---------- - 1.0e+07 -(1 row) - -SELECT '-1.0e+7'::seg AS seg; - seg ----------- - -1.0e+07 -(1 row) - -SELECT '1e-7'::seg AS seg; - seg -------- - 1e-07 -(1 row) - -SELECT '-1e-7'::seg AS seg; - seg --------- - -1e-07 -(1 row) - -SELECT '1.0e-7'::seg AS seg; - seg ---------- - 1.0e-07 -(1 row) - -SELECT '-1.0e-7'::seg AS seg; - seg ----------- - -1.0e-07 -(1 row) - -SELECT '2e-6'::seg AS seg; - seg -------- - 2e-06 -(1 row) - -SELECT '2e-5'::seg AS seg; - seg -------- - 2e-05 -(1 row) - -SELECT '2e-4'::seg AS seg; - seg --------- - 0.0002 -(1 row) - -SELECT '2e-3'::seg AS seg; - seg -------- - 0.002 -(1 row) - -SELECT '2e-2'::seg AS seg; - seg ------- - 0.02 -(1 row) - -SELECT '2e-1'::seg AS seg; - seg ------ - 0.2 -(1 row) - -SELECT '2e-0'::seg AS seg; - seg ------ - 2 -(1 row) - -SELECT '2e+0'::seg AS seg; - seg ------ - 2 -(1 row) - -SELECT '2e+1'::seg AS seg; - seg ------ - 2e1 -(1 row) - -SELECT '2e+2'::seg AS seg; - seg ------ - 2e2 -(1 row) - -SELECT '2e+3'::seg AS seg; - seg ------ - 2e3 -(1 row) - -SELECT '2e+4'::seg AS seg; - seg ------ - 2e4 -(1 row) - -SELECT '2e+5'::seg AS seg; - seg -------- - 2e+05 -(1 row) - -SELECT '2e+6'::seg AS seg; - seg -------- - 2e+06 -(1 row) - --- Significant digits preserved -SELECT '1'::seg AS seg; - seg ------ - 1 -(1 row) - -SELECT '1.0'::seg AS seg; - seg ------ - 1.0 -(1 row) - -SELECT '1.00'::seg AS seg; - seg ------- - 1.00 -(1 row) - -SELECT '1.000'::seg AS seg; - seg -------- - 1.000 -(1 row) - -SELECT '1.0000'::seg AS seg; - seg --------- - 1.0000 -(1 row) - -SELECT '1.00000'::seg AS seg; - seg ---------- - 1.00000 -(1 row) - -SELECT '1.000000'::seg AS seg; - seg ---------- - 1.00000 -(1 row) - -SELECT '0.000000120'::seg AS seg; - seg ----------- - 1.20e-07 -(1 row) - -SELECT '3.400e5'::seg AS seg; - seg ------------ - 3.400e+05 -(1 row) - --- Digits truncated -SELECT '12.34567890123456'::seg AS seg; - seg ---------- - 12.3457 -(1 row) - --- Numbers with certainty indicators -SELECT '~6.5'::seg AS seg; - seg ------- - ~6.5 -(1 row) - -SELECT '<6.5'::seg AS seg; - seg ------- - <6.5 -(1 row) - -SELECT '>6.5'::seg AS seg; - seg ------- - >6.5 -(1 row) - -SELECT '~ 6.5'::seg AS seg; - seg ------- - ~6.5 -(1 row) - -SELECT '< 6.5'::seg AS seg; - seg ------- - <6.5 -(1 row) - -SELECT '> 6.5'::seg AS seg; - seg ------- - >6.5 -(1 row) - --- Open intervals -SELECT '0..'::seg AS seg; - seg ------- - 0 .. -(1 row) - -SELECT '0...'::seg AS seg; - seg ------- - 0 .. -(1 row) - -SELECT '0 ..'::seg AS seg; - seg ------- - 0 .. -(1 row) - -SELECT '0 ...'::seg AS seg; - seg ------- - 0 .. -(1 row) - -SELECT '..0'::seg AS seg; - seg ------- - .. 0 -(1 row) - -SELECT '...0'::seg AS seg; - seg ------- - .. 0 -(1 row) - -SELECT '.. 0'::seg AS seg; - seg ------- - .. 0 -(1 row) - -SELECT '... 0'::seg AS seg; - seg ------- - .. 0 -(1 row) - --- Finite intervals -SELECT '0 .. 1'::seg AS seg; - seg --------- - 0 .. 1 -(1 row) - -SELECT '-1 .. 0'::seg AS seg; - seg ---------- - -1 .. 0 -(1 row) - -SELECT '-1 .. 1'::seg AS seg; - seg ---------- - -1 .. 1 -(1 row) - --- (+/-) intervals -SELECT '0(+-)1'::seg AS seg; - seg ---------- - -1 .. 1 -(1 row) - -SELECT '0(+-)1.0'::seg AS seg; - seg -------------- - -1.0 .. 1.0 -(1 row) - -SELECT '1.0(+-)0.005'::seg AS seg; - seg ----------------- - 0.995 .. 1.005 -(1 row) - -SELECT '101(+-)1'::seg AS seg; - seg ------------------- - 1.00e2 .. 1.02e2 -(1 row) - --- incorrect number of significant digits in 99.0: -SELECT '100(+-)1'::seg AS seg; - seg ----------------- - 99.0 .. 1.01e2 -(1 row) - --- invalid input -SELECT ''::seg AS seg; -ERROR: seg_in: can't parse an empty string -SELECT 'ABC'::seg AS seg; -ERROR: parse error, expecting `FLOAT' or `RANGE' or `EXTENSION' at or near position 1, character ('A', \101), input: 'ABC' - -SELECT '1ABC'::seg AS seg; -ERROR: expecting end of input at or near position 2, character ('A', \101), input: '1ABC' - -SELECT '1.'::seg AS seg; -ERROR: expecting end of input at or near position 2, character ('.', \056), input: '1.' - -SELECT '1.....'::seg AS seg; -ERROR: expecting end of input at or near position 6, character ('.', \056), input: '1.....' - -SELECT '.1'::seg AS seg; -ERROR: parse error, expecting `FLOAT' or `RANGE' or `EXTENSION' at or near position 2, character ('1', \061), input: '.1' - -SELECT '1..2.'::seg AS seg; -ERROR: expecting end of input at or near position 5, character ('.', \056), input: '1..2.' - -SELECT '1 e7'::seg AS seg; -ERROR: expecting end of input at or near position 3, character ('e', \145), input: '1 e7' - -SELECT '1e700'::seg AS seg; -ERROR: numeric value 1e700 unrepresentable --- --- testing the operators --- --- equality/inequality: --- -SELECT '24 .. 33.20'::seg = '24 .. 33.20'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '24 .. 33.20'::seg = '24 .. 33.21'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '24 .. 33.20'::seg != '24 .. 33.20'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '24 .. 33.20'::seg != '24 .. 33.21'::seg AS bool; - bool ------- - t -(1 row) - --- overlap --- -SELECT '1'::seg && '1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '1'::seg && '2'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 ..'::seg && '0 ..'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg && '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '..0'::seg && '0..'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '-1 .. 0.1'::seg && '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '-1 .. 0'::seg && '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '-1 .. -0.0001'::seg && '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 ..'::seg && '1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg && '1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg && '2'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 2'::seg && '1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '1'::seg && '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '2'::seg && '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '1'::seg && '0 .. 2'::seg AS bool; - bool ------- - t -(1 row) - --- overlap on the left --- -SELECT '1'::seg &< '0'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '1'::seg &< '1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '1'::seg &< '2'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg &< '0'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg &< '1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg &< '2'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg &< '0 .. 0.5'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg &< '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg &< '0 .. 2'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg &< '1 .. 2'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg &< '2 .. 3'::seg AS bool; - bool ------- - f -(1 row) - --- overlap on the right --- -SELECT '0'::seg &> '1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '1'::seg &> '1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '2'::seg &> '1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0'::seg &> '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '1'::seg &> '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '2'::seg &> '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 0.5'::seg &> '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg &> '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 2'::seg &> '0 .. 2'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '1 .. 2'::seg &> '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '2 .. 3'::seg &> '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - --- left --- -SELECT '1'::seg << '0'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '1'::seg << '1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '1'::seg << '2'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg << '0'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg << '1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg << '2'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 1'::seg << '0 .. 0.5'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg << '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg << '0 .. 2'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg << '1 .. 2'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg << '2 .. 3'::seg AS bool; - bool ------- - t -(1 row) - --- right --- -SELECT '0'::seg >> '1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '1'::seg >> '1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '2'::seg >> '1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0'::seg >> '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '1'::seg >> '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '2'::seg >> '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. 0.5'::seg >> '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 1'::seg >> '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0 .. 2'::seg >> '0 .. 2'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '1 .. 2'::seg >> '0 .. 1'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '2 .. 3'::seg >> '0 .. 1'::seg AS bool; - bool ------- - t -(1 row) - --- "contained in" (the left value belongs within the interval specified in the right value): --- -SELECT '0'::seg ~ '0'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0'::seg ~ '0 ..'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0'::seg ~ '.. 0'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0'::seg ~ '-1 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0'::seg ~ '-1 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '-1'::seg ~ '-1 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '1'::seg ~ '-1 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '-1 .. 1'::seg ~ '-1 .. 1'::seg AS bool; - bool ------- - t -(1 row) - --- "contains" (the left value contains the interval specified in the right value): --- -SELECT '0'::seg @ '0'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '0 .. '::seg ~ '0'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '.. 0'::seg ~ '0'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '-1 .. 1'::seg ~ '0'::seg AS bool; - bool ------- - f -(1 row) - -SELECT '0'::seg ~ '-1 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '-1'::seg ~ '-1 .. 1'::seg AS bool; - bool ------- - t -(1 row) - -SELECT '1'::seg ~ '-1 .. 1'::seg AS bool; - bool ------- - t -(1 row) - --- Load some example data and build the index --- -CREATE TABLE test_seg (s seg); -\copy test_seg from 'data/test_seg.data' -CREATE INDEX test_seg_ix ON test_seg USING gist (s); -SELECT count(*) FROM test_seg WHERE s @ '11..11.3'; - count -------- - 143 -(1 row) - --- Test sorting -SELECT * FROM test_seg WHERE s @ '11..11.3' GROUP BY s; - s ------------------ - .. 4.0e1 - .. >8.2e1 - .. 9.0e1 - <1.0 .. >13.0 - 1.3 .. 12.0 - 2.0 .. 11.5 - 2.1 .. 11.8 - <2.3 .. - >2.3 .. - 2.4 .. 11.3 - 2.5 .. 11.5 - 2.5 .. 11.8 - 2.6 .. - 2.7 .. 12.0 - <3.0 .. - 3 .. 5.8e1 - 3.1 .. 11.5 - 3.5 .. 11.5 - 3.5 .. 12.2 - <4.0 .. >1.2e1 - <4.0 .. - 4 .. 1.2e1 - 4.0 .. 11.7 - 4.0 .. 12.5 - 4.0 .. 13.0 - 4.0 .. 6.0e1 - 4.0 .. - 4.2 .. 11.5 - 4.2 .. 11.7 - <4.5 .. >1.2e1 - 4.5 .. 11.5 - 4.5 .. <1.2e1 - 4.5 .. >1.2e1 - 4.5 .. 12.5 - 4.5 .. 1.15e2 - 4.7 .. 11.8 - 4.8 .. 11.5 - 4.8 .. 11.6 - 4.8 .. 12.5 - 4.8 .. - 4.9 .. >1.2e1 - 4.9 .. - 5 .. 11.5 - 5 .. 1.2e1 - 5 .. 3.0e1 - 5.0 .. 11.4 - 5.0 .. 11.5 - 5.0 .. 11.6 - 5.0 .. 11.7 - 5.0 .. 12.0 - 5.0 .. >12.0 - 5.0 .. >1.2e1 - 5.2 .. 11.5 - 5.2 .. >1.2e1 - 5.25 .. >1.2e1 - 5.3 .. 11.5 - 5.3 .. 1.3e1 - 5.3 .. >9.0e1 - 5.3 .. - 5.4 .. - 5.5 .. 11.5 - 5.5 .. 11.7 - 5.5 .. 1.2e1 - 5.5 .. >1.2e1 - 5.5 .. 12.5 - 5.5 .. 13.5 - 5.5 .. - >5.5 .. - 5.7 .. - 5.9 .. - 6 .. 11.5 - 6 .. >1.2e1 - 6.0 .. 11.5 - 6.0 .. 1.3e1 - >6.0 .. <11.5 - 6.1 .. >1.2e1 - 6.1 .. - 6.2 .. >11.5 - 6.3 .. - 6.5 .. 11.5 - 6.5 .. 12.0 - 6.5 .. >12.0 - 6.5 .. - 6.6 .. - 6.7 .. 11.5 - 6.7 .. - 6.75 .. - 6.8 .. - 6.9 .. 12.2 - 6.9 .. >9.0e1 - 6.9 .. - <7.0 .. >11.5 - 7.0 .. 11.5 - 7.0 .. >11.5 - 7.0 .. - >7.15 .. - 7.2 .. 13.5 - 7.3 .. >9.0e1 - 7.3 .. - >7.3 .. - 7.4 .. 12.1 - 7.4 .. - 7.5 .. 11.5 - 7.5 .. 12.0 - 7.5 .. - 7.7 .. 11.5 - 7.7 .. - 7.75 .. - 8.0 .. 11.7 - 8.0 .. 12.0 - 8.0 .. >13.0 - 8.2 .. - 8.3 .. - 8.5 .. >11.5 - 8.5 .. 12.5 - 8.5 .. - 8.6 .. >9.9e1 - 8.7 .. 11.3 - 8.7 .. 11.7 - 8.9 .. 11.5 - 9 .. >1.2e1 - 9.0 .. 11.3 - 9.0 .. 11.5 - 9.0 .. 1.2e1 - 9.0 .. - 9.2 .. 1.2e1 - 9.4 .. 12.2 - <9.5 .. 1.2e1 - <9.5 .. >12.2 - 9.5 .. - 9.6 .. 11.5 - 9.7 .. 11.5 - 9.7 .. >1.2e1 - 9.8 .. >12.5 - <1.0e1 .. >11.6 - 10.0 .. 11.5 - 10.0 .. 12.5 - 10.0 .. >12.5 - 10.2 .. 11.8 - <10.5 .. 11.5 - 10.5 .. 11.5 - 10.5 .. <13.5 - 10.7 .. 12.3 -(143 rows) - diff --git a/contrib/seg/seg-validate.pl b/contrib/seg/seg-validate.pl deleted file mode 100755 index 9272936aef..0000000000 --- a/contrib/seg/seg-validate.pl +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/perl -$integer = '[+-]?[0-9]+'; -$real = '[+-]?[0-9]+\.[0-9]+'; - -$RANGE = '(\.\.)(\.)?'; -$PLUMIN = q(\'\+\-\'); -$FLOAT = "(($integer)|($real))([eE]($integer))?"; -$EXTENSION = '<|>|~'; - -$boundary = "($EXTENSION)?$FLOAT"; -$deviation = $FLOAT; - -$rule_1 = $boundary . $PLUMIN . $deviation; -$rule_2 = $boundary . $RANGE . $boundary; -$rule_3 = $boundary . $RANGE; -$rule_4 = $RANGE . $boundary; -$rule_5 = $boundary; - - -print "$rule_5\n"; -while (<>) { -# s/ +//g; - if ( /^($rule_1)$/ ) { - print; - } - elsif ( /^($rule_2)$/ ) { - print; - } - elsif ( /^($rule_3)$/ ) { - print; - } - elsif ( /^($rule_4)$/ ) { - print; - } - elsif ( /^($rule_5)$/ ) { - print; - } - else { - print STDERR "error in $_\n"; - } - -} diff --git a/contrib/seg/seg.c b/contrib/seg/seg.c deleted file mode 100644 index 097304b638..0000000000 --- a/contrib/seg/seg.c +++ /dev/null @@ -1,1119 +0,0 @@ -/****************************************************************************** - This file contains routines that can be bound to a Postgres backend and - called by the backend in the process of processing queries. The calling - format for these routines is dictated by Postgres architecture. -******************************************************************************/ - -#include "postgres.h" - -#include - -#include "access/gist.h" -#include "access/rtree.h" -#include "utils/elog.h" -#include "utils/palloc.h" -#include "utils/builtins.h" - -#include "segdata.h" - -#define max(a,b) ((a) > (b) ? (a) : (b)) -#define min(a,b) ((a) <= (b) ? (a) : (b)) -#define abs(a) ((a) < (0) ? (-a) : (a)) - -/* -#define GIST_DEBUG -#define GIST_QUERY_DEBUG -*/ - -extern void set_parse_buffer(char *str); -extern int seg_yyparse(); - -/* -extern int seg_yydebug; -*/ - -/* -** Input/Output routines -*/ -SEG *seg_in(char *str); -char *seg_out(SEG * seg); -float32 seg_lower(SEG * seg); -float32 seg_upper(SEG * seg); -float32 seg_center(SEG * seg); - -/* -** GiST support methods -*/ -bool gseg_consistent(GISTENTRY *entry, SEG * query, StrategyNumber strategy); -GISTENTRY *gseg_compress(GISTENTRY *entry); -GISTENTRY *gseg_decompress(GISTENTRY *entry); -float *gseg_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result); -GIST_SPLITVEC *gseg_picksplit(bytea *entryvec, GIST_SPLITVEC *v); -bool gseg_leaf_consistent(SEG * key, SEG * query, StrategyNumber strategy); -bool gseg_internal_consistent(SEG * key, SEG * query, StrategyNumber strategy); -SEG *gseg_union(bytea *entryvec, int *sizep); -SEG *gseg_binary_union(SEG * r1, SEG * r2, int *sizep); -bool *gseg_same(SEG * b1, SEG * b2, bool *result); - - -/* -** R-tree suport functions -*/ -bool seg_same(SEG * a, SEG * b); -bool seg_contains_int(SEG * a, int *b); -bool seg_contains_float4(SEG * a, float4 *b); -bool seg_contains_float8(SEG * a, float8 *b); -bool seg_contains(SEG * a, SEG * b); -bool seg_contained(SEG * a, SEG * b); -bool seg_overlap(SEG * a, SEG * b); -bool seg_left(SEG * a, SEG * b); -bool seg_over_left(SEG * a, SEG * b); -bool seg_right(SEG * a, SEG * b); -bool seg_over_right(SEG * a, SEG * b); -SEG *seg_union(SEG * a, SEG * b); -SEG *seg_inter(SEG * a, SEG * b); -void rt_seg_size(SEG * a, float *sz); -float *seg_size(SEG * a); - -/* -** Various operators -*/ -int32 seg_cmp(SEG * a, SEG * b); -bool seg_lt(SEG * a, SEG * b); -bool seg_le(SEG * a, SEG * b); -bool seg_gt(SEG * a, SEG * b); -bool seg_ge(SEG * a, SEG * b); -bool seg_different(SEG * a, SEG * b); - -/* -** Auxiliary funxtions -*/ -static int restore(char *s, float val, int n); -int significant_digits(char *s); - - -/***************************************************************************** - * Input/Output functions - *****************************************************************************/ - -SEG * -seg_in(char *str) -{ - SEG *result = palloc(sizeof(SEG)); - - set_parse_buffer(str); - - /* - * seg_yydebug = 1; - */ - if (seg_yyparse(result) != 0) - { - pfree(result); - return NULL; - } - return (result); -} - -/* - * You might have noticed a slight inconsistency between the following - * declaration and the SQL definition: - * CREATE FUNCTION seg_out(opaque) RETURNS opaque ... - * The reason is that the argument passed into seg_out is really just a - * pointer. POSTGRES thinks all output functions are: - * char *out_func(char *); - */ -char * -seg_out(SEG * seg) -{ - char *result; - char *p; - - if (seg == NULL) - return (NULL); - - p = result = (char *) palloc(40); - - if (seg->l_ext == '>' || seg->l_ext == '<' || seg->l_ext == '~') - p += sprintf(p, "%c", seg->l_ext); - - if (seg->lower == seg->upper && seg->l_ext == seg->u_ext) - { - /* - * indicates that this interval was built by seg_in off a single - * point - */ - p += restore(p, seg->lower, seg->l_sigd); - } - else - { - if (seg->l_ext != '-') - { - /* print the lower boudary if exists */ - p += restore(p, seg->lower, seg->l_sigd); - p += sprintf(p, " "); - } - p += sprintf(p, ".."); - if (seg->u_ext != '-') - { - /* print the upper boudary if exists */ - p += sprintf(p, " "); - if (seg->u_ext == '>' || seg->u_ext == '<' || seg->l_ext == '~') - p += sprintf(p, "%c", seg->u_ext); - p += restore(p, seg->upper, seg->u_sigd); - } - } - - return (result); -} - -float32 -seg_center(SEG * seg) -{ - float32 result = (float32) palloc(sizeof(float32data)); - - if (!seg) - return (float32) NULL; - - *result = ((float) seg->lower + (float) seg->upper) / 2.0; - return (result); -} - -float32 -seg_lower(SEG * seg) -{ - float32 result = (float32) palloc(sizeof(float32data)); - - if (!seg) - return (float32) NULL; - - *result = (float) seg->lower; - return (result); -} - -float32 -seg_upper(SEG * seg) -{ - float32 result = (float32) palloc(sizeof(float32data)); - - if (!seg) - return (float32) NULL; - - *result = (float) seg->upper; - return (result); -} - - -/***************************************************************************** - * GiST functions - *****************************************************************************/ - -/* -** The GiST Consistent method for segments -** Should return false if for all data items x below entry, -** the predicate x op query == FALSE, where op is the oper -** corresponding to strategy in the pg_amop table. -*/ -bool -gseg_consistent(GISTENTRY *entry, - SEG * query, - StrategyNumber strategy) -{ - /* - * * if entry is not leaf, use gseg_internal_consistent, * else use - * gseg_leaf_consistent - */ - if (GIST_LEAF(entry)) - return (gseg_leaf_consistent((SEG *) DatumGetPointer(entry->key), query, strategy)); - else - return (gseg_internal_consistent((SEG *) DatumGetPointer(entry->key), query, strategy)); -} - -/* -** The GiST Union method for segments -** returns the minimal bounding seg that encloses all the entries in entryvec -*/ -SEG * -gseg_union(bytea *entryvec, int *sizep) -{ - int numranges, - i; - SEG *out = (SEG *) NULL; - SEG *tmp; - -#ifdef GIST_DEBUG - fprintf(stderr, "union\n"); -#endif - - numranges = (VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY); - tmp = (SEG *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[0].key); - *sizep = sizeof(SEG); - - for (i = 1; i < numranges; i++) - { - out = gseg_binary_union(tmp, (SEG *) - DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key), - sizep); - if (i > 1) - pfree(tmp); - tmp = out; - } - - return (out); -} - -/* -** GiST Compress and Decompress methods for segments -** do not do anything. -*/ -GISTENTRY * -gseg_compress(GISTENTRY *entry) -{ - return (entry); -} - -GISTENTRY * -gseg_decompress(GISTENTRY *entry) -{ - return (entry); -} - -/* -** The GiST Penalty method for segments -** As in the R-tree paper, we use change in area as our penalty metric -*/ -float * -gseg_penalty(GISTENTRY *origentry, GISTENTRY *newentry, float *result) -{ - SEG *ud; - float tmp1, - tmp2; - - ud = seg_union((SEG *) DatumGetPointer(origentry->key), - (SEG *) DatumGetPointer(newentry->key)); - rt_seg_size(ud, &tmp1); - rt_seg_size((SEG *) DatumGetPointer(origentry->key), &tmp2); - *result = tmp1 - tmp2; - pfree(ud); - -#ifdef GIST_DEBUG - fprintf(stderr, "penalty\n"); - fprintf(stderr, "\t%g\n", *result); -#endif - - return (result); -} - - - -/* -** The GiST PickSplit method for segments -** We use Guttman's poly time split algorithm -*/ -GIST_SPLITVEC * -gseg_picksplit(bytea *entryvec, - GIST_SPLITVEC *v) -{ - OffsetNumber i, - j; - SEG *datum_alpha, - *datum_beta; - SEG *datum_l, - *datum_r; - SEG *union_d, - *union_dl, - *union_dr; - SEG *inter_d; - bool firsttime; - float size_alpha, - size_beta, - size_union, - size_inter; - float size_waste, - waste; - float size_l, - size_r; - int nbytes; - OffsetNumber seed_1 = 0, - seed_2 = 0; - OffsetNumber *left, - *right; - OffsetNumber maxoff; - -#ifdef GIST_DEBUG - fprintf(stderr, "picksplit\n"); -#endif - - maxoff = ((VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY)) - 2; - nbytes = (maxoff + 2) * sizeof(OffsetNumber); - v->spl_left = (OffsetNumber *) palloc(nbytes); - v->spl_right = (OffsetNumber *) palloc(nbytes); - - firsttime = true; - waste = 0.0; - - for (i = FirstOffsetNumber; i < maxoff; i = OffsetNumberNext(i)) - { - datum_alpha = (SEG *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key); - for (j = OffsetNumberNext(i); j <= maxoff; j = OffsetNumberNext(j)) - { - datum_beta = (SEG *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[j].key); - - /* compute the wasted space by unioning these guys */ - /* size_waste = size_union - size_inter; */ - union_d = seg_union(datum_alpha, datum_beta); - rt_seg_size(union_d, &size_union); - inter_d = seg_inter(datum_alpha, datum_beta); - rt_seg_size(inter_d, &size_inter); - size_waste = size_union - size_inter; - - pfree(union_d); - - if (inter_d != (SEG *) NULL) - pfree(inter_d); - - /* - * are these a more promising split that what we've already - * seen? - */ - - if (size_waste > waste || firsttime) - { - waste = size_waste; - seed_1 = i; - seed_2 = j; - firsttime = false; - } - } - } - - left = v->spl_left; - v->spl_nleft = 0; - right = v->spl_right; - v->spl_nright = 0; - - datum_alpha = (SEG *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[seed_1].key); - datum_l = seg_union(datum_alpha, datum_alpha); - rt_seg_size(datum_l, &size_l); - datum_beta = (SEG *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[seed_2].key); - datum_r = seg_union(datum_beta, datum_beta); - rt_seg_size(datum_r, &size_r); - - /* - * Now split up the regions between the two seeds. An important - * property of this split algorithm is that the split vector v has the - * indices of items to be split in order in its left and right - * vectors. We exploit this property by doing a merge in the code - * that actually splits the page. - * - * For efficiency, we also place the new index tuple in this loop. This - * is handled at the very end, when we have placed all the existing - * tuples and i == maxoff + 1. - */ - - maxoff = OffsetNumberNext(maxoff); - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) - { - /* - * If we've already decided where to place this item, just put it - * on the right list. Otherwise, we need to figure out which page - * needs the least enlargement in order to store the item. - */ - - if (i == seed_1) - { - *left++ = i; - v->spl_nleft++; - continue; - } - else if (i == seed_2) - { - *right++ = i; - v->spl_nright++; - continue; - } - - /* okay, which page needs least enlargement? */ - datum_alpha = (SEG *) DatumGetPointer(((GISTENTRY *) VARDATA(entryvec))[i].key); - union_dl = seg_union(datum_l, datum_alpha); - union_dr = seg_union(datum_r, datum_alpha); - rt_seg_size(union_dl, &size_alpha); - rt_seg_size(union_dr, &size_beta); - - /* pick which page to add it to */ - if (size_alpha - size_l < size_beta - size_r) - { - pfree(datum_l); - pfree(union_dr); - datum_l = union_dl; - size_l = size_alpha; - *left++ = i; - v->spl_nleft++; - } - else - { - pfree(datum_r); - pfree(union_dl); - datum_r = union_dr; - size_r = size_alpha; - *right++ = i; - v->spl_nright++; - } - } - *left = *right = FirstOffsetNumber; /* sentinel value, see dosplit() */ - - v->spl_ldatum = PointerGetDatum(datum_l); - v->spl_rdatum = PointerGetDatum(datum_r); - - return v; -} - -/* -** Equality methods -*/ -bool * -gseg_same(SEG * b1, SEG * b2, bool *result) -{ - if (seg_same(b1, b2)) - *result = TRUE; - else - *result = FALSE; - -#ifdef GIST_DEBUG - fprintf(stderr, "same: %s\n", (*result ? "TRUE" : "FALSE")); -#endif - - return (result); -} - -/* -** SUPPORT ROUTINES -*/ -bool -gseg_leaf_consistent(SEG * key, - SEG * query, - StrategyNumber strategy) -{ - bool retval; - -#ifdef GIST_QUERY_DEBUG - fprintf(stderr, "leaf_consistent, %d\n", strategy); -#endif - - switch (strategy) - { - case RTLeftStrategyNumber: - retval = (bool) seg_left(key, query); - break; - case RTOverLeftStrategyNumber: - retval = (bool) seg_over_left(key, query); - break; - case RTOverlapStrategyNumber: - retval = (bool) seg_overlap(key, query); - break; - case RTOverRightStrategyNumber: - retval = (bool) seg_over_right(key, query); - break; - case RTRightStrategyNumber: - retval = (bool) seg_right(key, query); - break; - case RTSameStrategyNumber: - retval = (bool) seg_same(key, query); - break; - case RTContainsStrategyNumber: - retval = (bool) seg_contains(key, query); - break; - case RTContainedByStrategyNumber: - retval = (bool) seg_contained(key, query); - break; - default: - retval = FALSE; - } - return (retval); -} - -bool -gseg_internal_consistent(SEG * key, - SEG * query, - StrategyNumber strategy) -{ - bool retval; - -#ifdef GIST_QUERY_DEBUG - fprintf(stderr, "internal_consistent, %d\n", strategy); -#endif - - switch (strategy) - { - case RTLeftStrategyNumber: - case RTOverLeftStrategyNumber: - retval = (bool) seg_over_left(key, query); - break; - case RTOverlapStrategyNumber: - retval = (bool) seg_overlap(key, query); - break; - case RTOverRightStrategyNumber: - case RTRightStrategyNumber: - retval = (bool) seg_right(key, query); - break; - case RTSameStrategyNumber: - case RTContainsStrategyNumber: - retval = (bool) seg_contains(key, query); - break; - case RTContainedByStrategyNumber: - retval = (bool) seg_overlap(key, query); - break; - default: - retval = FALSE; - } - return (retval); -} - -SEG * -gseg_binary_union(SEG * r1, SEG * r2, int *sizep) -{ - SEG *retval; - - retval = seg_union(r1, r2); - *sizep = sizeof(SEG); - - return (retval); -} - - -bool -seg_contains(SEG * a, SEG * b) -{ - return ((a->lower <= b->lower) && (a->upper >= b->upper)); -} - -bool -seg_contained(SEG * a, SEG * b) -{ - return (seg_contains(b, a)); -} - -/***************************************************************************** - * Operator class for R-tree indexing - *****************************************************************************/ - -bool -seg_same(SEG * a, SEG * b) -{ - return seg_cmp(a, b) == 0; -} - -/* seg_overlap -- does a overlap b? - */ -bool -seg_overlap(SEG * a, SEG * b) -{ - return ( - ((a->upper >= b->upper) && (a->lower <= b->upper)) - || - ((b->upper >= a->upper) && (b->lower <= a->upper)) - ); -} - -/* seg_overleft -- is the right edge of (a) located to the left of the right edge of (b)? - */ -bool -seg_over_left(SEG * a, SEG * b) -{ - return (a->upper <= b->upper && !seg_left(a, b) && !seg_right(a, b)); -} - -/* seg_left -- is (a) entirely on the left of (b)? - */ -bool -seg_left(SEG * a, SEG * b) -{ - return (a->upper < b->lower); -} - -/* seg_right -- is (a) entirely on the right of (b)? - */ -bool -seg_right(SEG * a, SEG * b) -{ - return (a->lower > b->upper); -} - -/* seg_overright -- is the left edge of (a) located to the right of the left edge of (b)? - */ -bool -seg_over_right(SEG * a, SEG * b) -{ - return (a->lower >= b->lower && !seg_left(a, b) && !seg_right(a, b)); -} - - -SEG * -seg_union(SEG * a, SEG * b) -{ - SEG *n; - - n = (SEG *) palloc(sizeof(*n)); - - /* take max of upper endpoints */ - if (a->upper > b->upper) - { - n->upper = a->upper; - n->u_sigd = a->u_sigd; - n->u_ext = a->u_ext; - } - else - { - n->upper = b->upper; - n->u_sigd = b->u_sigd; - n->u_ext = b->u_ext; - } - - /* take min of lower endpoints */ - if (a->lower < b->lower) - { - n->lower = a->lower; - n->l_sigd = a->l_sigd; - n->l_ext = a->l_ext; - } - else - { - n->lower = b->lower; - n->l_sigd = b->l_sigd; - n->l_ext = b->l_ext; - } - - return (n); -} - - -SEG * -seg_inter(SEG * a, SEG * b) -{ - SEG *n; - - n = (SEG *) palloc(sizeof(*n)); - - /* take min of upper endpoints */ - if (a->upper < b->upper) - { - n->upper = a->upper; - n->u_sigd = a->u_sigd; - n->u_ext = a->u_ext; - } - else - { - n->upper = b->upper; - n->u_sigd = b->u_sigd; - n->u_ext = b->u_ext; - } - - /* take max of lower endpoints */ - if (a->lower > b->lower) - { - n->lower = a->lower; - n->l_sigd = a->l_sigd; - n->l_ext = a->l_ext; - } - else - { - n->lower = b->lower; - n->l_sigd = b->l_sigd; - n->l_ext = b->l_ext; - } - - return (n); -} - -void -rt_seg_size(SEG * a, float *size) -{ - if (a == (SEG *) NULL || a->upper <= a->lower) - *size = 0.0; - else - *size = (float) abs(a->upper - a->lower); - - return; -} - -float * -seg_size(SEG * a) -{ - float *result; - - result = (float *) palloc(sizeof(float)); - - *result = (float) abs(a->upper - a->lower); - - return (result); -} - - -/***************************************************************************** - * Miscellaneous operators - *****************************************************************************/ -int32 -seg_cmp(SEG * a, SEG * b) -{ - /* - * First compare on lower boundary position - */ - if (a->lower < b->lower) - return -1; - if (a->lower > b->lower) - return 1; - - /* - * a->lower == b->lower, so consider type of boundary. - * - * A '-' lower bound is < any other kind (this could only be relevant if - * -HUGE is used as a regular data value). A '<' lower bound is < any - * other kind except '-'. A '>' lower bound is > any other kind. - */ - if (a->l_ext != b->l_ext) - { - if (a->l_ext == '-') - return -1; - if (b->l_ext == '-') - return 1; - if (a->l_ext == '<') - return -1; - if (b->l_ext == '<') - return 1; - if (a->l_ext == '>') - return 1; - if (b->l_ext == '>') - return -1; - } - - /* - * For other boundary types, consider # of significant digits first. - */ - if (a->l_sigd < b->l_sigd) /* (a) is blurred and is likely to include - * (b) */ - return -1; - if (a->l_sigd > b->l_sigd) /* (a) is less blurred and is likely to be - * included in (b) */ - return 1; - - /* - * For same # of digits, an approximate boundary is more blurred than - * exact. - */ - if (a->l_ext != b->l_ext) - { - if (a->l_ext == '~') /* (a) is approximate, while (b) is exact */ - return -1; - if (b->l_ext == '~') - return 1; - /* can't get here unless data is corrupt */ - elog(ERROR, "seg_cmp: bogus lower boundary types %d %d", - (int) a->l_ext, (int) b->l_ext); - } - - /* at this point, the lower boundaries are identical */ - - /* - * First compare on upper boundary position - */ - if (a->upper < b->upper) - return -1; - if (a->upper > b->upper) - return 1; - - /* - * a->upper == b->upper, so consider type of boundary. - * - * A '-' upper bound is > any other kind (this could only be relevant if - * HUGE is used as a regular data value). A '<' upper bound is < any - * other kind. A '>' upper bound is > any other kind except '-'. - */ - if (a->u_ext != b->u_ext) - { - if (a->u_ext == '-') - return 1; - if (b->u_ext == '-') - return -1; - if (a->u_ext == '<') - return -1; - if (b->u_ext == '<') - return 1; - if (a->u_ext == '>') - return 1; - if (b->u_ext == '>') - return -1; - } - - /* - * For other boundary types, consider # of significant digits first. - * Note result here is converse of the lower-boundary case. - */ - if (a->u_sigd < b->u_sigd) /* (a) is blurred and is likely to include - * (b) */ - return 1; - if (a->u_sigd > b->u_sigd) /* (a) is less blurred and is likely to be - * included in (b) */ - return -1; - - /* - * For same # of digits, an approximate boundary is more blurred than - * exact. Again, result is converse of lower-boundary case. - */ - if (a->u_ext != b->u_ext) - { - if (a->u_ext == '~') /* (a) is approximate, while (b) is exact */ - return 1; - if (b->u_ext == '~') - return -1; - /* can't get here unless data is corrupt */ - elog(ERROR, "seg_cmp: bogus upper boundary types %d %d", - (int) a->u_ext, (int) b->u_ext); - } - - return 0; -} - -bool -seg_lt(SEG * a, SEG * b) -{ - return seg_cmp(a, b) < 0; -} - -bool -seg_le(SEG * a, SEG * b) -{ - return seg_cmp(a, b) <= 0; -} - -bool -seg_gt(SEG * a, SEG * b) -{ - return seg_cmp(a, b) > 0; -} - - -bool -seg_ge(SEG * a, SEG * b) -{ - return seg_cmp(a, b) >= 0; -} - -bool -seg_different(SEG * a, SEG * b) -{ - return seg_cmp(a, b) != 0; -} - - - -/***************************************************************************** - * Auxiliary functions - *****************************************************************************/ - -/* The purpose of this routine is to print the floating point - * value with exact number of significant digits. Its behaviour - * is similar to %.ng except it prints 8.00 where %.ng would - * print 8 - */ -static int -restore(char *result, float val, int n) -{ - static char efmt[8] = {'%', '-', '1', '5', '.', '#', 'e', 0}; - char buf[25] = { - '0', '0', '0', '0', '0', - '0', '0', '0', '0', '0', - '0', '0', '0', '0', '0', - '0', '0', '0', '0', '0', - '0', '0', '0', '0', '\0' - }; - char *p; - char *mant; - int exp; - int i, - dp, - sign; - - /* - * put a cap on the number of siugnificant digits to avoid nonsense in - * the output - */ - n = min(n, FLT_DIG); - - /* remember the sign */ - sign = (val < 0 ? 1 : 0); - - efmt[5] = '0' + (n - 1) % 10; /* makes %-15.(n-1)e -- this - * format guarantees that the - * exponent is always present */ - - sprintf(result, efmt, val); - - /* trim the spaces left by the %e */ - for (p = result; *p != ' '; p++); - *p = '\0'; - - /* get the exponent */ - mant = (char *) strtok(strdup(result), "e"); - exp = atoi(strtok(NULL, "e")); - - if (exp == 0) - { - /* use the supplied mantyssa with sign */ - strcpy((char *) index(result, 'e'), ""); - } - else - { - if (abs(exp) <= 4) - { - /* - * remove the decimal point from the mantyssa and write the - * digits to the buf array - */ - for (p = result + sign, i = 10, dp = 0; *p != 'e'; p++, i++) - { - buf[i] = *p; - if (*p == '.') - { - dp = i--; /* skip the decimal point */ - } - } - if (dp == 0) - dp = i--; /* no decimal point was found in the above - * for() loop */ - - if (exp > 0) - { - if (dp - 10 + exp >= n) - { - /* - * the decimal point is behind the last significant - * digit; the digits in between must be converted to - * the exponent and the decimal point placed after the - * first digit - */ - exp = dp - 10 + exp - n; - buf[10 + n] = '\0'; - - /* insert the decimal point */ - if (n > 1) - { - dp = 11; - for (i = 23; i > dp; i--) - buf[i] = buf[i - 1]; - buf[dp] = '.'; - } - - /* - * adjust the exponent by the number of digits after - * the decimal point - */ - if (n > 1) - sprintf(&buf[11 + n], "e%d", exp + n - 1); - else - sprintf(&buf[11], "e%d", exp + n - 1); - - if (sign) - { - buf[9] = '-'; - strcpy(result, &buf[9]); - } - else - strcpy(result, &buf[10]); - } - else - { /* insert the decimal point */ - dp += exp; - for (i = 23; i > dp; i--) - buf[i] = buf[i - 1]; - buf[11 + n] = '\0'; - buf[dp] = '.'; - if (sign) - { - buf[9] = '-'; - strcpy(result, &buf[9]); - } - else - strcpy(result, &buf[10]); - } - } - else - { /* exp <= 0 */ - dp += exp - 1; - buf[10 + n] = '\0'; - buf[dp] = '.'; - if (sign) - { - buf[dp - 2] = '-'; - strcpy(result, &buf[dp - 2]); - } - else - strcpy(result, &buf[dp - 1]); - } - } - - /* do nothing for abs(exp) > 4; %e must be OK */ - /* just get rid of zeroes after [eE]- and +zeroes after [Ee]. */ - - /* ... this is not done yet. */ - } - return (strlen(result)); -} - - -/* -** Miscellany -*/ - -bool -seg_contains_int(SEG * a, int *b) -{ - return ((a->lower <= *b) && (a->upper >= *b)); -} - -bool -seg_contains_float4(SEG * a, float4 *b) -{ - return ((a->lower <= *b) && (a->upper >= *b)); -} - -bool -seg_contains_float8(SEG * a, float8 *b) -{ - return ((a->lower <= *b) && (a->upper >= *b)); -} - -/* find out the number of significant digits in a string representing - * a floating point number - */ -int -significant_digits(char *s) -{ - char *p = s; - int n, - c, - zeroes; - - zeroes = 1; - /* skip leading zeroes and sign */ - for (c = *p; (c == '0' || c == '+' || c == '-') && c != 0; c = *(++p)); - - /* skip decimal point and following zeroes */ - for (c = *p; (c == '0' || c == '.') && c != 0; c = *(++p)) - { - if (c != '.') - zeroes++; - } - - /* count significant digits (n) */ - for (c = *p, n = 0; c != 0; c = *(++p)) - { - if (!((c >= '0' && c <= '9') || (c == '.'))) - break; - if (c != '.') - n++; - } - - if (!n) - return (zeroes); - - return (n); -} diff --git a/contrib/seg/seg.sql.in b/contrib/seg/seg.sql.in deleted file mode 100644 index f8acddeb35..0000000000 --- a/contrib/seg/seg.sql.in +++ /dev/null @@ -1,396 +0,0 @@ --- Create the user-defined type for 1-D floating point intervals (seg) --- -BEGIN TRANSACTION; - -CREATE FUNCTION seg_in(opaque) -RETURNS opaque -AS 'MODULE_PATHNAME' -LANGUAGE 'c'; - -CREATE FUNCTION seg_out(opaque) -RETURNS opaque -AS 'MODULE_PATHNAME' -LANGUAGE 'c'; - -CREATE TYPE seg ( -internallength = 12, -input = seg_in, -output = seg_out -); - -COMMENT ON TYPE seg IS -'floating point interval ''FLOAT .. FLOAT'', ''.. FLOAT'', ''FLOAT ..'' or ''FLOAT'''; - --- --- External C-functions for R-tree methods --- - --- Left/Right methods - -CREATE FUNCTION seg_over_left(seg, seg) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION seg_over_left(seg, seg) IS -'is over and left of'; - -CREATE FUNCTION seg_over_right(seg, seg) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION seg_over_right(seg, seg) IS -'is over and right of'; - -CREATE FUNCTION seg_left(seg, seg) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION seg_left(seg, seg) IS -'is left of'; - -CREATE FUNCTION seg_right(seg, seg) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION seg_right(seg, seg) IS -'is right of'; - - --- Comparison methods - -CREATE FUNCTION seg_lt(seg, seg) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION seg_lt(seg, seg) IS -'less than'; - -CREATE FUNCTION seg_le(seg, seg) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION seg_le(seg, seg) IS -'less than or equal'; - -CREATE FUNCTION seg_gt(seg, seg) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION seg_gt(seg, seg) IS -'greater than'; - -CREATE FUNCTION seg_ge(seg, seg) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION seg_ge(seg, seg) IS -'greater than or equal'; - -CREATE FUNCTION seg_contains(seg, seg) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION seg_contains(seg, seg) IS -'contains'; - -CREATE FUNCTION seg_contained(seg, seg) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION seg_contained(seg, seg) IS -'contained in'; - -CREATE FUNCTION seg_overlap(seg, seg) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION seg_overlap(seg, seg) IS -'overlaps'; - -CREATE FUNCTION seg_same(seg, seg) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION seg_same(seg, seg) IS -'same as'; - -CREATE FUNCTION seg_different(seg, seg) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION seg_different(seg, seg) IS -'different'; - --- support routines for indexing - -CREATE FUNCTION seg_union(seg, seg) RETURNS seg - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -CREATE FUNCTION seg_inter(seg, seg) RETURNS seg - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -CREATE FUNCTION seg_size(seg) RETURNS float4 - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - --- miscellaneous - -CREATE FUNCTION seg_upper(seg) RETURNS float4 - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -CREATE FUNCTION seg_lower(seg) RETURNS float4 - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - - --- --- OPERATORS --- - -CREATE OPERATOR < ( - LEFTARG = seg, RIGHTARG = seg, PROCEDURE = seg_lt, - COMMUTATOR = '>', NEGATOR = '>=', - RESTRICT = scalarltsel, JOIN = scalarltjoinsel -); - -CREATE OPERATOR <= ( - LEFTARG = seg, RIGHTARG = seg, PROCEDURE = seg_le, - COMMUTATOR = '>=', NEGATOR = '>', - RESTRICT = scalarltsel, JOIN = scalarltjoinsel -); - -CREATE OPERATOR > ( - LEFTARG = seg, RIGHTARG = seg, PROCEDURE = seg_gt, - COMMUTATOR = '<', NEGATOR = '<=', - RESTRICT = scalargtsel, JOIN = scalargtjoinsel -); - -CREATE OPERATOR >= ( - LEFTARG = seg, RIGHTARG = seg, PROCEDURE = seg_ge, - COMMUTATOR = '<=', NEGATOR = '<', - RESTRICT = scalargtsel, JOIN = scalargtjoinsel -); - -CREATE OPERATOR << ( - LEFTARG = seg, RIGHTARG = seg, PROCEDURE = seg_left, - COMMUTATOR = '>>', - RESTRICT = positionsel, JOIN = positionjoinsel -); - -CREATE OPERATOR &< ( - LEFTARG = seg, RIGHTARG = seg, PROCEDURE = seg_over_left, - COMMUTATOR = '&>', - RESTRICT = positionsel, JOIN = positionjoinsel -); - -CREATE OPERATOR && ( - LEFTARG = seg, RIGHTARG = seg, PROCEDURE = seg_overlap, - COMMUTATOR = '&&', - RESTRICT = positionsel, JOIN = positionjoinsel -); - -CREATE OPERATOR &> ( - LEFTARG = seg, RIGHTARG = seg, PROCEDURE = seg_over_right, - COMMUTATOR = '&<', - RESTRICT = positionsel, JOIN = positionjoinsel -); - -CREATE OPERATOR >> ( - LEFTARG = seg, RIGHTARG = seg, PROCEDURE = seg_right, - COMMUTATOR = '<<', - RESTRICT = positionsel, JOIN = positionjoinsel -); - -CREATE OPERATOR = ( - LEFTARG = seg, RIGHTARG = seg, PROCEDURE = seg_same, - COMMUTATOR = '=', NEGATOR = '<>', - RESTRICT = eqsel, JOIN = eqjoinsel, - SORT1 = '<', SORT2 = '<' -); - -CREATE OPERATOR <> ( - LEFTARG = seg, RIGHTARG = seg, PROCEDURE = seg_different, - COMMUTATOR = '<>', NEGATOR = '=', - RESTRICT = neqsel, JOIN = neqjoinsel -); - -CREATE OPERATOR @ ( - LEFTARG = seg, RIGHTARG = seg, PROCEDURE = seg_contains, - COMMUTATOR = '~', - RESTRICT = contsel, JOIN = contjoinsel -); - -CREATE OPERATOR ~ ( - LEFTARG = seg, RIGHTARG = seg, PROCEDURE = seg_contained, - COMMUTATOR = '@', - RESTRICT = contsel, JOIN = contjoinsel -); - - --- define the GiST support methods -CREATE FUNCTION gseg_consistent(opaque,seg,int4) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION gseg_compress(opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION gseg_decompress(opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION gseg_penalty(opaque,opaque,opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -CREATE FUNCTION gseg_picksplit(opaque, opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION gseg_union(bytea, opaque) RETURNS seg - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION gseg_same(seg, seg, 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_seg_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 = 'seg'), - true, - 0); - - --- get the comparators for segments and store them in a tmp table -SELECT o.oid AS opoid, o.oprname -INTO TEMP TABLE seg_ops_tmp -FROM pg_operator o, pg_type t -WHERE o.oprleft = t.oid and o.oprright = t.oid - and t.typname = 'seg'; - --- make sure we have the right operators --- SELECT * from seg_ops_tmp; - --- using the tmp table, generate the amop entries - --- seg_left -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 1, false, c.opoid - FROM pg_opclass opcl, seg_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_seg_ops' - and c.oprname = '<<'; - --- seg_overleft -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 2, false, c.opoid - FROM pg_opclass opcl, seg_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_seg_ops' - and c.oprname = '&<'; - --- seg_overlap -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 3, false, c.opoid - FROM pg_opclass opcl, seg_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_seg_ops' - and c.oprname = '&&'; - --- seg_overright -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 4, false, c.opoid - FROM pg_opclass opcl, seg_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_seg_ops' - and c.oprname = '&>'; - --- seg_right -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 5, false, c.opoid - FROM pg_opclass opcl, seg_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_seg_ops' - and c.oprname = '>>'; - --- seg_same -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 6, false, c.opoid - FROM pg_opclass opcl, seg_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_seg_ops' - and c.oprname = '='; - --- seg_contains -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 7, false, c.opoid - FROM pg_opclass opcl, seg_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_seg_ops' - and c.oprname = '@'; - --- seg_contained -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 8, false, c.opoid - FROM pg_opclass opcl, seg_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_seg_ops' - and c.oprname = '~'; - -DROP TABLE seg_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_seg_ops' - and proname = 'gseg_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_seg_ops' - and proname = 'gseg_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_seg_ops' - and proname = 'gseg_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_seg_ops' - and proname = 'gseg_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_seg_ops' - and proname = 'gseg_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_seg_ops' - and proname = 'gseg_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_seg_ops' - and proname = 'gseg_same'; - -END TRANSACTION; diff --git a/contrib/seg/segdata.h b/contrib/seg/segdata.h deleted file mode 100644 index 69d85e0bc0..0000000000 --- a/contrib/seg/segdata.h +++ /dev/null @@ -1,9 +0,0 @@ -typedef struct SEG -{ - float lower; - float upper; - char l_sigd; - char u_sigd; - char l_ext; - char u_ext; -} SEG; diff --git a/contrib/seg/segparse.y b/contrib/seg/segparse.y deleted file mode 100644 index 3c2d6c28c0..0000000000 --- a/contrib/seg/segparse.y +++ /dev/null @@ -1,187 +0,0 @@ -%{ -#define YYERROR_VERBOSE -#define YYPARSE_PARAM result /* need this to pass a pointer (void *) to yyparse */ - -#include -#include -#include -#include "segdata.h" -#include "buffer.h" - -#include "postgres.h" -#include "utils/elog.h" - -#ifdef __CYGWIN__ -#define HUGE HUGE_VAL -#endif /* __CYGWIN__ */ - -#undef yylex /* falure to redefine yylex will result in calling the */ -#define yylex seg_yylex /* wrong scanner when running inside postgres backend */ - - extern int errno; - extern int yylex(); /* defined as seg_yylex in segscan.c */ - extern int significant_digits( char *str ); /* defined in seg.c */ - - int seg_yyerror( char *msg ); - int seg_yyparse( void *result ); - - float seg_atof( char *value ); - -#define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) -#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) -#define ABS(X) ((X) < 0 ? (-X) : (X)) - - long threshold; - char strbuf[25] = { - '0', '0', '0', '0', '0', - '0', '0', '0', '0', '0', - '0', '0', '0', '0', '0', - '0', '0', '0', '0', '0', - '0', '0', '0', '0', '\0' - }; - -%} - -/* BISON Declarations */ -%union { - struct BND { - float val; - char ext; - char sigd; - } bnd; - char * text; -} -%token FLOAT -%token RANGE -%token PLUMIN -%token EXTENSION -%type boundary -%type deviation -%start range - -/* Grammar follows */ -%% - - -range: - boundary PLUMIN deviation { - ((SEG *)result)->lower = $1.val - $3.val; - ((SEG *)result)->upper = $1.val + $3.val; - sprintf(strbuf, "%g", ((SEG *)result)->lower); - ((SEG *)result)->l_sigd = MAX(MIN(6, significant_digits(strbuf)), MAX($1.sigd, $3.sigd)); - sprintf(strbuf, "%g", ((SEG *)result)->upper); - ((SEG *)result)->u_sigd = MAX(MIN(6, significant_digits(strbuf)), MAX($1.sigd, $3.sigd)); - ((SEG *)result)->l_ext = '\0'; - ((SEG *)result)->u_ext = '\0'; - } - | - boundary RANGE boundary { - ((SEG *)result)->lower = $1.val; - ((SEG *)result)->upper = $3.val; - if ( ((SEG *)result)->lower > ((SEG *)result)->upper ) { - reset_parse_buffer(); - elog(ERROR, "swapped boundaries: %g is greater than %g", ((SEG *)result)->lower, ((SEG *)result)->upper ); - YYERROR; - } - ((SEG *)result)->l_sigd = $1.sigd; - ((SEG *)result)->u_sigd = $3.sigd; - ((SEG *)result)->l_ext = ( $1.ext ? $1.ext : '\0' ); - ((SEG *)result)->u_ext = ( $3.ext ? $3.ext : '\0' ); - } - | - boundary RANGE { - ((SEG *)result)->lower = $1.val; - ((SEG *)result)->upper = HUGE; - ((SEG *)result)->l_sigd = $1.sigd; - ((SEG *)result)->u_sigd = 0; - ((SEG *)result)->l_ext = ( $1.ext ? $1.ext : '\0' ); - ((SEG *)result)->u_ext = '-'; - } - ; - | - RANGE boundary { - ((SEG *)result)->lower = -HUGE; - ((SEG *)result)->upper = $2.val; - ((SEG *)result)->l_sigd = 0; - ((SEG *)result)->u_sigd = $2.sigd; - ((SEG *)result)->l_ext = '-'; - ((SEG *)result)->u_ext = ( $2.ext ? $2.ext : '\0' ); - } - | - boundary { - ((SEG *)result)->lower = ((SEG *)result)->upper = $1.val; - ((SEG *)result)->l_sigd = ((SEG *)result)->u_sigd = $1.sigd; - ((SEG *)result)->l_ext = ((SEG *)result)->u_ext = ( $1.ext ? $1.ext : '\0' ); - } - ; - -boundary: - FLOAT { - $$.ext = '\0'; - $$.sigd = significant_digits($1); - $$.val = seg_atof($1); - } - | - EXTENSION FLOAT { - $$.ext = $1[0]; - $$.sigd = significant_digits($2); - $$.val = seg_atof($2); - } - ; - -deviation: - FLOAT { - $$.ext = '\0'; - $$.sigd = significant_digits($1); - $$.val = seg_atof($1); - } - ; - -%% - - -float seg_atof ( char *value ) { - float result; - char *buf = (char *) palloc(256); - - errno = 0; - sscanf(value, "%f", &result); - - if ( errno ) { - sprintf(buf, "numeric value %s unrepresentable", value); - reset_parse_buffer(); - elog(ERROR, buf); - } - - return result; -} - - -int seg_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 near 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; -} - - diff --git a/contrib/seg/segscan.l b/contrib/seg/segscan.l deleted file mode 100644 index ea9032685a..0000000000 --- a/contrib/seg/segscan.l +++ /dev/null @@ -1,53 +0,0 @@ -%{ -/* -** A scanner for EMP-style numeric ranges -*/ - -#include -#include -#include "segparse.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 seg_yylex YY_PROTO(( void )); \ -int seg_yylex YY_PROTO(( void )) -#define yylval seg_yylval - -/* 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 seg_flush_scanner_buffer(void); -%} - -range (\.\.)(\.)? -plumin (\'\+\-\')|(\(\+\-)\) -integer [+-]?[0-9]+ -real [+-]?[0-9]+\.[0-9]+ -float ({integer}|{real})([eE]{integer})? - -%% - -{range} yylval.text = yytext; return RANGE; -{plumin} yylval.text = yytext; return PLUMIN; -{float} yylval.text = yytext; return FLOAT; -\< yylval.text = "<"; return EXTENSION; -\> yylval.text = ">"; return EXTENSION; -\~ yylval.text = "~"; return EXTENSION; -[ ]+ /* discard spaces */ -. return yytext[0]; /* alert parser of the garbage */ - -%% - -int seg_yylex(); - -void seg_flush_scanner_buffer(void) { - YY_FLUSH_BUFFER; -} diff --git a/contrib/seg/sort-segments.pl b/contrib/seg/sort-segments.pl deleted file mode 100755 index 1205d3b972..0000000000 --- a/contrib/seg/sort-segments.pl +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/perl - -# this script will sort any table with the segment data type in its last column - -while (<>) { - chomp; - push @rows, $_; -} - -foreach ( sort { - @ar = split("\t", $a); - $valA = pop @ar; - $valA =~ s/[~<> ]+//g; - @ar = split("\t", $b); - $valB = pop @ar; - $valB =~ s/[~<> ]+//g; - $valA <=> $valB -} @rows ) { - print "$_\n";; -} diff --git a/contrib/seg/sql/seg.sql b/contrib/seg/sql/seg.sql deleted file mode 100644 index 95394c95d0..0000000000 --- a/contrib/seg/sql/seg.sql +++ /dev/null @@ -1,223 +0,0 @@ --- --- Test seg datatype --- - --- --- first, define the datatype. Turn off echoing so that expected file --- does not depend on contents of seg.sql. --- -\set ECHO none -\i seg.sql -\set ECHO all - --- --- testing the input and output functions --- - --- Any number -SELECT '1'::seg AS seg; -SELECT '-1'::seg AS seg; -SELECT '1.0'::seg AS seg; -SELECT '-1.0'::seg AS seg; -SELECT '1e7'::seg AS seg; -SELECT '-1e7'::seg AS seg; -SELECT '1.0e7'::seg AS seg; -SELECT '-1.0e7'::seg AS seg; -SELECT '1e+7'::seg AS seg; -SELECT '-1e+7'::seg AS seg; -SELECT '1.0e+7'::seg AS seg; -SELECT '-1.0e+7'::seg AS seg; -SELECT '1e-7'::seg AS seg; -SELECT '-1e-7'::seg AS seg; -SELECT '1.0e-7'::seg AS seg; -SELECT '-1.0e-7'::seg AS seg; -SELECT '2e-6'::seg AS seg; -SELECT '2e-5'::seg AS seg; -SELECT '2e-4'::seg AS seg; -SELECT '2e-3'::seg AS seg; -SELECT '2e-2'::seg AS seg; -SELECT '2e-1'::seg AS seg; -SELECT '2e-0'::seg AS seg; -SELECT '2e+0'::seg AS seg; -SELECT '2e+1'::seg AS seg; -SELECT '2e+2'::seg AS seg; -SELECT '2e+3'::seg AS seg; -SELECT '2e+4'::seg AS seg; -SELECT '2e+5'::seg AS seg; -SELECT '2e+6'::seg AS seg; - - --- Significant digits preserved -SELECT '1'::seg AS seg; -SELECT '1.0'::seg AS seg; -SELECT '1.00'::seg AS seg; -SELECT '1.000'::seg AS seg; -SELECT '1.0000'::seg AS seg; -SELECT '1.00000'::seg AS seg; -SELECT '1.000000'::seg AS seg; -SELECT '0.000000120'::seg AS seg; -SELECT '3.400e5'::seg AS seg; - --- Digits truncated -SELECT '12.34567890123456'::seg AS seg; - --- Numbers with certainty indicators -SELECT '~6.5'::seg AS seg; -SELECT '<6.5'::seg AS seg; -SELECT '>6.5'::seg AS seg; -SELECT '~ 6.5'::seg AS seg; -SELECT '< 6.5'::seg AS seg; -SELECT '> 6.5'::seg AS seg; - --- Open intervals -SELECT '0..'::seg AS seg; -SELECT '0...'::seg AS seg; -SELECT '0 ..'::seg AS seg; -SELECT '0 ...'::seg AS seg; -SELECT '..0'::seg AS seg; -SELECT '...0'::seg AS seg; -SELECT '.. 0'::seg AS seg; -SELECT '... 0'::seg AS seg; - --- Finite intervals -SELECT '0 .. 1'::seg AS seg; -SELECT '-1 .. 0'::seg AS seg; -SELECT '-1 .. 1'::seg AS seg; - --- (+/-) intervals -SELECT '0(+-)1'::seg AS seg; -SELECT '0(+-)1.0'::seg AS seg; -SELECT '1.0(+-)0.005'::seg AS seg; -SELECT '101(+-)1'::seg AS seg; --- incorrect number of significant digits in 99.0: -SELECT '100(+-)1'::seg AS seg; - --- invalid input -SELECT ''::seg AS seg; -SELECT 'ABC'::seg AS seg; -SELECT '1ABC'::seg AS seg; -SELECT '1.'::seg AS seg; -SELECT '1.....'::seg AS seg; -SELECT '.1'::seg AS seg; -SELECT '1..2.'::seg AS seg; -SELECT '1 e7'::seg AS seg; -SELECT '1e700'::seg AS seg; - --- --- testing the operators --- - --- equality/inequality: --- -SELECT '24 .. 33.20'::seg = '24 .. 33.20'::seg AS bool; -SELECT '24 .. 33.20'::seg = '24 .. 33.21'::seg AS bool; -SELECT '24 .. 33.20'::seg != '24 .. 33.20'::seg AS bool; -SELECT '24 .. 33.20'::seg != '24 .. 33.21'::seg AS bool; - --- overlap --- -SELECT '1'::seg && '1'::seg AS bool; -SELECT '1'::seg && '2'::seg AS bool; -SELECT '0 ..'::seg && '0 ..'::seg AS bool; -SELECT '0 .. 1'::seg && '0 .. 1'::seg AS bool; -SELECT '..0'::seg && '0..'::seg AS bool; -SELECT '-1 .. 0.1'::seg && '0 .. 1'::seg AS bool; -SELECT '-1 .. 0'::seg && '0 .. 1'::seg AS bool; -SELECT '-1 .. -0.0001'::seg && '0 .. 1'::seg AS bool; -SELECT '0 ..'::seg && '1'::seg AS bool; -SELECT '0 .. 1'::seg && '1'::seg AS bool; -SELECT '0 .. 1'::seg && '2'::seg AS bool; -SELECT '0 .. 2'::seg && '1'::seg AS bool; -SELECT '1'::seg && '0 .. 1'::seg AS bool; -SELECT '2'::seg && '0 .. 1'::seg AS bool; -SELECT '1'::seg && '0 .. 2'::seg AS bool; - --- overlap on the left --- -SELECT '1'::seg &< '0'::seg AS bool; -SELECT '1'::seg &< '1'::seg AS bool; -SELECT '1'::seg &< '2'::seg AS bool; -SELECT '0 .. 1'::seg &< '0'::seg AS bool; -SELECT '0 .. 1'::seg &< '1'::seg AS bool; -SELECT '0 .. 1'::seg &< '2'::seg AS bool; -SELECT '0 .. 1'::seg &< '0 .. 0.5'::seg AS bool; -SELECT '0 .. 1'::seg &< '0 .. 1'::seg AS bool; -SELECT '0 .. 1'::seg &< '0 .. 2'::seg AS bool; -SELECT '0 .. 1'::seg &< '1 .. 2'::seg AS bool; -SELECT '0 .. 1'::seg &< '2 .. 3'::seg AS bool; - --- overlap on the right --- -SELECT '0'::seg &> '1'::seg AS bool; -SELECT '1'::seg &> '1'::seg AS bool; -SELECT '2'::seg &> '1'::seg AS bool; -SELECT '0'::seg &> '0 .. 1'::seg AS bool; -SELECT '1'::seg &> '0 .. 1'::seg AS bool; -SELECT '2'::seg &> '0 .. 1'::seg AS bool; -SELECT '0 .. 0.5'::seg &> '0 .. 1'::seg AS bool; -SELECT '0 .. 1'::seg &> '0 .. 1'::seg AS bool; -SELECT '0 .. 2'::seg &> '0 .. 2'::seg AS bool; -SELECT '1 .. 2'::seg &> '0 .. 1'::seg AS bool; -SELECT '2 .. 3'::seg &> '0 .. 1'::seg AS bool; - --- left --- -SELECT '1'::seg << '0'::seg AS bool; -SELECT '1'::seg << '1'::seg AS bool; -SELECT '1'::seg << '2'::seg AS bool; -SELECT '0 .. 1'::seg << '0'::seg AS bool; -SELECT '0 .. 1'::seg << '1'::seg AS bool; -SELECT '0 .. 1'::seg << '2'::seg AS bool; -SELECT '0 .. 1'::seg << '0 .. 0.5'::seg AS bool; -SELECT '0 .. 1'::seg << '0 .. 1'::seg AS bool; -SELECT '0 .. 1'::seg << '0 .. 2'::seg AS bool; -SELECT '0 .. 1'::seg << '1 .. 2'::seg AS bool; -SELECT '0 .. 1'::seg << '2 .. 3'::seg AS bool; - --- right --- -SELECT '0'::seg >> '1'::seg AS bool; -SELECT '1'::seg >> '1'::seg AS bool; -SELECT '2'::seg >> '1'::seg AS bool; -SELECT '0'::seg >> '0 .. 1'::seg AS bool; -SELECT '1'::seg >> '0 .. 1'::seg AS bool; -SELECT '2'::seg >> '0 .. 1'::seg AS bool; -SELECT '0 .. 0.5'::seg >> '0 .. 1'::seg AS bool; -SELECT '0 .. 1'::seg >> '0 .. 1'::seg AS bool; -SELECT '0 .. 2'::seg >> '0 .. 2'::seg AS bool; -SELECT '1 .. 2'::seg >> '0 .. 1'::seg AS bool; -SELECT '2 .. 3'::seg >> '0 .. 1'::seg AS bool; - - --- "contained in" (the left value belongs within the interval specified in the right value): --- -SELECT '0'::seg ~ '0'::seg AS bool; -SELECT '0'::seg ~ '0 ..'::seg AS bool; -SELECT '0'::seg ~ '.. 0'::seg AS bool; -SELECT '0'::seg ~ '-1 .. 1'::seg AS bool; -SELECT '0'::seg ~ '-1 .. 1'::seg AS bool; -SELECT '-1'::seg ~ '-1 .. 1'::seg AS bool; -SELECT '1'::seg ~ '-1 .. 1'::seg AS bool; -SELECT '-1 .. 1'::seg ~ '-1 .. 1'::seg AS bool; - --- "contains" (the left value contains the interval specified in the right value): --- -SELECT '0'::seg @ '0'::seg AS bool; -SELECT '0 .. '::seg ~ '0'::seg AS bool; -SELECT '.. 0'::seg ~ '0'::seg AS bool; -SELECT '-1 .. 1'::seg ~ '0'::seg AS bool; -SELECT '0'::seg ~ '-1 .. 1'::seg AS bool; -SELECT '-1'::seg ~ '-1 .. 1'::seg AS bool; -SELECT '1'::seg ~ '-1 .. 1'::seg AS bool; - --- Load some example data and build the index --- -CREATE TABLE test_seg (s seg); - -\copy test_seg from 'data/test_seg.data' - -CREATE INDEX test_seg_ix ON test_seg USING gist (s); -SELECT count(*) FROM test_seg WHERE s @ '11..11.3'; - --- Test sorting -SELECT * FROM test_seg WHERE s @ '11..11.3' GROUP BY s; diff --git a/contrib/spi/Makefile b/contrib/spi/Makefile deleted file mode 100644 index cf4c0d1dbf..0000000000 --- a/contrib/spi/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/spi/Makefile,v 1.21 2001/09/06 10:49:30 petere Exp $ - -subdir = contrib/spi -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -MODULES = autoinc insert_username moddatetime refint timetravel -DATA_built = $(addsuffix .sql, $(MODULES)) -DOCS = README.spi $(addsuffix .example, $(MODULES)) - -ifdef REFINT_VERBOSE -PG_CPPFLAGS = -DREFINT_VERBOSE -endif - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/spi/README.spi b/contrib/spi/README.spi deleted file mode 100644 index 65868f0fc7..0000000000 --- a/contrib/spi/README.spi +++ /dev/null @@ -1,104 +0,0 @@ - -Here are general trigger functions provided as workable examples -of using SPI and triggers. "General" means that functions may be -used for defining triggers for any tables but you have to specify -table/field names (as described below) while creating a trigger. - -1. refint.c - functions for implementing referential integrity. - -check_primary_key () is to used for foreign keys of a table. - - You are to create trigger (BEFORE INSERT OR UPDATE) using this -function on a table referencing another table. You are to specify -as function arguments: triggered table column names which correspond -to foreign key, referenced table name and column names in referenced -table which correspond to primary/unique key. - You may create as many triggers as you need - one trigger for -one reference. - -check_foreign_key () is to used for primary/unique keys of a table. - - You are to create trigger (BEFORE DELETE OR UPDATE) using this -function on a table referenced by another table(s). You are to specify -as function arguments: number of references for which function has to -performe checking, action if referencing key found ('cascade' - to delete -corresponding foreign key, 'restrict' - to abort transaction if foreign keys -exist, 'setnull' - to set foreign key referencing primary/unique key -being deleted to null), triggered table column names which correspond -to primary/unique key, referencing table name and column names corresponding -to foreign key (, ... - as many referencing tables/keys as specified -by first argument). - Note, that NOT NULL constraint and unique index have to be defined by -youself. - - There are examples in refint.example and regression tests -(sql/triggers.sql). - - To CREATE FUNCTIONs use refint.sql (will be made by gmake from -refint.source). - - -2. timetravel.c - functions for implementing time travel feature. - - Old internally supported time-travel (TT) used insert/delete -transaction commit times. To get the same feature using triggers -you are to add to a table two columns of abstime type to store -date when a tuple was inserted (start_date) and changed/deleted -(stop_date): - -CREATE TABLE XXX ( - ... ... - date_on abstime default currabstime(), - date_off abstime default 'infinity' - ... ... -); - -- so, tuples being inserted with NULLs in date_on/date_off will get -_current_date_ in date_on (name of start_date column in XXX) and INFINITY in -date_off (name of stop_date column in XXX). - - Tuples with stop_date equal INFINITY are "valid now": when trigger will -be fired for UPDATE/DELETE of a tuple with stop_date NOT equal INFINITY then -this tuple will not be changed/deleted! - - If stop_date equal INFINITY then on - -UPDATE: only stop_date in tuple being updated will be changed to current -date and new tuple with new data (coming from SET ... in UPDATE) will be -inserted. Start_date in this new tuple will be setted to current date and -stop_date - to INFINITY. - -DELETE: new tuple will be inserted with stop_date setted to current date -(and with the same data in other columns as in tuple being deleted). - - NOTE: -1. To get tuples "valid now" you are to add _stop_date_ = 'infinity' - to WHERE. Internally supported TT allowed to avoid this... - Fixed rewriting RULEs could help here... - As work arround you may use VIEWs... -2. You can't change start/stop date columns with UPDATE! - Use set_timetravel (below) if you need in this. - - FUNCTIONs: - -timetravel() is general trigger function. - - You are to create trigger BEFORE (!!!) UPDATE OR DELETE using this -function on a time-traveled table. You are to specify two arguments: name of -start_date column and name of stop_date column in triggered table. - -currabstime() may be used in DEFAULT for start_date column to get -current date. - -set_timetravel() allows you turn time-travel ON/OFF for a table: - - set_timetravel('XXX', 1) will turn TT ON for table XXX (and report -old status). - set_timetravel('XXX', 0) will turn TT OFF for table XXX (-"-). - -Turning TT OFF allows you do with a table ALL what you want. - - There is example in timetravel.example. - - To CREATE FUNCTIONs use timetravel.sql (will be made by gmake from -timetravel.source). diff --git a/contrib/spi/autoinc.c b/contrib/spi/autoinc.c deleted file mode 100644 index 92d3e97c22..0000000000 --- a/contrib/spi/autoinc.c +++ /dev/null @@ -1,107 +0,0 @@ - -#include "executor/spi.h" /* this is what you need to work with SPI */ -#include "commands/trigger.h" /* -"- and triggers */ -#include "commands/sequence.h" /* for nextval() */ - -extern Datum autoinc(PG_FUNCTION_ARGS); - -PG_FUNCTION_INFO_V1(autoinc); - -Datum -autoinc(PG_FUNCTION_ARGS) -{ - TriggerData *trigdata = (TriggerData *) fcinfo->context; - Trigger *trigger; /* to get trigger name */ - int nargs; /* # of arguments */ - int *chattrs; /* attnums of attributes to change */ - int chnattrs = 0; /* # of above */ - Datum *newvals; /* vals of above */ - char **args; /* arguments */ - char *relname; /* triggered relation name */ - Relation rel; /* triggered relation */ - HeapTuple rettuple = NULL; - TupleDesc tupdesc; /* tuple description */ - bool isnull; - int i; - - if (!CALLED_AS_TRIGGER(fcinfo)) - elog(ERROR, "autoinc: not fired by trigger manager"); - if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) - elog(ERROR, "autoinc: can't process STATEMENT events"); - if (TRIGGER_FIRED_AFTER(trigdata->tg_event)) - elog(ERROR, "autoinc: must be fired before event"); - - if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) - rettuple = trigdata->tg_trigtuple; - else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) - rettuple = trigdata->tg_newtuple; - else - elog(ERROR, "autoinc: can't process DELETE events"); - - rel = trigdata->tg_relation; - relname = SPI_getrelname(rel); - - trigger = trigdata->tg_trigger; - - nargs = trigger->tgnargs; - if (nargs <= 0 || nargs % 2 != 0) - elog(ERROR, "autoinc (%s): even number gt 0 of arguments was expected", relname); - - args = trigger->tgargs; - tupdesc = rel->rd_att; - - chattrs = (int *) palloc(nargs / 2 * sizeof(int)); - newvals = (Datum *) palloc(nargs / 2 * sizeof(Datum)); - - for (i = 0; i < nargs;) - { - int attnum = SPI_fnumber(tupdesc, args[i]); - int32 val; - Datum seqname; - - if (attnum < 0) - elog(ERROR, "autoinc (%s): there is no attribute %s", - relname, args[i]); - if (SPI_gettypeid(tupdesc, attnum) != INT4OID) - elog(ERROR, "autoinc (%s): attribute %s must be of INT4 type", - relname, args[i]); - - val = DatumGetInt32(SPI_getbinval(rettuple, tupdesc, attnum, &isnull)); - - if (!isnull && val != 0) - { - i += 2; - continue; - } - - i++; - chattrs[chnattrs] = attnum; - seqname = DirectFunctionCall1(textin, - CStringGetDatum(args[i])); - newvals[chnattrs] = DirectFunctionCall1(nextval, seqname); - /* nextval now returns int64; coerce down to int32 */ - newvals[chnattrs] = Int32GetDatum((int32) DatumGetInt64(newvals[chnattrs])); - if (DatumGetInt32(newvals[chnattrs]) == 0) - { - newvals[chnattrs] = DirectFunctionCall1(nextval, seqname); - newvals[chnattrs] = Int32GetDatum((int32) DatumGetInt64(newvals[chnattrs])); - } - pfree(DatumGetTextP(seqname)); - chnattrs++; - i++; - } - - if (chnattrs > 0) - { - rettuple = SPI_modifytuple(rel, rettuple, chnattrs, chattrs, newvals, NULL); - if (rettuple == NULL) - elog(ERROR, "autoinc (%s): %d returned by SPI_modifytuple", - relname, SPI_result); - } - - pfree(relname); - pfree(chattrs); - pfree(newvals); - - return PointerGetDatum(rettuple); -} diff --git a/contrib/spi/autoinc.example b/contrib/spi/autoinc.example deleted file mode 100644 index a2f470dc2d..0000000000 --- a/contrib/spi/autoinc.example +++ /dev/null @@ -1,35 +0,0 @@ -DROP SEQUENCE next_id; -DROP TABLE ids; - -CREATE SEQUENCE next_id START -2 MINVALUE -2; - -CREATE TABLE ids ( - id int4, - idesc text -); - -CREATE TRIGGER ids_nextid - BEFORE INSERT OR UPDATE ON ids - FOR EACH ROW - EXECUTE PROCEDURE autoinc (id, next_id); - -INSERT INTO ids VALUES (0, 'first (-2 ?)'); -INSERT INTO ids VALUES (null, 'second (-1 ?)'); -INSERT INTO ids(idesc) VALUES ('third (1 ?!)'); - -SELECT * FROM ids; - -UPDATE ids SET id = null, idesc = 'first: -2 --> 2' - WHERE idesc = 'first (-2 ?)'; -UPDATE ids SET id = 0, idesc = 'second: -1 --> 3' - WHERE id = -1; -UPDATE ids SET id = 4, idesc = 'third: 1 --> 4' - WHERE id = 1; - -SELECT * FROM ids; - -SELECT 'Wasn''t it 4 ?' as nextval, nextval ('next_id') as value; - -insert into ids (idesc) select textcat (idesc, '. Copy.') from ids; - -SELECT * FROM ids; diff --git a/contrib/spi/autoinc.sql.in b/contrib/spi/autoinc.sql.in deleted file mode 100644 index 3676742943..0000000000 --- a/contrib/spi/autoinc.sql.in +++ /dev/null @@ -1,6 +0,0 @@ -DROP FUNCTION autoinc(); - -CREATE FUNCTION autoinc() - RETURNS opaque - AS 'MODULE_PATHNAME' - LANGUAGE 'C'; diff --git a/contrib/spi/insert_username.c b/contrib/spi/insert_username.c deleted file mode 100644 index 0bedaa98ae..0000000000 --- a/contrib/spi/insert_username.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * insert_username.c - * $Modified: Thu Oct 16 08:13:42 1997 by brook $ - * - * insert user name in response to a trigger - * usage: insert_username (column_name) - */ - -#include "executor/spi.h" /* this is what you need to work with SPI */ -#include "commands/trigger.h" /* -"- and triggers */ -#include "miscadmin.h" /* for GetUserName() */ - -extern Datum insert_username(PG_FUNCTION_ARGS); - -PG_FUNCTION_INFO_V1(insert_username); - -Datum -insert_username(PG_FUNCTION_ARGS) -{ - TriggerData *trigdata = (TriggerData *) fcinfo->context; - Trigger *trigger; /* to get trigger name */ - int nargs; /* # of arguments */ - Datum newval; /* new value of column */ - char **args; /* arguments */ - char *relname; /* triggered relation name */ - Relation rel; /* triggered relation */ - HeapTuple rettuple = NULL; - TupleDesc tupdesc; /* tuple description */ - int attnum; - - /* sanity checks from autoinc.c */ - if (!CALLED_AS_TRIGGER(fcinfo)) - elog(ERROR, "insert_username: not fired by trigger manager"); - if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) - elog(ERROR, "insert_username: can't process STATEMENT events"); - if (TRIGGER_FIRED_AFTER(trigdata->tg_event)) - elog(ERROR, "insert_username: must be fired before event"); - - if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) - rettuple = trigdata->tg_trigtuple; - else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) - rettuple = trigdata->tg_newtuple; - else - elog(ERROR, "insert_username: can't process DELETE events"); - - rel = trigdata->tg_relation; - relname = SPI_getrelname(rel); - - trigger = trigdata->tg_trigger; - - nargs = trigger->tgnargs; - if (nargs != 1) - elog(ERROR, "insert_username (%s): one argument was expected", relname); - - args = trigger->tgargs; - tupdesc = rel->rd_att; - - attnum = SPI_fnumber(tupdesc, args[0]); - - if (attnum < 0) - elog(ERROR, "insert_username (%s): there is no attribute %s", relname, args[0]); - if (SPI_gettypeid(tupdesc, attnum) != TEXTOID) - elog(ERROR, "insert_username (%s): attribute %s must be of TEXT type", - relname, args[0]); - - /* create fields containing name */ - newval = DirectFunctionCall1(textin, - CStringGetDatum(GetUserName(GetUserId()))); - - /* construct new tuple */ - rettuple = SPI_modifytuple(rel, rettuple, 1, &attnum, &newval, NULL); - if (rettuple == NULL) - elog(ERROR, "insert_username (%s): %d returned by SPI_modifytuple", - relname, SPI_result); - - pfree(relname); - - return PointerGetDatum(rettuple); -} diff --git a/contrib/spi/insert_username.example b/contrib/spi/insert_username.example deleted file mode 100644 index 41e69bcbf2..0000000000 --- a/contrib/spi/insert_username.example +++ /dev/null @@ -1,21 +0,0 @@ -DROP TABLE username_test; - -CREATE TABLE username_test ( - name text, - username text not null -); - -CREATE TRIGGER insert_usernames - BEFORE INSERT OR UPDATE ON username_test - FOR EACH ROW - EXECUTE PROCEDURE insert_username (username); - -INSERT INTO username_test VALUES ('nothing'); -INSERT INTO username_test VALUES ('null', null); -INSERT INTO username_test VALUES ('empty string', ''); -INSERT INTO username_test VALUES ('space', ' '); -INSERT INTO username_test VALUES ('tab', ' '); -INSERT INTO username_test VALUES ('name', 'name'); - -SELECT * FROM username_test; - diff --git a/contrib/spi/insert_username.sql.in b/contrib/spi/insert_username.sql.in deleted file mode 100644 index 436fc88b73..0000000000 --- a/contrib/spi/insert_username.sql.in +++ /dev/null @@ -1,6 +0,0 @@ -DROP FUNCTION insert_username(); - -CREATE FUNCTION insert_username() - RETURNS opaque - AS 'MODULE_PATHNAME' - LANGUAGE 'C'; diff --git a/contrib/spi/moddatetime.c b/contrib/spi/moddatetime.c deleted file mode 100644 index bd45dc72b3..0000000000 --- a/contrib/spi/moddatetime.c +++ /dev/null @@ -1,111 +0,0 @@ -/* -moddatetime.c - -What is this? -It is a function to be called from a trigger for the perpose of updating -a modification datetime stamp in a record when that record is UPDATEd. - -Credits -This is 95%+ based on autoinc.c, which I used as a starting point as I do -not really know what I am doing. I also had help from -Jan Wieck who told me about the timestamp_in("now") function. -OH, me, I'm Terry Mackintosh -*/ - -#include "executor/spi.h" /* this is what you need to work with SPI */ -#include "commands/trigger.h" /* -"- and triggers */ - -extern Datum moddatetime(PG_FUNCTION_ARGS); - -PG_FUNCTION_INFO_V1(moddatetime); - -Datum -moddatetime(PG_FUNCTION_ARGS) -{ - TriggerData *trigdata = (TriggerData *) fcinfo->context; - Trigger *trigger; /* to get trigger name */ - int nargs; /* # of arguments */ - int attnum; /* positional number of field to change */ - Datum newdt; /* The current datetime. */ - char **args; /* arguments */ - char *relname; /* triggered relation name */ - Relation rel; /* triggered relation */ - HeapTuple rettuple = NULL; - TupleDesc tupdesc; /* tuple description */ - - if (!CALLED_AS_TRIGGER(fcinfo)) - elog(ERROR, "moddatetime: not fired by trigger manager."); - - if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) - elog(ERROR, "moddatetime: can't process STATEMENT events."); - - if (TRIGGER_FIRED_AFTER(trigdata->tg_event)) - elog(ERROR, "moddatetime: must be fired before event."); - - if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) - elog(ERROR, "moddatetime: must be fired before event."); - else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) - rettuple = trigdata->tg_newtuple; - else - elog(ERROR, "moddatetime: can't process DELETE events."); - - rel = trigdata->tg_relation; - relname = SPI_getrelname(rel); - - trigger = trigdata->tg_trigger; - - nargs = trigger->tgnargs; - - if (nargs != 1) - elog(ERROR, "moddatetime (%s): A single argument was expected.", relname); - - args = trigger->tgargs; - /* must be the field layout? */ - tupdesc = rel->rd_att; - - /* Get the current datetime. */ - newdt = DirectFunctionCall1(timestamp_in, - CStringGetDatum("now")); - - /* - * This gets the position in the turple of the field we want. args[0] - * being the name of the field to update, as passed in from the - * trigger. - */ - attnum = SPI_fnumber(tupdesc, args[0]); - - /* - * This is were we check to see if the feild we are suppost to update - * even exits. The above function must return -1 if name not found? - */ - if (attnum < 0) - elog(ERROR, "moddatetime (%s): there is no attribute %s", relname, - args[0]); - - /* - * OK, this is where we make sure the timestamp field that we are - * modifying is really a timestamp field. Hay, error checking, what a - * novel idea !-) - */ - if (SPI_gettypeid(tupdesc, attnum) != TIMESTAMPOID) - elog(ERROR, "moddatetime (%s): attribute %s must be of TIMESTAMP type", - relname, args[0]); - -/* 1 is the number of items in the arrays attnum and newdt. - attnum is the positional number of the field to be updated. - newdt is the new datetime stamp. - NOTE that attnum and newdt are not arrays, but then a 1 ellement array - is not an array any more then they are. Thus, they can be considered a - one element array. -*/ - rettuple = SPI_modifytuple(rel, rettuple, 1, &attnum, &newdt, NULL); - - if (rettuple == NULL) - elog(ERROR, "moddatetime (%s): %d returned by SPI_modifytuple", - relname, SPI_result); - -/* Clean up */ - pfree(relname); - - return PointerGetDatum(rettuple); -} diff --git a/contrib/spi/moddatetime.example b/contrib/spi/moddatetime.example deleted file mode 100644 index e4a713c12a..0000000000 --- a/contrib/spi/moddatetime.example +++ /dev/null @@ -1,27 +0,0 @@ -DROP TABLE mdt; - -CREATE TABLE mdt ( - id int4, - idesc text, - moddate timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL -); - -CREATE TRIGGER mdt_moddatetime - BEFORE UPDATE ON mdt - FOR EACH ROW - EXECUTE PROCEDURE moddatetime (moddate); - -INSERT INTO mdt VALUES (1, 'first'); -INSERT INTO mdt VALUES (2, 'second'); -INSERT INTO mdt VALUES (3, 'third'); - -SELECT * FROM mdt; - -UPDATE mdt SET id = 4 - WHERE id = 1; -UPDATE mdt SET id = 5 - WHERE id = 2; -UPDATE mdt SET id = 6 - WHERE id = 3; - -SELECT * FROM mdt; diff --git a/contrib/spi/moddatetime.sql.in b/contrib/spi/moddatetime.sql.in deleted file mode 100644 index d497900ecf..0000000000 --- a/contrib/spi/moddatetime.sql.in +++ /dev/null @@ -1,6 +0,0 @@ -DROP FUNCTION moddatetime(); - -CREATE FUNCTION moddatetime() - RETURNS opaque - AS 'MODULE_PATHNAME' - LANGUAGE 'C'; diff --git a/contrib/spi/preprocessor/README.MAX b/contrib/spi/preprocessor/README.MAX deleted file mode 100644 index 7969438c60..0000000000 --- a/contrib/spi/preprocessor/README.MAX +++ /dev/null @@ -1,76 +0,0 @@ - -Here are general trigger functions provided as workable examples -of using SPI and triggers. "General" means that functions may be -used for defining triggers for any tables but you have to specify -table/field names (as described below) while creating a trigger. - -1. refint.c - functions for implementing referential integrity. - -check_primary_key () is to used for foreign keys of a table. - - You are to create trigger (BEFORE INSERT OR UPDATE) using this -function on a table referencing another table. You are to specify -as function arguments: triggered table column names which correspond -to foreign key, referenced table name and column names in referenced -table which correspond to primary/unique key. - You may create as many triggers as you need - one trigger for -one reference. - -check_foreign_key () is to used for primary/unique keys of a table. - - You are to create trigger (BEFORE DELETE OR UPDATE) using this -function on a table referenced by another table(s). You are to specify -as function arguments: number of references for which function has to -performe checking, action if referencing key found ('cascade' - to delete -corresponding foreign key, 'restrict' - to abort transaction if foreign keys -exist, 'setnull' - to set foreign key referencing primary/unique key -being deleted to null), triggered table column names which correspond -to primary/unique key, referencing table name and column names corresponding -to foreign key (, ... - as many referencing tables/keys as specified -by first argument). - Note, that NOT NULL constraint and unique index have to be defined by -youself. - - There are examples in refint.example and regression tests -(sql/triggers.sql). - - To CREATE FUNCTIONs use refint.sql (will be made by gmake from -refint.source). - -# Excuse me for my bad english. Massimo Lambertini -# -# -# New check foreign key -# -I think that cascade mode is to be considered like that the operation over -main table is to be made also in referenced table . -When i Delete , i must delete from referenced table , -but when i update , i update referenced table and not delete like unmodified refint.c . - -I made a patch that when i update it check the type of modified key ( if is a text , char() i -added '') and then create a update query that do the right think . - -For my point of view that policy is helpfull because i do not have in referenced table -loss of information . - - -In preprocessor subdir i have placed a little utility that from a SQL92 table definition, -it create all trigger for foreign key . - - -the schema that i use to analyze the problem is this - -create table -A -( key int4 not null primary key ,...) ; -create table -REFERENCED_B -( key int 4 , ... , -foreign key ( key ) references A -- -); - - - - - - diff --git a/contrib/spi/preprocessor/example.sql b/contrib/spi/preprocessor/example.sql deleted file mode 100644 index 7ecd6ad7e5..0000000000 --- a/contrib/spi/preprocessor/example.sql +++ /dev/null @@ -1,37 +0,0 @@ --- Note the syntax is strict because i have no time to write better perl filter. --- --- [blank] is 1 blank --- at the end of an interesting line must be a [,] or [--] --- [ending] must be a , or -- --- --- foreign[blank]key[blank]([blank]keyname,..,keyname[blank])[blank]references[blank]table[blank][ending] --- --- step1.e < example.sql | step2.pl > foreign_key_triggers.sql --- --- step1.e is a simple program that UPPERCASE ALL . I know that is simple implementing in Perl --- bu i haven't time - - -CREATE TABLE -gruppo -( -codice_gruppo int4 NOT NULL, -descrizione varchar(32) NOT NULL -primary key ( codice_gruppo ) - -) ; - --- --- fa_parte : Appartenenza di una Azienda Conatto o Cliente ad un certo GRUPPO --- - -CREATE TABLE -fa_parte -( -codice_gruppo int4 NOT NULL, -codice_contatto int4 NOT NULL, - -primary key ( codice_gruppo,codice_contatto ) , -foreign key ( codice_gruppo ) references gruppo -- -); - diff --git a/contrib/spi/preprocessor/step1.c b/contrib/spi/preprocessor/step1.c deleted file mode 100644 index 8a5379e8e0..0000000000 --- a/contrib/spi/preprocessor/step1.c +++ /dev/null @@ -1,27 +0,0 @@ -#include - -char * -strtoupper(char *string) -{ - int i; - - for (i = 0; i < strlen(string); i++) - string[i] = toupper((unsigned char) string[i]); - return string; -} - - - -void -main(char argc, char **argv) -{ - char str[250]; - int sw = 0; - - while (fgets(str, 240, stdin)) - { - if (sw == 0) - printf("%s", strtoupper(str)); - } - -} diff --git a/contrib/spi/preprocessor/step1.e b/contrib/spi/preprocessor/step1.e deleted file mode 100755 index 7590ab8505..0000000000 Binary files a/contrib/spi/preprocessor/step1.e and /dev/null differ diff --git a/contrib/spi/preprocessor/step2.pl b/contrib/spi/preprocessor/step2.pl deleted file mode 100755 index 76ce7944cc..0000000000 --- a/contrib/spi/preprocessor/step2.pl +++ /dev/null @@ -1,123 +0,0 @@ -#!/usr/bin/perl - -## -## MAIN -## -$table_name=""; -$old_name=""; -$references_table=""; -$references_column=""; -$is_create=0; - - - -while ( <> ) -{ - chop; - $str=$_ ; - - if ($is_create == 1) { - $table_name=$str; - $is_create=2; - } - if ( $str =~ /^CREATE TABLE/ ){ - $is_create=1; - } - if ($is_create == 2) { - if ($str =~ /^FOREIGN KEY/){ - ($d1,$d2,$d3,$columns,$d4,$d5,$references_table,$d6) = split (/ /,$str,8); - #printf "Table $table_name $columns $references_table\n"; - - if ($table_name ne $old_name ){ - printf "--\n-- Trigger for $table_name\n--\n\n"; - } - - foreach $i ( split(/,/ , $columns ) ){ - print "CREATE INDEX I_$table_name"; - print "_$i ON $table_name ( $i ) ;\n"; - } - - printf "\nCREATE TRIGGER T_P_$table_name"; - printf "_$references_table BEFORE INSERT OR UPDATE ON $table_name FOR EACH ROW\n" ; - printf "EXECUTE PROCEDURE\n"; - printf "check_primary_key("; - $val=0; - foreach $i ( split(/,/ , $columns ) ){ - print "'$i',"; - $val=$val+1 ; - } - print "'$references_table',"; - - $t=1; - foreach $i ( split(/,/,$columns ) ){ - print "'$i'"; - if ( $t < $val ) { - printf ","; - } - $t=$t+1; - } - print " );\n\n"; - - printf "CREATE TRIGGER T_F_D_$references_table"; - printf "_$table_name BEFORE DELETE ON $references_table FOR EACH ROW\n" ; - printf "EXECUTE PROCEDURE\n"; - printf "check_foreign_key(1,'cascade',"; - $val=0; - foreach $i ( split(/,/ , $columns ) ){ - print "'$i',"; - $val=$val+1 ; - } - print "'$table_name',"; - - $t=1; - foreach $i ( split(/,/,$columns ) ){ - print "'$i'"; - if ( $t < $val ) { - printf ","; - } - $t=$t+1; - } - print " );\n\n"; - - printf "CREATE TRIGGER T_F_U_$references_table"; - printf "_$table_name AFTER UPDATE ON $references_table FOR EACH ROW\n" ; - printf "EXECUTE PROCEDURE\n"; - printf "check_foreign_key(1,'cascade',"; - $val=0; - foreach $i ( split(/,/ , $columns ) ){ - print "'$i',"; - $val=$val+1 ; - } - print "'$table_name',"; - - $t=1; - foreach $i ( split(/,/,$columns ) ){ - print "'$i'"; - if ( $t < $val ) { - printf ","; - } - $t=$t+1; - } - print " );\n\n"; - - if ($table_name ne $old_name ){ - printf "-- ********************************\n\n\n"; - } - $old_name=$table_name ; - - - - - } - } - if ($str =~ /^\)\;/ ) { - $is_create = 0 ; - } - -} - - - - - - diff --git a/contrib/spi/refint.c b/contrib/spi/refint.c deleted file mode 100644 index 55c0fd13e6..0000000000 --- a/contrib/spi/refint.c +++ /dev/null @@ -1,609 +0,0 @@ -/* - * refint.c -- set of functions to define referential integrity - * constraints using general triggers. - */ - -#include "executor/spi.h" /* this is what you need to work with SPI */ -#include "commands/trigger.h" /* -"- and triggers */ -#include - - -extern Datum check_primary_key(PG_FUNCTION_ARGS); -extern Datum check_foreign_key(PG_FUNCTION_ARGS); - - -typedef struct -{ - char *ident; - int nplans; - void **splan; -} EPlan; - -static EPlan *FPlans = NULL; -static int nFPlans = 0; -static EPlan *PPlans = NULL; -static int nPPlans = 0; - -static EPlan *find_plan(char *ident, EPlan ** eplan, int *nplans); - -/* - * check_primary_key () -- check that key in tuple being inserted/updated - * references existing tuple in "primary" table. - * Though it's called without args You have to specify referenced - * table/keys while creating trigger: key field names in triggered table, - * referenced table name, referenced key field names: - * EXECUTE PROCEDURE - * check_primary_key ('Fkey1', 'Fkey2', 'Ptable', 'Pkey1', 'Pkey2'). - */ - -PG_FUNCTION_INFO_V1(check_primary_key); - -Datum -check_primary_key(PG_FUNCTION_ARGS) -{ - TriggerData *trigdata = (TriggerData *) fcinfo->context; - Trigger *trigger; /* to get trigger name */ - int nargs; /* # of args specified in CREATE TRIGGER */ - char **args; /* arguments: column names and table name */ - int nkeys; /* # of key columns (= nargs / 2) */ - Datum *kvals; /* key values */ - char *relname; /* referenced relation name */ - Relation rel; /* triggered relation */ - HeapTuple tuple = NULL; /* tuple to return */ - TupleDesc tupdesc; /* tuple description */ - EPlan *plan; /* prepared plan */ - Oid *argtypes = NULL; /* key types to prepare execution plan */ - bool isnull; /* to know is some column NULL or not */ - char ident[2 * NAMEDATALEN]; /* to identify myself */ - int ret; - int i; - -#ifdef DEBUG_QUERY - elog(DEBUG3, "Check_primary_key Enter Function"); -#endif - - /* - * Some checks first... - */ - - /* Called by trigger manager ? */ - if (!CALLED_AS_TRIGGER(fcinfo)) - elog(ERROR, "check_primary_key: not fired by trigger manager"); - - /* Should be called for ROW trigger */ - if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) - elog(ERROR, "check_primary_key: can't process STATEMENT events"); - - /* If INSERTion then must check Tuple to being inserted */ - if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) - tuple = trigdata->tg_trigtuple; - - /* Not should be called for DELETE */ - else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) - elog(ERROR, "check_primary_key: can't process DELETE events"); - - /* If UPDATion the must check new Tuple, not old one */ - else - tuple = trigdata->tg_newtuple; - - trigger = trigdata->tg_trigger; - nargs = trigger->tgnargs; - args = trigger->tgargs; - - if (nargs % 2 != 1) /* odd number of arguments! */ - elog(ERROR, "check_primary_key: odd number of arguments should be specified"); - - nkeys = nargs / 2; - relname = args[nkeys]; - rel = trigdata->tg_relation; - tupdesc = rel->rd_att; - - /* Connect to SPI manager */ - if ((ret = SPI_connect()) < 0) - elog(ERROR, "check_primary_key: SPI_connect returned %d", ret); - - /* - * We use SPI plan preparation feature, so allocate space to place key - * values. - */ - kvals = (Datum *) palloc(nkeys * sizeof(Datum)); - - /* - * Construct ident string as TriggerName $ TriggeredRelationId and try - * to find prepared execution plan. - */ - sprintf(ident, "%s$%u", trigger->tgname, rel->rd_id); - plan = find_plan(ident, &PPlans, &nPPlans); - - /* if there is no plan then allocate argtypes for preparation */ - if (plan->nplans <= 0) - argtypes = (Oid *) palloc(nkeys * sizeof(Oid)); - - /* For each column in key ... */ - for (i = 0; i < nkeys; i++) - { - /* get index of column in tuple */ - int fnumber = SPI_fnumber(tupdesc, args[i]); - - /* Bad guys may give us un-existing column in CREATE TRIGGER */ - if (fnumber < 0) - elog(ERROR, "check_primary_key: there is no attribute %s in relation %s", - args[i], SPI_getrelname(rel)); - - /* Well, get binary (in internal format) value of column */ - kvals[i] = SPI_getbinval(tuple, tupdesc, fnumber, &isnull); - - /* - * If it's NULL then nothing to do! DON'T FORGET call SPI_finish - * ()! DON'T FORGET return tuple! Executor inserts tuple you're - * returning! If you return NULL then nothing will be inserted! - */ - if (isnull) - { - SPI_finish(); - return PointerGetDatum(tuple); - } - - if (plan->nplans <= 0) /* Get typeId of column */ - argtypes[i] = SPI_gettypeid(tupdesc, fnumber); - } - - /* - * If we have to prepare plan ... - */ - if (plan->nplans <= 0) - { - void *pplan; - char sql[8192]; - - /* - * Construct query: SELECT 1 FROM _referenced_relation_ WHERE - * Pkey1 = $1 [AND Pkey2 = $2 [...]] - */ - sprintf(sql, "select 1 from %s where ", relname); - for (i = 0; i < nkeys; i++) - { - sprintf(sql + strlen(sql), "%s = $%d %s", - args[i + nkeys + 1], i + 1, (i < nkeys - 1) ? "and " : ""); - } - - /* Prepare plan for query */ - pplan = SPI_prepare(sql, nkeys, argtypes); - if (pplan == NULL) - elog(ERROR, "check_primary_key: SPI_prepare returned %d", SPI_result); - - /* - * Remember that SPI_prepare places plan in current memory context - * - so, we have to save plan in Top memory context for latter - * use. - */ - pplan = SPI_saveplan(pplan); - if (pplan == NULL) - elog(ERROR, "check_primary_key: SPI_saveplan returned %d", SPI_result); - plan->splan = (void **) malloc(sizeof(void *)); - *(plan->splan) = pplan; - plan->nplans = 1; - } - - /* - * Ok, execute prepared plan. - */ - ret = SPI_execp(*(plan->splan), kvals, NULL, 1); - /* we have no NULLs - so we pass ^^^^ here */ - - if (ret < 0) - elog(ERROR, "check_primary_key: SPI_execp returned %d", ret); - - /* - * If there are no tuples returned by SELECT then ... - */ - if (SPI_processed == 0) - elog(ERROR, "%s: tuple references non-existing key in %s", - trigger->tgname, relname); - - SPI_finish(); - - return PointerGetDatum(tuple); -} - -/* - * check_foreign_key () -- check that key in tuple being deleted/updated - * is not referenced by tuples in "foreign" table(s). - * Though it's called without args You have to specify (while creating trigger): - * number of references, action to do if key referenced - * ('restrict' | 'setnull' | 'cascade'), key field names in triggered - * ("primary") table and referencing table(s)/keys: - * EXECUTE PROCEDURE - * check_foreign_key (2, 'restrict', 'Pkey1', 'Pkey2', - * 'Ftable1', 'Fkey11', 'Fkey12', 'Ftable2', 'Fkey21', 'Fkey22'). - */ - -PG_FUNCTION_INFO_V1(check_foreign_key); - -Datum -check_foreign_key(PG_FUNCTION_ARGS) -{ - TriggerData *trigdata = (TriggerData *) fcinfo->context; - Trigger *trigger; /* to get trigger name */ - int nargs; /* # of args specified in CREATE TRIGGER */ - char **args; /* arguments: as described above */ - char **args_temp; - int nrefs; /* number of references (== # of plans) */ - char action; /* 'R'estrict | 'S'etnull | 'C'ascade */ - int nkeys; /* # of key columns */ - Datum *kvals; /* key values */ - char *relname; /* referencing relation name */ - Relation rel; /* triggered relation */ - HeapTuple trigtuple = NULL; /* tuple to being changed */ - HeapTuple newtuple = NULL; /* tuple to return */ - TupleDesc tupdesc; /* tuple description */ - EPlan *plan; /* prepared plan(s) */ - Oid *argtypes = NULL; /* key types to prepare execution plan */ - bool isnull; /* to know is some column NULL or not */ - bool isequal = true; /* are keys in both tuples equal (in - * UPDATE) */ - char ident[2 * NAMEDATALEN]; /* to identify myself */ - int is_update = 0; - int ret; - int i, - r; - -#ifdef DEBUG_QUERY - elog(DEBUG3, "Check_foreign_key Enter Function"); -#endif - - /* - * Some checks first... - */ - - /* Called by trigger manager ? */ - if (!CALLED_AS_TRIGGER(fcinfo)) - elog(ERROR, "check_foreign_key: not fired by trigger manager"); - - /* Should be called for ROW trigger */ - if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) - elog(ERROR, "check_foreign_key: can't process STATEMENT events"); - - /* Not should be called for INSERT */ - if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) - elog(ERROR, "check_foreign_key: can't process INSERT events"); - - /* Have to check tg_trigtuple - tuple being deleted */ - trigtuple = trigdata->tg_trigtuple; - - /* - * But if this is UPDATE then we have to return tg_newtuple. Also, if - * key in tg_newtuple is the same as in tg_trigtuple then nothing to - * do. - */ - is_update = 0; - if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) - { - newtuple = trigdata->tg_newtuple; - is_update = 1; - } - trigger = trigdata->tg_trigger; - nargs = trigger->tgnargs; - args = trigger->tgargs; - - if (nargs < 5) /* nrefs, action, key, Relation, key - at - * least */ - elog(ERROR, "check_foreign_key: too short %d (< 5) list of arguments", nargs); - - nrefs = pg_atoi(args[0], sizeof(int), 0); - if (nrefs < 1) - elog(ERROR, "check_foreign_key: %d (< 1) number of references specified", nrefs); - action = tolower((unsigned char) *(args[1])); - if (action != 'r' && action != 'c' && action != 's') - elog(ERROR, "check_foreign_key: invalid action %s", args[1]); - nargs -= 2; - args += 2; - nkeys = (nargs - nrefs) / (nrefs + 1); - if (nkeys <= 0 || nargs != (nrefs + nkeys * (nrefs + 1))) - elog(ERROR, "check_foreign_key: invalid number of arguments %d for %d references", - nargs + 2, nrefs); - - rel = trigdata->tg_relation; - tupdesc = rel->rd_att; - - /* Connect to SPI manager */ - if ((ret = SPI_connect()) < 0) - elog(ERROR, "check_foreign_key: SPI_connect returned %d", ret); - - /* - * We use SPI plan preparation feature, so allocate space to place key - * values. - */ - kvals = (Datum *) palloc(nkeys * sizeof(Datum)); - - /* - * Construct ident string as TriggerName $ TriggeredRelationId and try - * to find prepared execution plan(s). - */ - sprintf(ident, "%s$%u", trigger->tgname, rel->rd_id); - plan = find_plan(ident, &FPlans, &nFPlans); - - /* if there is no plan(s) then allocate argtypes for preparation */ - if (plan->nplans <= 0) - argtypes = (Oid *) palloc(nkeys * sizeof(Oid)); - - /* - * else - check that we have exactly nrefs plan(s) ready - */ - else if (plan->nplans != nrefs) - elog(ERROR, "%s: check_foreign_key: # of plans changed in meantime", - trigger->tgname); - - /* For each column in key ... */ - for (i = 0; i < nkeys; i++) - { - /* get index of column in tuple */ - int fnumber = SPI_fnumber(tupdesc, args[i]); - - /* Bad guys may give us un-existing column in CREATE TRIGGER */ - if (fnumber < 0) - elog(ERROR, "check_foreign_key: there is no attribute %s in relation %s", - args[i], SPI_getrelname(rel)); - - /* Well, get binary (in internal format) value of column */ - kvals[i] = SPI_getbinval(trigtuple, tupdesc, fnumber, &isnull); - - /* - * If it's NULL then nothing to do! DON'T FORGET call SPI_finish - * ()! DON'T FORGET return tuple! Executor inserts tuple you're - * returning! If you return NULL then nothing will be inserted! - */ - if (isnull) - { - SPI_finish(); - return PointerGetDatum((newtuple == NULL) ? trigtuple : newtuple); - } - - /* - * If UPDATE then get column value from new tuple being inserted - * and compare is this the same as old one. For the moment we use - * string presentation of values... - */ - if (newtuple != NULL) - { - char *oldval = SPI_getvalue(trigtuple, tupdesc, fnumber); - char *newval; - - /* this shouldn't happen! SPI_ERROR_NOOUTFUNC ? */ - if (oldval == NULL) - elog(ERROR, "check_foreign_key: SPI_getvalue returned %d", SPI_result); - newval = SPI_getvalue(newtuple, tupdesc, fnumber); - if (newval == NULL || strcmp(oldval, newval) != 0) - isequal = false; - } - - if (plan->nplans <= 0) /* Get typeId of column */ - argtypes[i] = SPI_gettypeid(tupdesc, fnumber); - } - args_temp = args; - nargs -= nkeys; - args += nkeys; - - /* - * If we have to prepare plans ... - */ - if (plan->nplans <= 0) - { - void *pplan; - char sql[8192]; - char **args2 = args; - - plan->splan = (void **) malloc(nrefs * sizeof(void *)); - - for (r = 0; r < nrefs; r++) - { - relname = args2[0]; - - /*--------- - * For 'R'estrict action we construct SELECT query: - * - * SELECT 1 - * FROM _referencing_relation_ - * WHERE Fkey1 = $1 [AND Fkey2 = $2 [...]] - * - * to check is tuple referenced or not. - *--------- - */ - if (action == 'r') - - sprintf(sql, "select 1 from %s where ", relname); - - /*--------- - * For 'C'ascade action we construct DELETE query - * - * DELETE - * FROM _referencing_relation_ - * WHERE Fkey1 = $1 [AND Fkey2 = $2 [...]] - * - * to delete all referencing tuples. - *--------- - */ - - /* - * Max : Cascade with UPDATE query i create update query that - * updates new key values in referenced tables - */ - - - else if (action == 'c') - { - if (is_update == 1) - { - int fn; - char *nv; - int k; - - sprintf(sql, "update %s set ", relname); - for (k = 1; k <= nkeys; k++) - { - int is_char_type = 0; - char *type; - - fn = SPI_fnumber(tupdesc, args_temp[k - 1]); - nv = SPI_getvalue(newtuple, tupdesc, fn); - type = SPI_gettype(tupdesc, fn); - - if ((strcmp(type, "text") && strcmp(type, "varchar") && - strcmp(type, "char") && strcmp(type, "bpchar") && - strcmp(type, "date") && strcmp(type, "timestamp")) == 0) - is_char_type = 1; -#ifdef DEBUG_QUERY - elog(DEBUG3, "Check_foreign_key Debug value %s type %s %d", - nv, type, is_char_type); -#endif - - /* - * is_char_type =1 i set ' ' for define a new - * value - */ - sprintf(sql + strlen(sql), " %s = %s%s%s %s ", - args2[k], (is_char_type > 0) ? "'" : "", - nv, (is_char_type > 0) ? "'" : "", (k < nkeys) ? ", " : ""); - is_char_type = 0; - } - strcat(sql, " where "); - - } - else -/* DELETE */ - sprintf(sql, "delete from %s where ", relname); - - } - - /* - * For 'S'etnull action we construct UPDATE query - UPDATE - * _referencing_relation_ SET Fkey1 null [, Fkey2 null [...]] - * WHERE Fkey1 = $1 [AND Fkey2 = $2 [...]] - to set key - * columns in all referencing tuples to NULL. - */ - else if (action == 's') - { - sprintf(sql, "update %s set ", relname); - for (i = 1; i <= nkeys; i++) - { - sprintf(sql + strlen(sql), "%s = null%s", - args2[i], (i < nkeys) ? ", " : ""); - } - strcat(sql, " where "); - } - - /* Construct WHERE qual */ - for (i = 1; i <= nkeys; i++) - { - sprintf(sql + strlen(sql), "%s = $%d %s", - args2[i], i, (i < nkeys) ? "and " : ""); - } - - /* Prepare plan for query */ - pplan = SPI_prepare(sql, nkeys, argtypes); - if (pplan == NULL) - elog(ERROR, "check_foreign_key: SPI_prepare returned %d", SPI_result); - - /* - * Remember that SPI_prepare places plan in current memory - * context - so, we have to save plan in Top memory context - * for latter use. - */ - pplan = SPI_saveplan(pplan); - if (pplan == NULL) - elog(ERROR, "check_foreign_key: SPI_saveplan returned %d", SPI_result); - - plan->splan[r] = pplan; - - args2 += nkeys + 1; /* to the next relation */ - } - plan->nplans = nrefs; -#ifdef DEBUG_QUERY - elog(DEBUG3, "Check_foreign_key Debug Query is : %s ", sql); -#endif - } - - /* - * If UPDATE and key is not changed ... - */ - if (newtuple != NULL && isequal) - { - SPI_finish(); - return PointerGetDatum(newtuple); - } - - /* - * Ok, execute prepared plan(s). - */ - for (r = 0; r < nrefs; r++) - { - /* - * For 'R'estrict we may to execute plan for one tuple only, for - * other actions - for all tuples. - */ - int tcount = (action == 'r') ? 1 : 0; - - relname = args[0]; - - sprintf(ident, "%s$%u", trigger->tgname, rel->rd_id); - plan = find_plan(ident, &FPlans, &nFPlans); - ret = SPI_execp(plan->splan[r], kvals, NULL, tcount); - /* we have no NULLs - so we pass ^^^^ here */ - - if (ret < 0) - elog(ERROR, "check_foreign_key: SPI_execp returned %d", ret); - - /* If action is 'R'estrict ... */ - if (action == 'r') - { - /* If there is tuple returned by SELECT then ... */ - if (SPI_processed > 0) - elog(ERROR, "%s: tuple referenced in %s", - trigger->tgname, relname); - } -#ifdef REFINT_VERBOSE - else - elog(DEBUG3, "%s: %d tuple(s) of %s are %s", - trigger->tgname, SPI_processed, relname, - (action == 'c') ? "deleted" : "setted to null"); -#endif - args += nkeys + 1; /* to the next relation */ - } - - SPI_finish(); - - return PointerGetDatum((newtuple == NULL) ? trigtuple : newtuple); -} - -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); -} diff --git a/contrib/spi/refint.example b/contrib/spi/refint.example deleted file mode 100644 index 1300e81654..0000000000 --- a/contrib/spi/refint.example +++ /dev/null @@ -1,82 +0,0 @@ ---Column ID of table A is primary key: - -CREATE TABLE A ( - ID int4 not null -); -CREATE UNIQUE INDEX AI ON A (ID); - ---Columns REFB of table B and REFC of C are foreign keys referenting ID of A: - -CREATE TABLE B ( - REFB int4 -); -CREATE INDEX BI ON B (REFB); - -CREATE TABLE C ( - REFC int4 -); -CREATE INDEX CI ON C (REFC); - ---Trigger for table A: - -CREATE TRIGGER AT BEFORE DELETE OR UPDATE ON A FOR EACH ROW -EXECUTE PROCEDURE -check_foreign_key (2, 'cascade', 'ID', 'B', 'REFB', 'C', 'REFC'); -/* -2 - means that check must be performed for foreign keys of 2 tables. -cascade - defines that corresponding keys must be deleted. -ID - name of primary key column in triggered table (A). You may - use as many columns as you need. -B - name of (first) table with foreign keys. -REFB - name of foreign key column in this table. You may use as many - columns as you need, but number of key columns in referenced - table (A) must be the same. -C - name of second table with foreign keys. -REFC - name of foreign key column in this table. -*/ - ---Trigger for table B: - -CREATE TRIGGER BT BEFORE INSERT OR UPDATE ON B FOR EACH ROW -EXECUTE PROCEDURE -check_primary_key ('REFB', 'A', 'ID'); - -/* -REFB - name of foreign key column in triggered (B) table. You may use as - many columns as you need, but number of key columns in referenced - table must be the same. -A - referenced table name. -ID - name of primary key column in referenced table. -*/ - ---Trigger for table C: - -CREATE TRIGGER CT BEFORE INSERT OR UPDATE ON C FOR EACH ROW -EXECUTE PROCEDURE -check_primary_key ('REFC', 'A', 'ID'); - --- Now try - -INSERT INTO A VALUES (10); -INSERT INTO A VALUES (20); -INSERT INTO A VALUES (30); -INSERT INTO A VALUES (40); -INSERT INTO A VALUES (50); - -INSERT INTO B VALUES (1); -- invalid reference -INSERT INTO B VALUES (10); -INSERT INTO B VALUES (30); -INSERT INTO B VALUES (30); - -INSERT INTO C VALUES (11); -- invalid reference -INSERT INTO C VALUES (20); -INSERT INTO C VALUES (20); -INSERT INTO C VALUES (30); - -DELETE FROM A WHERE ID = 10; -DELETE FROM A WHERE ID = 20; -DELETE FROM A WHERE ID = 30; - -SELECT * FROM A; -SELECT * FROM B; -SELECT * FROM C; diff --git a/contrib/spi/refint.sql.in b/contrib/spi/refint.sql.in deleted file mode 100644 index d193319d9d..0000000000 --- a/contrib/spi/refint.sql.in +++ /dev/null @@ -1,12 +0,0 @@ -DROP FUNCTION check_primary_key (); -DROP FUNCTION check_foreign_key (); - -CREATE FUNCTION check_primary_key () - RETURNS opaque - AS 'MODULE_PATHNAME' - LANGUAGE 'C'; - -CREATE FUNCTION check_foreign_key () - RETURNS opaque - AS 'MODULE_PATHNAME' - LANGUAGE 'C'; diff --git a/contrib/spi/timetravel.c b/contrib/spi/timetravel.c deleted file mode 100644 index 1731190a5d..0000000000 --- a/contrib/spi/timetravel.c +++ /dev/null @@ -1,423 +0,0 @@ -/* - * timetravel.c -- function to get time travel feature - * using general triggers. - */ - -#include "executor/spi.h" /* this is what you need to work with SPI */ -#include "commands/trigger.h" /* -"- and triggers */ -#include - -#define ABSTIMEOID 702 /* it should be in pg_type.h */ - -AbsoluteTime currabstime(void); -Datum timetravel(PG_FUNCTION_ARGS); -Datum set_timetravel(PG_FUNCTION_ARGS); - -typedef struct -{ - char *ident; - void *splan; -} EPlan; - -static EPlan *Plans = NULL; /* for UPDATE/DELETE */ -static int nPlans = 0; - -static char **TTOff = NULL; -static int nTTOff = 0; - -static EPlan *find_plan(char *ident, EPlan ** eplan, int *nplans); - -/* - * timetravel () -- - * 1. IF an update affects tuple with stop_date eq INFINITY - * then form (and return) new tuple with stop_date eq current date - * and all other column values as in old tuple, and insert tuple - * with new data and start_date eq current date and - * stop_date eq INFINITY - * ELSE - skip updation of tuple. - * 2. IF an delete affects tuple with stop_date eq INFINITY - * then insert the same tuple with stop_date eq current date - * ELSE - skip deletion of tuple. - * 3. On INSERT, if start_date is NULL then current date will be - * inserted, if stop_date is NULL then INFINITY will be inserted. - * - * In CREATE TRIGGER you are to specify start_date and stop_date column - * names: - * EXECUTE PROCEDURE - * timetravel ('date_on', 'date_off'). - */ - -PG_FUNCTION_INFO_V1(timetravel); - -Datum -timetravel(PG_FUNCTION_ARGS) -{ - TriggerData *trigdata = (TriggerData *) fcinfo->context; - Trigger *trigger; /* to get trigger name */ - char **args; /* arguments */ - int attnum[2]; /* fnumbers of start/stop columns */ - Datum oldon, - oldoff; - Datum newon, - newoff; - Datum *cvals; /* column values */ - char *cnulls; /* column nulls */ - char *relname; /* triggered relation name */ - Relation rel; /* triggered relation */ - HeapTuple trigtuple; - HeapTuple newtuple = NULL; - HeapTuple rettuple; - TupleDesc tupdesc; /* tuple description */ - int natts; /* # of attributes */ - EPlan *plan; /* prepared plan */ - char ident[2 * NAMEDATALEN]; - bool isnull; /* to know is some column NULL or not */ - bool isinsert = false; - int ret; - int i; - - /* - * Some checks first... - */ - - /* Called by trigger manager ? */ - if (!CALLED_AS_TRIGGER(fcinfo)) - elog(ERROR, "timetravel: not fired by trigger manager"); - - /* Should be called for ROW trigger */ - if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) - elog(ERROR, "timetravel: can't process STATEMENT events"); - - /* Should be called BEFORE */ - if (TRIGGER_FIRED_AFTER(trigdata->tg_event)) - elog(ERROR, "timetravel: must be fired before event"); - - /* INSERT ? */ - if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) - isinsert = true; - - if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) - newtuple = trigdata->tg_newtuple; - - trigtuple = trigdata->tg_trigtuple; - - rel = trigdata->tg_relation; - relname = SPI_getrelname(rel); - - /* check if TT is OFF for this relation */ - for (i = 0; i < nTTOff; i++) - if (strcasecmp(TTOff[i], relname) == 0) - break; - if (i < nTTOff) /* OFF - nothing to do */ - { - pfree(relname); - return PointerGetDatum((newtuple != NULL) ? newtuple : trigtuple); - } - - trigger = trigdata->tg_trigger; - - if (trigger->tgnargs != 2) - elog(ERROR, "timetravel (%s): invalid (!= 2) number of arguments %d", - relname, trigger->tgnargs); - - args = trigger->tgargs; - tupdesc = rel->rd_att; - natts = tupdesc->natts; - - for (i = 0; i < 2; i++) - { - attnum[i] = SPI_fnumber(tupdesc, args[i]); - if (attnum[i] < 0) - elog(ERROR, "timetravel (%s): there is no attribute %s", relname, args[i]); - if (SPI_gettypeid(tupdesc, attnum[i]) != ABSTIMEOID) - elog(ERROR, "timetravel (%s): attributes %s and %s must be of abstime type", - relname, args[0], args[1]); - } - - if (isinsert) /* INSERT */ - { - int chnattrs = 0; - int chattrs[2]; - Datum newvals[2]; - - oldon = SPI_getbinval(trigtuple, tupdesc, attnum[0], &isnull); - if (isnull) - { - newvals[chnattrs] = GetCurrentAbsoluteTime(); - chattrs[chnattrs] = attnum[0]; - chnattrs++; - } - - oldoff = SPI_getbinval(trigtuple, tupdesc, attnum[1], &isnull); - if (isnull) - { - if ((chnattrs == 0 && DatumGetInt32(oldon) >= NOEND_ABSTIME) || - (chnattrs > 0 && DatumGetInt32(newvals[0]) >= NOEND_ABSTIME)) - elog(ERROR, "timetravel (%s): %s ge %s", - relname, args[0], args[1]); - newvals[chnattrs] = NOEND_ABSTIME; - chattrs[chnattrs] = attnum[1]; - chnattrs++; - } - else - { - if ((chnattrs == 0 && DatumGetInt32(oldon) >= - DatumGetInt32(oldoff)) || - (chnattrs > 0 && DatumGetInt32(newvals[0]) >= - DatumGetInt32(oldoff))) - elog(ERROR, "timetravel (%s): %s ge %s", - relname, args[0], args[1]); - } - - pfree(relname); - if (chnattrs <= 0) - return PointerGetDatum(trigtuple); - - rettuple = SPI_modifytuple(rel, trigtuple, chnattrs, - chattrs, newvals, NULL); - return PointerGetDatum(rettuple); - } - - oldon = SPI_getbinval(trigtuple, tupdesc, attnum[0], &isnull); - if (isnull) - elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[0]); - - oldoff = SPI_getbinval(trigtuple, tupdesc, attnum[1], &isnull); - if (isnull) - elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[1]); - - /* - * If DELETE/UPDATE of tuple with stop_date neq INFINITY then say - * upper Executor to skip operation for this tuple - */ - if (newtuple != NULL) /* UPDATE */ - { - newon = SPI_getbinval(newtuple, tupdesc, attnum[0], &isnull); - if (isnull) - elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[0]); - newoff = SPI_getbinval(newtuple, tupdesc, attnum[1], &isnull); - if (isnull) - elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[1]); - - if (oldon != newon || oldoff != newoff) - elog(ERROR, "timetravel (%s): you can't change %s and/or %s columns (use set_timetravel)", - relname, args[0], args[1]); - - if (newoff != NOEND_ABSTIME) - { - pfree(relname); /* allocated in upper executor context */ - return PointerGetDatum(NULL); - } - } - else if (oldoff != NOEND_ABSTIME) /* DELETE */ - { - pfree(relname); - return PointerGetDatum(NULL); - } - - newoff = GetCurrentAbsoluteTime(); - - /* Connect to SPI manager */ - if ((ret = SPI_connect()) < 0) - elog(ERROR, "timetravel (%s): SPI_connect returned %d", relname, ret); - - /* Fetch tuple values and nulls */ - cvals = (Datum *) palloc(natts * sizeof(Datum)); - cnulls = (char *) palloc(natts * sizeof(char)); - for (i = 0; i < natts; i++) - { - cvals[i] = SPI_getbinval((newtuple != NULL) ? newtuple : trigtuple, - tupdesc, i + 1, &isnull); - cnulls[i] = (isnull) ? 'n' : ' '; - } - - /* change date column(s) */ - if (newtuple) /* UPDATE */ - { - cvals[attnum[0] - 1] = newoff; /* start_date eq current date */ - cnulls[attnum[0] - 1] = ' '; - cvals[attnum[1] - 1] = NOEND_ABSTIME; /* stop_date eq INFINITY */ - cnulls[attnum[1] - 1] = ' '; - } - else -/* DELETE */ - { - cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */ - cnulls[attnum[1] - 1] = ' '; - } - - /* - * Construct ident string as TriggerName $ TriggeredRelationId and try - * to find prepared execution plan. - */ - sprintf(ident, "%s$%u", trigger->tgname, rel->rd_id); - plan = find_plan(ident, &Plans, &nPlans); - - /* if there is no plan ... */ - if (plan->splan == NULL) - { - void *pplan; - Oid *ctypes; - char sql[8192]; - - /* allocate ctypes for preparation */ - ctypes = (Oid *) palloc(natts * sizeof(Oid)); - - /* - * Construct query: INSERT INTO _relation_ VALUES ($1, ...) - */ - sprintf(sql, "INSERT INTO %s VALUES (", relname); - for (i = 1; i <= natts; i++) - { - sprintf(sql + strlen(sql), "$%d%s", - i, (i < natts) ? ", " : ")"); - ctypes[i - 1] = SPI_gettypeid(tupdesc, i); - } - - /* Prepare plan for query */ - pplan = SPI_prepare(sql, natts, ctypes); - if (pplan == NULL) - elog(ERROR, "timetravel (%s): SPI_prepare returned %d", relname, SPI_result); - - /* - * Remember that SPI_prepare places plan in current memory context - * - so, we have to save plan in Top memory context for latter - * use. - */ - pplan = SPI_saveplan(pplan); - if (pplan == NULL) - elog(ERROR, "timetravel (%s): SPI_saveplan returned %d", relname, SPI_result); - - plan->splan = pplan; - } - - /* - * Ok, execute prepared plan. - */ - ret = SPI_execp(plan->splan, cvals, cnulls, 0); - - if (ret < 0) - elog(ERROR, "timetravel (%s): SPI_execp returned %d", relname, ret); - - /* Tuple to return to upper Executor ... */ - if (newtuple) /* UPDATE */ - { - HeapTuple tmptuple; - - tmptuple = SPI_copytuple(trigtuple); - rettuple = SPI_modifytuple(rel, tmptuple, 1, &(attnum[1]), &newoff, NULL); - - /* - * SPI_copytuple allocates tmptuple in upper executor context - - * have to free allocation using SPI_pfree - */ - SPI_pfree(tmptuple); - } - else -/* DELETE */ - rettuple = trigtuple; - - SPI_finish(); /* don't forget say Bye to SPI mgr */ - - pfree(relname); - - return PointerGetDatum(rettuple); -} - -/* - * set_timetravel (relname, on) -- - * turn timetravel for specified relation ON/OFF - */ -PG_FUNCTION_INFO_V1(set_timetravel); - -Datum -set_timetravel(PG_FUNCTION_ARGS) -{ - Name relname = PG_GETARG_NAME(0); - int32 on = PG_GETARG_INT32(1); - char *rname; - char *d; - char *s; - int i; - - for (i = 0; i < nTTOff; i++) - if (namestrcmp(relname, TTOff[i]) == 0) - break; - - if (i < nTTOff) /* OFF currently */ - { - if (on == 0) - PG_RETURN_INT32(0); - - /* turn ON */ - free(TTOff[i]); - if (nTTOff == 1) - free(TTOff); - else - { - if (i < nTTOff - 1) - memcpy(&(TTOff[i]), &(TTOff[i + 1]), (nTTOff - i) * sizeof(char *)); - TTOff = realloc(TTOff, (nTTOff - 1) * sizeof(char *)); - } - nTTOff--; - PG_RETURN_INT32(0); - } - - /* ON currently */ - if (on != 0) - PG_RETURN_INT32(1); - - /* turn OFF */ - if (nTTOff == 0) - TTOff = malloc(sizeof(char *)); - else - TTOff = realloc(TTOff, (nTTOff + 1) * sizeof(char *)); - s = rname = DatumGetCString(DirectFunctionCall1(nameout, - NameGetDatum(relname))); - d = TTOff[nTTOff] = malloc(strlen(rname) + 1); - while (*s) - *d++ = tolower((unsigned char) *s++); - *d = 0; - pfree(rname); - nTTOff++; - - PG_RETURN_INT32(1); -} - -AbsoluteTime -currabstime() -{ - return (GetCurrentAbsoluteTime()); -} - -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->splan = NULL; - (*nplans)++; - - return (newp); -} diff --git a/contrib/spi/timetravel.example b/contrib/spi/timetravel.example deleted file mode 100644 index 4244bed19f..0000000000 --- a/contrib/spi/timetravel.example +++ /dev/null @@ -1,68 +0,0 @@ -drop table tttest; - -create table tttest ( - price_id int4, - price_val int4, - price_on abstime, - price_off abstime -); - -create trigger timetravel - before insert or delete or update on tttest - for each row - execute procedure - timetravel (price_on, price_off); - -insert into tttest values (1, 1, null, null); -insert into tttest(price_id, price_val) values (2, 2); -insert into tttest(price_id, price_val,price_off) values (3, 3, 'infinity'); - -insert into tttest(price_id, price_val,price_off) values (3, 3, - abstime('now'::timestamp - '100 days'::interval)); -insert into tttest(price_id, price_val,price_on) values (3, 3, 'infinity'); - -select * from tttest; -delete from tttest where price_id = 2; -select * from tttest; --- what do we see ? - --- get current prices -select * from tttest where price_off = 'infinity'; - --- change price for price_id == 3 -update tttest set price_val = 30 where price_id = 3; -select * from tttest; - --- now we want to change price_id from 3 to 5 in ALL tuples --- but this gets us not what we need -update tttest set price_id = 5 where price_id = 3; -select * from tttest; - --- restore data as before last update: -select set_timetravel('tttest', 0); -- turn TT OFF! -delete from tttest where price_id = 5; -update tttest set price_off = 'infinity' where price_val = 30; -select * from tttest; - --- and try change price_id now! -update tttest set price_id = 5 where price_id = 3; -select * from tttest; --- isn't it what we need ? - -select set_timetravel('tttest', 1); -- turn TT ON! - --- we want to correct some date -update tttest set price_on = 'Jan-01-1990 00:00:01' where price_id = 5 and - price_off <> 'infinity'; --- but this doesn't work - --- try in this way -select set_timetravel('tttest', 0); -- turn TT OFF! -update tttest set price_on = '01-Jan-1990 00:00:01' where price_id = 5 and - price_off <> 'infinity'; -select * from tttest; --- isn't it what we need ? - --- get price for price_id == 5 as it was '10-Jan-1990' -select * from tttest where price_id = 5 and - price_on <= '10-Jan-1990' and price_off > '10-Jan-1990'; diff --git a/contrib/spi/timetravel.sql.in b/contrib/spi/timetravel.sql.in deleted file mode 100644 index 46912abf6d..0000000000 --- a/contrib/spi/timetravel.sql.in +++ /dev/null @@ -1,12 +0,0 @@ -DROP FUNCTION timetravel(); -DROP FUNCTION set_timetravel(name, int4); - -CREATE FUNCTION timetravel() - RETURNS opaque - AS 'MODULE_PATHNAME' - LANGUAGE 'C'; - -CREATE FUNCTION set_timetravel(name, int4) - RETURNS int4 - AS 'MODULE_PATHNAME' - LANGUAGE 'C' WITH (isStrict); diff --git a/contrib/start-scripts/freebsd b/contrib/start-scripts/freebsd deleted file mode 100644 index a4e412cd69..0000000000 --- a/contrib/start-scripts/freebsd +++ /dev/null @@ -1,56 +0,0 @@ -#! /bin/sh - -# PostgreSQL boot time startup script for FreeBSD. Copy this file to -# /usr/local/etc/rc.d/postgresql. - -# Created through merger of the Linux start script by Ryan Kirkpatrick -# and the script in the FreeBSD ports collection. - -# $Header: /cvsroot/pgsql/contrib/start-scripts/freebsd,v 1.2 2001/04/19 19:17:44 petere Exp $ - -## EDIT FROM HERE - -# Installation prefix -prefix=/usr/local/pgsql - -# Data directory -PGDATA="/usr/local/pgsql/data" - -# Who to run pg_ctl as, should be "postgres". -PGUSER=postgres - -# Where to keep a log file -PGLOG="$PGDATA/serverlog" - -## STOP EDITING HERE - -# The path that is to be used for the script -PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin - -# What to use to start up the postmaster -DAEMON="$prefix/bin/pg_ctl" - -test -x "$DAEMON" || exit 0 - -case $1 in - start) - su -l $PGUSER -c "$DAEMON start -D '$PGDATA' -s -l $PGLOG" - echo -n ' postgresql' - ;; - stop) - su -l $PGUSER -c "$DAEMON stop -D '$PGDATA' -s -m fast" - ;; - restart) - su -l $PGUSER -c "$DAEMON restart -D '$PGDATA' -s -m fast" - ;; - status) - su -l $PGUSER -c "$DAEMON status -D '$PGDATA'" - ;; - *) - # Print help - echo "Usage: `basename $0` {start|stop|restart|status}" 1>&2 - exit 1 - ;; -esac - -exit 0 diff --git a/contrib/start-scripts/linux b/contrib/start-scripts/linux deleted file mode 100644 index ec89d05591..0000000000 --- a/contrib/start-scripts/linux +++ /dev/null @@ -1,92 +0,0 @@ -#! /bin/sh - -# chkconfig: 2345 98 02 -# description: PostgreSQL RDBMS - -# This is an example of a start/stop script for SysV-style init, such -# as is used on Linux systems. You should edit some of the variables -# and maybe the 'echo' commands. -# -# Place this file at /etc/init.d/postgresql (or -# /etc/rc.d/init.d/postgresql) and make symlinks to -# /etc/rc.d/rc0.d/K02postgresql -# /etc/rc.d/rc1.d/K02postgresql -# /etc/rc.d/rc2.d/K02postgresql -# /etc/rc.d/rc3.d/S98postgresql -# /etc/rc.d/rc4.d/S98postgresql -# /etc/rc.d/rc5.d/S98postgresql -# Or, if you have chkconfig, simply: -# chkconfig --add postgresql -# -# Proper init scripts on Linux systems normally require setting lock -# and pid files under /var/run as well as reacting to network -# settings, so you should treat this with care. - -# Original author: Ryan Kirkpatrick - -# $Header: /cvsroot/pgsql/contrib/start-scripts/linux,v 1.3 2001/07/30 14:52:42 momjian Exp $ - -## EDIT FROM HERE - -# Installation prefix -prefix=/usr/local/pgsql - -# Data directory -PGDATA="/usr/local/pgsql/data" - -# Who to run pg_ctl as, should be "postgres". -PGUSER=postgres - -# Where to keep a log file -PGLOG="$PGDATA/serverlog" - -## STOP EDITING HERE - -# Check for echo -n vs echo \c -if echo '\c' | grep -s c >/dev/null 2>&1 ; then - ECHO_N="echo -n" - ECHO_C="" -else - ECHO_N="echo" - ECHO_C='\c' -fi - -# The path that is to be used for the script -PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin - -# What to use to start up the postmaster -DAEMON="$prefix/bin/pg_ctl" - -set -e - -# Only start if we can find pg_ctl. -test -f $DAEMON || exit 0 - -# Parse command line parameters. -case $1 in - start) - $ECHO_N "Starting PostgreSQL: "$ECHO_C - su - $PGUSER -c "$DAEMON start -D '$PGDATA' -s -l $PGLOG" - echo "ok" - ;; - stop) - echo -n "Stopping PostgreSQL: " - su - $PGUSER -c "$DAEMON stop -D '$PGDATA' -s -m fast" - echo "ok" - ;; - restart) - echo -n "Restarting PostgreSQL: " - su - $PGUSER -c "$DAEMON restart -D '$PGDATA' -s -m fast" - echo "ok" - ;; - status) - su - $PGUSER -c "$DAEMON status -D '$PGDATA'" - ;; - *) - # Print help - echo "Usage: $0 {start|stop|restart|status}" 1>&2 - exit 1 - ;; -esac - -exit 0 diff --git a/contrib/string/Makefile b/contrib/string/Makefile deleted file mode 100644 index 8a38d9c39e..0000000000 --- a/contrib/string/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/string/Attic/Makefile,v 1.16 2001/09/06 10:49:30 petere Exp $ - -subdir = contrib/string -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -MODULES = string_io -DATA_built = string_io.sql -DOCS = README.string_io - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/string/README.string_io b/contrib/string/README.string_io deleted file mode 100644 index 4b4d10166f..0000000000 --- a/contrib/string/README.string_io +++ /dev/null @@ -1,23 +0,0 @@ -String io module for postgresql. -Copyright (C) 1999, Massimo Dal Zotto - -This software is distributed under the GNU General Public License -either version 2, or (at your option) any later version. - - -These output functions can be used as substitution of the standard text -output functions to get the value of text fields printed in the format -used for C strings. This allows the output of queries or the exported -files to be processed more easily using standard unix filter programs -like perl or awk. - -If you use the standard functions instead you could find a single tuple -splitted into many lines and the tabs embedded in the values could be -confused with those used as field delimters. - -My function translates all non-printing characters into corresponding -esacape sequences as defined by the C syntax. All you need to reconstruct -the exact value in your application is a corresponding unescape function -like the string_input defined in the source code. - -Massimo Dal Zotto diff --git a/contrib/string/string_io.c b/contrib/string/string_io.c deleted file mode 100644 index fdc6da1915..0000000000 --- a/contrib/string/string_io.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * string_io.c -- - * - * This file defines C-like input/output conversion routines for strings. - * - * Copyright (C) 1999, Massimo Dal Zotto - * - * This software is distributed under the GNU General Public License - * either version 2, or (at your option) any later version. - */ - -#include "postgres.h" - -#include - -#include "utils/builtins.h" - -#include "string_io.h" - -/* define this if you want to see iso-8859 characters */ -#define ISO8859 - -#undef MIN -#define MIN(x, y) ((x) < (y) ? (x) : (y)) -#define VALUE(char) ((char) - '0') -#define DIGIT(val) ((val) + '0') -#define ISOCTAL(c) (((c) >= '0') && ((c) <= '7')) -#ifndef ISO8859 -#define NOTPRINTABLE(c) (!isprint((unsigned char) (c))) -#else -#define NOTPRINTABLE(c) (!isprint((unsigned char) (c)) && \ - ((unsigned char) (c) < (unsigned char) 0xa0)) -#endif - -/* - * string_output() -- - * - * This function takes a pointer to a string data and an optional - * data size and returns a printable representation of the string - * translating all escape sequences to C-like \nnn or \c escapes. - * The function is used by output methods of various string types. - * - * Arguments: - * data - input data (can be NULL) - * size - optional size of data. A negative value indicates - * that data is a null terminated string. - * - * Returns: - * a pointer to a new string containing the printable - * representation of data. - */ - -unsigned char * -string_output(unsigned char *data, int size) -{ - register unsigned char c, - *p, - *r, - *result; - register int l, - len; - - if (data == NULL) - { - result = (char *) palloc(2); - result[0] = '-'; - result[1] = '\0'; - return (result); - } - - if (size < 0) - size = strlen(data); - - /* adjust string length for escapes */ - len = size; - for (p = data, l = size; l > 0; p++, l--) - { - switch (*p) - { - case '\\': - case '"': - case '\b': - case '\f': - case '\n': - case '\r': - case '\t': - case '\v': - len++; - break; - case '{': - /* Escape beginning of string, to distinguish from arrays */ - if (p == data) - len++; - break; - default: - if (NOTPRINTABLE(*p)) - len += 3; - } - } - len++; - - result = (char *) palloc(len); - - for (p = data, r = result, l = size; (l > 0) && (c = *p); p++, l--) - { - switch (c) - { - case '\\': - case '"': - *r++ = '\\'; - *r++ = c; - break; - case '\b': - *r++ = '\\'; - *r++ = 'b'; - break; - case '\f': - *r++ = '\\'; - *r++ = 'f'; - break; - case '\n': - *r++ = '\\'; - *r++ = 'n'; - break; - case '\r': - *r++ = '\\'; - *r++ = 'r'; - break; - case '\t': - *r++ = '\\'; - *r++ = 't'; - break; - case '\v': - *r++ = '\\'; - *r++ = 'v'; - break; - case '{': - /* Escape beginning of string, to distinguish from arrays */ - if (p == data) - *r++ = '\\'; - *r++ = c; - break; - default: - if (NOTPRINTABLE(c)) - { - *r = '\\'; - r += 3; - *r-- = DIGIT(c & 07); - c >>= 3; - *r-- = DIGIT(c & 07); - c >>= 3; - *r = DIGIT(c & 03); - r += 3; - } - else - *r++ = c; - } - } - *r = '\0'; - - return ((char *) result); -} - -/* - * string_input() -- - * - * This function accepts a C string in input and copies it into a new - * object allocated with palloc() translating all escape sequences. - * An optional header can be allocatd before the string, for example - * to hold the length of a varlena object. - * This function is not necessary for input from sql commands because - * the parser already does escape translation, all data input routines - * receive strings in internal form. - * - * Arguments: - * str - input string possibly with escapes - * size - the required size of new data. A value of 0 - * indicates a variable size string, while a - * negative value indicates a variable size string - * of size not greater than this absolute value. - * hdrsize - size of an optional header to be allocated before - * the data. It must then be filled by the caller. - * rtn_size - an optional pointer to an int variable where the - * size of the new string is stored back. - * - * Returns: - * a pointer to the new string or the header. - */ - -unsigned char * -string_input(unsigned char *str, int size, int hdrsize, int *rtn_size) -{ - register unsigned char *p, - *r; - unsigned char *result; - int len; - - if ((str == NULL) || (hdrsize < 0)) - return (char *) NULL; - - /* Compute result size */ - len = strlen(str); - for (p = str; *p;) - { - if (*p++ == '\\') - { - if (ISOCTAL(*p)) - { - if (ISOCTAL(*(p + 1))) - { - p++; - len--; - } - if (ISOCTAL(*(p + 1))) - { - p++; - len--; - } - } - if (*p) - p++; - len--; - } - } - - /* result has variable length */ - if (size == 0) - size = len + 1; - else - /* result has variable length with maximum size */ - if (size < 0) - size = MIN(len, -size) + 1; - - result = (char *) palloc(hdrsize + size); - memset(result, 0, hdrsize + size); - if (rtn_size) - *rtn_size = size; - - r = result + hdrsize; - for (p = str; *p;) - { - register unsigned char c; - - if ((c = *p++) == '\\') - { - switch (c = *p++) - { - case '\0': - p--; - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - c = VALUE(c); - if (isdigit(*p)) - c = (c << 3) + VALUE(*p++); - if (isdigit(*p)) - c = (c << 3) + VALUE(*p++); - *r++ = c; - break; - case 'b': - *r++ = '\b'; - break; - case 'f': - *r++ = '\f'; - break; - case 'n': - *r++ = '\n'; - break; - case 'r': - *r++ = '\r'; - break; - case 't': - *r++ = '\t'; - break; - case 'v': - *r++ = '\v'; - break; - default: - *r++ = c; - } - } - else - *r++ = c; - } - - return ((char *) result); -} - -unsigned char * -c_charout(int32 c) -{ - char str[2]; - - str[0] = (char) c; - str[1] = '\0'; - - return (string_output(str, 1)); -} - -/* - * This can be used for SET, bytea, text and unknown data types - */ - -unsigned char * -c_textout(struct varlena * vlena) -{ - int len = 0; - char *s = NULL; - - if (vlena) - { - len = VARSIZE(vlena) - VARHDRSZ; - s = VARDATA(vlena); - } - return (string_output(s, len)); -} - -/* - * This can be used for varchar and bpchar strings - */ - -unsigned char * -c_varcharout(unsigned char *s) -{ - int len = 0; - - if (s) - { - len = *(int32 *) s - 4; - s += 4; - } - return (string_output(s, len)); -} - -#if 0 -struct varlena * -c_textin(unsigned char *str) -{ - struct varlena *result; - int len; - - if (str == NULL) - return ((struct varlena *) NULL); - - result = (struct varlena *) string_input(str, 0, VARHDRSZ, &len); - VARSIZE(result) = len; - - return (result); -} - -int32 * -c_charin(unsigned char *str) -{ - return (string_input(str, 1, 0, NULL)); -} -#endif - -/* end of file */ - -/* - * Local Variables: - * tab-width: 4 - * c-indent-level: 4 - * c-basic-offset: 4 - * End: - */ diff --git a/contrib/string/string_io.h b/contrib/string/string_io.h deleted file mode 100644 index b6a368698a..0000000000 --- a/contrib/string/string_io.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef STRING_IO_H -#define STRING_IO_H - -unsigned char *string_output(unsigned char *data, int size); -unsigned char *string_input(unsigned char *str, int size, int hdrsize, - int *rtn_size); -unsigned char *c_charout(int32 c); -unsigned char *c_textout(struct varlena * vlena); -unsigned char *c_varcharout(unsigned char *s); - -#if 0 -struct varlena *c_textin(unsigned char *str); -int32 * -c_charin(unsigned char *str) -#endif -#endif - -/* - * Local Variables: - * tab-width: 4 - * c-indent-level: 4 - * c-basic-offset: 4 - * End: - */ diff --git a/contrib/string/string_io.sql.in b/contrib/string/string_io.sql.in deleted file mode 100644 index 2a15e4b535..0000000000 --- a/contrib/string/string_io.sql.in +++ /dev/null @@ -1,79 +0,0 @@ --- string_io.sql -- --- --- SQL code to define the new string I/O functions --- --- Copyright (c) 1998, Massimo Dal Zotto --- --- This file is distributed under the GNU General Public License --- either version 2, or (at your option) any later version. - --- Define the new output functions. --- -create function c_charout(opaque) returns int4 - as 'MODULE_PATHNAME' - language 'c'; - -create function c_textout(opaque) returns int4 - as 'MODULE_PATHNAME' - language 'c'; - -create function c_varcharout(opaque) returns int4 - as 'MODULE_PATHNAME' - language 'c'; - --- This is not needed because escapes are handled by the parser --- --- create function c_textin(opaque) --- returns text --- as 'MODULE_PATHNAME' --- language 'c'; - --- Define a function which sets the new output routines for char types. --- --- select c_mode(); --- -create function c_mode() returns text - as 'update pg_type set typoutput=''c_textout'' where typname=''SET''; - update pg_type set typoutput=''c_varcharout'' where typname=''bpchar''; - update pg_type set typoutput=''c_textout'' where typname=''bytea''; - update pg_type set typoutput=''c_charout'' where typname=''char''; - update pg_type set typoutput=''c_textout'' where typname=''text''; - update pg_type set typoutput=''c_textout'' where typname=''unknown''; - update pg_type set typoutput=''c_varcharout'' where typname=''varchar''; - select ''c_mode''::text;' - language 'sql'; - --- Define a function which restores the standard routines for char types. --- --- select pg_mode(); --- -create function pg_mode() returns text - as 'update pg_type set typoutput=''textout'' where typname=''SET''; - update pg_type set typoutput=''varcharout'' where typname=''bpchar''; - update pg_type set typoutput=''textout'' where typname=''bytea''; - update pg_type set typoutput=''charout'' where typname=''char''; - update pg_type set typoutput=''textout'' where typname=''text''; - update pg_type set typoutput=''textout'' where typname=''unknown''; - update pg_type set typoutput=''varcharout'' where typname=''varchar''; - select ''pg_mode''::text;' - language 'sql'; - --- Use these to do the changes manually. --- --- update pg_type set typoutput='textout' where typname='SET'; --- update pg_type set typoutput='varcharout' where typname='bpchar'; --- update pg_type set typoutput='textout' where typname='bytea'; --- update pg_type set typoutput='charout' where typname='char'; --- update pg_type set typoutput='textout' where typname='text'; --- update pg_type set typoutput='textout' where typname='unknown'; --- update pg_type set typoutput='varcharout' where typname='varchar'; --- --- update pg_type set typoutput='c_textout' where typname='SET'; --- update pg_type set typoutput='c_varcharout' where typname='bpchar'; --- update pg_type set typoutput='c_textout' where typname='bytea'; --- update pg_type set typoutput='c_charout' where typname='char'; --- update pg_type set typoutput='c_textout' where typname='text'; --- update pg_type set typoutput='c_textout' where typname='unknown'; --- update pg_type set typoutput='c_varcharout' where typname='varchar'; - --- end of file diff --git a/contrib/tips/Makefile b/contrib/tips/Makefile deleted file mode 100644 index 3b9e423471..0000000000 --- a/contrib/tips/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/tips/Attic/Makefile,v 1.5 2001/09/06 10:49:30 petere Exp $ - -subdir = contrib/tips -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -DOCS = README.apachelog - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/tips/README.apachelog b/contrib/tips/README.apachelog deleted file mode 100644 index 964c6ec1a3..0000000000 --- a/contrib/tips/README.apachelog +++ /dev/null @@ -1,91 +0,0 @@ - -HOW TO get Apache to log to PostgreSQL -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Note: contain of files 'httpconf.txt' and 'apachelog.sql' are below this - text. - - -First, this is intended mostly as a starting point, an example of how to do it. - -The file 'httpconf.txt' is commented and contains two example lines to make -this work, a custom log format, and a line that sends the log data to psql. -I think that the comments in this file should be sufficient. - -The file 'apachelog.sql' is a little SQL to create the table and grant -permissions to it. - -You must: - -1. Already have 'nobody' (or what ever your web server runs as) as a valid - PostgreSQL user. - -2. Create the database to hold the log, (example 'createdb www_log') - -3. Edit the file 'apachelog.sql' and change the name of the table to what - ever you used in step 2. ALSO if need be, change the name 'nobody' in - the grant statement. - -4. As an appropriate user (postgres is ok), do 'psql www_log < apachelog.sql'. - This should have created the table and granted access to it. - -5. SAVE A COPY OF YOUR httpd.conf !!! - -6. Edit httpd.conf, add the two lines in the example file as appropriate, - IN THE ORDER IN WHICH THEY APPEAR. This is simple for a single server, - but a little more complex for virtual hosts, but if you set up virtual - hosts, then you should know were to put these lines. - -7. Down and restart your httpd. I do it on Red Hat 4.1 like this: - /etc/rc.d/init.d/httpd.init stop - then - /etc/rc.d/init.d/httpd.init start - OR I understand you can send it a signal 16 like 'kill -16 ' and do it. - -8. I should be working, query the web server about 30 or more times then look - in the db and see what you have, if nothing then query the web server - 30 or 50 more time and then check. If still nothing, look in the server's - error log to see what is going on. But you should have data. - -NOTES: -The log data is cached some where, and so will not appear INSTANTLY in the -database! I found that it took around 30 queries of the web server, then -many rows are written to the db at once. - -ALSO, I leave it up to you to create any indexes on the table that you want. - -The error log can (*I think*) also be sent to PostgreSQL in the same fashion. - -At some point in the future, I will be writing some PHP to interface to this -and generate statistical type reports, so check my site once and a while if -you are interested it this. - -Terry Mackintosh -http://www.terrym.com - -Have fun ... and remember, this is mostly just intended as a stating point, -not as a finished idea. - ---- apachelog.sql : --- - -drop table access; -CREATE TABLE access (host char(200), ident char(200), authuser char(200), accdate timestamp, request char(500), ttime int2, status int2, bytes int4) archive = none; -grant all on access to nobody; - ---- httpconf.txt: --- - -# This is mostly the same as the default, except for no square brakets around -# the time or the extra timezone info, also added the download time, 3rd from -# the end, number of seconds. - -LogFormat "insert into access values ( '%h', '%l', '%u', '%{%d/%b/%Y:%H:%M:%S}t', '%r', %T, %s, %b );" - -# The above format ALMOST eleminates the need to use sed, except that I noticed -# that when a frameset page is called, then the bytes transfered is '-', which -# will choke the insert, so replaced it with '-1'. - -TransferLog '| su -c "sed \"s/, - );$/, -1 );/\" | /usr/local/pgsql/bin/psql www_log" nobody' - - - - diff --git a/contrib/tools/add-emacs-variables b/contrib/tools/add-emacs-variables deleted file mode 100755 index 7b50aef659..0000000000 --- a/contrib/tools/add-emacs-variables +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -# -# Add local variables to C sources files to set emacs C style to 4-space tabs. -# -# Usage: cd $PG_HOME && add-emacs-variables `find . -name \*.[chy] -print` - -for f in $*; do - if [ -L $f ] || grep -q '^ \* Local Variables:' $f; then - continue - fi - echo $f - touch -r $f /tmp/.add-local-variables.$$ - cat <<- ' EOF' >> $f - - /* - * Local Variables: - * tab-width: 4 - * c-indent-level: 4 - * c-basic-offset: 4 - * End: - */ - EOF - touch -r /tmp/.add-local-variables.$$ $f -done - -rm -f /tmp/.add-local-variables.$$ - -# end of file diff --git a/contrib/tools/find-sources b/contrib/tools/find-sources deleted file mode 100755 index 6d4c5ae60e..0000000000 --- a/contrib/tools/find-sources +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/echo Usage: source -# -# Set the shell variables files, cfiles, hfiles, yfiles and sfiles with -# the names of all .c, .h, .y, and .S files in current directory tree. -# Define also some shell functions to grep the files. Typical usage is: -# -# $ cd src/ -# $ source ../contrib/tools/find-sources -# $ gh BLCKSZ # grep BLCKSZ in .h files -# $ gcl MAXTUPLEN # list all .c files containing MAXTUPLEN -# -# THIS SCRIPT MUST BE SOURCED FROM BASH. -# -# Copyright (C) 1999 Massimo Dal Zotto -# -# 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. - -# Build the file lists -dir=${1-`pwd`}/ -cfiles=`find $dir -name \*.c | sort` -hfiles=`find $dir -name \*.h | sort` -yfiles=`find $dir -name \*.y | sort` -sfiles=`find $dir -name \*.S | sort` -files="$hfiles $cfiles $yfiles $sfiles" - -# Define some functions to grep the files in the lists -function g() { grep -- "$*" $files /dev/null; } -function gc() { grep -- "$*" $cfiles /dev/null; } -function gh() { grep -- "$*" $hfiles /dev/null; } -function gy() { grep -- "$*" $yfiles /dev/null; } -function gS() { grep -- "$*" $sfiles /dev/null; } -function gl() { grep -l -- "$*" $files /dev/null; } -function gcl() { grep -l -- "$*" $cfiles /dev/null; } -function ghl() { grep -l -- "$*" $hfiles /dev/null; } -function gyl() { grep -l -- "$*" $yfiles /dev/null; } -function gSl() { grep -l -- "$*" $sfiles /dev/null; } - -# end of file diff --git a/contrib/tools/make-tags b/contrib/tools/make-tags deleted file mode 100755 index b5b606314a..0000000000 --- a/contrib/tools/make-tags +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# -# Makes an emacs tagfile for all .[chS] and .el files in the current -# directory tree. - -etags $(find . -name \*.h) 2>/dev/null || true -etags -a $(find . -name \*.c) 2>/dev/null || true -etags -a $(find . -name \*.S) 2>/dev/null || true -etags -a $(find . -name \*.el) 2>/dev/null || true diff --git a/contrib/tsearch/Makefile b/contrib/tsearch/Makefile deleted file mode 100644 index 8241c261c0..0000000000 --- a/contrib/tsearch/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/tsearch/Attic/Makefile,v 1.1 2001/10/12 23:19:09 tgl Exp $ - -subdir = contrib/tsearch -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -MODULE_big = tsearch -OBJS = parser.o crc32.o morph.o txtidx.o query.o gistidx.o rewrite.o - -DATA_built = tsearch.sql -DOCS = README.tsearch -REGRESS = tsearch - -parser.c: parser.l -ifdef FLEX - $(FLEX) $(FLEXFLAGS) -8 -Ptsearch_yy -o'$@' $< -else - @$(missing) flex $< $@ -endif - -EXTRA_CLEAN = parser.c - -include $(top_srcdir)/contrib/contrib-global.mk -# DO NOT DELETE diff --git a/contrib/tsearch/README.tsearch b/contrib/tsearch/README.tsearch deleted file mode 100644 index c63ae91edd..0000000000 --- a/contrib/tsearch/README.tsearch +++ /dev/null @@ -1,348 +0,0 @@ -Tsearch contrib module contains implementation of new data type txtidx - -a searchable data type (textual) with indexed access. - -All work was done by Teodor Sigaev (teodor@stack.net) and Oleg Bartunov -(oleg@sai.msu.su). - -IMPORTANT NOTICE: - -This is a first step of our work on integration of OpenFTS -full text search engine (http://openfts.sourceforge.net/) into -PostgreSQL. It's based on our recent development of GiST -(Generalized Search Tree) for PostgreSQL 7.2 (see our GiST page -at http://www.sai.msu.su/~megera/postgres/gist/ for info about GiST) -and will works only for PostgreSQL version 7.2 and later. - -We didn't try to implement a full-featured search engine with -stable interfaces but rather experiment with various approaches. -There are many issues remains (most of them just not documented or -implemented) but we'd like to present a working prototype -of full text search engine fully integrated into PostgreSQL to -collect user's feedback and recommendations. - -INSTALLATION: - - cd contrib/tsearch - gmake - gmake install - -REGRESSION TEST: - - gmake installcheck - -USAGE: - - psql DATABASE < tsearch.sql (from contrib/tsearch) - - -INTRODUCTION: - -This module provides an implementation of a new data type 'txtidx' which is -a string of a space separated "words". "Words" with spaces -should be enclosed in apostrophes and apostrophes inside a "word" should be -escaped by backslash. - -This is quite different from OpenFTS approach which uses array -of integers (ID of lexems) and requires storing of lexem-id pairs in database. -One of the prominent benefit of this new approach is that it's possible now -to perform full text search in a 'natural' way. - -Some examples: - - create table foo ( - titleidx txtidx - ); - - 2 regular words: - insert into foo values ( 'the are' ); - Word with space: - insert into foo values ( 'the\\ are' ); - Words with apostrophe: - insert into foo values ( 'value\'s this' ); - Complex word with apostrophe: - insert into foo values ( 'value\'s this we \'PostgreSQL site\'' ); - - select * from foo where titleidx @@ '\'PostgreSQL site\' | this'; - select * from foo where titleidx @@ 'value\'s | this'; - select * from foo where titleidx @@ '(the|this)&!we'; - -test=# select 'two words'::txtidx; - txtidx ---------------- - 'two' 'words' -(1 row) - -test=# select 'single\\ word'::txtidx; - txtidx ---------------- - 'single word' -(1 row) - - -FULL TEXT SEARCH: - -The basic idea of this data type is to use it for full text search inside -database. If you have a 'text' column title and corresponding column -titleidx of type 'txtidx', which contains the same information from -text column, then search on title could be replaced by -searching on titleidx which would be fast because of indexed access. - -As a real life example consider database with table 'titles' containing -titles of mailing list postings in column 'title': - - create table titles ( - title text - - ); - -Suppose, you already have a lot of titles and want to do full text search -on them. - -First, you need to install contrib/tsearch module (see INSTALLATION and USAGE). -Add column 'titleidx' of type txtidx, containing space separated words from -title. It's possible to use function txt2txtidx(title) to fill 'titleidx' -column (see notice 1): - - -- add titleidx column of type txtidx - alter table titles add titleidx txtidx; - update titles set titleidx=txt2txtidx(title); - -Create index on titleidx: - create index t_idx on titles using gist(titleidx); - -and now you can search all titles with words 'patch' and 'gist': - select title from titles where titleidx ## 'patch&gist'; - -Here, ## is a new operation defined for type 'txtidx' which could use index -(if exists) built on titleidx. This operator uses morphology to -expand query, i.e. - ## 'patches&gist' will find titles with 'patch' and 'gist' also. -If you want to provide query as is, use operator @@ instead: - select title from titles where titleidx @@ 'patch&gist'; -but remember, that function txt2txtidx does uses morphology, so you need -to fill column 'titleidx' using some another way. We hope in future releases -provide more consistent and convenient interfaces. - -Query could contains boolean operators &,|,!,() with their usual meaning, -for example: 'patch&gist&!cvs', 'patch|cvs'. -Each operation ( ##, @@ ) requires appropriate query type - - txtidx ## mquery_txt - txtidx @@ query_txt - -To see what query actually will be used : - -test=# select 'patches&gist'::mquery_txt; - mquery_txt ------------------- - 'patch' & 'gist' -(1 row) - -test=# select 'patches&gist'::query_txt; - query_txt --------------------- - 'patches' & 'gist' -(1 row) - -Notice the difference ! - -You could use trigger to be sure column 'titleidx' is consistent -with any changes in column 'title': - - create trigger txtidxupdate before update or insert on titles - for each row execute procedure tsearch(titleidx, title); - -This trigger uses the same parser, dictionaries as function -txt2txtidx (see notice 1). -Current syntax allows creating trigger for several columns -you want to be searchable: - - create trigger txtidxupdate before update or insert on titles - for each row execute procedure tsearch(titleidx, title1, title2,... ); - -Use function txtidxsize(titleidx) to get the number of "words" in column -titleidx. To get total number of words in table titles: - -test=# select sum(txtidxsize(titleidx)) from titles; - sum ---------- - 1917182 -(1 row) - -NOTICES: - -1. -function txt2txtidx and trigger use parser, dictionaries coming with -this contrib module on default. Parser is mostly the same as in OpenFTS and -dictionaries are simple stemmers (sort of Lovin's stemmer which uses a -longest match algorithm.) for english and russian languages. There is a perl -script makedict/makedict.pl, which could be used to create specific -dictionaries from files with endings and stop-words. -Example files for english and russian languages are available -from http://www.sai.msu.su/~megera/postgres/gist/tsearch/. -Run script without parameters to see information about arguments and options. - -Example: -cd makedict -./makedict.pl -l LOCALNAME -e FILEENDINGS -s FILESTOPWORD \ - -o ../dict/YOURDICT.dct - -Another options of makedict.pl: --f do not execute tolower for any char --a function of checking stopword will be work after lemmatize, - default is before - -You need to edit dict.h to use your dictionary and, probably, -morph.c to change mapdict array. - -Don't forget to do - make clean; make; make install - -2. -txtidx doesn't preserve words ordering (this is not critical for searching) -for performance reason, for example: - -test=# select 'page two'::txtidx; - txtidx --------------- - 'two' 'page' -(1 row) - -3. -Indexed access provided by txtidx data type isn't always good -because of internal data structure we use (RD-Tree). Particularly, -queries like '!gist' will be slower than just a sequential scan, -because for such queries RD-Tree doesn't provides selectivity on internal -nodes and all checks should be processed at leaf nodes, i.t. scan of -full index. You may play with function query_tree to see how effective -will be index usage: - -test=# select querytree( 'patch&gist'::query_txt ); - querytree ------------------- - 'patch' & 'gist' -(1 row) - -This is an example of "good" query - index will effective for both words. - -test=# select querytree( 'patch&!gist'::query_txt ); - querytree ------------ - 'patch' -(1 row) - -This means that index is effective only to search word 'patch' and resulted -rows will be checked against '!gist'. - -test=# select querytree( 'patch|!gist'::query_txt ); - querytree ------------ - T -(1 row) - -test=# select querytree( '!gist'::query_txt ); - querytree ------------ - T -(1 row) - -These two queries will be processed by scanning of full index ! -Very slow ! - -4. -Following selects produce the same result - - select title from titles where titleidx @@ 'patch&gist'; - select title from titles where titleidx @@ 'patch' and titleidx @@ 'gist'; - -but the former will be more effective, because of internal optimization -of query executor. - - -TODO: - -Better configurability (as in OpenFTS) -User's interfaces to parser, dictionaries ... -Write documentation - - -BENCHMARKS: - -We use test collection in our experiments which contains 377905 -titles from various mailing lists stored in our mailware -project. - -All runs were performed on IBM ThinkPad T21 notebook with -PIII 733 Mhz, 256 RAM, 20 Gb HDD, Linux 2.2.19, postgresql 7.2.dev -We didn't do extensive benchmarking and all -numbers provide for illustration. Actual performance -is strongly depends on many factors (query, collection, dictionaries -and hardware). - -Collection is available for download from -http://www.sai.msu.su/~megera/postgres/gist/tsearch/ -as mw_titles.gz (about 3Mb). - -0. install contrib/tsearch module -1. createdb test -2. psql test < tsearch.sql (from contrib/tsearch) -3. zcat mw_titles.gz | psql test - (it will creates table, copy test data and creates index) - -Database contains one table: - -test=# \d titles - Table "titles" - Column | Type | Modifiers -----------+------------------------+----------- - title | character varying(256) | - titleidx | txtidx | -Indexes: t_idx - -Index was created as: - create index t_idx on titles using gist(titleidx); - (notice: this operation takes about 14 minutes on my notebook) - -Typical select looks like: - select title from titles where titleidx @@ 'patch&gist'; - -Total number of lexems in collection : 1917182 - -1. We trust index - we consider index is exact and no - checking against tuples is necessary. - - update pg_amop set amopreqcheck = false where amopclaid = - (select oid from pg_opclass where opcname = 'gist_txtidx_ops'); - -using gist indices -1: titleidx @@ 'patch&gist' 0.000u 0.000s 0m0.054s 0.00% -2: titleidx @@ 'patch&gist' 0.020u 0.000s 0m0.045s 44.82% -3: titleidx @@ 'patch&gist' 0.000u 0.000s 0m0.044s 0.00% -using gist indices (morph) -1: titleidx ## 'patch&gist' 0.000u 0.010s 0m0.046s 21.62% -2: titleidx ## 'patch&gist' 0.010u 0.010s 0m0.046s 43.47% -3: titleidx ## 'patch&gist' 0.000u 0.000s 0m0.046s 0.00% -disable gist index -1: titleidx @@ 'patch&gist' 0.000u 0.010s 0m1.601s 0.62% -2: titleidx @@ 'patch&gist' 0.000u 0.000s 0m1.607s 0.00% -3: titleidx @@ 'patch&gist' 0.010u 0.000s 0m1.607s 0.62% -traditional like -1: title ~* 'gist' and title ~* 'patch' 0.010u 0.000s 0m9.206s 0.10% -2: title ~* 'gist' and title ~* 'patch' 0.000u 0.010s 0m9.205s 0.10% -3: title ~* 'gist' and title ~* 'patch' 0.010u 0.000s 0m9.208s 0.10% - -2. Need to check results against tuples to avoid possible hash collision. - - update pg_amop set amopreqcheck = true where amopclaid = - (select oid from pg_opclass where opcname = 'gist_txtidx_ops'); - -using gist indices -1: titleidx @@ 'patch&gist' 0.010u 0.000s 0m0.052s 19.26% -2: titleidx @@ 'patch&gist' 0.000u 0.000s 0m0.045s 0.00% -3: titleidx @@ 'patch&gist' 0.010u 0.000s 0m0.045s 22.39% -using gist indices (morph) -1: titleidx ## 'patch&gist' 0.000u 0.000s 0m0.046s 0.00% -2: titleidx ## 'patch&gist' 0.000u 0.010s 0m0.046s 21.75% -3: titleidx ## 'patch&gist' 0.020u 0.000s 0m0.047s 42.13% - -There are no visible difference between these 2 cases but your -mileage may vary. diff --git a/contrib/tsearch/crc32.c b/contrib/tsearch/crc32.c deleted file mode 100644 index dc93db727c..0000000000 --- a/contrib/tsearch/crc32.c +++ /dev/null @@ -1,103 +0,0 @@ -/* Both POSIX and CRC32 checksums */ - -#include -#include -#include - -#include "crc32.h" - -/* - * This code implements the AUTODIN II polynomial - * The variable corresponding to the macro argument "crc" should - * be an unsigned long. - * Oroginal code by Spencer Garrett - */ - -#define _CRC32_(crc, ch) (crc = (crc >> 8) ^ crc32tab[(crc ^ (ch)) & 0xff]) - -/* generated using the AUTODIN II polynomial - * x^32 + x^26 + x^23 + x^22 + x^16 + - * x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1 - */ - -static const unsigned int crc32tab[256] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, - 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, - 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, - 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, - 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, - 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, - 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, - 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, - 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, - 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, - 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, - 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, - 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, - 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, - 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, - 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, - 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, - 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, -}; - -unsigned int -crc32_sz(char *buf, int size) -{ - unsigned int crc = ~0; - char *p; - int len, - nr; - - len = 0; - nr = size; - for (len += nr, p = buf; nr--; ++p) - _CRC32_(crc, *p); - return ~crc; -} diff --git a/contrib/tsearch/crc32.h b/contrib/tsearch/crc32.h deleted file mode 100644 index 97254a4a90..0000000000 --- a/contrib/tsearch/crc32.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _CRC32_H -#define _CRC32_H - -/* Returns crc32 of data block */ -extern unsigned int crc32_sz(char *buf, int size); - -/* Returns crc32 of null-terminated string */ -#define crc32(buf) crc32_sz((buf),strlen(buf)) - -#endif diff --git a/contrib/tsearch/data/test_tsearch.data b/contrib/tsearch/data/test_tsearch.data deleted file mode 100644 index 21f649e638..0000000000 --- a/contrib/tsearch/data/test_tsearch.data +++ /dev/null @@ -1,500 +0,0 @@ -\N i8 hy qO xa jL wR le l5 JA jX zf RO vW wD wA CC mm wH FN yd td L8 ec rv th oC iX iR sm y4 gH pR qG UE cx ww zV c9 Zv TX Eo F5 Gd KM b9 wB rm Ym YL XJ u7 XZ uK iq tm uX di iF uC hc ge -\N gr tY pH jH PO WA Iw Ag Wq r3 yd oW rb ip et eJ yl a9 dk pu y6 su Ov hF xe qE SD qR zT kP ml ea tp pg dQ e3 s3 hH gn hZ j7 hB qS qD V0 v4 W0 nu Ee wK ez uN rD sz wX e7 pn yF gH uh ki KX Rb qV F1 bH sR yJ ry r2 -\N q1 q8 wP w9 vS ww rQ dE qT wo qP Sa Rv MC Sn u8 yL -\N hv ra sA fR qs pS 4w z5 lS wT Ad wY q6 Zg bd vT wA E4 FT w7 LD eS yg et iC pM sw ja qv Ov jM ma b3 Wu wi qy uG HS Wh eX rT tJ eN ur e2 ut gv aS ui dY qY dU qO Gv cY lx kw xM FL x2 HD ny nu HH DT wG wH rS Wb wZ yY yU tj ha aK rw sW iO h1 UX ku v6 wc Qa Rv xb S8 Qd F2 zo K2 eW w4 yH yu yi -\N rs tT gp qh wT q6 lG Zh vR B8 uY uU LH pX jM ww qE xu FP FD Rs qu KI dR fN gQ gW jv Oq ZT 2R lc ke wg l9 x3 x5 7G Vs ar e7 u2 s8 t0 aV dJ KL Nm U2 zp GF yw eE oc tW a1 -\N qs Uz wR Gq Q9 rl E0 pe dj a9 hP qw AW ER KQ Pp uu pl zO wp Fr R6 ej pv u5 hh aV lW ko qC Pn Qj EZ n8 wN eU tQ -\N pO h9 rd qs hR lA U0 Um me wP 0P rl mV rc ab r0 fe fJ fK qn jh Iy cn lB bl lN b5 LL YG YH qt qp uZ oD dQ aS gn cR qA wa cU Fy ZY vo xk Eq vg mR ns yY t7 yI op th yO oV pv em tc hg aZ iO S5 ct Os WU LQ Dr mP Hk sI gX -\N hm k5 pw a5 qh nb q3 ql wR wT z7 Oz wU WH kv q8 c3 mt Mg Hb A3 rz pZ uO y1 rb av uS eK dz q0 D3 qW j2 ls wy qq Jf nG eo Gl ed ix eM he qT dU hp jc f2 m9 qP hB l4 gY zF l6 Qr Dn cP x1 OH QK kK S3 Hy wG ZS ot wJ sl oZ iE e9 ay iT u5 ai hM gH pY hz qK ki h8 jA zu QB Ei vc Qj Hg EV H6 yH u0 tb iD -\N qg d1 bt c5 r3 iV g6 D7 RC ml Gk uH yn y0 zO UH qD wh Ib uo u4 oM qG qL yZ -\N hb a3 q5 pL yj lo QY kI Sy fo Rj kK zq dL wn 7a zi wN wM yr w3 tv r1 -\N fT k6 iZ qN qj q2 q3 bL Zd AV RO wO lK Tg eA ew eD y1 ia yl iC g6 po aW sC zm qn gl wq qW zR Jp wt j5 Gs vt qt yc rR oP yW tL yE hr i8 tB uu j0 xd lz vu nL QD Fu wg Pf Wj bT Ee wH t2 TP sz uM oo tg ha u4 f5 sW pQ pR jU qK MH ki zB vj OB cX DF Hj Ef CJ Q6 u9 tv rV o4 sY ru fQ ir -\N pS kO uK tZ vV uM t9 uk k2 jA o6 ob -\N qs nb GH lD q7 jC SP El w0 py qx i2 qE la RL qw tu ti dQ ue iv OI wa Qr ED t3 fg oa of rr fv qZ xn WU wQ Te hx -\N yB tY pq az fI qg qN lA bu ji lG WG q8 mi CV rl Up LG om oQ yM pV iN aQ gg js hA On ww qR bj VN PV HE b5 mh qe Cc mk qt RB eu qy rW tr qo eC oP sN oH e2 aO iv e4 hy dT s6 qT P1 hB Ih qS wg x1 BD L1 t1 rO R9 uV Wb aw gU os t0 aH e0 s0 hj pE Or qJ zZ qL Fd ks QV bq QM bG EC RY oj u8 u0 yJ ru r1 yX o7 -\N z4 wR qz cg nQ Ir bB GB w7 E5 zc pJ E9 pX uO fP tS aQ db q9 Iy qE Zv xu A9 l1 Mb qw Tc qu fi hw ur dE e4 hK lj wo wf Fi EP Rl wH vh ek Vp oi sv rH ay hj Px aa eR tv do ir -\N tR o9 gB tT pP qa qs a5 pS rf q1 kj by Ub RU Ox Co O8 nY wP wA wS RD Kk b1 zc rl rz uO tS ig fH db qm q0 bg Rr FU ld Lr WB En nD cW vr HY rn qr eN eM aU p8 so oH ut hZ gQ wp Ow bE ky wj DW t1 Pl Er Wc ot na R9 wL ou uN uM wX iQ sc e8 sn re rr f7 hz h4 ce wz qX wx kp Px TL TX Ai wQ Hf EC 6U rZ og yt ok yy yp -\N sA pP a7 qM qh Of je qj lO pH wT H0 ji cg z8 2V xS zl mo IK Hm on tU d8 av oT pN iV eZ ja qn Pq wy 7R MQ qu p1 tu p6 ti ur pj uy ui qO I9 qA nJ XM S1 Ya FB 7J rO Wn t6 wZ yU iQ yI gO en pb aJ f5 hf ug uh hk aV pR wl wz Im jA v9 U2 ks IT br wV wN sE iA o5 ox eI r2 iG aj sP -\N sA TN z8 ew uO eH g8 zT wy 27 FF uH TE eN pd eh hV 2E wh TY oi sW xx 2P Qs MX wB Q3 rL eQ aa eU -\N d4 eF tA zQ j2 Em C0 vV wf kJ dw uk qL Y9 rN -\N SQ nm kl w8 uR Kz C1 pC y1 g4 oI jV wr zY EW BY Se eC yn ti gQ gT Rd l5 EJ yP tk dA qZ qX IR wm ON Q2 To eW -\N rd gu z2 kj qk Bl 6D Wy Nw xq Iu 8t rI uC kq nX qL Oa VI kd o6 -\N ra gr hE wY Q0 oW tI ia pB hA qR lV ms QU Pu qw qr ml qt ep sV i5 oF fM oe nL xh x1 xz u4 ha ao fc ug pW nh N9 qV kh vx Uq w1 u0 eI iF -\N q1 d2 qz Zd JD Qb WJ nT Ah mJ eA eD y1 et fJ qE En b8 ty iv ht fV tN tM sg jb ky AI en us tl ud iU zJ qL U1 ci ru iw tW -\N fR ub h9 pD Ub jK VH z6 wU WH wP 5z YT w9 w0 uY om Tl rc r6 ax d7 et y2 tw dz se vF Ii m3 lf b4 Jf vr qw qy uF es qp eN tL to yE ue ph e3 uy i0 jl pz oe qO zP wp Ft KA zF qD wd kr QF l9 mm wF QX EF t3 x8 ex rG ev s8 yS iT dA rw aL hN tc f6 fv nd Nc AD Fj NR X0 BX yq Ti rX ok tb hx o8 dp -\N o0 jq Un xU q8 wO qQ Gg ta oJ ec aZ dL BL wB -\N o9 iJ pq gu gp nv qk GG lA q4 nW bo z8 9a Iw wU q8 Eh wI nT JK uT ys C1 r5 uP y1 yl py oY hT gd tD db qn cz qW lp Re c7 Dh j5 Ia bz Dj qr qt Wd Wf qi rT sV uL uZ tL ta yR e4 tM sg pc jv hC hV lc xg xM bR vf R8 na wL ou td wC up rJ s8 e8 iR yS iI qK P0 lT Ho wb X8 BV LW w1 rZ eW aa rV ry gX o8 -\N tT hn gN un dB fU uQ qf d4 q3 PP ji lF wU bX q8 Hx kb nY T5 bN Hb Ex yf eF yj g1 g2 tO yk g3 eJ sK hY dv qc gj qv sy bg wr nA wy bx Z0 RC rm ml uG te qp i5 ue oJ s4 im oq qT Gx Sa gT l4 SV AT v3 Bq mv wD X3 80 x8 aq Xk rG yP en gS us dq aK tz aL tx o2 dG f9 kV Or h4 jY k1 jO h8 kp lT Os kh as tn eU ul tm sU aN tW sP -\N Za YI pe sH pV y4 y5 hY tH jg QY qt KE ti ue QK yY iE cq wl P0 LW mF eR w5 -\N k9 bt xU kc me IS O5 z9 kb GV uR rc oE sK qn ve Wi Mm rn eu to ue uy qA xf bY t1 td t7 aw up yF pR dK cG zr Sc 3d At RW EC rL sT Zo rN do -\N o9 z5 wY vI ya eA ee fO gf vA Ov ww Rr wr lB Ro qq vr Gj nw rU ym iv s4 hu tM wo wp zS bR Fs wG ej DU Y1 yT yU e7 eb em dD pQ v7 cr UM Ae OZ 0z KC Tq RW ZL RT wB Y9 Xv tm tQ di eO tE gC -\N tT un qs qN a7 qh je qj k0 O1 wR q6 wY AB Q9 Qm Wr eA er eH pi hI sC hS m6 W1 bv Lo ZR Tn YK ep oP es Ve XX sB uX hG sa gQ qP wd N2 zH wF Xf wJ Y3 wL e7 os u4 oN iP kN ko Qp S7 lY zN bA WU U4 kh F4 zo Y9 Q6 oh iw tQ -\N qa a4 gu a7 cp z1 hE Ma q7 LU Dp w7 eA rc ee d8 y4 tw eZ iM aE Bv Ii qE VB zT lC lV WM Ro LK qr HP rE TW yv es fp aS zU oe qU qI BP wg cP P7 v4 ek rD wC ar rJ tj e8 od e0 pm h2 h4 In Qf WU WI 19 bJ rL rC eE yJ eT tW eP -\N gV qd kj cd T3 c3 IH wS rg mC rx LH fD g8 gh cc vw b7 qe aT j7 qO ws wG oy t6 t9 gO eb e8 us u5 rq Oe zJ jY OZ cJ wb be Ei Pm og sE w4 yu XW sU yX iF -\N o9 ub rd hW gs z3 Ql nQ RU WG jC 1T kv mr ZM Ah Dd JK w8 eJ aQ ig y8 pp fJ li wq jj cc qR No wy wu En bx Yr qy oO es fy pd tK ix ph yR sf vX PN P2 jQ Fs ED oy Yk os iE s9 u5 aK ud gD uf kB xc U1 xm Eu xW 19 wN Vh w1 To eE eR aa rB rN ru aN r1 eI -\N SE kl 7h B6 xS yM tP an tA qb GN UO Pt xi Cl QP qy oP Vr ym rI ti tL i5 e1 e4 i9 ff I5 qP Jx Ht QL uo en pE ku h7 IW wN w4 eY iA sI -\N ql xT wI K6 ew sF eG uP eH oY sq ja g9 i3 qE cv l1 qq bv W2 La eu Wg eC ef oH fs tB pc xd qS nL Qu FN DY oi iU yF re fc hj hk xv zN ZZ w1 eW -\N pO al hm qk jt cd ju nm LI RS w9 Ev uT eA 2f r4 d6 ey iM pa Nu wr m4 Is bc xZ W3 eu Tb HA ft p4 ti to hr dY aF I6 Iz R4 Jb x7 wJ Xg na rF gI at pn gD re WQ qZ ze bO wc vz Sm zo My ye u7 oh DK w5 iS yX tW fE dp -\N jL Za GK cM wU vQ jC zc iu mB oE fO fP iC sC 2l HY qr eB p5 pf dQ Pa Fy lc td sz oo aw u1 rJ fl tz Nx Aq xx OZ xb 55 Y0 -\N uQ wR lH jV rI i7 ss qO gY bT S3 u1 dy OX Hg it -\N pS hR lF jX bN QQ uP eH ab yl pN jg NG bz Gd qr yW i9 j8 ZI 3V oZ at hd cX oj u9 rt uz ro ov -\N SQ ga NY SE cj ID rg r3 pK Kv ee sH eK dk sZ pp q0 mN Az kP ei qi rY eM ph p9 gW hC m0 cP EA mn Yf t1 5y wX oL e6 ec u2 e7 uh uj uk aV qL lW qX zr qV Mw Qg Cq wW wB PW Tu w2 mF Ut gK af yo ie ob -\N hn um a6 q7 Af Du r4 uP tP eJ sK lo Le m8 Rp eu ei qi KY oP oF tp ur oJ hu tB dY qU gT tf oZ wC s7 e7 ua pW aX Nb wx WY Fj wn 18 wV Es yq ok w4 uz yX yC -\N pA qg qh q4 Fv Qz kx q6 Cp GB c6 pr eH id iN qW we bk WN qq b6 qy qu es ic s1 oG gn wp OP qF Ic rO os yP rJ fj aG oC ay dA fv wl Qp F1 Yx n7 Ea w2 LY yJ iq iw rM o5 -\N o9 pS d3 lP wR Qc Md E5 rk w0 pM gx lf kU qt qp to tC pk fB tB qI lh nt Yd Vt ot rA tg gD zX wx vj RQ Cr HM mA JP Vg u8 rt eI it -\N dX dV h9 rf qf uW a8 qh Uv K3 RI IS YR r3 eq uU Tz yN y6 qc ps jf wq xe WX lC qR j4 kU xX NB 4z Sr tr uq p6 uZ oF i6 s1 fs pj tC hu qU hZ f1 hp lj S4 QX tg yP gS oB tz dS sW pm ug hM iP qL lE vl wQ TB Xv eQ w2 yG w4 sT o6 -\N qd q4 PA z6 Qz IA 70 r3 mB iu eS r5 gh T9 Cj vZ qw Mb kO vt qr qt Gh qo ty eB kq N1 XB EF rP ek gU rG s7 rJ sn ai hg o1 uj pR jT Fg v0 Tq TX wW bJ BM Ct w1 Zi rN ox iw ri -\N al rd w8 vP yd yk r0 pi po se sr qA l0 QK iR e9 hM kC rZ aa w6 -\N un pq qd a8 z2 qk z5 WS bi xY Qx WG wP T4 mJ GV Qm rg c6 w7 w9 eS y1 g2 eJ yz gg qc qn wq qW M9 WX qE kR 27 FP Fq m7 xp 3P qr rR tr ij il eh aU s1 uC fX ut qU sj j8 j9 Ya nr Rz wG wH EG x8 sl t7 yU Vf ay dS ap re dH qG qH qJ hz qK zZ qX k3 cy IQ OX QV Eu nx n6 6R LQ n0 Y0 Uq tb sY iw fm aN -\N yV dC qs gM q2 cV Ok wT B2 cj wU mr zj kn E5 iu pZ r8 pe fP oT tq a9 y5 sZ eZ cl wq qQ WV A7 lN kY Jd qe qr yx RM qi ea LN TE y9 eV eN eh iv tX e3 aS tN j8 wf xh cO FL nC wk xz ES Rx Ee wH uB aq u1 ar e7 up iT iU o2 wl ko jO cu Pc WO AL HM Uq rN ul yZ ro -\N pw NA wU JD yf oE QR Xr sk wa Hw QL wG x6 S9 u7 aM -\N uv tR ub k7 qg hE U6 jt gs z3 by TN bi AV z7 jC ck Q7 2N nY CX km mK RF pJ XI LH sF uP yj tO ia ab tq fq pM fD qc qv ps su qW FU xu cm Zb bc qr qt Tn ei rW Gl p1 Xi qo tt ed ef rI iz yW oH tC uy tV aS qU l4 Qr t4 wX e5 ae op oa em tz gD dq rw ug dr UX qJ Be ko cG nl JE AJ xW Q1 vv AX rL w2 yt aa u0 eU ah -\N dC pH SQ jt ql Un q5 cg lK w9 uR uY pZ uO sX qv qQ cc lN fu ym ho Su PN qA bQ Pd wj Wj Yk ou wL rK o2 pT UC kM jA wm ry rM ob -\N gB pw qf wE q3 lS q4 SY bL lG q8 T3 WL rg eD io eF if oI hP lo kW wy qw ei YZ rT es p6 fp hi qO bn Qw wg CY np uV yY oa uo iR of em ug x9 qH nj n8 Ea u8 eR w6 -\N iJ dg cd lw GK wU zl Dd Eb eq sG ia am iN wq xt NK wr xJ qq p5 pd pk aS sd fN lj jW FK l9 nt wL oo fj sb u4 gS fx hg o1 dr fb hj h8 xc yq CH eR E2 aa af ah ob -\N a2 o0 hn pD iZ hW jG q1 jL qz IP le me wI bB r3 Z7 g1 eH tD sw g9 qQ c9 vy uD qo es eC tJ uw dQ ur hJ dY oe zP lk l5 FL wj Ys t2 ej t4 ek rS sl yU oa u3 gD pm rw h1 pR h2 pY wl 2P S7 wQ 6R mI 10 ox o6 -\N i3 qw EE ur cY nX R2 Wj t2 uB iR aJ cL QM u0 oz -\N qd qN Un qz xY nQ AN Kg Hc c6 w8 93 eq tS g9 wy mg W3 RB 3F Wf rW KT oP es ef aT eM s6 pc wg bW x1 xl wG HL Yk yO eb ud hM hl pY wb U4 zp bJ BM sE sR sY ox aM -\N rc IX QS Ls qy aT ut pk Yo Ys ec hs lQ xv ks -\N yB al zf wS CN ac ih tH ww VB kT b3 xo qe qi te ea p8 tN qD cI Ix xk Pk BG Rc tl f4 wb rB ru -\N iy qd a5 jq jw qh SW Fv Oz cj Hc QQ ya ee yN pr av oR uS iV fA qb q9 bh nS D0 qe I1 b0 FH qy qu qi rY oS uL hq rI ix e1 aO p0 qT sf qI UH ll KO lx nZ Sg Jz Hq Sh P8 x3 wG rD sx yO yP u3 pv rq dS tc rr wx lR xb wn Ep Hh bK yw Q6 og yr yG sI tQ do iF -\N hv qa qf jG hE q1 kj qz Bh lr kn rj Th Kz eF eH av pp i1 aR gl UR Lr bz xp Yr ZE qt Tn es fL hw s5 qA ED t4 wZ sx rG sv e9 fz hf aL h1 aV bG Ym eE yG -\N k8 nn jy q4 WD lF xU Q9 A1 4V yd mB r6 yh pB tA g6 dn D3 PL j1 jk WC cn wy 26 rR TE ti fa e4 uy fB gR hB kD lc qF P5 wh AU Fa Iv Xo HF ot EG rA Wv TP ec yO aH iU pW hj aC h3 pY k2 U1 wB rL rZ yt eR w6 ru af yo eP -\N qd uQ qh qM q3 VG Qc c5 RD vP uT eq on yN ii XP uP r8 d0 sZ qx UE PL lX qE wr QR lM nH qt HA qo KI rI e2 tX iv aO s3 ow KP xf Rh Ya R2 Rk CW nt bY wD J8 t1 HK Y1 ns t6 wC ev sQ rq yF UX Aw cH Qs U2 zN Sm RT wB bK yq DH 8W w3 rC yG o3 yi ox ov ir -\N U0 q7 Qb mL oR nU b5 1L xB tr tp in qT hZ So V6 DQ o2 qH wl Nb rV fW -\N sS jr Zf Zh XT oY hY aW y8 js Ob wq Ny OR vy fi eN tB qI j9 gT Ib ot oy rD e5 Y6 tg th pT gq wz RT rL eW fm ie ri ir ro ah -\N o0 qj H9 wY ee g9 gk Jd FG qt 3D fu rU iz tL fd tV aD hL wp OO wf nB ez sv tl f4 dr Oy rp -\N ak iL k6 qh q2 VD K3 Zd bo lJ K7 km 5c uT rz yd uP uA is r0 qn zQ wq j1 qE cv Pw FU md BW Yw qq Ra rW qu eX ik aT y0 rU ti yW fZ ic aO ow gm jc I7 Nf P4 FJ xg kr bR xk BS mb Pk HL wL TA ez sv e9 us oM rw ap gq wl k2 qZ h8 GU kf eT ru tQ ag uz rp -\N yB az dd fU rf hW qg wE U9 O3 q5 q6 Ag c2 O7 wA Kh w8 vO mC yg tU uA Uh tA tw ih hU fJ su bg ww bh kW Ry Ru wy kY wu wi Fw 20 b9 qo ik oA eV hw s1 e1 e3 fC uu s5 tN qY hZ jc dO OU jQ Gb kF Pf xl x3 YV Lz iQ eb e8 os sn fx dw qG qL wc ka n8 GF LY sE tv yK di sI o7 r2 rp -\N iL mJ vI sD ia y6 wq rm p5 uX ho nr EF ej WQ iq fn -\N fT cs Uo io er iC tw ig mM c9 xK Ab ZE uw i5 s1 e4 pl ui f2 lj P4 Sf X4 kZ ej ez eb oV of rw dy aV qH f0 h5 ki qX cX EB og gK oz uc -\N Ul IO zd kn w9 y3 wt qq Wp jl I9 Jk cA h5 wx wB tm do -\N iy hv cs A2 ee yz y6 gk kQ Em qy uq ts W0 rq rr VT Pb nc Q5 -\N qN q3 vT vU yk eJ fP tw zm qq qy y9 hH wo wg Rh EP x5 wK mR el L9 aV hz w5 -\N hQ qz wY CX rh uR w9 E8 r4 fq iM fJ gj dm qn gl jN IZ l1 YH mz rW e2 qO wh nt wk zw t7 e5 iQ fh eb sn ud aZ UV Fh Sv Dq Q1 Ku zs EB Ue XQ rN o6 do -\N ub lO SQ wR D1 mt O7 Ts T5 RD XE iu yg oT gg se pp qc js lu xt j3 j4 wt PC vZ 5O Yr qw ZW qr eu Db Sy eB eM fo i0 aD gW m9 Ig Ih lc OD N4 Pg Rx bI ni Kq wL aw e7 aZ jO MK bO wb Ei mI Ep wB eQ di do -\N q1 Ub xT DB wT wS IK pL ee oR tO eJ iC is fr jk ls c9 qq YG qt eo rW tp p8 dY pz gm hZ or xs bT x8 t4 t8 s7 OJ lT wv vx u7 w4 eT ox yo -\N pO o9 iH dX qa rf qf pD d2 kl Ad lH kb bd Qm bB b1 Z8 ew d6 yg d7 yM tI eH iC iV oI y6 sZ dx qn UT qm gz PJ zW jj 4d bk WB lM xB KE yx oO qp yb yn eN fo yW fp e4 aA fd jz qU gW qA zS nL V9 wf Qt Qi vg ni Wx HK 9F sz tg t0 gA de re iO aV h2 jT x0 h4 wx wc Fg Rb Rn nc Yz IY zp DS Ep Zw PR Xv rZ yH yK Zp do hc eP -\N hb tY z2 qz Qz zh Gw mG kb vE zz tI tP py eL jp tG qc aR qv gx la qR cn Lr nD nG ve qt 6g ml oP pd uq uw eh i8 uy dT ho j8 wp wd Qe xM W0 x4 QK el e9 pb sm pn tc GT ce OJ JR mI DS wB Ym eW u8 -\N iJ yB hn U7 cd GJ Co Dp LP b2 r5 eD tI pN qx g0 jB jN jj we bl Ri OT Pi RB yc sV ty oH ph hH e4 hy sd wp ll Ft l7 wh cA Ys wF Wb t7 sv uo sb sn ha pb sW de UN qC BZ WO EN as tb eU af eO -\N d2 k0 wR q4 q5 c2 sJ iV pM g8 m1 l1 5S ij aA lb XM vf ej TA ar th od sm cw GY Bu Qd Q1 u8 ry rN -\N qa Ux q3 mJ Ex YU zx rk Gi rl YA is py am tw ja js db ps dn qb qn GN lC Pe qq vr qr eo qi eC oA eV uZ yQ oF in ho qO Jj Jk wk wD ZP wF Lz t8 tk ha pv fz pn ug o2 pE uk kV gq v7 Oi qV wv DJ tv fn fW -\N dX a3 k5 um uQ jD Og nn q5 Qx Cu wP RD wS d6 pX ac oE rb uP tP eJ eK ih fF qc gj qm xK b4 Dz Jg Sq Jh eu yx eo rE es uL yW tp i6 pj ho qI qF SN OG Xo YV Pk wJ Wb gO ar uo eb iR iY pQ uh qG h6 VT wv Sn n0 rX af uz hx eO -\N yV ub tY gN gu fU dM ca q2 d4 cN Ad Iw K6 bf zl zz 2o w7 Uo ee yk iX g3 am fw oI jo se hA vS qn Iy qQ 24 bl j6 G4 cW JV 1L ei qy KE J4 qi ep oF aO hH tB gm sh lh vC UF vu wd P6 xM Qt kH Rk l9 S4 wH mR t4 oi rF iQ op oX u4 e9 fk u5 iT re uk f0 kB nd qK ce jP lR cy jS Qd qB Sb Tq n7 n8 Ed Ue tn ox o6 iD r2 it -\N qa pA jD qN qg jt GH q5 lG Ag Qv Ah Qn vR Da rh w7 b2 rz rx d6 d7 eG eH yl a9 eK dl tw sC hP hA su gz lo qE Le nS kT QY QI 1H kP mz qu es yb yn p6 eh fs oK aS im dY px gQ qP qS l6 Iv Rl zw DR 4R Hi wJ rP t6 gO s8 e8 at e9 f3 aK dG f9 qH pT dZ WW Rv wb OC Pv be wQ CS Q1 xR Xx eQ yr u9 sR tb yL tQ iF hc iG -\N a5 co dh bt lw ck lH w7 3E mp r3 rz yf yh Uh eH tD y8 fG pa aR vA dm su q9 D5 qW Re vH HE JC 1G IB xZ qq qw YG vt rn RB Cb rY ym eM i7 hr ff f2 qP Rd lx wg lb kH va Jv Qi Xd wH Wc el uN sz tf gU oZ ae e9 e0 iU dr iO dt fb dH jO UM wx S5 Oa KX lY Rn OC zy F3 HB Tt wB u9 oz hx iF iG -\N ak o0 qd q7 eq g1 y2 pt dk g8 qb vS QE Dh 5I Pt YH qo uL tp oJ sp oq dI UH zG xN Rx TP tf iE f6 cG Rv zM xW Zq 5f mD sR yK ru ro -\N a2 tT ub rs IJ mL oW pe eL gd vA UE zm SA Pq lC Yw QI qw LV ep qo uJ ym tL yE hJ s6 UF qP 82 FK Y1 wL oi t8 fk pb tx o1 Sk lm Oo xv n2 AD Fk n6 DP ON Q6 rV -\N qf jF kk nm Oz q7 B2 xO FW Kj rh Ua oE yl gh vD qE GN WB Pt wi Z0 Se Gj 48 oF i5 oH so hZ wp AE wg nC kG Xf ev pv oV au iY aZ f7 qB Q5 eQ yr tv yy ol ry o4 oc di eP -\N pO o9 dC a5 jD z1 SQ wS B7 tI r9 sL eZ aW tG zm si NG qE kY b5 Pp eB oD jl ff oe cE qP gY YV QK R4 Xf Kw iW sn tx gG uh cq qL Qa 2S mT eQ rB dp -\N qs Qz Cd dl se q0 lV eu Yi rW qo uH uJ uL eN tX wo qD e6 pv gG jE zX kp qC Q3 ye EN -\N un qs qh SE WS lF SO eq yf eF y3 g4 zb hS q0 nO qw J2 y0 uu fB dI f1 kq OA UL t3 ot fh aK yF fv dt f8 jO Sx wx At wn CS LQ ZC -\N ub qa qs iK pw uQ a6 pD dM d1 qM d2 qk cV zd bi WD nE Ah Qb Kg Kh IJ 1P rk w9 Wt r5 d5 pX Uf eH yk oY pM i2 hP st qn si qm zW we ls PX Lr Ri qr Sr Db HP qu XK fy oS eg eN uC ur i7 sa hp vN qS kw Dn OD Rh xj W9 wk Ph AP Yh el oi oo e7 gP ay s0 f4 gF aZ jY qK qL qX 1k v9 qC JQ zy n5 kg Hd wW wV bJ Hj Ur eR rN ry eO o7 -\N df a6 dN je ql NO q6 Ox wO zl bN rh ya mV E0 yN pr gd pi y8 i4 c7 G1 j6 Wo RV eu XG eo C0 YX ea sV oS wp Qw wL ou uN t6 u2 os of f6 dt f0 jT wc jA Ae qV Rm DS PQ Y7 Qk CK aa ux -\N dB iZ jK zd wY WH c3 zk 2o rj HW vP on eD ac tO g2 r0 id tA tH qb dm PJ M8 nP OE Pu bb Tc Gh ml rQ uF tu eh yE tX gv pk jv j8 lk xs kD Fi mx bE wD t3 mR wK wL TD eb iE tz dw rw pm re fb dJ h6 qL wz wx qX qV U3 vz xE EX 2w Ty eW Xm oz aN -\N tY a6 wE wI RO lJ bN RH r5 g4 aW jd q0 gz xy m6 wu qq ET oO eX qp TR y0 fi aU e3 oJ gm px lg wk TU ek tg u2 oV em dG uk nd qJ cy Hp wQ mI bJ Q4 iA fm r1 eI ie ux -\N tR qg H7 qk jL kc Jr AM mo w8 E8 tD gl kW SD Jo QR vL Gs qe b9 Mm FH eo uH ft ik e2 i0 uu ff qU f2 jQ v2 wg kG ek aq Wm yI yO s8 e8 sQ aB cw WT cK Pb Pn Xl bJ yq wM eW XQ sU r2 -\N qk WA q6 JJ wS uT gd gf ly eC pj Sa Pd wL e5 wC dA kX zK zZ zB wV rM tE -\N jq Uz nv Ql As jX z8 q7 O7 YT rl eA E0 yM y2 pr ia sZ sq sr qQ qR vK OE Pe Lr bl LL RM yx y0 eg ti e1 ue uu ui jx zD Oq kD Rg lv lb R1 FX rO mE TS ay f6 fc iO qG pY qJ qK Qs Ky Qh Y9 ok o4 aM -\N qh DL jt wY A2 yk y2 i4 zQ kQ we Bb Dg m6 qq ZW rT ta tC ff xs xd qF G0 1d Yg DU wZ iY sW tc dD hj hk MH OV zi wN Hk eE yJ af -\N ra ak uW q3 cB ji wY FW Gw T4 mu Ts QW Ww rj vO rl yd Ug d9 gj i3 zW qW wy md qq bv rn qy pd tL ic p9 hr dR hH ui sf f1 I6 ws cY ES EF t5 Kr EK oo t7 ec e8 u4 od dq jI cH JR zM JY Q1 zp yq 2e og yo tm -\N tR tT qa qd jF pG qh jr SW Ao q3 qz Za wT JS Bl vW Q9 wS Uu w0 YA pL yf rx ee tU r7 gg dv It lo ww UP Js qq qe LZ eu qy rR yb rI aY yE ta tV im sh Ss UK QD QF bW rO sl wL t5 e5 uM th ha fx re iI fv jE hk Ot cq kM h8 ks BK vl QN xE Te Tt rL u7 iq ry ag dp o8 -\N sA z1 qj q2 nn wR z5 mq xU q7 GV T6 w7 r4 C1 mB sD eD yM oT tA hT tS tw gd tF g8 se aR gh fH qv qn zm hS qW qE OQ WC xJ vZ xL Wo rn I2 Sr rQ aT yQ uw s1 tX hy fM pc wo hV gY vu wd lc UL P8 wk wK el oZ oa rH gP pn gF fx fc f7 rr dy x9 uk f0 pY wl v7 cr cH Qs wv nz Lv lU 5o xE Ym LY eR yi iA gL ox r1 dp -\N uv qd hm qf gp k9 kj wE lF bs Ej 2i El WL T7 rj w0 rz yf YS r8 tP py tq tw dl iM qc db qQ SD Ry c9 OE If qw AW qu uH tt p5 p7 p8 oJ zI oe qU qI lk j9 sk zS kA lc wh wk zq mQ vh t2 ej R9 mR ez t6 e5 op rK gA pb dq ap f9 pY qK qZ wc kd Pv bD Sm Dr u7 mF o3 yK di r2 -\N pO a3 uW q5 Q7 ck kb Zj Td zz yf jd wq xH ld qr W4 p1 ij fu tp Qq SV Y2 yT t6 e5 op dw iU pW jP ka QV 4U Qf Rm vb w6 -\N fY a6 qg cs z3 ql DC jZ wY me cj O6 ba kv wP w8 eA r5 uO fw iB ig g7 gg sy bg qR cb cQ Ro xL xV eX tt rU pd hG im oq gQ AO Rl Pl aq sz t7 e6 os uf ug gG pR qL qZ VT MJ Px wb ci Qf OV be bG wW mP Mi rZ u7 w3 eI yC -\N GH cM Ca RG uY pM y7 g8 lX yc qi rE uH yn uq eh tZ ph wo cR SV Fp KH sl oi sx oV gA iU h1 jE Fd Rv QV WI JY yy ry o4 tQ sI -\N qd iZ qh q3 cg lF wY xA Ez eq om Ug eG yj fO fP yz qx qE WB OR Jg xB C9 p4 tJ y0 iz tC oJ tB I6 P1 kA zF Qe Yp wj mv rA ez rD uh pT zL lm Sz wc lR bq OC Zq sR af gL eI ux it -\N a2 qa h9 qh q3 Fn kx vE WZ uS sJ yz fD g7 vH c9 Xq XJ LN tZ wp wf kG kK bY vf J9 5y uN yI e6 rH sn tx hj kN Rb -\N un qs fI qM jK JS bd O8 Bx vT eq YA XP yg pZ yM dj fP tP tA oY dl qc cx qQ m1 Rt WN D0 WM Yr qw AQ qt Tb HA p1 uK yn ef tJ gv im sd hK pz jx zI wa wf BA l0 wD mQ ej Wv t5 EK iQ pv oV f3 em aK rq hN hh f7 uk qH Ot jU ng jI h7 wz cr v9 BJ bK rC eR iA iS iw eI iD ov pU hc aj -\N pw gM qd jF U6 z3 jL q4 wT bi lr ID wA WZ w8 ya Ev ew r6 yN ee io r8 ip eJ tD iM si j2 Jo D7 m4 PV IV YG qi il ti i6 ta ib aP fB hZ wd vu wf wh kt kH OG KK nM rP TI ek ns t7 Y5 wC ae iR pv hf UB wc Ho wb wn Mi rN w6 yK tm tE rp -\N o9 un h0 a6 pF Iq xI Tg w8 Z7 r5 om oQ eG oR y4 sr fH zv vw ZQ Tc Ws rQ Db rW eo ym tL fV i9 pz jx j7 hX OI qF x2 l9 x3 QJ bY TO el sx yS yD ao aZ uj hl dL TJ nz wn kg kh ON wV w1 w5 gL eI -\N gV az ql nm rc r7 yl ja zn q9 xw nO IZ qt pk x4 L4 tg u3 of zK wc GO qB mO eQ u7 tv rM iG fE -\N o0 iK qd um qg k9 MB bu wY bX nY wS Hm eA mB iu pe eG ey sH Uh g2 iC iV aQ tD qx ja qb hA 2j lp xr WC vL WN wi SL Tx qt rQ eC Vw oF uw sM ic qY j7 Ns hB 2Q kw wf vp 1f X1 5C ZS Y1 rG tg oZ e7 fh eb iE up e0 ap VE WQ zZ cr wz h8 wv GO lY Fk AZ PR rZ H4 eW w2 ok w5 iA sI ro aM -\N dV d2 Cd qc zT 25 xp Wd TE es sh EO Wn f4 WO tv oc -\N uv qd qN hR Bj B1 mw LG io sH lo qQ xH m6 28 rn XX p7 im qT jn jW bm qF R1 mn ny ED em iI dD wn cZ DS vc wB Hh Q4 yw Ur rt ie o6 ux r2 -\N rs dh z1 jr cB vQ r3 eq om y1 sG r9 if tw qb qn m2 vy Dc b0 ik fa ib aA jz qU sg qS 1s bE OF W9 oZ sv t9 oC pv rw dD o2 dH lQ ka lU 1m Qk Q4 Y0 ye YQ w2 w6 sI ob it -\N o9 dB iZ fI qN qj mw 3v wP LI E3 km zz YY mo ya rz mV yg r7 yh pC oR r9 pM a0 tD ih db lt PG jf gl Re ww qW m4 j5 xi wi YD nH YG qr rm ET EY uG rE rR y9 y0 sB tu oD aY oF iv oH i8 oK uu sf gQ lg wa NN UJ qS cU kD XB wg cS 3K YV HK pn iI hh cw kM wz wx wc n3 JR wm QN bD zo mO JO wM Q6 w3 rt aN hx ah aM uc dp -\N pS PT vQ kc bs vU vO XU ee IB hV wj x3 nu ud yF qH wb Lb gZ -\N ra o9 qs tY rd pS dB PU qj U6 k9 nb qk Oj ql wT jX bo RI xO O0 mK rh bM Mj uT mB rc yN et yl pM ih i1 g9 qm xq OQ bj wt Jp xu Pt bc eo ep qi KY sV uK fy rI i5 im dY hK ui tM f2 UF UG qD kF nC S3 Fs 12 t2 rO DU wK ek yT EJ t7 s7 oC ay s9 pv fl s0 gF tx fc aC pY v5 qK ce qZ cr jP cK Hp U3 zM xR II Yv Ea CF Hj ye w3 Tp do tW ux -\N o9 qa iK wT kc q8 WK SP YY w8 w0 ys eA om tU yz pN fe aE g9 ps g0 i4 qb fK qn qm UT j1 D6 4d cb vJ vK xy j5 BE wi ve qq Gf qr J3 uG qo p4 sM s2 ut fd pl qT jz ui qY qU qA nK FJ Iz xh wk Iv QZ FB rO X6 TI sl rS HC oi Wm us ai dw o1 hh aB qH qJ jU ng wl zr vk Tw 5a vc Hk mD yr u7 w2 yt tn eU ul ah -\N uv ra qs tY jH q4 O4 bC vR O9 RG JZ mC r4 uI g1 ey g3 sJ am sq fJ qn It xt lN Dl Jh b9 G8 Dv qt YZ ea ue Ss W9 wj kK bI YM tg t0 oB yS iU uj qK nf v6 nj OX qB WY Mw 1n PQ eQ w1 rX rp ge -\N a2 PA E4 XY yd sJ vS jj xJ lM qy qp rI uX p8 pj tV xs wD wF oZ gD sW rw uj uk qJ k1 xx UM Eu BX mY EM eY -\N az h0 qz Iq bL kb xP yf y8 qn RV hX oC re GT k2 bO Qg CF rL -\N yV Uj d2 mq Hx wS w7 mV yN r8 ab an aE jN xw Al UP BE qr ZR ep rE qo eC ur aP hp PN wp I9 Rf wf vo QK t8 eb yD uk kV WW wx WT OX kh mI eQ yJ oz fn ie aM rp -\N iK df qg jG k9 wY kc RO wI vE bB rl ew io oR eH sq oI qc qE D7 m4 Pu Gd Db oO yv yQ ix eh fL pg ib hu pl cR Fr xd cY ke mx Yh wK aG hf hk qG Sj WE MZ GP U4 AK mA rZ rV af ox di yX ob -\N hn pA pw qd iL qh q1 z3 wR T3 wO wS vU Uu LD pe fO dj oT dx pp VL qQ Rr ls j4 FS Dl ve C6 rQ LN XK eC rT ty ik y0 tu yQ fZ s5 sd sh jn wa UJ ws lx Qr cA Rz wD nu ek yY yI Y6 uo os up f4 fz qK h8 qC WR At 18 CA wW rV sY ox o6 -\N dV wU wO uO m2 we Rp b6 qe ik e1 bQ W8 x5 ez fh u4 iY jY WU lI F5 u8 w3 yL tE -\N sA ds qd NO q5 RA jd qo rU R7 uo ar ud oN aK fv dG wl qX qV ye yL eP ge -\N sS rf qN bu GJ rj Uo yz tF m1 kW ZR oO y0 pf tC dY qU V6 xh t4 oo uM dF jE qH dZ v8 Ho wn WO 0W DJ rV o3 du ro -\N iJ Uj k7 me lG IH Hv wS rj pL sD uO y1 yk d0 pt y4 g4 oU tw sq tD fJ hA qm qQ 4a kW D7 xy m5 bx C9 yx nw tr qo uJ fu eN p6 s1 ht tB qO zP kq x2 wk wJ wK yT wZ sz ae iW ay fk ao ug pQ qG k1 qL xx qC cL Qk 56 BN oj yt eT Ut Uy tW ir yC -\N k5 pG cp z5 wR NO Zd Tk eJ an qx gj i3 su we UP 3q yQ fX ib tV qP Ik wj Yf u1 os rK jT Qo qX n9 w1 rB -\N k9 Uv gs wR 3b mH km bM We w9 eS oR yk r0 g5 aQ gf Nq qv lL m5 YD ZQ qt qp sV ed p5 oF eh i7 pz hL sg jn wa m0 NM kF W8 wj DE e7 ar iY pn lY wn Fx w3 rB eY aM -\N o9 d2 VG GK Ex RF rc hY qm j4 Ga qw rm Ls YL Cm eN tL tp fp tB I3 qY qO j9 vN zF wf QG mb KJ Qi Jb mQ wL rJ s8 lW UM zt wb F4 xW F9 -\N ra go lS Qx wI c6 B0 Rw g1 yz fe g8 OW qq Ra mz eX oA fu iz tL uC e1 P6 x1 tf rH tk fz ap hl qH k3 xb Mw zM Yb yw Q5 aa rp -\N YU qx sC xe j2 OQ Gs i6 i9 l0 -\N yV sS tT gu fI qj bt ql lS IO nW GK Hl uP zv gl nI xt wy Dz qe uD nw rW qu uw e4 qY px qF zw ZA TY ek t7 pv dG Ho wn Uq rX yX eP -\N ga 1W lD wY O7 XR pK r9 g6 hU jg lX SD nO xt wr zY kU l2 nw 9R rT i5 to tp tC s6 f1 UD KO XB Rj Qy ES t0 f4 fx iI rr hM hj fb jI Oi n1 vk ci 9e mT Yc 2r tv gK yp ux -\N hb hn k0 wY M4 w7 rc tS y6 j3 QE ve qy rT so dI qO dP lk xf mQ wL em f5 pR wl wn 3k eW yt w4 ri -\N qa sS lq wR bX T3 r5 eD eG sX dn we 7n Ra qe b9 rm Wd rW eo oA rI e1 e2 ut aP hu qO ws UZ ai tz nl cu wQ Ln wN ie aj -\N yB rs un hm dg qM qk Ao mw Fn kv uR Uo pJ E9 sF ia tP tw a0 tD sX fG su xq m1 Om nA vK wy xK Em l1 Z0 nH b0 mz qy p2 rU aU iv p9 pz UG lz xN wf xg FK ZU wj wD u1 e9 tl aK hf sW o1 pW dt gq v5 lm h7 Nn nl wQ Uq Zt o3 ad ry iD iG -\N a3 pP dV qs gN U6 jy kk IO Dt wT ck rg Ua yd YA yh ax ac y1 pe pC pV fP fw dc qv zb dn q0 Ju jj m1 UI lX qE qR T9 Ja HE wi vw m7 l1 JN qe Wa qt XG rQ qy Yi qu p3 yb ed eN tZ so s3 tB ho fM px gW zO lx wf SM mc DQ Wj Yg L4 uV Yk TP t5 wZ oL fk f4 pE kC dJ wz qB zM WI br ZK wW Ty 6I vm EB LT eQ w2 eY yp yZ o6 eI -\N fU ga IO nT wP JZ yf rv oE eH pt dz ih sX qx g0 qm hF xe lZ gc D5 bh 2z cn D9 1r SZ Li bv qe 6d bb ER xV yx p2 ea tJ p5 aY uq dQ pg oH qT s6 px sh KO qA NN OA bQ cS kK HH CR wG TU Y4 t6 e5 oZ th sn oV u5 dw qG dH uk n1 zr qV 3d n4 Yx xE wV EB H4 yo ro hx o8 rp -\N ra gu hm a7 jw qM qh jr gs k0 ql xT q5 Dt RU wY K5 WH FW LU kb AM M6 Bx vY QQ Ev rk 2s mC yd eS io pC pV g2 eK tq tw iN ih aE qc D5 UI qE wt qq m8 vr NB EE HU rW rR tt ed fi eM e1 e3 hH hi sh zP qO wp l4 ws qF QF Pg EG TO uN gU u1 t9 oX e7 u4 od dS de hh pY qL h7 GY jS vz GF Y8 Uq sE do ro rp -\N qs qg GK Ta bf r3 HW r7 r9 sH uA g3 sq tD g7 hA lu qW xr wy Wu RZ kO bb i6 uy aS dI qI zA hV jW Rf 1f 2U va AP Qi Rc DU wK yT t7 u2 oB re aX v8 cG qB WY wn kg Pn yi rN ru -\N gr ra jq qf go ga jH gs q3 TM q8 K7 O8 mJ yM er ip uA eJ hY i1 dv qb vG cv m5 wy xK G5 Wi nG W3 3w uD rW uG ep hq ta fC fd aA I5 hX qP wp V7 qS l6 l9 l0 Jn TY t6 iE rJ tk od yS oN pQ tc zL nh qC xv wc cu ks Ei Lm vm CJ yi ad r1 sI sP -\N qa hm A3 ac q9 nA RJ If qw rR Vw tJ ib Su qU wo dP j0 wf Pf 2Y wk YM rA Wb ae gA gS f8 gq Im Ar Pb EC F9 yu rM -\N T8 eJ an y4 tD eZ lN Z9 LJ qy sM uw dQ US cP nu tg vn -\N qa ds k5 hW k8 k0 ql Hl 1R wI FW c6 w7 mZ rj XY r4 E0 yM yh eG r0 uS fS iB oI qv q0 ww lp GM lN bx NC QI l1 qe Wg ea qo eB tK eg to ur jc oe dP hV wa 2Q nK AT Rg wf wg cA xk Jn Pk Yg Er ot uV Wb aq oL wX e6 ev sv uo Vf eb aH ud dA pE qG jR kN jU ng Ae wv n3 IW lY kf cL Pb wV Tt vn EB vm u7 eW aa w6 rM gX r2 o8 -\N q4 q6 VK d6 eG pC pV r0 tw i3 q0 we TW sM e4 ow SN KG up hM qX zV nz wM u9 ul ri do -\N pO uv dC qs qd hm qg q2 jJ SW kl me q8 xA wA xF Z5 yd r4 Rq sF pX tI ia r9 yl dj dk eK qx i2 sr qv qb lB wi nF Wu qe Tv FH qo rR yb fy eB rI aI oK qT pc UD qI qA ws qS lc zH nC x2 cS t2 DI Ke wK sz oC yP s9 yS ai ln wz cG wc wv Os qB F2 EC Y8 DG wM rZ yr eE rN sY du sU eU fm eI o6 dp hc -\N fT qj q6 Wq Up uT LG er UW db lL Ws oF oG e4 1i R0 wX fh th Vf re hM Zi -\N a3 tY pw pH cg uO r7 oI q0 lB c0 vL xX mh HU b9 qy tt sV p5 eh to hH ow tM oe Si sk OI gT kq cU vi J5 wF el tf yU u3 yA uj dy qH qL ct wc EL Y0 o3 o6 iF ge -\N a3 dd by wT lF 2V Bl 7c bN Cf YO Go yf ii et ey yl aQ aW g8 hO i3 qb dn qn lu vF vG 2k Le Ml wy T0 4h xK qw b7 bb eu Xr qu tt y0 oS sN tL pf oG tZ tX pl ss US xd cU OA qD xN ke QF vp kH ny Wk R8 ej rD t7 sc e6 rH ud tx aL gG re hj UX qJ gw xx zV xm IY CA vb yw EN oh u9 aa w5 w6 ul oc aN uc -\N qa un dN hQ hW d1 jr jy kk kl wT kz zf z7 cM q7 me xP wP mJ rh uE E7 ys rz eq ew eD XP ee yj y1 tO fw aQ po i2 jN li On m2 nA vq wu Ck ER Yu Db Yi Gl ty eh uw fp tX e2 fs uu sf jx oe jb qP cY bn qD wg 3Z nu J9 mR t6 gP pv ha tl ai fx uf fc kX qH gw xb zt qV QB IR Cq vb Y9 Ct ol fn ah hx sP -\N dB wT cM ch jC wI Dd ys on tD po y8 q0 wq kT eu tC tV or Fr S3 na e7 uf gG re F5 Tt aa tb ie -\N a5 jw qh q1 qj Oj xY my B6 eS yg yl y5 zm PV qw qt qo ea rI aO in s4 gv i0 aD lh wa qF Gm Rk vs oy R0 ez aB lm Qs Qh ry ox -\N ga ca z6 nR wO rg bM vU Uu rj E0 uI io pe eH d9 ab tw fe tF fK wy lN md RK SK qq qw HY kP Dc qy y0 p5 p6 p7 ic pg e4 jb gE wp qA bn xf kS ZI oy e5 uM wX iE yP fv jE ng OJ jA v9 bP QV eR aN pU -\N a4 jw a8 O1 q3 Un GH le nQ q8 IG rg rl eA io er tU fP dk hY sq aE lo qQ wt wy 5I xJ cW Dz oO qo yn ty y9 y0 sB ef tJ uw ta ur i8 tB oq aF hZ qI wo sk zS qS vi wf kt nB Y1 oy wK R0 oL ex ec tg t9 eb ap fv qK jI cr S6 Et xQ bF Ep mI AX rt yu iq af aM yC -\N gr uv hv tR a3 qs lO U7 jy qz kl z6 GK GZ Ag kn rg K0 w7 Wr rl pJ ii yh uP ac oT d0 g6 tD y6 fr se pp dc g9 cl gx qW PL m1 Ii qR vZ OY nF EU eo p1 oS y0 rI ix aU uC aI fX p9 NM Jj lz Pa kw UL Rg GW QH 4m EO QC L5 rP oy EJ uN yY yU t8 sv ud fx aC dy aV gq qJ VE Sl Bu TH U3 Rn nz n5 zM Yz bD TX EL EX n9 Es RT rZ rX ol sY rN yo -\N pH cb JX wu ib vB Ih TY oy tl VU -\N df qd k7 z2 q2 ju jZ zf cM mw YR Gu rx yh yM eF pC qx jd q0 OW Pw wt RJ xo mf xL qq qw uD TW KU ik oA oD ti hK f1 xs qD wf Dm S2 Ph Xo ou sx ae iW t9 eb u3 rK aK hf dw aX Oe zL zZ wm Sm EL cX Cw LQ za Tu yw rX yu rN fn yi eI -\N a6 ql wR jX z7 wU xI yM fO if a0 dv ww lX Zv Dk tu sN hH ff hu zO ws Rf wf AA ni Kq uV t7 uM gO e8 oB sm tz hl UC zZ OL lR KC n6 bK RY iF -\N qs gM TN RP iu pi qe eC to L1 wH rA wL iT kX Fd vx Q1 ri -\N gu pw qg wE d4 WS q4 cN q5 me Qv zj zl Ex Wr XO yg r7 eG et ey uS iV po aW se cx Az lB NZ NC qq EW Rs rQ yx ep tJ uq eh fZ hG gv jc dI wp Sa nC Ya cS FV QZ TI Wn aw e7 oX u6 pn re o2 hM fv qG hl dL v9 qV TZ 6Y rL ye rX Ur tn eO -\N gr qj z6 lD TM Jw Hc eD y5 se kE ht tN jb 12 yT EK ao iO wV eW eY fm tW ir -\N gV fR ak o0 gB rd dV gu qf qg qh jG Ux qj pH k0 Oj WA jZ bi JA Eg c1 FE Qn B5 RS rg b1 vO Z7 Us d5 r5 ii tU yh y1 oR eK sL pM hY dc tH sy ww zE VB wt m6 IV mj qe 6f qt Gk TQ rU yQ aU aP dR hH qY sf qA Ik kt wD Rz ej t3 ot EJ uB wX oZ th s7 t0 aG gA pv em fz sW o1 iP qH nd h5 Et Ho cu Yz Tq wQ wN eT tn yo sI ov a1 -\N iJ rs rd qd pD qg qh z4 ql IP nQ q5 xU bZ lH O7 my 3W XE wS 2p w9 rk eS er d8 pu y6 qc gl Bv QA RV qt RB oS rU fN qY qU hX or wa qS AT zG mx Xo BG Yh ec os eb hd rw dw iP VW ki OK qX cu wb Sn wm yJ o3 tm eI ah -\N tR rd pq qd um qj U7 q3 cf DB K4 GL mr Gw c3 bs K8 vI 4V Kz Cg rz et ey tP fq y5 eL gd dx qx hP mN cz wq xH m4 Av T0 vZ m6 qw Tv rQ EI il sB tK eg uq tC wo qO zS Rd nX 2Y Fo J5 l0 L1 Hy Vy t3 t4 yT Va Y5 rG e7 uo oX at iR yS hd uf fx re rr aC kC cq qK cw h6 kp xn zu bD cZ CA Pn PQ w1 rX Vc w6 yo iS fW ir ov -\N ra iJ a3 qs qN jF qM nv cs cV kz q5 Um q7 q8 km ya ys rx yN d8 sH pt fe se js UE RK m7 Wp ET ei qy to tZ s4 aF 3i Lc wK EJ HC ex t7 oC sm s0 tl fx re fb jR jP qC KC JR cC w3 yL oc ob eP -\N sA yB qN k8 lF D1 c3 wP vR WL yd iu Kb sZ g7 mN jM lZ SD m3 lV qq J1 eX qo rY rU eM pk I3 hi Rf FK nC wD Vu yT td sc tg s9 tz tx dH x9 qH ku dZ mY yr w3 oj sE eI gZ tQ hx ah fE -\N w9 rl rc oR fq a9 pp db gj hS lC qr eC p4 ph hB x1 ez u5 qX Ea 6T tn -\N a3 qa dd qf qN qM qj VJ wI Ag wO IG E3 WZ r6 d7 ax pe rb ey r9 is oT tq oY if hY se qx aR qb vD qW qE nP xy nD Wi IN Gj qu y9 eV ti tB qT px UD wo ll cY wd Hw kH Fp Wk wG wH YM Vo uB rD t7 iQ yO oX eb yP yS au u6 rq iI iO pE qH nz vl be n8 wV Hk og rC eR yu u0 rN yL iS do eO -\N dd nn Oc El YU Tl rc rv r7 y2 hI qc qm wu cQ qw xC kP tr fu ib zI qU wp vi cI QJ nu zw t1 wL fh ev os f4 f6 f7 cD zC qX zy WU bS QN u0 -\N o9 gr fU a7 qk xU q7 wP El YU fP oU y5 pM pp qm jM St oP uC fX tN hL zS KP Bq P7 Hi yS qJ ki qC Qa n6 oj eY w6 yK sI -\N q7 xO sr he uu sd s6 gY ws Iz fk sW aL v6 lQ Fh IE oh uz pU -\N Of ch zj rk rx rc g8 i1 jk Tv uL fi e1 ic sp in jl jv j7 NM rP R8 gO hf wx TB oz tW it -\N SE kc Tj rx yh eH tD pa zb qv c8 j5 Ri EQ b9 rm ik eV uL ti p6 eN oK tN wp jm ws ke bR wj rP en gD rq f6 aC aB ZC rZ eW tb ro -\N qd wR d6 i3 j1 ww If qt yn fd e4 qF J5 Yh t8 u1 ev qC wv PW u7 oj ok yZ tW o8 -\N un pA jD qh qM DZ PI z3 NY gs k0 wT xY z6 cj K5 GL bZ D1 FQ YE YR rh T7 oT if g6 iM pa ps fK zW lX kR lV nA wu vw eo Cm te qo tr eC ty sB y0 i5 to yE so tC I5 sg cT qS SC ws Qr xj 2U N5 Rl CW DW Ys QJ YN QC Y1 sl t9 oX sv s8 yA s0 tl yS rw tx fx dS rr cq cD qL Qa Au Qg Vg rX yt iq tn yL uz eI sI r2 ob -\N rs gM qk GG M3 rj eq mV yf sK gx ve eh iv i7 N3 pb uf gH uj TG OX wW bG oz sU o6 -\N iH a3 Uj rd qs df h0 jD d2 kj q2 Ap wR Ol nW bZ q7 FQ Ir RA w0 eq YA r6 d6 eG eJ pN py pp sr qb jB wq nI xe we lM BE xo W2 QO mj qr HP tr qo qp ef oF yW aI e2 i8 fB tM dO dP I8 l4 wd P5 SN Pf GR vs Rx kZ vh t2 wJ ot ar t9 at iR dw qJ Nc cw Fd Sx qC MZ lT Pv br wV Dr Q3 yq vn ye YW DK oh rC w3 yt sE ov ge -\N ds h0 jw hE qh jr jt ql me NA Ah xA Tf Wt pJ pK om 97 rc yg yM oE yj eG dl fe sZ g9 lo qQ qW WX Rr c8 nS vq m7 xL Gs vr qw qr KQ qi qo eB tK ue dW e2 i8 i9 hy hH qT f1 pc vV qS bn Ij I0 UJ xh wk QZ ns EJ uN oi yI rH od ha tl re tc o1 uh aC iP qJ WE Qh LQ EB w3 w4 iA oz eU ri uz eP -\N fR iJ DL qk z3 qz wT z9 Gq mr wO zz RD Dd rz ee sw pp g0 sy vG ww Iu PZ UO cb T9 ld qr ei yx rW es ts zI wp wd GW wj HF R4 TT x8 wL t6 HC gP eb aJ ai iU o2 nh qV Ey kg DP wQ F5 RT CG YW sR tb gJ rB fm ro ah iG -\N sS Ux q4 ji xA mJ mi LD rl pJ r4 rx yg tI iX a9 ig gj j1 ww Ii QE j3 Mz vL qq Ye m8 b8 YL qp ik KI eg uq fi oK fB oq fM sf oe hp V4 nK wg mx kt vs J8 YN Wc wJ ot td Wn iW os u4 tl u5 rq de iO x9 dL qL n2 JI wB iF hx -\N iy jK ql q4 wT kz Fb q7 vY w8 uR ax Uf yM yl py oU dl pM iN sq hO j1 qR ls j6 IC SL kO Xq JM qe qr qt yc es rY pf he i8 s3 pj tM oe qO lk wp j9 nB Yd bU rS e5 yI ar rH gA ud aL hh Oe wx S6 DO KV be Pm w5 fn eY du do pU -\N pO rd qs iL rf uQ Of JF NF IH w8 B0 uR pL Us eD Tz tU eF rb sJ tF fF i1 pa dv UE fK m2 qR wt j5 c0 vw xo b7 p7 qT zI wo gT qA OO qD bT nt zq x8 ou e5 u2 fj s0 yD sW re cD qX jP wc jA GA JT bH HM eQ rV hx gX -\N iy iJ pA gy qd qg hE d2 qk d4 qz q5 nW wU AM Qm FT w7 Rq yN eF oE pV eK fq sK y4 tS am fD qx q9 jf Ju wy lM ZW Wp ER Sy qu oA ta jl ss gQ Fe wa P2 kq ws 2W Dn xz t2 ej rP rS yY e6 iQ aG e0 u5 tx dD pQ fv jR qJ ku OJ qL wz Fd S5 nj qX zt 2D qB nx Pm Ce F9 w3 eR tW rp aj it -\N sS qa gM dM qk c1 JD K0 T8 Mk rk Tk om yN Tz r7 pX ac av oT tS if fw eZ y6 se qb hA su qn cl WX we qR zT kR mj RC qo es tJ ym iz tK i6 fa i7 s3 pl jx dU qU j0 ws v2 wj Ys YV wD S4 wF nM DT Wv uB ez TA wX e0 fz aL ap qG WR Ar wb Fj n4 cZ Qg wQ Fc mP yq EV sE eU aM gX dp tE -\N a2 hv yB nv H7 jt lw xT LU wP YR rg 2o 93 uO pr eJ eZ jB lZ ww Az OQ bk b5 wi qw rQ HS te ea es ed fu ti uZ fd tM jc dO qI j9 zS j0 wd XV Iz Hr Wx el ns oi t8 sc t9 sb fk hg cD Rb MZ wn 4I OV Ln yr oz tm ro o8 -\N iy PI jt kz ST TM rh ya b2 om eF eH tP eL iN sC qc g0 ps zQ nU Pq j3 OE A7 Ja Js nG Tc qe Pp eo eM fC s3 hH i9 jl qY I8 lk wa AE 1p vh oX rK em hf dD jT Rn Tq iS oc o6 sO pI -\N qs gM qN Gw Qb CX w8 uR YP Up uY eK eZ aR sy qb hD bx RL qt Yi nw tt eB fL eh pg oH ib qY qI BP Jz Lf EO Ph wH oy Y5 oM aZ tc aB wv wb kg wW eQ ok aa Uy w6 ag iG pI -\N ra a5 dB co qN d4 bu Qz kx me nR Q8 my LP T8 Gu rk yN et y1 eJ g7 Yq D0 j6 b6 qq rn KW ei yc uq e2 s3 oJ s6 Jl kF Rl ny wG mW t2 CO el yY ez eb e0 aL qG kM k3 n2 zr TK qB n5 n7 eT tm ul -\N pO uv a2 o0 rd hQ dh hW a8 d4 wI Z2 vT Ww Kb d7 pV tq fA tA dl oI y6 iM fF aE qv sy si wq Pq Bn b3 lM b5 wi kU qu rU uL rI tX fB ss or sk wp qD W7 kH nN ES Hy wH rP uM sx e6 rH rK pn sQ rr hM dt iP dH pT wl h8 qC vj lY bq zN GD wN Q4 Hj yq Xb mF ok tm ge -\N ub pA fY qf dh qj q4 wT mw cM K5 Gw kb El w7 w8 mX YA ii dj dk gd dc gh st qb Iu jk qR bz vZ Ab b5 mf Pu qe XD nq eo yb pd i6 ue dQ e1 qO wo Sp 1o N1 4v AT qF Fi OF xj Rj DQ Ew nM X5 wH na uB e5 uM sb oB em pb re iP x9 h7 zV xm bw 1v mP Zr w3 Xm eE yG rV rt iA iS ro eP -\N cM bp Hc rx y4 sr q9 jj Rt qo uK eV to ff So BG EG Y4 L0 gO os ay tx qH hl qC wb -\N z3 nn O9 xF fS gd g8 nS eC p0 tB wF uV iW jT WR Dq bJ u7 E2 -\N da Td tA tw tF tt aY dQ sf gI ae rL E1 gK af dp -\N un fI DX wT M5 vO ys j3 i5 aD nr wj mn tg OX bS iA -\N hv yV qa qf dg qj Do Ek w0 is sL eZ sr i2 ww we RL vr qw y9 tu p5 uC hJ I6 UD ws l5 qF xh kH Lg wF wJ uV tf t7 e7 dt qZ ka xn cX xE fn it -\N iy yV rs qg uW Oh q3 lr vQ bZ AB ZM wA Ds b1 w9 rl rz uY Wy om uO eF fO py tw fe qx i2 qc qb qn ww vG kE wr j5 j6 OY qq nG SL qw mj YH XF YK XG qu te p2 ft y9 uK ym uq so fX ff fN qY dU f1 Na lh wo qO gE sk v1 wg mc DQ wj Iv 1h Pk 3s ej oy ek td ex ae yI t9 gO e8 rK tz ud rq aX hz dK qZ kf wm yq Cy w4 H6 rt ry tn r1 gZ ux pI -\N d2 wE Aa cB O3 xI tU tI gd wq PL xG WC LM dE e4 sj hC Ic Wc rA wC gO o1 dD iP wl In wx jS TV rX yi yC -\N tY um hQ co Ux ql q6 wI bC kn Q0 r7 yz iB pM g7 po qv Re we bh 8J Ru xo Ra eu uD qy uH eC ty rY yn hw sM e1 pg p0 dR qY oe lc x1 kt xz Pl t4 el t5 ex sn us dq rq ao f8 pR MD qL v7 v0 n7 kh vn wM u7 CZ eT w6 gL yo eI di tW -\N ub jG pH q1 q2 d4 q4 qz kl lD cN ji z9 RO Ek GB w7 rh pK eA ax yj pV oT yl an sL y5 po iM i1 zb fJ qb i4 gl xq si m1 jj lB l2 uL sN ue s1 ta hG zU lh Nd j9 cI Qu wD BH EF rO rA aq t7 ex t8 od en fz fc dF h7 qZ n1 v9 zy 4A TC BB Ea YW mF iA yp eO aj rp ob -\N o9 qa h9 dN VO a7 qj jt ji nE kc cj zh wO Q0 w7 E5 Ui vI ya Wy C2 r6 uI pX yh y2 tO pr ab dj pN a9 pM tw sq ig hI bg nI Ry lV wy IC bc Li qe IM Dv rQ Xy KI i5 fa fV uu aF dO vV zA l3 BI kD nX W8 nt Lh Hu rA uB uN ec rJ ua fk iR s0 f4 uf dw jT k2 KZ ML cL KM wV vv Es TB yJ w5 rN yo af ru ah iG -\N VG wR zh wO on ew eF aE hA Id uF eg p9 EF gI aL ng 16 rZ o3 -\N qs jw qh cV z4 Ok wT K8 Kg km wA uU uS sJ oY iV tw jM c9 FO nD 20 qw W3 Yi rE qo yv rR oP qp ue oH s3 uu px jc hX wf v2 bR EP wG Pz t7 t9 au re zJ kN xc bO kg 1v HB wV Tt u9 gJ yu ry iw dp o8 -\N qd wI IJ RH eF fe jM kW xJ Wh uK ef ti e2 j8 OU Xo ny wH rP wJ uB s7 pb Nb qV EV o6 o7 yX -\N gr dC fT qs gM qd dN k6 lO k9 nb As zg bZ Lw uI ee g4 dl qv q9 lu jg RX W4 YJ ep oO sV uq hq yW aO fC e3 ui dY dU sk Gc gY qS l7 kZ ED ej wL uN yU Wm oC gq qK qC ks TK Ti eQ EM LY Vl eR ry sY yo ro eO -\N Lq d7 i4 7W y0 qT gw cH o6 eO -\N fR hb dC o0 yB hn gi jH SW kj wE O1 VG nm Q8 Bz zk bf mL Ev eD r8 iV hT fG tH qv VZ D3 NG xJ 0H 42 EW vt YG qr qt HA qu HS qp ij yn eg oF tL p8 fZ oH iv jl ss dY zU or sk UJ cO kt rP Wb wX fg ev t9 rJ yP u5 us yS aK rw aL iO kC dt jR hl ln wl wz GY WY QV qB mU Hd Ky Ku zp wW yw rL oh eE w4 yZ -\N fU dg qf pG jG O1 DC by q4 ST T3 lJ vE Jr AM 2i rz eA LH pL eD pZ y4 g8 i2 db g0 fJ q9 qn bl En HR m8 qw rn qt Yi ei YK qu Xi uH fy yn ix uy gn jx f2 gR Fi x2 ZO Pl vh ek sz u1 s7 yA em u5 dA re f7 hl qH jU OZ Ar zB ci TK OB n7 Vh og w1 ok eR o5 ri ro tW rp it -\N gV ra fR ub h0 hm pF qj kk zf zh rj eq d7 oE eH iB oI gg i4 jd PH nU gc qW Rr m3 vJ Ry Is Dk QI rm qy qu ep p3 ed pd ta s3 tC fd sa im ow jc oe qI j0 gT bm vM zF Nj Rg W7 x2 nr wF Hi rP wK CO t6 t7 e6 aG eb u3 e9 f4 oM o2 dK h4 gq jO cr OZ ka KX Rn wn DO Ep wB vn Ef rZ eW yi r2 ro sO ob -\N fT a4 qs pq iZ pD U5 cs q3 qz RA rh w7 rk mV Kv ee y1 tO dj sJ tA pN oI tF i2 tH q0 VX vF ww 2l cb wt Yq kU Ye Gs qe W4 qy qi Xi tt es qp ed ef ti i7 tC pl jz ho zO qI zA Fy ZY Rk X2 R3 Ht YV ex op ae iQ u2 aG pb of dD h4 lQ wx cy cu zy wm RY Ef DJ Vx sT iA eY tE -\N rs al qd uQ ga qj SW wE PA bi ba E4 YY mo d6 er et tI rb py eK am iB fe y7 fH jV mN qE qR OE c0 l1 QI mh 44 Xe ei eV hq ix e1 pg pj ui hp PM Fr qS kD Nk 1V wj Fa wF yT t5 Vp ex wX fh pn ug fc pQ iO gH dG Oy nf v6 Bt jO qZ GU Me wm n7 br TX Mt Q1 sU eU di uz aM iF uc aj -\N da a6 q1 pH Uv Oj ji Mp T5 mi rj Cf JL w0 pK ew ii rv oE r9 iC id sL se su q9 vD we j3 Ac D9 Yw EW W3 y0 tK aO hr in e4 hu dU qU jb wp cR qS V9 P5 vi xM kF S1 EA t2 wH Y1 CO iQ yO au iY oN dS fx yF Qa zV qV F1 Y8 wM u8 rC o3 -\N iu r5 eL Dz rT m9 hB lc x2 ZP Aw uz -\N k0 pX qE qr I2 YZ qo aP t1 ou n4 -\N qg q1 wR wT wU 5x IJ rg Lq eG ia r9 is dl aW g9 xX W2 qt aU i7 US jc f2 gE qA gT l7 lb mc x3 3p tz u6 kX f8 fb ku AG Hd oj o3 fn tW -\N ds rs k5 go qg ga qj gs by q3 xY q6 K5 4K O8 wS Td mo w8 Th ys eq pK yf r5 uO rb r9 tD y8 tG hO qn gz li M0 OQ kW qR G1 wy IV b7 vt qr qu ti to ta ut sa i0 pl oq sd ho qA gY Qq l4 kS Fu wg QG KJ EH ez yU TF s7 os s9 yA em pQ tc fv qG VE Sx AF ci AH Qj bJ DF RY rL wM Zy tv ol eY ox ri ie tQ ir yC -\N ak ra yB ds gt fY qh d3 ql jK jL NI Zs q5 zf lF SO wO mu YT wA w8 Kl uE E7 2d mB yN tU ac pV id pM sq sw jo dv jd jg qQ qW qE wr j5 Wu 1H b6 vr YF Cx LZ rn HO Gh qi es eV ty p7 fX fs s5 pl sf lh sh I8 qA xs 1o kq zG QH wk Fs Vo wL ez iQ uo tj u3 gS iI jE jR hk qL xx 1j v8 nz kf vz wW yw yt w4 rB ol o4 rN ux iG sP gC -\N yV fR qa rd gM pS jD a8 qh lS VG q5 lG Eh z0 vT mi vY rg LP Ex ew d6 yg rv oE fS sZ g6 sy hA cx qQ wy j6 Dk HR l1 qe Gl eX LN uK sV ty aT rU uC ts hi hL lg jv qI vC m0 Fy xg QG EO HF MU MO kZ ot np oy na el yY wZ fh gP up iR e9 s9 f4 gF pW uh uj jR aB qH UC wl ce qZ h8 v9 wv IE 37 Eu GF Yv 1m mA yw wM oh DK sR oc eI o8 -\N qN cd Zf y4 oI dv xq q0 lC Av cW kI XD LX qi gn BH em uf WE jA OX IW qB wn mY zs Y9 ux -\N qd qf wE lS lF K4 Eg bC E5 rl eA r4 oQ er ip g2 yl oT iV ps gx qR wy xJ vZ xL bx 3O qr eu qi uJ p7 uC ph in pk qT I4 gQ wp V6 kw kD xk zw 11 Yj wJ rD oZ th yO eb yA tl au tx qJ wl dZ wz cG zV Qa Rb wm 7a zs Vj YW eE eO -\N jD go qg d2 ji Qn wA bf T8 ys eq uI d6 eD yN r7 is qb q9 lp lZ qE c0 Wu Tx Wa te qp 64 uq in qT qY wp j0 lz l5 OG cA sz uN ec rH pb pW h2 kV Aw WY Qf 16 RW eW tb aj -\N a2 gr qs fU dB qN q1 Uc jr qk cN q6 B2 nE lG q7 q8 wI wP b1 Ec rk yj pC fO iV sK gk jB qm zW m1 WX zT xy wy Em 41 EE Gh XG Cn yv qp sN oD aO pj fs ut s5 tB aD jc j9 xa UJ ws kF wg vp nV Fa Wk mQ x6 vh Wv t4 ex iQ 7r Y6 sv oX ev eb rJ rK em aJ pQ gH f8 TH Os Sb mT AK Q1 xR yw Ti eE tb as ox o5 yo gX uc -\N qj lP z0 Aj wP vR wA bB XT w9 ya on ew yM ia iX pt tw dz jo aE cc qE lC qR cn b3 c0 IB ml qi uJ qp pf p8 e1 s3 tN ui sg PN I8 hB Ij Qw Pd Ld Fo AP TY rO 3B R0 sz iE gP rJ e9 fk gD pW rr uj cF qZ zr RQ 4P Kp PR Vj w5 iq eY rN ie eO ir pI -\N gr rs gy pw qd ga jJ z3 kj ql nn Bg DM Zz uY pL E0 LH eF oE am y5 fD qx hI UW i4 q9 hS jB vD cx nI qW WX zT QR D0 wi 43 W3 Cc b9 QA rW oA eV rY p4 eN tK ti yQ pd i5 oG ic yE so tC dE pj ff hL oe sj qS wf V9 xN Gm wg xM 1f Ph DR vg wK ns t6 uM oa e8 sb t0 gS sm fx o1 de h1 uk qH zJ zK ng ct GP nx xE 3z wM rZ yK tn ro -\N qa PT k7 Og kl wY RP Hx wP wA Ui mX Eb 95 ac eG dj yz aQ iN ih i2 q0 cz cb Dg xi cQ JC qe qt es ed sB eN iz fp ta fC tV tN gW kA I0 lz Sd Il qF 1s Iz QF nC xj xk EP R7 rP gU t7 wC t0 en tl iY iU pW kN kM qL ct Qp cH Fl wm n6 RW Eo QM vx Ty eE ru iG -\N um rf qd dB qf Od d1 MB U0 le xU wY q6 mt bC QW CM uU Us r5 Uf oR tq eK sX i1 It la cb Ax T0 wu Ab 1t qq G6 kO G7 mk qr EY HA ea qp y0 eN ue tV ho I6 I8 Sp xs qF V9 Jl kt Rk Qy ot 14 na uB aq op yO en tk oB oN tx f0 qK jP VI IW TJ X9 zi n6 WO wB sE aa ag oc gX -\N iy ub gy PT pD qf me xP w7 rj Tk r4 rx uI ii r7 uS pB pt g5 fw gf dm wi W1 eu rE TQ oO es pd rI tL oG s2 fX aP oK I4 dI lh f2 1i vM cP BH wJ wX of oN tx dt h2 hl qK WQ qZ lR TL F3 Ce Kp yr yG ro yX -\N k6 qf cp lA wP GV eS pL uO eG am tF y7 i3 hD jk we D7 RL b8 Gg uG es rT p5 eg eM tZ ow 3y EO wG t1 Lc wK oL tj en aK fc f6 dF GT OL qC Rn TZ wV rX di ov -\N pP qd iZ qM VK JG r4 pL yM y7 sC qn jf qy rQ p8 yR dI qU hB wd Rf KS GW QG S1 x7 ec ae iW eb ai sQ v8 h8 lE Ea Vh YW yp -\N iK a7 cp SQ q1 lq ql WA qz lr zh RP RA GB w9 ys uI yM pX uP r9 pr eK qv qb hS bg wt kU Pu Dc p1 qo ik uK y9 y0 eN hr tX ts pk jl cE lj l5 P6 v4 wk nu vg oy aq aw rG os aZ uj kC pY qL OJ qC Pc Fj JR bF cX Es vn Q4 Y0 og w2 Ue u8 iS ag ie yC -\N rs dd iK k5 hm dg k7 go q1 qk wT q7 wI wS T6 K0 Go ii ee io yM ey sL sZ sw jg si D3 qQ qW NH lp cc kW xt m3 Ip lN nF Zm qq Tc eX rY aT iz p7 uX oF he oG dQ e1 i7 pj sp s4 oK qT gT Sd xf Ow Qr Pd HD wj QH x3 YB Lx wX uM e6 t8 s7 uo u2 iT sW pm rr qG h3 Aq ze h8 ks zB KB bH EC wB vb w2 oj af -\N ak ds dh jG cp WS q5 nQ wY SU Q7 kb O7 YS sF et r9 tA sq y6 dn sy cx nA j6 JC QI qw qe qr RB Tn 3G eo uH tr ft rI uw oF i5 ue ta fs s3 uy aS ss qU Ns lj wp zF wg SM x1 Ix mc va MI Rx ej yY Y4 t7 ex u1 Y6 u3 up en au dS ap kV qH kN gw k1 zV Eu lU kh TX Qk Dr DH wM Ti H5 o4 w6 yK af fQ sO aj -\N uv sA hb pS q4 As wI Ej Qm zc yd yN fP y3 tD hY UE qw qy es tu uq tX e3 jz UD SV l6 Fu xh DQ wK wX yI dJ qZ v0 Qd GA mP wM yy tn fn yX -\N qh qz aR qQ ma kq Rx Qa sT eI -\N dC df iL hE c1 Jt Qn yd yN pe et pN pi D7 kE G2 j6 RL SK nG Z0 m8 mh qw J1 eu qu rR es eC uK eV uL pf e4 sg jv m9 qF vd wK gU rH e9 f3 oN qV vj DH aa ru ux yX o8 a1 -\N ra qs h0 qh Bf q3 DV bL mr IF wS Df Ev b2 pL om Tz ax yk tA y7 aW dn zR Ax QT m5 xX Wp qy qi qo aT ti p7 tV i0 fM qU sh So lk qP hB P5 xk Ib vd HK t2 np ek yT uM u1 iR sm yF ug aZ qJ v5 WR Fg zV AF qV cK Ay CS wW PQ wN w1 yH as yK eI -\N tR yB df um qf iZ k7 q3 wE cB cj nE Zg A2 E6 ya r3 uT on Rq io oW qx ja qv cx cv bh vJ qR lV PC 3A RM ep uK ed eV aU p8 so fX p0 ts e4 fB hJ qT dY px sf f1 zO vX qA wa Sa qS vM wf xg kF FZ R3 bU t1 TU ez t7 Va e6 fl tz uf gG iO qG qJ h5 zZ nh qZ zt Et bA lU Tq vz xE BB mD u7 oh 5k rV rt tb yu tn ah -\N gr da tY qj by wE lS AV kc Qc wI wO XR mX CM yg oE XS pr uA pt dk oY hP qm qQ zW vK xi lN HE RX kO Dz Yt qe Tv EU qi YZ tt y9 eV rY ym aY uq pg oJ aA s4 sg hp f1 qU wp qA bn vi OS Iz Hw kt t2 rS wL R0 ez rF pv hs oM dD f8 uj dJ pT dK kM k1 qZ qX wc n3 nl wv QN zo vx wW Dr yr oj r1 tQ -\N ra jG jr Ao c1 WH rj fP gz Iy lo gc Dh qw qr 8p eo eV fu tL i5 uy uu ui qP mb HK yT ou aq oi e9 iP dt k2 qX vb mF iD -\N rd h0 qN ql lA VG qz lw q8 RA SP Ts pr av qc vS vG kU Am Z0 Lo rY eV eh i8 aA pl dT dU I4 zS W7 Wj xl Yg Yh rA ex u4 pn lW GU Pc ON n9 n0 wM EM tn -\N gB iK rd ql xI bd YR E3 QQ w7 Ex rz on uI yg ax fO pV ab tA jp qW xi Wi qw qe FH mz eo Gk qu uJ ed eV eN fo uX yE fV jv ws lx kr KF N5 QJ EA S4 vh ez uM tj iR od gA tk f5 dH uk pR pT In v9 jS Sv qB zN wb vl ZJ wm CA Mu zs Ef rL YW u8 eR iD uz ah -\N iy iJ ub qs lO ql jK DV H0 wY cM q7 wU Eh FQ w8 Hm w9 mV yd rz rx rv r9 eH pr eK dk eL hI qc sy i4 qQ lp jj we m2 G2 FO j5 wy m6 ve Tx YG W3 RV rn rQ qy HS tt y9 rY ym eh to e1 ur ff hK dO wa kq jW P7 Yp ky R2 Wx oy uV rA yT t6 yY sz t7 wC s0 of dS oM kX ng qL qZ vj WT wb lY wm LW DH mD eW w3 tv eR as yu aN gZ sI ro do -\N o9 k7 q2 Dt 1I wA Uu T8 uT mV eF uO g3 gj hP jN Nt cm RJ ms wi b6 IM qu eo yc eX qp eg sf dO sh I8 Ih qA wa wf kD Yo xj QL wF ek uN wX t7 s8 rJ f9 qH qK k1 lQ h7 In nj UM Bu qV OV n7 bH BN 3z w1 yt eT o4 gL -\N a2 gt rs tY rd rf qd qN jF qh k8 q1 qj ql d4 cg wT q5 z7 lr WF wU q7 sD yg yh g1 eG tO eL ih sw tF fG qx dv q0 wq qQ UU PX vL xi Js Jd ZE La uD qy rR KY ft i5 eM p8 p9 i8 hG im aS jz tN qO UL wg 8d vs AP mQ x6 no t3 uB wL tf iW rH oX ua pv iR us pb tx pW dG h1 uk UX cr Sz ko wx JW vl rC tv af du eI -\N gM wE cM jX lF vQ vW kb WK E3 Df r3 r4 ew yf tI id fe fr su xr SL Jg rQ rW uq tp ss qY ws OD nV wG rO t7 ar th aK dA yF sW iO jT cq v9 KB IY u9 -\N qd ga q1 H8 xT Um wT nQ wY wP A2 rg w7 Hm Cf Tj uT r3 Ch oE r8 pa qb jB zW mM wq PL m2 wr wy mh HI ei qy nw uF yv s1 fX ut sa tB ss hL qU qI zP Nf zD AR l5 5H Gm vo Ix xk wk wF vf el R0 sx e6 uo rJ f3 em dD uh qJ cF wz N9 GA TC Qk Mu RT ye w4 o4 ad ag -\N qa jr kz c3 c6 vP E0 NG wu uG ty uK tu to hr sp UD m0 AR Pa qF wf kr Fi Ya kK Wl Xs ED MP X6 uB gU fh rJ e9 yA oM wl vj Ha EX Y0 iD -\N qM q2 Oh cd q7 Kk LD ys yd rv yk id wt qy iz rI fi i5 ic e1 ht 5Z iQ ha ai sQ pn aL gH UN Kt wQ mI Dr AX u8 u9 gK ru ov hc eP -\N iy sA un h9 rf fI hE Uc U6 cd q6 wU zl Zz rk LF yd rx d7 eF er rb d9 r9 iM hU zv ps qb jf qm M8 qQ Ji G2 kT qq EW La Xy qo es ft ik tL yE ur aS tB m9 I8 qA kA qS bm zG Ix Ya kL t1 wJ R9 oi uM aw yO iE yS yF hg gq nh zC Sb NW Qf xm BC xR bJ Es rX w3 yJ iq tm di gX o7 pI aj sP -\N iL qf pD k6 H0 NA IS q8 4p zl JL Z5 Hm Ec io sF dk if gd qW 1A ld lf qr yx rE TQ y9 pd iz yW sa wp bn jQ W6 v3 x2 bR TA yI ha en o1 iO iP pR kp nl lT kd Eu kf KN n8 zs rX ux -\N iH dB gM jD wR zj xP vP qb c8 PC G7 uF uZ p7 sh or xh xM wh MT no fh dH wv TK lI QM vb mS iF -\N hE ql wI bN C1 rc ip ia av oR y8 Mx Yr Dx eX Gz 1p Ic wF aJ kN 51 bJ wN o6 -\N hb tY dV gu pS qj lS qz ch q8 Zh xP bs vT rh oE oT pB y5 y6 fr ih sC q0 Re Zx lM Id xp Yy qr rY aY p6 he dQ s4 ff qT sd vX jb qO qP Gb ws wd Sd cO Fp KG S1 nM rP CU 8l Y2 tf ev sn au us fz hj qG wc U4 Au Qh wV BN eQ r1 -\N uW vR eq rx et rb fA eK id qx UI kR WN uF p4 tL aU hw tX im Sf yD dZ bO wb xW -\N uv yB iK qd gM gp k8 qk Ao z6 PS mw zf jC Eg A1 wA 7c zz rh YI LF pL r7 yh d8 g2 r0 tq su cz PL qE QE wr WV kU HO qt yv uJ ij es eC ik yn ym uw tL sM he p8 fa ho wo gY ws zF bW nB 5q QL t1 rO rP ej Xg uV el L8 rD wZ rG gO rH sv fh yA iT pn hd ao aZ tc dr aC dy Ot Sj nd qZ OK UM OL Sx xb wb WI n8 JI rZ yr sR H6 eT o3 ru rM pI -\N rs fI Ag c3 Lw ys eF sG qu qi uq eh e4 gY Qt Ya rO HX oa f5 1j Qa cL wQ rL yH pU -\N ub rd qd fI jL zk oQ r8 y1 tP sL i2 qn SD cQ 6d mj W3 p6 ta fM BO nV Qi wH Yj e0 ao uh kN h6 r2 -\N pA q1 Fm c4 IG Ex 2a YI mX eK eZ dv jf qW qE 4s xt ld Dh qq mg qr yc eh s4 HJ yY s9 pv rr uj Or qJ cD wc lY X0 wV Hh ye eW yH rB yK o5 tm -\N pP q3 mw RD uP tD j2 lV aF Ih hB Ee Xh yY ua ug aa tb -\N sA tR ds az qd fI dN hW qg dh qh NT z3 qz Ad q7 q8 Tf vU uE mX vP LG Tz er yj tO hY fr sw tH qn hF gx jj PZ wt lB cm m7 wi b7 vr Lo YL qi rY ef sN uq rI fX oH I3 sd I4 ho vB wa qA Ik UK AR Hw l8 Ya CW S4 wG R7 ot wK gU u1 fh th rK en sm u5 iY iU re pR hk qG kN gq cF h8 nj ct GP wb Qg Hj wM Cy ok eR tv u0 sY fQ o6 gX eO sP ob -\N yV ak ra co wY zj E7 ew Tl fO eK eZ iM q0 jM bj lC Tc rm eC OU bn Sd OS x2 Lh wJ ot oi Y6 e6 yP oB sQ P0 jS Qh EL bG RR rC XW pU -\N iH um k9 q4 lS jX Ej om sF Uh dz oI qx cl zm qW qR Zc qe I2 i6 uu qP wp ws qD Sd FJ mx QK YN wJ uB gU ar pn rr qG ln dL AL Vg mF w6 -\N tR ub ds jD gp qk jK d4 kv xO wS Gi YO sJ sL eL tw i3 OW QE Zx NX b4 qq EE eu uF uH eX p2 rR ea rY ef eB y0 eN rI eh e1 oH fX fV sj jn xf qD vi l7 wG x7 R9 uV ek yT ns aw sx sc Vf tk ud dS o2 pR kV aB GT v6 UN qZ WR wv Rb Os IE U4 Rm zM RW n8 vc za Q3 Zu yy o3 yi ag pU -\N iJ a4 Uj GG jy Dt 1W rj A6 r3 ii pe r0 eJ tA tS fF i2 hO Ov wq kW QT OT m7 qq xV ei LV KR YX yb rI fa ur dE pj hi Si jQ wg R4 x5 HJ oy 5i u3 tx tc nd v6 OZ wc qV BZ QB Qj ZL DG Ed Ka Vh w3 yt eY w6 -\N o9 fT az pS hQ uQ a8 ql wE WG z8 YE WK bf RS wA c6 Dd ys rl Wy om pe iX y3 g4 dz gf se tG pa vA jN jj Al qW SF ma j5 QY wu xo Dc rn Se eu xB nw qu qi p4 ef rU sM eh im aD gm jv PM zD G0 wg QF AI QZ YM QC t8 op iW oX ay tc aV k1 ko vj qB zo wQ bG Q2 n0 rL yt as rN uz -\N o0 jq qf hE qh 7k q7 kb wP Z5 Tl ew yg et oR eZ jp g9 jV gk lX vK vw QA qo OU QG kK xz Rx rO Wc oa us iP x0 ku Hp JR o3 -\N pP dC gi fI qf ql by wE lA Za Un qz q4 jC Zh wP Kg O9 Qm bM Wt r6 Rw eG iX yl tP am a0 aW i2 fH tH xq gc EQ xX Yr qt Xt nw qu rI uq tL ue pj p0 hK vX UF jm kq ws Jl 1s P6 cA He X2 wk wD R5 wG bI HK rO wJ t5 sx fh sv e9 yA aJ e0 pn ao ug aC kN h4 gq nj WR cu Qs kf vx xW K1 og yt u0 yK di gX dp -\N iJ tT sS dV a6 Uz gp qk cV lq ql Un kz GJ wT 4y FQ lH z0 6H w8 vP r5 ee tU sG pV y4 pu a0 tG q9 gx qQ qW we la WX Rr ls zY QU wi xZ Wi xp EW qe rn ei qo uJ rT fy ik TR tK sN pf i5 tC sp s4 in gv i0 f1 Si kS nL kw bQ cO MU EH oi ec sc wC u3 gA fk sm oM kB wx Bo ZJ HV Y0 EN og Q6 eR tv tb rB u0 w6 tm -\N rd iK Og q3 q5 cN xP c4 IG mi E0 rc yM id tq oU po gg qb sy Ob hF PK xr QR UP j6 nG xX b0 qt Tm eo Vw uX yW pg tC e4 gY P4 XV Pd wg N5 R3 wk Iv Rl Ht oy uV uB wC ar t9 gA s0 em pW x0 pT bw wm vv vm yG fn ad af do -\N hb GG kl q5 T1 mi A4 B9 r4 ee uP pr g8 gl q0 cc kR c9 vq Yy Wa qy mz ty yn yQ aI oG tX tN Nd ws 1d ky x3 sz td gU t8 op gS tz de aV Sk cy zM be wV Qk og uc -\N pH qj d2 cd q3 q4 bi wP vT oQ y1 ps cW Kn Gz ij p4 sp e4 wa SX Nj v1 W7 mE s7 e9 tc k1 lW zC vj wb KB tW a1 aj -\N rd a5 hQ qg qh q1 lA cd kl Mp K8 mJ vY zz YU uT uO sG yz hI gk sy q0 m1 qW b5 wi Dz qw RC AW eu ZR uK ti eM yR lk kw nZ wg FX TT wG x7 rr lm jU TH Tt eQ oc o6 yX ro o8 a1 -\N a2 dM wY Ej rh RG pe a9 oI y7 zT vK Ga YF Pp FH ml tJ p5 sN tK im jv V6 lb Pf zq TY wH t5 gO sv e8 iT f7 aC P9 cu bw kg Qk F7 w2 eE w5 tQ eP -\N VS rg rj 70 YS Nq uF eX hH jn kG EP e0 -\N df q3 U9 4J bN rj HW uP tD i1 dc hI zb WV G3 l1 RZ qt qy ty tJ ef eg sM tX aP in px aF mx R3 R6 t2 t4 rD uo e0 iY iI hh qG zC v8 qC cH Px zy zi ye og eR tm iF -\N gr pq SE pp qe lQ n1 cy qB wB eY -\N gN q1 ji sC NH Pe YH qT Ss rw hf KX zM o6 gX -\N iH hQ Ap bL wI wA 3Y er pC eH r0 yl tA tS dl gg fG i3 hP kW lC ls RL FF Wg qi uH uK yQ yW oK aS wp Gc jm QF TO yY fh e9 pn qK Sz Nm lI Q1 vb yq 2e rL tv sY di sP -\N o0 yB rf k6 qM Fv q5 wI RP FE Dd mZ rz ee oE ia yz am ig hP fJ su gl li we m2 ls xJ md Z0 uH YX eB eh ur i8 qY oe I5 jv cE jb jm lx cI kG oy HX e5 u2 tj kV qH Qo AF Pv TZ AZ Vg yZ ri ge -\N iL z2 d2 cs ba wA 1O ys uY eD er d8 sH qx sr qb jd Ov xq nU lV G1 kU Pu Rp qq EE ET rm eu XH i5 p8 tX in I3 bn v3 AP R5 oy sl oo dr dG hj lm Sk Ff VU cu wb kd zi wV Mu w3 yt ok rV ol eY yX ah -\N hv qs qf qM pH O2 zg wA A2 rl pZ oW uO y2 ey iX uS d0 eK fG ww j4 WV A7 wu qq bv te tr uJ tp ue ts dO qO cY UK J5 rA ou aq iQ ev tj u5 tx gG dF dG h4 qJ Nc wz v7 Im KV JT Y8 rZ w2 yy eI ge -\N gt df jG Og k0 lq kz zf Iw Kh GV CN uR eA eq yj iX id eZ dc qc st wq c0 lM FA LJ qq mj Sw qe xB rQ qo yn rU aT e1 p9 s2 ts i8 s5 I3 sf jc xa hB Qq gY wd P5 Ow QF wj 1N wD QZ yT ex e5 op at sm ud tz yF tc aX f7 dG qG VE Sl qV TL wn 2H Ky Yv F8 rt o8 -\N yV dh kj jL wR bi kc 4J nT c5 LO Z3 E8 on oR g3 g8 UQ sr qm hD lL c0 nH Ws qu uG ph tC dY oq qO nJ Wn t7 oX zJ qJ kM h6 qL zZ qZ qC HN bK fW ob -\N un qs fU k7 co je gp O1 Bg Dt vU rj mC rz rx r6 g3 eK qc UW fJ li qW lX kU Z9 BR b6 mz yc ty tL yW yR e4 I3 UD cE I9 Rf bQ xh EP wF ej rP Vu wL u1 os ay of pm ap gG dt hk aB qL lQ Qs lT nl U3 wQ n7 BM Ef Xm yH w6 ru fQ tW -\N qN ql zj RG eD hS we qw rE p7 p8 yR tV pc lh Gx I8 wp lz cP fv lQ 1b di -\N rs Q0 is q0 Yq RL qq vr qA v3 TU In h7 zy u9 o7 -\N ak pw Af z0 wA JH Tf tO ey r0 tA fe tF tH wt m5 xu wu xo l1 b7 bv Se W4 qi es dY gE vM l8 nV kH l0 J9 bI ez iW UX f0 GT zC 6W bF cX u8 w6 yo o6 fW -\N gB PY gp pG Ql Um lF bX 6q RA w7 vU rj Ui pJ Tl ii y1 r8 ac eG yl sJ tP y3 py iM tG zv lL Ip wt Av Fq qw Dc Yu ei uF qu TW y9 eM tL dQ fX hK oq zU jx hB I9 bQ Iz mv wD Qi Pz Lx EK aw fg aG u4 iR tk of pb aZ f7 qK wz lE Qs WY wn DD bJ mP yq ZB CJ rC tm yo -\N o0 pA rd qf dN qg nm ji q6 cM wP Ec uU ax r8 uS aQ se lt G1 bl vZ JC mj 6h uL eN yW e1 yE tC i0 dO gE Gn v2 R1 7F ED x8 rF oo t8 s9 u5 pb fc ug aB pT UC ce qZ h8 U3 GA Fl BC yq iq iw iD o6 r2 tE -\N da qf qN nm wR Jw c2 IG rj vI ys pL eD ii ax y1 uA r9 ia ab tq an eK dl sL jo g8 qv gl hS jf D5 c7 kT IX wy wi lM qq Dz kO qe FF Pp qt eu Wd YX eC p3 rT ty ik p6 pg i6 e3 sa fd dR gb jl aS hZ qO j9 j0 qS qD wf P7 bR wD x5 HH t2 wL el rF tg ar rJ tk em ud pn rw aV IQ nl qV X8 OV wQ wB EC vm Y0 w2 eW 5k w6 fW a1 -\N a4 a5 z1 hR qk q3 mq zf Qc wU Q8 bd A3 xF eS yN rc et d8 pr oR yl fA se dv dn UY vZ wu En Mb QA tJ uq i6 pl dU jx f1 xs qS qD vM KD wh kH mv ED rP rA CO tg oa u2 iE ha iR dA pR cq UV Oy qB QB Eo ye rZ rC eI o6 iD iF do yC -\N a3 qs w0 po gx xo nH uJ e1 lz OS wj uV ud tx rr gq VE cH CS Xz -\N rs rd qs qd hW dh q1 ql Dy mJ zz wS vY pJ eA mV yf om Uf sG uP iX pB ab eJ tq fr tG i3 Nq dn gc WX WC qR wr lV T0 cm wy wu kO qe qr ZE uG oA ed ym p5 oS uq i5 tp pg s1 oK tB fB vX Ns P1 wa qS kA qD lx Ps Sf ZY kJ Pl rO rS rD wZ tf ev gP e8 u3 iR od f5 dH qJ cw qK h6 qL AD qB Fj TL AL zs H2 rL eQ rX eR w5 eU yZ iD pU hc tE -\N pA pw Q0 j4 4f vq IV Yu rY fa e4 kw xM wj t3 Ff ye w1 oj rV ul eP -\N mw Di Ec Wt rx kO I4 qO l3 iQ iW pY yL -\N dX uv yV qa a3 iJ pS qh cg Qc 2N mC uT eq rz eA Kc pZ sJ dl iN db fK su qm qE m2 we 1q kE Bn xy WB Yq qq vr qw xC Gf Tn rE oO qo p8 iv e2 tC e3 e4 fV ff pl sd qY qI Si PM ws AA zw bU Hu FN Yj pv hs gH o2 dy ln v5 qV zB TK bq 4P Qj ZZ wV 8n H1 Y9 wM yw og mF u7 tQ ov sP -\N iy wT GX ND T5 r0 yl tG dc qc tH wt ld nD Zn Tc KE qu qo qp tK fa hH gn qP 5D qD AR Rg oZ fh at aG 2A kd nx w2 w5 -\N iL wP ee yM tU eF dl eL qb cl qn Ob qE qR m6 mf Xq I2 uD fN pc gW m9 l7 Fs EH gI e7 fk yS pE OK 30 mF o8 uc -\N dB k5 a7 je kj q3 wE wT q6 Ie ck Kg kn Gr LF pJ io uS id iN aQ jo qx su hD qm li qQ jM we lC WC ld D8 lB xJ Em rn J4 TQ oO eg fL sM he ue so hG oK dT qT px j7 qI nZ l9 Lj x8 wJ na wK ez ex rG e7 u5 h4 kN AD cu Oa Qd DO Q4 eQ w3 yy sY sU r1 ri iF yC uc -\N fR iJ fT dB dN gp qh pH ga GG kl WS wT AB q8 lK wP mi w9 Tj pK yf ew uS yz id gd y7 dc qx hP qv gl jN q0 D4 qW Re qE cn cQ Pt wu lM Dk Cz Yy qr rQ te qi rR ea eX yE dQ oK qT sg qA nK wh kt bT BD Lh wF YB Hu mW el rD rG sb em oN qG WQ OJ zX wv n4 Bo Qf bF RE wB EV yq CL yu w5 ad ag iD a1 gC -\N qd ga Dt Ej kn r5 ax sG iX av am pu g5 eZ fe qm nU Ii zT wr VM QT Jd IM RB ml yx yv rU hr gv aD DW X4 uB HX wZ rD oL oo rG yF f6 iI uk dL wl yw yu ie iD -\N yV ga z3 kk PP nQ le lr bp Qc T1 c2 Hc vT Lw JL w9 uR r3 ys iu eS rc Ud yj r9 pB oT tA sK gj jM gx xG SF lC qR HT ve SL G7 qy nw Vw fo ta tB oq fN qU hC qP OP nZ Ow wk ZO zq Yg wG Ke yT Kr yY sb tk rK tz iU o1 rr pR qH dL dZ P0 n2 ci CD vn mS aa yH ry w6 af du gC -\N q1 q2 mw bZ K6 xF Ec r4 rx yg eD d8 pV is sJ qc q9 zW vF gc cv D0 xX RN eX uJ ij ts ff gE I8 zG 4m x5 vh oy yY Y5 wC tg at fk oB fv f9 qL bO k4 zN be wW Ea RY tv w4 ru ov -\N tU g2 TQ oD pk tM Fi Y1 uf ku wn eW -\N hn rd um qg qh pH Aa ZN bC GV w8 rj eA eS uI r7 r8 ey fw gh jf qn nU cc la 3U bx ve Po ET ei eo ea qp uL i7 uu fB dT pz qT m0 zF l8 kL t1 ej wJ oy rF th rK gS sm em ap hg o2 UB wx ka Hd br Q2 Hg Y8 2e eQ tb aN oc it eP -\N tT um gi qh lP kl lw q4 q6 RO b1 if y6 qc tH g0 q9 qm j2 we xt xi nD Is nG bc KU yW sM yE dW e2 f1 lg qO wp zS gY l4 UL lv W9 bR xl QL vf AS Yg Y3 t5 wC ec iY hf iI f6 re hk qZ jP Oo qX xv v0 F2 vx CD vb yq eW Zu yX -\N lO Dt mt Z3 RG av uS pa xq wq qe qt YX y9 eV rY tK hu oe OI R1 x7 wK wZ td jY WW qC 15 bA Hd mO 72 -\N rs wI vT rh We JL uR Tz tw hT y8 fH i3 qb qm b3 qy ep oP yn tu aY hw fd UG qP QD x7 rS yY td u1 t9 sm uh dZ qL 4T RW KN wN rC eO -\N a4 d3 kk q5 q6 WF WG M4 2B vT w7 uR uO Rw pC g2 sL if y8 fJ vA Rr ld WN xo qw rn ml La qu ep rE rR qo pd eg oG e1 i8 ui qT px I4 jc gQ oe Jj ws kS QD UL zH SM QL tf gO e8 os tk rK ay us u6 dw dH pR qH qJ Oy lm jO cF Ff wm br K1 EN og aa rB yJ o4 tE -\N gB dd rd qd a6 qj wT jX z7 xI q7 kv mV uY pK oR yk eK eL y5 eZ aQ dx qx tH sy jN Pe vL FP xZ m8 nG Jh KQ qr La ei ft p9 oH hJ tN ho UD xs wa jQ vN Il zG P7 Fp Ic QK wD bU e7 gO hd sQ ug hh iP Sl cH qC Px wb Hs RQ Qh bK rL Ef yw DJ yt u9 sT yi uz uc a1 -\N al tT pq um uQ Un z6 wA vU w8 eD sJ r0 tq pu dz qx js 2j nA Ip vZ lM qq qe YJ uD ei Wf qi te p1 tu il tK iv dY I0 xg Sf Ix gP fk ai qK lm qL cH Fg qV Vg yw rL yy rV rM pU uc -\N rd iK qd jD pH gs k0 q3 qz IA q6 Af q7 6w O8 Tg Gi sJ oU aQ po ja qn q0 qQ gc NH xt wr FS m8 qw AQ Wp HO qu RM uH tr qp tJ aY fi aO i8 aA i9 tV gv qU wo lj vV wa jm qA qD UK nL G0 QD Dn GW Ic kJ nN wF wG DY ej rP Y3 rS yY e6 wC oZ fh eb e0 of hd yF uf aB gw qC wW Yc CD JI Y7 n0 wN CG u0 rN yp ie a1 dp o8 -\N iH h9 qd xY yl eZ g9 lt qm On vG RZ Dx QA KT p1 eX YX oD uZ e3 in sd OI qA CQ DR mE e8 ua yA dK wx bw 4P Vx tn o7 pU -\N iJ rf fU jt gs lD wU q7 wO 2u bd K8 rg wS Gi oE yl if sq hI dn jN qW Bb cb wt lM Sq vr qe Wd qi qo tK uC hp I0 Pa W6 Fo v4 1M X3 t7 u5 sQ ai hg ap hM jU Fl TZ wV w4 ry tn yL fm gL ox -\N ql DB ch wU rl ih qc 25 PB qq ty yW fp aO qY Sp P1 qA rF iU rw qG uk gq kM dZ wv At qB JO eQ Ur rB ad -\N ra fY gM iZ qk qz lF bp kc IS nR wS mB eS Tl d6 uP pe ey sJ fq eK iV pN sX ly qb jd jN q0 lp m2 xL FS xX Rs b8 HU RN EY qo yn Vr yQ ti aI e1 so ts jz dU dO OI Sa I0 Oq Ow 3r 1a wg QG R4 YV TY R8 wK wL s7 u4 of e0 gD pm yF h1 qG n1 lT Sv qB Eu WI Mt EZ w2 yK sU dp -\N rd qf DZ Aa bo PD pM qW RN TF aH WU -\N dV jD hE jt Ao ql zg eq pZ oE dj fw sC fJ Nt Io FI Lr xu nS Mx qe qt ei rQ qy yW eM e1 i8 sp in jv wo cI Fa x6 FN ej Wv oi uM yI oC au yF Mt Te AZ Yv yi ad yo yZ -\N uv hv tY qd nv jH qj q1 ql wE Fv VJ q7 Gw FE WL vU w8 vP 6K yd r7 yj ia ey oT g6 dx tF iM hU aE qx fH g9 lt fK hS su Ov lo m1 cn T9 wi kI qq qw xX AW nw es yb Vw yn rY pd ix eM so ut oJ dU f2 lj qP jm W5 xh ny wG 13 Wc QC ek el sx oo th uo yO at pv hN uh hj qJ zK qL lW zX qV cC wV EN yr w3 yy sT Uy iq ox aN ah -\N rs pA df iL iZ qM k9 bu jZ bi ji Du LO Ts YY xF CV Gu mC ii rc uP d8 ey pV av tO yz y5 fD qx sC qv jV qR xt bk m6 OT md qq qt rQ eX p2 yn sB XC fp pj qT cE wp I8 j0 wa qD Gn Ps qF bE Qt wh ky l9 ZA wG rP Wn fh rH em Vn dH VW ng wz k2 h8 F1 nz ZH Yz Q5 Zy E1 yH ad tW eP tE -\N dB wR A1 pK ew uU r7 d0 pN fe g8 la qq b0 ef oS oH pk fM wa Wk yI ev ua sQ WU n5 Tw Xc eR -\N fR yB qa hm d2 q2 O1 Oj Ox DM Oc km Kj r5 pX rb et r9 y7 vS PJ q0 4s lM Gs qe eu ep ti tL oF jQ OD Pf nr nB EA ej yY rH u2 iU qH dK zL qV xE 2K vc vb ZB Xn yG gK ox tW -\N hb dC rd fU gu zd JS wU xA c5 A5 w9 vO r5 d0 g3 oY iB i3 hA jM Nu Rr wy m8 b9 Ws qu rU eg uZ hw eh hG sp sf dO jb zP dP nZ wJ Wv fg ae aH oB hd dD gH dZ qZ xc S5 VI JE n4 RE bH mA wM as sT tn yL -\N wI w7 om Ug qA x4 YN R7 gI re n3 n7 -\N iJ pA qd qg uW qM d4 z4 q8 T3 mu YP Uf ia pM eZ ih qn jM nU kW qR j6 qw bb Yu QS rW Wf rE qi rU jz tM gW lh cE xa wa xs bn nL Ys t1 wK R9 gU oC u4 hd ku Hp yG rV as yZ ro dp -\N qa sS dC gu qk cs cV Fv nm z7 lF z8 xS A3 rk r5 YS eG y1 po qv cl jf xq vH we wr qR b3 bv Yr Wf rE qo sV tJ ti eg dQ ic fX jz dU qP vB ws nL wd wj zq vg t2 ZF Wb tf yU ex yI yP tj en ua ud dr pE qK dL lQ qZ h7 OL v8 cy VI wv cK EL GD Q2 yw w1 ye XQ w5 gK o6 ob -\N k5 hR jK ju K3 Jq q6 zg wI ID bB wA GB RF Rq g1 et oT pN hT dc ww c7 we c8 cm xo mg W1 1L yx tr p2 oO LM rY aO e2 i9 e4 hi tN dI lv cP cA 2U t2 no uB ex rK yS pW qG aV pY qL Qo Lb Pn Eo wB eR tb yK ie iD r2 tW o8 -\N ra qa qd pH jH d2 DX d4 2Z jL q5 lD cM wU wI 2t wA Dd LG uI tO id iN UQ ww Rr G2 wu RL qe 1L qi qo eC yn ed uw p8 ut sj Ig P4 zH xM P8 vs vg x7 ot CU L6 sx gU yP t0 gS aZ pE nf wl qZ nj lR cy WR qV TJ S7 U2 lY be br Ym w2 af ri it ob -\N pP Uv nb bu kz wI Ah Z3 c6 rg LA vI oE ia oT pM dv gk 2h xq kQ xG bv qr b9 J2 eC oD aY p8 qI wp zD AY KG EA mQ 6b QC uN fh tl u5 aV UB jI zX k2 wc zy 1x KC AH RW vc wV yq ZV E2 rp -\N a2 iy sA fT pP un qN Qz Ol lF mG wO FR vU ya rk w0 pJ pL eL dz i3 jd su Ob c8 PB Id b9 ep yn rU tK s3 sh sj xa l3 wa Nj ke kr Ic xl BD ej rG yO f3 aL f5 sW re uh h2 aV cq bO vk kf bD mU wQ wM eW Ue tv ol tb o3 ul ov -\N iy a5 gu q2 SE lS Dt zf O4 DM Ez JJ Uu IK uE w0 YA eA on uI tU rv y1 et r9 tq y5 hT dc fG i2 vS q0 Av IV kU IN il eN rI p7 uC e2 ut sp fV qT gn f2 wo qA OP V7 ws l6 wh Ys zq t2 Wc Y3 sx yI t9 t0 yS of rq ug o2 aV kN h5 jU jI ko v0 nz wn kf Te Dw u8 yt fn r1 ie yC it -\N qj lw ji eq oE g7 jf JC Yr qo V7 P7 wD MA Xg wz qB u7 w3 -\N un Ol eH g5 PX b8 rR oG gn mx Yf Wv sl oN JO uz -\N qg qM q5 wY Eg RI bM mZ d5 rx pt eK fS pi tD eZ hO gh q0 lL PL kQ wr D0 l1 qq kO ER qt Wf EI p2 rU uq yE tX s4 hC zD vN Ps Ix ZO Wk t4 Y3 Xh ez rF u3 up yS Ou xx zV Qa wb At Rm Eu Qj wV za zs eQ Zy rV ry tn tQ yC ob -\N sS qa pP rd jF a7 lP H8 Um kc q7 WL rg r3 w0 Wy Tl a0 ih ly qm qQ m1 xG qR UP Ja b8 YH Dc LX rW ep ea eV aY uX to p7 tp tB I3 qU gQ dO gR zA l8 Rj OG oy uB e5 ae tg t0 sQ tx hj AD GS IT vc bH Yb EB w2 yG u9 w5 fn iw sI di ah hc -\N ub o0 iK pS qd q1 ga lP cf kl M3 z7 q8 uE ee Ud iX g5 iB gd aQ fH tH pa qc PG UE UR xw ww qR vJ m5 Jd nG IN Tx FF xC ER QS eo qi p2 KY pd eg e1 yR ut ib oJ tB hi hK ho gm qU qI hC OU Gn wg SN wh Ix wj Wj wG ot rA wL uN e5 rG s7 t0 oC sm tz hf fx pW x0 wz TH qV 1z zt n4 qB cL wn xQ xR Y8 RT Y9 rZ tb iw Vb -\N qN lq bu Eg Iw wI 2u 3Q T6 K0 yd sD eD rb eH eK yz if pu y6 iN fr qc qm Ob IL ma b4 En wu Dk nH b8 qe bb mj Ws qt HO YL uG qi ea TW uH p5 eg tL yR i9 pl lh cE I7 wp qA xs Dn 7P kr P7 EO vs mb Pk ni Yh EF rP wJ ej Y2 iQ Y6 u5 em e0 iI MD jY lW nj Fh bq Pc xm KM Q2 wV K1 rX u7 Ut eT gJ tb iw gX fW yX -\N qa pw k6 qN qg qh As U0 Dy q7 wP Hv 4Z 4C w0 d7 et aW wr bl Mx md j6 An wi qt LC yx eC tJ rI fX ht in gm UA qO qA Ik Ys Eq N7 wH rS wZ wX e7 eb aK gG iP Sj pY ka rL sU ag -\N gB Uz q2 qz wR q4 z7 IA Ad Je AM my vI zc mX yM r7 yk uA pt g6 hY y7 sX ih qx pa hP jd sy gk NH No qq YG RC 3S qy ep p2 yb oA TR eB p5 eN ic yR dW tC in hK qT zP I8 lz kS cI Lg X3 wD Xa X5 ZF yT Y5 op u1 oa iW fh oC rK ay pb pW uh qG zJ qH h5 nf cD Nv qX kp Qs qB 6Q cL kh xE u7 eW tv sR as rt o4 eY tn iS -\N hv qj bo RU z9 T3 lJ Q9 rg vI rj sD r8 g2 sJ yl aQ fe po pa qv jf dm qQ Re we la wt wu qq vt Gj ei YZ rR XK uK pf so pk im zU UA sg j8 sk zD Sd xz zw kL wK oL uM yI rH sv u5 pb tz dL Oi wz h7 S8 Qf wn cX F4 mO wB Ed oh eE eR ry eU eI oc fW -\N hn a7 cV q6 cj q8 fS jV RL qq QI oD dT l5 cO Qr zq ex u2 aH oN pR wx kp wb yH gX -\N gV qg je zg jC q8 FR r6 yN ii g1 pe sJ tA eL jo sr jV nI jj zR bj nS qr qi ur hZ vu wh cS EP S3 Hu ez rH u2 t0 dw uj Oi wx n5 18 bF wB YQ oh ov -\N gB dC um jr MN wE bL T6 vI pJ C4 d7 rb ia yz tF qn dm kE xB ft aU ix tV xd Qq xg Rx x6 vg R8 wZ op h3 qJ qX lR xv qC KC WP LQ Ea rN rM ri eO yX -\N ra gt qs dV iK gN co qg qM qj cB qz z6 wT ji q6 Dy Qc B4 wS Ds vU Cf on yg d8 eH py hU tG qc hP qn D3 wq c9 PV Pr OR qq ml eo uG TW es il oS fi uw to eM ic oJ ho px wo qP m0 qA 1o KS 7O cP wh wk wG X5 Ee YN bI EF wJ ns R0 ez uM u1 iW eb iR fk oV s0 fl hN h1 pR x0 UX cD wz Aq jP Im k4 qV bP wm n0 vm u7 w4 gJ tm uz tE a1 -\N gV iL pS dB hE nb wR Ql kc zh Tf mp Lw ab uS pN a0 tG pa tH ps hF WC 1A Yw l1 FS EQ Wp qr rW yv tr eh so i0 qF wf l7 wG na ou aH ay f4 iO iP f8 cD h7 nj Rn wb qB QN WP oj w3 w6 di iD pU eO -\N hm fU pD qk bi WF q6 wU B2 q7 q8 Oc lJ c3 O7 6S A1 JH RG rj 2s Z7 YA id eZ fr gh VL cl zQ hD jh xH Ru c0 bz wu Dl qw Km kP b9 rn eu yc YC p4 rU tK uX fo ue p9 iv tV s5 dO l4 cU Rg W6 OS Fi 4b UZ l7 Ld l8 FX Jb Ee Wx rP ek tg e8 uf de qH hz h4 qJ gq Nb wx qC Sv GO wm zi zo TC 3k EZ EC rZ ye oh CK w2 sY iA gK rM eI sI dp -\N gi go z5 qz WJ mG Kl yh g5 y6 g9 xt p6 eh aP sa qU DW J8 QL Yg aw t7 iR zJ v5 v7 bA Tw yq CZ gC -\N pS qN z3 SW gs q4 Ie GX YE WZ r3 Us eF d9 pB y6 tG y8 qb gc ww Az c8 cb lV wy A9 qq qw l2 C8 qu uF yx qo ic dE ut e4 uu tB fN oe dP wa UJ bQ Sg mx lv v3 Ya xk wD bY N7 rA CP gU Va yO u2 sv rK iR yA hf kC kp bO qB GP QB Yc Ku Q3 DJ o3 eY ad sI o7 tW ge uc -\N dX yV iJ pw a8 qM pH k9 DZ q1 q3 cN wO wP my El bB Uo on eH id yz am fe hY sw hA M8 vG wt vL WM qq W3 Ls Gj yx eo ef eN ta e3 I3 zU hL m0 wd cO ZY l9 nN EA Yj e5 rG gI fg gP u4 iR tl tz pm dD kC P9 zX Sx qC qV kf Ln ON QM LW vn vm eW yG sE as iS di ro gC -\N al tT gu qf qj xO q8 c4 wS E5 uR vP eA rz g3 fw sX tH db kQ wt sV tB aD hV 1u gT Ss xk wj QJ Pk rP e7 ha fk f6 dr rr hk dK nf Qo lR ka IE Fk cZ Yz Q3 Ym Ks gL -\N gB q1 qk wE q3 q4 T1 Ox Di nY wA wS Gi eA rx yg r6 io oW y1 d8 ey ab g3 is eK pu eZ dx qx tH i3 jV fK Io xH wt OE kR nD md PB vZ wi Ro Se b9 tr yb p4 i5 p7 uX fp p8 sp in oK hJ qY hZ wa Qq zD qD 3t wj AA DY 5u el yI uo gO t0 u5 tl dq gD rw uf gG kB UX dJ qJ GO wb zM lU TX vc Es EV RY Zt w2 Tp w5 tn o6 -\N ra pS hm qf qg 4q wE Ql q4 z6 D1 wP vT xS Tg 2s E7 r3 ys oQ eF C4 av dj pN aW sr tH hF gx UY wr Ac Zv m6 WN kO C5 qt qy YL yc uH oD rI uq fZ dQ i7 tX fC aA uu qT oe I5 gE cE wa Gb vN xg wh OG Ya xk Fs EA Yf zw wH uB 8x th iW rJ aH yA e9 tl yD tx yF iI fc kX hl zJ Or qJ MH WW kf zM Lb OB QN WP wW wN Ym u7 rV ie pU -\N Uj by wO mL dl qx m3 8i 2Y R1 u4 hj h6 Qa xv rN rM -\N qa gM qh ql U9 lS E3 yk fA tS wr vJ Ac En Id uD KE yE i7 fN tN f1 kS AT ME l8 kL HK Lx rP ek L6 EK oi e6 wC u4 2H Pn 9y Zq Qk EC CF yq oj Vz tb o4 iw ox gX tE -\N gt ub hn qd qf hQ dh q1 lP qk by ql lq wE wR SY wY lH z0 Ge K9 w8 Th vP pZ yg tI fO tP r0 g4 yz ig sX iM i1 jV qn q0 wq nU 5T Pw WM Id qe Gg qt XG Wh eN uC tZ pj e4 tV i0 ff qT gm dP jb qP cR gR qA nK ws OS wf ne wD mm wF t1 Vu wZ t8 e7 t0 od hs dq dF aV kM v5 KL WE Fg cX AL AX yq Y9 rX yH ul hc -\N wE cf q4 cj bf wS Ww yd Tk eF eK y8 qv fK wt kO qe ep rT ik ut OP MR J0 ej t3 s8 iR pT qK kM WW cG wc GI lU n6 yr rC oc -\N ak fT gy rd hn a6 uQ q2 q4 lr IA Eg D1 Eb on sJ dj pN pp qv i4 hS gx ww xJ m8 kO IM rT fi tC uy tB pl qY pc UF kF kt mv l0 QJ x7 oi uM TF ap uk wl qL zB vj wv TK RE Y7 De Q4 rC ad rM ul iS fQ yX r2 -\N dX gB hE DL k9 z3 qk lF Ad ch JS O5 vQ zl rj Wr Th r4 tU uO r8 fP iC g4 fS g6 iM fr wq bg nO wt Dg Ru lN Rp Wi YD qq xZ EW I1 KQ qt rQ Wg sB pj hK qU vX OI jm Pa vi x5 wF ni rO ot oy DI uN Y6 yO rH sb us tz aC f8 aV VE h5 jI MJ n2 ci Rm Yx Ep RT 5f yq u9 rB hx aj -\N iH a3 PI mt Do w7 zc NH qE WV Rs xC qr ts ut pj im hp xa lv x3 Ph TT sc od rr qH kM OC RQ Xl vv JP Ef sT tW -\N fT iK a7 lP jZ jX K4 Hz wO bV Q9 6t uR rl qx qv js dm Fw Wd rE ea fd hu jc qU zO P3 lx Pf wk vf fj 2O wx Sb GS IT ol yp di eO ro -\N tR iH yV h9 k5 qj qk nb wY GK q8 c6 Mj A5 YI uR rl uY eq uP yj r8 XS sH a0 eZ oI y8 ly lp lX FU IL kE zY Cj SK Xq 7U EY p2 uH yv qp rT y9 eg pf so ph tX tC uy e4 tN j0 gY Ik vM UL MT nM mm x6 wJ rP EH sb u4 oV of tc jT pT qJ jY k1 S5 Qs 7Z DO zi cX wQ wB mA wM Uw sR w5 o3 o5 sU r1 yX fE -\N h9 gM cp z2 Fb zd GK vE O7 mt bC wP bd rg w8 rk Kx mV uU rb oR yk eH r0 y5 hT pu tF se aR fJ hP su m2 cb c9 c0 b3 nS qq qw RV Gg ij y9 oA oD oF pg i7 hK dO PM 2n sj wa vM zw vg yY oM qX nj v9 F3 eE w5 w6 iw sP eP -\N da jq iZ z1 lS z5 cg nT zk 1I Gt w7 YI r3 XI yN pC fA tA eZ iN i2 qc UW si qW D5 kW IL b4 FA IB 6C uD rQ YL Wg tr qp p4 rY sM ut s5 hi qI dO j7 jn j0 qS Iz P7 wG aq ex gO aX ku Nc h8 n3 v0 OC AH wm lI zp rL H5 iS eU o6 -\N gr sA a4 iK dM gp q1 wY M5 FW A2 T6 rj mX E9 et eJ q0 OT wu Em FA mj qe YG Gh J2 te tJ p5 eg tK eM aO i7 dI lh cE m9 wa wf Ys Eq L1 t3 ej el tf t9 rK u4 ay rw gG dr hj aC qG zK h6 dZ OK zy KC Mr Fz IU Hk yJ oz eY ag iD r2 ov -\N ds fU pS VO qf qN pF a8 pH q4 cB le cN H0 JG Gy B9 rk r3 pJ yd oE hT pu ig eZ hU q0 qm nU ww qW OW xH b4 Is A0 qq HU bb Cn XH oO qo y0 fZ ue e2 yR fa pj in sa hJ ui Sp nJ zG wj GE wk Xg rA ex Vs oZ eb pv tl iU x0 ln cq xx IQ S7 wv Qs zN TL wN LR yr r2 -\N az qf fI qN U5 wE Jq zh WH c4 sD is y5 po OQ kI SZ qe rm qy yv p4 yE tB ho 1u GQ R3 Pl TD oV u4 hg aX zJ wz wb vl vv sE 5k eO -\N tT gi pD jK lq q6 wI GX mJ uT ax av g7 qv zm lo 5Y Dh cW xo ve vy XG yv iv i0 Qq xg Jv L2 yI sc gA pv pn iU ug GY k3 cL oj tv yL di -\N qk SE PD Gt rz uU d6 io d7 tq gf Em ym tu ib oe V3 Si wa NM wf qF wg Rk kZ yD hl wx cy bP MX eT -\N uv yB dd k9 pH q4 me O6 nR xA mu LD r5 rb g2 oR fe pa fJ hP db lu qn Nr j2 bk kT xL rn Wf qp tL uC dQ i7 tX fV AR Sf xM mx x1 zw Yh Lz mR t6 L9 s8 aH u6 X7 yw ol tQ eO gC pI -\N IA ys jh wy sB i0 cP u3 qL KL kh -\N pO al qg qM d2 gs q2 Ap qz q4 q7 kv Ah O8 RS 2o Ex zx QW Z5 r4 r8 y1 is tS y8 qc dm lL we wr SG lB JX wu JV qe EE qt qy es ed ym hw to tX hr s2 oH dT dY aF dI dO qO OO qA W5 UZ wh kH X1 t1 HK no R7 rP na sl EJ op ev tj eb sb yA pb u5 tx dS o1 hz v6 lW jP k4 wv DO wn AJ BC wN yw To w4 as eY yK iS iG rp o8 -\N rs tY q1 wT wY xP E3 wA yd d7 hT tS sZ fK su kW xG BW cW qw oO fu oD ix sd zU jn qD cI Fi xh MO CP ev th ua e0 em kC lm cu U3 n8 xR yq Ti yJ fm yX tW -\N dX z2 ga kb YO sF sK fD gf i2 vS qW vJ vw qe eu mz tu sp xs qS ES t0 eb aK uh hl n1 v9 wv kd o8 rp -\N ds qN qj qz cB kz bo wI O6 z9 FQ Wq mL CV CB LF eq r6 r8 iC y4 am sZ sX po jp g8 zE we wu En EW qw 3q LZ KW tt ty ti e1 fX ut tC uu s6 ow gm sh qP vN l4 UJ OP xN wh QK Wz Rc wH uV uM ar e7 uf aZ uh pY h5 lQ VT nz lU lI Lm DD rL eR rt yu o4 eU yZ iF -\N iZ lD me Z1 y2 dj aR qb b4 l1 mz ij rY to aD xs Sd wf EO HJ wL ex iE u5 pR zJ GT Oi wc kg mY EX Zt Ks yG eU aj -\N gr iy fT pq um qj DZ wT GJ cN RU kx q8 wS uE rk Eb ee fO jB jf la Ji kE qq QI qw rQ yb qp il eB y0 iv ff zP l3 xM Fi x4 R5 Xd R0 oL wC t8 ae iW oX fk of pb qJ ku xc ct wc IE xn zi wM rZ w2 tb u0 sU pI -\N a3 sS je Un zf vQ Zg wO mX d7 pM gd VN eu YK TQ ik fu aI qT qF J0 TO yY at iI qK wz lW n7 LY -\N ub DZ rv qt rm Wg ea pc j9 qA mR h8 -\N a4 wP Td uR pX qq kI yx gO wc tm aN -\N pO gN rf a5 uW qN q1 nn wE IS z8 WJ Ca T5 IJ Eb Tz eF pr iX g3 eK tA a0 y6 sq pa wq cx kQ qW we Rt c0 Mz PV Py wi cW mj qt qu 0e oA tJ uX pf to hr aO tX yR ts fd fV s5 ui qU j7 gW UG Ss cY kS qF xM FK wg vp kt mv QJ mn Lk vh yT oL rF th os e8 tj ua rK oN pQ dG kV kM WQ kp AD bP Os bw Pb Qh WP zs Q6 u0 gJ yu o5 iF a1 -\N a6 hE PU VD cd q4 jZ z6 Qc jC bZ Eh wI b1 eD yM eG fO uS iB tD y8 gj zm PK lC QR wu mh qw Sw fi ue j0 XM kZ Y2 ev aJ dF h3 qK qC TX RR rL rC Ut ad sO ro tW -\N a2 pA wE kk Eg q7 lH zj wP 4Z Gi yd yg rc io iX r9 jB xe Rr IZ Jd ij tZ p9 qI l4 Pa G9 S4 Vi tj pb hd f4 qH qK lQ Qs HN ro -\N gN k9 Qz aW wu kI YF e2 pk V8 xk wG 5y t3 sl u4 yA gD hN qL Zr oj iG -\N fR qN qh pH k0 q2 nQ wI zz rh rx ee eF uO d7 iX eL fH qv dm vG PX wi m8 qq Gh uD qy eC fu yW uw sa tB lg US sk wf 5H QF Sh vp wk QK zw QZ wG aq of yS aK aL f5 re f8 pR ku qX wc U1 lR Qs wb F4 Cw K2 Ka Hk mF yr w3 ro ir -\N gr qh ql WH kv E4 r4 oY lu qW PB ET uJ tB tN xs kr DT td t8 e8 UC xn eQ yi af -\N q5 Dt eD y1 am qv UT gx m7 Yt rR yQ yR dY sh MT wD Wm th BV Ym -\N tR qs ca lP Uv q3 wU O5 C1 rx om ee er tA oU i1 jB Rt Ry oS ti fC ss px jn gY Jz vp EA tg ay rq u6 aL de qC zt wn EZ rZ eQ aa rM ox -\N uv ds h9 fY rf jq hE qh H8 d4 wR WF Du ck wI km YP uT rv io g1 rb av y4 tw a0 hY sZ qx gh hA q9 qW zE 1A bz bx bv qw Po EE Wa qi XK rI i6 ic he tM hL sj jb qP wp Jk Qr kF SM l8 bE x3 Qu QL t1 x6 yY fg rJ ua ug qG kV k1 wl v7 xx BJ Ae wc n3 zy TL TZ ZK wQ RE n0 yw oh yr oz eU fm do ux uc -\N hb pA h0 pG q3 mw q6 mG LS LH am sC gz Al j2 wt T9 lM qe J2 rm rE rR rY fL yW uX i0 2E EO bT vh rA yS sm pb oN tx re Ff wn wV Tu rt ox ul ge -\N al fw Zb p6 hi qY AY ou rG Sx AG rZ Uy -\N bX wI kv T5 3W E7 sH hT fF nU la xo qi s3 uy jb 1o vM vi l6 bE X3 ny Pk aw u1 rK fx kM qC be RW Yn eY eO ro -\N dN q3 JF w0 E0 LH rv zv js j2 xG ld HR qe mk s3 DR Kw kC dH h2 qL cG zV n3 Ym yt aa as -\N fT tY qh PI d3 qz IP wU wI q8 WJ A1 Mg mJ uT Wt r3 om uA y3 oU fD dc zW lp xe cn Dh nG qe kP qt mz Xy ef aY oD tZ p8 i0 hu hZ qO kw jW qF kF 3y v3 QJ W0 Ib Ew t4 fg oC e9 ua oV hs u6 f9 h6 vj qV lI wQ IU Yv Xv rC w6 rM r2 -\N d2 d4 AV jC SI RS uT 5Q pa mM s4 e5 tc kM -\N qa Uk uW qh VD d3 q4 xO wO c3 WL wA w7 w9 mC r4 y2 fP r0 tw fr g8 aE qn lp SD bk En vr Gd HU J1 xV XG rW ep Wh ed fu uL eB fL fZ i7 ht jx Ns V3 ll zS j0 OP xf qF l6 l7 SN Wk zw wG ej TI Wb wZ t6 oZ rH rJ uf jE aV dJ h6 qL wl Oi Im v8 zr qV wn Ku wB bJ Ef o4 yL r1 eI sO iF uc -\N k7 qg q5 kx Oz mu WL wS rh b2 rk yh qn qE 6o 1y mj ei pf yE e1 dW hJ hX dO qO Gc Rh v2 zw x5 t1 t3 yU th e9 em au qH f0 qK kM qL kp wc 5p vx bG Ea EV wN wM w2 rX o3 yK ru -\N a2 gr qa az dd gM d1 k9 hR wE bZ lG mG nY wP xD mp YO pJ uY XS uA pt g4 tw eZ jV q9 qn wr nD md nF qq nG Pi bb J2 EU YL ij ty sB oS eh hw i6 hG m9 nJ wa qS W5 qF nZ zH Hw wh bE ZO Fs Rz mE Yk Y3 uB t7 t8 u2 u3 en ha fl yD hf qH qK wc 1x Ze w1 oj eE w3 eY du uz iD ah pI -\N o0 hn qz q5 Du 2B bN A4 Ex rj y1 dj yz y5 ig tF tH js qv 5E gc j3 ls D8 Yw bc Cz Tx Mb Wf ij ty aI aS hi lh l3 qD N1 7O wf wh QH wG ot rA L6 el e5 s8 dG Vm 3f 7o wn YW gJ tb eT -\N fU a5 cp ch Hx Hc RD eH tG G4 Li Sw sf Il EG eb zJ 2O cG eW uc -\N qs Uc RP mL Eb yd if pa c7 OQ vK wu OT Yq RL uZ tV gb zU vM W0 sc TF ud qK wm Ko yy eR tW -\N ak tT ub pA pq iL jq q1 hR k0 Uv ql q3 kk Zs q5 z8 IS lH q8 w7 QW eS ii av yz dl hT tD g6 vS jM zR PX bj No G2 G7 La C7 Xt mz yx tt ym oS to s1 ur ta s3 gv pl qY pc qI sh jv j8 gR l3 BI OA wd Fy v1 S1 ZP HG 5e t1 rP wJ MS wL t5 el Wm at fl e0 sQ h3 dL qZ ka OX TJ qB wb wQ RE xR rX EM eE yu ri do uc a1 rp -\N uv rs un qs um iL Ul q2 jy kl wO A1 rj Tj pK YS r5 yN uO oE y4 oU y5 aR zb g0 qn gx zT lB 2v rm qy nw YZ LM eg oG i7 ht ss qY qI gE wf bW lv lb wh cS wk HF 7G YB zw HK ns oL rH th yO f4 rq dt uj Qo Fd wx nk Rv ka Fl mU RR Q3 w2 oj eE rt w6 ru ul -\N qs hQ qf qN d1 k0 q2 kk O5 NA SI bV mX E9 Tz d8 tq dl eZ qv jf zW ww wu xo b8 W3 I2 te p3 rY iz s1 ut aS s5 hK wo wa l6 wh Bq xk wj wD rA gU yI u1 t0 aK ai tc aX iP uj nf zB wv bD WO Fz QM Qj PE mD eW rV gJ ol yK tn iq yL iS sI ie r2 -\N d3 NI wR WS LI mJ Ds sH sL qx vS Rp ft ik e1 sd aF ho xN wg zH 6b rP eb f3 u5 uf dF pY k1 wz vk vx K2 DG wM eR rV rB -\N gV iZ qz wO O7 K0 oQ tI r9 uS iB ps g0 jM JB TQ ue iv pj sa cR kH t1 ot wC at e9 yS o2 aB qJ wW za rN yi -\N tY qN qh NT ql lA q3 kl wT q5 Mp mG O9 LS LH g2 id eZ sw hU qb cx nU PL kW wt vZ V2 1t wi mh qr eu rm QS xB ei ij uJ yb sN aI iv pj oJ dE hy Gv kA lz Pa nX wg wj kJ CW ZP Wk Eq wJ t5 ns rF e6 rH ev t9 eb iR e0 sm gS gD dS f5 dD de fc f8 x0 lm qZ wz xc wc KX cu wv ks Lv KV wn Pv Ei wm JU wW Yv Zy yt E2 rB w6 oc o6 tQ iG -\N q2 O2 GJ q6 zh mG LI mo vO Ch Tl ax ip hO wt lN Ro Wo qr tr tt oS fo e1 dE hG gb sk W5 Fp KG mm L6 yI u3 fl hs u6 fx re rr dL wb JR EL RW Pm RT To rX w4 gX -\N yV a3 qa Uz k9 q2 O2 bp nY zl Mj vO Tk rx uI g5 pu qx Nr xt ls lM RV QS yv ik fZ tV wp nK Gn QH Qi Yf ek e5 pb au tc aC kC Br qZ 4T qC MX lY wm KB EZ w2 u8 eI o8 -\N rf VO q1 O2 wT q5 Oc 5l A2 eS oE sC cx wq qW kY Em Tx rm p2 qo ft ed uq fs i9 oK lz v3 AU xj v4 wF L3 EG ej ex wl Rv qV AK mI HM CJ yr w4 sI -\N a2 tR qa fY qd qh Oh kk lq Dy bZ Oc JF wA K0 ip pM po qx wq cx we wr bj j5 Yq qe Gg rQ rR oO rU oD ix qT aF or sj qO jn gR sk wd nC Xo xl Wk HH Yf EH EK aq ex ar en tl yS rq pm ug qL qZ wB wN yw og XW aN iF it -\N ak kk wU IG Df w0 rb y4 fr gg i2 qb qW YF J1 ij ue s2 qT aD I5 Yp AI l9 wK kM qL zN Yb eE rB ir tE -\N hb q2 lD wT q7 Qm km wS w7 vI iu yf rc g1 pr oT a9 pN dk iB qx hI qc jd jg hD q0 lo jj cn WB mz eC qp uJ y9 tu yQ aU tp hG pl jx vX j7 wd 3y cA au rq kV qG dH k2 OK cF Qa wv bP Dw IU De K2 RT Hj wM rC eR o3 eY fn sI iF sO -\N hQ q1 qj d3 WS As lD mu rj uT d8 ey oU iB eZ gf y7 qx qn VZ qm vD zW ww D8 xu V1 Av b6 mg Gs bb G8 rm qy yv rR rY oA tB dT jb qA j0 qS l5 nZ QG wj t4 td t6 eb ua s0 pn iI aC x9 qJ k4 wc v9 S7 cJ zy WO 10 HN yq Vz u0 fm uz ux -\N ra pP qd d2 VG WJ Qn rh We hT st jM Bv wu wi qy y9 dE gW wa SB UZ R1 Qu Pz ot td rG gO e8 sn iY zr wc S0 wW Ea PW AC w1 H4 w6 rp -\N fR uv pA jt qk q4 lS wU wI mt xA vU Tk eD rb pe fP am sr hP qv m1 gc En Yw qq qt uD EY eo p3 tJ tu eN ix uX yE tp ic s3 aD hZ qI UF qA kr wh vd Lk YN 5t u1 t0 od rr x9 f0 zJ kN nk WP zs sE rV eI pI -\N yB dC qs PY qk nb jJ ql q5 M3 mG zz E5 i1 zR lC Zx xu vq HR xp BY ei yx Gl qi qp ij eg aI ph aP tN dY zP qP BP kF J5 Ib vd EG el yY td yO iE aG em fc kX zX h8 wv Sv Q1 Te wV vm YQ ol iF a1 -\N ak rd rf qg lO nQ xY z6 q6 mw c1 Cu z8 q7 vW wP A2 zz w8 YO uU ee yN r8 av yz y6 pp UQ dv i3 db jV q9 2l xG Rp IB LJ Sq Tx Tc mj mk qr rW TE p3 ik eg pj e3 i9 im tB tN fM Na j7 lj wa cT Rg v4 He x3 kL bI R7 wJ Y1 L6 wK el 9F t6 gU tj od e9 tz re uh o2 zK ki cF lW jP Sc S6 Qs qB Yn yw mS mD w3 rV as yi ox du yZ ir yC dp hc -\N yV gy iK k5 dB gM Ux qj GC w8 eA g6 dx po jB 5T PV wi RZ qp jv v1 EA en aL iI dt qJ pY w4 iF ux -\N iy pD yg qq p4 in qA Y1 yY TA fb zK S6 lU -\N ql wS rv yj jk kE lM FF LB FX S4 aV UV wl n1 Rv dp -\N qh d3 RS IH rc aQ we 7Y uD t3 h2 zt cu oc -\N fR hn k6 je q3 K4 TM zh lJ Aj LI A4 T7 w7 Kx uT pL rc ih tH hP wq PL ls ma OE lf wu l1 ve Lp qt qy fi ti he oH hi ow tM cU P7 nr va R3 TT wK wC s8 s0 hs aL o2 hk x0 qJ lm v5 wl qZ 7u IW Os lU AH wM Hk E1 o4 rM fQ ro sO -\N gr sA rd um pF ca ga ql qz wT lD z6 vW kv my XT CN Wr eq Tk Rw fe qx qc qR QR RK QA qi eX p3 p5 dQ ff pc sh cY Oq v4 wG s7 yO yA od rq dt UN bw zM DA bG Q5 ru ah -\N iy qd k6 dM Oj qz zd vR w0 r7 d8 et y1 eG yj gz qq p3 il i8 gE wp SX S1 wJ t4 lm jO Qp PW Xc vm sR uz iG -\N qf U8 Iq rg rk g4 iM ih OQ FP A0 IB Tc uJ tN nC kZ Ll u1 UN qV cK Lv vv -\N a4 df um jG z2 lq wR TN xU ID wO Ez rk rz ew d5 tI iX tO r0 sK fA fe fr hP jk wr V1 ms Wu JM RC qt tr eX uK Vr to tZ ut hL sg hB qD XN Rj Jc 6x MO Wz rP ek Y4 oi oo ae sc e9 od pn hg wz jS QV Ln JU rX yG as rN gK o7 sO it -\N dd qs qd PY k9 lw wT DB GK zf nW WH T2 NF zx w8 rj uE w0 Tl ew r6 uI eF g1 oR eJ pN an tq oU fF qv gj jV q0 kQ 2l UO OE kU Wi W1 Tx qe RV 1L Ws eu LV p4 rU fo tZ ph ib fV uu I3 qU oe pc gW wp SX zD kw W6 BO W9 cS CW MY QZ ZF rG fh e8 ay yD fz rw fc ng qZ cG wx Qp OZ qV lY Ha cX AL IU RT mP E1 eE w4 tn ul ru o6 ag aj -\N qa kv E5 bM yj j4 m5 RJ qe rI ht OI qF Qe t6 e5 aw t8 wC dw UN Yb -\N iy jG jJ d4 ju Ol wY bs WK Wq T8 a9 y4 tA dx jp qc q9 su si UT q0 M8 qQ 4a zY qq ZQ Sw Po qe qt La sN p6 ht oJ hy hH qI Gc bn W7 AU Ya kZ na oa oX oV jE fb Or wl qX ze cG WE Fk TZ TV CG Uq w6 -\N dX sA qa qs dB go lO z3 lF Ox jC WJ 93 Tj Tk yf ii eF fO uA sK g5 fS eL oI fr sX fG se q9 xq qW j3 m6 4h qq l2 eu rQ qu qi HS uH p6 ix fX qA I0 wf ke bQ ne wh xl MS uN ex sx yI ua pb s0 rq aK ao fc pR qJ cw WQ VY wv U2 3h wQ RE yw EB gL eU -\N hv gV iL jD go qh d3 wE q4 q5 Ej lK my GV A2 Ds Ex E7 rk yf fq pu fF qx hO js gx j1 qE kW GM Ja nS wy lN D0 Cz Xt te Xu tt sB eM ix ic p0 i8 im ui dI gT ws OS R1 Qy Pz L6 e5 e6 op sb pv sn iI rr v6 qL lE zy Pv mT DA yq ol w6 yZ ag it -\N ds gy dg jF qg uW qj Uv q5 q8 Q8 Q0 Qm E5 rk yd Tz pV if qn Ju cv xy kI qw mj Ls yv rU oF tZ so yR oq qI m9 SC kw qF zH Jx wh kG l0 t1 Pz uN fj os ha sn f3 e0 oM aB cw ct nj zy wn Fl wW vn fn tn ie ov -\N co qh jr jJ cB bi wT q6 RA Qm zx uR r5 an fw tG jM Re j5 vL Em SL xZ qe Wa 45 nq eX yb ed ef ph e4 tB s6 qY lz cU Gm Pd GQ mc cA 85 Yf wF Hu sb eb fk fv dt cq lQ qZ wW wV xR n0 eQ ok eR eT iw r2 o7 fE it -\N ra dX Og WD wT O9 i4 It PK qo ic dT hJ jl oq sf lz wd cA Hi fg f5 ap x9 gq nd IY Q6 eP -\N o9 gB a5 z5 q6 wU w0 Tl r9 dj if tS ig It zQ lL qw qy ep ed rY p5 ut hH dR i0 hL qP qA zS wd Ya ot Xk s7 e9 oM iO dL ki k2 wv Q1 5g eR rB rM -\N qs w0 om eD tK ta th gF iI aV og 6O eE o8 -\N pO tY rf qf hE Qc Hz bV c5 mi rh ew tU eF sH iX r0 d0 pB tq fw ig g8 fH i2 UW hF qW qR SF cn wi FH qt HP nq yv fy tJ oD uX ut fB hu tN qT OI qS OA xM Dm Fa nM QX yY oo ec ev oX sb yA rK yS ud jY dZ zV qC zB QB 17 TB LT yt u9 w4 rB sT eT ry yL o5 di ux -\N gB gt az Uk gM qh d3 bt qz WD lD O3 bL cM q7 ck K7 We b2 yd Ua ew Tl Rq yg uS tq js fK jB gz jN jg qQ IN qr rQ qy 3H C0 qp p3 yn ef sB ym jl sf sh hV qD P4 FJ OD Ix kZ ni wJ wZ tg t0 tj e0 sm oM kX ku cw Nb zC Aw cy qV bq kg wQ Pn ZZ wV CD wN yr sE o6 pU eO gC -\N gy rf qf k6 qh qj cd q3 kk cj FW B4 FR mJ w7 bM Wr ya Z7 Wt w0 r8 ip tI is pN am y5 qb hS jf qW UU wr nP QT wi 1t bx qq qw AW ER Cv qy rW eo oA iz fp iv qI jm nK kr QF XM EO nr W0 QJ bI t3 uV wK ek Wn ex e5 rF rH gA iT f5 pm hM f8 qJ GY jP lE wc qC lT S9 zu Lb Q1 JU w1 Uw w3 oj tn tQ ir r2 tE -\N ak gN pw a5 qh k9 qk nb 2L qz wR kv mt Gt w7 zx ii oE Ug iX sZ qx qc aR sr zb su vG qE nP YG qt YJ sV uK pd uq pf oF eh jb sk gY ws ke KD bE OG kH x6 mE wZ e6 yO iW aH rw pm rr qG pT lm qL qZ wz Qs lY wb wn Q3 RY rX gJ iA o5 ge -\N gy qM d3 q3 IA c1 Ta Ex E5 E8 eG sy cl jf qE NJ nH m9 qA W6 ek iW kV qG aB n4 w5 iq do -\N uv gV qa un az jD qM Eg Iw nR q8 zj nY c5 vU rl rx yN et ia uA is oT pt hU iM gj qv VV xe xu 1G Wo vt qt St qy rW qi Wh ft es uK hw to p8 fN f1 hp qU sk P2 l4 zF qF G0 Fi l7 bE ky Iv mn Xp nN DT 6b rO Kw uV rA TP e6 sv s8 sn tl fz iY qH hz VE v8 h8 TH wc WY QB xm S9 Hs wQ zs yq Tu EN Zt w4 dp yC -\N sA ak gi hW qM gp PP qz Fm ID lH 6w 9h XR w7 Ui oW rb oE ia uS fq g5 y5 ig oI y6 iM gk zE qE GN 3O Ye xZ Jh qe Db qi p1 ep rE oP TE y9 oS pj e3 p0 zP qA Ih l4 cU zG wg SN Rh Lf FZ Ic KH ni wH vh Wx th aG u3 f6 uj jY k3 2A wc KV lU WO HB eQ w1 rB XW yo eI o7 gX -\N hW WD r0 g4 sZ b7 Pi sN tC in Qt ZS rG eU -\N iy hv hb hQ qf z3 q2 xY IA TM zf Jw Wq A3 rk w0 d6 eG et is id po tG gh Ob jj wr nP No wt Ja wy xL l2 Yr BT bb Tc Cx qr rn qt LC rW Sy eX y0 rU oD to tZ oG yE hr pj dE tV e4 qT aD OO qA jQ FJ l7 Fo wh nt Pl rO wL Vp yY tf Va e6 fg th ar s7 os at s8 re dF pE hj f0 qX qC X7 lU nc zo TX bF wW PQ CG w1 rX iD pU it fE -\N qf fI lD 4o Ge Da T5 zz mo zx vI Ui w9 pJ rl rz r4 uY r5 sF av oT fq tw sC zv g9 qv i4 UT Iy m1 wy xo b0 uD Cb qy rQ uG Wg sN fo ix uC aA i9 ss sd dI sh j8 qP xa EP W0 7H wL t7 iW tj yA hs e0 fz hd u6 hh dr dH uk qJ qK wx OL xb qV wb S8 15 WY zM JR nx IT Eo Fx wW Yv Zy To eE yu yi iq eY iw rM uz yZ ob -\N pO ra iK qd qf je jr lP wR ji nE wU 2B nT wA E7 rx XO ia yl tA ig fF hP gk jf q9 vD si gc qE RK wu BY YG rQ sB oS fu eh eM uX ic aO pj hy im dU qY cR 2E l5 Qw v1 Lf mv wk Rx DY rP rA rG gI eb hs au ap bO Oa Sn zi F6 H1 Zt eY yZ do -\N lJ vU y2 if qR wr ta so kG 3K oL u1 f5 -\N yB cV mq lF zz uE uI dx qe Tv qu eX tZ hH tB dY dS WI rB -\N hb gt qa h9 rf qf qg k9 q1 lO q3 ql z8 GL zg q8 1T wO vR rg Ez wS mo w9 YO r3 yd E9 eA sF a0 iM tG y8 aR qb nI wr qR WV m4 IX D9 NZ Yq FA If Yr BT qr mz qi ea rR XX aT ic pk qI zA hV kq W7 cO xj wD x4 ZS wH Y3 rF ec u2 e9 aH s0 uh iO UN h8 IQ zB bS NR be zo Fz vb wM PR yw mD rC Ur eR iA yL ox eI ux eO tW o8 -\N qs rd RH yf pX oW d8 tq ig ih cl QR Yw qq in Qy Wc ek rH yA qG cD X9 QM LQ To o3 ul a1 -\N a2 cp As GK kc 4u zj Z2 T5 zz rb eH sH sX fG fH g9 hP vD gx OQ cv Pe WV b8 qe Cc nw tr il tL e3 qU l4 MT wk wH aq TD e9 gF lm qZ Bu JQ mY WP vb DG Y0 ye YQ w6 r1 -\N iJ az qN pH Qv bV bf mZ iu is y8 aR fH q9 hD qQ Ji SF ld UP qo p2 aT sp in qI nK l5 e0 rw Px 5o eW oc tE -\N qd jr PA q5 w9 HW hU y8 dn qn zW wr ma ei XL dQ i7 i9 vB SX wf wH na wL uM e7 s0 h2 nh nk Fj Yl wn IU u7 as ad eY sO uc -\N lA uP iC g5 aY Ic x8 u2 ar eb wB yr aj -\N pO da rd un qg uW lq M2 4r WG q8 z9 T3 zc d9 aE st q0 li qW wt kR qu rY eN sM qF kF kH ny yT gI rH u5 em tc kV h8 qX lR JQ Ef -\N a2 dh qh q1 H8 qz z6 kx z8 bV 3Q Df pK Tl d8 tq tF g8 zb qW 5P Zm qe Cv yb eC uZ iv e2 gQ wp UH kq ws lc wk x3 t8 rJ fc iO jE dK lR lT wv WT bw be Eo Q4 ye yy rV ok yo yp ir iG -\N rs iJ tY pS Ul wR Bh kb RS Z4 Z8 er pX uO uP y1 rb fO jo gg dv PH q0 jN xw ww D8 Rp YD YF Tx b0 oP yn oF jl tM px fM jc zF QD Pk wH rP uV TP t9 iR yF ug qG v5 ku qZ Fd k4 cu Mw zN IU bG LQ LY rV sU -\N iK dM cM oR tw pu lp eh qD kK J0 em ng Tw -\N ra ds qk cg q7 K6 4p T6 YU Lq Go yd eq r8 fw am dm xy cm V1 Cz eo qi ij yn eg hq tC sj qA I0 OA l6 P6 wj vd wF mR yT ex e6 yO t9 ev s8 en rr bq kg HB Lm RE bJ mS w1 eT du -\N o9 gy bL WZ T8 HQ iu iX av y5 y8 jN j1 nP xt T9 vw qq 43 xV 9W Yi ft es hy OP Lg vs HG wD EF Wx ou oX sW dr ze xR sT fm ah -\N a3 wR Fb jC c2 w8 rx fe q9 hD xq qQ wi te y9 e1 qT qI qS nL cA BH u2 mD tv hx -\N ra jH q3 Aa T3 1O eq LH rv fO uS pt dj pM pi qn zR bj xJ cm IX A0 Ra HI eu nw yc p3 rU rI ue e2 jl hi wo G9 xN QH wL wX gO yP rr dJ nd cH U3 Fj bD JY vn w1 iA ox tm uz -\N Ma y5 bl QI G7 rI fL aP 7A yO ko rp -\N um dh pG Wq r5 sF ia tA an hS Ne q9 wt SH RK Yi ym oF tB oq dO hV wj Ic oi sc pE Sc wQ wB wM tQ -\N hQ qM GG q4 xU K4 K7 Uo Wt Kb et fO ey aW g0 xi Am IN qy eo qi eB aY ue OG nt kL wX s9 dF qG f9 v6 Rv Sv Pc TL mY bJ wB eQ H4 o3 ri -\N tT uQ qh nb qz wT jX ya on om io oW hA QP e2 fd e4 hp hX P2 vM xg xN rA L8 iU yF jR qH k4 1l Oa TK zp yw rZ sY ul yX eO eP -\N iJ yB qs fI Ul qk by ql jL wR bi q5 bL TM q7 xP K7 vY Gi Tj rl rx yf yM tU er r8 pe ip eJ y4 fD jN gx zT vJ xt xH RJ kT cm Ri nH ZQ Pp eu rW to pg e1 ue dW e2 so tB gm qI jb nK gY Pa v1 xj FL kH 3K kL ED Wx Wc ek yY ez wC iQ yO u4 iT tz aK hN f8 h2 hl UV wz h8 GI nk cH zt WT bw KN yq E1 tv Zp ag it -\N qs rf jq go qh a8 jJ xT le wU QQ yd d6 d0 fF qc su c7 lC Wp ty y0 tu ti pf ta aA UG vB Rf vi Rx no uN yU e5 7r up rJ aG ha hs fc wz bO qV bP TV Ki eR -\N yB qa rd lO Ok q6 O6 ba r6 oW oR yl am aQ gd dc hO cx c0 Wu G4 IB C5 ep rE qo ed yW iv ta hy jc PN xs Oq xN BO zG Ps kr Iz Yp wh wj xl Xo zq mE na ek wL wX wC rG uo iR tk aJ dA rw hM iO uj fb jT qJ dK nh zX jP qX wc zr zy zu nc xE wW wV vn H2 Q6 EN eW ad yL af eO iF r2 -\N yB o0 dN z1 q1 SW qk PO xT wR lS z8 Ox wU JD RO q8 lH mH wA rg eA C3 pZ tU g2 is a9 pN tw po qc SA jj vH Ax xH kT wy JV mg nH kP b9 qi oD ht e4 uu Ij qF Sf nC wk AP wD QZ rD yI s7 tk pb iT f7 o2 f9 kV qH h4 ln wz GI Qd zN xm Sn 39 Yn rZ u7 yr yJ iS ie ag ir tW -\N pO dX uv pq jD dM d2 hR cs gs d3 q4 wR NP AB Di mH vT w7 w0 on Tl ia tA aQ dz y7 i1 qc PG q0 wq j2 c7 la cb IL wr lV nA Ru 4g vZ nF bc SL qq QP qt uD rQ Wg eX uw he tZ yE p9 ui OU vu AT Ix W0 vf bI ED Yh wH rA Y6 wC u1 t8 fj oV iY tz kX h1 hj jY qJ h6 ng jO wz cJ IE mT RQ Te n9 mP mA Q5 8W rB o7 sP ob -\N pO ra dg ca qj q2 IS kn RD wS Lq tU yM yl y5 tG pp qW we cn A7 1t Jd m7 Wo Yr SZ QA HP ei qy eC p4 hw p7 to aU iv ht qT qY qO l4 lz xM wD Yf wG ez s7 en f3 tx yF rr f8 cw jI QV Yz RY eW w2 oj w4 w5 sT rN oz ri o6 dp aj -\N gM jG ju q5 NP lF q7 xO 1Y Qn K0 jo pp qx tH q9 4f OR Ro Pu bv eu nw uq aO dY jb j9 gR Rd nZ wj wJ R9 CO TA rK od dD gG hM dF pR kM ng OJ qC Sb Qd wb TZ Cq EX wB vb Ty eQ tv iw -\N fU uQ co qk jL cg lD lG wO vR GC bd rj r3 yd rz iu ew d6 io tO sH y7 jp db dn qn qm si xG qR ls Jo Lr wy RK WN m7 QU bb es oP qp rU eN ta e3 in hy dY hL vC Gc gT jW ke 2T wh Rk Lj HG oy e6 yO ev em fz rw pQ re dG qK ku Oi qZ k4 qV lI RQ n8 EC 4D Yb wB E1 iw iD o6 ir do ux pI eP -\N a2 wU JD eF dc mN 5E qp pl xd aG ay -\N yV o9 al a5 uQ qg jw PI z2 jt cd q5 3m zl Ez vU RG JL rz yf iX sJ fP d0 tq fF hA hS zW Om nI M0 xG c8 A7 kI qw Cc ei XG J3 tt tu il p6 ix tp tX ib sp hG p0 fC pj Su qU jv sj lk qP ws qS Gm 1X mx lv wj Qu L1 DT wH Wv uN aq fg rG e6 uo ar iE up iT sW tx f6 o2 h3 qC Qa Ho vj U3 kd zy n6 mY wW vc LR EM w2 sE rt o4 yC a1 tE -\N qs dV pA tY iZ uW qh jJ z3 TN jC Eg E4 QQ w7 uT r3 uU Kb uP g1 fO iV if fD gd sC qm qE xG Ia WB HE kY HU Tv rW qu rR es p3 ue s2 aS i0 dT qT hZ jm j0 gY cI Fi Hw nV EA KK vf Rx 68 TI rP wL oi Vp at oM iO uk pT qH qJ dL cF lR cX wQ Ku Ki w2 yH af ul sP yC it -\N ub yB dC tY gM dM go nv wE ql by lA O1 ju O3 jX Fm Aj wA rg E4 vI A6 r4 XO Tz oE ip pV dk tq a0 tF fG tG i4 PZ SD Ry kY mg HY G7 eu qy Yi rW qp eg yW hw sM uC i7 dW fX s3 sf zO m9 xs vN Rf cI nZ kr Qt 9Y Pj Lk Ee Pz EF rK e0 fx uf aZ fc qG jR Oy lQ cG Qp UM AD wc zN bw n6 My xR mP Tu EN o3 iq ir ro -\N da a3 d1 jr DZ ca ql NU q3 cf O6 nR mt lK YR RS LP w7 A5 pJ YS yM r8 ey tO fS dz iM ih sw qx qv zn gl j1 xe lC Zc vw 6a mh b9 qt rm rE oO qp p4 tK ix p7 oG tZ yR sp aA hK Ih lx qD mx 4n kK vf el oo TD ae yO fj uf pR hl qJ qK WR qC qV kf Yz mY wQ HN zs Dr eE u8 rV eT ru ie ag tW -\N gt pH z0 zl mu uI av zm Om UI vH qR HE qr es fL ws W6 nC rA rK kp OL wM yu it -\N dd df jq jD Ux ql El 3R ya uU iu ee eH g3 sJ uS iB pp qc jV hD bh zT UO D8 b3 xu bc rQ te uH eX tt eB il qU pc gE sj qP Ih xf 3r GR Yh QX TU wL Wn sz up ay iT aB jT qZ v7 wn lI za 6O w3 fn yK eU ie gZ ro -\N yV o9 qf Eg Eh mH JH rh r3 rv iX y3 a0 sr qc qQ qR wr QE bx kI m8 mk qi LM uK eB aI ur e2 xd nC cA EO mb ED uV rS up yA of hN lW wz qZ Et Qh wM Zr rC o3 r2 -\N sS qg qj pH qk q2 cs z4 bi Qc cj q8 Qn w7 rj ys eA r4 uY om rc ii fP sJ eJ yz eL qx qv zn gk q9 hS m2 Ii D7 NK c8 j4 qq Dl Gg Pp EI qo YC oD fo eh fp ta hy oK tV uu US dP qF SB zG KS Sg N3 wh x2 nr cS wk KH Wk wF Ew 7H 7K oy t6 gI rG yP s9 yA e9 pb tc dt dH hk h2 pT qH h7 wz n1 qV kd Pm cC xR Kp yK tm ge -\N gr qa fT tT gN qs pw PU ca pH lS cg cN zf bZ q7 z0 c3 Qn GV w7 RG uT E8 ii er ip sG y3 oY eK hT gd qx g0 qv db su jN qQ lZ UU Jo Ru An wi Kn Sq nH qr qy yx eo qi XZ y9 rU pd aU p7 dQ he ut oK fd jz ui hC j9 l3 hB xd jQ gY KH wF Xs sl rS aq ez Y4 TS uM yI e0 gH dK pY v5 qK qL ko JQ wc nk v0 wb QV br IU wM 6P sR gK yp pU -\N o0 pA pF z3 jt jy z7 cM nE w8 yz fD fG zn qQ lL vG wr WB Ia xX YJ ty eh e1 so ts tC s4 i0 tN wo wp wa OP va wk X3 vg QX rS sn au f3 tz sQ hN rr o2 fv UN k2 vj Ey DJ -\N iy ra iJ tY a4 un rf qg dM jr kj Uv wE cV GK wY z8 Oc wP mo JL mZ Ev Ch rv tU ax y2 g3 oY y6 iM UQ qv hP qb hD Iy lp NK W2 bb HO ep tr oS eN sM p8 p9 hy ss ui gm qI OO vN AE qD W6 Ps Dn wD wG rO mR yT oL oZ rG s7 u5 tl yD rr aX f0 cq ku qX ze n4 wn Kt CA JY bG Yc zs yw rZ w1 eU rM r1 -\N hv fU ca Q8 mt LA r3 pL yh tO sy YH tV x4 tg yP oV wn Ze sP -\N o9 qa az gM qd pw hQ pD ga qj cd q3 jK PD Du c2 zk xF T8 eq om eS rc uA y3 pu ig qx se qv db st qn Ii lX QE wt xK NX kU BR qe qr qt rm eu XF xB RN qu qi ep qo rR eX XK p5 ym fi uq to uX ix aI hJ gn zI Oq qF kD wf xN kr W8 Rl kK mQ rP rF u1 s7 oa fh e7 yP e0 pR qL Sx cK AG kg Kt mP EB rL EM eE w6 du rM yZ iF eP -\N qs PI AM 6A uT r4 ii sD uA iB y6 pa kT PB WM qq Dz qt qp y0 he p8 ue tB qU or qO wh 40 8j t4 sl rF iU gH hh qC IQ bF rL wM mF oh eW iS dp -\N da pS a7 jr z4 q3 bu xT IP jX q6 NP z7 bp lG bZ YE wO IG bB Ww RF om uU eF r8 ey pt tA pN y7 gg tH dn PG qb Ri qq 42 qw ZW b9 b0 xB qt qy YL Wh XK ft aT yW i7 sp dE pz fN qY Si m0 Ik wf Sg CQ QL HK Er EG Lc ek na wC iW iR rK ua e0 aK iU sW ap uj aV aB hl UV zC Qa wc JW vj QV vk Ay kg xW ON RW 1b wN rL EB vm eQ H4 yt oz eU uz -\N a2 qa rd cp qh Ub VG WS U0 4G bp Da YO Ev Kz eq uU ee eF yk pr sJ sK fe oI lt UY j2 GN Io vK nS 27 lN Wu ve Yr l2 qu qi rY il uL tJ eg uX i5 yR tX ph oJ gQ or zP wa qS gY Iz V0 Qt wj Ic cA Lh YB np ej sl td L8 yI iW s8 e8 yS yD sQ aL dt pT TG Te Yb eU tQ r1 ir fE -\N tR h9 go qj B1 wU q7 zh El Tg mB YS eD ii er r8 XS pe r0 sw db Ov M7 D3 Re nO Nu zR Pq Ji wr lC OR qw EE Yy qr rn rm rE qi te ea qo yb yn y0 uZ uq iz tL yR i0 fM wp qS qD He Wk kL Ew AS HL ez oo oX iE s0 f4 dL WQ wl WW lR qC qV vk mT mY KN Ep EM yt sY aM sO rp sP -\N ak fT qg Bg ji q6 Bk xI Tf mo uR pJ yk uA qv wq gc qE KE ef eB tK uq i6 oH iv gb qS Rx el yO rr pE wz wx Ho xQ TC mO yK du r1 tQ oc hc tE -\N ra ub qj jH jt DX ql q6 Da Tf r3 ew iu sG tP yl eL gc 6N tt rY pd yE ff lz kt yP fl yF dL rN -\N o9 hb h9 qd dh qg q1 qj jy SE q5 wT nR Qv Ge c5 El 6y Uo rv ax pe et r0 fe y6 dx qx hA qQ lo we zY V1 wy Dl vr Wa qr rm qi qp yn tZ pg ph dE p0 dO qP wp wf bW xh ky xz wH HL TO EK rD sv rJ rq re h1 qG qH KL F1 zM 18 EZ xE vm EN 5j o3 rN fW fE it -\N dB c2 bB O0 w8 Kl Kc y4 qx zm PK cW Id ve mh Lp rQ jb FL x1 Qi wD Lx f3 cy bq DD ye fn iG diff --git a/contrib/tsearch/deflex.h b/contrib/tsearch/deflex.h deleted file mode 100644 index f9d6847167..0000000000 --- a/contrib/tsearch/deflex.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __DEFLEX_H__ -#define __DEFLEX_H__ - -/* rememder !!!! */ -#define LASTNUM 19 - -#define LATWORD 1 -#define NONLATINWORD 2 -#define UWORD 3 -#define EMAIL 4 -#define FURL 5 -#define HOST 6 -#define FLOAT 7 -#define FINT 8 -#define PARTWORD 9 -#define NONLATINPARTWORD 10 -#define LATPARTWORD 11 -#define SPACE 12 -#define SYMTAG 13 -#define HTTP 14 -#define DEFISWORD 15 -#define DEFISLATWORD 16 -#define DEFISNONLATINWORD 17 -#define URI 18 -#define FILEPATH 19 - -extern const char *descr[]; - -#endif diff --git a/contrib/tsearch/dict.h b/contrib/tsearch/dict.h deleted file mode 100644 index cc0b1a396b..0000000000 --- a/contrib/tsearch/dict.h +++ /dev/null @@ -1,10 +0,0 @@ -#define TABLE_DICT_START ,{ -#define TABLE_DICT_END } - -#include "dict/porter_english.dct" -#ifdef USE_LOCALE -#include "dict/russian_stemming.dct" -#endif - -#undef TABLE_DICT_START -#undef TABLE_DICT_END diff --git a/contrib/tsearch/dict/porter_english.dct b/contrib/tsearch/dict/porter_english.dct deleted file mode 100644 index 5158a9b876..0000000000 --- a/contrib/tsearch/dict/porter_english.dct +++ /dev/null @@ -1,1285 +0,0 @@ -/* - * ----START-LICENCE---- - * Copyright 1999,2000 BrightStation PLC - * - * 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 - * -----END-LICENCE----- - */ -/* Version 1: see http://open.muscat.com/ for further information */ - - -#ifdef DICT_BODY -#include /* tolower */ - -static void * setup_english_stemmer(); - -static const char * english_stem(void * z, const char * q, int i0, int i1); - -static void closedown_english_stemmer(void * z); - - -/* To set up the english stemming process: - - void * z = setup_stemmer(); - - to use it: - - char * p = stem(z, q, i0, i1); - - The word to be stemmed is in byte address q offsets i0 to i1 - inclusive (i.e. from q[i0] to q[i1]). The stemmed result is the - C string at address p. - - To close down the stemming process: - - closedown_stemmer(z); - -*/ - -/* The English stemming algorithm is essentially the Porter stemming - * algorithm, and has been coded up by its author. It follows the algorithm - * presented in - * - * Porter, 1980, An algorithm for suffix stripping, Program, Vol. 14, - * no. 3, pp 130-137, - * - * only differing from it at the points marked -DEPARTURE- and -NEW- - * below. - * - * For a more faithful version of the Porter algorithm, see - * - * http://www.muscat.com/~martin/stem.html - * - */ - -/* Later additions: - - June 2000 - - The 'l' of the 'logi' -> 'log' rule is put with the stem, so that - short stems like 'geo' 'theo' etc work like 'archaeo' 'philo' etc. - - This follows a suggestion of Barry Wilkins, reasearch student at - Birmingham. - - - February 2000 - - the cvc test for not dropping final -e now looks after vc at the - beginning of a word, so are, eve, ice, ore, use keep final -e. In this - test c is any consonant, including w, x and y. This extension was - suggested by Chris Emerson. - - -fully -> -ful treated like -fulness -> -ful, and - -tionally -> -tion treated like -tional -> -tion - - both in Step 2. These were suggested by Hiranmay Ghosh, of New Delhi. - - Invariants proceed, succeed, exceed. Also suggested by Hiranmay Ghosh. - -*/ - -#include -#include -#include - -struct pool { - - int size; - struct pool_entry * entries; - -}; - -/* This is used as a library to resolve exceptions in the various - stemming algorithms. Typical use is, - - struct pool * p = create_pool(t); - char * s_translated = search_pool(p, strlen(s), s); - ... - free_pool(p); - - t is an array of strings, e.g. - - static char * t[] = { - - "sky", "sky/skies/", - "die", "dying/", - "lie", "lying/", - "tie", "tying/", - .... - 0, 0 - - }; - - if s is "sky", "skies", "dying" etc., translated_s is becomes "sky", - "sky", "die" etc. - - The code includes a sort/merge capability which may be turned into - (or replaced by) something more general later on. - -*/ - -/* merge(n, p, q, r, l, k, f) repeatedly merges n-byte sequences of items of - size k from addresses p and q into r. f is the comparison routine and - l is the limit point for q. -*/ - -static void merge(int n, char * p, char * q, char * r, char * l, int k, - int (*f)(char *, char *)) -{ char * q0 = q; - if (q0 > l) { memmove(r, p, l-p); return; } - while (p < q0) - { char * pl = n+p; - char * ql = n+q; - if (ql > l) ql = l; - while(true) - { if (p >= pl) { memmove(r, q, ql-q); r += ql-q; q = ql; break; } - if (q >= ql) { memmove(r, p, pl-p); r += pl-p; p = pl; break; } - if (f(p, q)) { memmove(r, p, k); p += k; } - else { memmove(r, q, k); q += k; } - r += k; - } - } - memmove(r, q, l-q); -} - -/* In sort(p, c, k, f), p+c is a byte address at which begin a sequence of - items of size k to be sorted. p+l is the address of the byte after the - last of these items, so l - c is divisible by k. f is a comparison function - for a pair of these items: f(p+i, q+j) is true if the item at p+i is before - the item at q+j, false if it is equal to or after it. -*/ - -static void sort(char * p, int c, int l, int k, - int (*f)(char *, char *)) -{ - char * q = malloc(l-c); /* temporary work space */ - int j = k; - int w = l-c; - while (j < w) - { int cycle; - for (cycle = 1; cycle <= 2; cycle++) - { int h = (w+j-1) / j / 2 * j; /* half way */ - if (cycle == 1) merge(j, p+c, p+c+h, q, p+l, k, f); - else merge(j, q, q+h, p+c, q+w, k, f); - j *= 2; - } - } - free(q); -} - -struct pool_entry { - - const char * translation; - const char * pointer; - int length; - -}; - -static void print_entry(struct pool_entry * p) - { - { int j; for (j=0;jlength;j++) fprintf(stderr, "%c", (p->pointer)[j]); } - fprintf(stderr, " --> %s\n", p->translation); - } - -/* - debugging aid - static void print_pool(struct pool * p) - { int i; - int size = p->size; - struct pool_entry * q = p->entries; - fprintf(stderr, "\nPool:\n"); - for (i = 0; i < size; i++) print_entry(q+i); - } -*/ - -/* compare(p, q) is our comparison function, used for f above -*/ - -static int compare(char * char_p, char * char_q) -{ struct pool_entry * p = (struct pool_entry *) char_p; - struct pool_entry * q = (struct pool_entry *) char_q; - if (p->length == q->length) return memcmp(p->pointer, q->pointer, p->length) < 0; - return p->length < q->length; -} - -static int count_slashes(const char * s[]) -{ int slash_count = 0; - int i; - for (i = 1; s[i] != 0; i += 2) - { const char * p = s[i]; - int j = 0; - while (p[j] != 0) if (p[j++] == '/') slash_count++; - } - return slash_count; -} - -static struct pool * create_pool(const char * s[]) -{ int size = count_slashes(s); - struct pool_entry * z = (struct pool_entry *) malloc(size * sizeof(struct pool_entry)); - struct pool_entry * q = z; - int i; - for (i = 1; s[i] != 0; i += 2) - { const char * p = s[i]; - int j = 0; - int j0 = 0; - while(true) - { if (p[j] == 0) - { if (j0 != j) { fprintf(stderr, "%s lacks final '/'\n", p); exit(1); } - break; - } - if (p[j] == '/') - { - q->translation = s[i-1]; - q->pointer = p+j0; q->length = j-j0; - q++; - j0 = j+1; - } - j++; - } - } - sort((char *) z, 0, size * sizeof(struct pool_entry), sizeof(struct pool_entry), compare); - - /* now validate the contents */ - - for (i = 1; i < size; i++) - { struct pool_entry * p = z+i; - struct pool_entry * q = z+i-1; - if (p->length == q->length && memcmp(p->pointer, q->pointer, p->length) == 0) - { fprintf(stderr, "warning: "); print_entry(p); - fprintf(stderr, " and "); print_entry(q); - } - } - - { struct pool * p = (struct pool *) malloc(sizeof(struct pool)); - p->entries = z; - p->size = size; - return p; - } -} - -static int compare_to_pool(int length, const char * s, int length_p, const char * s_p) -{ if (length != length_p) return length-length_p; - return memcmp(s, s_p, length); -} - -static const char * search_pool(struct pool * p, int length, char * s) -{ int i = 0; - int j = p->size; - struct pool_entry * q = p->entries; - if (j == 0) return 0; /* empty pool */ - if (compare_to_pool(length, s, q->length, q->pointer) < 0) return 0; - while(true) - { - int h = (i+j)/2; - int diff = compare_to_pool(length, s, (q+h)->length, (q+h)->pointer); - if (diff == 0) return (q+h)->translation; - if (j-i <= 1) return 0; - if (diff < 0) j = h; else i = h; - } -} - -static void free_pool(struct pool * p) -{ free(p->entries); - free(p); -} - -struct english_stemmer -{ - char * p; - int p_size; - int k; - int j; - struct pool * irregulars; -}; - -/* The main part of the stemming algorithm starts here. z->p is a buffer - holding a word to be stemmed. The letters are in z->p[0], z->p[1] ... - ending at z->p[z->k]. z->k is readjusted downwards as the stemming - progresses. Zero termination is not in fact used in the algorithm. - - Note that only lower case sequences are stemmed. Forcing to lower case - should be done before english_stem(...) is called. - - We will write p, k etc in place of z->p, z->k in the comments. -*/ - -/* cons(z, i) is true <=> p[i] is a consonant. -*/ - -static int cons(struct english_stemmer * z, int i) -{ switch (z->p[i]) - { case 'a': case 'e': case 'i': case 'o': case 'u': - return false; - case 'y': - return (i==0) ? true : !cons(z, i - 1); - default: return true; - } -} - -/* m(z) measures the number of consonant sequences between 0 and j. if c is - a consonant sequence and v a vowel sequence, and <..> indicates arbitrary - presence, - - gives 0 - vc gives 1 - vcvc gives 2 - vcvcvc gives 3 - .... -*/ - -static int m(struct english_stemmer * z) -{ int n = 0; - int i = 0; - while(true) - { if (i > z->j) return n; - if (! cons(z, i)) break; i++; - } - i++; - while(true) - { while(true) - { if (i > z->j) return n; - if (cons(z, i)) break; - i++; - } - i++; - n++; - while(true) - { if (i > z->j) return n; - if (! cons(z, i)) break; - i++; - } - i++; - } -} - -/* vowelinstem(z) is true p[0], ... p[j] contains a vowel -*/ - -static int vowelinstem(struct english_stemmer * z) -{ int i; - for (i = 0; i <= z->j; i++) if (! cons(z, i)) return true; - return false; -} - -/* doublec(z, i) is true <=> p[i], p[i - 1] contain a double consonant. -*/ - -static int doublec(struct english_stemmer * z, int i) -{ if (i < 1) return false; - if (z->p[i] != z->p[i - 1]) return false; - return cons(z, i); -} - -/* cvc(z, i) is true <=> - - a) ( -NEW- ) i == 1, and p[0] p[1] is vowel consonant, or - - b) p[i - 2], p[i - 1], p[i] has the form consonant - - vowel - consonant and also if the second c is not w, x or y. this is used - when trying to restore an e at the end of a short word. e.g. - - cav(e), lov(e), hop(e), crim(e), but - snow, box, tray. - -*/ - -static int cvc(struct english_stemmer * z, int i) -{ - if (i == 0) return false; /* i == 0 never happens perhaps */ - - if (i == 1) return !cons(z, 0) && cons(z, 1); - - if (!cons(z, i) || cons(z, i - 1) || !cons(z, i - 2)) return false; - { int ch = z->p[i]; - if (ch == 'w' || ch == 'x' || ch == 'y') return false; - } - return true; -} - -/* ends(z, s, length) is true <=> p[0], ... p[k] ends with the string s. -*/ - -static int ends(struct english_stemmer * z, const char * s, int length) -{ - if (length > z->k + 1) return false; - if (memcmp(z->p + z->k - length + 1, s, length) != 0) return false; - z->j = z->k - length; - return true; -} - -/* setto(z, s, length) sets p[j + 1] ... to the characters in the string s, - readjusting k. -*/ - -static void setto(struct english_stemmer * z, const char * s, int length) -{ - memmove(z->p + z->j + 1, s, length); - z->k = z->j + length; -} - -/* r(z, s, length) is used further down. */ - -static void r(struct english_stemmer * z, const char * s, int length) -{ - if (m(z) > 0) setto(z, s, length); -} - -/* step_1ab(z) gets rid of plurals and -ed or -ing. e.g. - - caresses -> caress - ponies -> poni - sties -> sti - tie -> tie (-NEW-: see below) - caress -> caress - cats -> cat - - feed -> feed - agreed -> agree - disabled -> disable - - matting -> mat - mating -> mate - meeting -> meet - milling -> mill - messing -> mess - - meetings -> meet - -*/ - -static void step_1ab(struct english_stemmer * z) -{ if (z->p[z->k] == 's') - { if (ends(z, "sses", 4)) z->k -= 2; else - if (ends(z, "ies", 3)) - if (z->j == 0) z->k--; else z->k -= 2; - - /* this line extends the original algorithm, so that 'flies'->'fli' but - 'dies'->'die' etc */ - - else - if (z->p[z->k - 1] != 's') z->k--; - } - - if (ends(z, "ied", 3)) { if (z->j == 0) z->k--; else z->k -= 2; } else - - /* this line extends the original algorithm, so that 'spied'->'spi' but - 'died'->'die' etc */ - - if (ends(z, "eed", 3)) { if (m(z) > 0) z->k--; } else - if ((ends(z, "ed", 2) || ends(z, "ing", 3)) && vowelinstem(z)) - { z->k = z->j; - if (ends(z, "at", 2)) setto(z, "ate", 3); else - if (ends(z, "bl", 2)) setto(z, "ble", 3); else - if (ends(z, "iz", 2)) setto(z, "ize", 3); else - if (doublec(z, z->k)) - { z->k--; - { int ch = z->p[z->k]; - if (ch == 'l' || ch == 's' || ch == 'z') z->k++; - } - } - else if (m(z) == 1 && cvc(z, z->k)) setto(z, "e", 1); - } -} - -/* step_1c(z) turns terminal y to i when there is another vowel in the stem. - - -NEW-: This has been modified from the original Porter algorithm so that y->i - is only done when y is preceded by a consonant, but not if the stem - is only a single consonant, i.e. - - (*c and not c) Y -> I - - So 'happy' -> 'happi', but - 'enjoy' -> 'enjoy' etc - - This is a much better rule. Formerly 'enjoy'->'enjoi' and 'enjoyment'-> - 'enjoy'. Step 1c is perhaps done too soon; but with this modification that - no longer really matters. - - Also, the removal of the vowelinstem(z) condition means that 'spy', 'fly', - 'try' ... stem to 'spi', 'fli', 'tri' and conflate with 'spied', 'tried', - 'flies' ... - -*/ - -static void step_1c(struct english_stemmer * z) -{ - if (ends(z, "y", 1) && z->j > 0 && cons(z, z->k - 1)) z->p[z->k] = 'i'; -} - - -/* step_2(z) maps double suffices to single ones. so -ization ( = -ize plus - -ation) maps to -ize etc. Note that the string before the suffix must give - m(z) > 0. -*/ - -static void step_2(struct english_stemmer * z) -{ switch (z->p[z->k - 1]) - { - case 'a': - if (ends(z, "ational", 7)) { r(z, "ate", 3); break; } - if (ends(z, "tional", 6)) { r(z, "tion", 4); break; } - break; - case 'c': - if (ends(z, "enci", 4)) { r(z, "ence", 4); break; } - if (ends(z, "anci", 4)) { r(z, "ance", 4); break; } - break; - case 'e': - if (ends(z, "izer", 4)) { r(z, "ize", 3); break; } - break; - case 'l': - if (ends(z, "bli", 3)) { r(z, "ble", 3); break; } /*-DEPARTURE-*/ - - /* To match the published algorithm, replace this line with - case 'l': - if (ends(z, "abli", 4)) { r(z, "able", 4); break; } - */ - if (ends(z, "alli", 4)) - { - if (m(z) > 0) { setto(z, "al", 2); step_2(z); } /*-NEW-*/ - break; - } - - if (ends(z, "fulli", 5)) { r(z, "ful", 3); break; } /*-NEW-*/ - if (ends(z, "entli", 5)) { r(z, "ent", 3); break; } - if (ends(z, "eli", 3)) { r(z, "e", 1); break; } - if (ends(z, "ousli", 5)) { r(z, "ous", 3); break; } - break; - case 'o': - if (ends(z, "ization", 7)) { r(z, "ize", 3); break; } - if (ends(z, "ation", 5)) { r(z, "ate", 3); break; } - if (ends(z, "ator", 4)) { r(z, "ate", 3); break; } - break; - case 's': - if (ends(z, "alism", 5)) { r(z, "al", 2); break; } - if (ends(z, "iveness", 7)) { r(z, "ive", 3); break; } - if (ends(z, "fulness", 7)) { r(z, "ful", 3); break; } - if (ends(z, "ousness", 7)) { r(z, "ous", 3); break; } - break; - case 't': - if (ends(z, "aliti", 5)) { r(z, "al", 2); break; } - if (ends(z, "iviti", 5)) { r(z, "ive", 3); break; } - if (ends(z, "biliti", 6)) { r(z, "ble", 3); break; } - break; - case 'g': - if (ends(z, "logi", 4)) - { z->j++; /*-NEW-*/ /*(Barry Wilkins)*/ - r(z, "og", 2); break; - } /*-DEPARTURE-*/ - - /* To match the published algorithm, delete this line */ - - } -} - -/* step_3(z) deals with -ic-, -full, -ness etc. Similar strategy to step_2. -*/ - -static void step_3(struct english_stemmer * z) -{ switch (z->p[z->k]) - { - case 'e': - if (ends(z, "icate", 5)) { r(z, "ic", 2); break; } - if (ends(z, "ative", 5)) { r(z, "", 0); break; } - if (ends(z, "alize", 5)) { r(z, "al", 2); break; } - break; - case 'i': - if (ends(z, "iciti", 5)) { r(z, "ic", 2); break; } - break; - case 'l': - if (ends(z, "ical", 4)) { r(z, "ic", 2); break; } - if (ends(z, "ful", 3)) { r(z, "", 0); break; } - break; - case 's': - if (ends(z, "ness", 4)) { r(z, "", 0); break; } - break; - } -} - -/* step_4() takes off -ant, -ence etc., in context vcvc. -*/ - -static void step_4(struct english_stemmer * z) -{ switch (z->p[z->k - 1]) - { case 'a': - if (ends(z, "al", 2)) break; return; - case 'c': - if (ends(z, "ance", 4)) break; - if (ends(z, "ence", 4)) break; return; - case 'e': - if (ends(z, "er", 2)) break; return; - case 'i': - if (ends(z, "ic", 2)) break; return; - case 'l': - if (ends(z, "able", 4)) break; - if (ends(z, "ible", 4)) break; return; - case 'n': - if (ends(z, "ant", 3)) break; - if (ends(z, "ement", 5)) break; - if (ends(z, "ment", 4)) break; - if (ends(z, "ent", 3)) break; return; - case 'o': - if (ends(z, "ion", 3) && (z->p[z->j] == 's' || - z->p[z->j] == 't')) break; - if (ends(z, "ou", 2)) break; return; - /* takes care of -ous */ - case 's': - if (ends(z, "ism", 3)) break; return; - case 't': - if (ends(z, "ate", 3)) break; - if (ends(z, "iti", 3)) break; return; - case 'u': - if (ends(z, "ous", 3)) break; return; - case 'v': - if (ends(z, "ive", 3)) break; return; - case 'z': - if (ends(z, "ize", 3)) break; return; - default: - return; - } - if (m(z) > 1) z->k = z->j; -} - -/* step_5(z) removes a final -e if m(z) > 1, and changes -ll to -l if - m(z) > 1. -*/ - -static void step_5(struct english_stemmer * z) -{ z->j = z->k; - if (z->p[z->k] == 'e') - { int a = m(z); - if (a > 1 || (a == 1 && !cvc(z, z->k - 1))) z->k--; - } - if (z->p[z->k] == 'l' && doublec(z, z->k) && m(z) > 1) z->k--; -} - -static const char * english_stem(void * z_, const char * q, int i0, int i1) -{ - struct english_stemmer * z = (struct english_stemmer *) z_; - int p_size = z->p_size; - - if (i1 - i0 + 50 > p_size) - { free(z->p); - p_size = i1 - i0 + 75; /* ample */ z->p_size = p_size; - z->p = (char *) malloc(p_size); - } - - memmove(z->p, q + i0, i1 - i0 + 1); - - z->k = i1 - i0; - - - { const char * t = search_pool(z->irregulars, z->k + 1, z->p); - if (t != 0) { - z->k = strlen(t) - 1; - return t; - } - } - - if (z->k > 1) /*-DEPARTURE-*/ - - /* With this line, strings of length 1 or 2 don't go through the - stemming process, although no mention is made of this in the - published algorithm. Remove the line to match the published - algorithm. */ - - { step_1ab(z); step_1c(z); - step_2(z); - step_3(z); - step_4(z); - step_5(z); - } - - z->p[z->k + 1] = 0; /* C string form for now */ - return z->p; -} - -/* -NEW- - This is a table of irregular forms. It is quite short, but still - reflects the errors actually drawn to Martin Porter's attention over - a 20 year period! - - Extend it as necessary. - - The form of the table is: - - "p1" "s11/s12/s13/ ... /" - "p2" "s21/s22/s23/ ... /" - ... - "pn" "sn1/sn2/sn3/ ... /" - 0, 0 - - String sij is mapped to paradigm form pi, and the main stemming - process is then bypassed. -*/ - -static const char * irregular_forms[] = { - - "sky", "sky/skies/", - "die", "dying/", - "lie", "lying/", - "tie", "tying/", - "news", "news/", - "inning", "innings/inning/", - "outing", "outings/outing/", - "canning", "cannings/canning/", - "howe", "howe/", - - /*-NEW-*/ - "proceed", "proceed/", - "exceed", "exceed/", - "succeed", "succeed/", /* Hiranmay Ghosh */ - - 0, 0 /* terminator */ - -}; - - -/* - * is_stopword part - */ -typedef struct { - unsigned char val; - unsigned char flag; - unsigned char right; - - unsigned char child; -} ESWNODE; - -/* is exists left tree ? */ -#define L 0x01 -/* finish word flag */ -#define F 0x02 -#define ISLEFT(x) (((ESWNODE*)x)->flag & L) -#define ISFINISH(x) (((ESWNODE*)x)->flag & F) - - -static ESWNODE engstoptree[] = { - {'m',L,9,126}, - {'d',L,4,71}, - {'b',L,2,40}, - {'a',F,0,14}, - {'c',0,0,62}, - {'f',L,2,79}, - {'e',0,0,75}, - {'h',0,1,90}, - {'i',F,0,108}, - {'t',L,4,177}, - {'o',L,2,135}, - {'n',0,0,131}, - {'s',0,0,156}, - {'v',L,2,210}, - {'u',0,0,201}, - {'w',0,1,211}, - {'y',0,0,237}, - - {'m',L|F,5,0}, - {'f',L,2,12}, - {'b',0,0,7}, - {'g',0,1,13}, - {'l',0,0,17}, - {'r',L,2,19}, - {'n',F,0,16}, - {'s',F,1,0}, - {'t',F,0,0}, - - {'o',0,0,1}, - - {'u',0,1,2}, - {'v',F,0,0}, - - {'t',F,0,0}, - - {'t',0,0,1}, - - {'e',0,0,1}, - - {'r',F,0,0}, - - {'a',0,0,1}, - - {'i',0,0,1}, - - {'n',F,0,1}, - - {'s',0,0,1}, - - {'t',F,0,0}, - - {'l',F,0,0}, - - {'d',F,1,0}, - {'i',F,0,0}, - - {'e',F,0,0}, - - {'o',L,2,21}, - {'e',F,0,3}, - {'u',0,1,21}, - {'y',F,0,0}, - - {'f',L,3,9}, - {'c',0,1,4}, - {'e',0,0,6}, - {'l',0,1,8}, - {'t',0,0,9}, - - {'a',0,0,1}, - - {'u',0,0,1}, - - {'s',F,0,0}, - - {'n',F,0,0}, - - {'o',0,0,1}, - - {'r',F,0,0}, - - {'o',0,0,1}, - - {'w',F,0,0}, - - {'w',0,0,1}, - - {'e',0,0,1}, - - {'e',0,0,1}, - - {'n',F,0,0}, - - {'t',0,0,1}, - - {'h',F,0,0}, - - {'t',F,0,0}, - - {'a',0,1,2}, - {'o',0,0,2}, - - {'n',F,0,0}, - - {'u',0,0,1}, - - {'l',0,0,1}, - - {'d',F,0,0}, - - {'o',L|F,2,4}, - {'i',0,0,2}, - {'u',0,0,5}, - - {'d',F,0,0}, - - {'e',F,1,0}, - {'w',0,0,1}, - - {'n',F,0,0}, - - {'r',0,0,1}, - - {'e',F,0,0}, - - {'a',0,0,1}, - - {'c',0,0,1}, - - {'h',F,0,0}, - - {'o',L,2,5}, - {'e',0,0,3}, - {'r',0,1,4}, - {'u',0,0,5}, - - {'w',F,0,0}, - - {'r',F,0,0}, - - {'o',0,0,1}, - - {'m',F,0,0}, - - {'r',0,0,1}, - - {'t',0,0,1}, - - {'h',0,0,1}, - - {'e',0,0,1}, - - {'r',F,0,0}, - - {'e',L|F,2,7}, - {'a',F,0,3}, - {'i',F,1,11}, - {'o',0,0,15}, - - {'d',F,1,0}, - {'v',0,0,1}, - - {'e',F,0,0}, - - {'r',F,0,1}, - - {'e',F,1,0}, - {'s',0,0,1}, - - {'e',0,0,1}, - - {'l',0,0,1}, - - {'f',F,0,0}, - - {'m',F,0,1}, - - {'s',0,0,1}, - - {'e',0,0,1}, - - {'l',0,0,1}, - - {'f',F,0,0}, - - {'w',F,0,0}, - - {'n',L|F,2,4}, - {'f',F,0,0}, - {'s',F,1,0}, - {'t',F,0,3}, - - {'t',0,0,1}, - - {'o',F,0,0}, - - {'s',0,0,1}, - - {'e',0,0,1}, - - {'l',0,0,1}, - - {'f',F,0,0}, - - {'o',L,3,6}, - {'a',0,1,4}, - {'e',F,0,0}, - {'u',0,1,7}, - {'y',F,0,8}, - - {'y',F,0,0}, - - {'r',0,1,2}, - {'s',0,0,2}, - - {'e',F,0,0}, - - {'t',F,0,0}, - - {'s',0,0,1}, - - {'t',F,0,0}, - - {'s',0,0,1}, - - {'e',0,0,1}, - - {'l',0,0,1}, - - {'f',F,0,0}, - - {'o',F,0,1}, - - {'r',F,1,0}, - {'t',F,0,0}, - - {'t',L,4,11}, - {'n',L|F,2,7}, - {'f',F,0,5}, - {'r',F,0,0}, - {'v',L,2,16}, - {'u',0,0,9}, - {'w',0,0,16}, - - {'f',F,0,0}, - - {'c',F,1,0}, - {'l',0,0,1}, - - {'i',F,0,0}, - - {'h',0,0,1}, - - {'e',0,0,1}, - - {'r',F,0,0}, - - {'r',F,1,2}, - {'t',F,0,0}, - - {'s',0,0,1}, - - {'e',0,0,1}, - - {'l',0,0,1}, - - {'v',F,0,0}, - - {'e',0,0,1}, - - {'r',F,0,0}, - - {'n',F,0,0}, - - {'h',L,2,6}, - {'a',0,0,3}, - {'o',F,1,12}, - {'u',0,0,13}, - - {'m',0,0,1}, - - {'e',F,0,0}, - - {'e',L|F,2,0}, - {'a',0,0,2}, - {'o',0,0,3}, - - {'l',0,0,1}, - - {'l',F,0,0}, - - {'u',0,0,1}, - - {'l',0,0,1}, - - {'d',F,0,0}, - - {'m',0,0,1}, - - {'e',F,0,0}, - - {'c',0,0,1}, - - {'h',F,0,0}, - - {'h',0,1,2}, - {'o',F,0,27}, - - {'i',L|F,3,0}, - {'a',0,1,4}, - {'e',F,0,5}, - {'o',0,1,17}, - {'r',0,0,18}, - - {'n',F,1,0}, - {'t',F,0,0}, - - {'n',L|F,3,0}, - {'i',0,1,5}, - {'m',F,0,5}, - {'s',L,2,9}, - {'r',0,0,7}, - {'y',F,0,0}, - - {'r',F,0,0}, - - {'s',0,0,1}, - - {'e',0,0,1}, - - {'l',0,0,1}, - - {'v',F,0,0}, - - {'e',F,0,0}, - - {'e',F,0,0}, - - {'s',0,0,1}, - - {'e',F,0,0}, - - {'o',0,0,1}, - - {'u',0,0,1}, - - {'g',0,0,1}, - - {'h',F,0,0}, - - {'o',F,0,0}, - - {'n',0,1,2}, - {'p',F,0,0}, - - {'d',0,1,2}, - {'t',0,0,3}, - - {'e',0,0,1}, - - {'r',F,0,0}, - - {'i',0,0,1}, - - {'l',F,0,0}, - - {'e',0,0,1}, - - {'r',0,0,1}, - - {'i',F,0,0}, - - {'h',L,3,7}, - {'a',F,1,0}, - {'e',F,0,3}, - {'i',0,1,17}, - {'o',0,0,20}, - - {'r',0,0,1}, - - {'e',F,0,0}, - - {'e',L,2,5}, - {'a',0,0,3}, - {'i',F,1,6}, - {'o',F,0,9}, - - {'t',F,0,0}, - - {'n',F,1,0}, - {'r',0,0,1}, - - {'e',F,0,0}, - - {'c',0,1,2}, - {'l',0,0,2}, - - {'h',F,0,0}, - - {'e',F,0,0}, - - {'m',F,0,0}, - - {'l',0,1,2}, - {'t',0,0,2}, - - {'l',F,0,0}, - - {'h',F,0,0}, - - {'u',0,0,1}, - - {'l',0,0,1}, - - {'d',F,0,0}, - - {'o',0,0,1}, - - {'u',F,0,1}, - - {'r',F,0,1}, - - {'s',0,0,1}, - - {'e',0,0,1}, - - {'l',0,0,1}, - - {'f',F,1,0}, - {'v',F,0,0} -}; - -static unsigned int -find_english_stopword( unsigned char *buf, int len ) { - ESWNODE *ptr = engstoptree; - int result = 0; - unsigned char *cur = buf; - - while( cur - buf < len ) { - if ( ptr->val == *cur ) { - cur++; - if ( ISFINISH(ptr) ) result = cur - buf; - if ( ! ptr->child ) break; - ptr += ptr->child; - } else if ( ptr->val > *cur ) { - if ( ISLEFT(ptr) ) - ptr++; - else - break; - } else { - if ( ptr->right ) - ptr += ptr->right; - else - break; - } - } - return result; -} - -#undef L -#undef F -#undef ISLEFT -#undef ISFINISH - -static int -is_stopengword(void* obj,char* word,int len) { - return ( len == find_english_stopword((unsigned char*)word, len) ) ? 1 : 0; -} - -static void * setup_english_stemmer() -{ - struct english_stemmer * z = (struct english_stemmer *) malloc(sizeof(struct english_stemmer)); - z->p = 0; z->p_size = 0; - z->irregulars = create_pool(irregular_forms); - return (void *) z; -} - -static void closedown_english_stemmer(void * z_) -{ - struct english_stemmer * z = (struct english_stemmer *) z_; - free_pool(z->irregulars); - free(z->p); - free(z); -} - -static char* -engstemming(void* obj, char *word, int *len) { - struct english_stemmer * z = (struct english_stemmer *) obj; - const char* stemmed_word; - char *result = word; - - while(result-word < *len) { - *result = tolower((unsigned char) *result); - result++; - } - stemmed_word = english_stem(obj, word, 0, *len-1); - *len = z->k + 1; - - result = (char*)palloc( *len ); - memcpy((void*)result, (void*)stemmed_word, *len); - return result; -} -#endif /* DICT_BODY */ - -#ifdef DICT_TABLE -TABLE_DICT_START - "C", - setup_english_stemmer, - closedown_english_stemmer, - engstemming, - NULL, - is_stopengword -TABLE_DICT_END -#endif - diff --git a/contrib/tsearch/dict/russian_stemming.dct b/contrib/tsearch/dict/russian_stemming.dct deleted file mode 100644 index ec7549e544..0000000000 --- a/contrib/tsearch/dict/russian_stemming.dct +++ /dev/null @@ -1,18319 +0,0 @@ -/* - * Autogenerated file - * - * Variant of the Lovin's stemmer which uses a longest match algorithm. - * Endings are stored in a suffix tree. - */ - -#ifdef DICT_BODY -typedef struct { - uint8 val; - uint8 flag; - uint8 right; - uint16 child; -} ru_RUKOI8R_NODE; - -/* is exists left tree ? */ -#define L 0x01 -/* finish word flag */ -#define F 0x02 -#define ISLEFT(x) (((ru_RUKOI8R_NODE*)x)->flag & L) -#define ISFINISH(x) (((ru_RUKOI8R_NODE*)x)->flag & F) - -#define MINLENREST 3 - -static ru_RUKOI8R_NODE ru_RUKOI8R_endstree[]={ - {'Í',L,14,5488}, - {'Å',L|F,7,1102}, - {'Á',L|F,3,594}, - {'£',0,1,25}, - {'À',F,0,71}, - {'Ã',L,2,1063}, - {'Â',F,0,0}, - {'Ä',F,0,1095}, - {'É',L|F,3,3072}, - {'Ç',F,1,2299}, - {'È',0,0,2306}, - {'Ë',L|F,2,5303}, - {'Ê',F,0,4217}, - {'Ì',F,0,5410}, - {'Õ',L|F,7,9607}, - {'Ñ',L|F,3,7715}, - {'Î',F,1,6971}, - {'Ï',F,0,7049}, - {'Ó',L,2,9413}, - {'Ò',0,0,9396}, - {'Ô',F,0,9412}, - {'Ù',L|F,4,10886}, - {'×',L,2,10275}, - {'Ö',F,0,10272}, - {'Ø',F,0,10499}, - {'Ý',L|F,2,11126}, - {'Ú',0,0,11124}, - {'Þ',F,0,11139}, - - {'Ì',L,3,22}, - {'Á',F,1,4}, - {'É',F,0,9}, - {'Î',0,1,25}, - {'Ø',F,0,32}, - - {'Ë',L|F,2,0}, - {'Ç',F,0,3}, - {'Ò',0,1,3}, - {'Ý',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Î',L|F,2,5}, - {'Ã',0,0,2}, - {'Ô',F,0,4}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Þ',F,0,0}, - - {'Î',L,2,3}, - {'É',F,0,0}, - {'Ó',F,0,2}, - - {'Å',F,0,0}, - - {'Á',F,0,0}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'É',F,0,1}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,1}, - - {'Ö',L|F,3,6}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,1}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,4}, - {'Ô',F,0,5}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Î',L,6,124}, - {'Å',L,3,49}, - {'À',F,1,10}, - {'Á',F,0,25}, - {'É',F,1,52}, - {'Ì',F,0,104}, - {'Ò',L,3,134}, - {'Ï',F,1,0}, - {'Ñ',F,0,128}, - {'Õ',L|F,2,134}, - {'Ó',0,0,132}, - {'Ø',F,0,479}, - - {'Î',F,0,1}, - - {'Ô',L,3,10}, - {'Ç',F,1,0}, - {'Î',0,0,4}, - {'Û',L,2,10}, - {'Ø',F,0,8}, - {'Þ',F,0,0}, - - {'£',F,1,2}, - {'Å',F,0,2}, - - {'Ì',F,0,0}, - - {'Ì',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'×',L,4,15}, - {'Ë',L|F,2,8}, - {'Ç',F,0,5}, - {'Ò',0,0,11}, - {'Ý',L|F,2,0}, - {'Û',0,0,16}, - {'Þ',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'É',F,1,2}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ä',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ã',0,0,1}, - - {'É',0,0,1}, - - {'Î',F,0,1}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ã',L,2,7}, - {'Â',0,0,3}, - {'Î',F,1,19}, - {'Ô',F,0,43}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Î',0,0,12}, - - {'Ò',L,2,4}, - {'Ë',F,0,2}, - {'Ú',0,0,3}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,11}, - {'Þ',F,0,0}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',F,0,2}, - - {'É',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,2}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',L|F,3,10}, - {'Ä',0,1,5}, - {'Ì',F,0,5}, - {'Ý',L|F,2,0}, - {'Ö',F,0,7}, - {'Þ',F,0,0}, - - {'Ö',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Å',F,1,2}, - {'×',0,0,12}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,6}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Å',F,1,2}, - {'Ø',F,0,10}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Ì',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Ò',L,5,240}, - {'Ì',L|F,2,0}, - {'Ë',F,0,8}, - {'Í',0,1,70}, - {'Î',F,0,119}, - {'Û',L|F,3,253}, - {'Ô',0,1,245}, - {'×',0,0,249}, - {'Ý',0,1,289}, - {'Þ',F,0,335}, - - {'Ó',L|F,4,17}, - {'Î',L,2,10}, - {'Ã',0,0,5}, - {'Ï',F,0,9}, - {'Ø',L,2,57}, - {'×',0,0,55}, - {'Ú',F,0,0}, - - {'É',0,0,1}, - - {'Î',0,0,1}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'É',F,0,0}, - - {'×',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ê',L,3,25}, - {'Ä',F,1,0}, - {'Å',F,0,4}, - {'×',L,2,25}, - {'Ô',0,0,22}, - {'Ú',0,0,37}, - - {'Û',0,1,2}, - {'Þ',F,0,2}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Î',L,2,8}, - {'Ç',0,0,2}, - {'Ô',F,0,8}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'Á',F,1,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'£',F,1,0}, - {'Å',F,0,0}, - - {'Å',L|F,2,6}, - {'£',F,0,2}, - {'Ï',F,0,9}, - - {'Ø',0,0,1}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',0,1,2}, - {'Ø',F,0,2}, - - {'Õ',F,0,0}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ë',0,1,2}, - {'Ø',F,0,0}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Å',L|F,2,9}, - {'£',F,0,2}, - {'É',F,0,45}, - - {'Á',F,0,1}, - - {'Ë',L|F,2,0}, - {'Ç',0,0,2}, - {'Ò',0,0,2}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ñ',L,2,22}, - {'Á',F,0,2}, - {'Õ',F,0,24}, - - {'Ô',L,4,10}, - {'Ë',L|F,2,0}, - {'Ç',F,0,6}, - {'Ò',0,0,6}, - {'Û',L,2,14}, - {'×',0,0,6}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ù',F,0,3}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',F,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ò',L,6,62}, - {'Å',L|F,3,13}, - {'Â',0,1,9}, - {'Ä',F,0,0}, - {'Ç',F,1,0}, - {'Î',0,0,18}, - {'×',L,3,67}, - {'Ô',0,1,59}, - {'Ö',F,0,0}, - {'Ø',F,1,70}, - {'Þ',F,0,89}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',L|F,2,5}, - {'£',F,0,3}, - {'Å',F,1,21}, - {'Ï',F,0,32}, - - {'Ì',F,0,0}, - - {'Ò',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',0,1,2}, - {'×',F,0,2}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'×',L,3,9}, - {'Ì',F,1,5}, - {'Ö',0,0,6}, - {'Ý',L|F,2,0}, - {'Û',0,0,7}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Ã',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ô',0,0,1}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,0}, - {'Î',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Å',F,0,0}, - - {'É',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ì',F,0,1}, - - {'Á',F,1,2}, - {'Å',F,0,8}, - - {'Î',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',F,1,2}, - {'Õ',0,0,3}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,4}, - - {'Ë',F,1,0}, - {'×',0,0,1}, - - {'Ï',F,0,0}, - - {'Ì',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,12}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,1,2}, - {'×',0,0,2}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ó',L,2,3}, - {'Ñ',F,0,0}, - {'Ù',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Å',F,1,0}, - {'Ï',F,0,0}, - - {'Ó',L,2,8}, - {'Ê',0,0,2}, - {'×',F,0,7}, - - {'Á',F,1,2}, - {'Å',F,0,3}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ô',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,20}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',0,0,20}, - - {'Ò',L,3,11}, - {'Ä',0,1,4}, - {'Ë',F,0,4}, - {'×',0,1,9}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,1,2}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Î',0,0,1}, - - {'Ë',F,0,1}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,44}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,25}, - {'Õ',F,0,28}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,17}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',L|F,3,10}, - {'Ë',0,1,5}, - {'Ì',F,0,0}, - {'Û',L,2,27}, - {'×',0,0,25}, - {'Þ',F,0,0}, - - {'Ó',0,0,1}, - - {'×',0,0,1}, - - {'Ï',F,0,1}, - - {'Ø',F,0,0}, - - {'Ó',L|F,2,8}, - {'Á',F,0,2}, - {'Ù',F,0,0}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Å',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,0,1}, - - {'Î',F,1,2}, - {'Ú',F,0,0}, - - {'Î',0,0,1}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Õ',F,0,0}, - - {'Î',L|F,9,277}, - {'Ç',L|F,4,58}, - {'Ã',L|F,2,17}, - {'Â',F,0,15}, - {'Ä',F,0,54}, - {'Ë',L|F,2,67}, - {'È',0,0,61}, - {'Ì',F,1,162}, - {'Í',0,0,234}, - {'×',L,5,404}, - {'Ó',L,2,381}, - {'Ò',0,0,364}, - {'Ô',F,1,380}, - {'Ö',F,0,398}, - {'Û',L,2,424}, - {'Ú',0,0,422}, - {'Ý',F,1,437}, - {'Þ',F,0,451}, - - {'Ø',F,0,0}, - - {'Ê',L,2,34}, - {'É',F,0,2}, - {'Î',0,0,33}, - - {'Î',F,1,2}, - {'Þ',0,0,28}, - - {'Ö',L|F,3,0}, - {'Î',0,1,4}, - {'Ô',0,0,7}, - {'Ø',F,1,8}, - {'Þ',0,0,16}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,1,2}, - {'Å',F,0,0}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Ú',F,0,0}, - - {'Ï',0,1,2}, - {'Ñ',0,0,5}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'É',0,1,2}, - {'Õ',F,0,0}, - - {'Ò',0,0,1}, - - {'Á',F,1,0}, - {'Ï',F,0,0}, - - {'Ô',L,6,61}, - {'Î',L,3,40}, - {'Ä',F,1,0}, - {'É',F,0,8}, - {'Ï',F,1,44}, - {'Ó',F,0,48}, - {'Ú',L|F,3,0}, - {'×',0,1,61}, - {'Ø',F,0,64}, - {'Û',0,1,66}, - {'Þ',0,0,71}, - - {'Ô',L,2,23}, - {'Î',F,0,3}, - {'Ú',0,1,25}, - {'Þ',0,0,25}, - - {'Ö',L|F,3,0}, - {'Î',0,1,4}, - {'Ô',0,0,7}, - {'Ø',F,1,8}, - {'Þ',0,0,8}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'Å',L,2,5}, - {'Á',F,0,2}, - {'É',F,0,0}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Ö',0,0,1}, - - {'Õ',F,0,0}, - - {'×',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ê',0,1,2}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Å',L|F,2,3}, - {'£',F,0,0}, - {'Ï',F,0,2}, - - {'Ø',F,0,0}, - - {'Ø',F,0,0}, - - {'Ï',L|F,2,0}, - {'Á',F,0,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Á',F,1,0}, - {'Ï',0,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ì',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,1,2}, - {'Ú',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Õ',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ï',F,0,11}, - - {'Ë',F,0,0}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,2}, - - {'Ò',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'É',L|F,4,46}, - {'Å',L|F,2,0}, - {'Á',F,0,5}, - {'Ç',F,0,38}, - {'Ñ',L|F,2,0}, - {'Ë',F,0,50}, - {'Õ',F,0,55}, - - {'Ô',L,4,15}, - {'Ë',L|F,2,7}, - {'È',F,0,0}, - {'Ò',0,0,11}, - {'Ö',L,2,13}, - {'Õ',0,0,11}, - {'×',0,1,12}, - {'Þ',F,0,0}, - - {'Ø',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',F,0,0}, - - {'Ú',F,0,0}, - - {'Ï',L|F,2,4}, - {'É',F,0,2}, - {'Ù',F,0,0}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',L|F,2,4}, - {'Ä',F,0,0}, - {'Ö',0,1,4}, - {'×',0,0,4}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ø',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',F,0,1}, - - {'Ë',L|F,2,4}, - {'Ç',F,0,0}, - {'Ô',0,1,7}, - {'Þ',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Å',L|F,2,9}, - {'£',F,0,2}, - {'É',0,0,31}, - - {'Á',F,0,1}, - - {'Ë',L|F,2,0}, - {'Ç',0,0,2}, - {'Ò',0,0,2}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ñ',L,2,19}, - {'Á',F,0,2}, - {'Õ',F,0,21}, - - {'Ò',L,3,7}, - {'Ç',F,1,5}, - {'Ë',F,0,0}, - {'×',L,2,6}, - {'Ô',0,0,4}, - {'Ý',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ù',F,0,3}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',F,0,0}, - - {'Ä',0,0,1}, - - {'Á',F,0,0}, - - {'É',L|F,5,42}, - {'Â',L,2,27}, - {'Á',F,0,7}, - {'Å',F,1,28}, - {'Ç',F,0,0}, - {'Ô',L,2,53}, - {'Î',0,0,40}, - {'Ø',0,1,53}, - {'Þ',F,0,72}, - - {'Ô',L,3,6}, - {'Ë',F,1,0}, - {'Ò',F,0,3}, - {'×',F,1,4}, - {'Þ',0,0,14}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ò',0,0,1}, - - {'É',0,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,9}, - {'Ì',F,1,5}, - {'Ô',F,0,6}, - {'Ý',L|F,2,0}, - {'Û',0,0,6}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Õ',F,0,0}, - - {'Î',0,0,1}, - - {'Á',0,0,1}, - - {'Þ',0,0,1}, - - {'É',F,0,0}, - - {'Å',L|F,2,4}, - {'£',F,0,2}, - {'Ï',F,0,6}, - - {'Ì',F,0,0}, - - {'Ì',F,1,0}, - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'É',F,0,1}, - - {'Ã',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',0,0,1}, - - {'Á',F,1,2}, - {'Å',F,0,8}, - - {'Î',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',F,1,2}, - {'Õ',0,0,3}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,4}, - - {'Ë',F,1,0}, - {'×',0,0,1}, - - {'Ï',F,0,0}, - - {'Ì',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,12}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,1,2}, - {'×',0,0,2}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,1,2}, - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L,4,11}, - {'Á',L|F,2,7}, - {'£',F,0,0}, - {'Å',F,0,0}, - {'Ï',L|F,2,12}, - {'Î',0,0,10}, - {'Ó',0,1,11}, - {'Ù',F,0,0}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ë',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Á',0,0,1}, - - {'Î',F,0,0}, - - {'Å',L|F,3,7}, - {'£',F,1,0}, - {'Á',F,0,4}, - {'Ï',L|F,2,0}, - {'É',F,0,4}, - {'Ô',0,0,4}, - - {'Ë',F,0,0}, - - {'Ø',F,0,0}, - - {'Þ',F,0,0}, - - {'Ó',0,0,1}, - - {'Å',F,1,2}, - {'Ø',0,0,8}, - - {'Û',F,1,0}, - {'Þ',0,0,1}, - - {'É',0,0,1}, - - {'Î',F,0,1}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',0,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Õ',F,0,0}, - - {'Ò',0,0,1}, - - {'Á',F,1,0}, - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'À',0,1,2}, - {'É',F,0,11}, - - {'Á',0,1,2}, - {'Ñ',F,0,5}, - - {'×',0,0,1}, - - {'Ù',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,1,0}, - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'É',L|F,2,8}, - {'Å',F,0,2}, - {'Î',0,0,31}, - - {'É',F,1,0}, - {'Î',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Î',F,1,2}, - {'Þ',0,0,22}, - - {'Ø',L|F,2,5}, - {'Ô',0,0,2}, - {'Þ',0,0,12}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'Å',F,0,0}, - - {'Ú',F,0,0}, - - {'Î',L|F,12,542}, - {'Ç',L|F,6,181}, - {'Ã',L|F,3,29}, - {'Á',F,1,21}, - {'Â',F,0,26}, - {'Ä',F,1,65}, - {'Å',F,0,65}, - {'Ë',L|F,3,406}, - {'È',0,1,182}, - {'É',F,0,186}, - {'Ì',F,1,498}, - {'Í',0,0,520}, - {'×',L,6,929}, - {'Ó',L,3,810}, - {'Ï',F,1,559}, - {'Ò',0,0,792}, - {'Ô',F,1,809}, - {'Ö',F,0,922}, - {'Ú',L,3,1152}, - {'Ø',F,1,946}, - {'Ù',F,0,958}, - {'Ý',L|F,2,1165}, - {'Û',0,0,1149}, - {'Þ',F,0,1178}, - - {'Ë',L|F,2,0}, - {'Ç',F,0,3}, - {'Ò',0,1,3}, - {'Ý',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ø',F,0,0}, - - {'Ê',L,2,34}, - {'É',F,0,2}, - {'Î',0,0,33}, - - {'Î',F,1,2}, - {'Þ',0,0,28}, - - {'Ö',L|F,3,0}, - {'Î',0,1,4}, - {'Ô',0,0,7}, - {'Ø',F,1,8}, - {'Þ',0,0,16}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,1,2}, - {'Å',F,0,0}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Ú',F,0,0}, - - {'Û',L|F,2,19}, - {'Î',F,0,3}, - {'Ý',0,1,61}, - {'Þ',F,0,105}, - - {'Ô',L,3,10}, - {'Ç',F,1,0}, - {'Î',0,0,4}, - {'Û',L,2,10}, - {'Ø',F,0,8}, - {'Þ',F,0,0}, - - {'£',F,1,2}, - {'Å',F,0,2}, - - {'Ì',F,0,0}, - - {'Ì',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ó',L,2,8}, - {'Ê',0,0,2}, - {'×',F,0,7}, - - {'Á',F,1,2}, - {'Å',F,0,3}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ô',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,20}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',0,0,20}, - - {'Ò',L,3,11}, - {'Ä',0,1,4}, - {'Ë',F,0,4}, - {'×',0,1,9}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,1,2}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Î',F,0,1}, - - {'Ë',L|F,2,4}, - {'Ç',F,0,0}, - {'Ô',0,1,7}, - {'Þ',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,42}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,23}, - {'Õ',F,0,26}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,15}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ï',0,1,2}, - {'Ñ',0,0,5}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'É',0,1,2}, - {'Õ',F,0,0}, - - {'Ò',0,0,1}, - - {'Á',F,1,0}, - {'Ï',F,0,0}, - - {'Î',L|F,4,80}, - {'Ã',L,2,10}, - {'Â',0,0,6}, - {'Ë',F,0,14}, - {'Û',L|F,2,120}, - {'Ô',F,0,114}, - {'Ý',0,1,162}, - {'Þ',F,0,208}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Î',0,0,4}, - - {'Ë',F,1,0}, - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Å',F,0,0}, - - {'Ó',L|F,4,17}, - {'Î',L,2,10}, - {'Ã',0,0,5}, - {'Ï',F,0,9}, - {'Ø',L,2,57}, - {'×',0,0,55}, - {'Ú',F,0,0}, - - {'É',0,0,1}, - - {'Î',0,0,1}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'É',F,0,0}, - - {'×',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ê',L,3,25}, - {'Ä',F,1,0}, - {'Å',F,0,4}, - {'×',L,2,25}, - {'Ô',0,0,22}, - {'Ú',0,0,37}, - - {'Û',0,1,2}, - {'Þ',F,0,2}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Î',L,2,8}, - {'Ç',0,0,2}, - {'Ô',F,0,8}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'Á',F,1,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'£',F,1,0}, - {'Å',F,0,0}, - - {'Å',L|F,2,6}, - {'£',F,0,2}, - {'Ï',F,0,9}, - - {'Ø',0,0,1}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',0,1,2}, - {'Ø',F,0,2}, - - {'Õ',F,0,0}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ë',0,1,2}, - {'Ø',F,0,0}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',L,5,30}, - {'Á',L|F,2,8}, - {'£',F,0,0}, - {'Å',F,1,15}, - {'Ç',F,0,0}, - {'Ø',L|F,2,31}, - {'Ô',0,0,28}, - {'Û',0,1,30}, - {'Þ',F,0,0}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',F,0,2}, - - {'É',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,2}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',L|F,3,10}, - {'Ä',0,1,5}, - {'Ì',F,0,5}, - {'Ý',L|F,2,0}, - {'Ö',F,0,7}, - {'Þ',F,0,0}, - - {'Ö',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'£',F,1,2}, - {'Å',F,0,2}, - - {'Ì',F,0,0}, - - {'Ì',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Î',L,2,3}, - {'É',F,0,0}, - {'Ó',F,0,2}, - - {'Å',F,0,0}, - - {'Á',F,0,0}, - - {'Ó',L,2,8}, - {'Ê',0,0,2}, - {'×',F,0,7}, - - {'Á',F,1,2}, - {'Å',F,0,3}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ô',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,20}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',0,0,20}, - - {'Ò',L,3,11}, - {'Ä',0,1,4}, - {'Ë',F,0,4}, - {'×',0,1,9}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,1,2}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Î',F,0,1}, - - {'Ë',L|F,2,4}, - {'Ç',F,0,0}, - {'Ô',0,1,7}, - {'Þ',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,44}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,25}, - {'Õ',F,0,28}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,17}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',L,6,59}, - {'Î',L,3,40}, - {'Ä',F,1,0}, - {'É',F,0,8}, - {'Ï',F,1,44}, - {'Ó',F,0,46}, - {'Ú',L|F,3,0}, - {'×',0,1,59}, - {'Ø',F,0,62}, - {'Û',0,1,64}, - {'Þ',0,0,69}, - - {'Ô',L,2,23}, - {'Î',F,0,3}, - {'Ú',0,1,25}, - {'Þ',0,0,25}, - - {'Ö',L|F,3,0}, - {'Î',0,1,4}, - {'Ô',0,0,7}, - {'Ø',F,1,8}, - {'Þ',0,0,8}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'Å',L,2,5}, - {'Á',F,0,2}, - {'É',F,0,0}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Ö',0,0,1}, - - {'Õ',F,0,0}, - - {'Î',0,1,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Ê',0,1,2}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Å',L|F,2,3}, - {'£',F,0,0}, - {'Ï',F,0,2}, - - {'Ø',F,0,0}, - - {'Ø',F,0,0}, - - {'Ï',L|F,2,0}, - {'Á',F,0,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Á',F,1,0}, - {'Ï',0,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ì',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,1,2}, - {'Ú',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Õ',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ï',F,0,11}, - - {'Ë',F,0,0}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,2}, - - {'Ò',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Å',L|F,2,12}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',F,0,0}, - - {'Ò',L,3,5}, - {'È',F,1,0}, - {'Ë',F,0,0}, - {'Õ',0,1,3}, - {'Ö',0,0,3}, - - {'É',F,0,0}, - - {'Ô',F,0,0}, - - {'Ú',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,6}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',L|F,2,3}, - {'£',F,0,0}, - {'É',0,0,7}, - - {'Ñ',0,1,2}, - {'Õ',F,0,0}, - - {'Ì',0,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ä',0,0,1}, - - {'Á',F,0,0}, - - {'Ç',L|F,4,0}, - {'Â',L,2,13}, - {'Á',F,0,6}, - {'Å',F,0,14}, - {'Ô',L,2,24}, - {'É',F,0,19}, - {'Ø',F,1,24}, - {'Þ',F,0,0}, - - {'Ò',L|F,2,4}, - {'Ë',F,0,0}, - {'×',F,1,0}, - {'Þ',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,6}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Î',0,0,1}, - - {'Á',0,0,1}, - - {'Þ',0,0,1}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Í',L,3,67}, - {'Ë',F,1,5}, - {'Ì',F,0,0}, - {'Ô',L,2,224}, - {'Î',F,0,111}, - {'×',0,0,227}, - - {'Ó',L|F,4,17}, - {'Î',L,2,10}, - {'Ã',0,0,5}, - {'Ï',F,0,9}, - {'Ø',L,2,55}, - {'×',0,0,53}, - {'Ú',F,0,0}, - - {'É',0,0,1}, - - {'Î',0,0,1}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'É',F,0,0}, - - {'×',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ê',L,3,23}, - {'Ä',F,1,0}, - {'Å',F,0,4}, - {'×',L,2,23}, - {'Ô',0,0,20}, - {'Ú',0,0,35}, - - {'Þ',F,0,1}, - - {'É',F,0,1}, - - {'Î',L,2,8}, - {'Ç',0,0,2}, - {'Ô',F,0,8}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'Á',F,1,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'£',F,1,0}, - {'Å',F,0,0}, - - {'Å',L|F,2,6}, - {'£',F,0,2}, - {'Ï',F,0,9}, - - {'Ø',0,0,1}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',0,1,2}, - {'Ø',F,0,2}, - - {'Õ',F,0,0}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ë',0,1,2}, - {'Ø',F,0,0}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Å',L|F,2,9}, - {'£',F,0,2}, - {'É',F,0,43}, - - {'Á',F,0,1}, - - {'Ë',L|F,2,0}, - {'Ç',0,0,2}, - {'Ò',0,0,2}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ñ',L,2,20}, - {'Á',F,0,2}, - {'Õ',F,0,22}, - - {'Ô',L,4,10}, - {'Ë',L|F,2,0}, - {'Ç',F,0,6}, - {'Ò',0,0,6}, - {'Û',L,2,12}, - {'×',0,0,6}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ù',F,0,0}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',F,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ò',L,6,60}, - {'Å',L|F,3,13}, - {'Â',0,1,9}, - {'Ä',F,0,0}, - {'Ç',F,1,0}, - {'Î',0,0,18}, - {'×',L,3,65}, - {'Ô',0,1,57}, - {'Ö',F,0,0}, - {'Ø',F,1,68}, - {'Þ',F,0,84}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',L|F,2,5}, - {'£',F,0,3}, - {'Å',F,1,19}, - {'Ï',F,0,30}, - - {'Ì',F,0,0}, - - {'Ò',L|F,2,0}, - {'Ë',F,0,0}, - {'×',F,0,1}, - - {'Ï',F,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'×',L,3,9}, - {'Ì',F,1,5}, - {'Ö',0,0,6}, - {'Ý',L|F,2,0}, - {'Û',0,0,7}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Ã',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ô',0,0,1}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,0}, - {'Î',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Å',F,0,0}, - - {'É',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ì',F,0,1}, - - {'Á',F,1,2}, - {'Å',F,0,8}, - - {'Î',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',F,1,2}, - {'Õ',0,0,3}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,4}, - - {'Ë',F,1,0}, - {'×',0,0,1}, - - {'Ï',F,0,0}, - - {'Ì',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,12}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,1,2}, - {'×',0,0,2}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ó',L,2,3}, - {'Ñ',F,0,0}, - {'Ù',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Å',F,1,0}, - {'Ï',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,1,2}, - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ï',F,1,0}, - {'Õ',F,0,0}, - - {'Ê',L,5,92}, - {'Á',L|F,2,16}, - {'£',F,0,8}, - {'Å',F,1,17}, - {'É',F,0,74}, - {'Ó',L,3,102}, - {'Î',0,1,99}, - {'Ï',F,0,99}, - {'×',0,1,101}, - {'Ø',F,0,102}, - - {'Ô',L,3,5}, - {'À',F,1,0}, - {'Ï',F,0,0}, - {'Õ',F,1,0}, - {'×',0,0,2}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ï',L|F,5,0}, - {'Á',L|F,2,8}, - {'À',F,0,0}, - {'Ì',F,1,0}, - {'Î',F,0,28}, - {'Ô',L,2,39}, - {'Ñ',F,0,34}, - {'Õ',F,1,38}, - {'×',0,0,49}, - - {'Ô',L,4,15}, - {'Ë',L|F,2,8}, - {'Ç',F,0,5}, - {'Ò',0,0,11}, - {'Û',L,2,18}, - {'×',0,0,11}, - {'Þ',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',F,1,2}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ä',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ô',L,2,4}, - {'Ç',F,0,0}, - {'Û',0,1,4}, - {'Þ',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Å',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',L|F,4,7}, - {'Ë',L|F,2,0}, - {'Ä',F,0,0}, - {'Ì',F,0,0}, - {'×',L,2,6}, - {'Ö',0,0,4}, - {'Û',0,0,7}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',F,1,2}, - {'Ï',F,0,0}, - - {'Ë',F,0,0}, - - {'Õ',F,0,0}, - - {'À',F,1,0}, - {'Á',F,0,1}, - - {'Ò',L,3,6}, - {'Ç',F,1,4}, - {'Ë',F,0,0}, - {'×',0,1,4}, - {'Ý',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,1,2}, - {'É',F,0,2}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',0,0,1}, - - {'Î',F,0,0}, - - {'Å',L|F,3,7}, - {'£',F,1,0}, - {'Á',F,0,4}, - {'Ï',L|F,2,0}, - {'É',F,0,4}, - {'Ô',0,0,4}, - - {'Ë',F,0,0}, - - {'Ø',F,0,0}, - - {'Þ',F,0,0}, - - {'Ó',0,0,1}, - - {'Å',F,1,2}, - {'Ø',0,0,8}, - - {'Û',F,1,0}, - {'Þ',0,0,1}, - - {'É',0,0,1}, - - {'Î',F,0,1}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',0,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Î',0,1,2}, - {'Û',0,0,11}, - - {'Å',F,0,1}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,4}, - {'Ô',F,0,5}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Õ',F,0,0}, - - {'Í',L,3,13}, - {'Ë',0,1,5}, - {'Ì',F,0,0}, - {'Ô',L,2,177}, - {'Î',F,0,59}, - {'×',0,0,180}, - - {'Ó',0,0,1}, - - {'×',0,0,1}, - - {'Å',L|F,2,3}, - {'£',F,0,0}, - {'Ï',F,0,2}, - - {'Ø',F,0,0}, - - {'Ø',F,0,0}, - - {'Å',L|F,2,9}, - {'£',F,0,2}, - {'É',F,0,45}, - - {'Á',F,0,1}, - - {'Ë',L|F,2,0}, - {'Ç',0,0,2}, - {'Ò',0,0,2}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ñ',L,2,22}, - {'Á',F,0,2}, - {'Õ',F,0,24}, - - {'Ô',L,4,10}, - {'Ë',L|F,2,0}, - {'Ç',F,0,6}, - {'Ò',0,0,6}, - {'Û',L,2,14}, - {'×',0,0,6}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ù',F,0,3}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',F,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ò',L,6,62}, - {'Å',L|F,3,13}, - {'Â',0,1,9}, - {'Ä',F,0,0}, - {'Ç',F,1,0}, - {'Î',0,0,18}, - {'×',L,3,67}, - {'Ô',0,1,59}, - {'Ö',F,0,0}, - {'Ø',F,1,70}, - {'Þ',F,0,89}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',L|F,2,5}, - {'£',F,0,3}, - {'Å',F,1,21}, - {'Ï',F,0,32}, - - {'Ì',F,0,0}, - - {'Ò',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',0,1,2}, - {'×',F,0,2}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'×',L,3,9}, - {'Ì',F,1,5}, - {'Ö',0,0,6}, - {'Ý',L|F,2,0}, - {'Û',0,0,7}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Ã',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ô',0,0,1}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,0}, - {'Î',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Å',F,0,0}, - - {'É',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ì',F,0,1}, - - {'Á',F,1,2}, - {'Å',F,0,8}, - - {'Î',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',F,1,2}, - {'Õ',0,0,3}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,4}, - - {'Ë',F,1,0}, - {'×',0,0,1}, - - {'Ï',F,0,0}, - - {'Ì',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,12}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,1,2}, - {'×',0,0,2}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ó',L,2,3}, - {'Ñ',F,0,0}, - {'Ù',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Å',L|F,2,0}, - {'£',F,0,0}, - {'Ï',F,0,1}, - - {'Ë',0,0,1}, - - {'Ó',F,0,1}, - - {'Ê',0,0,1}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Ò',0,0,1}, - - {'Á',F,1,0}, - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'À',0,1,2}, - {'É',F,0,11}, - - {'Á',0,1,2}, - {'Ñ',F,0,5}, - - {'×',0,0,1}, - - {'Ù',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,1,0}, - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ï',0,1,2}, - {'Ñ',0,0,5}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Ñ',L|F,3,454}, - {'Á',F,1,4}, - {'É',F,0,269}, - {'Õ',F,1,0}, - {'Ù',F,0,567}, - - {'Î',L|F,9,173}, - {'Ç',L|F,4,50}, - {'Ã',L|F,2,16}, - {'Â',F,0,14}, - {'Ä',F,0,46}, - {'Ë',L|F,2,59}, - {'È',0,0,53}, - {'Ì',0,1,143}, - {'Í',0,0,154}, - {'Ö',L|F,4,225}, - {'Ó',L,2,203}, - {'Ò',0,0,186}, - {'Ô',F,0,202}, - {'Ú',L,2,244}, - {'×',0,0,222}, - {'Ý',F,1,243}, - {'Þ',F,0,246}, - - {'Ø',F,0,0}, - - {'Ê',L,2,28}, - {'É',F,0,2}, - {'Î',0,0,27}, - - {'Î',F,1,2}, - {'Þ',0,0,22}, - - {'Ø',L|F,2,5}, - {'Ô',0,0,2}, - {'Þ',0,0,12}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,0,1}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Ú',F,0,0}, - - {'Ï',0,1,2}, - {'Ñ',0,0,5}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'É',0,1,2}, - {'Õ',F,0,0}, - - {'Ò',0,0,1}, - - {'Á',F,1,0}, - {'Ï',F,0,0}, - - {'Ô',L,6,50}, - {'Î',L,3,40}, - {'Ä',F,1,0}, - {'É',F,0,8}, - {'Ï',F,1,41}, - {'Ó',F,0,43}, - {'Ú',L|F,3,0}, - {'×',0,1,50}, - {'Ø',F,0,53}, - {'Û',0,1,55}, - {'Þ',0,0,60}, - - {'Ô',L,2,23}, - {'Î',F,0,3}, - {'Ú',0,1,25}, - {'Þ',0,0,25}, - - {'Ö',L|F,3,0}, - {'Î',0,1,4}, - {'Ô',0,0,7}, - {'Ø',F,1,8}, - {'Þ',0,0,8}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'Á',F,1,2}, - {'É',F,0,0}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Î',0,1,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Ê',0,0,1}, - - {'É',F,0,0}, - - {'Ï',L|F,2,0}, - {'Á',F,0,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Á',F,1,0}, - {'Ï',0,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ì',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,1,2}, - {'Ú',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Õ',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ï',F,0,11}, - - {'Ë',F,0,0}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,2}, - - {'Ò',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',F,0,0}, - - {'Ò',L,3,5}, - {'È',F,1,0}, - {'Ë',F,0,0}, - {'Õ',0,1,3}, - {'Ö',0,0,3}, - - {'É',F,0,0}, - - {'Ô',F,0,0}, - - {'Ú',F,0,0}, - - {'Å',L|F,2,3}, - {'£',F,0,0}, - {'É',0,0,7}, - - {'Ñ',0,1,2}, - {'Õ',F,0,0}, - - {'Ì',0,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ä',0,0,1}, - - {'Á',F,0,0}, - - {'Å',L|F,3,15}, - {'Á',F,1,5}, - {'Â',0,0,10}, - {'Ô',L,2,19}, - {'Ç',F,0,0}, - {'Þ',F,0,0}, - - {'Ò',L|F,2,4}, - {'Ë',F,0,0}, - {'×',F,1,0}, - {'Þ',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,6}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,1,2}, - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L,4,11}, - {'Á',L|F,2,7}, - {'£',F,0,0}, - {'Å',F,0,0}, - {'Ï',L|F,2,12}, - {'Î',0,0,10}, - {'Ó',0,1,11}, - {'Ù',F,0,0}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ë',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Å',L|F,2,0}, - {'Á',F,0,0}, - {'É',F,0,0}, - - {'Á',0,0,1}, - - {'Î',F,0,0}, - - {'É',L|F,2,5}, - {'Á',F,0,3}, - {'Ï',F,1,0}, - {'Ô',0,0,3}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ó',0,0,1}, - - {'Å',F,1,2}, - {'Ø',0,0,8}, - - {'Û',F,1,0}, - {'Þ',0,0,1}, - - {'É',0,0,1}, - - {'Î',F,0,1}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',0,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,1,0}, - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ø',L,4,87}, - {'Î',L|F,2,69}, - {'Ë',F,0,5}, - {'Ò',0,0,82}, - {'Ý',L,2,129}, - {'Û',F,0,84}, - {'Þ',F,0,174}, - - {'Ó',L|F,4,17}, - {'Î',L,2,10}, - {'Ã',0,0,5}, - {'Ï',F,0,9}, - {'Ø',L,2,57}, - {'×',0,0,55}, - {'Ú',F,0,0}, - - {'É',0,0,1}, - - {'Î',0,0,1}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'É',F,0,0}, - - {'×',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ê',L,3,25}, - {'Ä',F,1,0}, - {'Å',F,0,4}, - {'×',L,2,25}, - {'Ô',0,0,22}, - {'Ú',0,0,37}, - - {'Û',0,1,2}, - {'Þ',F,0,2}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Î',L,2,8}, - {'Ç',0,0,2}, - {'Ô',F,0,8}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'Á',F,1,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'£',F,1,0}, - {'Å',F,0,0}, - - {'Å',L|F,2,6}, - {'£',F,0,2}, - {'Ï',F,0,9}, - - {'Ø',0,0,1}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',0,1,2}, - {'Ø',F,0,2}, - - {'Õ',F,0,0}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ë',0,1,2}, - {'Ø',F,0,0}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',L,3,10}, - {'Ç',F,1,0}, - {'Î',0,0,4}, - {'Û',L,2,10}, - {'Ø',F,0,8}, - {'Þ',F,0,0}, - - {'£',F,1,2}, - {'Å',F,0,2}, - - {'Ì',F,0,0}, - - {'Ì',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,1,0}, - {'Ï',F,0,0}, - - {'Û',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',L,2,8}, - {'Ê',0,0,2}, - {'×',F,0,7}, - - {'Á',F,1,2}, - {'Å',F,0,3}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ô',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,20}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',0,0,20}, - - {'Ò',L,3,11}, - {'Ä',0,1,4}, - {'Ë',F,0,4}, - {'×',0,1,9}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,1,2}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Î',F,0,1}, - - {'Ë',L|F,2,4}, - {'Ç',F,0,0}, - {'Ô',0,1,7}, - {'Þ',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,44}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,25}, - {'Õ',F,0,28}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,17}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Î',L,5,85}, - {'É',L|F,2,15}, - {'Á',F,0,8}, - {'Ë',0,1,66}, - {'Ì',F,0,69}, - {'Ô',L|F,3,92}, - {'Ò',0,1,89}, - {'Ó',0,0,89}, - {'×',0,1,108}, - {'Ø',F,0,0}, - - {'Ë',L|F,2,0}, - {'Ç',F,0,3}, - {'Ò',0,1,3}, - {'Ý',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ã',L,2,7}, - {'Â',0,0,3}, - {'Î',F,1,19}, - {'Ô',F,0,43}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Î',0,0,12}, - - {'Ò',L,2,4}, - {'Ë',F,0,2}, - {'Ú',0,0,3}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,11}, - {'Þ',F,0,0}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',F,0,2}, - - {'É',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,2}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',L|F,3,10}, - {'Ä',0,1,5}, - {'Ì',F,0,5}, - {'Ý',L|F,2,0}, - {'Ö',F,0,7}, - {'Þ',F,0,0}, - - {'Ö',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ó',0,0,1}, - - {'×',0,0,1}, - - {'Ï',F,0,1}, - - {'Ø',F,0,0}, - - {'Å',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,6}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',F,1,2}, - {'Ø',F,0,8}, - - {'Ö',L|F,3,6}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Ì',F,0,0}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ó',L|F,2,8}, - {'Á',F,0,2}, - {'Ù',F,0,0}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Å',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,0,1}, - - {'Î',F,1,2}, - {'Ú',F,0,0}, - - {'Î',0,0,1}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Í',L,3,13}, - {'Ë',0,1,5}, - {'Ì',F,0,0}, - {'Ô',L,2,177}, - {'Î',F,0,59}, - {'×',0,0,180}, - - {'Ó',0,0,1}, - - {'×',0,0,1}, - - {'Å',L|F,2,3}, - {'£',F,0,0}, - {'Ï',F,0,2}, - - {'Ø',F,0,0}, - - {'Ø',F,0,0}, - - {'Å',L|F,2,9}, - {'£',F,0,2}, - {'É',F,0,45}, - - {'Á',F,0,1}, - - {'Ë',L|F,2,0}, - {'Ç',0,0,2}, - {'Ò',0,0,2}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ñ',L,2,22}, - {'Á',F,0,2}, - {'Õ',F,0,24}, - - {'Ô',L,4,10}, - {'Ë',L|F,2,0}, - {'Ç',F,0,6}, - {'Ò',0,0,6}, - {'Û',L,2,14}, - {'×',0,0,6}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ù',F,0,3}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',F,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ò',L,6,62}, - {'Å',L|F,3,13}, - {'Â',0,1,9}, - {'Ä',F,0,0}, - {'Ç',F,1,0}, - {'Î',0,0,18}, - {'×',L,3,67}, - {'Ô',0,1,59}, - {'Ö',F,0,0}, - {'Ø',F,1,70}, - {'Þ',F,0,89}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',L|F,2,5}, - {'£',F,0,3}, - {'Å',F,1,21}, - {'Ï',F,0,32}, - - {'Ì',F,0,0}, - - {'Ò',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',0,1,2}, - {'×',F,0,2}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'×',L,3,9}, - {'Ì',F,1,5}, - {'Ö',0,0,6}, - {'Ý',L|F,2,0}, - {'Û',0,0,7}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Ã',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ô',0,0,1}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,0}, - {'Î',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Å',F,0,0}, - - {'É',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ì',F,0,1}, - - {'Á',F,1,2}, - {'Å',F,0,8}, - - {'Î',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',F,1,2}, - {'Õ',0,0,3}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,4}, - - {'Ë',F,1,0}, - {'×',0,0,1}, - - {'Ï',F,0,0}, - - {'Ì',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,12}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,1,2}, - {'×',0,0,2}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ó',L,2,3}, - {'Ñ',F,0,0}, - {'Ù',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Å',L|F,2,3}, - {'£',F,0,0}, - {'Ï',F,0,2}, - - {'Ø',F,0,0}, - - {'Ë',0,0,1}, - - {'Ó',F,0,1}, - - {'Ê',0,0,1}, - - {'É',F,0,0}, - - {'Ò',L,9,1051}, - {'É',L|F,4,35}, - {'Ç',L|F,2,21}, - {'Á',F,0,14}, - {'È',0,0,27}, - {'Ì',L|F,2,184}, - {'Ë',F,0,83}, - {'Í',0,1,271}, - {'Î',0,0,1033}, - {'×',L,4,1068}, - {'Ô',L|F,2,1043}, - {'Ó',0,0,1041}, - {'Ö',F,0,1062}, - {'Û',L,2,1067}, - {'Ø',F,0,1064}, - {'Ý',F,1,1115}, - {'Þ',F,0,1129}, - - {'Ë',L|F,2,0}, - {'Ç',F,0,3}, - {'Ò',0,1,3}, - {'Ý',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ï',0,1,2}, - {'Ñ',0,0,5}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'É',0,1,2}, - {'Õ',F,0,0}, - - {'Ò',0,0,1}, - - {'Á',F,1,0}, - {'Ï',F,0,0}, - - {'Ã',L,2,7}, - {'Â',0,0,3}, - {'Î',F,1,19}, - {'Ô',F,0,43}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Î',0,0,12}, - - {'Ò',L,2,4}, - {'Ë',F,0,2}, - {'Ú',0,0,3}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,11}, - {'Þ',F,0,0}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',F,0,2}, - - {'É',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,2}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',L|F,3,10}, - {'Ä',0,1,5}, - {'Ì',F,0,5}, - {'Ý',L|F,2,0}, - {'Ö',F,0,7}, - {'Þ',F,0,0}, - - {'Ö',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',L,6,64}, - {'Î',L,3,40}, - {'Ä',F,1,0}, - {'É',F,0,8}, - {'Ï',F,1,44}, - {'Ó',F,0,48}, - {'Ú',L|F,3,0}, - {'×',0,1,64}, - {'Ø',F,0,67}, - {'Û',0,1,69}, - {'Þ',0,0,74}, - - {'Ô',L,2,23}, - {'Î',F,0,3}, - {'Ú',0,1,25}, - {'Þ',0,0,25}, - - {'Ö',L|F,3,0}, - {'Î',0,1,4}, - {'Ô',0,0,7}, - {'Ø',F,1,8}, - {'Þ',0,0,8}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'Å',L,2,5}, - {'Á',F,0,2}, - {'É',F,0,0}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Ö',0,0,1}, - - {'Õ',F,0,0}, - - {'×',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ê',L,2,8}, - {'Å',0,0,2}, - {'×',0,0,7}, - - {'Þ',0,0,1}, - - {'É',F,0,1}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,1}, - - {'Ø',F,0,0}, - - {'Ï',L|F,2,0}, - {'Á',F,0,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Á',F,1,0}, - {'Ï',0,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ì',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,1,2}, - {'Ú',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Õ',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ï',F,0,11}, - - {'Ë',F,0,0}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,2}, - - {'Ò',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'É',L|F,4,60}, - {'Å',L|F,2,43}, - {'Á',F,0,5}, - {'Ç',F,0,52}, - {'Ñ',L|F,2,0}, - {'Ë',F,0,66}, - {'Õ',F,0,71}, - - {'Ô',L,4,15}, - {'Ë',L|F,2,7}, - {'È',F,0,0}, - {'Ò',0,0,11}, - {'Ö',L,2,13}, - {'Õ',0,0,11}, - {'×',0,1,12}, - {'Þ',F,0,0}, - - {'Ø',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',F,0,0}, - - {'Ú',F,0,0}, - - {'Ï',L|F,2,4}, - {'É',F,0,2}, - {'Ù',F,0,14}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ä',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,6}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ö',L,3,7}, - {'Ä',F,1,0}, - {'Ô',F,0,3}, - {'×',0,1,5}, - {'Û',0,0,6}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Õ',F,0,0}, - - {'Ø',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',F,0,1}, - - {'Ë',L|F,2,4}, - {'Ç',F,0,0}, - {'Ô',0,1,7}, - {'Þ',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ñ',L|F,3,453}, - {'Á',F,1,4}, - {'É',F,0,269}, - {'Ø',F,1,0}, - {'Ù',F,0,566}, - - {'Î',L|F,9,173}, - {'Ç',L|F,4,50}, - {'Ã',L|F,2,16}, - {'Â',F,0,14}, - {'Ä',F,0,46}, - {'Ë',L|F,2,59}, - {'È',0,0,53}, - {'Ì',0,1,143}, - {'Í',0,0,154}, - {'Ö',L|F,4,225}, - {'Ó',L,2,203}, - {'Ò',0,0,186}, - {'Ô',F,0,202}, - {'Ú',L,2,244}, - {'×',0,0,222}, - {'Ý',F,1,243}, - {'Þ',F,0,246}, - - {'Ø',F,0,0}, - - {'Ê',L,2,28}, - {'É',F,0,2}, - {'Î',0,0,27}, - - {'Î',F,1,2}, - {'Þ',0,0,22}, - - {'Ø',L|F,2,5}, - {'Ô',0,0,2}, - {'Þ',0,0,12}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,0,1}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Ú',F,0,0}, - - {'Ï',0,1,2}, - {'Ñ',0,0,5}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'É',0,1,2}, - {'Õ',F,0,0}, - - {'Ò',0,0,1}, - - {'Á',F,1,0}, - {'Ï',F,0,0}, - - {'Ô',L,6,50}, - {'Î',L,3,40}, - {'Ä',F,1,0}, - {'É',F,0,8}, - {'Ï',F,1,41}, - {'Ó',F,0,43}, - {'Ú',L|F,3,0}, - {'×',0,1,50}, - {'Ø',F,0,53}, - {'Û',0,1,55}, - {'Þ',0,0,60}, - - {'Ô',L,2,23}, - {'Î',F,0,3}, - {'Ú',0,1,25}, - {'Þ',0,0,25}, - - {'Ö',L|F,3,0}, - {'Î',0,1,4}, - {'Ô',0,0,7}, - {'Ø',F,1,8}, - {'Þ',0,0,8}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'Á',F,1,2}, - {'É',F,0,0}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Î',0,1,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Ê',0,0,1}, - - {'É',F,0,0}, - - {'Ï',L|F,2,0}, - {'Á',F,0,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Á',F,1,0}, - {'Ï',0,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ì',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,1,2}, - {'Ú',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Õ',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ï',F,0,11}, - - {'Ë',F,0,0}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,2}, - - {'Ò',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',F,0,0}, - - {'Ò',L,3,5}, - {'È',F,1,0}, - {'Ë',F,0,0}, - {'Õ',0,1,3}, - {'Ö',0,0,3}, - - {'É',F,0,0}, - - {'Ô',F,0,0}, - - {'Ú',F,0,0}, - - {'Å',L|F,2,3}, - {'£',F,0,0}, - {'É',0,0,7}, - - {'Ñ',0,1,2}, - {'Õ',F,0,0}, - - {'Ì',0,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ä',0,0,1}, - - {'Á',F,0,0}, - - {'Å',L|F,3,15}, - {'Á',F,1,5}, - {'Â',0,0,10}, - {'Ô',L,2,19}, - {'Ç',F,0,0}, - {'Þ',F,0,0}, - - {'Ò',L|F,2,4}, - {'Ë',F,0,0}, - {'×',F,1,0}, - {'Þ',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,6}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,1,2}, - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L,4,11}, - {'Á',L|F,2,7}, - {'£',F,0,0}, - {'Å',F,0,0}, - {'Ï',L|F,2,12}, - {'Î',0,0,10}, - {'Ó',0,1,11}, - {'Ù',F,0,0}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ë',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Å',L|F,2,0}, - {'Á',F,0,0}, - {'É',F,0,0}, - - {'Á',0,0,1}, - - {'Î',F,0,0}, - - {'É',L|F,2,5}, - {'Á',F,0,3}, - {'Ï',F,1,0}, - {'Ô',0,0,3}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ó',0,0,1}, - - {'Å',F,1,2}, - {'Ø',0,0,8}, - - {'Û',F,1,0}, - {'Þ',0,0,1}, - - {'É',0,0,1}, - - {'Î',F,0,1}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',0,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,1,0}, - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ø',L,4,86}, - {'Ë',L|F,2,7}, - {'Ä',0,0,5}, - {'Î',F,0,68}, - {'Ý',L,2,128}, - {'Û',F,0,83}, - {'Þ',F,0,173}, - - {'Á',F,0,0}, - - {'Ó',L|F,4,17}, - {'Î',L,2,10}, - {'Ã',0,0,5}, - {'Ï',F,0,9}, - {'Ø',L,2,57}, - {'×',0,0,55}, - {'Ú',F,0,0}, - - {'É',0,0,1}, - - {'Î',0,0,1}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'É',F,0,0}, - - {'×',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ê',L,3,25}, - {'Ä',F,1,0}, - {'Å',F,0,4}, - {'×',L,2,25}, - {'Ô',0,0,22}, - {'Ú',0,0,37}, - - {'Û',0,1,2}, - {'Þ',F,0,2}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Î',L,2,8}, - {'Ç',0,0,2}, - {'Ô',F,0,8}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'Á',F,1,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'£',F,1,0}, - {'Å',F,0,0}, - - {'Å',L|F,2,6}, - {'£',F,0,2}, - {'Ï',F,0,9}, - - {'Ø',0,0,1}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',0,1,2}, - {'Ø',F,0,2}, - - {'Õ',F,0,0}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ë',0,1,2}, - {'Ø',F,0,0}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',L,3,10}, - {'Ç',F,1,0}, - {'Î',0,0,4}, - {'Û',L,2,10}, - {'Ø',F,0,8}, - {'Þ',F,0,0}, - - {'£',F,1,2}, - {'Å',F,0,2}, - - {'Ì',F,0,0}, - - {'Ì',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Û',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',L,2,8}, - {'Ê',0,0,2}, - {'×',F,0,7}, - - {'Á',F,1,2}, - {'Å',F,0,3}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ô',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,20}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',0,0,20}, - - {'Ò',L,3,11}, - {'Ä',0,1,4}, - {'Ë',F,0,4}, - {'×',0,1,9}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,1,2}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Î',F,0,1}, - - {'Ë',L|F,2,4}, - {'Ç',F,0,0}, - {'Ô',0,1,7}, - {'Þ',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,44}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,25}, - {'Õ',F,0,28}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,17}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Î',L,5,85}, - {'É',L|F,2,15}, - {'Á',F,0,8}, - {'Ë',0,1,66}, - {'Ì',F,0,69}, - {'Ô',L|F,3,92}, - {'Ò',0,1,89}, - {'Ó',0,0,89}, - {'×',0,1,108}, - {'Ø',F,0,0}, - - {'Ë',L|F,2,0}, - {'Ç',F,0,3}, - {'Ò',0,1,3}, - {'Ý',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ã',L,2,7}, - {'Â',0,0,3}, - {'Î',F,1,19}, - {'Ô',F,0,43}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Î',0,0,12}, - - {'Ò',L,2,4}, - {'Ë',F,0,2}, - {'Ú',0,0,3}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,11}, - {'Þ',F,0,0}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',F,0,2}, - - {'É',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,2}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',L|F,3,10}, - {'Ä',0,1,5}, - {'Ì',F,0,5}, - {'Ý',L|F,2,0}, - {'Ö',F,0,7}, - {'Þ',F,0,0}, - - {'Ö',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ó',0,0,1}, - - {'×',0,0,1}, - - {'Ï',F,0,1}, - - {'Ø',F,0,0}, - - {'Å',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,6}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',F,1,2}, - {'Ø',F,0,8}, - - {'Ö',L|F,3,6}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Ì',F,0,0}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ó',L|F,2,8}, - {'Á',F,0,2}, - {'Ù',F,0,0}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Å',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,0,1}, - - {'Î',F,1,2}, - {'Ú',F,0,0}, - - {'Î',0,0,1}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Í',L,3,13}, - {'Ë',0,1,5}, - {'Ì',F,0,0}, - {'Ô',L,2,177}, - {'Î',F,0,59}, - {'×',0,0,180}, - - {'Ó',0,0,1}, - - {'×',0,0,1}, - - {'Å',L|F,2,3}, - {'£',F,0,0}, - {'Ï',F,0,2}, - - {'Ø',F,0,0}, - - {'Ø',F,0,0}, - - {'Å',L|F,2,9}, - {'£',F,0,2}, - {'É',F,0,45}, - - {'Á',F,0,1}, - - {'Ë',L|F,2,0}, - {'Ç',0,0,2}, - {'Ò',0,0,2}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ñ',L,2,22}, - {'Á',F,0,2}, - {'Õ',F,0,24}, - - {'Ô',L,4,10}, - {'Ë',L|F,2,0}, - {'Ç',F,0,6}, - {'Ò',0,0,6}, - {'Û',L,2,14}, - {'×',0,0,6}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ù',F,0,3}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',F,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ò',L,6,62}, - {'Å',L|F,3,13}, - {'Â',0,1,9}, - {'Ä',F,0,0}, - {'Ç',F,1,0}, - {'Î',0,0,18}, - {'×',L,3,67}, - {'Ô',0,1,59}, - {'Ö',F,0,0}, - {'Ø',F,1,70}, - {'Þ',F,0,89}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',L|F,2,5}, - {'£',F,0,3}, - {'Å',F,1,21}, - {'Ï',F,0,32}, - - {'Ì',F,0,0}, - - {'Ò',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',0,1,2}, - {'×',F,0,2}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'×',L,3,9}, - {'Ì',F,1,5}, - {'Ö',0,0,6}, - {'Ý',L|F,2,0}, - {'Û',0,0,7}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Ã',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ô',0,0,1}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,0}, - {'Î',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Å',F,0,0}, - - {'É',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ì',F,0,1}, - - {'Á',F,1,2}, - {'Å',F,0,8}, - - {'Î',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',F,1,2}, - {'Õ',0,0,3}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,4}, - - {'Ë',F,1,0}, - {'×',0,0,1}, - - {'Ï',F,0,0}, - - {'Ì',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,12}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,1,2}, - {'×',0,0,2}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ó',L,2,3}, - {'Ñ',F,0,0}, - {'Ù',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Å',L|F,2,3}, - {'£',F,0,0}, - {'Ï',F,0,2}, - - {'Ø',F,0,0}, - - {'Ë',0,0,1}, - - {'Ó',F,0,1}, - - {'Ê',0,0,1}, - - {'É',F,0,0}, - - {'Å',F,1,2}, - {'Ø',F,0,8}, - - {'Ö',L|F,3,6}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Ì',F,0,0}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ï',L|F,2,9}, - {'Á',F,0,3}, - {'Ó',F,1,8}, - {'Ù',F,0,0}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',F,0,0}, - - {'Å',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,0,1}, - - {'Î',F,1,2}, - {'Ú',F,0,0}, - - {'Î',0,0,1}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',0,0,1}, - - {'Å',F,0,0}, - - {'Á',0,1,2}, - {'Ï',F,0,0}, - - {'Î',F,0,0}, - - {'Ï',F,0,0}, - - {'Û',0,0,1}, - - {'Õ',F,0,0}, - - {'Ò',0,1,2}, - {'×',0,0,15}, - - {'Á',F,1,0}, - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'É',L|F,2,14}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',0,0,15}, - - {'Ë',L|F,2,4}, - {'Ä',0,0,2}, - {'Ò',0,0,7}, - - {'Á',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ô',F,1,2}, - {'Þ',F,0,0}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Î',F,0,1}, - - {'Ë',L|F,3,8}, - {'Â',0,1,4}, - {'Ç',F,0,0}, - {'Ô',0,1,10}, - {'Þ',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'À',0,1,2}, - {'É',F,0,11}, - - {'Á',0,1,2}, - {'Ñ',F,0,5}, - - {'×',0,0,1}, - - {'Ù',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,1,0}, - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Å',L|F,4,43}, - {'À',L|F,2,0}, - {'£',0,0,5}, - {'Á',F,0,29}, - {'Ï',L|F,2,555}, - {'É',F,0,294}, - {'Ù',F,0,887}, - - {'Ì',L,2,9}, - {'É',F,0,3}, - {'Î',0,1,13}, - {'Ô',F,0,20}, - - {'Î',F,1,0}, - {'Ô',F,0,1}, - - {'É',F,1,0}, - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'É',F,0,1}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,1}, - - {'Ö',L|F,3,6}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ò',L,3,6}, - {'Ç',F,1,4}, - {'Ë',F,0,0}, - {'×',0,1,4}, - {'Ý',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,1,2}, - {'É',F,0,2}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ó',L,7,120}, - {'Ë',L,3,67}, - {'Ã',0,1,12}, - {'É',F,0,43}, - {'Î',L|F,2,80}, - {'Ì',F,0,67}, - {'Ò',0,0,113}, - {'Ø',L,4,136}, - {'Ö',L|F,2,132}, - {'Ô',F,0,112}, - {'×',0,0,132}, - {'Ý',L|F,2,193}, - {'Û',F,0,133}, - {'Þ',F,0,239}, - - {'É',F,0,1}, - - {'Î',F,1,2}, - {'Þ',0,0,28}, - - {'Ö',L|F,3,0}, - {'Î',0,1,4}, - {'Ô',0,0,7}, - {'Ø',F,1,8}, - {'Þ',0,0,16}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'Î',L|F,2,0}, - {'Ã',0,0,2}, - {'Ô',F,0,13}, - - {'Á',0,1,2}, - {'Î',0,0,10}, - - {'Ë',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Å',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ó',0,0,1}, - - {'×',0,0,1}, - - {'Ï',F,0,1}, - - {'Ø',F,0,0}, - - {'Å',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,6}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ô',L,4,18}, - {'Ç',L|F,2,0}, - {'Å',F,0,5}, - {'Î',0,0,11}, - {'Û',L,2,17}, - {'Ø',F,0,15}, - {'Þ',F,0,17}, - - {'Ö',L|F,3,6}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'£',F,1,2}, - {'Å',F,0,2}, - - {'Ì',F,0,0}, - - {'Ì',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,1}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ó',L|F,2,8}, - {'Á',F,0,2}, - {'Ù',F,0,0}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Å',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,0,1}, - - {'Î',F,1,2}, - {'Ú',F,0,0}, - - {'Î',0,0,1}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',0,0,1}, - - {'Å',F,0,0}, - - {'Á',0,0,1}, - - {'Î',F,0,0}, - - {'Ï',F,0,0}, - - {'Û',0,0,1}, - - {'Õ',F,0,0}, - - {'Ò',L,2,9}, - {'Ê',0,0,3}, - {'Ó',0,1,21}, - {'×',F,0,21}, - - {'Á',F,1,2}, - {'Å',F,0,3}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ô',F,0,0}, - - {'Á',F,1,0}, - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,20}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',0,0,20}, - - {'Ò',L,3,11}, - {'Ä',0,1,4}, - {'Ë',F,0,4}, - {'×',0,1,9}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,1,2}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Î',F,0,1}, - - {'Ë',L|F,2,4}, - {'Ç',F,0,0}, - {'Ô',0,1,7}, - {'Þ',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',L|F,2,0}, - {'À',F,0,2}, - {'Ñ',F,0,44}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,25}, - {'Õ',F,0,28}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,17}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Á',F,1,0}, - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Í',L,5,92}, - {'Ã',L,2,12}, - {'Â',0,0,8}, - {'É',0,1,16}, - {'Ë',F,0,26}, - {'Û',L|F,3,156}, - {'Î',F,1,90}, - {'Ô',F,0,147}, - {'Ý',0,1,202}, - {'Þ',F,0,248}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Î',0,0,4}, - - {'Ë',F,1,0}, - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Å',F,0,0}, - - {'Ã',0,0,1}, - - {'Á',0,0,1}, - - {'Ë',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ó',L|F,4,17}, - {'Î',L,2,10}, - {'Ã',0,0,5}, - {'Ï',F,0,9}, - {'Ø',L,2,56}, - {'×',0,0,54}, - {'Ú',F,0,0}, - - {'É',0,0,1}, - - {'Î',0,0,1}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'É',F,0,0}, - - {'×',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',L,3,25}, - {'Å',F,1,4}, - {'Ê',0,0,22}, - {'×',0,1,24}, - {'Ú',0,0,37}, - - {'Û',0,1,2}, - {'Þ',F,0,2}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Î',L,2,8}, - {'Ç',0,0,2}, - {'Ô',F,0,8}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'Á',F,1,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'£',F,1,0}, - {'Å',F,0,0}, - - {'Å',L|F,2,6}, - {'£',F,0,2}, - {'Ï',F,0,9}, - - {'Ø',0,0,1}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',0,1,2}, - {'Ø',F,0,2}, - - {'Õ',F,0,0}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ë',0,1,2}, - {'Ø',F,0,0}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Å',0,0,1}, - - {'Õ',0,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Î',L,6,36}, - {'Â',L,3,20}, - {'£',F,1,0}, - {'Á',F,0,9}, - {'Å',F,1,20}, - {'Ç',F,0,0}, - {'Ö',L|F,3,0}, - {'Ò',0,1,33}, - {'Ô',0,0,36}, - {'Ø',L|F,2,48}, - {'×',0,0,41}, - {'Þ',F,0,0}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',F,0,2}, - - {'É',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,2}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',L|F,3,10}, - {'Ä',0,1,5}, - {'Ì',F,0,5}, - {'Ý',L|F,2,0}, - {'Ö',F,0,7}, - {'Þ',F,0,0}, - - {'Ö',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'£',F,1,2}, - {'Å',F,0,2}, - - {'Ì',F,0,0}, - - {'Ì',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ô',0,0,1}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,0}, - {'Î',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Å',F,0,0}, - - {'É',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ì',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ó',L,2,9}, - {'Ê',0,0,3}, - {'Õ',F,1,0}, - {'×',F,0,7}, - - {'Á',F,1,2}, - {'Å',F,0,3}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ô',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,20}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',0,0,20}, - - {'Ò',L,3,11}, - {'Ä',0,1,4}, - {'Ë',F,0,4}, - {'×',0,1,9}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,1,2}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Î',F,0,1}, - - {'Ë',L|F,3,8}, - {'Â',0,1,4}, - {'Ç',F,0,0}, - {'Ô',0,1,10}, - {'Þ',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,44}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,25}, - {'Õ',F,0,28}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,17}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Í',L,7,136}, - {'Ç',L|F,3,14}, - {'Â',F,1,11}, - {'Ä',F,0,11}, - {'Ë',L|F,2,24}, - {'È',0,0,18}, - {'Ì',F,0,126}, - {'Ô',L|F,3,303}, - {'Î',F,1,178}, - {'Ò',0,0,299}, - {'Ú',L,2,323}, - {'×',0,0,314}, - {'Ý',F,0,0}, - - {'Ø',F,0,0}, - - {'Ú',F,0,0}, - - {'Ï',0,1,2}, - {'Ñ',0,0,5}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'É',0,1,2}, - {'Õ',F,0,0}, - - {'Ò',0,0,1}, - - {'Á',F,1,0}, - {'Ï',F,0,0}, - - {'Ô',L,6,68}, - {'Î',L,3,14}, - {'Ã',0,1,9}, - {'Ä',F,0,0}, - {'Ï',F,1,18}, - {'Ó',F,0,20}, - {'Ú',L|F,3,0}, - {'×',0,1,68}, - {'Ø',F,0,71}, - {'Û',0,1,73}, - {'Þ',0,0,78}, - - {'É',0,0,1}, - - {'Î',0,0,1}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'Å',L,2,5}, - {'Á',F,0,2}, - {'É',F,0,0}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Ö',0,0,1}, - - {'Õ',F,0,0}, - - {'Î',0,1,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Ê',L,3,25}, - {'Ä',F,1,0}, - {'Å',F,0,4}, - {'×',L,2,25}, - {'Ô',0,0,22}, - {'Ú',0,0,37}, - - {'Û',0,1,2}, - {'Þ',F,0,2}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Î',L,2,8}, - {'Ç',0,0,2}, - {'Ô',F,0,8}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'Á',F,1,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'£',F,1,0}, - {'Å',F,0,0}, - - {'Å',L|F,2,6}, - {'£',F,0,2}, - {'Ï',F,0,9}, - - {'Ø',0,0,1}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',0,1,2}, - {'Ø',F,0,2}, - - {'Õ',F,0,0}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ë',0,1,2}, - {'Ø',F,0,0}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Ï',L|F,2,0}, - {'Á',F,0,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Á',F,1,0}, - {'Ï',0,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ì',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,1,2}, - {'Ú',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Õ',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ï',F,0,11}, - - {'Ë',F,0,0}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,2}, - - {'Ò',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',0,0,1}, - - {'È',F,1,0}, - {'Ö',0,0,1}, - - {'Ú',F,0,0}, - - {'Å',L|F,2,9}, - {'£',F,0,2}, - {'É',F,0,45}, - - {'Á',F,0,1}, - - {'Ë',L|F,2,0}, - {'Ç',0,0,2}, - {'Ò',0,0,2}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ñ',L,2,22}, - {'Á',F,0,2}, - {'Õ',F,0,24}, - - {'Ô',L,4,10}, - {'Ë',L|F,2,0}, - {'Ç',F,0,6}, - {'Ò',0,0,6}, - {'Û',L,2,14}, - {'×',0,0,6}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ù',F,0,3}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',F,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Î',L,6,28}, - {'Ä',L|F,3,0}, - {'Á',F,1,10}, - {'Â',0,0,13}, - {'Å',F,1,15}, - {'Ç',F,0,0}, - {'Ö',L|F,3,0}, - {'Ò',0,1,60}, - {'Ô',0,0,63}, - {'Ø',L|F,2,75}, - {'×',0,0,68}, - {'Þ',F,0,93}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',F,0,0}, - - {'É',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',L|F,2,5}, - {'£',F,0,3}, - {'Å',F,1,21}, - {'Ï',F,0,32}, - - {'Ì',F,0,0}, - - {'Ò',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',0,1,2}, - {'×',F,0,2}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'×',L,3,9}, - {'Ì',F,1,5}, - {'Ö',0,0,6}, - {'Ý',L|F,2,0}, - {'Û',0,0,7}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Ã',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ô',0,0,1}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,0}, - {'Î',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Å',F,0,0}, - - {'É',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ì',F,0,1}, - - {'Á',F,1,2}, - {'Å',F,0,8}, - - {'Î',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',F,1,2}, - {'Õ',0,0,3}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,4}, - - {'Ë',F,1,0}, - {'×',0,0,1}, - - {'Ï',F,0,0}, - - {'Ì',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,12}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,1,2}, - {'×',0,0,2}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,1,0}, - {'Õ',F,0,0}, - - {'Ï',L|F,4,12}, - {'É',L,2,9}, - {'Á',F,0,5}, - {'Î',0,0,8}, - {'Ó',L,2,9}, - {'Ñ',F,0,0}, - {'Ù',F,0,0}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ë',F,0,0}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Å',L|F,3,6}, - {'£',F,1,0}, - {'Á',F,0,3}, - {'É',F,1,4}, - {'Ï',F,0,0}, - - {'Ë',F,0,0}, - - {'Ø',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Í',L,3,13}, - {'Ë',0,1,5}, - {'Ì',F,0,0}, - {'Ô',L,2,177}, - {'Î',F,0,59}, - {'×',0,0,180}, - - {'Ó',0,0,1}, - - {'×',0,0,1}, - - {'Å',L|F,2,3}, - {'£',F,0,0}, - {'Ï',F,0,2}, - - {'Ø',F,0,0}, - - {'Ø',F,0,0}, - - {'Å',L|F,2,9}, - {'£',F,0,2}, - {'É',F,0,45}, - - {'Á',F,0,1}, - - {'Ë',L|F,2,0}, - {'Ç',0,0,2}, - {'Ò',0,0,2}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ñ',L,2,22}, - {'Á',F,0,2}, - {'Õ',F,0,24}, - - {'Ô',L,4,10}, - {'Ë',L|F,2,0}, - {'Ç',F,0,6}, - {'Ò',0,0,6}, - {'Û',L,2,14}, - {'×',0,0,6}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ù',F,0,3}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',F,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ò',L,6,62}, - {'Å',L|F,3,13}, - {'Â',0,1,9}, - {'Ä',F,0,0}, - {'Ç',F,1,0}, - {'Î',0,0,18}, - {'×',L,3,67}, - {'Ô',0,1,59}, - {'Ö',F,0,0}, - {'Ø',F,1,70}, - {'Þ',F,0,89}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',L|F,2,5}, - {'£',F,0,3}, - {'Å',F,1,21}, - {'Ï',F,0,32}, - - {'Ì',F,0,0}, - - {'Ò',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',0,1,2}, - {'×',F,0,2}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'×',L,3,9}, - {'Ì',F,1,5}, - {'Ö',0,0,6}, - {'Ý',L|F,2,0}, - {'Û',0,0,7}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Ã',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ô',0,0,1}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,0}, - {'Î',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Å',F,0,0}, - - {'É',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ì',F,0,1}, - - {'Á',F,1,2}, - {'Å',F,0,8}, - - {'Î',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',F,1,2}, - {'Õ',0,0,3}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,4}, - - {'Ë',F,1,0}, - {'×',0,0,1}, - - {'Ï',F,0,0}, - - {'Ì',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,12}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,1,2}, - {'×',0,0,2}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ó',L,2,3}, - {'Ñ',F,0,0}, - {'Ù',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Å',L|F,2,0}, - {'£',F,0,0}, - {'Ï',F,0,1}, - - {'Ë',0,0,1}, - - {'Ó',F,0,1}, - - {'Ê',0,0,1}, - - {'É',F,0,0}, - - {'Î',L,4,56}, - {'Å',L|F,2,8}, - {'£',F,0,6}, - {'É',F,0,23}, - {'Ó',L|F,2,88}, - {'Ï',F,0,52}, - {'Ø',0,1,101}, - {'Ú',F,0,0}, - - {'Ì',F,0,0}, - - {'Û',L,2,3}, - {'Ì',F,0,0}, - {'Þ',0,0,7}, - - {'É',F,0,1}, - - {'Ô',0,1,2}, - {'Ú',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Õ',F,0,0}, - - {'É',0,1,2}, - {'Ï',F,0,4}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Ô',L,2,23}, - {'Î',F,0,3}, - {'Ú',0,1,25}, - {'Þ',0,0,25}, - - {'Ö',L|F,3,0}, - {'Î',0,1,4}, - {'Ô',0,0,7}, - {'Ø',F,1,8}, - {'Þ',0,0,8}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'É',F,0,0}, - - {'Ô',L,3,13}, - {'Ä',F,1,0}, - {'Î',0,0,4}, - {'Ú',L|F,2,0}, - {'×',0,0,17}, - {'Þ',0,0,20}, - - {'Å',L,2,5}, - {'Á',F,0,2}, - {'É',F,0,0}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Ö',0,0,1}, - - {'Õ',F,0,0}, - - {'Ï',L|F,2,0}, - {'Á',F,0,2}, - {'Ó',0,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Á',F,1,0}, - {'Ï',0,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Á',F,1,2}, - {'É',F,0,2}, - - {'Ë',F,0,0}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ê',0,1,2}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Å',L|F,2,6}, - {'£',F,0,2}, - {'Ï',F,0,9}, - - {'Ø',0,0,1}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',0,1,2}, - {'Ø',F,0,2}, - - {'Õ',F,0,0}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ø',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',L|F,3,42}, - {'Á',F,1,4}, - {'Å',F,0,0}, - {'Ñ',F,1,0}, - {'Õ',F,0,49}, - - {'Ô',L,4,15}, - {'Ë',L|F,2,7}, - {'È',F,0,0}, - {'Ò',0,0,11}, - {'Ö',L,2,13}, - {'Õ',0,0,11}, - {'×',0,1,12}, - {'Þ',F,0,0}, - - {'Ø',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',F,0,0}, - - {'Ú',F,0,0}, - - {'Ï',L|F,2,4}, - {'É',F,0,2}, - {'Ù',F,0,14}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ä',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ö',L,3,7}, - {'Ä',F,1,0}, - {'Ô',F,0,3}, - {'×',0,1,5}, - {'Û',0,0,6}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Õ',F,0,0}, - - {'Î',F,0,1}, - - {'Ë',L|F,2,4}, - {'Ç',F,0,0}, - {'Ô',0,1,7}, - {'Þ',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',L|F,4,598}, - {'Á',L|F,2,64}, - {'£',F,0,5}, - {'Å',F,0,330}, - {'Ñ',L|F,2,1185}, - {'Ï',F,0,789}, - {'Ù',F,0,1300}, - - {'Ï',L|F,6,0}, - {'É',L|F,3,17}, - {'À',F,1,0}, - {'Á',F,0,9}, - {'Ì',F,1,20}, - {'Î',0,0,25}, - {'Õ',L|F,3,0}, - {'Ò',0,1,37}, - {'Ó',0,0,37}, - {'Ø',L|F,2,38}, - {'×',0,0,36}, - {'Ý',F,0,0}, - - {'Ë',L|F,2,0}, - {'Ç',F,0,3}, - {'Ò',0,1,3}, - {'Ý',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Î',F,1,2}, - {'Ô',F,0,2}, - - {'Þ',F,0,0}, - - {'É',F,1,0}, - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'É',F,0,1}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',F,1,2}, - {'Ë',F,0,8}, - - {'Ö',L|F,3,6}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ï',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,1}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,4}, - {'Ô',F,0,5}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Î',L|F,9,176}, - {'Ç',L|F,4,50}, - {'Ã',L|F,2,16}, - {'Â',F,0,14}, - {'Ä',F,0,46}, - {'Ë',L|F,2,59}, - {'È',0,0,53}, - {'Ì',0,1,146}, - {'Í',0,0,157}, - {'Ö',L|F,4,227}, - {'Ó',L,2,206}, - {'Ò',0,0,189}, - {'Ô',F,0,205}, - {'Ú',L,2,246}, - {'×',0,0,224}, - {'Ý',F,1,245}, - {'Þ',F,0,248}, - - {'Ø',F,0,0}, - - {'Ê',L,2,28}, - {'É',F,0,2}, - {'Î',0,0,27}, - - {'Î',F,1,2}, - {'Þ',0,0,22}, - - {'Ø',L|F,2,5}, - {'Ô',0,0,2}, - {'Þ',0,0,12}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,0,1}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Ú',F,0,0}, - - {'Ï',0,1,2}, - {'Ñ',0,0,5}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'É',0,1,2}, - {'Õ',F,0,0}, - - {'Ò',0,0,1}, - - {'Á',F,1,0}, - {'Ï',F,0,0}, - - {'Ô',L,6,53}, - {'Î',L,3,40}, - {'Ä',F,1,0}, - {'É',F,0,8}, - {'Ï',F,1,44}, - {'Ó',F,0,46}, - {'Ú',L|F,3,0}, - {'×',0,1,53}, - {'Ø',F,0,56}, - {'Û',0,1,58}, - {'Þ',0,0,63}, - - {'Ô',L,2,23}, - {'Î',F,0,3}, - {'Ú',0,1,25}, - {'Þ',0,0,25}, - - {'Ö',L|F,3,0}, - {'Î',0,1,4}, - {'Ô',0,0,7}, - {'Ø',F,1,8}, - {'Þ',0,0,8}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'Å',L,2,5}, - {'Á',F,0,2}, - {'É',F,0,0}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Ö',0,0,1}, - - {'Õ',F,0,0}, - - {'Î',0,1,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Ê',0,0,1}, - - {'É',F,0,0}, - - {'Ï',L|F,2,0}, - {'Á',F,0,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Á',F,1,0}, - {'Ï',0,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ì',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,1,2}, - {'Ú',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Õ',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ï',F,0,11}, - - {'Ë',F,0,0}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,2}, - - {'Ò',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',F,0,0}, - - {'Ò',L,3,5}, - {'È',F,1,0}, - {'Ë',F,0,0}, - {'Õ',0,1,3}, - {'Ö',0,0,3}, - - {'É',F,0,0}, - - {'Ô',F,0,0}, - - {'Ú',F,0,0}, - - {'Å',L|F,2,3}, - {'£',F,0,0}, - {'É',0,0,7}, - - {'Ñ',0,1,2}, - {'Õ',F,0,0}, - - {'Ì',0,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ä',0,0,1}, - - {'Á',F,0,0}, - - {'Å',L|F,3,15}, - {'Á',F,1,5}, - {'Â',0,0,10}, - {'Ô',L,2,19}, - {'Ç',F,0,0}, - {'Þ',F,0,0}, - - {'Ò',L|F,2,4}, - {'Ë',F,0,0}, - {'×',F,1,0}, - {'Þ',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,6}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,1,2}, - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L,4,10}, - {'Á',L|F,2,6}, - {'£',F,0,0}, - {'Å',F,0,0}, - {'Ï',L|F,2,11}, - {'Î',0,0,9}, - {'Ó',0,0,10}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ë',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Å',L|F,2,0}, - {'Á',F,0,0}, - {'É',F,0,0}, - - {'Á',0,0,1}, - - {'Î',F,0,0}, - - {'É',L|F,2,5}, - {'Á',F,0,3}, - {'Ï',F,1,0}, - {'Ô',0,0,3}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ó',0,0,1}, - - {'Å',F,1,2}, - {'Ø',0,0,8}, - - {'Û',F,1,0}, - {'Þ',0,0,1}, - - {'É',0,0,1}, - - {'Î',F,0,1}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',0,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,1,0}, - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ò',L,9,133}, - {'É',L|F,4,48}, - {'Á',L|F,2,15}, - {'À',F,0,0}, - {'Ã',0,0,38}, - {'Î',L|F,2,95}, - {'Ì',F,0,82}, - {'Ï',F,1,0}, - {'Ñ',F,0,121}, - {'×',L,4,140}, - {'Õ',L|F,2,125}, - {'Ó',0,0,123}, - {'Ö',0,0,135}, - {'Û',L|F,2,150}, - {'Ø',F,0,136}, - {'Ý',F,1,196}, - {'Þ',F,0,246}, - - {'Ô',L,4,15}, - {'Ë',L|F,2,8}, - {'Ç',F,0,5}, - {'Ò',0,0,11}, - {'Û',L,2,20}, - {'×',0,0,11}, - {'Ý',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ù',F,0,3}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ä',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ê',0,1,2}, - {'Î',0,0,2}, - - {'É',F,0,0}, - - {'Á',F,1,2}, - {'Å',F,0,0}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Ã',L,2,7}, - {'Â',0,0,3}, - {'Î',F,1,9}, - {'Ô',F,0,33}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,11}, - {'Þ',F,0,0}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',F,0,2}, - - {'É',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,2}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',L|F,3,10}, - {'Ä',0,1,5}, - {'Ì',F,0,5}, - {'Ý',L|F,2,0}, - {'Ö',F,0,7}, - {'Þ',F,0,0}, - - {'Ö',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'É',F,1,0}, - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,6}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Î',L,4,20}, - {'Ç',L|F,2,0}, - {'Å',F,0,6}, - {'Ë',F,0,12}, - {'Ø',L|F,2,22}, - {'Ô',0,0,19}, - {'Û',0,1,21}, - {'Þ',F,0,0}, - - {'Ö',L|F,3,6}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'£',F,1,2}, - {'Å',F,0,2}, - - {'Ì',F,0,0}, - - {'Ì',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ò',F,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',0,0,1}, - - {'Î',F,0,0}, - - {'Ï',F,0,0}, - - {'Î',0,1,2}, - {'Û',0,0,11}, - - {'Å',F,0,1}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,4}, - {'Ô',F,0,5}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Õ',F,0,0}, - - {'Ó',L,2,8}, - {'Ê',0,0,2}, - {'×',F,0,7}, - - {'Á',F,1,2}, - {'Å',F,0,3}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ô',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,20}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',0,0,20}, - - {'Ò',L,3,11}, - {'Ä',0,1,4}, - {'Ë',F,0,4}, - {'×',0,1,9}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,1,2}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Î',F,0,1}, - - {'Ë',L|F,3,8}, - {'Â',0,1,4}, - {'Ç',F,0,0}, - {'Ô',0,1,10}, - {'Þ',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',L,2,46}, - {'À',F,0,2}, - {'Ñ',F,0,47}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,25}, - {'Õ',F,0,28}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,17}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ö',L,6,92}, - {'Ì',L|F,3,0}, - {'Ä',F,1,9}, - {'Ë',F,0,9}, - {'Î',F,1,71}, - {'Ô',F,0,85}, - {'Û',L|F,3,91}, - {'×',0,1,86}, - {'Ø',0,0,87}, - {'Ý',0,1,137}, - {'Þ',F,0,183}, - - {'Á',F,0,0}, - - {'Ó',L|F,4,17}, - {'Î',L,2,10}, - {'Ã',0,0,5}, - {'Ï',F,0,9}, - {'Ø',L,2,57}, - {'×',0,0,55}, - {'Ú',F,0,0}, - - {'É',0,0,1}, - - {'Î',0,0,1}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'É',F,0,0}, - - {'×',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ê',L,3,25}, - {'Ä',F,1,0}, - {'Å',F,0,4}, - {'×',L,2,25}, - {'Ô',0,0,22}, - {'Ú',0,0,37}, - - {'Û',0,1,2}, - {'Þ',F,0,2}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Î',L,2,8}, - {'Ç',0,0,2}, - {'Ô',F,0,8}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'Á',F,1,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'£',F,1,0}, - {'Å',F,0,0}, - - {'Å',L|F,2,6}, - {'£',F,0,2}, - {'Ï',F,0,9}, - - {'Ø',0,0,1}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',0,1,2}, - {'Ø',F,0,2}, - - {'Õ',F,0,0}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ë',0,1,2}, - {'Ø',F,0,0}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',L,3,10}, - {'Ç',F,1,0}, - {'Î',0,0,4}, - {'Û',L,2,10}, - {'Ø',F,0,8}, - {'Þ',F,0,0}, - - {'£',F,1,2}, - {'Å',F,0,2}, - - {'Ì',F,0,0}, - - {'Ì',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Û',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',L,2,9}, - {'Ê',0,0,3}, - {'Õ',F,1,0}, - {'×',F,0,7}, - - {'Á',F,1,2}, - {'Å',F,0,3}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ô',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,20}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',0,0,20}, - - {'Ò',L,3,11}, - {'Ä',0,1,4}, - {'Ë',F,0,4}, - {'×',0,1,9}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,1,2}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Î',F,0,1}, - - {'Ë',L|F,3,8}, - {'Â',0,1,4}, - {'Ç',F,0,0}, - {'Ô',0,1,10}, - {'Þ',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,44}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,25}, - {'Õ',F,0,28}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,17}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Í',L,8,139}, - {'Ç',L|F,4,16}, - {'Ã',L|F,2,0}, - {'Â',F,0,0}, - {'Ä',F,0,12}, - {'Ë',L|F,2,18}, - {'È',0,0,16}, - {'Ì',F,0,120}, - {'Ô',L|F,4,328}, - {'Ò',L,2,311}, - {'Î',F,0,181}, - {'Ó',0,0,324}, - {'×',L,2,346}, - {'Ö',F,0,343}, - {'Ú',0,1,371}, - {'Þ',F,0,371}, - - {'Ú',F,0,0}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ó',L|F,5,47}, - {'É',L|F,2,12}, - {'Ã',0,0,7}, - {'Î',0,1,40}, - {'Ï',F,0,40}, - {'Ø',L|F,2,86}, - {'×',0,0,84}, - {'Ú',F,1,0}, - {'Þ',0,0,86}, - - {'É',0,0,1}, - - {'Î',0,0,1}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'Ô',L,2,23}, - {'Î',F,0,3}, - {'Ú',0,1,25}, - {'Þ',0,0,25}, - - {'Ö',L|F,3,0}, - {'Î',0,1,4}, - {'Ô',0,0,7}, - {'Ø',F,1,8}, - {'Þ',0,0,8}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'É',F,0,0}, - - {'Î',0,1,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Ê',L,3,25}, - {'Ä',F,1,0}, - {'Å',F,0,4}, - {'×',L,2,25}, - {'Ô',0,0,22}, - {'Ú',0,0,37}, - - {'Û',0,1,2}, - {'Þ',F,0,2}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Î',L,2,8}, - {'Ç',0,0,2}, - {'Ô',F,0,8}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'Á',F,1,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'£',F,1,0}, - {'Å',F,0,0}, - - {'Å',L|F,2,6}, - {'£',F,0,2}, - {'Ï',F,0,9}, - - {'Ø',0,0,1}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',0,1,2}, - {'Ø',F,0,2}, - - {'Õ',F,0,0}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ë',0,1,2}, - {'Ø',F,0,0}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Á',F,0,0}, - - {'Ì',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ï',F,0,5}, - - {'Ë',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',F,0,0}, - - {'Ò',L,3,5}, - {'È',F,1,0}, - {'Ë',F,0,0}, - {'Õ',0,1,3}, - {'Ö',0,0,3}, - - {'É',F,0,0}, - - {'Ô',F,0,0}, - - {'Ú',F,0,0}, - - {'Å',L|F,2,9}, - {'£',F,0,2}, - {'É',F,0,45}, - - {'Á',F,0,1}, - - {'Ë',L|F,2,0}, - {'Ç',0,0,2}, - {'Ò',0,0,2}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ñ',L,2,22}, - {'Á',F,0,2}, - {'Õ',F,0,24}, - - {'Ô',L,4,10}, - {'Ë',L|F,2,0}, - {'Ç',F,0,6}, - {'Ò',0,0,6}, - {'Û',L,2,14}, - {'×',0,0,6}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ù',F,0,3}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',F,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ä',0,1,2}, - {'Ô',F,0,2}, - - {'Á',F,0,0}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Î',L,7,35}, - {'Ä',L|F,3,0}, - {'Á',F,1,11}, - {'Â',0,0,16}, - {'Ç',L|F,2,0}, - {'Å',F,0,17}, - {'É',F,0,25}, - {'Ö',L|F,3,0}, - {'Ò',0,1,66}, - {'Ô',0,0,69}, - {'Ø',L|F,2,81}, - {'×',0,0,74}, - {'Þ',F,0,99}, - - {'Ò',L|F,2,4}, - {'Ë',F,0,0}, - {'×',F,1,0}, - {'Þ',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Î',0,0,1}, - - {'Á',0,0,1}, - - {'Þ',0,0,1}, - - {'É',F,0,0}, - - {'Á',L|F,2,5}, - {'£',F,0,3}, - {'Å',F,1,21}, - {'Ï',F,0,32}, - - {'Ì',F,0,0}, - - {'Ò',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',0,1,2}, - {'×',F,0,2}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'×',L,3,9}, - {'Ì',F,1,5}, - {'Ö',0,0,6}, - {'Ý',L|F,2,0}, - {'Û',0,0,7}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Ã',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ô',0,0,1}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,0}, - {'Î',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Å',F,0,0}, - - {'É',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ì',F,0,1}, - - {'Á',F,1,2}, - {'Å',F,0,8}, - - {'Î',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',F,1,2}, - {'Õ',0,0,3}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,4}, - - {'Ë',F,1,0}, - {'×',0,0,1}, - - {'Ï',F,0,0}, - - {'Ì',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,12}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,1,2}, - {'×',0,0,2}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Î',L,5,16}, - {'Á',L|F,2,8}, - {'£',F,0,0}, - {'Å',F,1,0}, - {'É',0,0,8}, - {'Ñ',L|F,2,0}, - {'Ï',F,0,11}, - {'Ó',0,1,11}, - {'Ù',F,0,0}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ë',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Á',0,0,1}, - - {'Î',F,0,0}, - - {'Å',L|F,3,0}, - {'£',F,1,0}, - {'Á',F,0,4}, - {'Ï',L|F,2,5}, - {'É',F,0,3}, - {'Ô',0,0,7}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ë',0,0,1}, - - {'Ó',F,0,1}, - - {'Ê',0,0,1}, - - {'É',F,0,0}, - - {'Ó',0,0,1}, - - {'Å',F,1,2}, - {'Ø',0,0,8}, - - {'Û',F,1,0}, - {'Þ',0,0,1}, - - {'É',0,0,1}, - - {'Î',F,0,1}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',0,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Õ',F,0,0}, - - {'É',L,2,3}, - {'Á',F,0,0}, - {'Ï',F,0,5}, - - {'Î',F,0,1}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Î',L,5,85}, - {'É',L|F,2,15}, - {'Á',F,0,8}, - {'Ë',0,1,66}, - {'Ì',F,0,69}, - {'Ô',L|F,3,92}, - {'Ò',0,1,89}, - {'Ó',0,0,89}, - {'×',0,1,108}, - {'Ø',F,0,0}, - - {'Ë',L|F,2,0}, - {'Ç',F,0,3}, - {'Ò',0,1,3}, - {'Ý',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ã',L,2,7}, - {'Â',0,0,3}, - {'Î',F,1,19}, - {'Ô',F,0,43}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Î',0,0,12}, - - {'Ò',L,2,4}, - {'Ë',F,0,2}, - {'Ú',0,0,3}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,11}, - {'Þ',F,0,0}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',F,0,2}, - - {'É',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,2}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',L|F,3,10}, - {'Ä',0,1,5}, - {'Ì',F,0,5}, - {'Ý',L|F,2,0}, - {'Ö',F,0,7}, - {'Þ',F,0,0}, - - {'Ö',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ó',0,0,1}, - - {'×',0,0,1}, - - {'Ï',F,0,1}, - - {'Ø',F,0,0}, - - {'Å',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,6}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',F,1,2}, - {'Ø',F,0,8}, - - {'Ö',L|F,3,6}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Ì',F,0,0}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ó',L|F,2,8}, - {'Á',F,0,2}, - {'Ù',F,0,0}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Å',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,0,1}, - - {'Î',F,1,2}, - {'Ú',F,0,0}, - - {'Î',0,0,1}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Í',L,3,13}, - {'Ë',0,1,5}, - {'Ì',F,0,0}, - {'Ô',L,2,177}, - {'Î',F,0,59}, - {'×',0,0,180}, - - {'Ó',0,0,1}, - - {'×',0,0,1}, - - {'Å',L|F,2,3}, - {'£',F,0,0}, - {'Ï',F,0,2}, - - {'Ø',F,0,0}, - - {'Ø',F,0,0}, - - {'Å',L|F,2,9}, - {'£',F,0,2}, - {'É',F,0,45}, - - {'Á',F,0,1}, - - {'Ë',L|F,2,0}, - {'Ç',0,0,2}, - {'Ò',0,0,2}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ñ',L,2,22}, - {'Á',F,0,2}, - {'Õ',F,0,24}, - - {'Ô',L,4,10}, - {'Ë',L|F,2,0}, - {'Ç',F,0,6}, - {'Ò',0,0,6}, - {'Û',L,2,14}, - {'×',0,0,6}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ù',F,0,3}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',F,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ò',L,6,62}, - {'Å',L|F,3,13}, - {'Â',0,1,9}, - {'Ä',F,0,0}, - {'Ç',F,1,0}, - {'Î',0,0,18}, - {'×',L,3,67}, - {'Ô',0,1,59}, - {'Ö',F,0,0}, - {'Ø',F,1,70}, - {'Þ',F,0,89}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',L|F,2,5}, - {'£',F,0,3}, - {'Å',F,1,21}, - {'Ï',F,0,32}, - - {'Ì',F,0,0}, - - {'Ò',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',0,1,2}, - {'×',F,0,2}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'×',L,3,9}, - {'Ì',F,1,5}, - {'Ö',0,0,6}, - {'Ý',L|F,2,0}, - {'Û',0,0,7}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Ã',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ô',0,0,1}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,0}, - {'Î',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Å',F,0,0}, - - {'É',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ì',F,0,1}, - - {'Á',F,1,2}, - {'Å',F,0,8}, - - {'Î',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',F,1,2}, - {'Õ',0,0,3}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,4}, - - {'Ë',F,1,0}, - {'×',0,0,1}, - - {'Ï',F,0,0}, - - {'Ì',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,12}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,1,2}, - {'×',0,0,2}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ó',L,2,3}, - {'Ñ',F,0,0}, - {'Ù',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Å',L|F,2,3}, - {'£',F,0,0}, - {'Ï',F,0,2}, - - {'Ø',F,0,0}, - - {'Ë',0,0,1}, - - {'Ó',F,0,1}, - - {'Ê',0,0,1}, - - {'É',F,0,0}, - - {'Ç',L|F,4,0}, - {'Â',L,2,15}, - {'Á',F,0,5}, - {'Å',F,0,16}, - {'Ô',L,2,73}, - {'É',F,0,68}, - {'Þ',F,0,0}, - - {'Ô',L,3,6}, - {'Ë',F,1,0}, - {'Ò',F,0,3}, - {'×',F,1,4}, - {'Þ',0,0,4}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ï',F,0,0}, - - {'É',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,4,39}, - {'Î',L,2,23}, - {'Ì',F,0,5}, - {'Ô',F,0,33}, - {'Ý',L|F,2,0}, - {'Û',0,0,35}, - {'Þ',F,0,35}, - - {'Å',L|F,2,7}, - {'Á',F,0,2}, - {'×',0,0,14}, - - {'Î',L|F,2,0}, - {'Ë',F,0,0}, - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,4}, - - {'Ë',F,1,0}, - {'×',0,0,1}, - - {'Ï',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,1,2}, - {'Ï',0,0,5}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'É',F,0,1}, - - {'Ã',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Å',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Õ',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,0}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,0,1}, - - {'Á',0,0,1}, - - {'Þ',0,0,1}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Í',L,8,502}, - {'Ç',L|F,4,17}, - {'Ã',L,2,13}, - {'Â',F,0,0}, - {'Ä',0,0,13}, - {'Ë',L|F,2,417}, - {'È',0,0,415}, - {'Ì',F,0,430}, - {'×',L,4,635}, - {'Ó',L,2,616}, - {'Î',F,0,524}, - {'Ô',F,0,615}, - {'Ý',L|F,2,0}, - {'Ú',0,0,650}, - {'Þ',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ú',F,0,0}, - - {'Å',F,1,2}, - {'Ï',F,0,155}, - - {'Ø',L,4,54}, - {'Í',L,2,10}, - {'Ë',0,0,5}, - {'Î',F,0,17}, - {'Ý',L,2,100}, - {'Û',F,0,51}, - {'Þ',F,0,145}, - - {'Ó',0,0,1}, - - {'Å',0,0,1}, - - {'Û',0,0,1}, - - {'Õ',F,0,0}, - - {'Å',0,0,1}, - - {'Á',0,1,2}, - {'Õ',0,0,5}, - - {'×',0,0,1}, - - {'Ù',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',L,5,20}, - {'Ç',L|F,2,0}, - {'Â',0,0,7}, - {'Î',0,1,9}, - {'Ò',0,0,12}, - {'×',L,2,22}, - {'Ö',F,0,0}, - {'Ø',F,1,26}, - {'Þ',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'£',F,1,2}, - {'Å',F,0,2}, - - {'Ì',F,0,0}, - - {'Ì',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ô',0,0,1}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,0}, - {'Î',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Å',F,0,0}, - - {'É',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ì',F,0,0}, - - {'Û',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',L,2,8}, - {'Ê',0,0,2}, - {'×',F,0,7}, - - {'Á',F,1,2}, - {'Å',F,0,3}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ô',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,20}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',0,0,20}, - - {'Ò',L,3,11}, - {'Ä',0,1,4}, - {'Ë',F,0,4}, - {'×',0,1,9}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,1,2}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Î',F,0,1}, - - {'Ë',L|F,3,8}, - {'Â',0,1,4}, - {'Ç',F,0,0}, - {'Ô',0,1,10}, - {'Þ',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,44}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,25}, - {'Õ',F,0,28}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,17}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Í',L,3,70}, - {'Ë',F,1,5}, - {'Ì',F,0,65}, - {'Ô',L,2,232}, - {'Î',F,0,114}, - {'×',0,0,235}, - - {'Ó',L|F,4,17}, - {'Î',L,2,10}, - {'Ã',0,0,5}, - {'Ï',F,0,9}, - {'Ø',L,2,55}, - {'×',0,0,53}, - {'Ú',F,0,0}, - - {'É',0,0,1}, - - {'Î',0,0,1}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'É',F,0,0}, - - {'×',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ê',L,3,23}, - {'Ä',F,1,0}, - {'Å',F,0,4}, - {'×',L,2,23}, - {'Ô',0,0,20}, - {'Ú',0,0,35}, - - {'Þ',F,0,1}, - - {'É',F,0,1}, - - {'Î',L,2,8}, - {'Ç',0,0,2}, - {'Ô',F,0,8}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'Á',F,1,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'£',F,1,0}, - {'Å',F,0,0}, - - {'Å',L|F,2,6}, - {'£',F,0,2}, - {'Ï',F,0,9}, - - {'Ø',0,0,1}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',0,1,2}, - {'Ø',F,0,2}, - - {'Õ',F,0,0}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ë',0,1,2}, - {'Ø',F,0,0}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Å',L|F,2,9}, - {'£',F,0,2}, - {'É',F,0,43}, - - {'Á',F,0,1}, - - {'Ë',L|F,2,0}, - {'Ç',0,0,2}, - {'Ò',0,0,2}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ñ',L,2,20}, - {'Á',F,0,2}, - {'Õ',F,0,22}, - - {'Ô',L,4,10}, - {'Ë',L|F,2,0}, - {'Ç',F,0,6}, - {'Ò',0,0,6}, - {'Û',L,2,12}, - {'×',0,0,6}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ù',F,0,0}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',F,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ò',L,6,62}, - {'Å',L|F,3,13}, - {'Â',0,1,9}, - {'Ä',F,0,0}, - {'Ç',F,1,0}, - {'Î',0,0,18}, - {'×',L,3,67}, - {'Ô',0,1,59}, - {'Ö',F,0,0}, - {'Ø',F,1,70}, - {'Þ',F,0,89}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',L|F,2,5}, - {'£',F,0,3}, - {'Å',F,1,21}, - {'Ï',F,0,32}, - - {'Ì',F,0,0}, - - {'Ò',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',0,1,2}, - {'×',F,0,2}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'×',L,3,9}, - {'Ì',F,1,5}, - {'Ö',0,0,6}, - {'Ý',L|F,2,0}, - {'Û',0,0,7}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Ã',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ô',0,0,1}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,0}, - {'Î',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Å',F,0,0}, - - {'É',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ì',F,0,1}, - - {'Á',F,1,2}, - {'Å',F,0,8}, - - {'Î',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',F,1,2}, - {'Õ',0,0,3}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,4}, - - {'Ë',F,1,0}, - {'×',0,0,1}, - - {'Ï',F,0,0}, - - {'Ì',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,12}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,1,2}, - {'×',0,0,2}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ó',L,2,3}, - {'Ñ',F,0,0}, - {'Ù',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Å',L|F,2,0}, - {'£',F,0,0}, - {'Ï',F,0,1}, - - {'Ë',0,0,1}, - - {'Ó',F,0,1}, - - {'Ê',0,0,1}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'×',L,3,11}, - {'Î',0,1,4}, - {'Ï',F,0,4}, - {'Ø',F,1,9}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'×',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,0}, - - {'Ì',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',L|F,4,44}, - {'Å',L|F,2,0}, - {'Á',F,0,5}, - {'Ç',F,0,36}, - {'Ñ',L|F,2,0}, - {'Ë',F,0,48}, - {'Õ',F,0,53}, - - {'Ô',L,4,15}, - {'Ë',L|F,2,7}, - {'È',F,0,0}, - {'Ò',0,0,11}, - {'Ö',L,2,13}, - {'Õ',0,0,11}, - {'×',0,1,12}, - {'Þ',F,0,0}, - - {'Ø',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',F,0,0}, - - {'Ú',F,0,0}, - - {'Ï',F,1,2}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',L|F,2,4}, - {'Ä',F,0,0}, - {'Ö',0,1,4}, - {'×',0,0,4}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ø',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',F,0,1}, - - {'Ô',L,2,3}, - {'Ç',F,0,0}, - {'Þ',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'£',F,1,2}, - {'Å',F,0,7}, - - {'Á',F,0,1}, - - {'Ë',L|F,2,0}, - {'Ç',0,0,2}, - {'Ò',0,0,2}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ñ',L,2,19}, - {'Á',F,0,2}, - {'Õ',F,0,21}, - - {'Ò',L,3,7}, - {'Ç',F,1,5}, - {'Ë',F,0,0}, - {'×',L,2,6}, - {'Ô',0,0,4}, - {'Ý',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ù',F,0,3}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',F,0,0}, - - {'Ç',L|F,4,0}, - {'Â',L,2,24}, - {'Á',F,0,6}, - {'Å',F,0,25}, - {'Ô',L,2,47}, - {'Î',0,0,34}, - {'Ø',F,1,47}, - {'Þ',F,0,66}, - - {'Ò',L|F,2,4}, - {'Ë',F,0,0}, - {'Ô',0,1,3}, - {'×',F,0,3}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ò',0,0,1}, - - {'É',0,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,9}, - {'Ì',F,1,5}, - {'Ô',F,0,6}, - {'Ý',L|F,2,0}, - {'Û',0,0,6}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Õ',F,0,0}, - - {'Å',L|F,2,4}, - {'£',F,0,2}, - {'Ï',F,0,6}, - - {'Ì',F,0,0}, - - {'Ì',F,1,0}, - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'É',F,0,1}, - - {'Ã',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,1}, - - {'Á',F,1,2}, - {'Å',F,0,8}, - - {'Î',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',F,1,2}, - {'Õ',0,0,3}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,4}, - - {'Ë',F,1,0}, - {'×',0,0,1}, - - {'Ï',F,0,0}, - - {'Ì',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,12}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,1,2}, - {'×',0,0,2}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ï',F,0,0}, - - {'Î',L,3,13}, - {'Á',F,1,5}, - {'É',0,0,7}, - {'Ó',L,2,12}, - {'Ï',F,0,10}, - {'Ù',F,0,0}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ë',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Å',L|F,2,4}, - {'£',F,0,0}, - {'Ï',F,1,0}, - {'Ô',0,0,2}, - - {'Ø',F,0,0}, - - {'Ó',0,0,1}, - - {'Å',F,1,2}, - {'Ø',0,0,8}, - - {'Û',F,1,0}, - {'Þ',0,0,1}, - - {'É',0,0,1}, - - {'Î',F,0,1}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',0,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Õ',F,0,0}, - - {'Ñ',L|F,5,440}, - {'É',L|F,2,355}, - {'Á',F,0,7}, - {'Ì',F,1,413}, - {'Î',0,0,424}, - {'Ó',L,2,452}, - {'Ò',0,0,450}, - {'×',0,1,1674}, - {'Ø',F,0,1675}, - - {'Ò',L,6,242}, - {'Ì',L|F,3,0}, - {'Ç',F,1,9}, - {'Ë',F,0,9}, - {'Í',0,1,71}, - {'Î',F,0,120}, - {'Û',L|F,3,247}, - {'Ô',0,1,236}, - {'×',0,0,240}, - {'Ý',F,1,288}, - {'Þ',F,0,334}, - - {'Á',F,0,0}, - - {'Ó',L|F,4,17}, - {'Î',L,2,10}, - {'Ã',0,0,5}, - {'Ï',F,0,9}, - {'Ø',L,2,57}, - {'×',0,0,55}, - {'Ú',F,0,0}, - - {'É',0,0,1}, - - {'Î',0,0,1}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'É',F,0,0}, - - {'×',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ê',L,3,25}, - {'Ä',F,1,0}, - {'Å',F,0,4}, - {'×',L,2,25}, - {'Ô',0,0,22}, - {'Ú',0,0,37}, - - {'Û',0,1,2}, - {'Þ',F,0,2}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Î',L,2,8}, - {'Ç',0,0,2}, - {'Ô',F,0,8}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'Á',F,1,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'£',F,1,0}, - {'Å',F,0,0}, - - {'Å',L|F,2,6}, - {'£',F,0,2}, - {'Ï',F,0,9}, - - {'Ø',0,0,1}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',0,1,2}, - {'Ø',F,0,2}, - - {'Õ',F,0,0}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ë',0,1,2}, - {'Ø',F,0,0}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Å',L|F,2,9}, - {'£',F,0,2}, - {'É',F,0,45}, - - {'Á',F,0,1}, - - {'Ë',L|F,2,0}, - {'Ç',0,0,2}, - {'Ò',0,0,2}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ñ',L,2,22}, - {'Á',F,0,2}, - {'Õ',F,0,24}, - - {'Ô',L,4,10}, - {'Ë',L|F,2,0}, - {'Ç',F,0,6}, - {'Ò',0,0,6}, - {'Û',L,2,14}, - {'×',0,0,6}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ù',F,0,3}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',F,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ò',L,6,62}, - {'Å',L|F,3,13}, - {'Â',0,1,9}, - {'Ä',F,0,0}, - {'Ç',F,1,0}, - {'Î',0,0,18}, - {'×',L,3,67}, - {'Ô',0,1,59}, - {'Ö',F,0,0}, - {'Ø',F,1,70}, - {'Þ',F,0,89}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',L|F,2,5}, - {'£',F,0,3}, - {'Å',F,1,21}, - {'Ï',F,0,32}, - - {'Ì',F,0,0}, - - {'Ò',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',0,1,2}, - {'×',F,0,2}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'×',L,3,9}, - {'Ì',F,1,5}, - {'Ö',0,0,6}, - {'Ý',L|F,2,0}, - {'Û',0,0,7}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Ã',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ô',0,0,1}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,0}, - {'Î',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Å',F,0,0}, - - {'É',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ì',F,0,1}, - - {'Á',F,1,2}, - {'Å',F,0,8}, - - {'Î',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',F,1,2}, - {'Õ',0,0,3}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,4}, - - {'Ë',F,1,0}, - {'×',0,0,1}, - - {'Ï',F,0,0}, - - {'Ì',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,12}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,1,2}, - {'×',0,0,2}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ó',L,2,3}, - {'Ñ',F,0,0}, - {'Ù',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'É',L,2,4}, - {'Å',F,0,0}, - {'Ï',F,1,0}, - {'Ù',F,0,0}, - - {'Þ',F,0,0}, - - {'Ó',L,2,8}, - {'Ê',0,0,2}, - {'×',F,0,7}, - - {'Á',F,1,2}, - {'Å',F,0,3}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ô',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,20}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',0,0,20}, - - {'Ò',L,3,11}, - {'Ä',0,1,4}, - {'Ë',F,0,4}, - {'×',0,1,9}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,1,2}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Î',F,0,1}, - - {'Ë',L|F,2,4}, - {'Ç',F,0,0}, - {'Ô',0,1,7}, - {'Þ',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,44}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,25}, - {'Õ',F,0,28}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,17}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ã',L,2,7}, - {'Â',0,0,3}, - {'Î',F,1,19}, - {'Ô',F,0,50}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Î',0,0,12}, - - {'Ò',L,2,4}, - {'Ë',F,0,2}, - {'Ú',0,0,3}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Å',F,0,0}, - - {'Ç',L|F,4,0}, - {'Á',L|F,2,6}, - {'£',F,0,0}, - {'Å',F,0,13}, - {'Û',L,2,26}, - {'Ô',0,0,23}, - {'Þ',F,0,0}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',F,0,2}, - - {'É',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,2}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',L|F,3,10}, - {'Ä',0,1,5}, - {'Ì',F,0,5}, - {'Ý',L|F,2,0}, - {'Ö',F,0,7}, - {'Þ',F,0,0}, - - {'Ö',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Å',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,6}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',F,1,2}, - {'Ø',F,0,10}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Ì',F,0,0}, - - {'Î',F,0,1}, - - {'Ô',L,3,10}, - {'Ç',F,1,0}, - {'Î',0,0,4}, - {'Û',L,2,10}, - {'Ø',F,0,8}, - {'Þ',F,0,0}, - - {'£',F,1,2}, - {'Å',F,0,2}, - - {'Ì',F,0,0}, - - {'Ì',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,0}, - - {'Ì',L|F,7,614}, - {'Å',L,3,115}, - {'À',0,1,12}, - {'Á',0,0,92}, - {'É',L,2,351}, - {'È',0,0,279}, - {'Ê',0,0,459}, - {'Ô',L,4,963}, - {'Ï',L,2,808}, - {'Í',0,0,629}, - {'Ñ',0,0,889}, - {'Ø',L|F,2,1119}, - {'Õ',F,0,1045}, - {'Ý',0,0,1205}, - - {'Ì',L,2,8}, - {'Á',0,0,3}, - {'Ò',0,1,8}, - {'Õ',F,0,8}, - - {'×',0,0,1}, - - {'Ù',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Û',F,1,2}, - {'Ý',0,0,26}, - - {'Ó',L,2,6}, - {'Ê',0,0,2}, - {'×',F,0,5}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,15}, - {'Á',F,0,2}, - {'Ñ',F,0,0}, - - {'Ò',L,3,6}, - {'Ä',0,1,4}, - {'Ë',F,0,0}, - {'×',0,1,4}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ï',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,40}, - - {'Ñ',L|F,2,24}, - {'Á',F,0,2}, - {'Õ',F,0,26}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,15}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Ì',0,1,2}, - {'Ý',0,0,14}, - - {'Á',0,1,2}, - {'É',0,0,9}, - - {'×',0,1,2}, - {'Þ',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ï',0,0,2}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'À',0,0,1}, - - {'Ñ',F,0,1}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',L|F,2,74}, - {'Å',F,0,3}, - {'Ô',0,1,142}, - {'Ý',0,0,159}, - - {'Û',F,1,2}, - {'Ý',0,0,26}, - - {'Ó',L,2,6}, - {'Ê',0,0,2}, - {'×',F,0,5}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,15}, - {'Á',F,0,2}, - {'Ñ',F,0,0}, - - {'Ò',L,3,6}, - {'Ä',0,1,4}, - {'Ë',F,0,0}, - {'×',0,1,4}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ï',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,40}, - - {'Ñ',L|F,2,24}, - {'Á',F,0,2}, - {'Õ',F,0,26}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,15}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Û',F,1,2}, - {'Ý',0,0,26}, - - {'Ó',L,2,6}, - {'Ê',0,0,2}, - {'×',F,0,5}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,15}, - {'Á',F,0,2}, - {'Ñ',F,0,0}, - - {'Ò',L,3,6}, - {'Ä',0,1,4}, - {'Ë',F,0,0}, - {'×',0,1,4}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ï',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,40}, - - {'Ñ',L|F,2,24}, - {'Á',F,0,2}, - {'Õ',F,0,26}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,15}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Å',L|F,2,5}, - {'£',F,0,2}, - {'É',0,0,14}, - - {'Ô',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',L,2,8}, - {'Á',0,0,3}, - {'Õ',0,1,7}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Ù',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'À',0,0,1}, - - {'Ñ',F,0,1}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,1}, - - {'Û',F,1,2}, - {'Ý',0,0,26}, - - {'Ó',L,2,6}, - {'Ê',0,0,2}, - {'×',F,0,5}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,15}, - {'Á',F,0,2}, - {'Ñ',F,0,0}, - - {'Ò',L,3,6}, - {'Ä',0,1,4}, - {'Ë',F,0,0}, - {'×',0,1,4}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ï',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,40}, - - {'Ñ',L|F,2,24}, - {'Á',F,0,2}, - {'Õ',F,0,26}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,15}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Í',L,2,20}, - {'Ì',0,0,3}, - {'Û',0,1,89}, - {'Ý',0,0,101}, - - {'Á',0,1,2}, - {'É',0,0,12}, - - {'×',0,1,2}, - {'Þ',F,0,0}, - - {'É',L|F,2,4}, - {'Å',F,0,0}, - {'Ï',0,1,3}, - {'Ù',0,0,4}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'É',F,0,1}, - - {'Û',F,1,2}, - {'Ý',0,0,26}, - - {'Ó',L,2,6}, - {'Ê',0,0,2}, - {'×',F,0,5}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,15}, - {'Á',F,0,2}, - {'Ñ',F,0,0}, - - {'Ò',L,3,6}, - {'Ä',0,1,4}, - {'Ë',F,0,0}, - {'×',0,1,4}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ï',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,40}, - - {'Ñ',L|F,2,24}, - {'Á',F,0,2}, - {'Õ',F,0,26}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,15}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'×',0,0,1}, - - {'É',L|F,2,8}, - {'Á',F,0,2}, - {'Ñ',F,0,0}, - - {'Ë',L|F,2,0}, - {'Ä',0,0,2}, - {'Ò',0,0,2}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ô',F,1,2}, - {'Þ',F,0,0}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'À',0,0,1}, - - {'Ñ',F,0,1}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Å',L|F,2,9}, - {'Á',F,0,2}, - {'É',F,0,77}, - - {'Ë',L|F,2,0}, - {'Ç',F,0,3}, - {'Ò',0,1,3}, - {'Ý',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Û',F,1,2}, - {'Ý',0,0,26}, - - {'Ó',L,2,6}, - {'Ê',0,0,2}, - {'×',F,0,5}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,15}, - {'Á',F,0,2}, - {'Ñ',F,0,0}, - - {'Ò',L,3,6}, - {'Ä',0,1,4}, - {'Ë',F,0,0}, - {'×',0,1,4}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ï',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,40}, - - {'Ñ',L|F,2,24}, - {'Á',F,0,2}, - {'Õ',F,0,26}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,15}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Û',F,1,2}, - {'Ý',0,0,26}, - - {'Ó',L,2,6}, - {'Ê',0,0,2}, - {'×',F,0,5}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,15}, - {'Á',F,0,2}, - {'Ñ',F,0,0}, - - {'Ò',L,3,6}, - {'Ä',0,1,4}, - {'Ë',F,0,0}, - {'×',0,1,4}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ï',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,40}, - - {'Ñ',L|F,2,24}, - {'Á',F,0,2}, - {'Õ',F,0,26}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,15}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'É',L|F,3,21}, - {'Á',F,1,4}, - {'Å',F,0,0}, - {'Ñ',F,1,0}, - {'Õ',F,0,0}, - - {'Õ',L,3,6}, - {'Ë',F,1,0}, - {'Ò',0,0,3}, - {'×',0,1,4}, - {'Þ',F,0,0}, - - {'É',F,0,0}, - - {'Ô',F,0,0}, - - {'É',L|F,2,4}, - {'Å',F,0,0}, - {'Ï',F,1,3}, - {'Ù',F,0,4}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',L|F,2,5}, - {'£',F,0,2}, - {'É',F,0,100}, - - {'Ï',F,1,0}, - {'Õ',F,0,0}, - - {'Ñ',L|F,4,23}, - {'Ì',L|F,2,0}, - {'Á',F,0,6}, - {'Ï',F,0,0}, - {'Û',L|F,2,25}, - {'Õ',F,0,22}, - {'Ý',0,1,48}, - {'Þ',F,0,0}, - - {'Ë',L|F,3,0}, - {'7',0,1,4}, - {'Ç',F,0,5}, - {'Ò',0,1,6}, - {'×',0,0,6}, - - {'×',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'É',F,1,2}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ó',L,2,6}, - {'Ê',0,0,2}, - {'×',F,0,5}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,15}, - {'Á',F,0,2}, - {'Ñ',F,0,0}, - - {'Ò',L,3,6}, - {'Ä',0,1,4}, - {'Ë',F,0,0}, - {'×',0,1,4}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ï',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,40}, - - {'Ñ',L|F,2,24}, - {'Á',F,0,2}, - {'Õ',F,0,26}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,15}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'×',L,3,7}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Û',F,1,5}, - {'Ý',0,0,29}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Á',F,0,0}, - - {'Ó',L,2,6}, - {'Ê',0,0,2}, - {'×',F,0,5}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,15}, - {'Á',F,0,2}, - {'Ñ',F,0,0}, - - {'Ò',L,3,6}, - {'Ä',0,1,4}, - {'Ë',F,0,0}, - {'×',0,1,4}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ï',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,40}, - - {'Ñ',L|F,2,24}, - {'Á',F,0,2}, - {'Õ',F,0,26}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,15}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Ç',0,1,2}, - {'Ì',0,0,72}, - - {'Å',F,0,1}, - - {'Û',F,1,2}, - {'Ý',0,0,26}, - - {'Ó',L,2,6}, - {'Ê',0,0,2}, - {'×',F,0,5}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,15}, - {'Á',F,0,2}, - {'Ñ',F,0,0}, - - {'Ò',L,3,6}, - {'Ä',0,1,4}, - {'Ë',F,0,0}, - {'×',0,1,4}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ï',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,40}, - - {'Ñ',L|F,2,24}, - {'Á',F,0,2}, - {'Õ',F,0,26}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,15}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Á',0,1,2}, - {'É',0,0,6}, - - {'×',0,1,2}, - {'Þ',F,0,0}, - - {'Ï',0,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Á',0,0,1}, - - {'Û',F,1,2}, - {'Ý',0,0,26}, - - {'Ó',L,2,6}, - {'Ê',0,0,2}, - {'×',F,0,5}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,15}, - {'Á',F,0,2}, - {'Ñ',F,0,0}, - - {'Ò',L,3,6}, - {'Ä',0,1,4}, - {'Ë',F,0,0}, - {'×',0,1,4}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ï',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,40}, - - {'Ñ',L|F,2,24}, - {'Á',F,0,2}, - {'Õ',F,0,26}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,15}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Å',L|F,4,44}, - {'À',L|F,2,10}, - {'£',F,0,5}, - {'Á',F,0,33}, - {'Ñ',L|F,2,77}, - {'É',F,0,69}, - {'Õ',F,0,78}, - - {'Ô',L,2,3}, - {'Ï',F,0,0}, - {'Õ',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',L|F,3,0}, - {'Á',F,1,4}, - {'Ì',F,0,0}, - {'Ñ',F,1,16}, - {'Õ',F,0,19}, - - {'Ò',L,3,7}, - {'Ç',F,1,4}, - {'Ë',F,0,0}, - {'×',0,1,5}, - {'Þ',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',L,3,6}, - {'Ë',F,1,0}, - {'Ò',F,0,3}, - {'×',0,1,4}, - {'Ý',F,0,0}, - - {'É',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Ï',L|F,4,0}, - {'Ì',L|F,2,0}, - {'Á',F,0,6}, - {'Î',0,0,19}, - {'Ô',L,2,23}, - {'Ñ',F,0,18}, - {'Õ',F,1,22}, - {'Þ',F,0,0}, - - {'Ò',L,3,7}, - {'Ç',F,1,4}, - {'Ë',F,0,0}, - {'×',0,1,5}, - {'Þ',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ç',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Å',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ì',L|F,2,0}, - {'Ä',F,0,0}, - {'Ô',F,1,2}, - {'×',0,0,3}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Á',F,0,0}, - - {'Ì',F,1,0}, - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Î',0,1,2}, - {'Þ',F,0,0}, - - {'Ç',F,0,0}, - - {'Í',0,0,1}, - - {'Å',F,1,2}, - {'Ï',F,0,0}, - - {'Û',F,1,2}, - {'Ý',0,0,26}, - - {'Ó',L,2,6}, - {'Ê',0,0,2}, - {'×',F,0,5}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,15}, - {'Á',F,0,2}, - {'Ñ',F,0,0}, - - {'Ò',L,3,6}, - {'Ä',0,1,4}, - {'Ë',F,0,0}, - {'×',0,1,4}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ï',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,40}, - - {'Ñ',L|F,2,24}, - {'Á',F,0,2}, - {'Õ',F,0,26}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,15}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Û',L,2,51}, - {'Ô',F,0,2}, - {'Þ',F,0,0}, - - {'É',L|F,2,36}, - {'Á',F,0,3}, - {'Ñ',F,1,44}, - {'Õ',0,0,44}, - - {'Ô',L,4,9}, - {'Ë',L|F,2,0}, - {'È',F,0,0}, - {'Ò',F,0,5}, - {'×',L,2,7}, - {'Ö',0,0,5}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'É',F,0,0}, - - {'Å',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,5}, - {'Á',F,0,3}, - {'Ï',F,1,4}, - {'Ù',0,0,15}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ä',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',L|F,3,5}, - {'Ä',F,1,0}, - {'Ì',F,0,0}, - {'Ö',0,1,4}, - {'×',0,0,4}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ì',F,0,0}, - - {'Î',F,0,0}, - - {'Å',L|F,2,5}, - {'£',F,0,2}, - {'É',F,0,29}, - - {'Ï',F,1,0}, - {'Õ',F,0,0}, - - {'Ï',L|F,3,0}, - {'Á',F,1,5}, - {'Ì',F,0,0}, - {'Õ',L|F,2,21}, - {'Ñ',F,0,16}, - {'Þ',F,0,0}, - - {'Ò',L,3,7}, - {'Ç',F,1,4}, - {'Ë',F,0,0}, - {'×',0,1,5}, - {'Þ',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',L|F,2,3}, - {'Ì',F,0,0}, - {'×',0,0,3}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Á',F,0,0}, - - {'À',0,0,1}, - - {'Ñ',F,0,1}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,1}, - - {'Þ',F,0,0}, - - {'Û',0,0,1}, - - {'Õ',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,1,2}, - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Î',L,6,158}, - {'Á',L|F,3,70}, - {'£',F,1,9}, - {'À',F,0,23}, - {'Å',F,1,79}, - {'É',F,0,141}, - {'Ó',L,3,158}, - {'Ï',F,1,152}, - {'Ñ',F,0,152}, - {'Õ',F,1,157}, - {'Ù',F,0,0}, - - {'Ô',L,4,13}, - {'Î',L,2,6}, - {'À',F,0,0}, - {'Ï',F,0,0}, - {'×',L,2,10}, - {'Õ',F,0,0}, - {'Ø',F,0,0}, - - {'Ë',F,0,1}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Ì',L|F,3,0}, - {'À',F,1,0}, - {'Á',F,0,4}, - {'Ñ',L|F,2,26}, - {'Ï',F,0,0}, - {'Õ',F,0,28}, - - {'Ô',L,4,15}, - {'Ë',L|F,2,8}, - {'Ç',F,0,5}, - {'Ò',0,0,11}, - {'Û',L,2,18}, - {'×',0,0,11}, - {'Þ',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',F,1,2}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ä',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ö',L,4,9}, - {'Ò',L|F,2,6}, - {'Ë',F,0,0}, - {'Ô',0,0,5}, - {'Û',L,2,7}, - {'×',0,0,5}, - {'Ý',F,0,0}, - - {'É',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Ï',F,0,0}, - - {'Õ',F,0,0}, - - {'Ï',L|F,5,0}, - {'Á',L|F,2,9}, - {'À',F,0,0}, - {'Ì',F,1,0}, - {'Î',F,0,27}, - {'Õ',L|F,3,45}, - {'Ñ',F,1,39}, - {'Ô',0,0,42}, - {'×',0,1,54}, - {'Ø',F,0,0}, - - {'Ò',L,3,13}, - {'Ç',F,1,5}, - {'Ë',F,0,6}, - {'Û',L,2,17}, - {'×',0,0,10}, - {'Þ',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'É',F,1,2}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ä',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ô',L,3,10}, - {'Ç',F,1,0}, - {'Ë',F,0,3}, - {'Û',0,1,9}, - {'Þ',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Å',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',L|F,4,7}, - {'Ë',L|F,2,0}, - {'Ä',F,0,0}, - {'Ì',F,0,0}, - {'×',L,2,6}, - {'Ö',0,0,4}, - {'Û',0,0,5}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Ì',L|F,2,0}, - {'Ä',F,0,0}, - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Î',L|F,2,8}, - {'Ç',F,0,2}, - {'×',0,0,20}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',L,3,10}, - {'Ç',F,1,0}, - {'Ë',F,0,3}, - {'Û',0,1,9}, - {'Þ',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ï',F,0,0}, - - {'Î',L|F,9,562}, - {'Ç',L|F,4,58}, - {'Ã',L|F,2,17}, - {'Â',F,0,15}, - {'Ä',F,0,54}, - {'Ë',L|F,2,67}, - {'È',0,0,61}, - {'Ì',0,1,155}, - {'Í',0,0,166}, - {'×',L,5,619}, - {'Ó',L,2,595}, - {'Ò',0,0,578}, - {'Ô',F,1,594}, - {'Ö',F,0,612}, - {'Û',L,2,639}, - {'Ú',0,0,637}, - {'Ý',F,1,653}, - {'Þ',F,0,653}, - - {'Ø',F,0,0}, - - {'Ê',L,2,34}, - {'É',F,0,2}, - {'Î',0,0,33}, - - {'Î',F,1,2}, - {'Þ',0,0,28}, - - {'Ö',L|F,3,0}, - {'Î',0,1,4}, - {'Ô',0,0,7}, - {'Ø',F,1,8}, - {'Þ',0,0,16}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,1,2}, - {'Å',F,0,0}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Ú',F,0,0}, - - {'Ï',0,1,2}, - {'Ñ',0,0,5}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'É',0,1,2}, - {'Õ',F,0,0}, - - {'Ò',0,0,1}, - - {'Á',F,1,0}, - {'Ï',F,0,0}, - - {'Ô',L,6,56}, - {'Î',L,3,40}, - {'Ä',F,1,0}, - {'É',F,0,8}, - {'Ï',F,1,41}, - {'Ó',F,0,43}, - {'Ú',L|F,3,0}, - {'×',0,1,56}, - {'Ø',F,0,59}, - {'Û',0,1,61}, - {'Þ',0,0,64}, - - {'Ô',L,2,23}, - {'Î',F,0,3}, - {'Ú',0,1,25}, - {'Þ',0,0,25}, - - {'Ö',L|F,3,0}, - {'Î',0,1,4}, - {'Ô',0,0,7}, - {'Ø',F,1,8}, - {'Þ',0,0,8}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'Å',0,1,2}, - {'É',F,0,0}, - - {'Ö',0,0,1}, - - {'Õ',F,0,0}, - - {'Î',0,1,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Ê',0,1,2}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Å',L|F,2,3}, - {'£',F,0,0}, - {'Ï',F,0,2}, - - {'Ø',F,0,0}, - - {'Ø',F,0,0}, - - {'Ï',L|F,2,0}, - {'Á',F,0,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Á',F,1,0}, - {'Ï',0,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ì',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ï',F,0,11}, - - {'Ë',F,0,0}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,2}, - - {'Ò',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',F,0,0}, - - {'Ò',L,3,5}, - {'È',F,1,0}, - {'Ë',F,0,0}, - {'Õ',0,1,3}, - {'Ö',0,0,3}, - - {'É',F,0,0}, - - {'Ô',F,0,0}, - - {'Ú',F,0,0}, - - {'Å',L|F,2,4}, - {'£',F,0,0}, - {'É',0,1,123}, - {'Ï',F,0,124}, - - {'Õ',L|F,4,0}, - {'Î',L|F,2,11}, - {'Ë',0,0,6}, - {'Ñ',0,0,24}, - {'Û',L|F,2,29}, - {'Ø',0,0,26}, - {'Ý',0,1,75}, - {'Þ',F,0,111}, - - {'Ó',0,0,1}, - - {'Å',0,0,1}, - - {'Û',0,0,1}, - - {'Õ',F,0,0}, - - {'Ô',L,3,10}, - {'Ç',F,1,0}, - {'Î',0,0,4}, - {'Û',L,2,10}, - {'Ø',F,0,8}, - {'Þ',F,0,0}, - - {'£',F,1,2}, - {'Å',F,0,2}, - - {'Ì',F,0,0}, - - {'Ì',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ì',0,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Û',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',L,2,8}, - {'Ê',0,0,2}, - {'×',F,0,7}, - - {'Á',F,1,2}, - {'Å',F,0,3}, - - {'Ë',F,1,0}, - {'Ö',F,0,0}, - - {'Ô',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L|F,2,20}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',0,0,20}, - - {'Ò',L,3,11}, - {'Ä',0,1,4}, - {'Ë',F,0,4}, - {'×',0,1,9}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,1,2}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Î',F,0,1}, - - {'Ë',L|F,3,8}, - {'Â',0,1,4}, - {'Ç',F,0,0}, - {'Ô',0,1,10}, - {'Þ',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'À',F,1,2}, - {'Ñ',F,0,34}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,25}, - {'Õ',F,0,28}, - - {'Ô',L,5,14}, - {'Ç',L|F,2,10}, - {'Ä',0,0,8}, - {'Ë',F,1,0}, - {'Ò',0,0,9}, - {'Û',L,3,17}, - {'Ö',0,1,9}, - {'×',0,0,9}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ä',0,0,1}, - - {'Á',F,0,0}, - - {'Î',L|F,4,118}, - {'Ì',L|F,2,0}, - {'Ë',F,0,5}, - {'Í',0,0,65}, - {'×',L,2,236}, - {'Ô',0,0,230}, - {'Ý',0,0,241}, - - {'Ó',L|F,4,17}, - {'Î',L,2,10}, - {'Ã',0,0,5}, - {'Ï',F,0,9}, - {'Ø',L,2,55}, - {'×',0,0,53}, - {'Ú',F,0,0}, - - {'É',0,0,1}, - - {'Î',0,0,1}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'É',F,0,0}, - - {'×',L,2,4}, - {'Î',0,0,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ê',L,3,23}, - {'Ä',F,1,0}, - {'Å',F,0,4}, - {'×',L,2,23}, - {'Ô',0,0,20}, - {'Ú',0,0,35}, - - {'Þ',F,0,1}, - - {'É',F,0,1}, - - {'Î',L,2,8}, - {'Ç',0,0,2}, - {'Ô',F,0,8}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ø',F,0,1}, - - {'Ì',F,0,0}, - - {'Á',F,1,2}, - {'Ó',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'£',F,1,0}, - {'Å',F,0,0}, - - {'Å',L|F,2,6}, - {'£',F,0,2}, - {'Ï',F,0,9}, - - {'Ø',0,0,1}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ó',0,1,2}, - {'Ø',F,0,2}, - - {'Õ',F,0,0}, - - {'Ó',0,0,1}, - - {'Õ',F,0,0}, - - {'Ë',0,1,2}, - {'Ø',F,0,0}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Á',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Å',L|F,2,9}, - {'£',F,0,2}, - {'É',F,0,45}, - - {'Á',F,0,1}, - - {'Ë',L|F,2,0}, - {'Ç',0,0,2}, - {'Ò',0,0,2}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ñ',L,2,22}, - {'Á',F,0,2}, - {'Õ',F,0,24}, - - {'Ô',L,4,10}, - {'Ë',L|F,2,0}, - {'Ç',F,0,6}, - {'Ò',0,0,6}, - {'Û',L,2,14}, - {'×',0,0,6}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ù',F,0,3}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',F,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ò',L,6,62}, - {'Å',L|F,3,13}, - {'Â',0,1,9}, - {'Ä',F,0,0}, - {'Ç',F,1,0}, - {'Î',0,0,18}, - {'×',L,3,67}, - {'Ô',0,1,59}, - {'Ö',F,0,0}, - {'Ø',F,1,70}, - {'Þ',F,0,89}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',L|F,2,5}, - {'£',F,0,3}, - {'Å',F,1,21}, - {'Ï',F,0,32}, - - {'Ì',F,0,0}, - - {'Ò',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',0,1,2}, - {'×',F,0,2}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'×',L,3,9}, - {'Ì',F,1,5}, - {'Ö',0,0,6}, - {'Ý',L|F,2,0}, - {'Û',0,0,7}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Õ',F,0,0}, - - {'É',F,0,1}, - - {'Ã',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ô',0,0,1}, - - {'Å',F,0,0}, - - {'Á',L|F,2,4}, - {'£',F,0,0}, - {'Å',F,1,0}, - {'Î',0,0,3}, - - {'Ë',F,1,0}, - {'Ò',F,0,0}, - - {'Å',F,0,0}, - - {'É',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ì',F,0,1}, - - {'Á',F,1,2}, - {'Å',F,0,8}, - - {'Î',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',F,1,2}, - {'Õ',0,0,3}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,4}, - - {'Ë',F,1,0}, - {'×',0,0,1}, - - {'Ï',F,0,0}, - - {'Ì',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,12}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,1,2}, - {'×',0,0,2}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ó',L,2,3}, - {'Ñ',F,0,0}, - {'Ù',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Å',L|F,2,0}, - {'£',F,0,0}, - {'Ï',F,0,1}, - - {'Ë',0,0,1}, - - {'Ó',F,0,1}, - - {'Ê',0,0,1}, - - {'É',F,0,0}, - - {'À',0,0,1}, - - {'Õ',0,0,1}, - - {'Ò',0,0,1}, - - {'É',0,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'É',L|F,4,16}, - {'Â',L,2,12}, - {'Á',F,0,5}, - {'Ç',F,0,0}, - {'Ô',L,2,21}, - {'Ë',F,0,15}, - {'Þ',F,0,0}, - - {'Ò',L|F,2,4}, - {'Ë',F,0,0}, - {'×',F,1,0}, - {'Þ',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Á',0,0,1}, - - {'Þ',0,0,1}, - - {'É',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,1,2}, - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L,4,11}, - {'Á',L|F,2,7}, - {'£',F,0,0}, - {'Å',F,0,0}, - {'Ï',L|F,2,12}, - {'Î',0,0,10}, - {'Ó',0,1,11}, - {'Ù',F,0,0}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ë',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Á',0,1,2}, - {'Ï',F,0,0}, - - {'Î',F,0,0}, - - {'Å',L|F,3,7}, - {'£',F,1,0}, - {'Á',F,0,4}, - {'Ï',L|F,2,0}, - {'É',F,0,4}, - {'Ô',0,0,4}, - - {'Ë',F,0,0}, - - {'Ø',F,0,0}, - - {'Þ',F,0,0}, - - {'Ó',0,0,1}, - - {'Å',F,1,2}, - {'Ø',0,0,8}, - - {'Û',F,1,0}, - {'Þ',0,0,1}, - - {'É',0,0,1}, - - {'Î',F,0,1}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',0,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Õ',F,0,0}, - - {'Ò',0,1,2}, - {'Õ',F,0,0}, - - {'Á',F,1,0}, - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,1,0}, - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Á',0,0,1}, - - {'Î',F,0,0}, - - {'É',L|F,4,42}, - {'Á',L|F,2,19}, - {'£',F,0,5}, - {'Å',F,0,18}, - {'Ô',L,2,191}, - {'Ï',F,0,43}, - {'Õ',0,0,204}, - - {'Á',F,1,2}, - {'É',F,0,7}, - - {'Ë',L|F,2,0}, - {'Ç',F,0,3}, - {'Ò',0,1,3}, - {'Ý',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Î',F,1,0}, - {'Ô',F,0,1}, - - {'É',F,1,0}, - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ë',F,0,0}, - - {'Ã',L,2,10}, - {'Á',F,0,3}, - {'É',F,1,14}, - {'Ø',F,0,0}, - - {'Ë',L|F,2,0}, - {'Ç',F,0,3}, - {'Ò',0,1,3}, - {'Ý',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ê',0,1,2}, - {'Î',0,0,2}, - - {'É',F,0,0}, - - {'Á',F,0,1}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Î',F,1,0}, - {'Ô',F,0,1}, - - {'É',F,1,0}, - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'×',L,2,5}, - {'Ô',F,0,2}, - {'Þ',F,0,0}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Ì',L,7,84}, - {'Ä',L|F,3,14}, - {'Â',F,1,12}, - {'Ã',F,0,0}, - {'È',L,2,17}, - {'Ç',F,0,11}, - {'Ë',F,0,16}, - {'Ó',L,4,117}, - {'Î',L|F,2,88}, - {'Í',0,0,84}, - {'Ò',0,0,100}, - {'×',L,2,130}, - {'Ô',F,0,113}, - {'Ú',0,0,133}, - - {'Ø',F,0,0}, - - {'Ú',F,0,0}, - - {'Ï',0,0,1}, - - {'Ì',0,0,1}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ó',L|F,4,42}, - {'Î',L,2,37}, - {'É',F,0,6}, - {'Ï',F,0,36}, - {'Ø',L|F,2,41}, - {'×',0,0,39}, - {'Ú',F,1,0}, - {'Þ',0,0,41}, - - {'Ô',L,2,23}, - {'Î',F,0,3}, - {'Ú',0,1,25}, - {'Þ',0,0,25}, - - {'Ö',L|F,3,0}, - {'Î',0,1,4}, - {'Ô',0,0,7}, - {'Ø',F,1,8}, - {'Þ',0,0,8}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'É',F,0,0}, - - {'Î',0,1,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Ê',0,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ì',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ï',F,0,9}, - - {'Ë',F,0,0}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',F,0,0}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'Õ',0,0,2}, - - {'É',F,0,0}, - - {'Ô',F,0,0}, - - {'É',0,0,1}, - - {'Ä',0,0,1}, - - {'Á',F,0,0}, - - {'Ç',L|F,3,0}, - {'Á',F,1,4}, - {'Â',0,0,7}, - {'Ô',0,1,9}, - {'Þ',F,0,0}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',F,0,0}, - - {'É',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,0}, - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Å',L|F,3,0}, - {'£',F,1,0}, - {'Á',F,0,4}, - {'Î',L,2,10}, - {'É',0,0,5}, - {'Ó',0,0,9}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ë',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ï',F,0,0}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Ó',0,0,1}, - - {'Å',F,1,2}, - {'Ø',0,0,8}, - - {'Û',F,1,0}, - {'Þ',0,0,1}, - - {'É',0,0,1}, - - {'Î',F,0,1}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',0,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Î',F,0,1}, - - {'Ë',L|F,3,8}, - {'Â',0,1,4}, - {'Ç',F,0,0}, - {'Ô',0,1,10}, - {'Þ',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ó',L,5,41}, - {'Ì',L|F,2,12}, - {'Ë',0,0,7}, - {'Î',0,1,22}, - {'Ò',0,0,36}, - {'×',L,2,296}, - {'Ô',F,0,225}, - {'Û',0,1,297}, - {'Þ',F,0,0}, - - {'Ó',0,0,1}, - - {'×',0,0,1}, - - {'Ï',F,0,1}, - - {'Ø',F,0,0}, - - {'Å',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,6}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Á',F,1,2}, - {'Å',F,0,5}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'×',F,0,0}, - - {'É',F,0,0}, - - {'Ö',L|F,3,8}, - {'Ì',F,1,0}, - {'Ô',F,0,3}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'Å',F,1,0}, - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',F,0,0}, - - {'É',L|F,4,104}, - {'Á',L|F,2,33}, - {'À',F,0,5}, - {'Å',0,0,57}, - {'Ñ',L|F,2,177}, - {'Ï',F,0,156}, - {'Õ',F,0,183}, - - {'Ï',L|F,3,0}, - {'Á',F,1,4}, - {'Ì',F,0,17}, - {'Ñ',F,1,18}, - {'Õ',F,0,21}, - - {'Ò',L,3,7}, - {'Ç',F,1,4}, - {'Ë',F,0,0}, - {'×',0,1,5}, - {'Þ',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ì',L|F,2,3}, - {'Ë',F,0,0}, - {'Ò',0,0,23}, - - {'É',L|F,3,19}, - {'Á',F,1,4}, - {'Å',F,0,0}, - {'Ñ',F,1,0}, - {'Õ',F,0,0}, - - {'Õ',L,3,6}, - {'Ë',F,1,0}, - {'Ò',0,0,3}, - {'×',0,1,4}, - {'Þ',F,0,0}, - - {'É',F,0,0}, - - {'Ô',F,0,0}, - - {'É',L|F,2,4}, - {'Å',F,0,0}, - {'Ï',F,1,3}, - {'Ù',F,0,0}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ô',0,0,1}, - - {'Å',L|F,2,7}, - {'£',F,0,2}, - {'É',F,0,33}, - - {'Ô',L,2,3}, - {'Ï',F,0,0}, - {'Õ',F,0,0}, - - {'Å',F,0,0}, - - {'Ñ',L|F,4,21}, - {'Ì',L|F,2,0}, - {'Á',F,0,5}, - {'Ï',F,0,0}, - {'Õ',L|F,2,22}, - {'Ô',0,0,20}, - {'Þ',F,0,0}, - - {'Ò',L,3,7}, - {'Ç',F,1,4}, - {'Ë',F,0,0}, - {'×',0,1,5}, - {'Þ',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,3}, - {'Å',F,0,0}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Å',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ì',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',F,1,2}, - {'×',0,0,3}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Á',F,1,0}, - {'Ï',F,0,0}, - - {'Ô',L|F,2,28}, - {'Ì',F,0,3}, - {'×',0,1,28}, - {'Û',0,0,28}, - - {'É',L|F,3,21}, - {'Á',F,1,4}, - {'Å',F,0,0}, - {'Ñ',F,1,0}, - {'Õ',F,0,0}, - - {'Õ',L,3,6}, - {'Ë',F,1,0}, - {'Ò',0,0,3}, - {'×',0,1,4}, - {'Þ',F,0,0}, - - {'É',F,0,0}, - - {'Ô',F,0,0}, - - {'É',L|F,2,4}, - {'Å',F,0,0}, - {'Ï',F,1,3}, - {'Ù',F,0,4}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'×',0,0,1}, - - {'É',L|F,2,14}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',0,0,15}, - - {'Ë',L|F,2,4}, - {'Ä',0,0,2}, - {'Ò',0,0,7}, - - {'Á',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'Ô',F,1,2}, - {'Þ',F,0,0}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Î',0,0,1}, - - {'Ë',F,0,1}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,1}, - - {'É',L|F,3,16}, - {'Á',F,1,4}, - {'Å',F,0,0}, - {'Ñ',F,1,0}, - {'Õ',F,0,0}, - - {'Õ',L,3,6}, - {'Ë',F,1,0}, - {'Ò',0,0,3}, - {'×',0,1,4}, - {'Þ',F,0,0}, - - {'É',F,0,0}, - - {'Ô',F,0,0}, - - {'Ï',F,1,2}, - {'Ù',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,0}, - - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Á',0,1,2}, - {'×',0,0,5}, - - {'×',0,0,1}, - - {'Å',F,1,0}, - {'É',0,0,1}, - - {'Þ',F,0,0}, - - {'É',F,0,1}, - - {'Þ',F,0,0}, - - {'Þ',F,0,0}, - - {'Ñ',L|F,3,53}, - {'Á',F,1,5}, - {'É',F,0,39}, - {'Õ',L,2,61}, - {'Ó',0,0,50}, - {'Ù',F,0,0}, - - {'Ö',L,5,12}, - {'Ë',L|F,2,0}, - {'È',F,0,0}, - {'Ò',F,1,6}, - {'Ô',0,0,6}, - {'Û',L,2,29}, - {'×',0,0,7}, - {'Ý',F,1,0}, - {'Þ',F,0,0}, - - {'É',F,0,0}, - - {'Å',F,1,0}, - {'É',F,0,0}, - - {'Ú',F,0,0}, - - {'É',L|F,2,5}, - {'Á',F,0,3}, - {'Ï',F,1,4}, - {'Ù',F,0,15}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ä',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ô',L|F,3,6}, - {'Ä',F,1,0}, - {'Ì',F,0,0}, - {'×',L,2,6}, - {'Ö',0,0,4}, - {'Û',0,0,6}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Õ',F,0,0}, - - {'Ì',F,0,0}, - - {'Å',F,1,0}, - {'Ï',F,0,1}, - - {'Î',F,1,2}, - {'Ú',F,0,0}, - - {'Î',0,0,1}, - - {'Å',0,0,1}, - - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',0,0,1}, - - {'Å',F,0,0}, - - {'Î',F,0,1}, - - {'Ô',L,2,3}, - {'Ç',F,0,0}, - {'Þ',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ï',F,0,0}, - - {'Ë',F,0,0}, - - {'Å',L|F,2,8}, - {'£',F,0,2}, - {'É',F,0,66}, - - {'Ï',L|F,2,0}, - {'À',F,0,0}, - {'Õ',F,1,0}, - {'×',0,0,1}, - - {'Ï',F,0,0}, - - {'Î',L|F,4,29}, - {'Á',L|F,2,7}, - {'À',F,0,0}, - {'Ì',F,0,0}, - {'Ñ',L|F,2,39}, - {'Ï',F,0,0}, - {'Õ',F,1,41}, - {'×',0,0,52}, - - {'Ò',L,3,13}, - {'Ç',F,1,5}, - {'Ë',F,0,6}, - {'Û',L,2,17}, - {'×',0,0,10}, - {'Þ',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'É',F,0,0}, - - {'É',F,1,2}, - {'Ù',F,0,2}, - - {'Þ',F,0,0}, - - {'Ä',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Õ',F,0,0}, - - {'Ô',L,3,10}, - {'Ç',F,1,0}, - {'Ë',F,0,3}, - {'Û',0,1,9}, - {'Þ',F,0,0}, - - {'Î',0,1,2}, - {'Ø',0,0,2}, - - {'É',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',0,0,1}, - - {'É',F,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ç',F,1,0}, - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ô',L|F,3,6}, - {'Ä',F,1,0}, - {'Ì',F,0,0}, - {'×',L,2,6}, - {'Ö',0,0,4}, - {'Û',0,0,6}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Õ',F,0,0}, - - {'Í',L,6,70}, - {'Ä',L|F,3,45}, - {'Â',F,1,10}, - {'Ã',F,0,10}, - {'Ë',0,1,43}, - {'Ì',0,0,53}, - {'Ó',L,3,208}, - {'Î',F,1,98}, - {'Ò',0,0,190}, - {'×',L,2,225}, - {'Ô',F,0,205}, - {'Ú',0,0,231}, - - {'Ø',F,0,0}, - - {'Ê',L,2,29}, - {'É',F,0,2}, - {'Î',0,0,28}, - - {'Î',F,1,2}, - {'Þ',0,0,23}, - - {'Ö',L|F,2,0}, - {'Ô',0,0,3}, - {'Ø',F,1,4}, - {'Þ',0,0,12}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,1}, - - {'Å',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L,2,3}, - {'Ë',F,0,0}, - {'×',0,0,2}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ô',0,1,2}, - {'×',0,0,3}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ô',0,0,1}, - - {'Ï',F,0,0}, - - {'É',F,0,0}, - - {'Á',F,0,1}, - - {'Ò',F,1,0}, - {'×',F,0,0}, - - {'Ú',F,0,0}, - - {'Ï',F,1,2}, - {'Ó',0,0,4}, - - {'Î',0,1,2}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'×',0,0,1}, - - {'Å',L|F,2,3}, - {'£',F,0,0}, - {'Ï',F,0,2}, - - {'Ø',F,0,0}, - - {'Ø',F,0,0}, - - {'Å',L|F,2,0}, - {'Á',F,0,3}, - {'Ñ',F,1,0}, - {'Õ',F,0,0}, - - {'Ò',L,3,5}, - {'È',F,1,0}, - {'Ë',F,0,0}, - {'Õ',0,1,3}, - {'Ö',0,0,3}, - - {'É',F,0,0}, - - {'Ô',F,0,0}, - - {'Ú',F,0,0}, - - {'Å',L|F,2,9}, - {'£',F,0,2}, - {'É',0,0,31}, - - {'Á',F,0,1}, - - {'Ë',L|F,2,0}, - {'Ç',0,0,2}, - {'Ò',0,0,2}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'Ñ',L,2,19}, - {'Á',F,0,2}, - {'Õ',F,0,21}, - - {'Ò',L,3,7}, - {'Ç',F,1,5}, - {'Ë',F,0,0}, - {'×',L,2,6}, - {'Ô',0,0,4}, - {'Ý',F,0,0}, - - {'Á',F,0,0}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'É',L|F,2,4}, - {'Á',F,0,2}, - {'Ù',F,0,3}, - - {'Ë',F,0,0}, - - {'Þ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ò',F,0,0}, - - {'Ä',0,0,1}, - - {'Á',F,0,0}, - - {'Ç',L|F,4,0}, - {'Â',L,2,26}, - {'Á',F,0,6}, - {'Å',F,0,27}, - {'Ô',L,2,49}, - {'Î',0,0,36}, - {'Ø',F,1,49}, - {'Þ',F,0,68}, - - {'Ô',L,3,6}, - {'Ë',F,1,0}, - {'Ò',F,0,3}, - {'×',F,1,4}, - {'Þ',0,0,14}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Ò',0,0,1}, - - {'É',0,0,1}, - - {'Ã',0,1,2}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'É',F,0,0}, - - {'À',0,0,1}, - - {'Ì',0,0,1}, - - {'Å',F,0,0}, - - {'Ö',L|F,3,9}, - {'Ì',F,1,5}, - {'Ô',F,0,6}, - {'Ý',L|F,2,0}, - {'Û',0,0,6}, - {'Þ',F,0,0}, - - {'×',0,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',F,0,0}, - - {'Õ',F,0,0}, - - {'Å',L|F,2,4}, - {'£',F,0,2}, - {'Ï',F,0,6}, - - {'Ì',F,0,0}, - - {'Ì',F,1,0}, - {'×',0,0,1}, - - {'Ô',0,0,1}, - - {'Ó',F,0,0}, - - {'É',F,0,1}, - - {'Ã',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ì',F,0,1}, - - {'Á',F,1,2}, - {'Å',F,0,8}, - - {'Î',L|F,2,0}, - {'Ë',F,0,0}, - {'Ô',F,1,2}, - {'Õ',0,0,3}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,1,2}, - {'É',F,0,4}, - - {'Ë',F,1,0}, - {'×',0,0,1}, - - {'Ï',F,0,0}, - - {'Ì',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'É',F,1,2}, - {'Ï',F,0,12}, - - {'Î',F,1,2}, - {'Ô',F,0,4}, - - {'Ô',0,0,1}, - - {'Î',0,0,1}, - - {'Å',F,0,0}, - - {'Á',F,1,2}, - {'Ó',F,0,4}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Á',F,0,0}, - - {'Ô',0,1,2}, - {'×',0,0,2}, - - {'Á',F,0,0}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,1,2}, - {'Õ',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',L|F,2,3}, - {'Ë',F,0,0}, - {'Ú',0,0,2}, - - {'É',F,0,0}, - - {'É',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'É',L,4,11}, - {'Á',L|F,2,7}, - {'£',F,0,0}, - {'Å',F,0,0}, - {'Ï',L|F,2,12}, - {'Î',0,0,10}, - {'Ó',0,1,11}, - {'Ù',F,0,0}, - - {'Ë',F,1,0}, - {'Ò',F,0,1}, - - {'É',F,0,0}, - - {'Ë',F,1,0}, - {'Ô',F,0,1}, - - {'Ó',F,0,1}, - - {'Á',F,0,0}, - - {'Å',F,0,0}, - - {'Ô',F,0,0}, - - {'Á',F,1,0}, - {'É',F,0,0}, - - {'Å',L|F,3,6}, - {'£',F,1,0}, - {'Á',F,0,3}, - {'É',F,1,4}, - {'Ï',F,0,0}, - - {'Ë',F,0,0}, - - {'Ø',F,0,0}, - - {'Þ',F,0,0}, - - {'Õ',F,0,0}, - - {'Õ',F,0,0}, - - {'À',0,1,2}, - {'É',F,0,11}, - - {'Á',0,1,2}, - {'Ñ',F,0,5}, - - {'×',0,0,1}, - - {'Ù',0,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0}, - - {'Ì',F,0,1}, - - {'×',0,0,1}, - - {'Á',F,0,1}, - - {'Ë',F,0,0}, - - {'Ô',0,0,1}, - - {'Á',F,0,1}, - - {'Ò',F,0,0}, - - {'Á',F,1,0}, - {'Ï',F,0,1}, - - {'Ô',0,0,1}, - - {'Á',F,0,0} -}; - -static ru_RUKOI8R_NODE ru_RUKOI8R_stoptree[]={ - {'Î',L,11,89}, - {'Ç',L,5,60}, - {'Â',L,2,20}, - {'Á',F,0,0}, - {'Ä',0,1,41}, - {'Å',0,0,46}, - {'Ë',L|F,3,65}, - {'È',0,1,56}, - {'É',F,0,58}, - {'Ì',0,1,70}, - {'Í',0,0,72}, - {'Õ',L|F,6,157}, - {'Ñ',L|F,3,0}, - {'Ï',F,1,89}, - {'Ð',0,0,103}, - {'Ó',F,1,106}, - {'Ô',0,0,106}, - {'Ú',L,3,168}, - {'Ö',0,1,152}, - {'×',F,0,152}, - {'Ü',0,1,170}, - {'Þ',0,0,173}, - - {'Ï',L,2,5}, - {'Å',0,0,3}, - {'Õ',0,1,6}, - {'Ù',F,0,14}, - - {'Ú',F,0,0}, - - {'Ì',0,0,1}, - - {'Å',0,0,1}, - - {'Å',F,0,0}, - - {'Ä',0,0,1}, - - {'Å',0,1,2}, - {'Õ',F,0,6}, - - {'Ô',L|F,2,3}, - {'Í',F,0,0}, - {'Û',0,0,2}, - - {'Å',F,0,0}, - - {'Ø',F,0,0}, - - {'Ô',F,0,0}, - - {'Ì',F,1,2}, - {'Ô',0,0,4}, - - {'É',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,0,0}, - - {'Ø',F,0,0}, - - {'Ì',L,2,5}, - {'Á',F,0,2}, - {'Ï',F,0,0}, - - {'Ö',0,0,1}, - - {'Å',F,0,0}, - - {'Ñ',F,0,0}, - - {'Ç',L,2,4}, - {'Å',F,0,0}, - {'Ó',0,1,3}, - {'Ý',0,0,6}, - - {'Ï',F,0,0}, - - {'Ì',0,1,2}, - {'Ô',0,0,2}, - - {'É',F,0,0}, - - {'Ø',F,0,0}, - - {'Å',F,0,0}, - - {'Ä',0,0,1}, - - {'Å',F,0,0}, - - {'Ï',0,0,1}, - - {'Ô',0,0,1}, - - {'Ñ',F,0,0}, - - {'Ì',L,2,4}, - {'È',F,0,0}, - {'Í',F,1,0}, - {'Ú',F,0,0}, - - {'É',F,0,0}, - - {'Ï',L|F,2,4}, - {'Á',0,0,2}, - {'Ô',0,0,5}, - - {'Ë',F,0,0}, - - {'Ç',0,0,1}, - - {'Ä',0,0,1}, - - {'Á',F,0,0}, - - {'Ï',F,0,0}, - - {'É',F,0,1}, - - {'Â',0,0,1}, - - {'Ï',F,0,0}, - - {'Ï',L,2,4}, - {'Î',0,0,2}, - {'Ù',F,0,0}, - - {'Å',F,0,0}, - - {'Ö',0,0,1}, - - {'Å',0,0,1}, - - {'Ô',F,0,0}, - - {'É',L|F,3,12}, - {'Á',F,1,4}, - {'Å',F,0,6}, - {'Ï',F,1,0}, - {'Õ',F,0,0}, - - {'Ä',0,1,2}, - {'Û',F,0,0}, - - {'Ï',F,0,0}, - - {'Ç',L,2,3}, - {'Å',F,0,0}, - {'Ô',F,0,0}, - - {'Ï',F,0,0}, - - {'È',F,0,0}, - - {'Î',L|F,3,9}, - {'Â',F,1,0}, - {'Ä',0,0,3}, - {'Ô',F,1,0}, - {'Þ',0,0,8}, - - {'Î',0,0,1}, - - {'Á',0,0,1}, - - {'Ë',0,0,1}, - - {'Ï',F,0,0}, - - {'É',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,0,0}, - - {'Å',0,0,1}, - - {'Î',0,0,1}, - - {'Ø',F,0,0}, - - {'Ï',F,1,2}, - {'Ò',0,0,2}, - - {'Ä',F,0,0}, - - {'É',F,0,0}, - - {'Ï',F,0,0}, - - {'Å',L|F,2,25}, - {'Á',0,0,3}, - {'Ï',F,1,34}, - {'Ù',F,0,0}, - - {'Ë',F,1,2}, - {'Í',F,0,0}, - - {'Ï',L,3,10}, - {'Á',0,1,4}, - {'É',0,0,4}, - {'Õ',0,1,14}, - {'Ö',0,0,14}, - - {'Ñ',F,0,0}, - - {'È',L|F,2,0}, - {'Å',F,0,0}, - {'Í',F,0,1}, - - {'É',F,0,0}, - - {'Ç',L,3,5}, - {'À',F,1,0}, - {'Å',F,0,0}, - {'Ê',F,1,0}, - {'Í',F,0,2}, - - {'Ï',F,0,0}, - - {'Õ',F,0,0}, - - {'À',F,0,0}, - - {'Å',F,0,0}, - - {'Í',F,0,1}, - - {'Ï',L,3,8}, - {'Á',F,1,4}, - {'Å',F,0,0}, - {'Õ',F,1,0}, - {'Ù',F,0,0}, - - {'È',F,1,0}, - {'Í',F,0,1}, - - {'É',F,0,0}, - - {'À',F,1,0}, - {'Ê',F,0,0}, - - {'Ì',L,3,6}, - {'Ç',0,1,4}, - {'Ê',F,0,0}, - {'Í',F,1,0}, - {'Ö',0,0,5}, - - {'Ï',F,0,0}, - - {'Ø',0,0,1}, - - {'Ë',0,0,1}, - - {'Ï',F,0,0}, - - {'Å',F,0,0}, - - {'Ö',F,0,1}, - - {'Å',F,0,0}, - - {'Å',F,0,0}, - - {'Ï',L|F,3,9}, - {'Á',0,1,4}, - {'Å',0,0,5}, - {'Ó',0,1,7}, - {'Ù',F,0,0}, - - {'Í',F,1,0}, - {'Ó',F,0,0}, - - {'Ó',0,0,1}, - - {'Ø',F,0,0}, - - {'Ô',F,0,0}, - - {'Å',F,0,1}, - - {'Ç',0,1,2}, - {'È',F,0,0}, - - {'Ï',F,0,0}, - - {'Á',F,1,0}, - {'Ä',0,0,1}, - - {'Å',0,0,1}, - - {'Ó',0,0,1}, - - {'Ø',F,0,0}, - - {'Ô',0,0,1}, - - {'É',L|F,2,0}, - {'Á',F,0,0}, - {'Ï',F,0,0}, - - {'Ô',L,2,7}, - {'Å',0,0,2}, - {'Ø',0,0,8}, - - {'Ê',L|F,2,0}, - {'Ç',0,0,2}, - {'Í',F,0,0}, - - {'Ï',F,0,0}, - - {'Ï',F,0,1}, - - {'Â',0,0,1}, - - {'Ù',F,0,0}, - - {'Å',F,1,0}, - {'Ñ',F,0,0} -}; - -static char* -ru_RUKOI8R_stem( void* obj, char *in, int *len ) { - ru_RUKOI8R_NODE *ptr = ru_RUKOI8R_endstree; - int result = 0; - uint8 *buf = (uint8 *)in; - uint8 *cur = buf + (*len) - 1; - - while( cur - buf >= MINLENREST ) { - *cur = tolower((unsigned char) *cur ); - if ( ptr->val == *cur ) { - if ( ISFINISH(ptr) ) result = buf + (*len) - cur; - cur--; - if ( ! ptr->child ) break; - ptr += ptr->child; - } else if ( ptr->val > *cur ) { - if ( ISLEFT(ptr) ) - ptr++; - else - break; - } else { - if ( ptr->right ) - ptr += ptr->right; - else - break; - } - } - while( cur - buf >= 0 ) { - *cur = tolower((unsigned char) *cur); - cur--; - } - - *len -= result; - return in; -} - -static int -ru_RUKOI8R_is_stopword( void *obj, char *in, int len ) { - ru_RUKOI8R_NODE *ptr = ru_RUKOI8R_stoptree; - int result = 0; - uint8 *buf = (uint8 *)in; - uint8 *cur = buf; - - while( cur - buf < len ) { - *cur = tolower((unsigned char) *cur ); - if ( ptr->val == *cur ) { - cur++; - if ( ISFINISH(ptr) ) result = cur - buf; - if ( ! ptr->child ) break; - ptr += ptr->child; - } else if ( ptr->val > *cur ) { - if ( ISLEFT(ptr) ) - ptr++; - else - break; - } else { - if ( ptr->right ) - ptr += ptr->right; - else - break; - } - } - return (result==len) ? 1 : 0; -} - -#undef L -#undef F -#undef ISLEFT -#undef ISFINISH -#undef MINLENREST -#endif /* DICT_BODY */ - -#ifdef DICT_TABLE -TABLE_DICT_START - "ru_RU.KOI8-R", - NULL, - NULL, - ru_RUKOI8R_stem, - ru_RUKOI8R_is_stopword, - NULL -TABLE_DICT_END -#endif - diff --git a/contrib/tsearch/expected/tsearch.out b/contrib/tsearch/expected/tsearch.out deleted file mode 100644 index f75b429bcb..0000000000 --- a/contrib/tsearch/expected/tsearch.out +++ /dev/null @@ -1,739 +0,0 @@ --- --- first, define the datatype. Turn off echoing so that expected file --- does not depend on contents of seg.sql. --- -\set ECHO none ---txtidx -select '1'::txtidx; - txtidx --------- - '1' -(1 row) - -select '1 '::txtidx; - txtidx --------- - '1' -(1 row) - -select ' 1'::txtidx; - txtidx --------- - '1' -(1 row) - -select ' 1 '::txtidx; - txtidx --------- - '1' -(1 row) - -select '1 2'::txtidx; - txtidx ---------- - '1' '2' -(1 row) - -select '\'1 2\''::txtidx; - txtidx --------- - '1 2' -(1 row) - -select '\'1 \\\'2\''::txtidx; - txtidx ---------- - '1 \'2' -(1 row) - -select '\'1 \\\'2\'3'::txtidx; - txtidx -------------- - '3' '1 \'2' -(1 row) - -select '\'1 \\\'2\' 3'::txtidx; - txtidx -------------- - '3' '1 \'2' -(1 row) - -select '\'1 \\\'2\' \' 3\' 4 '::txtidx; - txtidx ------------------- - '4' ' 3' '1 \'2' -(1 row) - ---query_txt -select '1'::query_txt; - query_txt ------------ - '1' -(1 row) - -select '1 '::query_txt; - query_txt ------------ - '1' -(1 row) - -select ' 1'::query_txt; - query_txt ------------ - '1' -(1 row) - -select ' 1 '::query_txt; - query_txt ------------ - '1' -(1 row) - -select '\'1 2\''::query_txt; - query_txt ------------ - '1 2' -(1 row) - -select '\'1 \\\'2\''::query_txt; - query_txt ------------ - '1 \'2' -(1 row) - -select '!1'::query_txt; - query_txt ------------ - !'1' -(1 row) - -select '1|2'::query_txt; - query_txt ------------ - '1' | '2' -(1 row) - -select '1|!2'::query_txt; - query_txt ------------- - '1' | !'2' -(1 row) - -select '!1|2'::query_txt; - query_txt ------------- - !'1' | '2' -(1 row) - -select '!1|!2'::query_txt; - query_txt -------------- - !'1' | !'2' -(1 row) - -select '!(!1|!2)'::query_txt; - query_txt ------------------- - !( !'1' | !'2' ) -(1 row) - -select '!(!1|2)'::query_txt; - query_txt ------------------ - !( !'1' | '2' ) -(1 row) - -select '!(1|!2)'::query_txt; - query_txt ------------------ - !( '1' | !'2' ) -(1 row) - -select '!(1|2)'::query_txt; - query_txt ----------------- - !( '1' | '2' ) -(1 row) - -select '1&2'::query_txt; - query_txt ------------ - '1' & '2' -(1 row) - -select '!1&2'::query_txt; - query_txt ------------- - !'1' & '2' -(1 row) - -select '1&!2'::query_txt; - query_txt ------------- - '1' & !'2' -(1 row) - -select '!1&!2'::query_txt; - query_txt -------------- - !'1' & !'2' -(1 row) - -select '(1&2)'::query_txt; - query_txt ------------ - '1' & '2' -(1 row) - -select '1&(2)'::query_txt; - query_txt ------------ - '1' & '2' -(1 row) - -select '!(1)&2'::query_txt; - query_txt ------------- - !'1' & '2' -(1 row) - -select '!(1&2)'::query_txt; - query_txt ----------------- - !( '1' & '2' ) -(1 row) - -select '1|2&3'::query_txt; - query_txt ------------------ - '1' | '2' & '3' -(1 row) - -select '1|(2&3)'::query_txt; - query_txt ------------------ - '1' | '2' & '3' -(1 row) - -select '(1|2)&3'::query_txt; - query_txt ---------------------- - ( '1' | '2' ) & '3' -(1 row) - -select '1|2&!3'::query_txt; - query_txt ------------------- - '1' | '2' & !'3' -(1 row) - -select '1|!2&3'::query_txt; - query_txt ------------------- - '1' | !'2' & '3' -(1 row) - -select '!1|2&3'::query_txt; - query_txt ------------------- - !'1' | '2' & '3' -(1 row) - -select '!1|(2&3)'::query_txt; - query_txt ------------------- - !'1' | '2' & '3' -(1 row) - -select '!(1|2)&3'::query_txt; - query_txt ----------------------- - !( '1' | '2' ) & '3' -(1 row) - -select '(!1|2)&3'::query_txt; - query_txt ----------------------- - ( !'1' | '2' ) & '3' -(1 row) - -select '1|(2|(4|(5|6)))'::query_txt; - query_txt ------------------------------------------ - '1' | ( '2' | ( '4' | ( '5' | '6' ) ) ) -(1 row) - -select '1|2|4|5|6'::query_txt; - query_txt ------------------------------------------ - ( ( ( '1' | '2' ) | '4' ) | '5' ) | '6' -(1 row) - -select '1&(2&(4&(5&6)))'::query_txt; - query_txt ------------------------------ - '1' & '2' & '4' & '5' & '6' -(1 row) - -select '1&2&4&5&6'::query_txt; - query_txt ------------------------------ - '1' & '2' & '4' & '5' & '6' -(1 row) - -select '1&(2&(4&(5|6)))'::query_txt; - query_txt ---------------------------------- - '1' & '2' & '4' & ( '5' | '6' ) -(1 row) - -select '1&(2&(4&(5|!6)))'::query_txt; - query_txt ----------------------------------- - '1' & '2' & '4' & ( '5' | !'6' ) -(1 row) - -select '1&(\'2\'&(\' 4\'&(\\|5 | \'6 \\\' !|&\')))'::query_txt; - query_txt ------------------------------------------- - '1' & '2' & ' 4' & ( '|5' | '6 \' !|&' ) -(1 row) - -select '1'::mquery_txt; - mquery_txt ------------- - '1' -(1 row) - -select '1 '::mquery_txt; - mquery_txt ------------- - '1' -(1 row) - -select ' 1'::mquery_txt; - mquery_txt ------------- - '1' -(1 row) - -select ' 1 '::mquery_txt; - mquery_txt ------------- - '1' -(1 row) - -select '\'1 2\''::mquery_txt; - mquery_txt ------------- - '1' & '2' -(1 row) - -select '\'1 \\\'2\''::mquery_txt; - mquery_txt ------------- - '1' & '2' -(1 row) - -select '!1'::mquery_txt; - mquery_txt ------------- - !'1' -(1 row) - -select '1|2'::mquery_txt; - mquery_txt ------------- - '1' | '2' -(1 row) - -select '1|!2'::mquery_txt; - mquery_txt ------------- - '1' | !'2' -(1 row) - -select '!1|2'::mquery_txt; - mquery_txt ------------- - !'1' | '2' -(1 row) - -select '!1|!2'::mquery_txt; - mquery_txt -------------- - !'1' | !'2' -(1 row) - -select '!(!1|!2)'::mquery_txt; - mquery_txt ------------------- - !( !'1' | !'2' ) -(1 row) - -select '!(!1|2)'::mquery_txt; - mquery_txt ------------------ - !( !'1' | '2' ) -(1 row) - -select '!(1|!2)'::mquery_txt; - mquery_txt ------------------ - !( '1' | !'2' ) -(1 row) - -select '!(1|2)'::mquery_txt; - mquery_txt ----------------- - !( '1' | '2' ) -(1 row) - -select '1&2'::mquery_txt; - mquery_txt ------------- - '1' & '2' -(1 row) - -select '!1&2'::mquery_txt; - mquery_txt ------------- - !'1' & '2' -(1 row) - -select '1&!2'::mquery_txt; - mquery_txt ------------- - '1' & !'2' -(1 row) - -select '!1&!2'::mquery_txt; - mquery_txt -------------- - !'1' & !'2' -(1 row) - -select '(1&2)'::mquery_txt; - mquery_txt ------------- - '1' & '2' -(1 row) - -select '1&(2)'::mquery_txt; - mquery_txt ------------- - '1' & '2' -(1 row) - -select '!(1)&2'::mquery_txt; - mquery_txt ------------- - !'1' & '2' -(1 row) - -select '!(1&2)'::mquery_txt; - mquery_txt ----------------- - !( '1' & '2' ) -(1 row) - -select '1|2&3'::mquery_txt; - mquery_txt ------------------ - '1' | '2' & '3' -(1 row) - -select '1|(2&3)'::mquery_txt; - mquery_txt ------------------ - '1' | '2' & '3' -(1 row) - -select '(1|2)&3'::mquery_txt; - mquery_txt ---------------------- - ( '1' | '2' ) & '3' -(1 row) - -select '1|2&!3'::mquery_txt; - mquery_txt ------------------- - '1' | '2' & !'3' -(1 row) - -select '1|!2&3'::mquery_txt; - mquery_txt ------------------- - '1' | !'2' & '3' -(1 row) - -select '!1|2&3'::mquery_txt; - mquery_txt ------------------- - !'1' | '2' & '3' -(1 row) - -select '!1|(2&3)'::mquery_txt; - mquery_txt ------------------- - !'1' | '2' & '3' -(1 row) - -select '!(1|2)&3'::mquery_txt; - mquery_txt ----------------------- - !( '1' | '2' ) & '3' -(1 row) - -select '(!1|2)&3'::mquery_txt; - mquery_txt ----------------------- - ( !'1' | '2' ) & '3' -(1 row) - -select '1|(2|(4|(5|6)))'::mquery_txt; - mquery_txt ------------------------------------------ - '1' | ( '2' | ( '4' | ( '5' | '6' ) ) ) -(1 row) - -select '1|2|4|5|6'::mquery_txt; - mquery_txt ------------------------------------------ - ( ( ( '1' | '2' ) | '4' ) | '5' ) | '6' -(1 row) - -select '1&(2&(4&(5&6)))'::mquery_txt; - mquery_txt ------------------------------ - '1' & '2' & '4' & '5' & '6' -(1 row) - -select '1&2&4&5&6'::mquery_txt; - mquery_txt ------------------------------ - '1' & '2' & '4' & '5' & '6' -(1 row) - -select '1&(2&(4&(5|6)))'::mquery_txt; - mquery_txt ---------------------------------- - '1' & '2' & '4' & ( '5' | '6' ) -(1 row) - -select '1&(2&(4&(5|!6)))'::mquery_txt; - mquery_txt ----------------------------------- - '1' & '2' & '4' & ( '5' | !'6' ) -(1 row) - -select '1&(\'2\'&(\' 4\'&(\\|5 | \'6 \\\' !|&\')))'::mquery_txt; - mquery_txt ---------------------------------- - '1' & '2' & '4' & ( '5' | '6' ) -(1 row) - -select 'querty-fgries | http://www.google.com/index.html | www.rambler.ru/index.shtml'::mquery_txt; - mquery_txt ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - ( 'querty-fgri' & 'querti' & 'fgri' | 'www.google.com/index.html' & 'www.google.com' & '/index.html' ) | 'www.rambler.ru/index.shtml' & 'www.rambler.ru' & '/index.shtml' -(1 row) - -CREATE TABLE test_txtidx( t text, a txtidx ); -\copy test_txtidx from 'data/test_tsearch.data' -SELECT count(*) FROM test_txtidx WHERE a @@ 'wr|qh'; - count -------- - 80 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a @@ 'wr&qh'; - count -------- - 6 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a @@ 'eq&yt'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a @@ 'eq|yt'; - count -------- - 47 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a @@ '(eq&yt)|(wr&qh)'; - count -------- - 7 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a @@ '(eq|yt)&(wr|qh)'; - count -------- - 11 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a ## 'wR|qh'; - count -------- - 80 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a ## 'wR&qh'; - count -------- - 6 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a ## 'eq&yt'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a ## 'eq|yt'; - count -------- - 47 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a ## '(eq&yt)|(wR&qh)'; - count -------- - 7 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a ## '(eq|yt)&(wR|qh)'; - count -------- - 11 -(1 row) - -create index wowidx on test_txtidx using gist (a); -SELECT count(*) FROM test_txtidx WHERE a @@ 'wr|qh'; - count -------- - 80 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a @@ 'wr&qh'; - count -------- - 6 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a @@ 'eq&yt'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a @@ 'eq|yt'; - count -------- - 47 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a @@ '(eq&yt)|(wr&qh)'; - count -------- - 7 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a @@ '(eq|yt)&(wr|qh)'; - count -------- - 11 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a ## 'wR|qh'; - count -------- - 80 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a ## 'wR&qh'; - count -------- - 6 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a ## 'eq&yt'; - count -------- - 1 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a ## 'eq|yt'; - count -------- - 47 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a ## '(eq&yt)|(wR&qh)'; - count -------- - 7 -(1 row) - -SELECT count(*) FROM test_txtidx WHERE a ## '(eq|yt)&(wR|qh)'; - count -------- - 11 -(1 row) - -select txt2txtidx('345 qwe@efd.r \' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 -/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234 - wow < jqw <> qwerty'); - txt2txtidx ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - 'ad' 'dw' 'jf' '234' '345' '4.2' '455' 'jqw' 'qwe' 'wer' 'wow' 'asdf' 'ewr1' 'qwer' 'sdjk' '5.005' 'ewri2' 'qwqwe' 'wefjn' 'gist.c' 'gist.h' 'qwerti' '234.435' ':8100/?' 'qwe-wer' 'readlin' 'www.com' '+4.0e-10' 'gist.h.c' 'rewt/ewr' 'qwe@efd.r' '/?ad=qwe&dw' '/wqe-324/ewr' 'aew.werc.ewr' '1aew.werc.ewr' '2aew.werc.ewr' '3aew.werc.ewr' '4aew.werc.ewr' '5aew.werc.ewr' '6aew.werc.ewr' '7aew.werc.ewr' '/usr/local/fff' '/awdf/dwqe/4325' ':8100/?ad=qwe&dw' 'teodor@stack.net' '5aew.werc.ewr:8100/?' ':8100/?ad=qwe&dw=%20%32' 'aew.werc.ewr/?ad=qwe&dw' '1aew.werc.ewr/?ad=qwe&dw' '3aew.werc.ewr/?ad=qwe&dw' '6aew.werc.ewr:8100/?ad=qwe&dw' '7aew.werc.ewr:8100/?ad=qwe&dw=%20%32' -(1 row) - -select txtidxsize(txt2txtidx('345 qw')); - txtidxsize ------------- - 2 -(1 row) - -select txtidxsize(txt2txtidx('345 qwe@efd.r \' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 -/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234 - wow < jqw <> qwerty')); - txtidxsize ------------- - 52 -(1 row) - -insert into test_txtidx (a) values ('345 qwerty'); -create trigger txtidxupdate before update or insert on test_txtidx -for each row execute procedure tsearch(a, t); -insert into test_txtidx (t) values ('345 qwerty'); -select count(*) FROM test_txtidx WHERE a @@ '345&qwerty'; - count -------- - 1 -(1 row) - -select count(*) FROM test_txtidx WHERE a ## '345&qwerty'; - count -------- - 1 -(1 row) - -update test_txtidx set t = null where t = '345 qwerty'; -select count(*) FROM test_txtidx WHERE a ## '345&qwerty'; - count -------- - 0 -(1 row) - -select count(*) FROM test_txtidx WHERE a @@ '345&qwerty'; - count -------- - 1 -(1 row) - diff --git a/contrib/tsearch/gistidx.c b/contrib/tsearch/gistidx.c deleted file mode 100644 index 5e52703684..0000000000 --- a/contrib/tsearch/gistidx.c +++ /dev/null @@ -1,658 +0,0 @@ -#include "postgres.h" - -#include - -#include "access/gist.h" -#include "access/itup.h" -#include "access/rtree.h" -#include "utils/elog.h" -#include "utils/palloc.h" -#include "utils/array.h" -#include "utils/builtins.h" -#include "storage/bufpage.h" -#include "access/tuptoaster.h" - -#include "txtidx.h" -#include "query.h" -#include "gistidx.h" -#include "crc32.h" - -PG_FUNCTION_INFO_V1( gtxtidx_in ); -Datum gtxtidx_in(PG_FUNCTION_ARGS); -PG_FUNCTION_INFO_V1( gtxtidx_out ); -Datum gtxtidx_out(PG_FUNCTION_ARGS); - -PG_FUNCTION_INFO_V1( gtxtidx_compress ); -Datum gtxtidx_compress(PG_FUNCTION_ARGS); -PG_FUNCTION_INFO_V1( gtxtidx_decompress ); -Datum gtxtidx_decompress(PG_FUNCTION_ARGS); -PG_FUNCTION_INFO_V1( gtxtidx_consistent ); -Datum gtxtidx_consistent(PG_FUNCTION_ARGS); -PG_FUNCTION_INFO_V1( gtxtidx_union ); -Datum gtxtidx_union(PG_FUNCTION_ARGS); -PG_FUNCTION_INFO_V1( gtxtidx_same ); -Datum gtxtidx_same(PG_FUNCTION_ARGS); -PG_FUNCTION_INFO_V1( gtxtidx_penalty ); -Datum gtxtidx_penalty(PG_FUNCTION_ARGS); -PG_FUNCTION_INFO_V1( gtxtidx_picksplit ); -Datum gtxtidx_picksplit(PG_FUNCTION_ARGS); - -#define GETENTRY(vec,pos) ((GISTTYPE *) DatumGetPointer(((GISTENTRY *) VARDATA(vec))[(pos)].key)) -#define SUMBIT(val) ( \ - GETBITBYTE(val,0) + \ - GETBITBYTE(val,1) + \ - GETBITBYTE(val,2) + \ - GETBITBYTE(val,3) + \ - GETBITBYTE(val,4) + \ - GETBITBYTE(val,5) + \ - GETBITBYTE(val,6) + \ - GETBITBYTE(val,7) \ -) - - -Datum -gtxtidx_in(PG_FUNCTION_ARGS) { - elog(ERROR,"Not implemented"); - PG_RETURN_DATUM(0); -} - -Datum -gtxtidx_out(PG_FUNCTION_ARGS) { - elog(ERROR,"Not implemented"); - PG_RETURN_DATUM(0); -} - -static int -compareint( const void * a, const void * b ) { - if ( *((int4*)a) == *((int4*)b) ) return 0; - return ( *((int4*)a) > *((int4*)b) ) ? 1 : -1; -} - -static int -uniqueint( int4* a, int4 l ) { - int4 *ptr, *res; - - if ( l == 1 ) - return l; - - ptr = res = a; - - qsort((void*)a, l, sizeof(int4), compareint ); - - while (ptr - a < l) - if (*ptr != *res) - *(++res) = *ptr++; - else - ptr++; - return res + 1 - a; -} - -static void -makesign( BITVECP sign, GISTTYPE *a) { - int4 k,len = ARRNELEM( a ); - int4 *ptr = GETARR( a ); - MemSet( (void*)sign, 0, sizeof(BITVEC) ); - for(k=0;kleafkey ) { /* txtidx */ - GISTTYPE *res; - txtidx *toastedval = (txtidx*)DatumGetPointer( entry->key ); - txtidx *val = (txtidx*)DatumGetPointer( PG_DETOAST_DATUM(entry->key) ); - int4 len; - int4 *arr; - WordEntry *ptr = ARRPTR(val); - char *words = STRPTR(val); - - len = CALCGTSIZE( ARRKEY, val->size ); - res = (GISTTYPE*)palloc( len ); - res->len = len; - res->flag = ARRKEY; - arr = GETARR(res); - len = val->size; - while( len-- ) { - *arr = crc32_sz( (uint8*)&words[ ptr->pos ], ptr->len ); - arr++; ptr++; - } - - len = uniqueint( GETARR(res), val->size ); - if ( len != val->size ) { - /* there is a collision of hash-function; - len is always less than val->size */ - len = CALCGTSIZE( ARRKEY, len ); - res = (GISTTYPE*)repalloc( (void*)res, len ); - res->len = len; - } - if ( val != toastedval ) - pfree(val); - - /* make signature, if array is too long */ - if ( res->len > TOAST_INDEX_TARGET ) { - GISTTYPE *ressign; - - len = CALCGTSIZE( SIGNKEY, 0 ); - ressign = (GISTTYPE*)palloc( len ); - ressign->len = len; - ressign->flag = SIGNKEY; - makesign( GETSIGN(ressign), res ); - pfree(res); - res = ressign; - } - - retval = (GISTENTRY*)palloc(sizeof(GISTENTRY)); - gistentryinit(*retval, PointerGetDatum(res), - entry->rel, entry->page, - entry->offset, res->len, FALSE); - } else if ( ISSIGNKEY(DatumGetPointer( entry->key )) && - ! ISALLTRUE(DatumGetPointer( entry->key )) ){ - int4 i,len; - GISTTYPE *res; - BITVECP sign = GETSIGN( DatumGetPointer( entry->key ) ); - - LOOPBYTE( - if ( (sign[i] & 0xff) != 0xff ) - PG_RETURN_POINTER(retval); - ); - - len = CALCGTSIZE( SIGNKEY|ALLISTRUE, 0 ); - res = (GISTTYPE*)palloc( len ); - res->len = len; - res->flag = SIGNKEY | ALLISTRUE; - - retval = (GISTENTRY*)palloc(sizeof(GISTENTRY)); - gistentryinit(*retval, PointerGetDatum(res), - entry->rel, entry->page, - entry->offset, res->len, FALSE); - } - PG_RETURN_POINTER(retval); -} - -Datum -gtxtidx_decompress(PG_FUNCTION_ARGS) { - GISTENTRY *entry = (GISTENTRY *)PG_GETARG_POINTER(0); - GISTTYPE *key = (GISTTYPE*)DatumGetPointer( PG_DETOAST_DATUM(entry->key) ); - - if ( key != (GISTTYPE*)DatumGetPointer(entry->key) ) { - GISTENTRY *retval = (GISTENTRY*)palloc(sizeof(GISTENTRY)); - gistentryinit(*retval, PointerGetDatum(key), - entry->rel, entry->page, - entry->offset, key->len, FALSE); - - PG_RETURN_POINTER(retval); - } - - PG_RETURN_POINTER(entry); -} - -typedef struct { - int4 *arrb; - int4 *arre; -} CHKVAL; - -/* - * is there value 'val' in array or not ? - */ -static bool -checkcondition_arr( void *checkval, ITEM* val ) { - int4 *StopLow = ((CHKVAL*)checkval)->arrb; - int4 *StopHigh = ((CHKVAL*)checkval)->arre; - int4 *StopMiddle; - - /* Loop invariant: StopLow <= val < StopHigh */ - - while (StopLow < StopHigh) { - StopMiddle = StopLow + (StopHigh - StopLow) / 2; - if (*StopMiddle == val->val) - return (true); - else if (*StopMiddle < val->val ) - StopLow = StopMiddle + 1; - else - StopHigh = StopMiddle; - } - - return (false); -} - -static bool -checkcondition_bit( void *checkval, ITEM* val ) { - return GETBIT( checkval, HASHVAL( val->val ) ); -} - -Datum -gtxtidx_consistent(PG_FUNCTION_ARGS) { - QUERYTYPE *query = (QUERYTYPE *)PG_GETARG_POINTER(1); - GISTTYPE *key = (GISTTYPE *)DatumGetPointer( - ((GISTENTRY *)PG_GETARG_POINTER(0))->key - ); - - if ( ISSIGNKEY(key) ) { - if ( ISALLTRUE(key) ) - PG_RETURN_BOOL(true); - - PG_RETURN_BOOL( execute( - GETQUERY(query), - (void*)GETSIGN(key), false, - checkcondition_bit - )); - } else { /* only leaf pages */ - CHKVAL chkval; - - chkval.arrb = GETARR(key); - chkval.arre = chkval.arrb + ARRNELEM(key); - PG_RETURN_BOOL( execute( - GETQUERY(query), - (void*)&chkval, true, - checkcondition_arr - ) ); - } -} - -static int4 -unionkey( BITVECP sbase, GISTTYPE *add ) { - int4 i; - - if ( ISSIGNKEY(add) ) { - BITVECP sadd = GETSIGN( add ); - - if ( ISALLTRUE(add) ) - return 1; - - LOOPBYTE( - sbase[i] |= sadd[i]; - ); - } else { - int4 *ptr = GETARR( add ); - for(i=0;ilen = len; - result->flag = flag; - if ( ! ISALLTRUE(result) ) - memcpy((void*)GETSIGN(result), (void*)base, sizeof( BITVEC ) ); - - PG_RETURN_POINTER( result ); -} - -Datum -gtxtidx_same(PG_FUNCTION_ARGS) { - GISTTYPE *a = (GISTTYPE*)PG_GETARG_POINTER(0); - GISTTYPE *b = (GISTTYPE*)PG_GETARG_POINTER(1); - bool *result = (bool *)PG_GETARG_POINTER(2); - - if ( ISSIGNKEY(a) ) { /* then b also ISSIGNKEY */ - if ( ISALLTRUE(a) && ISALLTRUE(b) ) { - *result = true; - } else if ( ISALLTRUE(a) ) { - *result = false; - } else if ( ISALLTRUE(b) ) { - *result = false; - } else { - int4 i; - BITVECP sa=GETSIGN(a), sb=GETSIGN(b); - - *result = true; - LOOPBYTE( - if ( sa[i] != sb[i] ) { - *result = false; - break; - } - ); - } - } else { /* a and b ISARRKEY */ - int4 lena = ARRNELEM(a), lenb = ARRNELEM(b); - - if ( lena != lenb ) { - *result = false; - } else { - int4 *ptra = GETARR(a), *ptrb = GETARR(b); - int4 i; - - *result = true; - for(i=0;ikey ); - GISTTYPE *newval = (GISTTYPE*)DatumGetPointer( newentry->key ); - int4 unionsize = 0; - BITVECP orig = GETSIGN(origval); - - if ( ISALLTRUE(origval) ) { - *penalty = 0.0; - PG_RETURN_POINTER( penalty ); - } - - if ( ISARRKEY(newval) ) { - int4 *ptr=GETARR(newval), n=ARRNELEM(newval); - while( n-- ) { - if ( GETBIT(orig, HASHVAL( *ptr ) ) == 0 ) - unionsize++; - ptr++; - } - *penalty = (float)unionsize; - } else { - if ( ISALLTRUE(newval) ) { - *penalty = (float) (SIGLENBIT - sizebitvec( orig ) ); - } else { - char valtmp; - BITVECP nval = GETSIGN(newval); - int4 i; - - LOOPBYTE( - valtmp = nval[i] | orig[i]; - unionsize += SUMBIT(valtmp) - SUMBIT(orig[i]); - ); - *penalty = (float)unionsize; - } - } - - PG_RETURN_POINTER( penalty ); -} - -typedef struct { - bool allistrue; - BITVEC sign; -} CACHESIGN; - -static void -fillcache( CACHESIGN *item, GISTTYPE *key ) { - item->allistrue = false; - if ( ISARRKEY( key ) ) { - makesign(item->sign, key); - } else if ( ISALLTRUE(key) ) { - item->allistrue = true; - } else { - memcpy( (void*)item->sign, (void*)GETSIGN(key), sizeof(BITVEC)); - } -} - -#define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) ) -typedef struct { - OffsetNumber pos; - int4 cost; -} SPLITCOST; - -static int -comparecost( const void *a, const void *b ) { - if ( ((SPLITCOST*)a)->cost == ((SPLITCOST*)b)->cost ) - return 0; - else - return ( ((SPLITCOST*)a)->cost > ((SPLITCOST*)b)->cost ) ? 1 : -1; -} - -Datum -gtxtidx_picksplit(PG_FUNCTION_ARGS) { - bytea *entryvec = (bytea *)PG_GETARG_POINTER(0); - GIST_SPLITVEC *v = (GIST_SPLITVEC *)PG_GETARG_POINTER(1); - OffsetNumber k,j; - GISTTYPE *datum_l, *datum_r; - BITVEC union_l, union_r; - bool firsttime = true; - int4 size_alpha,size_beta,sizeu,sizei; - int4 size_waste, waste = 0.0; - int4 size_l, size_r; - int4 nbytes; - OffsetNumber seed_1=0, seed_2=0; - OffsetNumber *left, *right; - OffsetNumber maxoff; - BITVECP ptra, ptrb, ptrc; - int i; - CACHESIGN *cache; - char valtmp; - SPLITCOST *costvector; - - maxoff = ((VARSIZE(entryvec) - VARHDRSZ) / sizeof(GISTENTRY)) - 2; - nbytes = (maxoff + 2) * sizeof(OffsetNumber); - v->spl_left = (OffsetNumber *) palloc(nbytes); - v->spl_right = (OffsetNumber *) palloc(nbytes); - - cache = (CACHESIGN*)palloc(sizeof(CACHESIGN)*(maxoff+2)); - fillcache( &cache[FirstOffsetNumber], GETENTRY(entryvec,FirstOffsetNumber) ); - - for (k = FirstOffsetNumber; k < maxoff; k = OffsetNumberNext(k)) { - for (j = OffsetNumberNext(k); j <= maxoff; j = OffsetNumberNext(j)) { - if ( k==FirstOffsetNumber ) - fillcache( &cache[j], GETENTRY(entryvec,j) ); - - if ( cache[k].allistrue || cache[j].allistrue ) { - sizeu = SIGLENBIT; - if ( cache[k].allistrue && cache[j].allistrue ) - sizei = SIGLENBIT; - else - sizei = ( cache[k].allistrue ) ? - sizebitvec( cache[j].sign ) : sizebitvec( cache[k].sign ); - } else { - sizeu = sizei = 0; - ptra = cache[j].sign; - ptrb = cache[k].sign; - /* critical section for bench !!! */ - -#define COUNT(pos) do { \ - if ( GETBITBYTE(*(char*)ptra,pos) ) { \ - sizeu++; \ - if ( GETBITBYTE(*(char*)ptrb, pos) ) \ - sizei++; \ - } else if ( GETBITBYTE(*(char*)ptrb, pos) ) \ - sizeu++; \ -} while(0) - LOOPBYTE( - COUNT(0); - COUNT(1); - COUNT(2); - COUNT(3); - COUNT(4); - COUNT(5); - COUNT(6); - COUNT(7); - ptra = (BITVECP) ( ((char*)ptra) + 1 ); - ptrb = (BITVECP) ( ((char*)ptrb) + 1 ); - ); - - } - size_waste = sizeu - sizei; - if (size_waste > waste || firsttime) { - waste = size_waste; - seed_1 = k; - seed_2 = j; - firsttime = false; - } - } - } - - left = v->spl_left; - v->spl_nleft = 0; - right = v->spl_right; - v->spl_nright = 0; - - if ( seed_1 == 0 || seed_2 == 0 ) { - seed_1 = 1; - seed_2 = 2; - } - - /* form initial .. */ - if ( cache[seed_1].allistrue ) { - datum_l = (GISTTYPE*)palloc( CALCGTSIZE( SIGNKEY|ALLISTRUE, 0 ) ); - datum_l->len = CALCGTSIZE( SIGNKEY|ALLISTRUE, 0 ); datum_l->flag = SIGNKEY|ALLISTRUE; - size_l = SIGLENBIT; - } else { - datum_l = (GISTTYPE*)palloc( CALCGTSIZE( SIGNKEY, 0 ) ); - datum_l->len = CALCGTSIZE( SIGNKEY, 0 ); datum_l->flag = SIGNKEY; - memcpy((void*)GETSIGN(datum_l), (void*)cache[seed_1].sign, sizeof(BITVEC)); - size_l = sizebitvec( GETSIGN(datum_l) ); - } - if ( cache[seed_2].allistrue ) { - datum_r = (GISTTYPE*)palloc( CALCGTSIZE( SIGNKEY|ALLISTRUE, 0 ) ); - datum_r->len = CALCGTSIZE( SIGNKEY|ALLISTRUE, 0 ); datum_r->flag = SIGNKEY|ALLISTRUE; - size_r = SIGLENBIT; - } else { - datum_r = (GISTTYPE*)palloc( CALCGTSIZE( SIGNKEY, 0 ) ); - datum_r->len = CALCGTSIZE( SIGNKEY, 0 ); datum_r->flag = SIGNKEY; - memcpy((void*)GETSIGN(datum_r), (void*)cache[seed_2].sign, sizeof(BITVEC)); - size_r = sizebitvec( GETSIGN(datum_r) ); - } - - maxoff = OffsetNumberNext(maxoff); - fillcache( &cache[maxoff], GETENTRY(entryvec,maxoff) ); - /* sort before ... */ - costvector=(SPLITCOST*)palloc( sizeof(SPLITCOST)*maxoff ); - for (j = FirstOffsetNumber; j <= maxoff; j = OffsetNumberNext(j)) { - costvector[j-1].pos = j; - if ( cache[j].allistrue ) { - size_alpha = SIGLENBIT - size_l; - size_beta = SIGLENBIT - size_r; - } else { - ptra = cache[seed_1].sign; - ptrb = cache[seed_2].sign; - ptrc = cache[j].sign; - size_beta = size_alpha = 0; - if ( cache[seed_1].allistrue ) { - if ( ! cache[seed_2].allistrue ) { - LOOPBIT( - if ( GETBIT(ptrc,i) && ! GETBIT(ptrb,i) ) - size_beta++; - ); - } - } else if ( cache[seed_2].allistrue ) { - if ( ! cache[seed_1].allistrue ) { - LOOPBIT( - if ( GETBIT(ptrc,i) && ! GETBIT(ptra,i) ) - size_alpha++; - ); - } - } else { - LOOPBIT( - if ( GETBIT(ptrc,i) && ! GETBIT(ptra,i) ) - size_alpha++; - if ( GETBIT(ptrc,i) && ! GETBIT(ptrb,i) ) - size_beta++; - ); - } - - } - costvector[j-1].cost = abs( size_alpha - size_beta ); - } - qsort( (void*)costvector, maxoff, sizeof(SPLITCOST), comparecost ); - - for (k = 0; k < maxoff; k++) { - j = costvector[k].pos; - if ( j == seed_1 ) { - *left++ = j; - v->spl_nleft++; - continue; - } else if ( j == seed_2 ) { - *right++ = j; - v->spl_nright++; - continue; - } - - if ( ISALLTRUE( datum_l ) || cache[j].allistrue ) { - size_alpha = SIGLENBIT; - } else { - ptra = cache[j].sign; - ptrb = GETSIGN(datum_l); - size_alpha = 0; - LOOPBYTE( - valtmp = union_l[i] = ptra[i] | ptrb[i]; - size_alpha += SUMBIT( valtmp ); - ); - } - if ( ISALLTRUE( datum_r ) || cache[j].allistrue ) { - size_beta = SIGLENBIT; - } else { - ptra = cache[j].sign; - ptrb = GETSIGN(datum_r); - size_beta = 0; - LOOPBYTE( - valtmp = union_r[i] = ptra[i] | ptrb[i]; - size_beta += SUMBIT( valtmp ); - ); - } - - if (size_alpha - size_l < size_beta - size_r + WISH_F(v->spl_nleft, v->spl_nright, 0.1)) { - if ( ! ISALLTRUE( datum_l ) ) { - if ( size_alpha == SIGLENBIT ) { - if ( size_alpha != size_l ) - MemSet( (void*)GETSIGN(datum_l),0xff, sizeof(BITVEC)); - } else - memcpy( (void*)GETSIGN(datum_l), (void*)union_l, sizeof(BITVEC) ); - } - size_l = size_alpha; - *left++ = j; - v->spl_nleft++; - } else { - if ( ! ISALLTRUE( datum_r ) ) { - if ( size_beta == SIGLENBIT ) { - if ( size_beta != size_r ) - MemSet( (void*)GETSIGN(datum_r),0xff, sizeof(BITVEC)); - } else - memcpy( (void*)GETSIGN(datum_r), (void*)union_r, sizeof(BITVEC) ); - } - size_r = size_beta; - *right++ = j; - v->spl_nright++; - } - } - - *right = *left = FirstOffsetNumber; - pfree(costvector); - pfree(cache); - v->spl_ldatum = PointerGetDatum(datum_l); - v->spl_rdatum = PointerGetDatum(datum_r); - - PG_RETURN_POINTER( v ); -} - - diff --git a/contrib/tsearch/gistidx.h b/contrib/tsearch/gistidx.h deleted file mode 100644 index db1b501e92..0000000000 --- a/contrib/tsearch/gistidx.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef __GISTIDX_H__ -#define __GISTIDX_H__ - -/* -#define GISTIDX_DEBUG -*/ - -/* - * signature defines - */ -#define BITBYTE 8 -#define SIGLENINT 64 /* >121 => key will toast, so it will not - * work !!! */ -#define SIGLEN ( sizeof(int4)*SIGLENINT ) -#define SIGLENBIT (SIGLEN*BITBYTE) - -typedef char BITVEC[SIGLEN]; -typedef char *BITVECP; - -#define LOOPBYTE(a) \ - for(i=0;i> i & 0x01 ) -#define CLRBIT(x,i) GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITBYTE ) ) -#define SETBIT(x,i) GETBYTE(x,i) |= ( 0x01 << ( (i) % BITBYTE ) ) -#define GETBIT(x,i) ( (GETBYTE(x,i) >> ( (i) % BITBYTE )) & 0x01 ) - -#define abs(a) ((a) < (0) ? -(a) : (a)) -#define min(a,b) ((a) < (b) ? (a) : (b)) -#define HASHVAL(val) (((unsigned int)(val)) % SIGLENBIT) -#define HASH(sign, val) SETBIT((sign), HASHVAL(val)) - - -/* - * type of index key - */ -typedef struct -{ - int4 len; - int4 flag; - char data[1]; -} GISTTYPE; - -#define ARRKEY 0x01 -#define SIGNKEY 0x02 -#define ALLISTRUE 0x04 - -#define ISARRKEY(x) ( ((GISTTYPE*)x)->flag & ARRKEY ) -#define ISSIGNKEY(x) ( ((GISTTYPE*)x)->flag & SIGNKEY ) -#define ISALLTRUE(x) ( ((GISTTYPE*)x)->flag & ALLISTRUE ) - -#define GTHDRSIZE ( sizeof(int4)*2 ) -#define CALCGTSIZE(flag, len) ( GTHDRSIZE + ( ( (flag) & ARRKEY ) ? ((len)*sizeof(int4)) : (((flag) & ALLISTRUE) ? 0 : SIGLEN) ) ) - -#define GETSIGN(x) ( (BITVECP)( (char*)x+GTHDRSIZE ) ) -#define GETARR(x) ( (int4*)( (char*)x+GTHDRSIZE ) ) -#define ARRNELEM(x) ( ( ((GISTTYPE*)x)->len - GTHDRSIZE )/sizeof(int4) ) - -#endif diff --git a/contrib/tsearch/makedict/makedict.pl b/contrib/tsearch/makedict/makedict.pl deleted file mode 100755 index 65c8af3bd2..0000000000 --- a/contrib/tsearch/makedict/makedict.pl +++ /dev/null @@ -1,301 +0,0 @@ -#!/usr/bin/perl -use strict; -use Getopt::Std; -use locale; - -my %opt; -getopts('l:he:s:ap:om:f', \%opt); - -if ( $opt{h} || ! ($opt{e}||$opt{s}) || !$opt{l} ) { - print< -Usage: -$0 -l LOCALENAME [ -e FILENAME ] [ -s FILENAME ] [ -p PREFIX ] [ -o FILENAME ] [ -a ] [ -m NUMBER ] --e FILENAME - file with endings of word --s FILENAME - file with list of stop-word --o FILENAME - out file, default STDOUT --a - stop-word are strimmed --p PREFIX - prefix of function and etc, default strimmed locale --m NUMBER - minimal length of rest after semming, default 3 --l LOCALENAME - name of locale --f - do not call tolower for each char -At least one of -e or -s must be defined -EOT -exit; -} - -if ( ! defined $opt{p} ) { - $opt{p} = $opt{l}; - $opt{p}=~s/[^a-zA-Z0-9_]+//g; -} -$opt{m}=3 if ! defined $opt{m}; - -my ($enddata,$stopdata) = ('',''); -my $maxchild = 0; - -if ( $opt{e} ) { - my @tree; - buildtree(\@tree, $opt{e}, 1); - printstruct( \@tree, 0, \$enddata); - undef @tree; -} - -if ( $opt{s} ) { - my @tree; - buildtree(\@tree, $opt{s}, 0); - printstruct( \@tree, 0, \$stopdata); - undef @tree; -} - - -die "No data\n" if ( ! (length $enddata || length $stopdata) ); - -$enddata = "\t{0,0,0,0}" if ( ! length $enddata ); -$stopdata = "\t{0,0,0,0}" if ( ! length $stopdata ); - -my $fh=\*STDOUT; -if ( $opt{o} ) { - open(OUT,">$opt{o}") || die "Can;t open file '$opt{o}' for writing\n"; - $fh = \*OUT; -} - -my $linktype = 'uint32'; -if ( $maxchild <= 0xff ) { - $linktype='uint8'; -} elsif ( $maxchild <= 0xffff ) { - $linktype='uint16'; -} - -my $wherecheck = ( $opt{a} ) ? - "NULL,\n\t$opt{p}_is_stopword" - : - "$opt{p}_is_stopword,\n\tNULL"; - -my ($tolower, $resttolower) = ('',''); -if ( ! $opt{f} ) { - $tolower = '*cur = tolower( *cur );'; - $resttolower=<= 0 ) { - *cur = tolower(*cur); - cur--; - } -EOT -} - -print {$fh} <flag & L) -#define ISFINISH(x) ((($opt{p}_NODE*)x)->flag & F) - -#define MINLENREST $opt{m} - -static $opt{p}_NODE $opt{p}_endstree[]={ -$enddata -}; - -static $opt{p}_NODE $opt{p}_stoptree[]={ -$stopdata -}; - -static char* -$opt{p}_stem( void* obj, char *in, int *len ) { - $opt{p}_NODE *ptr = $opt{p}_endstree; - int result = 0; - uint8 *buf = (uint8 *)in; - uint8 *cur = buf + (*len) - 1; - - while( cur - buf >= MINLENREST ) { - $tolower - if ( ptr->val == *cur ) { - if ( ISFINISH(ptr) ) result = buf + (*len) - cur; - cur--; - if ( ! ptr->child ) break; - ptr += ptr->child; - } else if ( ptr->val > *cur ) { - if ( ISLEFT(ptr) ) - ptr++; - else - break; - } else { - if ( ptr->right ) - ptr += ptr->right; - else - break; - } - } - $resttolower - *len -= result; - return in; -} - -static int -$opt{p}_is_stopword( void *obj, char *in, int len ) { - $opt{p}_NODE *ptr = $opt{p}_stoptree; - int result = 0; - uint8 *buf = (uint8 *)in; - uint8 *cur = buf; - - while( cur - buf < len ) { - $tolower - if ( ptr->val == *cur ) { - cur++; - if ( ISFINISH(ptr) ) result = cur - buf; - if ( ! ptr->child ) break; - ptr += ptr->child; - } else if ( ptr->val > *cur ) { - if ( ISLEFT(ptr) ) - ptr++; - else - break; - } else { - if ( ptr->right ) - ptr += ptr->right; - else - break; - } - } - return (result==len) ? 1 : 0; -} - -#undef L -#undef F -#undef ISLEFT -#undef ISFINISH -#undef MINLENREST -#endif /* DICT_BODY */ - -#ifdef DICT_TABLE -TABLE_DICT_START - \"$opt{l}\", - NULL, - NULL, - $opt{p}_stem, - $wherecheck -TABLE_DICT_END -#endif - -EOT - -close($fh) if ( $fh != \*STDOUT ); - - -sub buildtree { - my ($reftree,$file, $needreverse) = @_; - open(DATA,$file) || die "Can't open file '$file'\n"; - while() { - chomp; - next if ! length $_; - $_ = lc($_) if ! $opt{f}; - addtostruct( $reftree, ( $needreverse ) ? scalar(reverse($_)) : $_ ); - } - close DATA; -} - -sub mkbintree { - my ( $start, $stop, $rprop, $rres) = @_; - - my $middle = $start + int( ($stop-$start)/2 ); - - push( @$rres, $rprop->[$middle] ); - my $idx = $#$rres; - $rres->[$idx]{right}=0; - $rres->[$idx]{left}=0; - return 1 if ( $start == $stop ); - - my $leftsize = 0; - if ( $middle!=$start ) { - $rres->[$idx]{left}=1; - $leftsize = mkbintree( $start, $middle-1, $rprop, $rres ); - $rres->[$idx]{right}=$leftsize+1; - } else { - $rres->[$idx]{right} = 1; - } - return 1 + $leftsize + mkbintree( $middle+1, $stop, $rprop, $rres ); -} - -sub addtostruct { - my $node = shift; - my ($char, $subval) = split('', shift, 2); - $char = ord( $char ); - if ( ! defined $node->[$char] ) { - $node->[$char] = {}; - $node->[$char]{finish} = length $subval; - $node->[$char]{child} = []; - } elsif ( ! length $subval ) { - $node->[$char]{finish} = 0; - } - - addtostruct( $node->[$char]{child}, $subval ) if ( length $subval ); -} - -sub printstruct { - my ($node, $pre, $refout) = @_; - my $add = 0; - my @prop; - my $outchild; - my $current = 0; - my $poschild=0; - my @tmp; - - foreach my $i ( 0..255 ) { - next if ( !defined $node->[ $i ] ); - push @prop , { val=>$i, - nchild=>printstruct( $node->[ $i ]{child}, 1, \$outchild ), - poschild=>$poschild }; - $poschild += $prop[$#prop]{nchild}; - } - - return 0 if $#prop < 0; - if ($pre) { - $$refout .= ",\n\n"; - } - mkbintree(0,$#prop,\@prop,\@tmp); - @prop = @tmp; - - $current=$#prop+1; - foreach my $i ( 0..$#prop ) { - my $flag = ($prop[$i]{left}) ? 'L' : undef; - if ( $node->[ $prop[$i]{val} ]{finish}==0 ) { - $flag .= '|' if defined $flag; - $flag .= 'F'; - } elsif ( ! defined $flag ) { - $flag='0'; - } - $$refout .= "\t{'".chr( $prop[$i]{val} )."',". - $flag.','. - $prop[$i]{right}.','. - (($prop[$i]{nchild}==0)?0:($prop[$i]{poschild}+$current)).'}'. - (($i==$#prop)? '' : ",\n"); - - $maxchild = $prop[$i]{poschild}+$current if - ( $prop[$i]{nchild} && $prop[$i]{poschild}+$current > $maxchild ); - $current--; - $add += $prop[$i]{nchild}; - } - $$refout .= $outchild; - return $#prop+1 + $add; -} - - - diff --git a/contrib/tsearch/morph.c b/contrib/tsearch/morph.c deleted file mode 100644 index 60797b07e9..0000000000 --- a/contrib/tsearch/morph.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * morphology module - * New dictionary is include in dict.h. For languages which - * use latin charset it may be need to modify mapdict table. - * Teodor Sigaev - */ -#include "postgres.h" - -#include "utils/elog.h" -#include "utils/palloc.h" -#include "utils/builtins.h" -#include "catalog/pg_control.h" -#include "utils/pg_locale.h" - -#include "morph.h" -#include "deflex.h" - -/* - * Struct for calling dictionaries - * All of this methods are optional, but - * if all methods are NULL, then dictionary does nothing :) - * Return value of lemmatize must be palloced or the same. - * Return value of init must be malloced in other case - * it will be free in end of transaction! - */ -typedef struct -{ - char localename[LOCALE_NAME_BUFLEN]; - /* init dictionary */ - void *(*init) (void); - /* close dictionary */ - void (*close) (void *); - /* find in dictionary */ - char *(*lemmatize) (void *, char *, int *); - int (*is_stoplemm) (void *, char *, int); - int (*is_stemstoplemm) (void *, char *, int); -} DICT; - -/* insert all dictionaries */ -#define DICT_BODY -#include "dict.h" -#undef DICT_BODY - -/* fill dictionary's structure */ -#define DICT_TABLE -DICT dicts[] = { - { - "C", NULL, NULL, NULL, NULL, NULL /* fake dictionary */ - } -#include "dict.h" -}; - -#undef DICT_TABLE - -/* array for storing dictinary's objects (if needed) */ -void *dictobjs[ - lengthof(dicts)]; - -#define STOPLEXEM -2 -#define BYLOCALE -1 -#define NODICT 0 -#define DEFAULTDICT 1 - -#define MAXNDICT 2 -typedef int2 MAPDICT[MAXNDICT]; - -#define GETDICT(x,i) *( ((int2*)(x)) + (i) ) - -/* map dictionaries for lexem type */ -static MAPDICT mapdict[] = { - {NODICT, NODICT}, /* not used */ - {DEFAULTDICT, NODICT}, /* LATWORD */ - {BYLOCALE, NODICT}, /* NONLATINWORD */ - {BYLOCALE, DEFAULTDICT}, /* UWORD */ - {NODICT, NODICT}, /* EMAIL */ - {NODICT, NODICT}, /* FURL */ - {NODICT, NODICT}, /* HOST */ - {NODICT, NODICT}, /* FLOAT */ - {NODICT, NODICT}, /* FINT */ - {BYLOCALE, DEFAULTDICT}, /* PARTWORD */ - {BYLOCALE, NODICT}, /* NONLATINPARTWORD */ - {DEFAULTDICT, NODICT}, /* LATPARTWORD */ - {STOPLEXEM, NODICT}, /* SPACE */ - {STOPLEXEM, NODICT}, /* SYMTAG */ - {STOPLEXEM, NODICT}, /* HTTP */ - {BYLOCALE, DEFAULTDICT}, /* DEFISWORD */ - {DEFAULTDICT, NODICT}, /* DEFISLATWORD */ - {BYLOCALE, NODICT}, /* DEFISNONLATINWORD */ - {NODICT, NODICT}, /* URI */ - {NODICT, NODICT} /* FILEPATH */ -}; - -static bool inited = false; - -void -initmorph(void) -{ - int i, - j, - k; - MAPDICT *md; - bool needinit[lengthof(dicts)]; - -#ifdef USE_LOCALE - PG_LocaleCategories lc; - - int bylocaledict = NODICT; -#endif - - if (inited) - return; - for (i = 1; i < lengthof(dicts); i++) - needinit[i] = false; - -#ifdef USE_LOCALE - PGLC_current(&lc); - if ( lc.lc_ctype ) - for (i = 1; i < lengthof(dicts); i++) - if (strcmp(dicts[i].localename, lc.lc_ctype) == 0) - { - bylocaledict = i; - break; - } - PGLC_free_categories(&lc); -#endif - - for (i = 1; i < lengthof(mapdict); i++) - { - k = 0; - md = &mapdict[i]; - for (j = 0; j < MAXNDICT; j++) - { - GETDICT(md, k) = GETDICT(md, j); - if (GETDICT(md, k) == NODICT) - break; - else if (GETDICT(md, k) == BYLOCALE) - { -#ifdef USE_LOCALE - if (bylocaledict == NODICT) - continue; - GETDICT(md, k) = bylocaledict; -#else - continue; -#endif - } - if (GETDICT(md, k) >= (int2) lengthof(dicts)) - continue; - needinit[GETDICT(md, k)] = true; - k++; - } - for (; k < MAXNDICT; k++) - if (GETDICT(md, k) != STOPLEXEM) - GETDICT(md, k) = NODICT; - } - - for (i = 1; i < lengthof(dicts); i++) - if (needinit[i] && dicts[i].init) - dictobjs[i] = (*(dicts[i].init)) (); - - inited = true; - return; -} - -char * -lemmatize(char *word, int *len, int type) -{ - int2 nd; - int i; - DICT *dict; - - for (i = 0; i < MAXNDICT; i++) - { - nd = GETDICT(&mapdict[type], i); - if (nd == NODICT) - { - /* there is no dictionary */ - return word; - } - else if (nd == STOPLEXEM) - { - /* word is stopword */ - return NULL; - } - else - { - dict = &dicts[nd]; - if (dict->is_stoplemm && (*(dict->is_stoplemm)) (dictobjs[nd], word, *len)) - return NULL; - if (dict->lemmatize) - { - int oldlen = *len; - char *newword = (*(dict->lemmatize)) (dictobjs[nd], word, len); - - /* word is recognized by distionary */ - if (newword != word || *len != oldlen) - { - if (dict->is_stemstoplemm && - (*(dict->is_stemstoplemm)) (dictobjs[nd], word, *len)) - { - if (newword != word && newword) - pfree(newword); - return NULL; - } - return newword; - } - } - } - } - - return word; -} - -bool -is_stoptype(int type) -{ - return (GETDICT(&mapdict[type], 0) == STOPLEXEM) ? true : false; -} diff --git a/contrib/tsearch/morph.h b/contrib/tsearch/morph.h deleted file mode 100644 index 24bb0efc8c..0000000000 --- a/contrib/tsearch/morph.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __MORPH_H__ -#define __MORPH_H__ - -void initmorph(void); - -char *lemmatize(char *word, int *len, int type); - -bool is_stoptype(int type); - -#endif diff --git a/contrib/tsearch/parser.h b/contrib/tsearch/parser.h deleted file mode 100644 index f3aa0b8c06..0000000000 --- a/contrib/tsearch/parser.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __PARSER_H__ -#define __PARSER_H__ - -char *token; -int tokenlen; -int tsearch_yylex(void); -void start_parse_str(char *, int); -void start_parse_fh(FILE *, int); -void end_parse(void); - -#endif diff --git a/contrib/tsearch/parser.l b/contrib/tsearch/parser.l deleted file mode 100644 index 66b8cf56df..0000000000 --- a/contrib/tsearch/parser.l +++ /dev/null @@ -1,320 +0,0 @@ -%{ -#include -#include "deflex.h" -#include "parser.h" - -/* postgres allocation function */ -#include "postgres.h" -#define free pfree -#define malloc palloc -#define realloc repalloc - -#ifdef strdup -#undef strdup -#endif -#define strdup pstrdup - - -char *token = NULL; /* pointer to token */ -char *s = NULL; /* for returning full defis-word */ - -YY_BUFFER_STATE buf = NULL; /* buffer to parse; it need for parse from string */ - -int lrlimit = -1; /* for limiting read from filehandle ( -1 - unlimited read ) */ -int bytestoread = 0; /* for limiting read from filehandle */ - -/* redefine macro for read limited length */ -#define YY_INPUT(buf,result,max_size) \ - if ( yy_current_buffer->yy_is_interactive ) { \ - int c = '*', n; \ - for ( n = 0; n < max_size && \ - (c = getc( tsearch_yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( tsearch_yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } else { \ - if ( lrlimit == 0 ) \ - result=YY_NULL; \ - else { \ - if ( lrlimit>0 ) { \ - bytestoread = ( lrlimit > max_size ) ? max_size : lrlimit; \ - lrlimit -= bytestoread; \ - } else \ - bytestoread = max_size; \ - if ( ((result = fread( buf, 1, bytestoread, tsearch_yyin )) == 0) \ - && ferror( tsearch_yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - } \ - } - -#define YY_NO_UNPUT -%} - -/* parser's state for parsing defis-word */ -%x DELIM -/* parser's state for parsing URL*/ -%x URL -%x SERVER - -/* parser's state for parsing filepath */ - -%x INTAG -%x QINTAG - -/* NONLATIN char */ -NONLATINALNUM [0-9\200-\377] -NONLATINALPHA [\200-\377] -ALPHA [a-zA-Z\200-\377] -ALNUM [0-9a-zA-Z\200-\377] - - -HOSTNAME ([-_[:alnum:]]+\.)+[[:alpha:]]+ -URI [-_[:alnum:]/%,\.;=&?#]+ - -%% - -"<"[[:alpha:]] { BEGIN INTAG; - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return SYMTAG; - } - -"" { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return SYMTAG; -} - -"<"[^>[:alpha:]] { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return SPACE; -} - -"\"" { BEGIN QINTAG; - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return SYMTAG; - } - -"\\\"" { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return SYMTAG; -} - -"\"" { BEGIN INTAG; - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return SYMTAG; - } - -.|\n { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return SYMTAG; -} - -">" { BEGIN INITIAL; - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return SYMTAG; - } - -.|\n { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return SYMTAG; -} - - -[-_\.[:alnum:]]+@{HOSTNAME} /* Emails */ { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return EMAIL; -} - -[0-9] /* digit's and point (might be a version) */ { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return FINT; -} - -[0-9]+[0-9\.]*[0-9] /* digit's and point (might be a version) */ { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return FINT; -} - -[+-]?[0-9\.]+[eE][+-]?[0-9]+ /* float */ { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return FLOAT; -} - -http"://" { - BEGIN URL; - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return HTTP; -} - -ftp"://" { - BEGIN URL; - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return HTTP; -} - -{HOSTNAME}[/:]{URI} { - BEGIN SERVER; - if (s) { free(s); s=NULL; } - s = strdup( tsearch_yytext ); - tokenlen = tsearch_yyleng; - yyless( 0 ); - token = s; - return FURL; -} - -{HOSTNAME} { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return HOST; -} - -[/:]{URI} { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return URI; -} - -[[:alnum:]\./_-]+"/"[[:alnum:]\./_-]+ { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return FILEPATH; -} - -({NONLATINALNUM}+-)+{NONLATINALPHA}+ /* composite-word */ { - BEGIN DELIM; - if (s) { free(s); s=NULL; } - s = strdup( tsearch_yytext ); - tokenlen = tsearch_yyleng; - yyless( 0 ); - token = s; - return DEFISNONLATINWORD; -} - -([[:alnum:]]+-)+[[:alpha:]]+ /* composite-word */ { - BEGIN DELIM; - if (s) { free(s); s=NULL; } - tokenlen = tsearch_yyleng; - s = strdup( tsearch_yytext ); - yyless( 0 ); - token = s; - return DEFISLATWORD; -} - -({ALNUM}+-)+{ALPHA}+ /* composite-word */ { - BEGIN DELIM; - if (s) { free(s); s=NULL; } - s = strdup( tsearch_yytext ); - tokenlen = tsearch_yyleng; - yyless( 0 ); - token = s; - return DEFISWORD; -} - -{NONLATINALNUM}+ /* one word in composite-word */ { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return NONLATINPARTWORD; -} - -[[:alnum:]]+ /* one word in composite-word */ { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return LATPARTWORD; -} - -{ALNUM}+ /* one word in composite-word */ { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return PARTWORD; -} - -- { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return SPACE; -} - -.|\n /* return in basic state */ { - BEGIN INITIAL; - tokenlen = tsearch_yyleng; - yyless( 0 ); -} - -{NONLATINALNUM}+ /* normal word */ { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return NONLATINWORD; -} - -[[:alnum:]]+ /* normal word */ { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return LATWORD; -} - -{ALNUM}+ /* normal word */ { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return UWORD; -} - -.|\n { - token = tsearch_yytext; - tokenlen = tsearch_yyleng; - return SPACE; -} - -%% - -int tsearch_yywrap(void) { - return 1; -} - -/* clearing after parsing from string */ -void end_parse() { - if (s) { free(s); s=NULL; } - tsearch_yy_delete_buffer( buf ); - buf = NULL; -} - -/* start parse from string */ -void start_parse_str(char* str, int limit) { - if (buf) end_parse(); - buf = tsearch_yy_scan_bytes( str, limit ); - tsearch_yy_switch_to_buffer( buf ); - BEGIN INITIAL; -} - -/* start parse from filehandle */ -void start_parse_fh( FILE* fh, int limit ) { - if (buf) end_parse(); - lrlimit = ( limit ) ? limit : -1; - buf = tsearch_yy_create_buffer( fh, YY_BUF_SIZE ); - tsearch_yy_switch_to_buffer( buf ); - BEGIN INITIAL; -} - - diff --git a/contrib/tsearch/query.c b/contrib/tsearch/query.c deleted file mode 100644 index 6666720c9b..0000000000 --- a/contrib/tsearch/query.c +++ /dev/null @@ -1,797 +0,0 @@ -/* - * IO definitions for query_txt and mquery_txt. This type - * are identical, but for parsing mquery_txt used parser for text - * and also morphology is used. - * Internal structure: - * query tree, then string with original value. - * Query tree with plain view. It's means that in array of nodes - * right child is always next and left position = item+item->left - * Teodor Sigaev - */ -#include "postgres.h" - -#include - -#include "access/gist.h" -#include "access/itup.h" -#include "access/rtree.h" -#include "utils/elog.h" -#include "utils/palloc.h" -#include "utils/array.h" -#include "utils/builtins.h" -#include "storage/bufpage.h" - -#include "txtidx.h" -#include "crc32.h" -#include "query.h" -#include "morph.h" -#include "rewrite.h" - -#include "deflex.h" -#include "parser.h" - -PG_FUNCTION_INFO_V1(mqtxt_in); -Datum mqtxt_in(PG_FUNCTION_ARGS); - -PG_FUNCTION_INFO_V1(qtxt_in); -Datum qtxt_in(PG_FUNCTION_ARGS); - -PG_FUNCTION_INFO_V1(qtxt_out); -Datum qtxt_out(PG_FUNCTION_ARGS); - -PG_FUNCTION_INFO_V1(execqtxt); -Datum execqtxt(PG_FUNCTION_ARGS); - -PG_FUNCTION_INFO_V1(rexecqtxt); -Datum rexecqtxt(PG_FUNCTION_ARGS); - -PG_FUNCTION_INFO_V1(querytree); -Datum querytree(PG_FUNCTION_ARGS); - -#define END 0 -#define ERR 1 -#define VAL 2 -#define OPR 3 -#define OPEN 4 -#define CLOSE 5 -#define VALTRUE 6 /* for stop words */ -#define VALFALSE 7 - -/* parser's states */ -#define WAITOPERAND 1 -#define WAITOPERATOR 2 - -/* - * node of query tree, also used - * for storing polish notation in parser - */ -typedef struct NODE -{ - int4 type; - int4 val; - int2 distance; - int2 length; - struct NODE *next; -} NODE; - -typedef struct -{ - char *buf; - int4 state; - int4 count; - /* reverse polish notation in list (for temprorary usage) */ - NODE *str; - /* number in str */ - int4 num; - - /* user-friendly operand */ - int4 lenop; - int4 sumlen; - char *op; - char *curop; - - /* state for value's parser */ - TI_IN_STATE valstate; -} QPRS_STATE; - -/* - * get token from query string - */ -static int4 -gettoken_query(QPRS_STATE * state, int4 *val, int4 *lenval, char **strval) -{ - while (1) - { - switch (state->state) - { - case WAITOPERAND: - if (*(state->buf) == '!') - { - (state->buf)++; - *val = (int4) '!'; - return OPR; - } - else if (*(state->buf) == '(') - { - state->count++; - (state->buf)++; - return OPEN; - } - else if (*(state->buf) != ' ') - { - state->valstate.prsbuf = state->buf; - state->state = WAITOPERATOR; - if (gettoken_txtidx(&(state->valstate))) - { - *strval = state->valstate.word; - *lenval = state->valstate.curpos - state->valstate.word; - state->buf = state->valstate.prsbuf; - return VAL; - } - else - elog(ERROR, "No operand"); - } - break; - case WAITOPERATOR: - if (*(state->buf) == '&' || *(state->buf) == '|') - { - state->state = WAITOPERAND; - *val = (int4) *(state->buf); - (state->buf)++; - return OPR; - } - else if (*(state->buf) == ')') - { - (state->buf)++; - state->count--; - return (state->count < 0) ? ERR : CLOSE; - } - else if (*(state->buf) == '\0') - return (state->count) ? ERR : END; - else if (*(state->buf) != ' ') - return ERR; - break; - default: - return ERR; - break; - } - (state->buf)++; - } - return END; -} - -/* - * push new one in polish notation reverse view - */ -static void -pushquery(QPRS_STATE * state, int4 type, int4 val, int4 distance, int4 lenval) -{ - NODE *tmp = (NODE *) palloc(sizeof(NODE)); - - tmp->type = type; - tmp->val = val; - if (distance > 0xffff) - elog(ERROR, "Value is too big"); - if (lenval > 0xffff) - elog(ERROR, "Operand is too long"); - tmp->distance = distance; - tmp->length = lenval; - tmp->next = state->str; - state->str = tmp; - state->num++; -} - -/* - * This function is used for query_txt parsing - */ -static void -pushval_asis(QPRS_STATE * state, int type, char *strval, int lenval) -{ - if (lenval > 0xffff) - elog(ERROR, "Word is too long"); - - pushquery(state, type, crc32_sz((uint8 *) strval, lenval), - state->curop - state->op, lenval); - - while (state->curop - state->op + lenval + 1 >= state->lenop) - { - int4 tmp = state->curop - state->op; - - state->lenop *= 2; - state->op = (char *) repalloc((void *) state->op, state->lenop); - state->curop = state->op + tmp; - } - memcpy((void *) state->curop, (void *) strval, lenval); - state->curop += lenval; - *(state->curop) = '\0'; - state->curop++; - state->sumlen += lenval + 1; - return; -} - -/* - * This function is used for mquery_txt parsing - */ -static void -pushval_morph(QPRS_STATE * state, int typeval, char *strval, int lenval) -{ - int4 type, - lenlemm; - int4 count = 0; - char *lemm; - - start_parse_str(strval, lenval); - while ((type = tsearch_yylex()) != 0) - { - if (tokenlen > 0xffff) - { - end_parse(); - elog(ERROR, "Word is too long"); - } - lenlemm = tokenlen; - lemm = lemmatize(token, &lenlemm, type); - if (lemm) - { - pushval_asis(state, VAL, lemm, lenlemm); - if (lemm != token) - pfree(lemm); - } - else - pushval_asis(state, VALTRUE, 0, 0); - if (count) - pushquery(state, OPR, (int4) '&', 0, 0); - count++; - } - end_parse(); -} - -#define STACKDEPTH 32 -/* - * make polish notaion of query - */ -static int4 -makepol(QPRS_STATE * state, void (*pushval) (QPRS_STATE *, int, char *, int)) -{ - int4 val, - type; - int4 lenval; - char *strval; - int4 stack[STACKDEPTH]; - int4 lenstack = 0; - - while ((type = gettoken_query(state, &val, &lenval, &strval)) != END) - { - switch (type) - { - case VAL: - (*pushval) (state, VAL, strval, lenval); - while (lenstack && (stack[lenstack - 1] == (int4) '&' || - stack[lenstack - 1] == (int4) '!')) - { - lenstack--; - pushquery(state, OPR, stack[lenstack], 0, 0); - } - break; - case OPR: - if (lenstack && val == (int4) '|') - pushquery(state, OPR, val, 0, 0); - else - { - if (lenstack == STACKDEPTH) - elog(ERROR, "Stack too short"); - stack[lenstack] = val; - lenstack++; - } - break; - case OPEN: - if (makepol(state, pushval) == ERR) - return ERR; - if (lenstack && (stack[lenstack - 1] == (int4) '&' || - stack[lenstack - 1] == (int4) '!')) - { - lenstack--; - pushquery(state, OPR, stack[lenstack], 0, 0); - } - break; - case CLOSE: - while (lenstack) - { - lenstack--; - pushquery(state, OPR, stack[lenstack], 0, 0); - }; - return END; - break; - case ERR: - default: - elog(ERROR, "Syntax error"); - return ERR; - - } - } - while (lenstack) - { - lenstack--; - pushquery(state, OPR, stack[lenstack], 0, 0); - }; - return END; -} - -typedef struct -{ - WordEntry *arrb; - WordEntry *arre; - char *values; - char *operand; -} CHKVAL; - -/* - * compare 2 string values - */ -static int4 -ValCompare(CHKVAL * chkval, WordEntry * ptr, ITEM * item) -{ - if (ptr->len == item->length) - return strncmp( - &(chkval->values[ptr->pos]), - &(chkval->operand[item->distance]), - item->length); - - return (ptr->len > item->length) ? 1 : -1; -} - -/* - * is there value 'val' in array or not ? - */ -static bool -checkcondition_str(void *checkval, ITEM * val) -{ - WordEntry *StopLow = ((CHKVAL *) checkval)->arrb; - WordEntry *StopHigh = ((CHKVAL *) checkval)->arre; - WordEntry *StopMiddle; - int difference; - - /* Loop invariant: StopLow <= val < StopHigh */ - - while (StopLow < StopHigh) - { - StopMiddle = StopLow + (StopHigh - StopLow) / 2; - difference = ValCompare((CHKVAL *) checkval, StopMiddle, val); - if (difference == 0) - return (true); - else if (difference < 0) - StopLow = StopMiddle + 1; - else - StopHigh = StopMiddle; - } - - return (false); -} - -/* - * check for boolean condition - */ -bool -execute(ITEM * curitem, void *checkval, bool calcnot, bool (*chkcond) (void *checkval, ITEM * val)) -{ - if (curitem->type == VAL) - return (*chkcond) (checkval, curitem); - else if (curitem->val == (int4) '!') - { - return (calcnot) ? - ((execute(curitem + 1, checkval, calcnot, chkcond)) ? false : true) - : true; - } - else if (curitem->val == (int4) '&') - { - if (execute(curitem + curitem->left, checkval, calcnot, chkcond)) - return execute(curitem + 1, checkval, calcnot, chkcond); - else - return false; - } - else - { /* |-operator */ - if (execute(curitem + curitem->left, checkval, calcnot, chkcond)) - return true; - else - return execute(curitem + 1, checkval, calcnot, chkcond); - } - return false; -} - -/* - * boolean operations - */ -Datum -rexecqtxt(PG_FUNCTION_ARGS) -{ - return DirectFunctionCall2( - execqtxt, - PG_GETARG_DATUM(1), - PG_GETARG_DATUM(0) - ); -} - -Datum -execqtxt(PG_FUNCTION_ARGS) -{ - txtidx *val = (txtidx *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); - QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(1))); - CHKVAL chkval; - bool result; - - if (!val->size) - { - PG_FREE_IF_COPY(val, 0); - PG_FREE_IF_COPY(query, 1); - PG_RETURN_BOOL(false); - } - - chkval.arrb = ARRPTR(val); - chkval.arre = chkval.arrb + val->size; - chkval.values = STRPTR(val); - chkval.operand = GETOPERAND(query); - result = execute( - GETQUERY(query), - &chkval, - true, - checkcondition_str - ); - - PG_FREE_IF_COPY(val, 0); - PG_FREE_IF_COPY(query, 1); - PG_RETURN_BOOL(result); -} - -/* - * find left operand in polish notation view - */ -static void -findoprnd(ITEM * ptr, int4 *pos) -{ -#ifdef BS_DEBUG - elog(DEBUG3, (ptr[*pos].type == OPR) ? - "%d %c" : "%d %d ", *pos, ptr[*pos].val); -#endif - if (ptr[*pos].type == VAL || ptr[*pos].type == VALTRUE) - { - ptr[*pos].left = 0; - (*pos)++; - } - else if (ptr[*pos].val == (int4) '!') - { - ptr[*pos].left = 1; - (*pos)++; - findoprnd(ptr, pos); - } - else - { - ITEM *curitem = &ptr[*pos]; - int4 tmp = *pos; - - (*pos)++; - findoprnd(ptr, pos); - curitem->left = *pos - tmp; - findoprnd(ptr, pos); - } -} - - -/* - * input - */ -static QUERYTYPE * -queryin(char *buf, void (*pushval) (QPRS_STATE *, int, char *, int)) -{ - QPRS_STATE state; - int4 i; - QUERYTYPE *query; - int4 commonlen; - ITEM *ptr; - NODE *tmp; - int4 pos = 0; - -#ifdef BS_DEBUG - char pbuf[16384], - *cur; -#endif - - /* init state */ - state.buf = buf; - state.state = WAITOPERAND; - state.count = 0; - state.num = 0; - state.str = NULL; - - /* init value parser's state */ - state.valstate.oprisdelim = true; - state.valstate.len = 32; - state.valstate.word = (char *) palloc(state.valstate.len); - - /* init list of operand */ - state.sumlen = 0; - state.lenop = 64; - state.curop = state.op = (char *) palloc(state.lenop); - *(state.curop) = '\0'; - - /* parse query & make polish notation (postfix, but in reverse order) */ - makepol(&state, pushval); - pfree(state.valstate.word); - if (!state.num) - elog(ERROR, "Empty query"); - - /* make finish struct */ - commonlen = COMPUTESIZE(state.num, state.sumlen); - query = (QUERYTYPE *) palloc(commonlen); - query->len = commonlen; - query->size = state.num; - ptr = GETQUERY(query); - - /* set item in polish notation */ - for (i = 0; i < state.num; i++) - { - ptr[i].type = state.str->type; - ptr[i].val = state.str->val; - ptr[i].distance = state.str->distance; - ptr[i].length = state.str->length; - tmp = state.str->next; - pfree(state.str); - state.str = tmp; - } - - /* set user friendly-operand view */ - memcpy((void *) GETOPERAND(query), (void *) state.op, state.sumlen); - pfree(state.op); - - /* set left operand's position for every operator */ - pos = 0; - findoprnd(ptr, &pos); - -#ifdef BS_DEBUG - cur = pbuf; - *cur = '\0'; - for (i = 0; i < query->size; i++) - { - if (ptr[i].type == OPR) - sprintf(cur, "%c(%d) ", ptr[i].val, ptr[i].left); - else - sprintf(cur, "%d(%s) ", ptr[i].val, GETOPERAND(query) + ptr[i].distance); - cur = strchr(cur, '\0'); - } - elog(DEBUG3, "POR: %s", pbuf); -#endif - - return query; -} - -/* - * in without morphology - */ -Datum -qtxt_in(PG_FUNCTION_ARGS) -{ - PG_RETURN_POINTER(queryin((char *) PG_GETARG_POINTER(0), pushval_asis)); -} - -/* - * in with morphology - */ -Datum -mqtxt_in(PG_FUNCTION_ARGS) -{ - QUERYTYPE *query; - ITEM *res; - int4 len; - -#ifdef BS_DEBUG - ITEM *ptr; - int4 i; - char pbuf[16384], - *cur; -#endif - initmorph(); - query = queryin((char *) PG_GETARG_POINTER(0), pushval_morph); - res = clean_fakeval(GETQUERY(query), &len); - if (!res) - { - pfree(query); - PG_RETURN_NULL(); - } - memcpy((void *) GETQUERY(query), (void *) res, len * sizeof(ITEM)); -#ifdef BS_DEBUG - cur = pbuf; - *cur = '\0'; - ptr = GETQUERY(query); - for (i = 0; i < len; i++) - { - if (ptr[i].type == OPR) - sprintf(cur, "%c(%d) ", ptr[i].val, ptr[i].left); - else - sprintf(cur, "%d(%s) ", ptr[i].val, GETOPERAND(query) + ptr[i].distance); - cur = strchr(cur, '\0'); - } - elog(DEBUG3, "POR: %s", pbuf); -#endif - pfree(res); - PG_RETURN_POINTER(query); -} - - -/* - * out function - */ -typedef struct -{ - ITEM *curpol; - char *buf; - char *cur; - char *op; - int4 buflen; -} INFIX; - -#define RESIZEBUF(inf,addsize) \ -while( ( inf->cur - inf->buf ) + addsize + 1 >= inf->buflen ) \ -{ \ - int4 len = inf->cur - inf->buf; \ - inf->buflen *= 2; \ - inf->buf = (char*) repalloc( (void*)inf->buf, inf->buflen ); \ - inf->cur = inf->buf + len; \ -} - -/* - * recursive walk on tree and print it in - * infix (human-readable) view - */ -static void -infix(INFIX * in, bool first) -{ - if (in->curpol->type == VAL) - { - char *op = in->op + in->curpol->distance; - - RESIZEBUF(in, in->curpol->length * 2 + 2); - *(in->cur) = '\''; - in->cur++; - while (*op) - { - if (*op == '\'') - { - *(in->cur) = '\\'; - in->cur++; - } - *(in->cur) = *op; - op++; - in->cur++; - } - *(in->cur) = '\''; - in->cur++; - *(in->cur) = '\0'; - in->curpol++; - } - else if (in->curpol->val == (int4) '!') - { - bool isopr = false; - - RESIZEBUF(in, 1); - *(in->cur) = '!'; - in->cur++; - *(in->cur) = '\0'; - in->curpol++; - if (in->curpol->type == OPR) - { - isopr = true; - RESIZEBUF(in, 2); - sprintf(in->cur, "( "); - in->cur = strchr(in->cur, '\0'); - } - infix(in, isopr); - if (isopr) - { - RESIZEBUF(in, 2); - sprintf(in->cur, " )"); - in->cur = strchr(in->cur, '\0'); - } - } - else - { - int4 op = in->curpol->val; - INFIX nrm; - - in->curpol++; - if (op == (int4) '|' && !first) - { - RESIZEBUF(in, 2); - sprintf(in->cur, "( "); - in->cur = strchr(in->cur, '\0'); - } - - nrm.curpol = in->curpol; - nrm.op = in->op; - nrm.buflen = 16; - nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen); - - /* get right operand */ - infix(&nrm, false); - - /* get & print left operand */ - in->curpol = nrm.curpol; - infix(in, false); - - /* print operator & right operand */ - RESIZEBUF(in, 3 + (nrm.cur - nrm.buf)); - sprintf(in->cur, " %c %s", op, nrm.buf); - in->cur = strchr(in->cur, '\0'); - pfree(nrm.buf); - - if (op == (int4) '|' && !first) - { - RESIZEBUF(in, 2); - sprintf(in->cur, " )"); - in->cur = strchr(in->cur, '\0'); - } - } -} - - -Datum -qtxt_out(PG_FUNCTION_ARGS) -{ - QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); - INFIX nrm; - - if (query->size == 0) - elog(ERROR, "Empty"); - nrm.curpol = GETQUERY(query); - nrm.buflen = 32; - nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen); - *(nrm.cur) = '\0'; - nrm.op = GETOPERAND(query); - infix(&nrm, true); - - PG_FREE_IF_COPY(query, 0); - PG_RETURN_POINTER(nrm.buf); -} - -/* - * debug function, used only for view query - * which will be executed in non-leaf pages in index - */ -Datum -querytree(PG_FUNCTION_ARGS) -{ - QUERYTYPE *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); - INFIX nrm; - text *res; - ITEM *q; - int4 len; - - - if (query->size == 0) - elog(ERROR, "Empty"); - - q = clean_NOT(GETQUERY(query), &len); - - if (!q) - { - res = (text *) palloc(1 + VARHDRSZ); - VARATT_SIZEP(res) = 1 + VARHDRSZ; - *((char *) VARDATA(res)) = 'T'; - } - else - { - nrm.curpol = q; - nrm.buflen = 32; - nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen); - *(nrm.cur) = '\0'; - nrm.op = GETOPERAND(query); - infix(&nrm, true); - - res = (text *) palloc(nrm.cur - nrm.buf + VARHDRSZ); - VARATT_SIZEP(res) = nrm.cur - nrm.buf + VARHDRSZ; - strncpy(VARDATA(res), nrm.buf, nrm.cur - nrm.buf); - pfree(q); - } - - PG_FREE_IF_COPY(query, 0); - - PG_RETURN_POINTER(res); -} diff --git a/contrib/tsearch/query.h b/contrib/tsearch/query.h deleted file mode 100644 index 6d55f6b411..0000000000 --- a/contrib/tsearch/query.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef __QUERY_H__ -#define __QUERY_H__ -/* -#define BS_DEBUG -*/ - - -/* - * item in polish notation with back link - * to left operand - */ -typedef struct ITEM -{ - int2 type; - int2 left; - int4 val; - /* user-friendly value */ - uint16 distance; - uint16 length; -} ITEM; - -/* - *Storage: - * (len)(size)(array of ITEM)(array of operand in user-friendly form) - */ -typedef struct -{ - int4 len; - int4 size; - char data[1]; -} QUERYTYPE; - -#define HDRSIZEQT ( 2*sizeof(int4) ) -#define COMPUTESIZE(size,lenofoperand) ( HDRSIZEQT + size * sizeof(ITEM) + lenofoperand ) -#define GETQUERY(x) (ITEM*)( (char*)(x)+HDRSIZEQT ) -#define GETOPERAND(x) ( (char*)GETQUERY(x) + ((QUERYTYPE*)x)->size * sizeof(ITEM) ) - -#define ISOPERATOR(x) ( (x)=='!' || (x)=='&' || (x)=='|' || (x)=='(' || (x)==')' ) - -#define END 0 -#define ERR 1 -#define VAL 2 -#define OPR 3 -#define OPEN 4 -#define CLOSE 5 -#define VALTRUE 6 /* for stop words */ -#define VALFALSE 7 - -bool execute(ITEM * curitem, void *checkval, - bool calcnot, bool (*chkcond) (void *checkval, ITEM * val)); - -#endif diff --git a/contrib/tsearch/rewrite.c b/contrib/tsearch/rewrite.c deleted file mode 100644 index 5036c420ff..0000000000 --- a/contrib/tsearch/rewrite.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Rewrite routines of query tree - * Teodor Sigaev - */ - -#include "postgres.h" - -#include - -#include "access/gist.h" -#include "access/itup.h" -#include "access/rtree.h" -#include "utils/elog.h" -#include "utils/palloc.h" -#include "utils/array.h" -#include "utils/builtins.h" -#include "storage/bufpage.h" - -#include "query.h" -#include "rewrite.h" - -typedef struct NODE -{ - struct NODE *left; - struct NODE *right; - ITEM *valnode; -} NODE; - -/* - * make query tree from plain view of query - */ -static NODE * -maketree(ITEM * in) -{ - NODE *node = (NODE *) palloc(sizeof(NODE)); - - node->valnode = in; - node->right = node->left = NULL; - if (in->type == OPR) - { - node->right = maketree(in + 1); - if (in->val != (int4) '!') - node->left = maketree(in + in->left); - } - return node; -} - -typedef struct -{ - ITEM *ptr; - int4 len; - int4 cur; -} PLAINTREE; - -static void -plainnode(PLAINTREE * state, NODE * node) -{ - if (state->cur == state->len) - { - state->len *= 2; - state->ptr = (ITEM *) repalloc((void *) state->ptr, state->len * sizeof(ITEM)); - } - memcpy((void *) &(state->ptr[state->cur]), (void *) node->valnode, sizeof(ITEM)); - if (node->valnode->type == VAL) - state->cur++; - else if (node->valnode->val == (int4) '!') - { - state->ptr[state->cur].left = 1; - state->cur++; - plainnode(state, node->right); - } - else - { - int4 cur = state->cur; - - state->cur++; - plainnode(state, node->right); - state->ptr[cur].left = state->cur - cur; - plainnode(state, node->left); - } - pfree(node); -} - -/* - * make plain view of tree from 'normal' view of tree - */ -static ITEM * -plaintree(NODE * root, int4 *len) -{ - PLAINTREE pl; - - pl.cur = 0; - pl.len = 16; - if (root && (root->valnode->type == VAL || root->valnode->type == OPR)) - { - pl.ptr = (ITEM *) palloc(pl.len * sizeof(ITEM)); - plainnode(&pl, root); - } - else - pl.ptr = NULL; - *len = pl.cur; - return pl.ptr; -} - -static void -freetree(NODE * node) -{ - if (!node) - return; - if (node->left) - freetree(node->left); - if (node->right) - freetree(node->right); - pfree(node); -} - -/* - * clean tree for ! operator. - * It's usefull for debug, but in - * other case, such view is used with search in index. - * Operator ! always return TRUE - */ -static NODE * -clean_NOT_intree(NODE * node) -{ - if (node->valnode->type == VAL) - return node; - - if (node->valnode->val == (int4) '!') - { - freetree(node); - return NULL; - } - - /* operator & or | */ - if (node->valnode->val == (int4) '|') - { - if ((node->left = clean_NOT_intree(node->left)) == NULL || - (node->right = clean_NOT_intree(node->right)) == NULL) - { - freetree(node); - return NULL; - } - } - else - { - NODE *res = node; - - node->left = clean_NOT_intree(node->left); - node->right = clean_NOT_intree(node->right); - if (node->left == NULL && node->right == NULL) - { - pfree(node); - res = NULL; - } - else if (node->left == NULL) - { - res = node->right; - pfree(node); - } - else if (node->right == NULL) - { - res = node->left; - pfree(node); - } - return res; - } - return node; -} - -ITEM * -clean_NOT(ITEM * ptr, int4 *len) -{ - NODE *root = maketree(ptr); - - return plaintree(clean_NOT_intree(root), len); -} - -#define V_UNKNOWN 0 -#define V_TRUE 1 -#define V_FALSE 2 - -/* - * Clean query tree from values which is always in - * text (stopword) - */ -static NODE * -clean_fakeval_intree(NODE * node, char *result) -{ - char lresult = V_UNKNOWN, - rresult = V_UNKNOWN; - - if (node->valnode->type == VAL) - return node; - else if (node->valnode->type == VALTRUE) - { - pfree(node); - *result = V_TRUE; - return NULL; - } - - - if (node->valnode->val == (int4) '!') - { - node->right = clean_fakeval_intree(node->right, &rresult); - if (!node->right) - { - *result = (rresult == V_TRUE) ? V_FALSE : V_TRUE; - freetree(node); - return NULL; - } - } - else if (node->valnode->val == (int4) '|') - { - NODE *res = node; - - node->left = clean_fakeval_intree(node->left, &lresult); - node->right = clean_fakeval_intree(node->right, &rresult); - if (lresult == V_TRUE || rresult == V_TRUE) - { - freetree(node); - *result = V_TRUE; - return NULL; - } - else if (lresult == V_FALSE && rresult == V_FALSE) - { - freetree(node); - *result = V_FALSE; - return NULL; - } - else if (lresult == V_FALSE) - { - res = node->right; - pfree(node); - } - else if (rresult == V_FALSE) - { - res = node->left; - pfree(node); - } - return res; - } - else - { - NODE *res = node; - - node->left = clean_fakeval_intree(node->left, &lresult); - node->right = clean_fakeval_intree(node->right, &rresult); - if (lresult == V_FALSE || rresult == V_FALSE) - { - freetree(node); - *result = V_FALSE; - return NULL; - } - else if (lresult == V_TRUE && rresult == V_TRUE) - { - freetree(node); - *result = V_TRUE; - return NULL; - } - else if (lresult == V_TRUE) - { - res = node->right; - pfree(node); - } - else if (rresult == V_TRUE) - { - res = node->left; - pfree(node); - } - return res; - } - return node; -} - -ITEM * -clean_fakeval(ITEM * ptr, int4 *len) -{ - NODE *root = maketree(ptr); - char result = V_UNKNOWN; - NODE *resroot; - - resroot = clean_fakeval_intree(root, &result); - if (result != V_UNKNOWN) - { - elog(ERROR, "Your query contained only stopword(s), ignored"); - *len = 0; - return NULL; - } - - return plaintree(resroot, len); -} diff --git a/contrib/tsearch/rewrite.h b/contrib/tsearch/rewrite.h deleted file mode 100644 index 6b3543faca..0000000000 --- a/contrib/tsearch/rewrite.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __REWRITE_H__ -#define __REWRITE_H__ - -ITEM *clean_NOT(ITEM * ptr, int4 *len); -ITEM *clean_fakeval(ITEM * ptr, int4 *len); - -#endif diff --git a/contrib/tsearch/sql/tsearch.sql b/contrib/tsearch/sql/tsearch.sql deleted file mode 100644 index d863fa743c..0000000000 --- a/contrib/tsearch/sql/tsearch.sql +++ /dev/null @@ -1,162 +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 tsearch.sql -\set ECHO all - ---txtidx -select '1'::txtidx; -select '1 '::txtidx; -select ' 1'::txtidx; -select ' 1 '::txtidx; -select '1 2'::txtidx; -select '\'1 2\''::txtidx; -select '\'1 \\\'2\''::txtidx; -select '\'1 \\\'2\'3'::txtidx; -select '\'1 \\\'2\' 3'::txtidx; -select '\'1 \\\'2\' \' 3\' 4 '::txtidx; - ---query_txt -select '1'::query_txt; -select '1 '::query_txt; -select ' 1'::query_txt; -select ' 1 '::query_txt; -select '\'1 2\''::query_txt; -select '\'1 \\\'2\''::query_txt; -select '!1'::query_txt; -select '1|2'::query_txt; -select '1|!2'::query_txt; -select '!1|2'::query_txt; -select '!1|!2'::query_txt; -select '!(!1|!2)'::query_txt; -select '!(!1|2)'::query_txt; -select '!(1|!2)'::query_txt; -select '!(1|2)'::query_txt; -select '1&2'::query_txt; -select '!1&2'::query_txt; -select '1&!2'::query_txt; -select '!1&!2'::query_txt; -select '(1&2)'::query_txt; -select '1&(2)'::query_txt; -select '!(1)&2'::query_txt; -select '!(1&2)'::query_txt; -select '1|2&3'::query_txt; -select '1|(2&3)'::query_txt; -select '(1|2)&3'::query_txt; -select '1|2&!3'::query_txt; -select '1|!2&3'::query_txt; -select '!1|2&3'::query_txt; -select '!1|(2&3)'::query_txt; -select '!(1|2)&3'::query_txt; -select '(!1|2)&3'::query_txt; -select '1|(2|(4|(5|6)))'::query_txt; -select '1|2|4|5|6'::query_txt; -select '1&(2&(4&(5&6)))'::query_txt; -select '1&2&4&5&6'::query_txt; -select '1&(2&(4&(5|6)))'::query_txt; -select '1&(2&(4&(5|!6)))'::query_txt; -select '1&(\'2\'&(\' 4\'&(\\|5 | \'6 \\\' !|&\')))'::query_txt; -select '1'::mquery_txt; -select '1 '::mquery_txt; -select ' 1'::mquery_txt; -select ' 1 '::mquery_txt; -select '\'1 2\''::mquery_txt; -select '\'1 \\\'2\''::mquery_txt; -select '!1'::mquery_txt; -select '1|2'::mquery_txt; -select '1|!2'::mquery_txt; -select '!1|2'::mquery_txt; -select '!1|!2'::mquery_txt; -select '!(!1|!2)'::mquery_txt; -select '!(!1|2)'::mquery_txt; -select '!(1|!2)'::mquery_txt; -select '!(1|2)'::mquery_txt; -select '1&2'::mquery_txt; -select '!1&2'::mquery_txt; -select '1&!2'::mquery_txt; -select '!1&!2'::mquery_txt; -select '(1&2)'::mquery_txt; -select '1&(2)'::mquery_txt; -select '!(1)&2'::mquery_txt; -select '!(1&2)'::mquery_txt; -select '1|2&3'::mquery_txt; -select '1|(2&3)'::mquery_txt; -select '(1|2)&3'::mquery_txt; -select '1|2&!3'::mquery_txt; -select '1|!2&3'::mquery_txt; -select '!1|2&3'::mquery_txt; -select '!1|(2&3)'::mquery_txt; -select '!(1|2)&3'::mquery_txt; -select '(!1|2)&3'::mquery_txt; -select '1|(2|(4|(5|6)))'::mquery_txt; -select '1|2|4|5|6'::mquery_txt; -select '1&(2&(4&(5&6)))'::mquery_txt; -select '1&2&4&5&6'::mquery_txt; -select '1&(2&(4&(5|6)))'::mquery_txt; -select '1&(2&(4&(5|!6)))'::mquery_txt; -select '1&(\'2\'&(\' 4\'&(\\|5 | \'6 \\\' !|&\')))'::mquery_txt; -select 'querty-fgries | http://www.google.com/index.html | www.rambler.ru/index.shtml'::mquery_txt; - -CREATE TABLE test_txtidx( t text, a txtidx ); - -\copy test_txtidx from 'data/test_tsearch.data' - -SELECT count(*) FROM test_txtidx WHERE a @@ 'wr|qh'; -SELECT count(*) FROM test_txtidx WHERE a @@ 'wr&qh'; -SELECT count(*) FROM test_txtidx WHERE a @@ 'eq&yt'; -SELECT count(*) FROM test_txtidx WHERE a @@ 'eq|yt'; -SELECT count(*) FROM test_txtidx WHERE a @@ '(eq&yt)|(wr&qh)'; -SELECT count(*) FROM test_txtidx WHERE a @@ '(eq|yt)&(wr|qh)'; - -SELECT count(*) FROM test_txtidx WHERE a ## 'wR|qh'; -SELECT count(*) FROM test_txtidx WHERE a ## 'wR&qh'; -SELECT count(*) FROM test_txtidx WHERE a ## 'eq&yt'; -SELECT count(*) FROM test_txtidx WHERE a ## 'eq|yt'; -SELECT count(*) FROM test_txtidx WHERE a ## '(eq&yt)|(wR&qh)'; -SELECT count(*) FROM test_txtidx WHERE a ## '(eq|yt)&(wR|qh)'; - -create index wowidx on test_txtidx using gist (a); - -SELECT count(*) FROM test_txtidx WHERE a @@ 'wr|qh'; -SELECT count(*) FROM test_txtidx WHERE a @@ 'wr&qh'; -SELECT count(*) FROM test_txtidx WHERE a @@ 'eq&yt'; -SELECT count(*) FROM test_txtidx WHERE a @@ 'eq|yt'; -SELECT count(*) FROM test_txtidx WHERE a @@ '(eq&yt)|(wr&qh)'; -SELECT count(*) FROM test_txtidx WHERE a @@ '(eq|yt)&(wr|qh)'; - -SELECT count(*) FROM test_txtidx WHERE a ## 'wR|qh'; -SELECT count(*) FROM test_txtidx WHERE a ## 'wR&qh'; -SELECT count(*) FROM test_txtidx WHERE a ## 'eq&yt'; -SELECT count(*) FROM test_txtidx WHERE a ## 'eq|yt'; -SELECT count(*) FROM test_txtidx WHERE a ## '(eq&yt)|(wR&qh)'; -SELECT count(*) FROM test_txtidx WHERE a ## '(eq|yt)&(wR|qh)'; - -select txt2txtidx('345 qwe@efd.r \' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 -/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234 - wow < jqw <> qwerty'); - -select txtidxsize(txt2txtidx('345 qw')); - -select txtidxsize(txt2txtidx('345 qwe@efd.r \' http://www.com/ http://aew.werc.ewr/?ad=qwe&dw 1aew.werc.ewr/?ad=qwe&dw 2aew.werc.ewr http://3aew.werc.ewr/?ad=qwe&dw http://4aew.werc.ewr http://5aew.werc.ewr:8100/? ad=qwe&dw 6aew.werc.ewr:8100/?ad=qwe&dw 7aew.werc.ewr:8100/?ad=qwe&dw=%20%32 +4.0e-10 qwe qwe qwqwe 234.435 455 5.005 teodor@stack.net qwe-wer asdf qwer jf sdjk ewr1> ewri2 -/usr/local/fff /awdf/dwqe/4325 rewt/ewr wefjn /wqe-324/ewr gist.h gist.h.c gist.c. readline 4.2 4.2. 4.2, readline-4.2 readline-4.2. 234 - wow < jqw <> qwerty')); - -insert into test_txtidx (a) values ('345 qwerty'); - -create trigger txtidxupdate before update or insert on test_txtidx -for each row execute procedure tsearch(a, t); - -insert into test_txtidx (t) values ('345 qwerty'); - -select count(*) FROM test_txtidx WHERE a @@ '345&qwerty'; - -select count(*) FROM test_txtidx WHERE a ## '345&qwerty'; - -update test_txtidx set t = null where t = '345 qwerty'; - -select count(*) FROM test_txtidx WHERE a ## '345&qwerty'; - -select count(*) FROM test_txtidx WHERE a @@ '345&qwerty'; - diff --git a/contrib/tsearch/tsearch.sql.in b/contrib/tsearch/tsearch.sql.in deleted file mode 100644 index e53793cf71..0000000000 --- a/contrib/tsearch/tsearch.sql.in +++ /dev/null @@ -1,251 +0,0 @@ -BEGIN TRANSACTION; - --- TXTIDX type - -CREATE FUNCTION txtidx_in(opaque) -RETURNS opaque -AS 'MODULE_PATHNAME' -LANGUAGE 'c' with (isstrict); - -CREATE FUNCTION txtidx_out(opaque) -RETURNS opaque -AS 'MODULE_PATHNAME' -LANGUAGE 'c' with (isstrict); - -CREATE TYPE txtidx ( -internallength = -1, -input = txtidx_in, -output = txtidx_out, -storage = extended -); - -CREATE FUNCTION txt2txtidx(text) -RETURNS txtidx -AS 'MODULE_PATHNAME' -LANGUAGE 'c' with (isstrict); - -CREATE FUNCTION txtidxsize(txtidx) -RETURNS int4 -AS 'MODULE_PATHNAME' -LANGUAGE 'c' with (isstrict); - ---QUERYTYPES ---without morphology -CREATE FUNCTION qtxt_in(opaque) -RETURNS opaque -AS 'MODULE_PATHNAME' -LANGUAGE 'c' with (isstrict); - -CREATE FUNCTION qtxt_out(opaque) -RETURNS opaque -AS 'MODULE_PATHNAME' -LANGUAGE 'c' with (isstrict); - -CREATE TYPE query_txt ( -internallength = -1, -input = qtxt_in, -output = qtxt_out -); - ---with morphology -CREATE FUNCTION mqtxt_in(opaque) -RETURNS opaque -AS 'MODULE_PATHNAME' -LANGUAGE 'c' with (isstrict); - -CREATE TYPE mquery_txt ( -internallength = -1, -input = mqtxt_in, -output = qtxt_out -); - ---only for debug -CREATE FUNCTION querytree(query_txt) -RETURNS text -AS 'MODULE_PATHNAME' -LANGUAGE 'c' with (isstrict); - -CREATE FUNCTION querytree(mquery_txt) -RETURNS text -AS 'MODULE_PATHNAME' -LANGUAGE 'c' with (isstrict); - ---operations -CREATE FUNCTION execqtxt(txtidx, query_txt) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION execqtxt(txtidx, query_txt) IS 'boolean operation with text index'; - -CREATE FUNCTION execqtxt(txtidx, mquery_txt) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION execqtxt(txtidx, mquery_txt) IS 'boolean operation with text index'; - -CREATE FUNCTION rexecqtxt(query_txt, txtidx) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION rexecqtxt(query_txt, txtidx) IS 'boolean operation with text index'; - -CREATE FUNCTION rexecqtxt(mquery_txt, txtidx) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -COMMENT ON FUNCTION rexecqtxt(mquery_txt, txtidx) IS 'boolean operation with text index'; - -CREATE OPERATOR @@ ( - LEFTARG = txtidx, RIGHTARG = query_txt, PROCEDURE = execqtxt, - COMMUTATOR = '~@', RESTRICT = contsel, JOIN = contjoinsel -); - -CREATE OPERATOR ~@ ( - LEFTARG = query_txt, RIGHTARG = txtidx, PROCEDURE = rexecqtxt, - COMMUTATOR = '@@', RESTRICT = contsel, JOIN = contjoinsel -); - -CREATE OPERATOR ## ( - LEFTARG = txtidx, RIGHTARG = mquery_txt, PROCEDURE = execqtxt, - COMMUTATOR = '~#', RESTRICT = contsel, JOIN = contjoinsel -); - -CREATE OPERATOR ~# ( - LEFTARG = mquery_txt, RIGHTARG = txtidx, PROCEDURE = rexecqtxt, - COMMUTATOR = '##', RESTRICT = contsel, JOIN = contjoinsel -); - ---Trigger -create function tsearch() returns opaque as - 'MODULE_PATHNAME' - language 'C'; - ---GiST ---GiST key type -CREATE FUNCTION gtxtidx_in(opaque) -RETURNS opaque -AS 'MODULE_PATHNAME' -LANGUAGE 'c' with (isstrict); - -CREATE FUNCTION gtxtidx_out(opaque) -RETURNS opaque -AS 'MODULE_PATHNAME' -LANGUAGE 'c' with (isstrict); - -CREATE TYPE gtxtidx ( -internallength = -1, -input = gtxtidx_in, -output = gtxtidx_out -); - -CREATE FUNCTION gtxtidx_consistent(gtxtidx,opaque,int4) RETURNS bool - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION gtxtidx_compress(opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION gtxtidx_decompress(opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION gtxtidx_penalty(opaque,opaque,opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c' with (isstrict); - -CREATE FUNCTION gtxtidx_picksplit(opaque, opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION gtxtidx_union(bytea, opaque) RETURNS _int4 - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -CREATE FUNCTION gtxtidx_same(gtxtidx, gtxtidx, opaque) RETURNS opaque - AS 'MODULE_PATHNAME' LANGUAGE 'c'; - -INSERT INTO pg_opclass (opcamid, opcname, opcnamespace, opcowner, opcintype, opcdefault, opckeytype) - VALUES ( - (SELECT oid FROM pg_am WHERE amname = 'gist'), - 'gist_txtidx_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 = 'txtidx'), - true, - (SELECT oid FROM pg_type WHERE typname = 'gtxtidx')); - -SELECT o.oid AS opoid, o.oprname -INTO TEMP TABLE txtidx_ops_tmp -FROM pg_operator o, pg_type t, pg_type tq -WHERE o.oprleft = t.oid and o.oprright=tq.oid - and t.typname = 'txtidx' - and ( tq.typname='query_txt' or tq.typname='mquery_txt' ); - -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 1, true, c.opoid - FROM pg_opclass opcl, txtidx_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_txtidx_ops' - and c.oprname = '@@'; - -INSERT INTO pg_amop (amopclaid, amopstrategy, amopreqcheck, amopopr) - SELECT opcl.oid, 2, true, c.opoid - FROM pg_opclass opcl, txtidx_ops_tmp c - WHERE - opcamid = (SELECT oid FROM pg_am WHERE amname = 'gist') - and opcname = 'gist_txtidx_ops' - and c.oprname = '##'; - -DROP TABLE txtidx_ops_tmp; - -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_txtidx_ops' - and proname = 'gtxtidx_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_txtidx_ops' - and proname = 'gtxtidx_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_txtidx_ops' - and proname = 'gtxtidx_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_txtidx_ops' - and proname = 'gtxtidx_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_txtidx_ops' - and proname = 'gtxtidx_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_txtidx_ops' - and proname = 'gtxtidx_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_txtidx_ops' - and proname = 'gtxtidx_same'; - - - -END TRANSACTION; diff --git a/contrib/tsearch/txtidx.c b/contrib/tsearch/txtidx.c deleted file mode 100644 index 14f69913b7..0000000000 --- a/contrib/tsearch/txtidx.c +++ /dev/null @@ -1,593 +0,0 @@ -/* - * In/Out definitions for txtidx type - * Internal structure: - * string of values, array of position lexem in string and it's length - * Teodor Sigaev - */ -#include "postgres.h" - -#include "access/gist.h" -#include "access/itup.h" -#include "utils/elog.h" -#include "utils/palloc.h" -#include "utils/builtins.h" -#include "storage/bufpage.h" -#include "executor/spi.h" -#include "commands/trigger.h" - -#include "utils/pg_locale.h" - -#include /* tolower */ -#include "txtidx.h" -#include "query.h" - -#include "deflex.h" -#include "parser.h" - -#include "morph.h" - -PG_FUNCTION_INFO_V1(txtidx_in); -Datum txtidx_in(PG_FUNCTION_ARGS); - -PG_FUNCTION_INFO_V1(txtidx_out); -Datum txtidx_out(PG_FUNCTION_ARGS); - -PG_FUNCTION_INFO_V1(txt2txtidx); -Datum txt2txtidx(PG_FUNCTION_ARGS); - -PG_FUNCTION_INFO_V1(tsearch); -Datum tsearch(PG_FUNCTION_ARGS); - -PG_FUNCTION_INFO_V1(txtidxsize); -Datum txtidxsize(PG_FUNCTION_ARGS); - -/* - * in/out text index type - */ -static char *BufferStr; -static int -compareentry(const void *a, const void *b) -{ - if (((WordEntry *) a)->len == ((WordEntry *) b)->len) - { - return strncmp( - &BufferStr[((WordEntry *) a)->pos], - &BufferStr[((WordEntry *) b)->pos], - ((WordEntry *) b)->len); - } - return (((WordEntry *) a)->len > ((WordEntry *) b)->len) ? 1 : -1; -} - -static int -uniqueentry(WordEntry * a, int4 l, char *buf, int4 *outbuflen) -{ - WordEntry *ptr, - *res; - - res = a; - *outbuflen = res->len; - if (l == 1) - return l; - - ptr = a + 1; - BufferStr = buf; - qsort((void *) a, l, sizeof(int4), compareentry); - *outbuflen = res->len; - - while (ptr - a < l) - { - if (!(ptr->len == res->len && - strncmp(&buf[ptr->pos], &buf[res->pos], res->len) == 0)) - { - res++; - res->len = ptr->len; - res->pos = ptr->pos; - *outbuflen += res->len; - - } - ptr++; - } - return res + 1 - a; -} - -#define WAITWORD 1 -#define WAITENDWORD 2 -#define WAITNEXTCHAR 3 -#define WAITENDCMPLX 4 - -#define RESIZEPRSBUF \ -do { \ - if ( state->curpos - state->word == state->len ) \ - { \ - int4 clen = state->curpos - state->word; \ - state->len *= 2; \ - state->word = (char*)repalloc( (void*)state->word, state->len ); \ - state->curpos = state->word + clen; \ - } \ -} while (0) - -int4 -gettoken_txtidx(TI_IN_STATE * state) -{ - int4 oldstate = 0; - - state->curpos = state->word; - state->state = WAITWORD; - - while (1) - { - if (state->state == WAITWORD) - { - if (*(state->prsbuf) == '\0') - return 0; - else if (*(state->prsbuf) == '\'') - state->state = WAITENDCMPLX; - else if (*(state->prsbuf) == '\\') - { - state->state = WAITNEXTCHAR; - oldstate = WAITENDWORD; - } - else if (state->oprisdelim && ISOPERATOR(*(state->prsbuf))) - elog(ERROR, "Syntax error"); - else if (*(state->prsbuf) != ' ') - { - *(state->curpos) = *(state->prsbuf); - state->curpos++; - state->state = WAITENDWORD; - } - } - else if (state->state == WAITNEXTCHAR) - { - if (*(state->prsbuf) == '\0') - elog(ERROR, "There is no escaped character"); - else - { - RESIZEPRSBUF; - *(state->curpos) = *(state->prsbuf); - state->curpos++; - state->state = oldstate; - } - } - else if (state->state == WAITENDWORD) - { - if (*(state->prsbuf) == '\\') - { - state->state = WAITNEXTCHAR; - oldstate = WAITENDWORD; - } - else if (*(state->prsbuf) == ' ' || *(state->prsbuf) == '\0' || - (state->oprisdelim && ISOPERATOR(*(state->prsbuf)))) - { - RESIZEPRSBUF; - if (state->curpos == state->word) - elog(ERROR, "Syntax error"); - *(state->curpos) = '\0'; - return 1; - } - else - { - RESIZEPRSBUF; - *(state->curpos) = *(state->prsbuf); - state->curpos++; - } - } - else if (state->state == WAITENDCMPLX) - { - if (*(state->prsbuf) == '\'') - { - RESIZEPRSBUF; - *(state->curpos) = '\0'; - if (state->curpos == state->word) - elog(ERROR, "Syntax error"); - state->prsbuf++; - return 1; - } - else if (*(state->prsbuf) == '\\') - { - state->state = WAITNEXTCHAR; - oldstate = WAITENDCMPLX; - } - else if (*(state->prsbuf) == '\0') - elog(ERROR, "Syntax error"); - else - { - RESIZEPRSBUF; - *(state->curpos) = *(state->prsbuf); - state->curpos++; - } - } - else - elog(ERROR, "Inner bug :("); - state->prsbuf++; - } - - return 0; -} - -Datum -txtidx_in(PG_FUNCTION_ARGS) -{ - char *buf = (char *) PG_GETARG_POINTER(0); - TI_IN_STATE state; - WordEntry *arr; - int4 len = 0, - totallen = 64; - txtidx *in; - char *tmpbuf, - *cur; - int4 i, - buflen = 256; - - state.prsbuf = buf; - state.len = 32; - state.word = (char *) palloc(state.len); - state.oprisdelim = false; - - arr = (WordEntry *) palloc(sizeof(WordEntry) * totallen); - cur = tmpbuf = (char *) palloc(buflen); - while (gettoken_txtidx(&state)) - { - if (len == totallen) - { - totallen *= 2; - arr = (WordEntry *) repalloc((void *) arr, sizeof(int4) * totallen); - } - while (cur - tmpbuf + state.curpos - state.word >= buflen) - { - int4 dist = cur - tmpbuf; - - buflen *= 2; - tmpbuf = (char *) repalloc((void *) tmpbuf, buflen); - cur = tmpbuf + dist; - } - if (state.curpos - state.word > 0xffff) - elog(ERROR, "Word is too long"); - arr[len].len = state.curpos - state.word; - if (cur - tmpbuf > 0xffff) - elog(ERROR, "Too long value"); - arr[len].pos = cur - tmpbuf; - memcpy((void *) cur, (void *) state.word, arr[len].len); - cur += arr[len].len; - len++; - } - pfree(state.word); - - if (!len) - elog(ERROR, "Void value"); - - len = uniqueentry(arr, len, tmpbuf, &buflen); - totallen = CALCDATASIZE(len, buflen); - in = (txtidx *) palloc(totallen); - in->len = totallen; - in->size = len; - cur = STRPTR(in); - for (i = 0; i < len; i++) - { - memcpy((void *) cur, (void *) &tmpbuf[arr[i].pos], arr[i].len); - arr[i].pos = cur - STRPTR(in); - cur += arr[i].len; - } - pfree(tmpbuf); - memcpy((void *) ARRPTR(in), (void *) arr, sizeof(int4) * len); - pfree(arr); - PG_RETURN_POINTER(in); -} - -Datum -txtidxsize(PG_FUNCTION_ARGS) -{ - txtidx *in = (txtidx *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); - int4 ret = in->size; - - PG_FREE_IF_COPY(in, 0); - PG_RETURN_INT32(ret); -} - -Datum -txtidx_out(PG_FUNCTION_ARGS) -{ - txtidx *out = (txtidx *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); - char *outbuf; - int4 i, - j, - lenbuf = STRSIZE(out) + 1 /* \0 */ + out->size * 2 /* '' */ + out->size - 1 /* space */ ; - WordEntry *ptr = ARRPTR(out); - char *curin, - *curout; - - curout = outbuf = (char *) palloc(lenbuf); - for (i = 0; i < out->size; i++) - { - curin = STRPTR(out) + ptr->pos; - if (i != 0) - *curout++ = ' '; - *curout++ = '\''; - j = ptr->len; - while (j--) - { - if (*curin == '\'') - { - int4 pos = curout - outbuf; - - outbuf = (char *) repalloc((void *) outbuf, ++lenbuf); - curout = outbuf + pos; - *curout++ = '\\'; - } - *curout++ = *curin++; - } - *curout++ = '\''; - ptr++; - } - outbuf[lenbuf - 1] = '\0'; - PG_FREE_IF_COPY(out, 0); - PG_RETURN_POINTER(outbuf); -} - -typedef struct -{ - uint16 len; - char *word; -} WORD; - -typedef struct -{ - WORD *words; - int4 lenwords; - int4 curwords; -} PRSTEXT; - -/* - * Parse text to lexems - */ -static void -parsetext(PRSTEXT * prs, char *buf, int4 buflen) -{ - int type, - lenlemm; - char *ptr, - *ptrw; - char *lemm; - - start_parse_str(buf, buflen); - while ((type = tsearch_yylex()) != 0) - { - if (prs->curwords == prs->lenwords) - { - prs->lenwords *= 2; - prs->words = (WORD *) repalloc((void *) prs->words, prs->lenwords * sizeof(WORD)); - } - if (tokenlen > 0xffff) - { - end_parse(); - elog(ERROR, "Word is too long"); - } - - lenlemm = tokenlen; - lemm = lemmatize(token, &lenlemm, type); - - if (!lemm) - continue; - - if (lemm != token) - { - prs->words[prs->curwords].len = lenlemm; - prs->words[prs->curwords].word = lemm; - } - else - { - prs->words[prs->curwords].len = lenlemm; - ptrw = prs->words[prs->curwords].word = (char *) palloc(lenlemm); - ptr = token; - while (ptr - token < lenlemm) - { - *ptrw = tolower((unsigned char) *ptr); - ptr++; - ptrw++; - } - } - prs->curwords++; - } - end_parse(); -} - -static int -compareWORD(const void *a, const void *b) -{ - if (((WORD *) a)->len == ((WORD *) b)->len) - return strncmp( - ((WORD *) a)->word, - ((WORD *) b)->word, - ((WORD *) b)->len); - return (((WORD *) a)->len > ((WORD *) b)->len) ? 1 : -1; -} - -static int -uniqueWORD(WORD *a, int4 l) -{ - WORD *ptr, - *res; - - if (l == 1) - return l; - - res = a; - ptr = a + 1; - - qsort((void *) a, l, sizeof(WORD), compareWORD); - - while (ptr - a < l) - { - if (!(ptr->len == res->len && - strncmp(ptr->word, res->word, res->len) == 0)) - { - res++; - res->len = ptr->len; - res->word = ptr->word; - } - else - pfree(ptr->word); - ptr++; - } - - return res + 1 - a; -} - -/* - * make value of txtidx - */ -static txtidx * -makevalue(PRSTEXT * prs) -{ - int4 i, - lenstr = 0, - totallen; - txtidx *in; - WordEntry *ptr; - char *str, - *cur; - - prs->curwords = uniqueWORD(prs->words, prs->curwords); - for (i = 0; i < prs->curwords; i++) - lenstr += prs->words[i].len; - - totallen = CALCDATASIZE(prs->curwords, lenstr); - in = (txtidx *) palloc(totallen); - in->len = totallen; - in->size = prs->curwords; - - ptr = ARRPTR(in); - cur = str = STRPTR(in); - for (i = 0; i < prs->curwords; i++) - { - ptr->len = prs->words[i].len; - if (cur - str > 0xffff) - elog(ERROR, "Value is too big"); - ptr->pos = cur - str; - ptr++; - memcpy((void *) cur, (void *) prs->words[i].word, prs->words[i].len); - pfree(prs->words[i].word); - cur += prs->words[i].len; - } - pfree(prs->words); - return in; -} - -Datum -txt2txtidx(PG_FUNCTION_ARGS) -{ - text *in = (text *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0))); - PRSTEXT prs; - txtidx *out = NULL; - - prs.lenwords = 32; - prs.curwords = 0; - prs.words = (WORD *) palloc(sizeof(WORD) * prs.lenwords); - - initmorph(); - parsetext(&prs, VARDATA(in), VARSIZE(in) - VARHDRSZ); - PG_FREE_IF_COPY(in, 0); - - if (prs.curwords) - { - out = makevalue(&prs); - PG_RETURN_POINTER(out); - } - pfree(prs.words); - PG_RETURN_NULL(); -} - -/* - * Trigger - */ -Datum -tsearch(PG_FUNCTION_ARGS) -{ - TriggerData *trigdata; - Trigger *trigger; - Relation rel; - HeapTuple rettuple = NULL; - int numidxattr, - i; - PRSTEXT prs; - Datum datum = (Datum) 0; - - - if (!CALLED_AS_TRIGGER(fcinfo)) - elog(ERROR, "TSearch: Not fired by trigger manager"); - - trigdata = (TriggerData *) fcinfo->context; - if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) - elog(ERROR, "TSearch: Can't process STATEMENT events"); - if (TRIGGER_FIRED_AFTER(trigdata->tg_event)) - elog(ERROR, "TSearch: Must be fired BEFORE event"); - - if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) - rettuple = trigdata->tg_trigtuple; - else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) - rettuple = trigdata->tg_newtuple; - else - elog(ERROR, "TSearch: Unknown event"); - - trigger = trigdata->tg_trigger; - rel = trigdata->tg_relation; - - if (trigger->tgnargs < 2) - elog(ERROR, "TSearch: format tsearch(txtidx_field, text_field1,...)"); - - numidxattr = SPI_fnumber(rel->rd_att, trigger->tgargs[0]); - if (numidxattr < 0) - elog(ERROR, "TSearch: Can not find txtidx_field"); - - prs.lenwords = 32; - prs.curwords = 0; - prs.words = (WORD *) palloc(sizeof(WORD) * prs.lenwords); - - initmorph(); - /* find all words in indexable column */ - for (i = 1; i < trigger->tgnargs; i++) - { - int4 numattr; - text *txt_toasted, - *txt; - bool isnull; - Oid oidtype; - - numattr = SPI_fnumber(rel->rd_att, trigger->tgargs[i]); - oidtype = SPI_gettypeid(rel->rd_att, numattr); - if (numattr < 0 || (!(oidtype == TEXTOID || oidtype == VARCHAROID))) - { - elog(WARNING, "TSearch: can not find field '%s'", trigger->tgargs[i]); - continue; - } - txt_toasted = (text *) DatumGetPointer(SPI_getbinval(rettuple, rel->rd_att, numattr, &isnull)); - if (isnull) - continue; - txt = (text *) DatumGetPointer(PG_DETOAST_DATUM(PointerGetDatum(txt_toasted))); - - parsetext(&prs, VARDATA(txt), VARSIZE(txt) - VARHDRSZ); - if (txt != txt_toasted) - pfree(txt); - } - - /* make txtidx value */ - if (prs.curwords) - { - datum = PointerGetDatum(makevalue(&prs)); - rettuple = SPI_modifytuple(rel, rettuple, 1, &numidxattr, - &datum, NULL); - pfree(DatumGetPointer(datum)); - } - else - { - char nulls = 'n'; - - pfree(prs.words); - rettuple = SPI_modifytuple(rel, rettuple, 1, &numidxattr, - &datum, &nulls); - } - - if (rettuple == NULL) - elog(ERROR, "TSearch: %d returned by SPI_modifytuple", SPI_result); - - return PointerGetDatum(rettuple); -} diff --git a/contrib/tsearch/txtidx.h b/contrib/tsearch/txtidx.h deleted file mode 100644 index f528cbd5e7..0000000000 --- a/contrib/tsearch/txtidx.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef __TXTIDX_H__ -#define __TXTIDX_H__ - -/* -#define TXTIDX_DEBUG -*/ - -#include "postgres.h" - -#include "access/gist.h" -#include "access/itup.h" -#include "utils/elog.h" -#include "utils/palloc.h" -#include "utils/builtins.h" -#include "storage/bufpage.h" - -typedef struct -{ - uint16 len; - uint16 pos; -} WordEntry; - -typedef struct -{ - int4 len; - int4 size; - char data[1]; -} txtidx; - -#define DATAHDRSIZE (sizeof(int4)*2) -#define CALCDATASIZE(x, lenstr) ( x * sizeof(WordEntry) + DATAHDRSIZE + lenstr ) -#define ARRPTR(x) ( (WordEntry*) ( (char*)x + DATAHDRSIZE ) ) -#define STRPTR(x) ( (char*)x + DATAHDRSIZE + ( sizeof(WordEntry) * ((txtidx*)x)->size ) ) -#define STRSIZE(x) ( ((txtidx*)x)->len - DATAHDRSIZE - ( sizeof(WordEntry) * ((txtidx*)x)->size ) ) - -typedef struct -{ - char *prsbuf; - char *word; - char *curpos; - int4 len; - int4 state; - bool oprisdelim; -} TI_IN_STATE; - -int4 gettoken_txtidx(TI_IN_STATE * state); - -#endif diff --git a/contrib/userlock/Makefile b/contrib/userlock/Makefile deleted file mode 100644 index e98d5586e4..0000000000 --- a/contrib/userlock/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/userlock/Attic/Makefile,v 1.16 2001/09/06 10:49:30 petere Exp $ - -subdir = contrib/userlock -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -MODULES = user_locks -DATA_built = user_locks.sql -DOCS = README.user_locks - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/userlock/README.user_locks b/contrib/userlock/README.user_locks deleted file mode 100644 index 48acdd1d5f..0000000000 --- a/contrib/userlock/README.user_locks +++ /dev/null @@ -1,54 +0,0 @@ -User locks, by Massimo Dal Zotto -Copyright (C) 1999, Massimo Dal Zotto - -This software is distributed under the GNU General Public License -either version 2, or (at your option) any later version. - - -This loadable module provides support for user-level long-term cooperative -locks. For example one can write: - - select some_fields, user_write_lock_oid(oid) from table where id='key'; - -Now if the returned user_write_lock_oid field is 1 you have acquired an -user lock on the oid of the selected tuple and can now do some long operation -on it, like let the data being edited by the user. -If it is 0 it means that the lock has been already acquired by some other -process and you should not use that item until the other has finished. -Note that in this case the query returns 0 immediately without waiting on -the lock. This is good if the lock is held for long time. -After you have finished your work on that item you can do: - - update table set some_fields where id='key'; - select user_write_unlock_oid(oid) from table where id='key'; - -You can also ignore the failure and go ahead but this could produce conflicts -or inconsistent data in your application. User locks require a cooperative -behavior between users. User locks don't interfere with the normal locks -used by Postgres for transaction processing. - -This could also be done by setting a flag in the record itself but in -this case you have the overhead of the updates to the records and there -could be some locks not released if the backend or the application crashes -before resetting the lock flag. -It could also be done with a begin/end block but in this case the entire -table would be locked by Postgres and it is not acceptable to do this for -a long period because other transactions would block completely. - -The generic user locks use two values, group and id, to identify a lock, -which correspond to ip_posid and ip_blkid of an ItemPointerData. -Group is a 16 bit value while id is a 32 bit integer which could also be -an oid. The oid user lock functions, which take only an oid as argument, -use a group equal to 0. - -The meaning of group and id is defined by the application. The user -lock code just takes two numbers and tells you if the corresponding -entity has been successfully locked. What this means is up to you. - -My suggestion is that you use the group to identify an area of your -application and the id to identify an object in this area. -Or you can just lock the oid of the tuples which are by definition unique. - -Note also that a process can acquire more than one lock on the same entity -and it must release the lock the corresponding number of times. This can -be done by calling the unlock function until it returns 0. diff --git a/contrib/userlock/user_locks.c b/contrib/userlock/user_locks.c deleted file mode 100644 index e1ee603f80..0000000000 --- a/contrib/userlock/user_locks.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * user_locks.c -- - * - * This loadable module provides support for user-level long-term - * cooperative locks. - * - * Copyright (C) 1999, Massimo Dal Zotto - * - * This software is distributed under the GNU General Public License - * either version 2, or (at your option) any later version. - */ -#include "postgres.h" - -#include "miscadmin.h" -#include "storage/lmgr.h" -#include "storage/proc.h" - -#include "user_locks.h" - - -int -user_lock(uint32 id1, uint32 id2, LOCKMODE lockmode) -{ - LOCKTAG tag; - - memset(&tag, 0, sizeof(LOCKTAG)); - tag.dbId = MyDatabaseId; - tag.relId = 0; - tag.objId.blkno = (BlockNumber) id2; - tag.offnum = (OffsetNumber) (id1 & 0xffff); - - return LockAcquire(USER_LOCKMETHOD, &tag, InvalidTransactionId, - lockmode, true); -} - -int -user_unlock(uint32 id1, uint32 id2, LOCKMODE lockmode) -{ - LOCKTAG tag; - - memset(&tag, 0, sizeof(LOCKTAG)); - tag.dbId = MyDatabaseId; - tag.relId = 0; - tag.objId.blkno = (BlockNumber) id2; - tag.offnum = (OffsetNumber) (id1 & 0xffff); - - return LockRelease(USER_LOCKMETHOD, &tag, InvalidTransactionId, lockmode); -} - -int -user_write_lock(uint32 id1, uint32 id2) -{ - return user_lock(id1, id2, ExclusiveLock); -} - - -int -user_write_unlock(uint32 id1, uint32 id2) -{ - return user_unlock(id1, id2, ExclusiveLock); -} - -int -user_write_lock_oid(Oid oid) -{ - return user_lock(0, oid, ExclusiveLock); -} - -int -user_write_unlock_oid(Oid oid) -{ - return user_unlock(0, oid, ExclusiveLock); -} - -int -user_unlock_all(void) -{ - return LockReleaseAll(USER_LOCKMETHOD, MyProc, false, - InvalidTransactionId); -} - -/* end of file */ - -/* - * Local Variables: - * tab-width: 4 - * c-indent-level: 4 - * c-basic-offset: 4 - * End: - */ diff --git a/contrib/userlock/user_locks.h b/contrib/userlock/user_locks.h deleted file mode 100644 index 526e864661..0000000000 --- a/contrib/userlock/user_locks.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef USER_LOCKS_H -#define USER_LOCKS_H - -int user_lock(unsigned int id1, unsigned int id2, LOCKMODE lockmode); -int user_unlock(unsigned int id1, unsigned int id2, LOCKMODE lockmode); -int user_write_lock(unsigned int id1, unsigned int id2); -int user_write_unlock(unsigned int id1, unsigned int id2); -int user_write_lock_oid(Oid oid); -int user_write_unlock_oid(Oid oid); -int user_unlock_all(void); -#endif - -/* - * Local Variables: - * tab-width: 4 - * c-indent-level: 4 - * c-basic-offset: 4 - * End: - */ diff --git a/contrib/userlock/user_locks.sql.in b/contrib/userlock/user_locks.sql.in deleted file mode 100644 index f5ae6a6e95..0000000000 --- a/contrib/userlock/user_locks.sql.in +++ /dev/null @@ -1,76 +0,0 @@ --- user_locks.sql -- --- --- SQL code to define the user locks functions. --- --- Copyright (c) 1998, Massimo Dal Zotto --- --- This file is distributed under the GNU General Public License --- either version 2, or (at your option) any later version. - --- select user_lock(group,id,mode); --- -create function user_lock(int4,int4,int4) returns int4 - as 'MODULE_PATHNAME' - language 'c'; - --- select user_unlock(group,id,mode); --- -create function user_unlock(int4,int4,int4) returns int4 - as 'MODULE_PATHNAME' - language 'c'; - --- select user_write_lock(group,id); --- -create function user_write_lock(int4,int4) returns int4 - as 'MODULE_PATHNAME' - language 'c'; - --- select user_write_unlock(group,id); --- -create function user_write_unlock(int4,int4) returns int4 - as 'MODULE_PATHNAME' - language 'c'; - --- select user_write_lock(group,oid); --- -create function user_write_lock(int4,oid) returns int4 - as 'MODULE_PATHNAME' - language 'c'; - --- select user_write_unlock(group,oid); --- -create function user_write_unlock(int4,oid) returns int4 - as 'MODULE_PATHNAME' - language 'c'; - --- select user_write_lock_oid(oid); --- -create function user_write_lock_oid(oid) returns int4 - as 'MODULE_PATHNAME' - language 'c'; - --- select user_write_unlock_oid(oid); --- -create function user_write_unlock_oid(oid) returns int4 - as 'MODULE_PATHNAME' - language 'c'; - --- select user_write_lock_oid(int4); --- -create function user_write_lock_oid(int4) returns int4 - as 'MODULE_PATHNAME' - language 'c'; - --- select user_write_unlock_oid(int4); --- -create function user_write_unlock_oid(int4) returns int4 - as 'MODULE_PATHNAME' - language 'c'; - --- select user_unlock_all(); --- -create function user_unlock_all() returns int4 - as 'MODULE_PATHNAME' - language 'c'; - --- end of file diff --git a/contrib/vacuumlo/Makefile b/contrib/vacuumlo/Makefile deleted file mode 100644 index 72724b4612..0000000000 --- a/contrib/vacuumlo/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# $Header: /cvsroot/pgsql/contrib/vacuumlo/Makefile,v 1.11 2001/09/06 10:49:30 petere Exp $ - -subdir = contrib/vacuumlo -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -PROGRAM = vacuumlo -OBJS = vacuumlo.o - -PG_CPPFLAGS = -I$(libpq_srcdir) -PG_LIBS = $(libpq) - -DOCS = README.vacuumlo - -include $(top_srcdir)/contrib/contrib-global.mk diff --git a/contrib/vacuumlo/README.vacuumlo b/contrib/vacuumlo/README.vacuumlo deleted file mode 100644 index 66a3323eb4..0000000000 --- a/contrib/vacuumlo/README.vacuumlo +++ /dev/null @@ -1,46 +0,0 @@ -$Header: /cvsroot/pgsql/contrib/vacuumlo/Attic/README.vacuumlo,v 1.2 2000/11/21 17:54:21 tgl Exp $ - -This is a simple utility that will remove any orphaned large objects out of a -PostgreSQL database. An orphaned LO is considered to be any LO whose OID -does not appear in any OID data column of the database. - - -Compiling --------- - -Simply run make. A single executable "vacuumlo" is created. - - -Usage ------ - -vacuumlo [-v] database [db2 ... dbn] - -The -v flag outputs some progress messages to stdout. - - -Method ------- - -First, it builds a temporary table which contains all of the oid's of the -large objects in that database. - -It then scans through all columns in the database that are of type 'oid', -and removes any matching entries from the temporary table. - -The remaining entries in the temp table identify orphaned LOs. These are -removed. - - -Notes ------ - -I decided to place this in contrib as it needs further testing, but hopefully, -this (or a variant of it) would make it into the backend as a "vacuum lo" -command in a later release. - -Peter Mount -http://www.retep.org.uk -March 21 1999 - -Committed April 10 1999 Peter diff --git a/contrib/vacuumlo/vacuumlo.c b/contrib/vacuumlo/vacuumlo.c deleted file mode 100644 index cbeb562b32..0000000000 --- a/contrib/vacuumlo/vacuumlo.c +++ /dev/null @@ -1,458 +0,0 @@ -/*------------------------------------------------------------------------- - * - * vacuumlo.c - * This removes orphaned large objects from a database. - * - * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group - * Portions Copyright (c) 1994, Regents of the University of California - * - * - * IDENTIFICATION - * $Header: /cvsroot/pgsql/contrib/vacuumlo/vacuumlo.c,v 1.12 2002/06/20 20:29:24 momjian Exp $ - * - *------------------------------------------------------------------------- - */ - -#include -#include -#include -#include - -#ifdef HAVE_TERMIOS_H -#include -#endif - -#include -#include -#include -#include - -#include "libpq-fe.h" -#include "libpq/libpq-fs.h" - -#define atooid(x) ((Oid) strtoul((x), NULL, 10)) - -#define BUFSIZE 1024 - -extern char *optarg; -extern int optind, opterr, optopt; - -struct _param { - char *pg_user; - int pg_prompt; - char *pg_port; - char *pg_host; - int verbose; - int dry_run; -}; - -int vacuumlo(char *, struct _param *); -char *simple_prompt(const char *prompt, int , int); -void usage(void); - - -/* - * simple_prompt - * - * 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 0 if you want to hide what is entered (for passwords) - * - * Returns a malloc()'ed string with the input (w/o trailing newline). - */ -static int prompt_state = 0; - -char * -simple_prompt(const char *prompt, int maxlen, int 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 = 1; /* 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(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 = 0; /* SIGINT okay again */ - - return destination; -} - - - -/* - * This vacuums LOs of one database. It returns 0 on success, -1 on failure. - */ -int -vacuumlo(char *database, struct _param *param) -{ - PGconn *conn; - PGresult *res, - *res2; - char buf[BUFSIZE]; - int matched; - int deleted; - int i; - char *password = NULL; - - if(param->pg_prompt) { - password = simple_prompt("Password: ", 32, 0); - if(!password) { - fprintf(stderr, "failed to get password\n"); - exit(1); - } - } - - conn = PQsetdbLogin( param->pg_host, - param->pg_port, - NULL, - NULL, - database, - param->pg_user, - password - ); - - /* check to see that the backend connection was successfully made */ - if (PQstatus(conn) == CONNECTION_BAD) - { - fprintf(stderr, "Connection to database '%s' failed:\n", database); - fprintf(stderr, "%s", PQerrorMessage(conn)); - PQfinish(conn); - return -1; - } - - if (param->verbose) { - fprintf(stdout, "Connected to %s\n", database); - if(param->dry_run) - fprintf(stdout, "Test run: no large objects will be removed!\n"); - } - - /* - * First we create and populate the LO temp table - */ - buf[0] = '\0'; - strcat(buf, "SELECT DISTINCT loid AS lo "); - strcat(buf, "INTO TEMP TABLE vacuum_l "); - strcat(buf, "FROM pg_largeobject "); - res = PQexec(conn, buf); - if (PQresultStatus(res) != PGRES_COMMAND_OK) - { - fprintf(stderr, "Failed to create temp table:\n"); - fprintf(stderr, "%s", PQerrorMessage(conn)); - PQclear(res); - PQfinish(conn); - return -1; - } - PQclear(res); - - /* - * Vacuum the temp table so that planner will generate decent plans - * for the DELETEs below. - */ - buf[0] = '\0'; - strcat(buf, "VACUUM ANALYZE vacuum_l "); - res = PQexec(conn, buf); - if (PQresultStatus(res) != PGRES_COMMAND_OK) - { - fprintf(stderr, "Failed to vacuum temp table:\n"); - fprintf(stderr, "%s", PQerrorMessage(conn)); - PQclear(res); - PQfinish(conn); - return -1; - } - PQclear(res); - - /* - * Now find any candidate tables who have columns of type oid. - * - * NOTE: the temp table formed above is ignored, because its real table - * name will be pg_something. Also, pg_largeobject will be ignored. - * If either of these were scanned, obviously we'd end up with nothing - * to delete... - * - * NOTE: the system oid column is ignored, as it has attnum < 1. This - * shouldn't matter for correctness, but it saves time. - */ - buf[0] = '\0'; - strcat(buf, "SELECT c.relname, a.attname "); - strcat(buf, "FROM pg_class c, pg_attribute a, pg_type t "); - strcat(buf, "WHERE a.attnum > 0 "); - strcat(buf, " AND a.attrelid = c.oid "); - strcat(buf, " AND a.atttypid = t.oid "); - strcat(buf, " AND t.typname in ('oid', 'lo') "); - strcat(buf, " AND c.relkind = 'r'"); - strcat(buf, " AND c.relname NOT LIKE 'pg_%'"); - res = PQexec(conn, buf); - if (PQresultStatus(res) != PGRES_TUPLES_OK) - { - fprintf(stderr, "Failed to find OID columns:\n"); - fprintf(stderr, "%s", PQerrorMessage(conn)); - PQclear(res); - PQfinish(conn); - return -1; - } - - for (i = 0; i < PQntuples(res); i++) - { - char *table, - *field; - - table = PQgetvalue(res, i, 0); - field = PQgetvalue(res, i, 1); - - if (param->verbose) - fprintf(stdout, "Checking %s in %s\n", field, table); - - /* - * We use a DELETE with implicit join for efficiency. This is a - * Postgres-ism and not portable to other DBMSs, but then this - * whole program is a Postgres-ism. - */ - sprintf(buf, "DELETE FROM vacuum_l WHERE lo = \"%s\".\"%s\" ", - table, field); - res2 = PQexec(conn, buf); - if (PQresultStatus(res2) != PGRES_COMMAND_OK) - { - fprintf(stderr, "Failed to check %s in table %s:\n", - field, table); - fprintf(stderr, "%s", PQerrorMessage(conn)); - PQclear(res2); - PQclear(res); - PQfinish(conn); - return -1; - } - PQclear(res2); - } - PQclear(res); - - /* - * Run the actual deletes in a single transaction. Note that this - * would be a bad idea in pre-7.1 Postgres releases (since rolling - * back a table delete used to cause problems), but it should be safe - * now. - */ - res = PQexec(conn, "begin"); - PQclear(res); - - /* - * Finally, those entries remaining in vacuum_l are orphans. - */ - buf[0] = '\0'; - strcat(buf, "SELECT lo "); - strcat(buf, "FROM vacuum_l"); - res = PQexec(conn, buf); - if (PQresultStatus(res) != PGRES_TUPLES_OK) - { - fprintf(stderr, "Failed to read temp table:\n"); - fprintf(stderr, "%s", PQerrorMessage(conn)); - PQclear(res); - PQfinish(conn); - return -1; - } - - matched = PQntuples(res); - deleted = 0; - for (i = 0; i < matched; i++) - { - Oid lo = atooid(PQgetvalue(res, i, 0)); - - if (param->verbose) - { - fprintf(stdout, "\rRemoving lo %6u ", lo); - fflush(stdout); - } - - if(param->dry_run == 0) { - if (lo_unlink(conn, lo) < 0) - { - fprintf(stderr, "\nFailed to remove lo %u: ", lo); - fprintf(stderr, "%s", PQerrorMessage(conn)); - } - else - deleted++; - } else - deleted++; - } - PQclear(res); - - /* - * That's all folks! - */ - res = PQexec(conn, "end"); - PQclear(res); - - PQfinish(conn); - - if (param->verbose) - fprintf(stdout, "\r%s %d large objects from %s.\n", - (param->dry_run?"Would remove":"Removed"), deleted, database); - - return 0; -} - -void -usage(void) { - fprintf(stdout, "vacuumlo removes unreferenced large objects from databases\n\n"); - fprintf(stdout, "Usage:\n vacuumlo [options] dbname [dbnames...]\n\n"); - fprintf(stdout, "Options:\n"); - fprintf(stdout, " -v\t\tWrite a lot of output\n"); - fprintf(stdout, " -n\t\tDon't remove any large object, just show what would be done\n"); - fprintf(stdout, " -U username\tUsername to connect as\n"); - fprintf(stdout, " -W\t\tPrompt for password\n"); - fprintf(stdout, " -h hostname\tDatabase server host\n"); - fprintf(stdout, " -p port\tDatabase server port\n"); - fprintf(stdout, " -p port\tDatabase server port\n\n"); -} - - -int -main(int argc, char **argv) -{ - int rc = 0; - struct _param param; - int c; - int port; - - /* Parameter handling */ - param.pg_user = NULL; - param.pg_prompt = 0; - param.pg_host = NULL; - param.pg_port = 0; - param.verbose = 0; - param.dry_run = 0; - - while( 1 ) { - c = getopt(argc, argv, "?h:U:p:vnW"); - if(c == -1) - break; - - switch(c) { - case '?': - if(optopt == '?') { - usage(); - exit(0); - } - exit(1); - case ':': - exit(1); - case 'v': - param.verbose = 1; - break; - case 'n': - param.dry_run = 1; - param.verbose = 1; - break; - case 'U': - param.pg_user = strdup(optarg); - break; - case 'W': - param.pg_prompt = 1; - break; - case 'p': - port = strtol(optarg, NULL, 10); - if( (port < 1) || (port > 65535)) { - fprintf(stderr, "[%s]: invalid port number '%s'\n", argv[0], optarg); - exit(1); - } - param.pg_port = strdup(optarg); - break; - case 'h': - param.pg_host = strdup(optarg); - break; - } - } - - /* No database given? Show usage */ - if(optind >= argc-1) { - fprintf(stderr, "vacuumlo: missing required argument: database name\n"); - fprintf(stderr, "Try 'vacuumlo -?' for help.\n"); - exit(1); - } - - for(c = optind; c < argc; c++) { - /* Work on selected database */ - rc += (vacuumlo(argv[c], ¶m) != 0); - } - - return rc; -} diff --git a/contrib/xml/Makefile b/contrib/xml/Makefile deleted file mode 100644 index a75ac095f6..0000000000 --- a/contrib/xml/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -#------------------------------------------------------------------------- -# -# Makefile-- -# Adapted from tutorial makefile -#------------------------------------------------------------------------- - -subdir = contrib/xml -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global - -override CFLAGS+= $(CFLAGS_SL) -g - - -# -# DLOBJS is the dynamically-loaded object files. The "funcs" queries -# include CREATE FUNCTIONs that load routines from these files. -# -DLOBJS= pgxml_dom$(DLSUFFIX) - - -QUERIES= pgxml_dom.sql - -all: $(DLOBJS) $(QUERIES) - -%.so: %.o - $(CC) -shared -lxml2 -o $@ $< - - -%.sql: %.source - if [ -z "$$USER" ]; then USER=$$LOGNAME; fi; \ - if [ -z "$$USER" ]; then USER=`whoami`; fi; \ - if [ -z "$$USER" ]; then echo 'Cannot deduce $$USER.'; exit 1; fi; \ - rm -f $@; \ - C=`pwd`; \ - sed -e "s:_CWD_:$$C:g" \ - -e "s:_OBJWD_:$$C:g" \ - -e "s:_DLSUFFIX_:$(DLSUFFIX):g" \ - -e "s/_USER_/$$USER/g" < $< > $@ - -clean: - rm -f $(DLOBJS) $(QUERIES) - - - - diff --git a/contrib/xml/README b/contrib/xml/README deleted file mode 100644 index 6c714f74e1..0000000000 --- a/contrib/xml/README +++ /dev/null @@ -1,118 +0,0 @@ -This package contains some simple routines for manipulating XML -documents stored in PostgreSQL. This is a work-in-progress and -somewhat basic at the moment (see the file TODO for some outline of -what remains to be done). - -At present, two modules (based on different XML handling libraries) -are provided. - -Prerequisite: - -pgxml.c: -expat parser 1.95.0 or newer (http://expat.sourceforge.net) - -or - -pgxml_dom.c: -libxml2 (http://xmlsoft.org) - -The libxml2 version provides more complete XPath functionality, and -seems like a good way to go. I've left the old versions in there for -comparison. - -Compiling and loading: ----------------------- - -The Makefile only builds the libxml2 version. - -To compile, just type make. - -Then you can use psql to load the two function definitions: -\i pgxml_dom.sql - - -Function documentation and usage: ---------------------------------- - -pgxml_parse(text) returns bool - parses the provided text and returns true or false if it is -well-formed or not. It returns NULL if the parser couldn't be -created for any reason. - -pgxml_xpath (XQuery functions) - differs between the versions: - -pgxml.c (expat version) has: - -pgxml_xpath(text doc, text xpath, int n) returns text - parses doc and returns the cdata of the nth occurence of -the "simple path" entry. - -However, the remainder of this document will cover the pgxml_dom.c version. - -pgxml_xpath(text doc, text xpath, text toptag, text septag) returns text - evaluates xpath on doc, and returns the result wrapped in -... and each result node wrapped in -. toptag and septag may be empty strings, in which -case the respective tag will be omitted. - -Example: - -Given a table docstore: - - Attribute | Type | Modifier ------------+---------+---------- - docid | integer | - document | text | - -containing documents such as (these are archaeological site -descriptions, in case anyone is wondering): - - - - Church Farm, Ashton Keynes - watching brief - SU04209424 - - -one can type: - -select docid, -pgxml_xpath(document,'//site/name/text()','','') as sitename, -pgxml_xpath(document,'//site/location/text()','','') as location - from docstore; - -and get as output: - - docid | sitename | location --------+--------------------------------------+------------ - 1 | Church Farm, Ashton Keynes | SU04209424 - 2 | Glebe Farm, Long Itchington | SP41506500 - 3 | The Bungalow, Thames Lane, Cricklade | SU10229362 -(3 rows) - -or, to illustrate the use of the extra tags: - -select docid as id, -pgxml_xpath(document,'//find/type/text()','set','findtype') -from docstore; - - id | pgxml_xpath -----+------------------------------------------------------------------------- - 1 | - 2 | Urn - 3 | PotteryAnimal bone -(3 rows) - -Which produces a new, well-formed document. Note that document 1 had -no matching instances, so the set returned contains no -elements. document 2 has 1 matching element and document 3 has 2. - -This is just scratching the surface because XPath allows all sorts of -operations. - -Note: I've only implemented the return of nodeset and string values so -far. This covers (I think) many types of queries, however. - -John Gray 16 August 2001 - - diff --git a/contrib/xml/TODO b/contrib/xml/TODO deleted file mode 100644 index 5ddd62a658..0000000000 --- a/contrib/xml/TODO +++ /dev/null @@ -1,78 +0,0 @@ -PGXML TODO List -=============== - -Some of these items still require much more thought! Since the first -release, the XPath support has improved (because I'm no longer using a -homemade algorithm!). - -1. Performance considerations - -At present each document is parsed to produce the DOM tree on every query. - -Pros: - Easy - No persistent memory or storage allocation for parsed trees - (libxml docs suggest representation of a document might - be 4 times the size of the text) - -Cons: - Slow/ CPU intensive to parse. - Makes it difficult for PLs to apply libxml manipulations to create - new documents or amend existing ones. - - -2. XQuery - -I'm not sure if the addition of XQuery would be best as a function or -as a new front-end parser. This is one to think about, but with a -decent implementation of XPath, one of the prerequisites is covered. - -3. DOM Interfaces - -Expose more aspects of the DOM to user functions/ PLs. This would -allow a procedure in a PL to run some queries and then use exposed -interfaces to libxml to create an XML document out of the query -results. I accept the argument that this might be more properly -performed on the client side. - -4. Returning sets of documents from XPath queries. - -Although the current implementation allows you to amalgamate the -returned results into a single document, it's quite possible that -you'd like to use the returned set of nodes as a source for FROM. - -Is there a good way to optimise/index the results of certain XPath -operations to make them faster?: - -select docid, pgxml_xpath(document,'//site/location/text()','','') as location -where pgxml_xpath(document,'//site/name/text()','','') = 'Church Farm'; - -and with multiple element occurences in a document? - -select d.docid, pgxml_xpath(d.document,'//site/location/text()','','') -from docstore d, -pgxml_xpaths('docstore','document','//feature/type/text()','docid') ft -where ft.key = d.docid and ft.value ='Limekiln'; - -pgxml_xpaths params are relname, attrname, xpath, returnkey. It would -return a set of two-element tuples (key,value) consisting of the value of -returnkey, and the cdata value of the xpath. The XML document would be -defined by relname and attrname. - -The pgxml_xpaths function could be the basis of a functional index, -which could speed up the above query very substantially, working -through the normal query planner mechanism. - -5. Return type support. - -Better support for returning e.g. numeric or boolean values. I need to -get to grips with the returned data from libxml first. - - -John Gray 16 August 2001 - - - - - - diff --git a/contrib/xml/pgxml.c b/contrib/xml/pgxml.c deleted file mode 100644 index 682e7395b9..0000000000 --- a/contrib/xml/pgxml.c +++ /dev/null @@ -1,347 +0,0 @@ -/******************************************************** - * Interface code to parse an XML document using expat - ********************************************************/ - -#include "postgres.h" -#include "fmgr.h" - -#include "expat.h" -#include "pgxml.h" - -/* Memory management - we make expat use standard pg MM */ - -XML_Memory_Handling_Suite mhs; - -/* passthrough functions (palloc is a macro) */ - -static void * -pgxml_palloc(size_t size) -{ - return palloc(size); -} - -static void * -pgxml_repalloc(void *ptr, size_t size) -{ - return repalloc(ptr, size); -} - -static void -pgxml_pfree(void *ptr) -{ - return pfree(ptr); -} - -static void -pgxml_mhs_init() -{ - mhs.malloc_fcn = pgxml_palloc; - mhs.realloc_fcn = pgxml_repalloc; - mhs.free_fcn = pgxml_pfree; -} - -static void -pgxml_handler_init() -{ - /* - * This code should set up the relevant handlers from user-supplied - * settings. Quite how these settings are made is another matter :) - */ -} - -/* Returns true if document is well-formed */ - -PG_FUNCTION_INFO_V1(pgxml_parse); - -Datum -pgxml_parse(PG_FUNCTION_ARGS) -{ - /* called as pgxml_parse(document) */ - XML_Parser p; - text *t = PG_GETARG_TEXT_P(0); /* document buffer */ - int32 docsize = VARSIZE(t) - VARHDRSZ; - - pgxml_mhs_init(); - - pgxml_handler_init(); - - p = XML_ParserCreate_MM(NULL, &mhs, NULL); - if (!p) - { - elog(ERROR, "pgxml: Could not create expat parser"); - PG_RETURN_NULL(); /* seems appropriate if we couldn't parse */ - } - - if (!XML_Parse(p, (char *) VARDATA(t), docsize, 1)) - { - /* - * elog(WARNING, "Parse error at line %d:%s", - * XML_GetCurrentLineNumber(p), - * XML_ErrorString(XML_GetErrorCode(p))); - */ - XML_ParserFree(p); - PG_RETURN_BOOL(false); - } - - XML_ParserFree(p); - PG_RETURN_BOOL(true); -} - -/* XPath handling functions */ - -/* XPath support here is for a very skeletal kind of XPath! - It was easy to program though... */ - -/* This first is the core function that builds a result set. The - actual functions called by the user manipulate that result set - in various ways. -*/ - -static XPath_Results * -build_xpath_results(text *doc, text *pathstr) -{ - XPath_Results *xpr; - char *res; - pgxml_udata *udata; - XML_Parser p; - int32 docsize; - - xpr = (XPath_Results *) palloc((sizeof(XPath_Results))); - memset((void *) xpr, 0, sizeof(XPath_Results)); - xpr->rescount = 0; - - docsize = VARSIZE(doc) - VARHDRSZ; - - /* res isn't going to be the real return type, it is just a buffer */ - - res = (char *) palloc(docsize); - memset((void *) res, 0, docsize); - - xpr->resbuf = res; - - udata = (pgxml_udata *) palloc((sizeof(pgxml_udata))); - memset((void *) udata, 0, sizeof(pgxml_udata)); - - udata->currentpath[0] = '\0'; - udata->textgrab = 0; - - udata->path = (char *) palloc(VARSIZE(pathstr)); - memcpy(udata->path, VARDATA(pathstr), VARSIZE(pathstr) - VARHDRSZ); - - udata->path[VARSIZE(pathstr) - VARHDRSZ] = '\0'; - - udata->resptr = res; - udata->reslen = 0; - - udata->xpres = xpr; - - /* Now fire up the parser */ - pgxml_mhs_init(); - - p = XML_ParserCreate_MM(NULL, &mhs, NULL); - if (!p) - { - elog(ERROR, "pgxml: Could not create expat parser"); - pfree(xpr); - pfree(udata->path); - pfree(udata); - pfree(res); - return NULL; - } - XML_SetUserData(p, (void *) udata); - - /* Set the handlers */ - - XML_SetElementHandler(p, pgxml_starthandler, pgxml_endhandler); - XML_SetCharacterDataHandler(p, pgxml_charhandler); - - if (!XML_Parse(p, (char *) VARDATA(doc), docsize, 1)) - { - /* - * elog(WARNING, "Parse error at line %d:%s", - * XML_GetCurrentLineNumber(p), - * XML_ErrorString(XML_GetErrorCode(p))); - */ - XML_ParserFree(p); - pfree(xpr); - pfree(udata->path); - pfree(udata); - - return NULL; - } - - pfree(udata->path); - pfree(udata); - XML_ParserFree(p); - return xpr; -} - - -PG_FUNCTION_INFO_V1(pgxml_xpath); - -Datum -pgxml_xpath(PG_FUNCTION_ARGS) -{ - /* called as pgxml_xpath(document,pathstr, index) for the moment */ - - XPath_Results *xpresults; - text *restext; - - text *t = PG_GETARG_TEXT_P(0); /* document buffer */ - text *t2 = PG_GETARG_TEXT_P(1); - int32 ind = PG_GETARG_INT32(2) - 1; - - xpresults = build_xpath_results(t, t2); - - /* - * This needs to be changed depending on the mechanism for returning - * our set of results. - */ - - if (xpresults == NULL) /* parse error (not WF or parser failure) */ - PG_RETURN_NULL(); - - if (ind >= (xpresults->rescount)) - PG_RETURN_NULL(); - - restext = (text *) palloc(xpresults->reslens[ind] + VARHDRSZ); - memcpy(VARDATA(restext), xpresults->results[ind], xpresults->reslens[ind]); - - VARATT_SIZEP(restext) = xpresults->reslens[ind] + VARHDRSZ; - - pfree(xpresults->resbuf); - pfree(xpresults); - - PG_RETURN_TEXT_P(restext); -} - - -static void -pgxml_pathcompare(void *userData) -{ - char *matchpos; - - matchpos = strstr(UD->currentpath, UD->path); - - if (matchpos == NULL) - { /* Should we have more logic here ? */ - if (UD->textgrab) - { - UD->textgrab = 0; - pgxml_finalisegrabbedtext(userData); - } - return; - } - - /* - * OK, we have a match of some sort. Now we need to check that our - * match is anchored to the *end* of the string AND that it is - * immediately preceded by a '/' - */ - - /* - * This test wouldn't work if strlen (UD->path) overran the length of - * the currentpath, but that's not possible because we got a match! - */ - - if ((matchpos + strlen(UD->path))[0] == '\0') - { - if ((UD->path)[0] == '/') - { - if (matchpos == UD->currentpath) - UD->textgrab = 1; - } - else - { - if ((matchpos - 1)[0] == '/') - UD->textgrab = 1; - } - } -} - -static void -pgxml_starthandler(void *userData, const XML_Char * name, - const XML_Char ** atts) -{ - - char sepstr[] = "/"; - - if ((strlen(name) + strlen(UD->currentpath)) > MAXPATHLENGTH - 2) - elog(WARNING, "Path too long"); - else - { - strncat(UD->currentpath, sepstr, 1); - strcat(UD->currentpath, name); - } - if (UD->textgrab) - { - /* - * Depending on user preference, should we "reconstitute" the - * element into the result text? - */ - } - else - pgxml_pathcompare(userData); -} - -static void -pgxml_endhandler(void *userData, const XML_Char * name) -{ - /* - * Start by removing the current element off the end of the - * currentpath - */ - - char *sepptr; - - sepptr = strrchr(UD->currentpath, '/'); - if (sepptr == NULL) - { - elog(ERROR, "There's a problem..."); - sepptr = UD->currentpath; - } - if (strcmp(name, sepptr + 1) != 0) - { - elog(WARNING, "Wanted [%s], got [%s]", sepptr, name); - /* unmatched entry, so do nothing */ - } - else - { - sepptr[0] = '\0'; /* Chop that element off the end */ - } - - if (UD->textgrab) - pgxml_pathcompare(userData); - -} - -static void -pgxml_charhandler(void *userData, const XML_Char * s, int len) -{ - if (UD->textgrab) - { - if (len > 0) - { - memcpy(UD->resptr, s, len); - UD->resptr += len; - UD->reslen += len; - } - } -} - -/* Should I be using PG list types here? */ - -static void -pgxml_finalisegrabbedtext(void *userData) -{ - /* In res/reslen, we have a single result. */ - UD->xpres->results[UD->xpres->rescount] = UD->resptr - UD->reslen; - UD->xpres->reslens[UD->xpres->rescount] = UD->reslen; - UD->reslen = 0; - UD->xpres->rescount++; - - /* - * This effectively concatenates all the results together but we do - * know where one ends and the next begins - */ -} diff --git a/contrib/xml/pgxml.h b/contrib/xml/pgxml.h deleted file mode 100644 index 2b80124b77..0000000000 --- a/contrib/xml/pgxml.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Header for pg xml parser interface */ - -static void *pgxml_palloc(size_t size); -static void *pgxml_repalloc(void *ptr, size_t size); -static void pgxml_pfree(void *ptr); -static void pgxml_mhs_init(); -static void pgxml_handler_init(); -Datum pgxml_parse(PG_FUNCTION_ARGS); -Datum pgxml_xpath(PG_FUNCTION_ARGS); -static void pgxml_starthandler(void *userData, const XML_Char * name, - const XML_Char ** atts); -static void pgxml_endhandler(void *userData, const XML_Char * name); -static void pgxml_charhandler(void *userData, const XML_Char * s, int len); -static void pgxml_pathcompare(void *userData); -static void pgxml_finalisegrabbedtext(void *userData); - -#define MAXPATHLENGTH 512 -#define MAXRESULTS 100 - - -typedef struct -{ - int rescount; - char *results[MAXRESULTS]; - int32 reslens[MAXRESULTS]; - char *resbuf; /* pointer to the result buffer for pfree */ -} XPath_Results; - - - -typedef struct -{ - char currentpath[MAXPATHLENGTH]; - char *path; - int textgrab; - char *resptr; - int32 reslen; - XPath_Results *xpres; -} pgxml_udata; - - -#define UD ((pgxml_udata *) userData) diff --git a/contrib/xml/pgxml.source b/contrib/xml/pgxml.source deleted file mode 100644 index 8a04fa2c9b..0000000000 --- a/contrib/xml/pgxml.source +++ /dev/null @@ -1,7 +0,0 @@ ---SQL for XML parser - -CREATE FUNCTION pgxml_parse(text) RETURNS bool - AS '_OBJWD_/pgxml_DLSUFFIX_' LANGUAGE 'c' WITH (isStrict); - -CREATE FUNCTION pgxml_xpath(text,text,text,text) RETURNS text - AS '_OBJWD_/pgxml_DLSUFFIX_' LANGUAGE 'c' WITH (isStrict); \ No newline at end of file diff --git a/contrib/xml/pgxml_dom.c b/contrib/xml/pgxml_dom.c deleted file mode 100644 index 0c22aced06..0000000000 --- a/contrib/xml/pgxml_dom.c +++ /dev/null @@ -1,262 +0,0 @@ -/* Parser interface for DOM-based parser (libxml) rather than - stream-based SAX-type parser */ - -#include "postgres.h" -#include "fmgr.h" - -/* libxml includes */ - -#include -#include -#include - -/* declarations */ - -static void *pgxml_palloc(size_t size); -static void *pgxml_repalloc(void *ptr, size_t size); -static void pgxml_pfree(void *ptr); -static char *pgxml_pstrdup(const char *string); - -static void pgxml_parser_init(); - -static xmlChar *pgxmlNodeSetToText(xmlNodeSetPtr nodeset, xmlDocPtr doc, - xmlChar * toptagname, xmlChar * septagname, - int format); - -static xmlChar *pgxml_texttoxmlchar(text *textstring); - - -Datum pgxml_parse(PG_FUNCTION_ARGS); -Datum pgxml_xpath(PG_FUNCTION_ARGS); - -/* memory handling passthrough functions (e.g. palloc, pstrdup are - currently macros, and the others might become so...) */ - -static void * -pgxml_palloc(size_t size) -{ - return palloc(size); -} - -static void * -pgxml_repalloc(void *ptr, size_t size) -{ - return repalloc(ptr, size); -} - -static void -pgxml_pfree(void *ptr) -{ - return pfree(ptr); -} - -static char * -pgxml_pstrdup(const char *string) -{ - return pstrdup(string); -} - -static void -pgxml_parser_init() -{ - /* - * This code should also set parser settings from user-supplied info. - * Quite how these settings are made is another matter :) - */ - - xmlMemSetup(pgxml_pfree, pgxml_palloc, pgxml_repalloc, pgxml_pstrdup); - xmlInitParser(); - -} - - -/* Returns true if document is well-formed */ - -PG_FUNCTION_INFO_V1(pgxml_parse); - -Datum -pgxml_parse(PG_FUNCTION_ARGS) -{ - /* called as pgxml_parse(document) */ - xmlDocPtr doctree; - text *t = PG_GETARG_TEXT_P(0); /* document buffer */ - int32 docsize = VARSIZE(t) - VARHDRSZ; - - pgxml_parser_init(); - - doctree = xmlParseMemory((char *) VARDATA(t), docsize); - if (doctree == NULL) - { - /* xmlCleanupParser(); */ - PG_RETURN_BOOL(false); /* i.e. not well-formed */ - } - /* xmlCleanupParser(); */ - xmlFreeDoc(doctree); - PG_RETURN_BOOL(true); -} - -static xmlChar -* -pgxmlNodeSetToText(xmlNodeSetPtr nodeset, - xmlDocPtr doc, - xmlChar * toptagname, - xmlChar * septagname, - int format) -{ - /* Function translates a nodeset into a text representation */ - - /* - * iterates over each node in the set and calls xmlNodeDump to write - * it to an xmlBuffer -from which an xmlChar * string is returned. - */ - /* each representation is surrounded by ... */ - /* if format==0, add a newline between nodes?? */ - - xmlBufferPtr buf; - xmlChar *result; - int i; - - buf = xmlBufferCreate(); - - if ((toptagname != NULL) && (xmlStrlen(toptagname) > 0)) - { - xmlBufferWriteChar(buf, "<"); - xmlBufferWriteCHAR(buf, toptagname); - xmlBufferWriteChar(buf, ">"); - } - if (nodeset != NULL) - { - for (i = 0; i < nodeset->nodeNr; i++) - { - if ((septagname != NULL) && (xmlStrlen(septagname) > 0)) - { - xmlBufferWriteChar(buf, "<"); - xmlBufferWriteCHAR(buf, septagname); - xmlBufferWriteChar(buf, ">"); - } - xmlNodeDump(buf, doc, nodeset->nodeTab[i], 1, (format == 2)); - - if ((septagname != NULL) && (xmlStrlen(septagname) > 0)) - { - xmlBufferWriteChar(buf, ""); - } - if (format) - xmlBufferWriteChar(buf, "\n"); - } - } - - if ((toptagname != NULL) && (xmlStrlen(toptagname) > 0)) - { - xmlBufferWriteChar(buf, ""); - } - result = xmlStrdup(buf->content); - xmlBufferFree(buf); - return result; -} - -static xmlChar * -pgxml_texttoxmlchar(text *textstring) -{ - xmlChar *res; - int32 txsize; - - txsize = VARSIZE(textstring) - VARHDRSZ; - res = (xmlChar *) palloc(txsize + 1); - memcpy((char *) res, VARDATA(textstring), txsize); - res[txsize] = '\0'; - return res; -} - - -PG_FUNCTION_INFO_V1(pgxml_xpath); - -Datum -pgxml_xpath(PG_FUNCTION_ARGS) -{ - xmlDocPtr doctree; - xmlXPathContextPtr ctxt; - xmlXPathObjectPtr res; - xmlChar *xpath, - *xpresstr, - *toptag, - *septag; - xmlXPathCompExprPtr comppath; - - int32 docsize, - ressize; - text *t, - *xpres; - - t = PG_GETARG_TEXT_P(0); /* document buffer */ - xpath = pgxml_texttoxmlchar(PG_GETARG_TEXT_P(1)); /* XPath expression */ - toptag = pgxml_texttoxmlchar(PG_GETARG_TEXT_P(2)); - septag = pgxml_texttoxmlchar(PG_GETARG_TEXT_P(3)); - - docsize = VARSIZE(t) - VARHDRSZ; - - pgxml_parser_init(); - - doctree = xmlParseMemory((char *) VARDATA(t), docsize); - if (doctree == NULL) - { /* not well-formed */ - PG_RETURN_NULL(); - } - - ctxt = xmlXPathNewContext(doctree); - ctxt->node = xmlDocGetRootElement(doctree); - - /* compile the path */ - comppath = xmlXPathCompile(xpath); - if (comppath == NULL) - { - elog(WARNING, "XPath syntax error"); - xmlFreeDoc(doctree); - pfree((void *) xpath); - PG_RETURN_NULL(); - } - - /* Now evaluate the path expression. */ - res = xmlXPathCompiledEval(comppath, ctxt); - xmlXPathFreeCompExpr(comppath); - - if (res == NULL) - { - xmlFreeDoc(doctree); - pfree((void *) xpath); - PG_RETURN_NULL(); /* seems appropriate */ - } - /* now we dump this node, ?surrounding by tags? */ - /* To do this, we look first at the type */ - switch (res->type) - { - case XPATH_NODESET: - xpresstr = pgxmlNodeSetToText(res->nodesetval, - doctree, - toptag, septag, 0); - break; - case XPATH_STRING: - xpresstr = xmlStrdup(res->stringval); - break; - default: - elog(WARNING, "Unsupported XQuery result: %d", res->type); - xpresstr = xmlStrdup(""); - } - - - /* Now convert this result back to text */ - ressize = strlen(xpresstr); - xpres = (text *) palloc(ressize + VARHDRSZ); - memcpy(VARDATA(xpres), xpresstr, ressize); - VARATT_SIZEP(xpres) = ressize + VARHDRSZ; - - /* Free various storage */ - xmlFreeDoc(doctree); - pfree((void *) xpath); - xmlFree(xpresstr); - - PG_RETURN_TEXT_P(xpres); -} diff --git a/contrib/xml/pgxml_dom.source b/contrib/xml/pgxml_dom.source deleted file mode 100644 index a8582398b1..0000000000 --- a/contrib/xml/pgxml_dom.source +++ /dev/null @@ -1,7 +0,0 @@ ---SQL for XML parser - -CREATE FUNCTION pgxml_parse(text) RETURNS bool - AS '_OBJWD_/pgxml_dom_DLSUFFIX_' LANGUAGE 'c' WITH (isStrict); - -CREATE FUNCTION pgxml_xpath(text,text,text,text) RETURNS text - AS '_OBJWD_/pgxml_dom_DLSUFFIX_' LANGUAGE 'c' WITH (isStrict); \ No newline at end of file diff --git a/doc/FAQ b/doc/FAQ deleted file mode 100644 index 4052044954..0000000000 --- a/doc/FAQ +++ /dev/null @@ -1,1057 +0,0 @@ - - Frequently Asked Questions (FAQ) for PostgreSQL - - Last updated: Tue Jun 11 06:36:10 EDT 2002 - - Current maintainer: Bruce Momjian (pgman@candle.pha.pa.us) - - The most recent version of this document can be viewed at - http://www.PostgreSQL.org/docs/faq-english.html. - - Platform-specific questions are answered at - http://www.PostgreSQL.org/users-lounge/docs/faq.html. - _________________________________________________________________ - - General Questions - - 1.1) What is PostgreSQL? How is it pronounced? - 1.2) What is the copyright on PostgreSQL? - 1.3) What Unix platforms does PostgreSQL run on? - 1.4) What non-Unix ports are available? - 1.5) Where can I get PostgreSQL? - 1.6) Where can I get support? - 1.7) What is the latest release? - 1.8) What documentation is available? - 1.9) How do I find out about known bugs or missing features? - 1.10) How can I learn SQL? - 1.11) Is PostgreSQL Y2K compliant? - 1.12) How do I join the development team? - 1.13) How do I submit a bug report? - 1.14) How does PostgreSQL compare to other DBMSs? - 1.15) How can I financially assist PostgreSQL? - - User Client Questions - - 2.1) Are there ODBC drivers for PostgreSQL? - 2.2) What tools are available for using PostgreSQL with Web pages? - 2.3) Does PostgreSQL have a graphical user interface? A report - generator? An embedded query language interface? - 2.4) What languages are available to communicate with PostgreSQL? - - Administrative Questions - - 3.1) How do I install PostgreSQL somewhere other than - /usr/local/pgsql? - 3.2) When I start postmaster, I get a Bad System Call or core dumped - message. Why? - 3.3) When I try to start postmaster, I get IpcMemoryCreate errors. - Why? - 3.4) When I try to start postmaster, I get IpcSemaphoreCreate errors. - Why? - 3.5) How do I control connections from other hosts? - 3.6) How do I tune the database engine for better performance? - 3.7) What debugging features are available? - 3.8) Why do I get "Sorry, too many clients" when trying to connect? - 3.9) What are the pg_sorttempNNN.NN files in my database directory? - - Operational Questions - - 4.1) What is the difference between binary cursors and normal cursors? - 4.2) How do I SELECT only the first few rows of a query? - 4.3) How do I get a list of tables or other things I can see in psql? - 4.4) How do you remove a column from a table? - 4.5) What is the maximum size for a row, a table, and a database? - 4.6) How much database disk space is required to store data from a - typical text file? - 4.7) How do I find out what tables, indexes, databases, and users are - defined? - 4.8) My queries are slow or don't make use of the indexes. Why? - 4.9) How do I see how the query optimizer is evaluating my query? - 4.10) What is an R-tree index? - 4.11) What is the Genetic Query Optimizer? - 4.12) How do I perform regular expression searches and - case-insensitive regular expression searches? How do I use an index - for case-insensitive searches? - 4.13) In a query, how do I detect if a field is NULL? - 4.14) What is the difference between the various character types? - 4.15.1) How do I create a serial/auto-incrementing field? - 4.15.2) How do I get the value of a SERIAL insert? - 4.15.3) Don't currval() and nextval() lead to a race condition with - other users? - 4.15.4) Why aren't my sequence numbers reused on transaction abort? - Why are there gaps in the numbering of my sequence/SERIAL column? - 4.16) What is an OID? What is a TID? - 4.17) What is the meaning of some of the terms used in PostgreSQL? - 4.18) Why do I get the error "ERROR: Memory exhausted in - AllocSetAlloc()"? - 4.19) How do I tell what PostgreSQL version I am running? - 4.20) Why does my large-object operations get "invalid large obj - descriptor"? - 4.21) How do I create a column that will default to the current time? - 4.22) Why are my subqueries using IN so slow? - 4.23) How do I perform an outer join? - 4.24) How do I perform queries using multiple databases? - 4.25) How do I return multiple rows or columns from a function? - 4.26) Why can't I reliably create/drop temporary tables in PL/PgSQL - functions? - - Extending PostgreSQL - - 5.1) I wrote a user-defined function. When I run it in psql, why does - it dump core? - 5.2) How can I contribute some nifty new types and functions to - PostgreSQL? - 5.3) How do I write a C function to return a tuple? - 5.4) I have changed a source file. Why does the recompile not see the - change? - _________________________________________________________________ - - General Questions - - 1.1) What is PostgreSQL? - - PostgreSQL is pronounced Post-Gres-Q-L. - - PostgreSQL is an enhancement of the POSTGRES database management - system, a next-generation DBMS research prototype. While PostgreSQL - retains the powerful data model and rich data types of POSTGRES, it - replaces the PostQuel query language with an extended subset of SQL. - PostgreSQL is free and the complete source is available. - - PostgreSQL development is performed by a team of Internet developers - who all subscribe to the PostgreSQL development mailing list. The - current coordinator is Marc G. Fournier (scrappy@PostgreSQL.org). (See - below on how to join). This team is now responsible for all - development of PostgreSQL. - - The authors of PostgreSQL 1.01 were Andrew Yu and Jolly Chen. Many - others have contributed to the porting, testing, debugging, and - enhancement of the code. The original Postgres code, from which - PostgreSQL is derived, was the effort of many graduate students, - undergraduate students, and staff programmers working under the - direction of Professor Michael Stonebraker at the University of - California, Berkeley. - - The original name of the software at Berkeley was Postgres. When SQL - functionality was added in 1995, its name was changed to Postgres95. - The name was changed at the end of 1996 to PostgreSQL. - - 1.2) What is the copyright on PostgreSQL? - - PostgreSQL is subject to the following COPYRIGHT: - - PostgreSQL Data Base Management System - - Portions copyright (c) 1996-2002, PostgreSQL Global Development Group - Portions Copyright (c) 1994-6 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. - - The above is the BSD license, the classic open-source license. It has - no restrictions on how the source code may be used. We like it and - have no intention of changing it. - - 1.3) What Unix platforms does PostgreSQL run on? - - In general, a modern Unix-compatible platform should be able to run - PostgreSQL. The platforms that had received explicit testing at the - time of release are listed in the installation instructions. - - 1.4) What non-Unix ports are available? - - Client - - It is possible to compile the libpq C library, psql, and other - interfaces and binaries to run on MS Windows platforms. In this case, - the client is running on MS Windows, and communicates via TCP/IP to a - server running on one of our supported Unix platforms. A file - win31.mak is included in the distribution for making a Win32 libpq - library and psql. PostgreSQL also communicates with ODBC clients. - - Server - - The database server can run on Windows NT and Win2k using Cygwin, the - Cygnus Unix/NT porting library. See pgsql/doc/FAQ_MSWIN in the - distribution or the MS Windows FAQ on our web site. We have no plan to - do a native port to any Microsoft platform. - - 1.5) Where can I get PostgreSQL? - - The primary anonymous ftp site for PostgreSQL is - ftp://ftp.PostgreSQL.org/pub. For mirror sites, see our main web site. - - 1.6) Where can I get support? - - The main mailing list is: pgsql-general@PostgreSQL.org. It is - available for discussion of matters pertaining to PostgreSQL. To - subscribe, send mail with the following lines in the body (not the - subject line): - subscribe - end - - to pgsql-general-request@PostgreSQL.org. - - There is also a digest list available. To subscribe to this list, send - email to: pgsql-general-digest-request@PostgreSQL.org with a body of: - subscribe - end - - Digests are sent out to members of this list whenever the main list - has received around 30k of messages. - - The bugs mailing list is available. To subscribe to this list, send - email to pgsql-bugs-request@PostgreSQL.org with a body of: - subscribe - end - - There is also a developers discussion mailing list available. To - subscribe to this list, send email to - pgsql-hackers-request@PostgreSQL.org with a body of: - subscribe - end - - Additional mailing lists and information about PostgreSQL can be found - via the PostgreSQL WWW home page at: - - http://www.PostgreSQL.org - - There is also an IRC channel on EFNet, channel #PostgreSQL. I use the - Unix command irc -c '#PostgreSQL' "$USER" irc.phoenix.net. - - A list of commercial support companies is available at - http://www.postgresql.org/users-lounge/commercial-support.html. - - 1.7) What is the latest release? - - The latest release of PostgreSQL is version 7.2.1. - - We plan to have major releases every four months. - - 1.8) What documentation is available? - - Several manuals, manual pages, and some small test examples are - included in the distribution. See the /doc directory. You can also - browse the manual online at - http://www.PostgreSQL.org/users-lounge/docs/. - - There are two PostgreSQL books available online at - http://www.PostgreSQL.org/docs/awbook.html and - http://www.commandprompt.com/ppbook/. There is a list of PostgreSQL - books available for purchase at http://www.postgresql.org/books/. - There is also a collection of PostgreSQL technical articles at - http://techdocs.postgresql.org/. - - psql has some nice \d commands to show information about types, - operators, functions, aggregates, etc. - - Our web site contains even more documentation. - - 1.9) How do I find out about known bugs or missing features? - - PostgreSQL supports an extended subset of SQL-92. See our TODO list - for known bugs, missing features, and future plans. - - 1.10) How can I learn SQL? - - The PostgreSQL book at http://www.PostgreSQL.org/docs/awbook.html - teaches SQL. There is another PostgreSQL book at - http://www.commandprompt.com/ppbook. There is a nice tutorial at - http://www.intermedia.net/support/sql/sqltut.shtm, at - http://ourworld.compuserve.com/homepages/graeme_birchall/HTM_COOK.HTM, - and at http://sqlcourse.com. - - Another one is "Teach Yourself SQL in 21 Days, Second Edition" at - http://members.tripod.com/er4ebus/sql/index.htm - - Many of our users like The Practical SQL Handbook, Bowman, Judith S., - et al., Addison-Wesley. Others like The Complete Reference SQL, Groff - et al., McGraw-Hill. - - 1.11) Is PostgreSQL Y2K compliant? - - Yes, we easily handle dates past the year 2000 AD, and before 2000 BC. - - 1.12) How do I join the development team? - - First, download the latest source and read the PostgreSQL Developers - documentation on our web site, or in the distribution. Second, - subscribe to the pgsql-hackers and pgsql-patches mailing lists. Third, - submit high quality patches to pgsql-patches. - - There are about a dozen people who have commit privileges to the - PostgreSQL CVS archive. They each have submitted so many high-quality - patches that it was impossible for the existing committers to keep up, - and we had confidence that patches they committed were of high - quality. - - 1.13) How do I submit a bug report? - - Please visit the PostgreSQL BugTool page, which gives guidelines and - directions on how to submit a bug. - - Also check out our ftp site ftp://ftp.PostgreSQL.org/pub to see if - there is a more recent PostgreSQL version or patches. - - 1.14) How does PostgreSQL compare to other DBMSs? - - There are several ways of measuring software: features, performance, - reliability, support, and price. - - Features - PostgreSQL has most features present in large commercial DBMSs, - like transactions, subselects, triggers, views, foreign key - referential integrity, and sophisticated locking. We have some - features they do not have, like user-defined types, - inheritance, rules, and multi-version concurrency control to - reduce lock contention. - - Performance - PostgreSQL has performance similar to other commercial and open - source databases. it is faster for some things, slower for - others. In comparison to MySQL or leaner database systems, we - are slower on inserts/updates because of transaction overhead. - Of course, MySQL does not have any of the features mentioned in - the Features section above. We are built for reliability and - features, though we continue to improve performance in every - release. There is an interesting Web page comparing PostgreSQL - to MySQL at http://openacs.org/why-not-mysql.html - - Reliability - We realize that a DBMS must be reliable, or it is worthless. We - strive to release well-tested, stable code that has a minimum - of bugs. Each release has at least one month of beta testing, - and our release history shows that we can provide stable, solid - releases that are ready for production use. We believe we - compare favorably to other database software in this area. - - Support - Our mailing list provides a large group of developers and users - to help resolve any problems encountered. While we can not - guarantee a fix, commercial DBMSs do not always supply a fix - either. Direct access to developers, the user community, - manuals, and the source code often make PostgreSQL support - superior to other DBMSs. There is commercial per-incident - support available for those who need it. (See support FAQ - item.) - - Price - We are free for all use, both commercial and non-commercial. - You can add our code to your product with no limitations, - except those outlined in our BSD-style license stated above. - - 1.15) How can I financially assist PostgreSQL? - - PostgreSQL has had a first-class infrastructure since we started six - years ago. This is all thanks to Marc Fournier, who has created and - managed this infrastructure over the years. - - Quality infrastructure is very important to an open-source project. It - prevents disruptions that can greatly delay forward movement of the - project. - - Of course, this infrastructure is not cheap. There are a variety of - monthly and one-time expenses that are required to keep it going. If - you or your company has money it can donate to help fund this effort, - please go to http://www.pgsql.com/pg_goodies and make a donation. - - Although the web page mentions PostgreSQL, Inc, the "contributions" - item is solely to support the PostgreSQL project and does not fund any - specific company. If you prefer, you can also send a check to the - contact address. - _________________________________________________________________ - - User Client Questions - - 2.1) Are there ODBC drivers for PostgreSQL? - - There are two ODBC drivers available, PsqlODBC and OpenLink ODBC. - - PsqlODBC is included in the distribution. More information about it - can be gotten from ftp://ftp.PostgreSQL.org/pub/odbc/. - - OpenLink ODBC can be gotten from http://www.openlinksw.com. It works - with their standard ODBC client software so you'll have PostgreSQL - ODBC available on every client platform they support (Win, Mac, Unix, - VMS). - - They will probably be selling this product to people who need - commercial-quality support, but a freeware version will always be - available. Please send questions to postgres95@openlink.co.uk. - - See also the ODBC chapter of the Programmer's Guide. - - 2.2) What tools are available for using PostgreSQL with Web pages? - - A nice introduction to Database-backed Web pages can be seen at: - http://www.webreview.com - - There is also one at http://www.phone.net/home/mwm/hotlist/. - - For Web integration, PHP is an excellent interface. It is at - http://www.php.net. - - For complex cases, many use the Perl interface and CGI.pm. - - 2.3) Does PostgreSQL have a graphical user interface? A report generator? - An embedded query language interface? - - We have a nice graphical user interface called pgaccess, which is - shipped as part of the distribution. pgaccess also has a report - generator. The Web page is http://www.flex.ro/pgaccess - - We also include ecpg, which is an embedded SQL query language - interface for C. - - 2.4) What languages are available to communicate with PostgreSQL? - - We have: - * C (libpq) - * C++ (libpq++) - * Embedded C (ecpg) - * Java (jdbc) - * Perl (perl5) - * ODBC (odbc) - * Python (PyGreSQL) - * TCL (libpgtcl) - * C Easy API (libpgeasy) - * Embedded HTML (PHP from http://www.php.net) - _________________________________________________________________ - - Administrative Questions - - 3.1) How do I install PostgreSQL somewhere other than /usr/local/pgsql? - - Specify the --prefix option when running configure. - - 3.2) When I start postmaster, I get a Bad System Call or core dumped - message. Why? - - It could be a variety of problems, but first check to see that you - have System V extensions installed in your kernel. PostgreSQL requires - kernel support for shared memory and semaphores. - - 3.3) When I try to start postmaster, I get IpcMemoryCreate errors. Why? - - You either do not have shared memory configured properly in your - kernel or you need to enlarge the shared memory available in the - kernel. The exact amount you need depends on your architecture and how - many buffers and backend processes you configure for postmaster. For - most systems, with default numbers of buffers and processes, you need - a minimum of ~1 MB. See the PostgreSQL Administrator's Guide for more - detailed information about shared memory and semaphores. - - 3.4) When I try to start postmaster, I get IpcSemaphoreCreate errors. Why? - - If the error message is IpcSemaphoreCreate: semget failed (No space - left on device) then your kernel is not configured with enough - semaphores. Postgres needs one semaphore per potential backend - process. A temporary solution is to start postmaster with a smaller - limit on the number of backend processes. Use -N with a parameter less - than the default of 32. A more permanent solution is to increase your - kernel's SEMMNS and SEMMNI parameters. - - Inoperative semaphores can also cause crashes during heavy database - access. - - If the error message is something else, you might not have semaphore - support configured in your kernel at all. See the PostgreSQL - Administrator's Guide for more detailed information about shared - memory and semaphores. - - 3.5) How do I control connections from other hosts? - - By default, PostgreSQL only allows connections from the local machine - using Unix domain sockets. Other machines will not be able to connect - unless you add the -i flag to postmaster, and enable host-based - authentication by modifying the file $PGDATA/pg_hba.conf accordingly. - This will allow TCP/IP connections. - - 3.6) How do I tune the database engine for better performance? - - Certainly, indexes can speed up queries. The EXPLAIN command allows - you to see how PostgreSQL is interpreting your query, and which - indexes are being used. - - If you are doing many INSERTs, consider doing them in a large batch - using the COPY command. This is much faster than individual INSERTS. - Second, statements not in a BEGIN WORK/COMMIT transaction block are - considered to be in their own transaction. Consider performing several - statements in a single transaction block. This reduces the transaction - overhead. Also, consider dropping and recreating indexes when making - large data changes. - - There are several tuning options. You can disable fsync() by starting - postmaster with a -o -F option. This will prevent fsync()s from - flushing to disk after every transaction. - - You can also use the postmaster -B option to increase the number of - shared memory buffers used by the backend processes. If you make this - parameter too high, the postmaster may not start because you have - exceeded your kernel's limit on shared memory space. Each buffer is 8K - and the default is 64 buffers. - - You can also use the backend -S option to increase the maximum amount - of memory used by the backend process for temporary sorts. The -S - value is measured in kilobytes, and the default is 512 (i.e. 512K). - - You can also use the CLUSTER command to group data in tables to match - an index. See the CLUSTER manual page for more details. - - 3.7) What debugging features are available? - - PostgreSQL has several features that report status information that - can be valuable for debugging purposes. - - First, by running configure with the --enable-cassert option, many - assert()s monitor the progress of the backend and halt the program - when something unexpected occurs. - - Both postmaster and postgres have several debug options available. - First, whenever you start postmaster, make sure you send the standard - output and error to a log file, like: - cd /usr/local/pgsql - ./bin/postmaster >server.log 2>&1 & - - This will put a server.log file in the top-level PostgreSQL directory. - This file contains useful information about problems or errors - encountered by the server. Postmaster has a -d option that allows even - more detailed information to be reported. The -d option takes a number - that specifies the debug level. Be warned that high debug level values - generate large log files. - - If postmaster is not running, you can actually run the postgres - backend from the command line, and type your SQL statement directly. - This is recommended only for debugging purposes. Note that a newline - terminates the query, not a semicolon. If you have compiled with - debugging symbols, you can use a debugger to see what is happening. - Because the backend was not started from postmaster, it is not running - in an identical environment and locking/backend interaction problems - may not be duplicated. - - If postmaster is running, start psql in one window, then find the PID - of the postgres process used by psql. Use a debugger to attach to the - postgres PID. You can set breakpoints in the debugger and issue - queries from psql. If you are debugging postgres startup, you can set - PGOPTIONS="-W n", then start psql. This will cause startup to delay - for n seconds so you can attach to the process with the debugger, set - any breakpoints, and continue through the startup sequence. - - The postgres program has -s, -A, and -t options that can be very - useful for debugging and performance measurements. - - You can also compile with profiling to see what functions are taking - execution time. The backend profile files will be deposited in the - pgsql/data/base/dbname directory. The client profile file will be put - in the client's current directory. Linux requires a compile with - -DLINUX_PROFILE for proper profiling. - - 3.8) Why do I get "Sorry, too many clients" when trying to connect? - - You need to increase postmaster's limit on how many concurrent backend - processes it can start. - - The default limit is 32 processes. You can increase it by restarting - postmaster with a suitable -N value or modifying postgresql.conf. - - Note that if you make -N larger than 32, you must also increase -B - beyond its default of 64; -B must be at least twice -N, and probably - should be more than that for best performance. For large numbers of - backend processes, you are also likely to find that you need to - increase various Unix kernel configuration parameters. Things to check - include the maximum size of shared memory blocks, SHMMAX; the maximum - number of semaphores, SEMMNS and SEMMNI; the maximum number of - processes, NPROC; the maximum number of processes per user, MAXUPRC; - and the maximum number of open files, NFILE and NINODE. The reason - that PostgreSQL has a limit on the number of allowed backend processes - is so your system won't run out of resources. - - In PostgreSQL versions prior to 6.5, the maximum number of backends - was 64, and changing it required a rebuild after altering the - MaxBackendId constant in include/storage/sinvaladt.h. - - 3.9) What are the pg_sorttempNNN.NN files in my database directory? - - They are temporary files generated by the query executor. For example, - if a sort needs to be done to satisfy an ORDER BY, and the sort - requires more space than the backend's -S parameter allows, then - temporary files are created to hold the extra data. - - The temporary files should be deleted automatically, but might not if - a backend crashes during a sort. If you have no backends running at - the time, it is safe to delete the pg_tempNNN.NN files. - _________________________________________________________________ - - Operational Questions - - 4.1) What is the difference between binary cursors and normal cursors? - - See the DECLARE manual page for a description. - - 4.2) How do I SELECT only the first few rows of a query? - - See the FETCH manual page, or use SELECT ... LIMIT.... - - The entire query may have to be evaluated, even if you only want the - first few rows. Consider a query that has an ORDER BY. If there is an - index that matches the ORDER BY, PostgreSQL may be able to evaluate - only the first few records requested, or the entire query may have to - be evaluated until the desired rows have been generated. - - 4.3) How do I get a list of tables or other things I can see in psql? - - You can read the source code for psql in file - pgsql/src/bin/psql/describe.c. It contains SQL commands that generate - the output for psql's backslash commands. You can also start psql with - the -E option so it will print out the queries it uses to execute the - commands you give. - - 4.4) How do you remove a column from a table? - - We do not support ALTER TABLE DROP COLUMN, but do this: - BEGIN; - LOCK TABLE old_table; - SELECT ... -- select all columns but the one you want to remove - INTO TABLE new_table - FROM old_table; - DROP TABLE old_table; - ALTER TABLE new_table RENAME TO old_table; - COMMIT; - - 4.5) What is the maximum size for a row, a table, and a database? - - These are the limits: - Maximum size for a database? unlimited (500 GB databases exist) - Maximum size for a table? 16 TB - Maximum size for a row? unlimited in 7.1 and later - Maximum size for a field? 1 GB in 7.1 and later - Maximum number of rows in a table? unlimited - Maximum number of columns in a table? 250-1600 depending on column types - Maximum number of indexes on a table? unlimited - - Of course, these are not actually unlimited, but limited to available - disk space and memory/swap space. Performance may suffer when these - values get unusually large. - - The maximum table size of 16 TB does not require large file support - from the operating system. Large tables are stored as multiple 1 GB - files so file system size limits are not important. - - The maximum table size and maximum number of columns can be increased - if the default block size is increased to 32k. - - 4.6) How much database disk space is required to store data from a typical - text file? - - A PostgreSQL database may require up to five times the disk space to - store data from a text file. - - As an example, consider a file of 100,000 lines with an integer and - text description on each line. Suppose the text string avergages - twenty bytes in length. The flat file would be 2.8 MB. The size of the - PostgreSQL database file containing this data can be estimated as 6.4 - MB: - 36 bytes: each row header (approximate) - 24 bytes: one int field and one text filed - + 4 bytes: pointer on page to tuple - ---------------------------------------- - 64 bytes per row - - The data page size in PostgreSQL is 8192 bytes (8 KB), so: - - 8192 bytes per page - ------------------- = 128 rows per database page (rounded down) - 64 bytes per row - - 100000 data rows - -------------------- = 782 database pages (rounded up) - 128 rows per page - -782 database pages * 8192 bytes per page = 6,406,144 bytes (6.4 MB) - - Indexes do not require as much overhead, but do contain the data that - is being indexed, so they can be large also. - - 4.7) How do I find out what tables, indexes, databases, and users are - defined? - - psql has a variety of backslash commands to show such information. Use - \? to see them. There are also system tables beginning with pg_ that - describe these too. Also, psql -l will list all databases. - - Also try the file pgsql/src/tutorial/syscat.source. It illustrates - many of the SELECTs needed to get information from the database system - tables. - - 4.8) My queries are slow or don't make use of the indexes. Why? - - Indexes are not automatically used by every query. Indexes are only - used if the table is larger than a minimum size, and the query selects - only a small percentage of the rows in the table. This is because the - random disk access caused by an index scan is sometimes slower than a - straight read through the table, or sequential scan. - - To determine if an index should be used, PostgreSQL must have - statistics about the table. These statistics are collected using - VACUUM ANALYZE, or simply ANALYZE. Using statistics, the optimizer - knows how many rows are in the table, and can better determine if - indexes should be used. Statistics are also valuable in determining - optimal join order and join methods. Statistics collection should be - performed periodically as the contents of the table change. - - Indexes are normally not used for ORDER BY or to perform joins. A - sequential scan followed by an explicit sort is usually faster than an - index scan of a large table. - However, LIMIT combined with ORDER BY often will use an index because - only a small portion of the table is returned. - - When using wild-card operators such as LIKE or ~, indexes can only be - used if the beginning of the search is anchored to the start of the - string. Therefore, to use indexes, LIKE patterns must not start with - %, and ~(regular expression) patterns must start with ^. - - 4.9) How do I see how the query optimizer is evaluating my query? - - See the EXPLAIN manual page. - - 4.10) What is an R-tree index? - - An R-tree index is used for indexing spatial data. A hash index can't - handle range searches. A B-tree index only handles range searches in a - single dimension. R-trees can handle multi-dimensional data. For - example, if an R-tree index can be built on an attribute of type - point, the system can more efficiently answer queries such as "select - all points within a bounding rectangle." - - The canonical paper that describes the original R-tree design is: - - Guttman, A. "R-trees: A Dynamic Index Structure for Spatial - Searching." Proceedings of the 1984 ACM SIGMOD Int'l Conf on Mgmt of - Data, 45-57. - - You can also find this paper in Stonebraker's "Readings in Database - Systems". - - Built-in R-trees can handle polygons and boxes. In theory, R-trees can - be extended to handle higher number of dimensions. In practice, - extending R-trees requires a bit of work and we don't currently have - any documentation on how to do it. - - 4.11) What is the Genetic Query Optimizer? - - The GEQO module speeds query optimization when joining many tables by - means of a Genetic Algorithm (GA). It allows the handling of large - join queries through nonexhaustive search. - - 4.12) How do I perform regular expression searches and case-insensitive - regular expression searches? How do I use an index for case-insensitive - searches? - - The ~ operator does regular expression matching, and ~* does - case-insensitive regular expression matching. The case-insensitive - variant of LIKE is called ILIKE in PostgreSQL 7.1 and later. - - Case-insensitive equality comparisons are normally expressed as: - SELECT * - FROM tab - WHERE lower(col) = 'abc' - - This will not use an standard index. However, if you create a - functional index, it will be used: - CREATE INDEX tabindex on tab (lower(col)); - - 4.13) In a query, how do I detect if a field is NULL? - - You test the column with IS NULL and IS NOT NULL. - - 4.14) What is the difference between the various character types? - -Type Internal Name Notes --------------------------------------------------- -"char" char 1 character -CHAR(#) bpchar blank padded to the specified fixed length -VARCHAR(#) varchar size specifies maximum length, no padding -TEXT text no specific upper limit on length -BYTEA bytea variable-length byte array (null-byte safe) - - You will see the internal name when examining system catalogs and in - some error messages. - - The last four types above are "varlena" types (i.e., the first four - bytes on disk are the length, followed by the data). Thus the actual - space used is slightly greater than the declared size. However, these - data types are also subject to compression or being stored out-of-line - by TOAST, so the space on disk might also be less than expected. - - CHAR() is best when storing strings that are usually the same length. - VARCHAR() is best when storing variable-length strings but it limits - how long a string can be. TEXT is for strings of unlimited length, - maximum 1 gigabyte. BYTEA is for storing binary data, particularly - values that include NULL bytes. - - 4.15.1) How do I create a serial/auto-incrementing field? - - PostgreSQL supports a SERIAL data type. It auto-creates a sequence and - index on the column. For example, this: - CREATE TABLE person ( - id SERIAL, - name TEXT - ); - - is automatically translated into this: - CREATE SEQUENCE person_id_seq; - CREATE TABLE person ( - id INT4 NOT NULL DEFAULT nextval('person_id_seq'), - name TEXT - ); - CREATE UNIQUE INDEX person_id_key ON person ( id ); - - See the create_sequence manual page for more information about - sequences. You can also use each row's OID field as a unique value. - However, if you need to dump and reload the database, you need to use - pg_dump's -o option or COPY WITH OIDS option to preserve the OIDs. - - 4.15.2) How do I get the value of a SERIAL insert? - - One approach is to retrieve the next SERIAL value from the sequence - object with the nextval() function before inserting and then insert it - explicitly. Using the example table in 4.15.1, that might look like - this in Perl: - new_id = output of "SELECT nextval('person_id_seq')" - INSERT INTO person (id, name) VALUES (new_id, 'Blaise Pascal'); - - You would then also have the new value stored in new_id for use in - other queries (e.g., as a foreign key to the person table). Note that - the name of the automatically created SEQUENCE object will be named - __seq, where table and serialcolumn are the names - of your table and your SERIAL column, respectively. - - Alternatively, you could retrieve the assigned SERIAL value with the - currval() function after it was inserted by default, e.g., - INSERT INTO person (name) VALUES ('Blaise Pascal'); - new_id = output of "SELECT currval('person_id_seq')"; - - Finally, you could use the OID returned from the INSERT statement to - look up the default value, though this is probably the least portable - approach. In Perl, using DBI with Edmund Mergl's DBD::Pg module, the - oid value is made available via $sth->{pg_oid_status} after - $sth->execute(). - - 4.15.3) Don't currval() and nextval() lead to a race condition with other - users? - - No. Currval() returns the current value assigned by your backend, not - by all users. - - 4.15.4) Why aren't my sequence numbers reused on transaction abort? Why are - there gaps in the numbering of my sequence/SERIAL column? - - To improve concurrency, sequence values are given out to running - transactions as needed and are not locked until the transaction - completes. This causes gaps in numbering from aborted transactions. - - 4.16) What is an OID? What is a TID? - - OIDs are PostgreSQL's answer to unique row ids. Every row that is - created in PostgreSQL gets a unique OID. All OIDs generated during - initdb are less than 16384 (from backend/access/transam.h). All - user-created OIDs are equal to or greater than this. By default, all - these OIDs are unique not only within a table or database, but unique - within the entire PostgreSQL installation. - - PostgreSQL uses OIDs in its internal system tables to link rows - between tables. These OIDs can be used to identify specific user rows - and used in joins. It is recommended you use column type OID to store - OID values. You can create an index on the OID field for faster - access. - - OIDs are assigned to all new rows from a central area that is used by - all databases. If you want to change the OID to something else, or if - you want to make a copy of the table, with the original OIDs, there is - no reason you can't do it: - CREATE TABLE new_table(old_oid oid, mycol int); - SELECT old_oid, mycol INTO new FROM old; - COPY new TO '/tmp/pgtable'; - DELETE FROM new; - COPY new WITH OIDS FROM '/tmp/pgtable'; - - OIDs are stored as 4-byte integers, and will overflow at 4 billion. No - one has reported this ever happening, and we plan to have the limit - removed before anyone does. - - TIDs are used to identify specific physical rows with block and offset - values. TIDs change after rows are modified or reloaded. They are used - by index entries to point to physical rows. - - 4.17) What is the meaning of some of the terms used in PostgreSQL? - - Some of the source code and older documentation use terms that have - more common usage. Here are some: - * table, relation, class - * row, record, tuple - * column, field, attribute - * retrieve, select - * replace, update - * append, insert - * OID, serial value - * portal, cursor - * range variable, table name, table alias - - A list of general database terms can be found at: - http://www.comptechnews.com/~reaster/dbdesign.html - - 4.18) Why do I get the error "ERROR: Memory exhausted in AllocSetAlloc()"? - - If you are running a version older than 7.1, an upgrade may fix the - problem. Also it is possible you have run out of virtual memory on - your system, or your kernel has a low limit for certain resources. Try - this before starting postmaster: - ulimit -d 262144 - limit datasize 256m - - Depending on your shell, only one of these may succeed, but it will - set your process data segment limit much higher and perhaps allow the - query to complete. This command applies to the current process, and - all subprocesses created after the command is run. If you are having a - problem with the SQL client because the backend is returning too much - data, try it before starting the client. - - 4.19) How do I tell what PostgreSQL version I am running? - - From psql, type select version(); - - 4.20) Why does my large-object operations get "invalid large obj - descriptor"? - - You need to put BEGIN WORK and COMMIT around any use of a large object - handle, that is, surrounding lo_open ... lo_close. - - Currently PostgreSQL enforces the rule by closing large object handles - at transaction commit. So the first attempt to do anything with the - handle will draw invalid large obj descriptor. So code that used to - work (at least most of the time) will now generate that error message - if you fail to use a transaction. - - If you are using a client interface like ODBC you may need to set - auto-commit off. - - 4.21) How do I create a column that will default to the current time? - - Use CURRENT_TIMESTAMP: -CREATE TABLE test (x int, modtime timestamp DEFAULT CURRENT_TIMESTAMP ); - - 4.22) Why are my subqueries using IN so slow? - - Currently, we join subqueries to outer queries by sequentially - scanning the result of the subquery for each row of the outer query. A - workaround is to replace IN with EXISTS: -SELECT * - FROM tab - WHERE col1 IN (SELECT col2 FROM TAB2) - - to: -SELECT * - FROM tab - WHERE EXISTS (SELECT col2 FROM TAB2 WHERE col1 = col2) - - We hope to fix this limitation in a future release. - - 4.23) How do I perform an outer join? - - PostgreSQL 7.1 and later supports outer joins using the SQL standard - syntax. Here are two examples: - SELECT * - FROM t1 LEFT OUTER JOIN t2 ON (t1.col = t2.col); - - or - SELECT * - FROM t1 LEFT OUTER JOIN t2 USING (col); - - These identical queries join t1.col to t2.col, and also return any - unjoined rows in t1 (those with no match in t2). A RIGHT join would - add unjoined rows of t2. A FULL join would return the matched rows - plus all unjoined rows from t1 and t2. The word OUTER is optional and - is assumed in LEFT, RIGHT, and FULL joins. Ordinary joins are called - INNER joins. - - In previous releases, outer joins can be simulated using UNION and NOT - IN. For example, when joining tab1 and tab2, the following query does - an outer join of the two tables: - SELECT tab1.col1, tab2.col2 - FROM tab1, tab2 - WHERE tab1.col1 = tab2.col1 - UNION ALL - SELECT tab1.col1, NULL - FROM tab1 - WHERE tab1.col1 NOT IN (SELECT tab2.col1 FROM tab2) - ORDER BY col1 - - 4.24) How do I perform queries using multiple databases? - - There is no way to query any database except the current one. Because - PostgreSQL loads database-specific system catalogs, it is uncertain - how a cross-database query should even behave. - - Of course, a client can make simultaneous connections to different - databases and merge the information that way. - - 4.25) How do I return multiple rows or columns from a function? - - You can return result sets from PL/pgSQL functions using refcursors. - See - http://developer.postgresql.org/docs/postgres/plpgsql-cursors.html, - section 23.7.3.3. - - 4.26) Why can't I reliably create/drop temporary tables in PL/PgSQL - functions? - - PL/PgSQL caches function contents, and an unfortunate side effect is - that if a PL/PgSQL function accesses a temporary table, and that table - is later dropped and recreated, and the function called again, the - function will fail because the cached function contents still point to - the old temporary table. The solution is to use EXECUTE for temporary - table access in PL/PgSQL. This will cause the query to be reparsed - every time. - _________________________________________________________________ - - Extending PostgreSQL - - 5.1) I wrote a user-defined function. When I run it in psql, why does it - dump core? - - The problem could be a number of things. Try testing your user-defined - function in a stand-alone test program first. - - 5.2) How can I contribute some nifty new types and functions to PostgreSQL? - - Send your extensions to the pgsql-hackers mailing list, and they will - eventually end up in the contrib/ subdirectory. - - 5.3) How do I write a C function to return a tuple? - - This requires wizardry so extreme that the authors have never tried - it, though in principle it can be done. - - 5.4) I have changed a source file. Why does the recompile not see the - change? - - The Makefiles do not have the proper dependencies for include files. - You have to do a make clean and then another make. If you are using - GCC you can use the --enable-depend option of configure to have the - compiler compute the dependencies automatically. diff --git a/doc/FAQ_AIX b/doc/FAQ_AIX deleted file mode 100644 index 74a1fd5768..0000000000 --- a/doc/FAQ_AIX +++ /dev/null @@ -1,27 +0,0 @@ -From: Zeugswetter Andreas -Fri Feb 1 17:24:51 NFT 2002 - -On AIX 4.3.2 PostgreSQL compiled with the native IBM compiler xlc -(vac.C 5.0.1) passes all regression tests. -Other versions of OS and compiler should also work. If you don't have a -powerpc or use gcc you might see rounding differences in the geometry -regression test. - -Use the following configure flags in addition to your own -if you have readline or libz there: ---with-includes=/usr/local/include --with-libraries=/usr/local/lib - -If you need libpq++ and have trouble --with-CXX=xlC make sure you have -installed the appropriate C++ include files and use a C++ version that -supports the string class (e.g. VisualAge C++ filesets vacpp.cmp.batch 5.0 -and vacpp.cmp.include 5.0). - -There will probably be warnings about 0.0/0.0 division and duplicate symbols -which you can safely ignore. - -Compiling PostgreSQL with gcc (2.95.3) on AIX also works. -Use the configure flags: --with-CC=gcc - -Since the mktime() function does not work on AIX for dates before -1970, all localtime formatted datetimes will not use summer time for -dates before 1970. diff --git a/doc/FAQ_DEV b/doc/FAQ_DEV deleted file mode 100644 index 42dc34f19c..0000000000 --- a/doc/FAQ_DEV +++ /dev/null @@ -1,690 +0,0 @@ - - Developer's Frequently Asked Questions (FAQ) for PostgreSQL - - Last updated: Wed Apr 17 01:12:20 EDT 2002 - - Current maintainer: Bruce Momjian (pgman@candle.pha.pa.us) - - The most recent version of this document can be viewed at the - postgreSQL Web site, http://www.PostgreSQL.org. - _________________________________________________________________ - - General Questions - - 1.1) How do I get involved in PostgreSQL development? - 1.2) How do I add a feature or fix a bug? - 1.3) How do I download/update the current source tree? - 1.4) How do I test my changes? - 1.5) What tools are available for developers? - 1.6) What books are good for developers? - 1.7) What is configure all about? - 1.8) How do I add a new port? - 1.9) Why don't we use threads in the backend? - 1.10) How are RPM's packaged? - 1.11) How are CVS branches handled? - 1.12) Where can I get a copy of the SQL standards? - - Technical Questions - - 2.1) How do I efficiently access information in tables from the - backend code? - 2.2) Why are table, column, type, function, view names sometimes - referenced as Name or NameData, and sometimes as char *? - 2.3) Why do we use Node and List to make data structures? - 2.4) I just added a field to a structure. What else should I do? - 2.5) Why do we use palloc() and pfree() to allocate memory? - 2.6) What is elog()? - 2.7) What is CommandCounterIncrement()? - _________________________________________________________________ - - General Questions - - 1.1) How go I get involved in PostgreSQL development? - - This was written by Lamar Owen: - - 2001-06-22 - What open source development process is used by the PostgreSQL team? - - Read HACKERS for six months (or a full release cycle, whichever is - longer). Really. HACKERS _is_the process. The process is not well - documented (AFAIK -- it may be somewhere that I am not aware of) -- - and it changes continually. - What development environment (OS, system, compilers, etc) is required - to develop code? - - Developers Corner on the website has links to this information. The - distribution tarball itself includes all the extra tools and documents - that go beyond a good Unix-like development environment. In general, a - modern unix with a modern gcc, GNU make or equivalent, autoconf (of a - particular version), and good working knowledge of those tools are - required. - What areas need support? - - The TODO list. - - You've made the first step, by finding and subscribing to HACKERS. - Once you find an area to look at in the TODO, and have read the - documentation on the internals, etc, then you check out a current - CVS,write what you are going to write (keeping your CVS checkout up to - date in the process), and make up a patch (as a context diff only) and - send to the PATCHES list, prefereably. - - Discussion on the patch typically happens here. If the patch adds a - major feature, it would be a good idea to talk about it first on the - HACKERS list, in order to increase the chances of it being accepted, - as well as toavoid duplication of effort. Note that experienced - developers with a proven track record usually get the big jobs -- for - more than one reason. Also note that PostgreSQL is highly portable -- - nonportable code will likely be dismissed out of hand. - - Once your contributions get accepted, things move from there. - Typically, you would be added as a developer on the list on the - website when one of the other developers recommends it. Membership on - the steering committee is by invitation only, by the other steering - committee members, from what I have gathered watching froma distance. - - I make these statements from having watched the process for over two - years. - - To see a good example of how one goes about this, search the archives - for the name 'Tom Lane' and see what his first post consisted of, and - where he took things. In particular, note that this hasn't been _that_ - long ago -- and his bugfixing and general deep knowledge with this - codebase is legendary. Take a few days to read after him. And pay - special attention to both the sheer quantity as well as the - painstaking quality of his work. Both are in high demand. - - 1.2) How do I add a feature or fix a bug? - - The source code is over 350,000 lines. Many fixes/features are - isolated to one specific area of the code. Others require knowledge of - much of the source. If you are confused about where to start, ask the - hackers list, and they will be glad to assess the complexity and give - pointers on where to start. - - Another thing to keep in mind is that many fixes and features can be - added with surprisingly little code. I often start by adding code, - then looking at other areas in the code where similar things are done, - and by the time I am finished, the patch is quite small and compact. - - When adding code, keep in mind that it should use the existing - facilities in the source, for performance reasons and for simplicity. - Often a review of existing code doing similar things is helpful. - - The usual process for source additions is: - * Review the TODO list. - * Discuss hackers the desirability of the fix/feature. - * How should it behave in complex circumstances? - * How should it be implemented? - * Submit the patch to the patches list. - * Answer email questions. - * Wait for the patch to be applied. - - 1.3) How do I download/update the current source tree? - - There are several ways to obtain the source tree. Occasional - developers can just get the most recent source tree snapshot from - ftp.postgresql.org. For regular developers, you can use CVS. CVS - allows you to download the source tree, then occasionally update your - copy of the source tree with any new changes. Using CVS, you don't - have to download the entire source each time, only the changed files. - Anonymous CVS does not allows developers to update the remote source - tree, though privileged developers can do this. There is a CVS FAQ on - our web site that describes how to use remote CVS. You can also use - CVSup, which has similarly functionality, and is available from - ftp.postgresql.org. - - To update the source tree, there are two ways. You can generate a - patch against your current source tree, perhaps using the make_diff - tools mentioned above, and send them to the patches list. They will be - reviewed, and applied in a timely manner. If the patch is major, and - we are in beta testing, the developers may wait for the final release - before applying your patches. - - For hard-core developers, Marc(scrappy@postgresql.org) will give you a - Unix shell account on postgresql.org, so you can use CVS to update the - main source tree, or you can ftp your files into your account, patch, - and cvs install the changes directly into the source tree. - - 1.4) How do I test my changes? - - First, use psql to make sure it is working as you expect. Then run - src/test/regress and get the output of src/test/regress/checkresults - with and without your changes, to see that your patch does not change - the regression test in unexpected ways. This practice has saved me - many times. The regression tests test the code in ways I would never - do, and has caught many bugs in my patches. By finding the problems - now, you save yourself a lot of debugging later when things are - broken, and you can't figure out when it happened. - - 1.5) What tools are available for developers? - - Aside from the User documentation mentioned in the regular FAQ, there - are several development tools available. First, all the files in the - /tools directory are designed for developers. - RELEASE_CHANGES changes we have to make for each release - SQL_keywords standard SQL'92 keywords - backend description/flowchart of the backend directories - ccsym find standard defines made by your compiler - entab converts tabs to spaces, used by pgindent - find_static finds functions that could be made static - find_typedef finds typedefs in the source code - find_badmacros finds macros that use braces incorrectly - make_ctags make vi 'tags' file in each directory - make_diff make *.orig and diffs of source - make_etags make emacs 'etags' files - make_keywords make comparison of our keywords and SQL'92 - make_mkid make mkid ID files - mkldexport create AIX exports file - pgindent indents C source files - pgjindent indents Java source files - pginclude scripts for adding/removing include files - unused_oids in pgsql/src/include/catalog - - Let me note some of these. If you point your browser at the - file:/usr/local/src/pgsql/src/tools/backend/index.html directory, you - will see few paragraphs describing the data flow, the backend - components in a flow chart, and a description of the shared memory - area. You can click on any flowchart box to see a description. If you - then click on the directory name, you will be taken to the source - directory, to browse the actual source code behind it. We also have - several README files in some source directories to describe the - function of the module. The browser will display these when you enter - the directory also. The tools/backend directory is also contained on - our web page under the title How PostgreSQL Processes a Query. - - Second, you really should have an editor that can handle tags, so you - can tag a function call to see the function definition, and then tag - inside that function to see an even lower-level function, and then - back out twice to return to the original function. Most editors - support this via tags or etags files. - - Third, you need to get id-utils from: - ftp://alpha.gnu.org/gnu/id-utils-3.2d.tar.gz - ftp://tug.org/gnu/id-utils-3.2d.tar.gz - ftp://ftp.enst.fr/pub/gnu/gnits/id-utils-3.2d.tar.gz - - By running tools/make_mkid, an archive of source symbols can be - created that can be rapidly queried like grep or edited. Others prefer - glimpse. - - make_diff has tools to create patch diff files that can be applied to - the distribution. This produces context diffs, which is our preferred - format. - - Our standard format is to indent each code level with one tab, where - each tab is four spaces. You will need to set your editor to display - tabs as four spaces: - vi in ~/.exrc: - set tabstop=4 - set sw=4 - more: - more -x4 - less: - less -x4 - emacs: - M-x set-variable tab-width - or - ; Cmd to set tab stops & indenting for working with PostgreSQL code - (c-add-style "pgsql" - '("bsd" - (indent-tabs-mode . t) - (c-basic-offset . 4) - (tab-width . 4) - (c-offsets-alist . - ((case-label . +)))) - t) ; t = set this mode on - - and add this to your autoload list (modify file path in macro): - - (setq auto-mode-alist - (cons '("\\`/usr/local/src/pgsql/.*\\.[chyl]\\'" . pgsql-c-mode) - auto-mode-alist)) - or - /* - * Local variables: - * tab-width: 4 - * c-indent-level: 4 - * c-basic-offset: 4 - * End: - */ - - pgindent will the format code by specifying flags to your operating - system's utility indent. This article describes the value of a - constent coding style. - - pgindent is run on all source files just before each beta test period. - It auto-formats all source files to make them consistent. Comment - blocks that need specific line breaks should be formatted as block - comments, where the comment starts as /*------. These comments will - not be reformatted in any way. - - pginclude contains scripts used to add needed #include's to include - files, and removed unneeded #include's. - - When adding system types, you will need to assign oids to them. There - is also a script called unused_oids in pgsql/src/include/catalog that - shows the unused oids. - - 1.6) What books are good for developers? - - I have four good books, An Introduction to Database Systems, by C.J. - Date, Addison, Wesley, A Guide to the SQL Standard, by C.J. Date, et. - al, Addison, Wesley, Fundamentals of Database Systems, by Elmasri and - Navathe, and Transaction Processing, by Jim Gray, Morgan, Kaufmann - - There is also a database performance site, with a handbook on-line - written by Jim Gray at http://www.benchmarkresources.com. - - 1.7) What is configure all about? - - The files configure and configure.in are part of the GNU autoconf - package. Configure allows us to test for various capabilities of the - OS, and to set variables that can then be tested in C programs and - Makefiles. Autoconf is installed on the PostgreSQL main server. To add - options to configure, edit configure.in, and then run autoconf to - generate configure. - - When configure is run by the user, it tests various OS capabilities, - stores those in config.status and config.cache, and modifies a list of - *.in files. For example, if there exists a Makefile.in, configure - generates a Makefile that contains substitutions for all @var@ - parameters found by configure. - - When you need to edit files, make sure you don't waste time modifying - files generated by configure. Edit the *.in file, and re-run configure - to recreate the needed file. If you run make distclean from the - top-level source directory, all files derived by configure are - removed, so you see only the file contained in the source - distribution. - - 1.8) How do I add a new port? - - There are a variety of places that need to be modified to add a new - port. First, start in the src/template directory. Add an appropriate - entry for your OS. Also, use src/config.guess to add your OS to - src/template/.similar. You shouldn't match the OS version exactly. The - configure test will look for an exact OS version number, and if not - found, find a match without version number. Edit src/configure.in to - add your new OS. (See configure item above.) You will need to run - autoconf, or patch src/configure too. - - Then, check src/include/port and add your new OS file, with - appropriate values. Hopefully, there is already locking code in - src/include/storage/s_lock.h for your CPU. There is also a - src/makefiles directory for port-specific Makefile handling. There is - a backend/port directory if you need special files for your OS. - - 1.9) Why don't we use threads in the backend? - - There are several reasons threads are not used: - * Historically, threads were unsupported and buggy. - * An error in one backend can corrupt other backends. - * Speed improvements using threads are small compared to the - remaining backend startup time. - * The backend code would be more complex. - - 1.10) How are RPM's packaged? - - This was written by Lamar Owen: - - 2001-05-03 - - As to how the RPMs are built -- to answer that question sanely - requires me to know how much experience you have with the whole RPM - paradigm. 'How is the RPM built?' is a multifaceted question. The - obvious simple answer is that I maintain: - 1. A set of patches to make certain portions of the source tree - 'behave' in the different environment of the RPMset; - 2. The initscript; - 3. Any other ancilliary scripts and files; - 4. A README.rpm-dist document that tries to adequately document both - the differences between the RPM build and the WHY of the - differences, as well as useful RPM environment operations (like, - using syslog, upgrading, getting postmaster to start at OS boot, - etc); - 5. The spec file that throws it all together. This is not a trivial - undertaking in a package of this size. - - I then download and build on as many different canonical distributions - as I can -- currently I am able to build on Red Hat 6.2, 7.0, and 7.1 - on my personal hardware. Occasionally I receive opportunity from - certain commercial enterprises such as Great Bridge and PostgreSQL, - Inc. to build on other distributions. - - I test the build by installing the resulting packages and running the - regression tests. Once the build passes these tests, I upload to the - postgresql.org ftp server and make a release announcement. I am also - responsible for maintaining the RPM download area on the ftp site. - - You'll notice I said 'canonical' distributions above. That simply - means that the machine is as stock 'out of the box' as practical -- - that is, everything (except select few programs) on these boxen are - installed by RPM; only official Red Hat released RPMs are used (except - in unusual circumstances involving software that will not alter the - build -- for example, installing a newer non-RedHat version of the Dia - diagramming package is OK -- installing Python 2.1 on the box that has - Python 1.5.2 installed is not, as that alters the PostgreSQL build). - The RPM as uploaded is built to as close to out-of-the-box pristine as - is possible. Only the standard released 'official to that release' - compiler is used -- and only the standard official kernel is used as - well. - - For a time I built on Mandrake for RedHat consumption -- no more. - Nonstandard RPM building systems are worse than useless. Which is not - to say that Mandrake is useless! By no means is Mandrake useless -- - unless you are building Red Hat RPMs -- and Red Hat is useless if - you're trying to build Mandrake or SuSE RPMs, for that matter. But I - would be foolish to use 'Lamar Owen's Super Special RPM Blend Distro - 0.1.2' to build for public consumption! :-) - - I _do_ attempt to make the _source_ RPM compatible with as many - distributions as possible -- however, since I have limited resources - (as a volunteer RPM maintainer) I am limited as to the amount of - testing said build will get on other distributions, architectures, or - systems. - - And, while I understand people's desire to immediately upgrade to the - newest version, realize that I do this as a side interest -- I have a - regular, full-time job as a broadcast - engineer/webmaster/sysadmin/Technical Director which occasionally - prevents me from making timely RPM releases. This happened during the - early part of the 7.1 beta cycle -- but I believe I was pretty much on - the ball for the Release Candidates and the final release. - - I am working towards a more open RPM distribution -- I would dearly - love to more fully document the process and put everything into CVS -- - once I figure out how I want to represent things such as the spec file - in a CVS form. It makes no sense to maintain a changelog, for - instance, in the spec file in CVS when CVS does a better job of - changelogs -- I will need to write a tool to generate a real spec file - from a CVS spec-source file that would add version numbers, changelog - entries, etc to the result before building the RPM. IOW, I need to - rethink the process -- and then go through the motions of putting my - long RPM history into CVS one version at a time so that version - history information isn't lost. - - As to why all these files aren't part of the source tree, well, unless - there was a large cry for it to happen, I don't believe it should. - PostgreSQL is very platform-agnostic -- and I like that. Including the - RPM stuff as part of the Official Tarball (TM) would, IMHO, slant that - agnostic stance in a negative way. But maybe I'm too sensitive to - that. I'm not opposed to doing that if that is the consensus of the - core group -- and that would be a sneaky way to get the stuff into CVS - :-). But if the core group isn't thrilled with the idea (and my - instinct says they're not likely to be), I am opposed to the idea -- - not to keep the stuff to myself, but to not hinder the - platform-neutral stance. IMHO, of course. - - Of course, there are many projects that DO include all the files - necessary to build RPMs from their Official Tarball (TM). - - 1.11) How are CVS branches managed? - - This was written by Tom Lane: - - 2001-05-07 - - If you just do basic "cvs checkout", "cvs update", "cvs commit", then - you'll always be dealing with the HEAD version of the files in CVS. - That's what you want for development, but if you need to patch past - stable releases then you have to be able to access and update the - "branch" portions of our CVS repository. We normally fork off a branch - for a stable release just before starting the development cycle for - the next release. - - The first thing you have to know is the branch name for the branch you - are interested in getting at. To do this, look at some long-lived - file, say the top-level HISTORY file, with "cvs status -v" to see what - the branch names are. (Thanks to Ian Lance Taylor for pointing out - that this is the easiest way to do it.) Typical branch names are: - REL7_1_STABLE - REL7_0_PATCHES - REL6_5_PATCHES - - OK, so how do you do work on a branch? By far the best way is to - create a separate checkout tree for the branch and do your work in - that. Not only is that the easiest way to deal with CVS, but you - really need to have the whole past tree available anyway to test your - work. (And you *better* test your work. Never forget that dot-releases - tend to go out with very little beta testing --- so whenever you - commit an update to a stable branch, you'd better be doubly sure that - it's correct.) - - Normally, to checkout the head branch, you just cd to the place you - want to contain the toplevel "pgsql" directory and say - cvs ... checkout pgsql - - To get a past branch, you cd to whereever you want it and say - cvs ... checkout -r BRANCHNAME pgsql - - For example, just a couple days ago I did - mkdir ~postgres/REL7_1 - cd ~postgres/REL7_1 - cvs ... checkout -r REL7_1_STABLE pgsql - - and now I have a maintenance copy of 7.1.*. - - When you've done a checkout in this way, the branch name is "sticky": - CVS automatically knows that this directory tree is for the branch, - and whenever you do "cvs update" or "cvs commit" in this tree, you'll - fetch or store the latest version in the branch, not the head version. - Easy as can be. - - So, if you have a patch that needs to apply to both the head and a - recent stable branch, you have to make the edits and do the commit - twice, once in your development tree and once in your stable branch - tree. This is kind of a pain, which is why we don't normally fork the - tree right away after a major release --- we wait for a dot-release or - two, so that we won't have to double-patch the first wave of fixes. - - 1.12) Where can I get a copy of the SQL standards? - - There are two pertinent standards, SQL92 and SQL99. These standards - are endorsed by ANSI and ISO. A draft of the SQL92 standard is - available at http://www.contrib.andrew.cmu.edu/~shadow/. The SQL99 - standard must be purchased from ANSI at - http://webstore.ansi.org/ansidocstore/default.asp. The main standards - documents are ANSI X3.135-1992 for SQL92 and ANSI/ISO/IEC 9075-2-1999 - for SQL99. - - A summary of these standards is at - http://dbs.uni-leipzig.de/en/lokal/standards.pdf and - http://db.konkuk.ac.kr/present/SQL3.pdf. - - Technical Questions - - 2.1) How do I efficiently access information in tables from the backend code? - - You first need to find the tuples(rows) you are interested in. There - are two ways. First, SearchSysCache() and related functions allow you - to query the system catalogs. This is the preferred way to access - system tables, because the first call to the cache loads the needed - rows, and future requests can return the results without accessing the - base table. The caches use system table indexes to look up tuples. A - list of available caches is located in - src/backend/utils/cache/syscache.c. - src/backend/utils/cache/lsyscache.c contains many column-specific - cache lookup functions. - - The rows returned are cache-owned versions of the heap rows. - Therefore, you must not modify or delete the tuple returned by - SearchSysCache(). What you should do is release it with - ReleaseSysCache() when you are done using it; this informs the cache - that it can discard that tuple if necessary. If you neglect to call - ReleaseSysCache(), then the cache entry will remain locked in the - cache until end of transaction, which is tolerable but not very - desirable. - - If you can't use the system cache, you will need to retrieve the data - directly from the heap table, using the buffer cache that is shared by - all backends. The backend automatically takes care of loading the rows - into the buffer cache. - - Open the table with heap_open(). You can then start a table scan with - heap_beginscan(), then use heap_getnext() and continue as long as - HeapTupleIsValid() returns true. Then do a heap_endscan(). Keys can be - assigned to the scan. No indexes are used, so all rows are going to be - compared to the keys, and only the valid rows returned. - - You can also use heap_fetch() to fetch rows by block number/offset. - While scans automatically lock/unlock rows from the buffer cache, with - heap_fetch(), you must pass a Buffer pointer, and ReleaseBuffer() it - when completed. - - Once you have the row, you can get data that is common to all tuples, - like t_self and t_oid, by merely accessing the HeapTuple structure - entries. If you need a table-specific column, you should take the - HeapTuple pointer, and use the GETSTRUCT() macro to access the - table-specific start of the tuple. You then cast the pointer as a - Form_pg_proc pointer if you are accessing the pg_proc table, or - Form_pg_type if you are accessing pg_type. You can then access the - columns by using a structure pointer: -((Form_pg_class) GETSTRUCT(tuple))->relnatts - - You must not directly change live tuples in this way. The best way is - to use heap_modifytuple() and pass it your original tuple, and the - values you want changed. It returns a palloc'ed tuple, which you pass - to heap_replace(). You can delete tuples by passing the tuple's t_self - to heap_destroy(). You use t_self for heap_update() too. Remember, - tuples can be either system cache copies, which may go away after you - call ReleaseSysCache(), or read directly from disk buffers, which go - away when you heap_getnext(), heap_endscan, or ReleaseBuffer(), in the - heap_fetch() case. Or it may be a palloc'ed tuple, that you must - pfree() when finished. - - 2.2) Why are table, column, type, function, view names sometimes referenced - as Name or NameData, and sometimes as char *? - - Table, column, type, function, and view names are stored in system - tables in columns of type Name. Name is a fixed-length, - null-terminated type of NAMEDATALEN bytes. (The default value for - NAMEDATALEN is 32 bytes.) -typedef struct nameData - { - char data[NAMEDATALEN]; - } NameData; - typedef NameData *Name; - - Table, column, type, function, and view names that come into the - backend via user queries are stored as variable-length, - null-terminated character strings. - - Many functions are called with both types of names, ie. heap_open(). - Because the Name type is null-terminated, it is safe to pass it to a - function expecting a char *. Because there are many cases where - on-disk names(Name) are compared to user-supplied names(char *), there - are many cases where Name and char * are used interchangeably. - - 2.3) Why do we use Node and List to make data structures? - - We do this because this allows a consistent way to pass data inside - the backend in a flexible way. Every node has a NodeTag which - specifies what type of data is inside the Node. Lists are groups of - Nodes chained together as a forward-linked list. - - Here are some of the List manipulation commands: - - lfirst(i) - return the data at list element i. - - lnext(i) - return the next list element after i. - - foreach(i, list) - loop through list, assigning each list element to i. It is - important to note that i is a List *, not the data in the List - element. You need to use lfirst(i) to get at the data. Here is - a typical code snippet that loops through a List containing Var - *'s and processes each one: - -List *i, *list; - - foreach(i, list) - { - Var *var = lfirst(i); - - /* process var here */ - } - - lcons(node, list) - add node to the front of list, or create a new list with node - if list is NIL. - - lappend(list, node) - add node to the end of list. This is more expensive that lcons. - - nconc(list1, list2) - Concat list2 on to the end of list1. - - length(list) - return the length of the list. - - nth(i, list) - return the i'th element in list. - - lconsi, ... - There are integer versions of these: lconsi, lappendi, nthi. - List's containing integers instead of Node pointers are used to - hold list of relation object id's and other integer quantities. - - You can print nodes easily inside gdb. First, to disable output - truncation when you use the gdb print command: -(gdb) set print elements 0 - - Instead of printing values in gdb format, you can use the next two - commands to print out List, Node, and structure contents in a verbose - format that is easier to understand. List's are unrolled into nodes, - and nodes are printed in detail. The first prints in a short format, - and the second in a long format: -(gdb) call print(any_pointer) - (gdb) call pprint(any_pointer) - - The output appears in the postmaster log file, or on your screen if - you are running a backend directly without a postmaster. - - 2.4) I just added a field to a structure. What else should I do? - - The structures passing around from the parser, rewrite, optimizer, and - executor require quite a bit of support. Most structures have support - routines in src/backend/nodes used to create, copy, read, and output - those structures. Make sure you add support for your new field to - these files. Find any other places the structure may need code for - your new field. mkid is helpful with this (see above). - - 2.5) Why do we use palloc() and pfree() to allocate memory? - - palloc() and pfree() are used in place of malloc() and free() because - we find it easier to automatically free all memory allocated when a - query completes. This assures us that all memory that was allocated - gets freed even if we have lost track of where we allocated it. There - are special non-query contexts that memory can be allocated in. These - affect when the allocated memory is freed by the backend. - - 2.6) What is elog()? - - elog() is used to send messages to the front-end, and optionally - terminate the current query being processed. The first parameter is an - elog level of DEBUG (levels 1-5), LOG, INFO, NOTICE, ERROR, FATAL, or - PANIC. NOTICE prints on the user's terminal and the postmaster logs. - INFO prints only to the user's terminal and LOG prints only to the - server logs. (These can be changed from postgresql.conf.) ERROR prints - in both places, and terminates the current query, never returning from - the call. FATAL terminates the backend process. The remaining - parameters of elog are a printf-style set of parameters to print. - - elog(ERROR) frees most memory and open file descriptors so you don't - need to clean these up before the call. - - 2.7) What is CommandCounterIncrement()? - - Normally, transactions can not see the rows they modify. This allows - UPDATE foo SET x = x + 1 to work correctly. - - However, there are cases where a transactions needs to see rows - affected in previous parts of the transaction. This is accomplished - using a Command Counter. Incrementing the counter allows transactions - to be broken into pieces so each piece can see rows modified by - previous pieces. CommandCounterIncrement() increments the Command - Counter, creating a new part of the transaction. diff --git a/doc/FAQ_HPUX b/doc/FAQ_HPUX deleted file mode 100644 index 67ea07348a..0000000000 --- a/doc/FAQ_HPUX +++ /dev/null @@ -1,114 +0,0 @@ -======================================================= -Frequently Asked Questions (FAQ) for PostgreSQL 7.1 -HP-UX Specific -TO BE READ IN CONJUNCTION WITH THE NORMAL FAQ -======================================================= -last updated: $Date: 2001/04/30 23:55:26 $ - -current maintainer: Tom Lane (tgl@sss.pgh.pa.us) -original author: Tom Lane (tgl@sss.pgh.pa.us) - - -Questions covered here: -1.1) What do I need to install PostgreSQL on HP-UX? -1.2) Anything special about the build/install procedure? -1.3) yacc dies trying to process src/backend/parser/gram.y. -1.4) Linking the main postgres executable fails, complaining that - there's no "alloca" function. -1.5) OK, it seemed to build and install, but the regression test fails. - - ----------------------------------------------------------------------- -Section 1: Installing PostgreSQL ----------------------------------------------------------------------- - -1.1) What do I need to install PostgreSQL on HP-UX? - -PostgreSQL 7.1 should work on Series 700/800 machines running HPUX 9.*, -10.*, or 11.*, given appropriate system patch levels and build tools. -At least one developer routinely tests on HPUX 10.20, and we have reports -of successful install on HPUX 11. Releases before 7.1 were tested on -HPUX 9.03 and 9.05; 7.1 should still work there although no recent tests -have been reported. - -Aside from the PostgreSQL source distribution, you will need GNU make -(HP's make will not do), and either GNU gcc or HP's full ANSI C compiler. -If you intend to build from CVS sources rather than a distribution tarball, -you will also need flex (GNU lex) and bison (GNU yacc). - -I'd also recommend making sure you are fairly up-to-date on HP patches, -particularly if you are using HPUX 9. At a minimum, if you are on HPUX 9, -you *must* have PHSS_4630 (libm update) or a successor patch; otherwise -Postgres' date/time functions will misbehave. On general principles you -should be current on libc and ld/dld patches, as well as compiler patches -if you are using HP's C compiler. (The only other presently known failure -from out-of-date system libraries is that on HPUX 10.10, the backend will -crash after the second error message in a session unless you have upgraded -libc to PHCO_16722 or later.) - -See HP's support websites, such as http://us-support.external.hp.com/, -for free copies of their latest patches. - - -1.2) Anything special about the build/install procedure? - -If you have both HP's C compiler and GCC's, then you might want to -explicitly select the compiler to use when you run `configure': - CC=cc ./configure -for HP's C compiler, or - CC=gcc ./configure -for GCC. If you omit this setting, then configure will pick gcc -if it has a choice. - -The default install target location is /usr/local/pgsql, which -you might want to change to something under /opt. If so, use -the --prefix switch to configure. - - -1.3) yacc dies trying to process src/backend/parser/gram.y. - -HP's yacc doesn't create its tables large enough to handle the Postgres -grammar (a lot of other vendors' yaccs have this problem too). The -preferred solution is to use GNU bison instead. If you don't want to -do that for some reason, it's possible to increase yacc's table sizes -enough to cope. With a pre-6.4 PostgreSQL grammar, I was able to get -HPUX 9's yacc to work by setting YFLAGS to - -d -Np2000 -Ns3000 -Nm100000 -Nl2000 -Na30000 -Nc10000 -(You can edit YFLAGS either in the template file before running -configure, or in src/Makefile.global afterwards.) Later PostgreSQL -releases might require even larger tables, but this should do for -a starting point. - -Note that this shouldn't affect you if you are using a distribution -tarball, but it does matter if you pull the sources from the CVS server. -The CVS server does not store prebuilt yacc output files. - - -1.4) Linking the main postgres executable fails, complaining that - there's no "alloca" function. - -You're using an old version of GNU bison. Update to 1.28 or later, -and re-make the bison output files. Or build with gcc, or update to -HPUX 10, either of which will provide support for alloca. - - -1.5) OK, it seemed to build and install, but the regression test fails. - -There are several "expected failures" due to differences between HPUX -and the regression test reference platform used by the PostgreSQL group. -All of these should be compensated for by the regression test comparison -mechanism, with the possible exception of some low-order-digit differences -in the geometry tests (depending on which compiler and math library -versions you use). - -Any other error is cause for suspicion. In particular, if you see -failures in the datetime test on HPUX 9, you probably forgot to -install the libm patch PHSS_4630 --- see item 1.1 above. - -The parallel regression test script (gmake check) is known to lock up -when run under HP's default Bourne shell, at least in HPUX 10.20. This -appears to be a shell bug, not the fault of the script. If you see that -the tests have stopped making progress and only a shell process is -consuming CPU, kill the shell and start over with - gmake SHELL=/bin/ksh check -to use ksh instead. diff --git a/doc/FAQ_IRIX b/doc/FAQ_IRIX deleted file mode 100644 index 57757efbf0..0000000000 --- a/doc/FAQ_IRIX +++ /dev/null @@ -1,75 +0,0 @@ -======================================================= -Frequently Asked Questions (FAQ) for PostgreSQL 7.2 -IRIX Specific -TO BE READ IN CONJUNCTION WITH THE NORMAL FAQ -======================================================= -last updated: $Date: 2001/12/19 18:50:48 $ - -current maintainer: Luis Amigo (lamigo@atc.unican.es) -original author: Luis Amigo (lamigo@atc.unican.es) - - -Questions covered here: -1.1) What do I need to install PostgreSQL on IRIX? -1.2) Anything special about the build/install procedure? -1.3) OK, it seemed to build and install, but the regression test fails. - - ----------------------------------------------------------------------- -Section 1: Installing PostgreSQL ----------------------------------------------------------------------- - -1.1) What do I need to install PostgreSQL on IRIX? - -PostgreSQL 7.2 has been run on MIPS r8000, r10000(both ip25 and ip27) -and r12000(ip35) processors, running IRIX 6.5.5m, 6.5.12 and 6.5.13 with -MIPSPro compilers version 7.30, 7.3.1.2m and 7.3. - -Aside from the PostgreSQL source distribution, you will need GNU make -(SGI's make will not do), and the MIPSPro full ANSI C compiler. - -There are problems trying to build with GCC. It is a known gcc bug -(not fixed as of version 3.0) related to using functions that return -certain kinds of structures. This bug affects functions like -inet_ntoa, inet_lnaof, inet_netof, inet_makeaddr and semctl. It is -supposed to be fixed by forcing code to link those functions with -libgcc, but this has not been tested yet. - - -1.2) Anything special about the build/install procedure? - -In order to compile with cc you will need to execute: - -CC=cc ./configure - -You may want to edit src/templates/irix5 to include something like: - -CFLAGS='-O2' -LDFLAGS='-O2' - -It is a good place to improve performance of PostgreSQK, because here you -may use all MIPSPro power generating specific objects, see man cc. - -Another known problem is include location, it may be different from some -compiler installations to others. This may manifest itself with something like: - -cc-1020 cc: ERROR File = pqcomm.c, Line = 427 - The identifier "TCP_NODELAY" is undefined. - - if (setsockopt(port->sock, IPPROTO_TCP, TCP_NODELAY, - -Some versions include TCP definitions in , so it is necessary to -add #include in src/backend/libpq/pqcomm.c and in -src/interfaces/libpq/fe-connect.c. - - -1.3) OK, it seemed to build and install, but the regression test fails. - -There are several "expected failures" due to differences between your platform -and the regression test reference platform used by the PostgreSQL group. All -of these should be compensated for by the regression test comparison -mechanism, with the possible exception of some low-order-digit differences in -the geometry tests (depending on which FPU are you using) or order differences -between zero and NULL in join tests(depending on compiler version). - -Any other error is cause for suspicion. diff --git a/doc/FAQ_MSWIN b/doc/FAQ_MSWIN deleted file mode 100644 index b5724b32a7..0000000000 --- a/doc/FAQ_MSWIN +++ /dev/null @@ -1,57 +0,0 @@ -How to install PostgreSQL on Windows -==================================== -$Date: 2002/02/02 20:34:16 $ - -1. Install the latest Cygwin package, available at http://cygwin.com/. - The Cygwin package provides a UNIX-like API on top of the Win32 - API. Using older versions such as 1.0 or B20 might require extra - efforts. - - A pre-built PostgreSQL is part of the standard Cygwin distribution - and is installed by Cygwin's setup.exe. You are encouraged to use - this version unless it does not meet your needs. Please read the - README file, /usr/doc/Cygwin/postgresql-${version}.README, where - "${version}" is the version (e.g., 7.2). - -2. Install the latest cygipc package, available at - http://www.neuro.gatech.edu/users/cwilson/cygutils/V1.1/cygipc/. - Do not use versions prior to 1.04, they will not work. - - Use the following command to install the cygipc package: - - $ tar -C / -xjf cygipc-${version}.tar.bz2 - - where "${version}" is the version (e.g., 1.11-1). - -3. The Cygwin bin directory has to be placed in the path before the - Windows program directories, because the sort.exe has to be taken - from Cygwin, not Windows. - -4. Start ipc-daemon from the cygipc package. Use "net start ipc-daemon", - if ipc-daemon is installed as a service; otherwise, use "ipc-daemon &". - This program needs to be running anytime you start the PostgreSQL - server (postmaster) or initialize a database (initdb). - -5. Proceed according to the INSTALL file (i.e., ./configure; make; etc.) - noting the following Cygwin specific differences: - - o The GNU make command is called "make" not "gmake". - o The adduser command is not supported -- use the appropriate - user management application on Windows NT, 2000, or XP. - Otherwise, skip this step. - o The su command is not supported -- use ssh to simulate su - on Windows NT, 2000, or XP. Otherwise, skip this step. - - Alternatively, proceed according to the README file supplied with - the Cygwin PostgreSQL package. - -NOTE: The following are known issues with PostgreSQL on Windows: - -1. Cygwin's AF_UNIX sockets are really implemented as AF_INET sockets - so they are inherently insecure. - -2. make check can generate spurious regression test failures due to - overflowing the listen() backlog queue which causes connection - refused errors. - -Problem reports can be sent to pgsql-cygwin@postgresql.org. diff --git a/doc/FAQ_QNX4 b/doc/FAQ_QNX4 deleted file mode 100644 index c660698eb3..0000000000 --- a/doc/FAQ_QNX4 +++ /dev/null @@ -1,230 +0,0 @@ -PostgresSQL on QNX 4 --------------------- -last updated: $Date: 2001/12/21 06:00:15 $ - -current maintainer: Bernd Tegge (tegge@repas-aeg.de) -original author: Andreas Kardos (kardos@repas-aeg.de) - -This port is an important step because PostgreSQL is still the only free -relational database with full SQL and ODBC support available for QNX 4. -The only commercial databases available are Empress RDBMS and Velocis -Database Server (not supported for Digital Unix). - -The most effort required the emulation of System V semaphore sets, -shared memory and IPC and of some IEEE floating-point functionality. - -It is recommended to use the GNU C compiler instead of the Watcom compiler -because the Watcom compiler doesn't support a int8 datatype (long or -long long int) and it does not have a C++ frontend. The only advantage -using Watcom C would be support of Tk and pgaccess. - -QNX 4 does not offer native support of shared libraries. Therefore the related -functionality cannot be used. Shared library support could probably be -implemented in future. - -QNX 4 does not support UNIX domain sockets. Clients must use TCP/IP -sockets. Therefore you either have to set "tcpip_socket = true" in -your postgresql.conf or to start postmaster with the -i option. -Furthermore it's advisable to set to set the PGHOST or SOCK environment -variable for postmaster in an environment using native QNX networking. -Otherwise the postmaster might not use the IP-Address you think it does :-) - -Prerequisites: --------------- - -The following prerequisites have been used: - -QNX standard: -QNX 4.25, Watcom C 10.6, GNU make - -Available from http://www.teaser.fr/~jcmichot/ -flex-2.5.4a.tar.gz (flex) -egcs-112-qnx4-r20.tar[.gz] (GNU C) - -Available from ftp://ftp.visi.com/users/hawkeyd/qnx/ -bison-1.2.5.tar.gz - -Available from http://quics.qnx.com/cgi-bin/dir_find.cgi?/usr/free/ -perl 5.004_04 - -from ftp://ftp.freesoftware.com/pub/infozip/zlib/ -zlib 1.1.3 - -tcl8.0.3.tar.Z (Tcl) - -In order to achieve meaningful results for the regression tests, you need -a different shell. The standard QNX shell is quite broken with regard to -scripting (even QSSL suggested to use pdksh or bash). Both are available -in source and binaries at -http://quics.qnx.com/cgi-bin/dir_find.cgi?/usr/free/ - -flex can be built without any problems using the Watcom or GNU C compilers. - -The current version of bison (1.2.8 at the time of this writing) does not -build cleanly on QNX4 with gcc installed, but you can download src and -binary of a previous version from the above mentioned ftp site. - -download source -GNU C can be installed by -/etc/install -u egcs112-qnx4-r20.tar[.gz] - -Although Tcl can be built after some slight code changes using the Watcom -compiler, the GNU C compiler should be used instead. Otherwise it would be -impossible to link postgres built with GNU C together with libtcl8.0.a built -with the Watcom compiler. However, if you are going to build a Watcom version -you must build the tcl and tk libraries with Watcom too. - -To make unix/tclUnixTest.c compilable uncomment -#include -in it or -touch /usr/include/sys/resource.h -In unix/Makefile.in replace - ( echo cd $(TOP_DIR)/tests\; source all ) | ./tcltest -by - ( echo cd ../tests\; source all ) | ./tcltest -After that Tcl can be built and tested as stated in README. - -Tk cannot be built with GNU C due to the lack of a stack version of the -X11 library. With the Watcom compiler Tk could be built but this is not useful -because of the link problems mentioned above. - -Therefore the Tk interface and the pgaccess tool cannot be supported for a GNU C -version of PostgreSQL on QNX 4. - -PostgreSQL: ------------ - -On QNX 4 some headers are not in the directories expected. To avoid -modifications of the code the following links should be made: - -ln -s /usr/local/bin/perl /usr/local/bin/perl5 -ln -s /usr/include/errno.h /usr/include/sys/errno.h -ln -s /usr/include/ioctl.h /usr/include/sys/ioctl.h -ln -s /usr/src/pgsql/src/backend/port/qnx4/ipc.h /usr/include/sys/ipc.h -ln -s /usr/src/pgsql/src/backend/port/qnx4/sem.h /usr/include/sys/sem.h -ln -s /usr/src/pgsql/src/backend/port/qnx4/shm.h /usr/include/sys/shm.h - -For ecgs-2.91.60 the file -/usr/local/lib/gcc-lib/i386-pc-qnx4/egcs-2.91.66/include/g++/stl_alloc.h -had to be patched (extern "C++" { ... } // extern "C++"). -See attached patch. - -If all prerequisites are available postgres can be built and installed by -cd pgsql/src -./configure --with-tcl --without-tk --with-perl -gmake > make.log 2>&1 -gmake install > make.install.log 2>&1 -su -cd interfaces/perl5 -gmake install -exit - -All other steps can be carried out as stated in the INSTALL file. - -Make problems: --------------- - -Sometimes the Watcom library manager wlib crashes with SIGSEGV on some -object files. This is a general problem and not PostgreSQL related. -Currently bootstrap.o causes such a crash. The workaround is not to include -the object file into the SUBSYS.o but link it directly. For further information -see backend/Makefile and backend/bootstrap/Makefile. -libpgsql.a currently cannot be generated because of the same problem. But this -doesn't matter since shared libraries are not supported. -(The Makefiles are already changed to ignore this, you don't have to -do anything) - -Regression tests: ------------------ -please don't use the QNX shell for the parallel regression tests. Download -bash from quics.qnx.com and run 'make SHELL=/usr/local/bin/bash check' -instead. - -The majority of regression tests succeeded. The following tests failed: - -geometry: -Some slight deviation in the last digit and "0" instead of "-0". -Can be ignored. - -timestamp, tinterval, abstime, horology: -Differences for years before the UNIX epoch. The QNX library probably treats -time_t as unsigned -> dates before 1970 get moved into the far future. -Can be ignored. - -create_function_1, create_function_2, create_type, create_operator, -create_view, select_views, triggers, misc, plpgsql: -Error messages due to the lack of shared library support. - -rules, select_views: -looks like it fails because it depends on tables created by previously -failing tests. - -alter_table: -An expected failure message contains one blank more than expected. -Possibly a faulty output file. - -int8, subselect, union -fails for Watcom version because of lacking int8 support. - -The current state of this port should be sufficient for lot of applications. - - -Have fun! - -Andreas Kardos -2000-04-04 - -Bernd Tegge -tegge@repas-aeg.de -2001-12-10 - ---------------------------------------------------------------------------- - -*** ./stl_alloc.h.orig Sat Feb 28 05:17:28 1998 ---- ./stl_alloc.h Tue Nov 23 04:14:09 1999 -*************** -*** 120,125 **** ---- 120,126 ---- - #pragma set woff 1174 - #endif - -+ extern "C++" { - // Malloc-based allocator. Typically slower than default alloc below. - // Typically thread-safe and more storage efficient. - #ifdef __STL_STATIC_TEMPLATE_MEMBER_BUG -*************** -*** 682,687 **** ---- 683,689 ---- - # endif - - #endif /* ! __USE_MALLOC */ -+ } // extern "C++" - - #if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32) - #pragma reset woff 1174 - - -Patch required to build with gcc: - -*** /usr/src/postgresql-7.2b3/src/backend/port/qnx4/sem.h Thu Nov 8 21:37:52 2001 ---- src/backend/port/qnx4/sem.h Mon Dec 10 13:22:18 2001 -*************** -*** 55,60 **** ---- 55,71 ---- - ushort_t sem_num; /* semaphore # */ - short sem_op; /* semaphore operation */ - short sem_flg; /* operation flags */ -+ }; -+ -+ /* -+ * command union for semctl. -+ */ -+ -+ union semun { -+ int val; /* value for SETVAL */ -+ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ -+ unsigned short int *array; /* array for GETALL, SETALL */ -+ struct seminfo *__buf; /* buffer for IPC_INFO */ - }; - - extern int semctl(int semid, int semnum, int cmd, /* ... */ union semun arg); diff --git a/doc/FAQ_SCO b/doc/FAQ_SCO deleted file mode 100644 index 6f7d2670a9..0000000000 --- a/doc/FAQ_SCO +++ /dev/null @@ -1,139 +0,0 @@ -============================================================ -Frequently Asked Questions (FAQ) for PostgreSQL 7.2 -SCO UnixWare and OpenServer specific -to be read in conjunction with the installation instructions -============================================================ -last updated: $Date: 2001/08/29 19:14:39 $ - -current maintainer: Billy G. Allie (Bill.Allie@mug.org) -original author: Andrew Merrill (andrew@compclass.com) - - -PostgreSQL 7.1 can be built on SCO UnixWare 7 and SCO OpenServer 5. -On OpenServer, you can use either the OpenServer Development Kit or -the Universal Development Kit. - -However, some tweaking may be needed, as described below. - -Topics: -*) Skunkware -*) GNU Make -*) Readline -*) Using the UDK on OpenServer -*) Compiling PostgreSQL using the UDK -*) Reading the PostgreSQL man pages - - -*************************************************************************** -*) Skunkware - -You should locate your copy of the SCO Skunkware CD. The Skunkware CD is -included with UnixWare 7 and current versions of OpenServer 5. - -Skunkware includes ready-to-install versions of many popular programs that -are available on the Internet. For example, gzip, gunzip, GNU make, flex, -and bison are all included. - -If you do not have this CD, the software on it is available via anonymous -ftp from ftp.sco.com/skunkware. - -For UnixWare 7.1, this CD is now labeled "Open License Software Supplement". - -Skunkware has different versions for UnixWare and OpenServer. Make sure -you install the correct version for your operating system, except as noted -below. - - -*************************************************************************** -*) GNU Make - -You need to use the GNU make program, which is on the Skunkware CD. By -default, it installs as /usr/local/bin/make. To avoid confusion with the -SCO make program, you may want to rename GNU make to gmake. - - -*************************************************************************** -*) Readline - -If you install the readline library, then psql (the PostgreSQL command line -SQL interpreter) remembers each command you type, and allows you to use -arrow keys to recall and edit previous commands. This is very helpful, and -is strongly recommended. The readline library is on the Skunkware CD. - -The readline library is not included on the UnixWare 7.1 Skunkware CD. If -you have the UnixWare 7.0.0 or 7.0.1 Skunkware CDs, you can install it from -there. Otherwise, try ftp.sco.com/skunkware. - -By default, readline installs into /usr/local/lib and /usr/local/include. -However, the PostgreSQL configure program will not find it there without -help. If you installed readline, then use the following options to -configure: - -configure --with-libs=/usr/local/lib --with-includes=/usr/local/include - - -*************************************************************************** -*) Using the UDK on OpenServer - -If you are using the new Universal Development Kit (UDK) compiler on -OpenServer, you need to specify the locations of the UDK libraries: - -configure --with-libs=/udk/usr/lib --with-includes=/udk/usr/include - -Putting these together with the readline options from above: - -./configure --with-libs="/udk/usr/lib /usr/local/lib" --with-includes="/udk/usr/include /usr/local/include" - - -*************************************************************************** -*) Compiling PostgreSQL 7.1 with the UDK - -The program, backend/utils/adt/int8.c, tickles a compiler bug with in the -following versions (and probably others as well) of the C compiler: - - Optimizing C Compilation System (CCS) 3.2 08/18/98 - Optimizing C Compilation System (CCS) 3.2 09/28/99 - -If you encounter an error compiling backend/utils/adt/int8.c, please apply -the following patch: - -------------------------------8< CUT HERE >8------------------------------ -*** src/backend/utils/adt/int8.c.orig Sat Oct 7 20:48:17 2000 ---- src/backend/utils/adt/int8.c Sat Oct 7 20:52:03 2000 -*************** -*** 489,495 **** - if (arg1 < 1) - result = 0; - else -! for (i = arg1, result = 1; i > 0; --i) - result *= i; - - PG_RETURN_INT64(result); ---- 489,495 ---- - if (arg1 < 1) - result = 0; - else -! for (i = arg1, result = 1; i; --i) - result *= i; - - PG_RETURN_INT64(result); -------------------------------8< CUT HERE >8------------------------------ - -This compiler bug seems to be fixed at least in - - Optimizing C Compilation System (CCS) 4.0 10/23/00 (UDK FS 7.1.1b) - - -*************************************************************************** -*) Reading the PostgreSQL man pages - -By default, the PostgreSQL man pages are installed into -/usr/local/pgsql/man. By default, UnixWare does not look there for -man pages. To be able to read them you need to modify the MANPATH -variable in /etc/default/man. I use: - - MANPATH=/usr/lib/scohelp/%L/man:/usr/dt/man:/usr/man:/usr/share/man:scohelp:/usr/local/man:/usr/local/pgsql/man - -On OpenServer, some extra research needs to be invested to make the -man pages usable, because the man system is a bit different from other -platforms. Currently, PostgreSQL will not install them at all. diff --git a/doc/FAQ_Solaris b/doc/FAQ_Solaris deleted file mode 100644 index f3703fda82..0000000000 --- a/doc/FAQ_Solaris +++ /dev/null @@ -1,102 +0,0 @@ -============================================================ -Frequently Asked Questions (FAQ) for PostgreSQL 7.2 -Sun Solaris specific -to be read in conjunction with the installation instructions -============================================================ -last updated: $Date: 2002/03/04 17:47:11 $ - -current maintainer: Peter Eisentraut - - -Contents: - -1) What tools do I need to build and install PostgreSQL on Solaris? -2) Why do I get problems when building with OpenSSL support? -3) Why does configure complain about a failed test program? -4) How do I ensure that pg_dump and pg_restore can handle files > 2 Gb? -5) Why does my 64-bit build sometimes crash? - - -1) What tools do I need to build and install PostgreSQL on Solaris? - -You will need - -- GNU zip (for installing the documentation) -- GNU make -- GNU readline library (optional) -- GCC (if you don't have Sun's compiler) - -If you like Solaris packages, you can find these tools here: -http://www.sunfreeware.com - -If you prefer sources, look here: -http://www.gnu.org/order/ftp.html - -You can build with either GCC or Sun's compiler suite. We have heard reports -of problems when using gcc 2.95.1; gcc 2.95.3 is recommended. If you are -using Sun's compiler, be careful *not* to select /usr/ucb/cc; use -/opt/SUNWspro/bin/cc. - - -2) Why do I get problems when building with OpenSSL support? - -When you build PostgreSQL with OpenSSL support you might get -compilation errors in the following files: - -src/backend/libpq/crypt.c -src/backend/libpq/password.c -src/interfaces/libpq/fe-auth.c -src/interfaces/libpq/fe-connect.c - -This is because of a namespace conflict between the standard -/usr/include/crypt.h header and the header files provided by OpenSSL. - -Upgrading your OpenSSL installation to version 0.9.6a fixes this -problem. - - -3) Why does configure complain about a failed test program? - -This is probably a case of the run-time linker being unable to find -libz or some other non-standard library, such as libssl. To point it -to the right location, set the LD_LIBRARY_PATH environment variable, -e.g., - -LD_LIBRARY_PATH=/usr/local/lib:/usr/local/ssl/lib -export LD_LIBRARY_PATH - -and restart configure. You will also have to keep this setting -whenever you run any of the installed PostgreSQL programs. - -Alternatively, set the environment variable LD_RUN_PATH. See the -ld(1) man page for more information. - - -4) How do I ensure that pg_dump and pg_restore can handle files > 2 Gb? - -By default, gcc will build programs that only handle 32-bit file offsets. -This is not a real problem for the server but can easily be trouble for -pg_dump and pg_restore. Before running 'configure', set your CFLAGS variable -to specify support for files with 64-bit offsets. This has been verified -to work on Solaris 7: - - CFLAGS="`getconf LFS_CFLAGS`"; export CFLAGS - - -5) Why does my 64-bit build sometimes crash? - -On Solaris 7 and older, the 64-bit version of libc has a buggy vsnprintf -routine, which leads to erratic core dumps in PostgreSQL. The simplest known -workaround is to force PostgreSQL to use its own version of vsnprintf rather -than the library copy. To do this, after you run 'configure' edit two files -produced by configure: - -(1) In src/Makefile.global, change the line - SNPRINTF = -to read - SNPRINTF = snprintf.o - -(2) In src/backend/port/Makefile, add "snprintf.o" to OBJS. (Skip this -step if you see "$(SNPRINTF)" already listed in OBJS.) - -Then build as usual. diff --git a/doc/FAQ_german b/doc/FAQ_german deleted file mode 100644 index 9a7a7d50f6..0000000000 --- a/doc/FAQ_german +++ /dev/null @@ -1,1075 +0,0 @@ - - Häufig gestellte Fragen (FAQ) zu PostgreSQL - - Last updated: Sat Jul 10 00:37:57 EDT 1999 - - Current maintainer: Bruce Momjian (pgman@candle.pha.pa.us) - - Deutsche Übersetzung von Karsten Schulz (schulz@linux-systemhaus.de) - - Letzte Aktualisierung der deutschen Übersetzung: Don, den 05.08.1999, - 09:00 CET - - Die aktuellste Version dieses Dokuments kann auf der PostgreSQL - Website http://www.PostgreSQL.org angesehen werden. - - Linux-spezifische Fragen werden in - http://www.PostgreSQL.org/docs/faq-linux.html beantwortet (deutsche - Übersetzung in Arbeit!). - - Irix-spezifische Fragen werden in - http://www.PostgreSQL.org/docs/faq-irix.html beantwortet. - - HPUX-spezifische Fragen werden in - http://www.PostgreSQL.org/docs/faq-hpux.shtml beantwortet. - _________________________________________________________________ - - Allgemeine Fragen - - 1.1) Was ist PostgreSQL? - 1.2) Welches Copyright liegt auf PostgreSQL? - 1.3) Auf welchen Unix-Plattformen läuft PostgreSQL? - 1.4) Welche Nicht-Unix-Versionen sind verfügbar? - 1.5) Woher bekomme ich PostgreSQL? - 1.6) Wo bekomme ich Support für PostgreSQL? - 1.7) Was ist die neueste Version von PostgreSQL? - 1.8) Welche Dokumente sind für PostgreSQL verfügbar? - 1.9) Wie erfahre ich etwas über bekannte Fehler oder fehlende - Eigenschaften von PostgreSQL? - 1.10) Wie kann ich SQL lernen? - 1.11) Ist PostgreSQL Y2K (Jahr 2000) fähig? - 1.12) Wie kann ich am Entwicklerteam teilnehmen? - 1.13) Wie sende ich einen Fehler-Bericht? - 1.14) Wie läuft PostgreSQL im Vergleich zu anderen Datenbanksystemen? - - Fragen zu Benutzerprogrammen - - 2.1) Gibt es ODBC-Treiber für PostgreSQL? - 2.2) Welche Werkzeuge gibt es, um PostgreSQL-Datenbanken über - Webseiten verfügbar zu machen? - 2.3) Hat PostgreSQL eine grafische Benutzerschnittstelle? Einen - Report-Generator? Eine eingebaute Query-Schnittstelle? - 2.4) Welche Sprachen sind für die Kommunikation mit PostgreSQL - verfügbar? - - Administrative Fragen - - 3.1) Warum schlägt initdb fehl? - 3.2) Wie installiere ich PostgreSQL woanders als in /usr/local/pgsql? - 3.3) Wenn ich den postmaster starte, bekomme ich einen Bad System Call - oder eine core dumped Meldung. Warum? - 3.4) Wenn ich versuche, den postmaster zu starten, bekomme ich eine - IpcMemoryCreate Fehlermeldungen. Warum? - 3.5) Wenn ich versuche, den postmaster zu starten, bekomme ich eine - IpcSemaphoreCreate Fehlermeldungen. Warum? - 3.6) Wie verhindere ich, daß andere Hosts auf meine PostgreSQL - Datenbanken zugreifen? - 3.7) Warum kann ich mich nicht von einer anderen Maschine mit meiner - Datenbank verbinden? - 3.8) Warum kann ich nicht als root auf die Datenbank zugreifen? - 3.9) Alle meine Server stürzen bei gleichzeitigem Tabellenzugriff ab. - Warum? - 3.10) Wie optimiere ich die Datenbankmaschine für bessere Leistung? - 3.11) Welche Debugging/Fehlersuch-Hilfsmittel sind für PostgreSQL - verfügbar? - 3.12) Ich bekomme die Meldung "Sorry, too many clients", wenn ich eine - Verbindung versuche. Warum? - 3.13) Was sind die pg_psort.XXX Dateien in meinem - Datenbank-Verzeichnis? - 3.14) Wie richte ich eine Benutzergruppe (pg_group) ein? - - Fragen zum Betrieb - - 4.1) Das System scheint Kommata, Dezimalpunkte und Datumsformate - durcheinanderzubringen. - 4.2) Was ist der genauer Unterschied zwischen Binary Cursors und - Normal Cursors? - 4.3) Wie wähle ich per SELECT nur die ersten paar Zeilen in einem - Query aus? - 4.4) Wie bekomme ich eine Liste der Tabellen oder anderen Dingen, die - ich in psql sehen kann - 4.5) Wie entferne ich eine Spalte von einer Tabelle? - 4.6) Was ist die Maximalgröße für eine Zeile, eine Tabelle, eine - Datenbank? - 4.7) Wieviel Plattenplatz benötigt eine Datenbank zur Speicherung - einer Datendatei mit zeilenweisen Datensätzen? - 4.8) Wie finde ich heraus, welche Indizes oder Operationen in der - Datenbank definiert sind? - 4.9) Meine Queries sind langsam oder nutzen die Indizes nicht. Warum? - 4.10) Auf welche Weise kann ich sehen, wie der Query-Optimierer meine - Abfrage auswertet? - 4.11) Was ist ein R-Tree Index? - 4.12) Was ist "Genetic Query Optimization"? - 4.13) Wie verfahre ich bei der Suche mit regulären Ausdrücken und bei - einer Suche mit Ignorierung der Groß- und Kleinschreibweisen? - 4.14) Wie ermittle ich in einem Query, daß ein Feld NULL ist? - 4.15) Was ist der Unterschied zwischen den verschiedenen CHAR-Typen? - 4.16) Wie erzeuge ich ein serielles Feld mit automatischer Erhöhung - des Inhalts? - 4.17) Was ist ein Oid? Was ist ein Tid? - 4.18) Was ist die Bedeutung der verschiedenen Ausdrücke, die in - PostgreSQL benutzt werden (z.B. attribute, class,...)? - 4.19) Wieso bekomme ich einen Fehler: "FATAL: palloc failure: memory - exhausted?" - 4.20) Wie kann ich feststellen, welche PostgreSQL-Version ich laufen - habe? - 4.21) Beim Arbeiten mit "Large-Objects" kommt die Fehlermeldung: - invalid large obj descriptor. Warum? - - PostgreSQL erweitern - - 5.1) Ich habe eine benutzerdefinierte Funktion geschrieben. Wenn ich - sie in psql aufrufe, kommt ein core dump. Warum? - 5.2) Was bedeutet die Meldung: NOTICE:PortalHeapMemoryFree: 0x402251d0 - not in alloc set!? - 5.3) Wie kann ich ein paar elegante neue Feldtypen und Funktionen zu - PostgreSQL beitragen? - 5.4) Wie schreibe ich eine Funktion in C, die ein Tuple zurückliefert? - 5.5) Ich habe eine der Quellendateien geändert. Warum macht sich die - Änderung beim erneuten Compilerlauf nicht bemerkbar? - _________________________________________________________________ - - Allgemeine Fragen - - 1.1) Was ist PostgreSQL? - - PostgreSQL ist eine Verbesserung des - POSTGRES-Datenbank-Managementsystems, ein "Next-Generation" - DBMS-Forschungsprototyp. Während PostgreSQL das leistungsfähige - Datenmodell und die reichhaltigen Datentypen von POSTGRES beibehält, - ersetzt es die PostQuel-Abfragesprache durch eine ausgedehnte - Teilmenge von SQL. PostgreSQL ist frei und der komplette Quellcode ist - verfügbar. - - Die PostgreSQL-Entwicklung wird von einem Team von Internet-Entwickler - durchgeführt, die alle an der PostgreSQL-Entwicklungs-Mailingliste - teilnehmen. Der aktuelle Koordinator ist Marc G. Fournier - (scrappy@postgreSQL.org) (siehe unten, wie man sich anmelden kann). - Dieses Team ist jetzt für alle aktuellen und zukünftigen Entwicklungen - von PostgreSQL verantwortlich. - - Die Autoren von PostgreSQL 1.01 waren Andrew Yu und Jolly Chen. Viele - andere haben zur Portierung, zu den Tests, zur Fehlersuche und zur - Verbesserung des Codes beigetragen. Der ursprüngliche Postgres-Code, - von dem PostgreSQL abstammt, ist auf die Bemühungen von vielen - Studierenden und Diplomanden, sowie Programmierern, die unter der - Weisung des Professors Michael Stonebraker an der Universität von - Kalifornien, Berkeley arbeiteteten, zurückzuführen. - - Der ursprüngliche Name der Software bei Berkeley war Postgres. Als die - SQL-Funktionalität 1995 hinzugefügt wurde, wurde sein Name zu - Postgres95 geändert. Der Name wurde Ende 1996 zu PostgreSQL geändert. - - 1.2) Welches Copyright liegt auf PostgreSQL? - - PostgreSQL steht unter folgendem COPYRIGHT (Originaltext): - - PostgreSQL Data Base Management System - - Copyright (c) 1994-6 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. - - Es gilt die Copyright-Klausel im Original! Informativ folgt hier eine - Übersetzung. Die Übersetzung besitzt keinerlei rechtlichen Status. - Insbesondere kann sich niemand auf diese Übersetzung berufen: - - PostgreSQL Datenbank Management System - - Copyright (c) 1994-6 Regents of the University of California - - Die Erlaubnis, diese Software und seine Unterlagen für jeden möglichen - Zweck, ohne Gebühr und ohne eine schriftliche Vereinbarung zu - benutzen, zu kopieren, zu ändern und zu verteilen wird hiermit - bewilligt, vorausgesetzt daß der oben genannte Urheberrechtsvermerk - und dieser Paragraph und die folgenden zwei Paragraphen in allen - Kopien erscheinen. - - IN KEINEM FALL IST DIE UNIVERSITÄT VON KALIFORNIEN GEGENÜBER JEDEM - MÖGLICHEN BETEILIGTEN FÜR DIE DIREKTEN, INDIREKTEN, SPEZIELLEN, - BEILÄUFIGEN ODER FOLGESCHÄDEN, EINSCHLIEßLICH DER VERLORENEN PROFITE - VERANTWORTLICH, DIE AUS DEM GEBRAUCH VON DIESER SOFTWARE UND SEINEN - UNTERLAGEN HERAUS ENTSTEHEN, SELBST WENN DIE UNIVERSITÄT VON - KALIFORNIEN VON DER MÖGLICHKEIT SOLCHEN SCHADENS BENACHRICHTIGT WORDEN - IST. - - DIE UNIVERSITÄT VON KALIFORNIEN LEHNT SPEZIELL ALLE MÖGLICHE GARANTIEN - AB, EINSCHLIESSLICH, ABER NICHT BEGRENZT AUF, DIE IMPLIZIERTEN - GARANTIEN VON GESCHÄFTSNUTZEN UND EIGNUNG ZU EINEM BESTIMMTEN ZWECK. - DIE SOFTWARE, DIE NACHSTEHEND BEREITGESTELLT WIRD, BASIERT AUF EINER - "SO WIE SIE IST"-GRUNDLAGE, UND DIE UNIVERSITÄT VON KALIFORNIEN HAT - KEINE VERPFLICHTUNGEN, WARTUNG, SUPPORT, AKTUALISIERUNGSVORGÄNGE, - VERBESSERUNGEN ODER ÄNDERUNGEN ZUR VERFÜGUNG ZU STELLEN. - - 1.3) Auf welchen Unix-Plattformen läuft PostgreSQL? - - Die Autoren haben PostgreSQL auf folgenden Plattformen kompiliert und - getestet (einige dieser Kompilierungen benötigen den C-Compiler gcc): - * aix - IBM auf AIX 3.2.5 or 4.x - * alpha - DEC Alpha AXP auf Digital Unix 2.0, 3.2, 4.0 - * BSD44_derived - OS abgeleitet von 4.4-lite BSD (NetBSD, FreeBSD) - * bsdi - BSD/OS 2.x, 3.x, 4.x - * dgux - DG/UX 5.4R4.11 - * hpux - HP PA-RISC auf HP-UX 9.*, 10.* - * i386_solaris - i386 Solaris - * irix5 - SGI MIPS auf IRIX 5.3 - * linux - Intel i86 Alpha SPARC PPC M68k - * sco - SCO 3.2v5 Unixware - * sparc_solaris - SUN SPARC auf Solaris 2.4, 2.5, 2.5.1 - * sunos4 - SUN SPARC auf SunOS 4.1.3 - * svr4 - Intel x86 auf Intel SVR4 and MIPS - * ultrix4 - DEC MIPS auf Ultrix 4.4 - - 1.4) Welche Nicht-Unix-Versionen sind verfügbar? - - Es ist möglich, die libpq C-Bibliothek, psql und andere Schnittstellen - und Binaries zu kompilieren, um sie auf der MS-Windows-Plattform - laufen zu lassen. In diesem Fall läuft der Client auf MS-Windows und - steht über TCP/IP mit einem Server in Verbindung, der auf einer - unserer unterstützten Unixplattformen läuft. Es gibt die Datei - win31.mak in der Distribution, um die Win32 libpq-Bibliothek und psql - zu erzeugen. - - Der Datenbankserver arbeitet jetzt auch unter Benutzung der Cygnus - Unix/NT-Porting-Bibliotheken auf Windows NT. Siehe auch - pgsql/doc/README.NT in der Distribution. - - Es gibt eine weitere Portierung, die U/Win benutzt bei - http://surya.wipro.com/uwin/ported.html. - - 1.5) Woher bekomme ich PostgreSQL? - - Die erste Anlaufadresse für PostgreSQL ist der ftp-Server - ftp://ftp.postgreSQL.org/pub - - Die entsprechenden Spiegelserver sind auf der Hauptwebseite - aufgelistet. - - 1.6) Wo bekomme ich Support für PostgreSQL? - - Es gibt keinen offiziellen Support für PostgreSQL von der Universität - von Kalifornien, Berkeley. Der Support wird durch freiwilligen Einsatz - geleistet. - - Die Mailing-Liste ist: pgsql-general@postgreSQL.org. Die Liste ist für - PostgreSQL betreffende Themen vorbehalten. Um sich anzumelden, sende - eine Email mit folgenden Zeilen im Text (nicht in der Betreffzeile): - - subscribe - end - - an pgsql-general-request@postgreSQL.org. - - Es gibt auch eine Digest-Liste (Eine Liste, die Mails zusammengefasst - sendet). Um sich an dieser Digestliste anzumelden, sende eine Email - an: pgsql-general-digest-request@postgreSQL.org mit folgendem Text: - - subscribe - end - - Die Digests werden an die Mitglieder der Liste geschickt, wenn ca. - 30kB an Mails zusammengekommen sind. - - Die Bug-Mailingliste ist verfübar. Um sich an dieser Liste anzumelden, - sende eine Email an bugs-request@postgreSQL.org mit folgendem Text: - - - subscribe - end - - Es gibt ebenfalls eine Entwickler-Diskussionsliste. Um sich an dieser - Liste anzumelden, sende eine Email an hackers-request@postgreSQL.org - mit diesem Text: - - - subscribe - end - - Weitere Mailinglisten und Informationen zu PostgreSQL können auf der - PostgreSQL-Homepage im WWW gefunden werden: - - http://postgreSQL.org - - Es gibt außerdem einen IRC-Channel im EFNet, Kanal #PostgreSQL. Bruce - nutzt den Unix-Befehl: irc -c '#PostgreSQL' "$USER" irc.phoenix.net um - teilzunehmen - - Kommerzieller Support für PostgreSQL ist bei http://www.pgsql.com/ - verfügbar - - 1.7) Was ist die neueste Version von PostgreSQL? - - Das neueste Release von PostgreSQL ist die Version 6.5. - - Wir planen alle 4 Monate Hauptreleases herauszugeben. - - 1.8) Welche Dokumente sind für PostgreSQL verfügbar? - - Einige Handbücher, Man-Pages und einige kleine Testprogramme sind in - der Distribution enthalten. Siehe im /doc-Verzeichnis. - - psql hat einige nette \d-Befehle, um Informationen über Typen, - Operatoren, Funktionen, Aggregate, usw. zu zeigen. - - Die Website enthält sogar noch mehr Unterlagen. - - 1.9) Wie erfahre ich etwas über bekannte Fehler oder fehlende Eigenschaften - von PostgreSQL? - - PostgreSQL unterstützt eine ausgedehnte Untermenge von SQL-92. Siehe - unser TODO für eine Auflistung der bekannten Fehler, fehlende - Eigenschaften und zukünftige Pläne. - - 1.10) Wie kann ich SQL lernen? - - Es gibt nette SQL-Tutorials bei http://w3.one.net/~jhoffman/sqltut.htm - und bei - http://ourworld.compuserve.com/homepages/Graeme_Birchall/DB2_COOK.HTM. - - Viele unserer User mögen The Practical SQL Handbook, Bowman et al., - Addison Wesley. - - 1.11) Ist PostgreSQL Y2K (Jahr 2000) fähig? - - Ja, wir können Datumsangaben nach dem Jahr 2000 n.Chr. und vor 2000 - v.Chr. leicht verarbeiten. - - 1.12) Wie kann ich am Entwicklerteam teilnehmen? - - Zuerst lade die neuesten Quellen herunter und lies die - PostgreSQL-Entwicklerunterlagen auf unserer Website oder in der - Distribution. Zweitens melde Dich zu den Mailinglisten pgsql-hackers - und pgsql-patches an. Drittens sende qualitativ hochwertige - Programmänderungen an die pgsql-patches Mailingliste. - - Es gibt ungefähr ein Dutzend Leute, die das commit-Recht im - PostgreSQL-CVS Archiv haben. Alle haben so viele hochwertige Patches - eingebracht, daß es schwer für die CVS-Verwalter war, mitzuhalten. Und - wir hatten das Vertrauen, daß die Änderungen, die sie festlegten, sehr - wahrscheinlich von hoher Qualität sind. - - 1.13) Wie sende ich einen Fehler-Bericht? - - Fülle die "Fehler-Vorlage"-Datei (bug.template im doc-Verzeichnis) aus - und sende sie an: bugs@postgreSQL.org - - Überprüfe auch den ftp-Server ftp://ftp.postgreSQL.org/pub, um - nachzusehen, ob es eine neuere PostgreSQL-Version oder neue Patches - gibt. - - 1.14) Wie läuft PostgreSQL im Vergleich zu anderen Datenbanksystemen? - - Es gibt verschiedene Methoden, Software zu messen: Eigenschaften, - Leistung, Zuverlässigkeit, Support und Preis. - - Eigenschaften - PostgreSQL hat die meisten Eigenschaften, die in großen - kommerziellen DBMS's, wie Transaktionen, Sub-SELECTs, Trigger, - Views und verfeinertes Locking, vorhanden sind. Wir haben - einige Eigenschaften, die andere nicht haben, wie - benutzerbestimmte Typen, Vererbung, Regeln, und die - Multi-Versionen-Steuerung zum Verringern von konkurrierenden - Locks. Wir haben keine referentielle Integrität von externen - Schlüsseln oder Outer Joins, aber wir arbeiten an diesen Dingen - für unser nächstes Release. - - Leistung - PostgreSQL läuft in zwei Modi. Im normalen fsync-Modus wird - jede komplette Transaktion auf die Platte geschrieben und - garantiert, daß, selbst wenn das Betriebssystem abstürzt und - der Strom ausfällt, die Daten sicher gespeichert wurden. In - diesem Modus sind wir langsamer als die meisten kommerziellen - Datenbanken, zum Teil, weil wenige von ihnen solch eine - konservatives Methode der Datenspeicherung in ihren - Standardbetriebsmodi betreiben. - - Im no-fsync-Modus sind wir normalerweise schneller als - kommerzielle Datenbanken. In diesem Modus kann ein - Betriebssystemabsturz jedoch Datenkorruption zur Folge haben. - Wir arbeiten daran, einen Zwischenmodus zur Verfügung zu - stellen, der unter weniger Leistungseinbuße leidet als der - fsync-Modus und die Datenintegrität innerhalb 30 Sekunden im - Falle eines Betriebssystemabsturzes erlaubt. Der Modus ist - durch den Datenbankverwalter auswählbar. - - Im Vergleich zu MySQL oder schlankeren Datenbanksystemen sind - wir hinsichtlich INSERTs/UPDATEs langsamer, weil wir einen - Transaktions-Overhead haben. Selbstverständlich hat MySQL kaum - eine der Eigenschaften, die oben im Kapitel Eigenschaften - erwähnt werden. PostgreSQL ist für Flexibilität und gute - Eigenschaften designed, trotzdem fahren wir fort, die Leistung - durch Profiling und Quellcodeanalyse zu verbessern. - - Zuverlässigkeit - Wir stellen fest, daß ein DBMS zuverlässig sein muß, oder es - ist wertlos. Wir bemühen uns, gut geprüften, beständigen Code - freizugeben, der nur ein Minimum an Programmfehler hat. Jede - Freigabe hat mindestens einen Monat Betatestphase hinter sich, - und unsere Freigabehistorie zeigt, daß wir stabile, solide - Versionen freigeben, die im Produktionsbetrieb genutzt werden - können. Wir glauben, daß wir im Vergleich mit anderer - Datenbanksoftware vorteilhaft dastehen. - - Support - Unsere Mailingliste stellt eine große Gruppe Entwickler und - Benutzer zur Behebung aller möglichen anzutreffenden Probleme - zur Verfügung. Wir können nicht immer eine Fehlerbehebung - garantieren, kommerzielle DBMS's tun dies aber auch nicht. - Direkter Zugriff zu den Entwicklern, zur Benutzergemeinschaft, - zu den Handbüchern und zum Quellcode bietet häufig - höherwertigen PostgreSQL-Support im Vergleich zu anderen - DBMS's. Es gibt den kommerziellen "Pro-Ereignis"-Support, der - für diejenigen bereitgestellt wird, die ihn benötigen. (siehe - Support-Faq), - - Preis - PostgrSQL ist frei verfügbar, sowohl für die kommerzielle, wie - für die nicht-kommerzielle Nutzung. Du kannst Deinen Code fast - ohne Beschränkungen zu unserem hinzufügen. Die einzigen - Beschränkungen werden in der BSD-artigen Lizenz weiter oben - aufgeführt. - _________________________________________________________________ - - Fragen zu Benutzerprogrammen - - 2.1) Gibt es ODBC-Treiber für PostgreSQL? - - Es sind zwei ODBC-Treiber verfügbar: PostODBC und OpenLink ODBC. - - PostODBC ist in der Distribution enthalten. Mehr Informationen können - unter http://www.insightdist.com/psqlodbc abgerufen werden. - - OpenLink ODBC kann unter http://www.openlinksw.com geholt werden. Die - Software arbeitet mit OpenLinks Standard-ODBC-Client, so daß - PostgreSQL-ODBC auf jeder Client-Plattform zur Verfügung steht, die - unterstützt wird (Win, Mac, Unix, VMS). - - Sie werden dieses Produkt wahrscheinlich an Leute verkaufen, die - kommerziellen Qualitäts-Support brauchen, aber es wird immer eine - Freeware-Version verfügbar sein. Fragen dazu bitte an - postgres95@openlink.co.uk. - - 2.2) Welche Werkzeuge gibt es, um PostgreSQL-Datenbanken über Webseiten - verfügbar zu machen? - - Eine nette Einführung zu Datenbank-gestützten Webseiten kann unter - http://www.webtools.com abgerufen werden. - - Eine weitere gibt es bei http://www.phone.net/home/mwm/hotlist/. - - Für die Web-Integration ist PHP eine ausgezeichnete Schnittstelle. PHP - gibt es bei http://www.php.net - - PHP ist hervorragend für einfache Anbindungen geeignet. Für komplexere - Aufgaben nutzen viele die Perl-Schnittstelle mit CGI.pm. - - Einen WWW-Gateway, basierend auf WDB, kann man bei - http://www.eol.ists.ca/~dunlop/wdb-p95 herunterladen. - - 2.3) Hat PostgreSQL eine grafische Benutzerschnittstelle? Einen - Report-Generator? Eine eingebaute Query-Schnittstelle? - - Wir haben eine nette grafische Benutzerschnittstelle mit Namen - pgaccess, welche in der Distribution enthalten ist. pgaccess hat auch - einen Reportgenerator. Die Webpage liegt hier: - http://www.flex.ro/pgaccess - - In der Distribution gibt es außerdem ecpg,, welches eine eingebundene - SQL-Query-Schnittstelle für C zur Verfügung stellt. - - 2.4) Welche Sprachen sind für die Kommunikation mit PostgreSQL verfügbar? - - Wir haben: - * C(libpq) - * C++(libpq++) - * Embedded C(ecpg) - * Java(jdbc) - * Perl(perl5) - * ODBC(odbc) - * Python(PyGreSQL) - * TCL(libpgtcl) - * ein rohes C/4GL(contrib/pginterface) - * Embedded HTML(PHP from http://www.php.net) - _________________________________________________________________ - - Administrative Fragen - - 3.1) Warum schlägt initdb fehl? - - * überprüfe, daß keine Binaries vorheriger Versionen in Deinem Pfad - (PATH-Variable) sind. (Wenn Du die Meldung siehst: - NOTICE:heap_modifytuple: repl is \ 9, ist das das Problem.) - * überprüfe, daß der Pfad richtig gesetzt ist - * überprüfe, ob der User postgres der Eigentümer der entsprechenden - Dateien ist - - 3.2) Wie installiere ich PostgreSQL woanders als in /usr/local/pgsql? - - Der einfachste Weg ist mittels der --prefix Option beim configure den - Pfad anzugeben. Falls Du das vergessen haben solltest, kannst Du die - Datei Makefile.global ändern und POSTGRESDIR entsprechend anpassen, - oder Du erzeugst ein Makefile.custom und definierst POSTGRESDIR dort. - - 3.3) Wenn ich den postmaster starte, bekomme ich einen Bad System Call oder - eine core dumped Meldung. Warum? - - Das kann verschiedene Ursachen haben. Überprüfe zuerst, ob Dein Kernel - System V Extensions enthält. PostgreSQL benötigt die - Kernel-Unterstützung für Shared Memory und Semaphoren. - - 3.4) Wenn ich versuche, den postmaster zu starten, bekomme ich - IpcMemoryCreate Fehlermeldungen. Warum? - - Du hast entweder den Kernel nicht für Shared Memory konfiguriert, oder - Du mußt den Shared Memory Bereich vergrößern. Die genaue Größe hängt - von Deiner Systemarchitektur ab und mit wievielen Puffern und - Serverprozessen Du postmaster konfiguriert hast. Für die meisten - Systeme, mit Standardangaben für Puffer und Prozessen benötigst Du ein - Minimum von ca. 1 MB. - - 3.5) Wenn ich versuche, den postmaster zu starten, bekomme ich - IpcSemaphoreCreate Fehlermeldungen. Warum? - - Falls die Fehlermeldung IpcSemaphoreCreate: semget failed (No space - left on device) lautet, dann ist Dein Kernel mit zu wenig Semaphoren - konfiguriert. Postgres benötigt eine Semaphore pro möglichen - Backend-Prozess. Eine Zwischenlösung wäre, postmaster mit einer - geringeren Anzahl an Backend-Prozessen zu starten. Benutze dazu die -N - Option mit einem Wert kleiner als die standardmäßigen 32. Eine - dauerhafte Lösung wäre es, die Kernel-Parameter SEMMNS und SEMMNI zu - erhöhen. - - Falls die Fehlermeldung anders aussieht, hast Du möglicherweise keine - Semaphoren-Unterstützung in Deinem Kernel aktiviert. - - 3.6) Wie verhindere ich, daß andere Hosts auf meine PostgreSQL Datenbanken - zugreifen? - - Die Standardeinstellung ist, daß PostgreSQL Verbindungen von der - lokalen Maschine über Unix-Domain-Sockets erlaubt. Andere Maschinen - werden keine Verbindung aufbauen können, bis der postmaster mit der -i - Option gestartet ist und die Host-basierte Authentizierung in der - Datei $PGDATA/pg_hba.conf entsprechend angepasst ist. Das erlaubt - TCP/IP-Verbindungen. - - 3.7) Warum kann ich mich nicht von einer anderen Maschine mit meiner - Datenbank verbinden? - - Die Standardeinstellung erlaubt nur Unix-Domain-Socket-Verbindungen - der lokalen Maschine. Um TCP/IP Verbindungen zu ermöglichen, stelle - sicher, daß der postmaster mit der -i Option gestartet wurde, und füge - einen passenden Host-Eintrag in die Datei pgsql/data/pg_hba.conf ein. - Siehe auch die pg_hba.conf Man-Page. - - 3.8) Warum kann ich nicht als root auf die Datenbank zugreifen? - - Du solltest keine Datenbank-Benutzer mit der User-ID 0 (root) - erzeugen. Sie werden auf keine Datenbank zugreifen können. Das ist - eine Sicherheitsmaßnahme, wegen der Möglichkeit Objekt-Module - dynamisch in die Datenbank zu linken. - - 3.9) Alle meine Server stürzen bei gleichzeitigem Tabellenzugriff ab. - Warum? - - Dieses Problem kann durch einen Kernel verursacht werden, der ohne - Support für Semaphoren konfiguriert wurde. - - 3.10) Wie optimiere ich die Datenbankmaschine für bessere Leistung? - - Sicherlich können Indizes Abfragen beschleunigen. Der explain Befehl - erlaubt Dir zu sehen, wie PostgreSQL Deine Abfrage interpretiert und - welche Indizes benutzt werden. - - Wenn Du eine Menge INSERTs machst, überprüfe, ob Du sie als - Stapelverarbeitung mit dem copy-Befehl abarbeiten kannst. Das ist viel - schneller als einzelne INSERTs. Zweitens, SQL-Statements, die nicht in - einem begin work/commit Transaktions-Block eingegeben werden, werden - als eigene Transaktion behandelt. Überprüfe, ob die Statements nicht - in einen einzelnen Transaktions-Block zusammengefasst werden können. - Das reduziert den Transaktions-Overhead. Du kannst auch erwägen, - Indizes zu löschen und neu zu erstellen, wenn Du große Datenmengen - änderst. - - Es gibt verschiedene Tuning-Maßnahmen, die man ergreifen kann. Du - kannst fsync() abschalten, indem Du beim Starten des postmasters die - Optionen -o -F angibst. Das hindert fsync()´s daran, nach jeder - Transaktion die Daten auf die Platte zu schreiben. Du kannst auch mit - der -B Option des postmasters die Anzahl der Shared Memory Puffer für - den Backend-Prozess erhöhen. Falls Du diesen Wert zu hoch einstellst, - kann es sein, daß der postmaster nicht startet, weil der Shared Memory - Speicherplatz Deines Kernels aufgebraucht wird. Jeder Puffer ist 8 kB - groß und es gibt standardmäßig 64 Puffer. - - Du kannst ebenfalls die -S Option des Backends nutzen, um die Größe - des Speicherplatzes für temporäres Sortieren zu erhöhen. Der -S Wert - wird in Kilobyte gemessen und ist standardmäßig auf 512 kB festgelegt. - Es wäre jedoch unklug, den Wert zu hoch anzugeben, da ein Query - möglicherweise Speicherplatzmangel verursacht, wenn es viele - gleichzeitige Sortierungen durchführen muß. - - Der cluster Befehl kann benutzt werden, um Daten in Basistabellen zu - gruppieren, so daß sie auf einen Index zusammengebracht werden. Siehe - auch die cluster(l) Man-Page für weitere Details. - - 3.11) Welche Debugging/Fehlersuch-Hilfsmittel sind für PostgreSQL - verfügbar? - - PostgreSQL hat einige Möglichkeiten, Statusinformationen zu berichten, - die nützlich für die Fehlersuche sein können. - - Erstens, wenn beim configure-Lauf die Option --enable-cassert - angegeben wurde, verfolgen viele assert()´s den Fortschritt des - Backends und halten das Programm an, wenn etwas Unerwartetes passiert. - - Postmaster und postgres, haben mehrere Fehlersuch-Optionen zur - Verfügung. Stelle zuerst sicher, daß Du den Standard-Output und - Fehlerkanal in eine Datei umleitest, wenn Du den postmaster startest, - : - - cd /usr/local/pgsql - ./bin/postmaster >server.log 2>&1 & - - Das erzeugt eine server.log Datei im PostgreSQL-Verzeichnis. Diese - Datei enthält nützliche Informationen über Probleme oder Fehler, die - im Server aufgetreten sind. Postmaster hat eine -d Option, die noch - detailliertere Informationen liefert. Zur -d Option wird eine Nummer - angegeben, die den Debug-Level - also die Menge der berichteten - Information - angibt. Achtung, hohe Debug-Level erzeugen schnell große - Logdateien! - - Du kannst tatsächlich das Postgres-Backend auf der Kommandozeile - laufen lassen und SQL-Statements direkt eingeben. Diese Vorgehensweise - wird aber nur zur Fehlersuche empfohlen. Beachte, daß ein - Zeilenumbruch das SQL-Statement beendet, nicht das Semikolon. Wenn Du - PostgreSQL mit Debugging-Symbolen kompiliert hast, kannst Du einen - Debugger benutzen, um zu beobachten, was passiert. Da das Backend - nicht vom postmaster gestartet wurde, läuft es nicht in der gleichen - Umgebung und deshalb können einige locking/backend Operationen nicht - reproduziert werden. Einige Betriebssysteme können sich an einen - Backend-Prozess direkt anhängen, um Probleme zu diagnostizieren. - - Das Programm postgres hat -s, -A und -t Optionen, die bei der - Fehlersuche und Leistungsmessung sehr nützlich sein können. Du kannst - das Paket auch mit Profiling kompilieren, um zu sehen, welche - Funktionen wieviel Ausführungszeit beanspruchen. Das Backend Profil - wird im Verzeichnis pgsql/data/base/dbname abgelegt. Das Client Profil - wird in das aktuelle Verzeichnis abgelegt. - - 3.12) Ich bekomme die Meldung "Sorry, too many clients", wenn ich eine - Verbindung versuche. Warum? - - Du mußt die Grenze des postmasters, die festlegt, wieviele - gleichzeitige Backend-Prozesse gestartet werden können, hochsetzen. - - In Postgres 6.5 sind das normalerweise 32 Prozesse. Du kannst diesen - Wert dadurch erhöhen, daß Du den postmaster mit einem entsprechenden - -N Wert neu startest. In der Standardkonfiguration kannst Du -N auf - maximal 1024 setzen. Falls Du mehr brauchst, erhöhe MAXBACKENDS in - include/pg_config.h und kompiliere das Paket neu. Du kannst den - Standardwert von -N während der Konfiguration setzen, indem Du - --with-maxbackends angibst. Anmerkung: Falls Du -N größer als 32 - einstellst, solltest Du -B auf einen Wert, höher als 64 setzen. Für - eine hohe Anzahl an Backend-Prozessen, solltest Du möglicherweise - einige Unix-Kernel Parameter ebenfalls erhöhen. Folgendes Parameter - solltest Du prüfen: die Maximalgröße der Shared Memory Blocks SHMMAX, - die Maximalanzahl der Semaphoren SEMMNS und SEMMNI, die maximale - Anzahl von Prozessen NPROC, die maximale Anzahl von Prozessen pro User - MAXUPRC, und die Maximalzahl der geöffneten Dateien NFILE und NINODE. - Der Grund für die Begrenzung der erlaubten Backend-Prozesse liegt - darin, daß verhindert werden soll, daß das System seine freien - Ressourcen aufbraucht. - - In den Postgres-Versionen vor 6.5 war die maximale Anzahl von Backends - auf 64 festgelegt und eine Änderung setzte eine erneute Kompilierung - voraus, bei der die Konstante MaxBackendId in - include/storage/sinvaladt.h. entsprechend angepasst wurde. - - 3.13) Was sind die pg_psort.XXX Dateien in meinem Datenbank-Verzeichnis? - - Dies sind temporäre Dateien, die durch den Query-Ausführer erzeugt - werden. Wenn zum Beispiel eine Sortierung durchgeführt werden muß, um - ein ORDER BY auszuführen, und diese Sortierung mehr Platz benötigt, - als mit dem Backend-Parameter -S erlaubt wurde, dann werden diese - temporären Dateien erzeugt, um die Daten dort zu halten. - - Die temporären Dateien sollten automatisch gelöscht werden, falls das - Backend jedoch während einer Sortierung abstürzt, bleiben sie - erhalten. Wenn zu diesem Zeitpunkt keine Transaktion läuft, kannst Du - die pg_tempNNN.NN Dateien ohne Gefahr löschen. - - 3.14) Wie richte ich eine Benutzergruppe (pg_group) ein? - - Zur Zeit gibt es keine einfache Schnittstelle, um Benutzergruppen - einzurichten Du mußt explizit die pg_group-Tabelle mittels - INSERT/UPDATE modifizieren. Zum Beispiel: - - jolly=> INSERT into pg_group (groname, grosysid, grolist) - jolly=> values ('posthackers', '1234', '{5443, 8261}'); - INSERT 548224 - jolly=> grant INSERT on foo to group posthackers; - CHANGE - jolly=> - - Die Felder in pg_group sind: - * groname: der Gruppenname. Dieser Name sollte rein alphanumerisch - sein. Keine Unterstriche oder andere Punktionen - * grosysid: die Gruppen-ID. Die Gruppen-ID ist ein int4-Feld. Sie - sollte eindeutig für jede Gruppe sein. - * grolist: die Liste der pg_user IDs, die zu dieser Gruppe gehören. - (int4[].) - _________________________________________________________________ - - Fragen zum Betrieb - - 4.1) Das System scheint Kommata, Dezimalpunkte und Datumsformate - durcheinanderzubringen. - - Überprüfe die Konfiguration Deiner Locale-Einstellung. PostgreSQL - benutzt die Einstellungen des jeweiligen Users und nicht die des - postmaster Prozesses. Es gibt postgres und psql SET Befehle, um das - Datumsformat zu kontrollieren. Setzte diese entsprechend Deiner - Arbeitsumgebung. - - 4.2) Was ist der genauer Unterschied zwischen Binary Cursors und Normal - Cursors? - - Vgl. die declare Man-Page für eine Beschreibung. - - 4.3) Wie wähle ich per SELECT nur die ersten paar Zeilen in einem Query - aus? - - Vgl. die fetch Man-Page, oder benutze SELECT ... LIMIT.... - - Das verhindert nur, daß alle Ergebniszeilen zum Client übermittelt - werden. Die komplette Abfrage muß abgearbeitet werden, selbst wenn Du - nur die ersten paar Zeilen haben möchtest. Ziehe ein Query in - Erwägung, das ein ORDER BY benutzt. Es gibt keine Möglichkeit Zeilen - zurückzuliefern, bevor nicht die komplette Abfrage abgearbeitet ist. - - 4.4) Wie bekomme ich eine Liste der Tabellen oder anderen Dingen, die ich - in psql sehen kann - - Du kannst Dir die Datei pgsql/src/bin/psql/psql.c mit dem Quellcode - für psql ansehen. Sie enthält die SQL-Befehle, die die - Backslash-Kommandos (\) ausführen. Seit Postgres 6.5 kannst Du psql - auch mit der -E Option starten. Dadurch gibt psql die Queries aus, die - es bei der Ausführung der Befehle benutzt. - - 4.5) Wie entferne ich eine Spalte von einer Tabelle? - - Wir unterstützen alter table drop column nicht, aber mache es so: - - SELECT ... -- wähle alle Spalten außer die, die Du entfernen willst - INTO TABLE new_table - FROM old_table; - DROP TABLE old_table; - ALTER TABLE new_table RENAME TO old_table; - - 4.6) Was ist die Maximalgröße für eine Zeile, eine Tabelle, eine Datenbank? - - Zeilen sind auf 8 kB begrenzt, aber das kann geändert werden, indem Du - in include/config.h die Konstante BLCKSZ änderst. Um Attribute mit - mehr als 8 kB zu nutzen, kannst Du auch das "Large Object Interface" - benutzen. - - Zeilen überschreiten keine 8 kB-Grenzen. Eine Zeile mit 5 kB wird 8 kB - Speicherplatz benötigen. - - Tabellen- und Datenbankgrößen haben keine Grenzen. Es gibt viele - Datenbanken mit zig Gigabytes und wahrscheinlich einige mit hunderten - Gigabyte. - - 4.7) Wieviel Plattenplatz benötigt eine Datenbank zur Speicherung einer - Datendatei mit zeilenweisen Datensätzen? - - Eine Postgres Datenbank kann ungefähr sechseinhalb mal soviel Platz - brauchen, wie eine einfache Textdatei. - - Betrachten wir eine Datei mit 300.000 Zeilen, mit jeweil zwei Integern - pro Zeile. Die einfache Textdatei benötigt 2,4 MB Speicherplatz. Die - Größe der Postgres Datenbankdatei, die diese Daten enthält, liegt - ungefähr bei 14 MB. - 36 Bytes: jeder Zeilenkopf (ungefähr) - + 8 Bytes: zwei Integer-Felder @ jedes 4 Bytes - + 4 Bytes: Zeiger auf den Datensatz - ----------------------------------------------- - 48 Bytes pro Zeile - - Die Größe einer Datenseite in PostgreSQL ist 8192 Bytes (8 KB), also: - - 8192 Bytes pro Seite - --------------------- = 171 Zeilen pro Seite (aufgerundet) - 48 Bytes pro Zeile - - 300000 Datenzeilen - ----------------------- = 1755 Datenbankseiten - 171 Zeilen pro Seite - -1755 Datenbankseiten * 8192 Bytes pro Seite = 14,376,960 Bytes (14MB) - - Indizes haben nicht einen solchen Overhead, sie beinhalten jedoch die - Daten, die sie indizieren und können so auch sehr groß werden. - - 4.8) Wie finde ich heraus, welche Indizes oder Operationen in der Datenbank - definiert sind? - - psql hat eine Vielzahl von Backslash Befehlen, um solche Informationen - zu zeigen. Benutze \?, um sie zu sehen. - - Schaue Dir auch die Datei pgsql/src/tutorial/syscat.source. an. Sie - illustriert viele der SELECTs, die benötigt werden, um diese - Informationen von der Datenbank-Systemtabelle zu erhalten - - 4.9) Meine Queries sind langsam oder nutzen die Indizes nicht. Warum? - - PostgeSQL pflegt automatische Statistiken nicht. Um die Statistiken zu - aktualisieren, mußt Du ein explizites vacuum eingeben. Nach dieser - Aktualisierung weiß der Optimierer wieviele Zeilen in der Tabelle sind - und kann besser entscheiden, ob Indizes benutzt werden sollten. Der - Optimierer benutzt keine Indizes, wenn die Tabelle klein ist, weil ein - sequentieller Suchlauf dann schneller sein würde. - - Benutze den Befehl vacuum analyze für die spaltenspezifische - Optimierung. Vacuum analyze ist für komplexe Multi-Join-Abfragen - wichtig, damit der Optimierer die Anzahl der Zeilen von jeder Tabelle - schätzen und dann die passende Join-Reihenfolge wählen kann. Das - Backend verfolgt die Spaltenstatistik nicht selbst, so daß vacuum - analyze regelmäßig aufgerufen werden sollte. - - Indizes werden nicht für ORDER BY Operationen benutzt. - - Bei der Nutzung von Wildcard-Operatoren wie LIKE oder ~, können - Indizes nur benutzt werden, wenn die Suche mit dem Anfang eines - Strings startet. Um also Indizes zu nutzen, sollten LIKE-Suchen nicht - mit %, und ~ beginnen (Die Sucheparameter regulärer Ausdrücke sollten - mit ^. beginnen. - - 4.10) Auf welche Weise kann ich sehen, wie der Query-Optimierer meine - Abfrage auswertet? - - Vgl. die EXPLAIN Man-Page. - - 4.11) Was ist ein R-Tree Index? - - Ein R-Tree Index wird benutzt, um räumliche Daten zu indizieren. Ein - Hash-Index kann nicht für Bereichssuchen genutzt werden. Ein B-Tree - Index kann nur für Bereichssuchen in eindimensionalen Daten genutzt - werden. R-Trees können multi-dimensionale Daten abhandeln. Ein - Beispiel: Wenn ein R-Tree Index auf ein Attribut vom Typ POINT - gebildet wird, dann kann das System Abfragen wie z.B. "Zeige alle - Punkte, die sich in einem umgebenden Rechteck befinden" effizienter - beantworten. - - Die kanonische Veröffentlichung , die das originale R-Tree Design - beschreibt ist: - - Guttman, A. "R-Trees: A Dynamic Index Structure for Spatial - Searching." Proc of the 1984 ACM SIGMOD Int'l Conf on Mgmt of Data, - 45-57. - - Du kannst dieses Werk ebenfalls in Stonebraker's "Readings in Database - Systems" finden. - - Die eingebauten R-Trees können Polygone und Rechtecke verarbeiten. - Theoretisch können R-Trees auf eine hohe Anzahl von Dimensionen - erweitert werden. Praktisch bedingt diese Erweiterung eine Menge - Arbeit und wir haben derzeit keinerlei Dokumentation darüber, wie das - zu machen wäre. - - 4.12) Was ist "Genetic Query Optimization"? - - Das GEQO-Modul in PostgreSQL soll dazu dienen, das Optimierungsproblem - beim Joining vieler Tabellen auf der Basis genetischer Algorithmen - (GA) zu lösen. Es erlaubt die Behandlung von großen Join-Queries ohne - erschöpfende Suche. - - Für weitere Informationen siehe die Dokumentation. - - 4.13) Wie verfahre ich bei der Suche mit regulären Ausdrücken und bei einer - Suche mit Ignorierung der Groß- und Kleinschreibweisen? - - ~ und ~* sind wahrscheinlich das, was Du willst. Vgl. psql's \do - Befehl. - - 4.14) Wie ermittle ich in einem Query, daß ein Feld NULL ist? - - Du testest die Spalte mit IS NULL und IS NOT NULL. - - 4.15) Was ist der Unterschied zwischen den verschiedenen CHAR-Typen? - -Typ interner Name Bemerkungen --------------------------------------------------- -CHAR char 1 Zeichen -CHAR(#) bpchar mit Leerzeichen gefüllt bis zur angegebenen Län -ge -VARCHAR(#) varchar Die Größe legt die Maximallänge fest, kein Ausf -üllen mit Leerzeichen -TEXT text Die Länge wird nur durch die maximale Zeilenlän -ge beschränkt -BYTEA bytea Bytearray mit variabler Länge - - Du mußt die internen Namen benutzen, wenn Du interne Operationen - durchführen willst. - - Die letzten vier Typen sind "varlena"-Typen (d.h. die ersten vier - Bytes geben die Länge an, gefolgt von den Daten). CHAR(#) belegt die - maximale Anzahl von Bytes, unabhängig davon, wieviele Daten im Feld - gespeichert werden. TEXT, VARCHAR(#) und BYTEA haben alle eine - variable Länge auf dem Datenträger, deshalb gibt es einen leichten - Geschwindigkeitsnachteil bei der Nutzung dieser Typen. Genauer, der - Nachteil gilt für den Zugriff auf alle Spalten nach der ersten Spalte - dieses Typs. - - 4.16) Wie erzeuge ich ein serielles Feld mit automatischer Erhöhung des - Inhalts? - - PostgreSQL unterstützt einen SERIAL Datentyp. Er erzeugt automatisch - eine Sequenz und einen Index auf die Spalte. Siehe die create_sequence - Man-Page für weitere Informationen über Sequenzen. Du kannst aber auch - das Oid Feld jeder Zeile als eindeutigen Wert nutzen. Jedoch mußt Du, - falls Du Deine Datenbank einmal komplett ausgeben und wieder einlesen - willst, die pg_dump's -o oder die copy with oids Option benutzen, um - die Oids zu retten. - - 4.17) Was ist ein Oid? Was ist ein Tid? - - Oids sind PostgreSQLs Antwort auf eindeutige Zeilen-IDs. Jede Zeile, - die in PostgreSQL erzeugt wird, bekommt eine eindeutige Oid. Alle - Oids, die während initdb erzeugt werden, sind kleiner als 16384 (nach - backend/access/transam.h). Alle Oids, die durch den Benutzer erzeugt - werden, sind gleich oder größer als dieser Wert. Standardmäßig sind - all diese Oids nicht nur innerhalb einer Tabelle oder Datenbank, - sondern in der gesamten PostgreSQL Installation eindeutig. - - PostgreSQL benutzt Oids in seinen internen Systemtabellen, um Zeilen - zwischen den Tabellen zu verbinden. Diese Oids können zur - Identifikation spezifischer Benutzerzeilen und in Joins genutzt - werden. Es wird empfohlen, den Spaltentyp OID zu nutzen, um Oids-Werte - zu speichern. Siehe die sql(l) Man-Page, um die anderen internen - Spalten kennenzulernen. Du kannst einen Index auf ein Oid-Feld - erzeugen, um schnelleren Zugriff zu erreichen. - - Oids werden allen neuen Zeilen von einem zentralen Bereich, der von - allen Datenbanken genutzt wird, zugewiesen. Es gibt keinen Grund, - warum Du nicht die Oid ändern, oder eine Kopie der Tabelle mit den - originalen Oids anlegen könntest. - CREATE TABLE new_table(old_oid oid, mycol int); - SELECT INTO new SELECT old_oid, mycol FROM old; - COPY new TO '/tmp/pgtable'; - DELETE FROM new; - COPY new WITH OIDS FROM '/tmp/pgtable'; - - Tids werden genutzt, um spezifische physische Zeilen mit Block und - Versatzwert zu identifizieren. Tids ändern sich, wenn Zeilen geändert - oder neu geladen werden. Sie werden von Index-Einträgen genutzt, um - die Zeilen physisch zu adressieren. - - 4.18) Was ist die Bedeutung der verschiedenen Ausdrücke, die in PostgreSQL - benutzt werden (z.B. attribute, class,...)? - - Einige der Quelltexte und die ältere Dokumentation nutzen allgemeine - Begriffe. Hier sind einige aufgeführt: - * row, record, tuple - * attribute, field, column - * table, class - * retrieve, SELECT - * replace, UPDATE - * append, INSERT - * oid, serial value - * portal, cursor - * range variable, table name, table alias - - 4.19) Wieso bekomme ich einen Fehler: "FATAL: palloc failure: memory - exhausted?" - - Möglicherweise ist der virtuelle Speicher verbraucht oder Dein Kernel - hat eine niedrige Grenze für bestimmte Ressourcen. Versuche dieses, - bevor Du den postmaster startest: - - ulimit -d 65536 - limit datasize 64m - - Je nach Deiner eingesetzten Shell mag nur einer dieser Befehle - funktionieren. Aber es wird die Grenze des Datensegments für Prozesse - erhöhen und vielleicht läuft so Dein Query durch. Dieser Befehl wirkt - sich auf den aktuellen Prozess und alle seine Unterprozesse aus, die - nach diesem Befehl gestartet werden. Falls Du ein Problem mit dem - SQL-CLient hast, weil das Backend zu viele Daten zurückliefert, - versuche diesen Befehl, bevor Du den SQL-Client startest. - - 4.20) Wie kann ich feststellen, welche PostgreSQL-Version ich laufen habe? - - Gib in psql SELECT version(); ein - - 4.21) Beim Arbeiten mit "large-object" kommt die Fehlermeldung: invalid - large obj descriptor. Warum? - - Du solltest die Befehle BEGIN WORK und COMMIT bei jeden Gebrauch von - Large Objects benutzen. Also um lo_open ... lo_close. - - Die Dokumentation hat schon immer darauf hingewiesen, daß lo_open in - eine Transaktion eingebunden werden muß, aber die PostgreSQL Versionen - vor 6.5 haben diese Regel nicht erzwungen. Statt dessen scheiterten - sie gelegentlich, wenn Du diese Regel gebrochen hattest. - - Das aktuelle PostgreSQL erzwingt diese Regel, indem es die Handles der - Large Objects beim COMMIT der Transaktion schließt, was sofort nach - dem lo_open passiert, wenn Du nicht innerhalb einer Transaktion bist. - So führt der erste Versuch, etwas mit dem Large Object zu machen zu - einem invalid large obj descriptor. Also wird der Code, der bisher - benutzt wurde, nun diese Fehlermeldung erzeugen, wenn Du keine - Transaktionen benutzt hast. - - Falls Du eine Client-Schnittstelle wie ODBC benutzt, kann es sein, daß - Du auto-commit off setzen mußt. - _________________________________________________________________ - - PostgreSQL erweitern - - 5.1) Ich habe eine benutzerdefinierte Funktion geschrieben. Wenn ich sie in - psql aufrufe, kommt ein core dump. Warum? - - Dieses Problem kann viele Ursachen haben. Teste deine Funktion zuerst - in einem Extra-Testprogramm. Stelle außerdem sicher, daß Deine - Funktion nicht etwa elog-Nachrichten sendet, wenn der Client Daten - erwartet, wie in den type_in() oder type_out() Funktionen - - 5.2) Was bedeutet die Meldung: NOTICE:PortalHeapMemoryFree: 0x402251d0 not - in alloc set!? - - Du pfreest etwas, das Du nicht palloct hast! Stelle sicher, daß Du - nicht malloc/free und palloc/pfree durcheinanderwürfelst. - - 5.3) Wie kann ich ein paar elegante neue Feldtypen und Funktionen zu - PostgreSQL beitragen? - - Sende Deine Erweiterungen zur pgsql-hackers Mailing Liste, und sie - werden eventuell im contrib/ Verzeichnis enden. - - 5.4) Wie schreibe ich eine Funktion in C, die einen Tuple zurückliefert? - - Das erfordert derart extreme Genialität, daß die Autoren es niemals - versucht haben, obwohl es im Prinzip zu machen wäre. - - 5.5) Ich habe eine der Quellendateien geändert. Warum macht sich die - Änderung beim erneuten Compilerlauf nicht bemerkbar? - - Die Makefiles finden nicht die richtigen Abhängigkeiten. Du mußt ein - make clean und dann ein weiteres make machen. diff --git a/doc/FAQ_japanese b/doc/FAQ_japanese deleted file mode 100644 index 0d989f2f49..0000000000 --- a/doc/FAQ_japanese +++ /dev/null @@ -1,1297 +0,0 @@ -PostgreSQL(¥Ý¥¹¥È¥°¥ì¥¹¡¦¥­¥å¡¼¡¦¥¨¥ë)¤Ë¤Ä¤¤¤Æ¤è¤¯¤¢¤ë¼ÁÌä¤È¤½¤Î²òÅú(FAQ) - -¸¶Ê¸ºÇ½ª¹¹¿·Æü: Fri Apr 26 23:03:46 EDT 2002 - -¸½ºß¤Î°Ý»ý´ÉÍý¼Ô: Bruce Momjian (pgman@candle.pha.pa.us) -Maintainer of Japanese Translation: Jun Kuwamura (juk@postgresql.jp) - -¤³¤Îʸ½ñ¤ÎºÇ¿·ÈÇ¤Ï http://www.PostgreSQL.org/docs/faq-english.html ¤Ç¸«¤ë¤³¤È¤¬ -¤Ç¤­¤Þ¤¹¡£ - -¥×¥é¥Ã¥È¥Û¡¼¥à¤ËÆÃÍ­¤Î¼ÁÌä¤Ë¤Ä¤¤¤Æ¤Ï: http://www.PostgreSQL.org/users-lounge/ -docs/faq.html -¤Ë²óÅú¤¬¤¢¤ê¤Þ¤¹¡£ - -(°Ê²¼¡¢Ìõ¼Ô¤Ë¤è¤ëÃí¼á¤ò [ÌõÃí¡§ ¤È ] ¤È¤Ç°Ï¤ó¤Çµ­¤·¤Þ¤¹¡£) -[ÌõÃí¡§ - ÆüËܸìÈÇÀ½ºî¤Ë¤Ä¤¤¤Æ¤Î¥á¥â¤ÏºÇ¸åÈø¤Ø°Üư¤·¤Þ¤·¤¿¡£ - - ÆüËܸìÈǤΤ³¤Îʸ½ñ¤Ï ËÜ²È "User's Lounge" ¤Î "Collection of FAQs" ¤Î - "Japanese" ¤È¤¤¤¦¸«½Ð¤·¤Î¤È¤³¤í¤Ë¤¢¤ê¤Þ¤¹¡£¤Þ¤¿¡¢°Ê²¼¤Î¥µ¥¤¥È¤Ë¤â - ¤¢¤ê¤Þ¤¹¡£ - http://www.rccm.co.jp/~juk/pgsql/ - http://www.linux.or.jp/JF/ - - ¤³¤ÎÏÂÌõ¤Ë¤Ä¤¤¤Æ¤ªµ¤¤Å¤­¤ÎÅÀ¤Ï(juk@postgresql.jp)¤Þ¤Ç¥á¡¼¥ë¤Ç¤ª´ó¤»²¼¤µ¤¤¡£ -] - - -¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬ - °ìÈÌŪ¤Ê¼ÁÌä - -1.1) PostgreSQL¤È¤Ï²¿¤Ç¤¹¤«¡©²¿¤ÈÆÉ¤ß¤Þ¤¹¤«¡© -1.2) PostgreSQL¤ÎÃøºî¸¢¤Ï¤É¤¦¤Ê¤Ã¤Æ¤Þ¤¹¤«¡© -1.3) PostgreSQL¤Îưºî¤¹¤ëUnix¥×¥é¥Ã¥È¥Û¡¼¥à¤Ï¡© -1.4) Unix°Ê³°¤Î°Ü¿¢ÈǤǻȤ¨¤ë¤â¤Î¤Ï¡© -1.5) PostgreSQL¤Ï¤É¤³¤«¤éÆþ¼ê¤Ç¤­¤Þ¤¹¤«¡© -1.6) ¥µ¥Ý¡¼¥È¤Ï¤É¤³¤Ç¼õ¤±¤é¤ì¤Þ¤¹¤«¡© -1.7) ºÇ¿·ÈǤϤɤì¤Ç¤¹¤« -1.8) ¤É¤Î¤è¤¦¤Êʸ½ñ¤¬¤¢¤ê¤Þ¤¹¤«¡© -1.9) ´ûÃΤΥХ°¤ä̤¤À̵¤¤µ¡Ç½¤Ï¤É¤¦¤ä¤Ã¤Æ¸«¤Ä¤±¤Þ¤¹¤«¡© -1.10) SQL¤Ï¤É¤¦¤¹¤ì¤Ð³Ø¤Ù¤Þ¤¹¤«¡© -1.11) PostgreSQL¤ÏÀ¾Îñ2000ǯÌäÂê(Y2K)¤ËÂбþ¤·¤Æ¤¤¤Þ¤¹¤«¡© -1.12) ³«È¯¥Á¡¼¥à¤Ë¤Ï¤É¤Î¤è¤¦¤Ë»²²Ã¤·¤Þ¤¹¤«¡© -1.13) ¥Ð¥°¥ì¥Ý¡¼¥È¤Ï¤É¤Î¤è¤¦¤Ëȯ¿®¤·¤Þ¤¹¤«¡© -1.14) ¾¤ÎDBMS¤Î¤ÈÈæ¤Ù¤ÆPostgreSQL¤Ï¤É¤¦¤Ê¤Î¤Ç¤¹¤«¡© -1.15) PostgreSQL¤ò»ñ¶âÌ̤DZç½õ¤¹¤ë¤Ë¤Ï¤É¤¦¤¹¤ì¤Ð¤è¤¤¤Ç¤¹¤«¡© - - ¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¤¥¢¥ó¥È¤Î¼ÁÌä - -2.1) PostgreSQL ¤Î ODBC ¥É¥é¥¤¥Ð¡¼¤Ï¤¢¤ê¤Þ¤¹¤«¡© -2.2) PostgreSQL ¤ò Web ¥Ú¡¼¥¸¤ÈÏ¢·È¤µ¤»¤ë¤Ë¤Ï¤É¤ó¤Ê¥Ä¡¼¥ë¤¬¤¢¤ê¤Þ¤¹¤«¡© -2.3) PostgreSQL ¤Ë¥°¥é¥Õ¥£¥«¥ë¡¦¥æ¡¼¥¶¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Ï¤¢¤ê¤Þ¤¹¤«¡©¥ì¥Ý¡¼¥È¥¸ -¥§¥Í¥ì¡¼¥¿¤äËä¤á¹þ¤ßÌ䤤¹ç¤ï¤»¸À¸ì¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Ï¤¢¤ê¤Þ¤¹¤«¡© -2.4) PostgreSQL ¤ÈÄÌ¿®¤¹¤ë¤Ë¤Ï¤É¤ó¤Ê¸À¸ì¤¬»È¤¨¤Þ¤¹¤«¡© - - ´ÉÍý¾å¤Î¼ÁÌä - -3.1) ¤É¤Î¤è¤¦¤Ë¤¹¤ì¤Ð /usr/local/pgsql °Ê³°¤Î¾ì½ê¤Ë¥¤¥ó¥¹¥È¡¼¥ë¤Ç¤­¤Þ¤¹¤«¡© -3.2) postmaster ¤òÁö¤é¤»¤ë¤È¡¢ Bad System Call ¤È¤«¥³¥¢¡¦¥À¥ó¥×¤·¤¿¤È¤Î¥á¥Ã¥»¡¼ -¥¸¤¬½Ð¤Þ¤¹¡£¤Ê¤¼¤Ç¤¹¤«¡© -3.3) postmaster ¤òÁö¤é¤»¤è¤¦¤È¤¹¤ë¤È¡¢ IpcMemoryCreate ¥¨¥é¡¼¤¬½Ð¤Þ¤¹¡£¤Ê¤¼¤Ç¤¹ -¤«¡© -3.4) postmaster¤òÁö¤é¤»¤è¤¦¤È¤¹¤ë¤È¡¢ IpcSemaphoreCreate ¥¨¥é¡¼¤¬½Ð¤Þ¤¹¡£¤Ê¤¼¤Ç -¤¹¤«¡© -3.5) ¾¤Î¥Û¥¹¥È¤«¤é¤ÎÀܳ¤Ï¤É¤Î¤è¤¦¤ËÀ©¸æ¤·¤Þ¤¹¤«¡© -3.6) ¤è¤êÎɤ¤À­Ç½¤òÆÀ¤ë¤¿¤á¤Ë¤Ï¡¢¥Ç¡¼¥¿¥Ù¡¼¥¹¡¦¥¨¥ó¥¸¥ó¤ò¤É¤Î¤è¤¦¤ËÄ´À°¤¹¤ì¤ÐÎÉ -¤¤¤Ç¤¹¤«¡© -3.7) ¤É¤Î¤è¤¦¤Ê¥Ç¥Ð¥°µ¡Ç½¤¬»È¤¨¤Þ¤¹¤«¡© -3.8) Àܳ¤·¤è¤¦¤È¤¹¤ë¤È¤­¤Ë 'Sorry, too many clients' ¤¬½Ð¤ë¤Î¤Ï¤Ê¤¼¤Ç¤¹¤«¡© -3.9) ¼«Ê¬¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¡¦¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¢¤ë pg_sorttemp.XXX ¥Õ¥¡¥¤¥ë¤Ï²¿¤Ç¤¹¤« -¡© - - Áàºî¾å¤Î¼ÁÌä - -4.1) ¥Ð¥¤¥Ê¥ê¡¦¥«¡¼¥½¥ë¤ÈÄ̾參¡¼¥½¥ë¤È¤Î°ã¤¤¤Ï²¿¤Ç¤¹¤«¡© -4.2) ºÇ½é¤Î¿ô¥í¥¦¤Î¤ß¤ò select ¤¹¤ë¤Ë¤Ï¤É¤¦¤·¤Þ¤¹¤«¡© -4.3) ¥Æ¡¼¥Ö¥ë¤ä¤½¤Î¾¤Î¾ðÊó¤Î¥ê¥¹¥È¤ò psql ¤Ç¸«¤ë¤Ë¤Ï¤É¤¦¤·¤Þ¤¹¤«¡© -4.4) ¥Æ¡¼¥Ö¥ë¤«¤é¥«¥é¥à¤Îºï½ü¤Ï¤É¤Î¤è¤¦¤Ë¤·¤Þ¤¹¤«¡© -4.5) ¥í¥¦¡¢¥Æ¡¼¥Ö¥ë¡¢¥Ç¡¼¥¿¥Ù¡¼¥¹¤ÎºÇÂ祵¥¤¥º¤Ï¡© -4.6) °ìÈÌŪ¤Ê¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤«¤é¥Ç¡¼¥¿¤òÊݸ¤¹¤ë¤Ë¤Ï¡¢¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¥Ç¥£¥¹¥¯ÍÆ -Î̤ϤɤΤ¯¤é¤¤É¬ÍפǤ¹¤«¡© -4.7) ÄêµÁ¤µ¤ì¤¿¥Æ¡¼¥Ö¥ë¡¢¥¤¥ó¥Ç¥Ã¥¯¥¹¡¢¥Ç¡¼¥¿¥Ù¡¼¥¹¡¢¤ª¤è¤Ó¡¢¥æ¡¼¥¶¤ò¤É¤Î¤è¤¦¤Ë -¤·¤Æ¸«¤Ä¤±½Ð¤·¤Þ¤¹¤«¡© -4.8) Ì䤤¹ç¤ï¤»¤¬ÃÙ¤¤¤¦¤¨¡¢¥¤¥ó¥Ç¥Ã¥¯¥¹¤ò»È¤Ã¤Æ¤¤¤ëÍͻҤ¬¤¢¤ê¤Þ¤»¤ó¡£¤Ê¤¼¤Ç¤¹¤« -¡© -4.9) Ì䤤¹ç¤ï¤»¥ª¥Ö¥Æ¥£¥Þ¥¤¥¶¤¬¤É¤Î¤è¤¦¤ËÌ䤤¹ç¤ï¤»¤òɾ²Á¤¹¤ë¤«¤ò¸«¤ë¤Ë¤Ï¤É¤¦¤· -¤Þ¤¹¤«¡© -4.10) R-tree ¥¤¥ó¥Ç¥Ã¥¯¥¹¤È¤Ï²¿¤Ç¤¹¤«¡© -4.11) °äÅÁŪÌ䤤¹ç¤ï¤»ºÇŬ²½¤È¤Ï²¿¤Ç¤¹¤«¡© -4.12) Àµµ¬É½¸½¤Ç¤Î¸¡º÷¤äÂçʸ»ú¤È¾®Ê¸»ú¤È¤ò¶èÊ̤·¤Ê¤¤Àµµ¬É½¸½¸¡º÷¤Ï¤É¤Î¤è¤¦¤Ë¼Â -¸½¤·¤Þ¤¹¤«¡©Âçʸ»ú¤È¾®Ê¸»ú¤È¤ò¶èÊ̤·¤Ê¤¤¸¡º÷¤Î¤¿¤á¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ï¤É¤Î¤è¤¦¤Ë»È -¤¤¤Þ¤¹¤«¡© -4.13) Ì䤤¹ç¤ï¤»¤ÎÃæ¤Ç¡¢¥Õ¥£¡¼¥ë¥É¤¬ NULL ¤Ç¤¢¤ë¤³¤È¤ò¸¡½Ð¤¹¤ë¤Ë¤Ï¤É¤¦¤·¤Þ¤¹¤« -¡© -4.14) ¿§¡¹¤Êʸ»ú·¿¤Î¤½¤ì¤¾¤ì¤Î°ã¤¤¤Ï²¿¤Ç¤¹¤«¡© -4.15.1) ÄÌÈÖ(serial)¡¿¼«Æ°Áýʬ¥Õ¥£¡¼¥ë¥É¤Ï¤É¤Î¤è¤¦¤Ë¤Ä¤¯¤ê¤Þ¤¹¤«¡© -4.15.2) SERIAL¥Ç¡¼¥¿·¿¤ËÁÞÆþ¤µ¤ì¤ëÃͤϡ¢¤É¤¦¤¹¤ì¤ÐÆÀ¤é¤ì¤Þ¤¹¤«¡© -4.15.3) ¾¤Î¥æ¡¼¥¶¤È¤Î¶¥¹ç¾õÂÖ¤òÈò¤±¤ë¤¿¤á¤Ë¤Ï¡¢currval() ¤È nextval() ¤Ï»È¤ï¤Ê -¤¤¤Û¤¦¤¬¤è¤¤¤Î¤Ç¤·¤ç¤¦¤«¡© -4.15.4) ¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤¬ÃæÃǤ·¤¿¤È¤­¤Ë¤â¤¦¤¤¤Á¤É¥·¡¼¥±¥ó¥¹Èֹ椬»È¤ï¤ì¤Ê¤¤¤Î -¤Ï¤Ê¤¼¤Ç¤¹¤«¡©¥·¡¼¥±¥ó¥¹¡¿SERIAL¥«¥é¥à¤Ë¶õ¤­¤¬¤¢¤ë¤Î¤Ï¤Ê¤¼¤Ç¤¹¤«¡© -4.16) OID ¤È¤Ï²¿¤Ç¤¹¤«¡© TID ¤È¤Ï²¿¤Ç¤¹¤«¡© -4.17) PostgreSQL ¤Ç»È¤ï¤ì¤ë¤¤¤¯¤Ä¤«¤ÎÍѸì¤Î°ÕÌ£¤Ï²¿¤Ç¤¹¤«¡© -4.18) ¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸ "ERROR: Memory exhausted in AllocSetAlloc()"¤¬½Ð¤ë¤Î¤Ï¤Ê -¤¼¤Ç¤¹¤«¡© -4.19) ¤É¤Î¥Ð¡¼¥¸¥ç¥ó¤Î PostgreSQL ¤òÁö¤é¤»¤Æ¤¤¤ë¤Î¤«¤òÄ´¤Ù¤ë¤Ë¤Ï¤É¤¦¤·¤Þ¤¹¤«¡© -4.20) ¥é¡¼¥¸¥ª¥Ö¥¸¥§¥¯¥È¤ÎÁàºî¤Ç¡¢invalid large obj descriptor¤È½Ð¤ë¤Î¤Ï¤Ê¤¼¤Ç -¤¹¤«¡© -4.21) ¸½ºß¤Î»þ¹ï¤¬¥Ç¥Õ¥©¥ë¥È¤È¤Ê¤ë¤è¤¦¤Ê¥«¥é¥à¤Ï¤É¤Î¤è¤¦¤Ë¤Ä¤¯¤ê¤Þ¤¹¤«¡© -4.22) ¤Ê¤¼¡¢IN¤ò»È¤¦ÉûÌ䤤¹ç¤ï¤»¤¬¤È¤Æ¤âÃÙ¤¤¤Î¤Ç¤¹¤«¡© -4.23) ³°Éô·ë¹ç(outer join)¤Ï¤É¤Î¤è¤¦¤Ë¼Â¸½¤·¤Þ¤¹¤«? -4.24) Ê£¿ô¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò»È¤¦Ì䤤¹ç¤ï¤»¤Ï¤É¤Î¤è¤¦¤Ë¤¹¤ì¤Ð¤Ç¤­¤Þ¤¹¤«¡© -4.25) ´Ø¿ô¤ÇÊ£¿ô¤Î¥í¥¦¤Þ¤¿¤Ï¥«¥é¥à¤òÊÖ¤¹¤Ë¤Ï¤É¤¦¤·¤Þ¤¹¤«¡© - - PostgreSQL¤Î³ÈÄ¥¤Ë¤Ä¤¤¤Æ¤Î¼ÁÌä - -5.1) ¼«Ê¬¤Ç½ñ¤¤¤¿¥æ¡¼¥¶ÄêµÁ´Ø¿ô¤ò psql ¤ÎÃæ¤Ç¼Â¹Ô¤¹¤ë¤È¥³¥¢¡¦¥À¥ó¥×¤·¤Æ¤·¤Þ¤¦¤Î -¤Ï¤Ê¤¼¤Ç¤¹¤«¡© -5.2) PostgreSQL ÍѤ˽ñ¤¤¤¿¤Á¤ç¤Ã¤ÈÁÇŨ¤Ê¿·¤·¤¤·¿¤ä´Ø¿ô¤òÄ󶡤·¤Æ¥×¥í¥¸¥§¥¯¥È¤Ë -¹×¸¥¤·¤¿¤¤¤Î¤Ç¤¹¤¬¡© -5.3) ¥¿¥×¥ë¤òÊÖ¤¹ C¸À¸ì¤Î´Ø¿ô¤Ï¤É¤Î¤è¤¦¤Ë½ñ¤­¤Þ¤¹¤«¡© -5.4) ¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤òÊѹ¹¤·¤Þ¤·¤¿¡£ºÆ¥³¥ó¥Ñ¥¤¥ë¤·¤Æ¤âÊѲ½¤¬¸«¤é¤ì¤Ê¤¤¤Î¤Ï¤Ê¤¼ -¤Ç¤¹¤«¡© - -¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬ - °ìÈÌŪ¤Ê¼ÁÌä - -1.1) PostgreSQL ¤È¤Ï²¿¤Ç¤¹¤«¡© - -Post-Gres-Q-L.(¥Ý¥¹¥È - ¥°¥ì¥¹ - ¥­¥å¡¼ - ¥¨¥ë) ¤Èȯ²»¤·¤Þ¤¹¡£ - -PostgreSQL ¤Ï¼¡À¤Âå DBMS ¸¦µæÍѤΥץí¥È¥¿¥¤¥×¤Ç¤¢¤Ã¤¿ POSTGRES ¥Ç¡¼¥¿¥Ù¡¼¥¹´ÉÍý -¥·¥¹¥Æ¥à¤Î²þÎÉÈǤǤ¹¡£PostgreSQL ¤Ï POSTGRES ¤Î¶¯ÎϤʥǡ¼¥¿¡¦¥â¥Ç¥ë¤ÈË­É٤ʥǡ¼ -¥¿¡¦¥¿¥¤¥×(·¿)¤òÊÝ»ý¤·¤Ê¤¬¤é¡¢POSTGRES ¤Ç»È¤ï¤ì¤¿ PostQuel Ì䤤¹ç¤ï¤»¸À¸ì¤ò¡¢³È -Ä¥¤·¤¿ SQL ¤Î¥µ¥Ö¥»¥Ã¥È¤ËÃÖ¤­´¹¤¨¤Æ¤¤¤Þ¤¹¡£PostgreSQL ¤Ï̵ÎÁ¤Ç´°Á´¤Ê¥½¡¼¥¹¤òÍø -ÍѤǤ­¤Þ¤¹¡£ - -PostgreSQL ¤Î³«È¯¤Ï¡¢PostgreSQL ³«È¯¥á¡¼¥ê¥ó¥°¥ê¥¹¥È¤Ë»²²Ã¤·¤Æ¤¤¤ë¥¤¥ó¥¿¡¼¥Í¥Ã -¥È¾å¤Î³«È¯¼Ô¥Á¡¼¥à¤Ç¤¹¤Ù¤Æ¹Ô¤Ê¤ï¤ì¤Æ¤¤¤Þ¤¹¡£¸½ºß¤ÎºÂĹ¤Ï Marc G. Fournier ( -scrappy@PostgreSQL.org )¤Ç¤¹¡£(°Ê²¼¤Ë»²²Ã¤Î»ÅÊý¤¬¤¢¤ê¤Þ¤¹¡£)¸½ºß¡¢¤³¤Î¥Á¡¼¥à¤¬ -PostgreSQL ³«È¯¤Î¤¹¤Ù¤Æ¤ÎÌÌÅݤò¤ß¤Æ¤¤¤Þ¤¹¡£ - -Postgres95-1.01 ¤ÎÃæ¿´Åª¤Ê³«È¯¼Ô¤Ï Andrew Yu ¤È Jolly Chen ¤Ç¤·¤¿¤¬¡¢¤½¤Î¾ÂçÀª -¤Î¿Í¡¹¤¬¤³¤Î¥³¡¼¥É¤Î°Ü¿¢¡¢¥Æ¥¹¥È¡¢¥Ç¥Ð¥°¡¢¤ª¤è¤Ó¡¢²þÎɤ˻²²Ã¤·¤Þ¤·¤¿¡£ -PostgreSQL ¤ÎÇÉÀ¸¸µ¥³¡¼¥É¤Ç¤¢¤ë POSTGRES ¤Ï¥«¥ê¥Õ¥©¥ë¥Ë¥¢Âç³Ø¥Ð¡¼¥¯¥ì¥¤¹»¤Ë¤ª¤¤ -¤Æ¡¢ Michael Stonebraker ¶µ¼ø¤Î»Ø´ø¤Î¤â¤È¡¢Â¿¤¯¤Î³ØÀ¸¡¢Â´¶ÈÀ¸¡¢ËÜ¿¦¤Î¥×¥í¥°¥é¥Þ -¤¿¤Á¤ÎÅØÎϤˤè¤êºî¤é¤ì¤Þ¤·¤¿¡£ - -¥Ð¡¼¥¯¥ì¥¤¤Ë¤ª¤±¤ë¤³¤Î¥½¥Õ¥È¥¦¥§¥¢¤Î¤â¤È¤Î̾Á°¤Ï Postgres ¤Ç¤·¤¿¤¬¡¢SQL ¤Îµ¡Ç½ -¤¬Äɲ䵤줿 1995 ǯ¤Ë¤½¤Î̾Á°¤Ï Postgres95 ¤ËÊѹ¹¤µ¤ì¡¢1996 ǯ¤Î½ª¤ê¤Ë¤½¤Î̾Á° -¤Ï PostgreSQL ¤ËÊѹ¹¤µ¤ì¤Þ¤·¤¿¡£ - -1.2) PostgreSQL ¤ÎÃøºî¸¢¤Ï¤É¤¦¤Ê¤Ã¤Æ¤Þ¤¹¤«¡© - -PostgreSQL ¤Ï²¼µ­¤ÎÃøºî¸¢¤Ë½¾¤¤¤Þ¤¹¡£ - [ÌõÃí¡§ - ÀµÊ¸¤Ï±Ñ¸ì¤Ç¤¹¡£»²¹Í¤È¤·¤Æ¡¢Ìõʸ¤òÊ»µ­·ÇºÜ¤·¤Þ¤¹¡£ - ] - - -PostgreSQL Data Base Management System - -Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group Portions -Copyright (c) 1994-6 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. - - POSTGRESQL ¥Ç¡¼¥¿¥Ù¡¼¥¹´ÉÍý¥·¥¹¥Æ¥à - - ÉôÊ¬ÅªÃøºî¸¢ (c) 1996-2002, PostgreSQL¹ñºÝ³«È¯¥Á¡¼¥à - ÉôÊ¬ÅªÃøºî¸¢ (c) 1994-6 ¥«¥ê¥Õ¥©¥ë¥Ë¥¢Âç³ØËܹ» - - - ËÜ¥½¥Õ¥È¥¦¥§¥¢¤ª¤è¤Ó¤½¤Îʸ½ñ°ì¼°¤Ï¾åµ­¤ÎÃøºî¸¢É½¼¨¤È¡¢¤³¤Îʸ¾Ï - ¤ª¤è¤Ó¤³¤ì¤Ë³¤¯Æó¤Ä¤ÎÃÊÍÁ´¤Æ¤ÎÊ£À½¤ËźÉÕ¤µ¤ì¤Æ¤¤¤ë¸Â¤ê¤Ë¤ª¤¤ - ¤Æ¡¢»ÈÍÑ¡¢Ê£À½¡¢½¤Àµ¤ª¤è¤ÓÇÛÉդεö²Ä¤ò¡¢¤¤¤«¤Ê¤ëÌÜŪ¤Ç¤¢¤Ã¤â¡¢Ìµ - ½þ¤Ç¤«¤ÄƱ°Õ½ñ̵¤·¤Ë¹Ô¤Ê¤¨¤ë¤³¤È¤ò¤³¤³¤Ëǧ¤á¤Þ¤¹¡£ - - ¥«¥ê¥Õ¥©¥ë¥Ë¥¢Âç³Ø¤Ï¡¢¤¤¤«¤Ê¤ëÅö»ö¼Ô¤Ë¤¿¤¤¤·¤Æ¤â¡¢Íø±×¤Î²õ¼º¤ò - ´Þ¤à¡¢Ä¾ÀÜŪ¡¢´ÖÀÜŪ¡¢ÆÃÊÌ¡¢¶öÁ³¤¢¤ë¤¤¤ÏɬÁ³Åª¤Ë¤«¤«¤ï¤é¤ºÀ¸¤¸¤¿ - »³²¤Ë¤Ä¤¤¤Æ¡¢¤¿¤È¤¨¥«¥ê¥Õ¥©¥ë¥Ë¥¢Âç³Ø¤¬¤³¤ì¤é¤Î»³²¤Ë¤Ä¤¤¤ÆÁÊÄÉ - ¤ò¼õ¤±¤Æ¤¤¤¿¤È¤·¤Æ¤â¡¢°ìÀÚ¤ÎÀÕǤ¤òÉ餤¤Þ¤»¤ó¡£ - - ¥«¥ê¥Õ¥©¥ë¥Ë¥¢Âç³Ø¤Ï¡¢¾¦ÍÑÌÜŪ¤Ë¤ª¤±¤ë°ÅÌÛ¤ÎÊݾڤȡ¢ÆÃÄêÌÜŪ¤Ç - ¤ÎŬ¹çÀ­¤Ë´Ø¤·¤Æ¤Ï¤â¤È¤è¤ê¡¢¤³¤ì¤é¤Ë¸Â¤é¤º¡¢¤¤¤«¤Ê¤ëÊݾڤâÊü´þ¤¹ - ¤ë¤³¤È¤òÌÀ¸À¤·¤Þ¤¹¡£°Ê²¼¤ËÍѰդµ¤ì¤¿¥½¥Õ¥È¥¦¥§¥¢¤Ï¡Ö¤½¤Î¤Þ¤Þ¡×¤ò - ´ðËܸ¶Íý¤È¤·¡¢¥«¥ê¥Õ¥©¥ë¥Ë¥¢Âç³Ø¤Ï¤½¤ì¤ò°Ý»ý¡¢»Ù±ç¡¢¹¹¿·¡¢²þÎɤ¢ - ¤ë¤¤¤Ï½¤Àµ¤¹¤ëµÁ̳¤òÉ餤¤Þ¤»¤ó¡£ - - [ÌõÃí¡§ - Ãøºî¸¢¤Ë´Ø¤¹¤ëÀµÊ¸¤Ï¾åµ­¤Î±Ñ¸ì¤Ë¤è¤ëɽµ­¤Ç¤¹¡£ÆüËܸìÌõ¤Ï¤¢¤¯¤Þ¤Ç - »²¹Í¤Ç¤¹¡£ - ] - - -¾åµ­¤ÏBSD¥é¥¤¥»¥ó¥¹¤Ç¸Å¤­¥ª¡¼¥×¥ó¥½¡¼¥¹¤Î¥é¥¤¥»¥ó¥¹¤Ç¤¹¡£¥½¡¼¥¹¥³¡¼¥É¤¬¤É¤Î¤è¤¦ -¤Ë»È¤ï¤ì¤è¤¦¤È¤âÀ©¸Â¤·¤Þ¤»¤ó¡£¹¥¤Þ¤·¤¤¤³¤È¤Ê¤Î¤Ç¡¢²æ¡¹¤â¤½¤ì¤òÊѤ¨¤ë¤Ä¤â¤ê¤Ï¤¢ -¤ê¤Þ¤»¤ó¡£ - -1.3) PostgreSQL ¤Îưºî´Ä¶­¤Ï¡© - -Ãø¼Ô¤é¤Ï PostgreSQL ¤Î¥³¥ó¥Ñ¥¤¥ë¤È¥Æ¥¹¥È¤ò¼¡¤Î¥×¥é¥Ã¥È¥Û¡¼¥à¾å¤Ç¹Ô¤Ê¤¤¤Þ¤·¤¿¡£ -(¤³¤ì¤é¤Î¤¦¤Á¤Î¤¤¤¯¤Ä¤«¤Ï¥³¥ó¥Ñ¥¤¥ë¤Ë gcc ¤¬É¬ÍפǤ¹)¡§ - -°ìÈÌŪ¤Ë¡¢ºÇ¶á¤ÎUnix¸ß´¹¥×¥é¥Ã¥È¥Û¡¼¥à¤Ê¤é¤ÐPostgreSQL¤ò¤Ï¤·¤é¤»¤é¤ì¤ë¤Ï¤º¤Ç¤¹ -¡£¥ê¥ê¡¼¥¹¤Î»þÅÀ¤Ç¼ÂºÝ¤Ë¥Æ¥¹¥È¤ò¹Ô¤Ê¤Ã¤¿¤³¤È¤ÎÊó¹ð¤¬¤Ê¤µ¤ì¤¿¥×¥é¥Ã¥È¥Û¡¼¥à¤Ë¤Ä -¤¤¤Æ¤Ï¥¤¥ó¥¹¥È¡¼¥ë¼ê°ú½ñ¤ËÎóµó¤·¤Æ¤¢¤ê¤Þ¤¹¡£ - -1.4) Unix°Ê³°¤Î°Ü¿¢ÈǤǻȤ¨¤ë¤â¤Î¤Ï¡© - -¥¯¥é¥¤¥¢¥ó¥È - -MS Windows ¥×¥é¥Ã¥È¥Û¡¼¥à¾å¤Ç¡¢libpq C ¥é¥¤¥Ö¥é¥ê¡¢psql¡¢¤½¤ì¤È¤½¤Î¾¤Î¥¤¥ó¥¿¡¼ -¥Õ¥§¡¼¥¹¤Ï¥³¥ó¥Ñ¥¤¥ë²Äǽ¤Ç¡¢¥Ð¥¤¥Ê¥ê¡¼¤¬Áö¤ê¤Þ¤¹¡£¤³¤Î¾ì¹ç¡¢¥¯¥é¥¤¥¢¥ó¥È¤ò MS -Windows ¾å¤ÇÁö¤é¤»¤Æ¡¢TCP/IP ·Ðͳ¤Ç¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë Unix ¥×¥é¥Ã¥È¥Û¡¼¥à¾å¤ÇÁö -¤ë¥µ¡¼¥Ð¤ÈÄÌ¿®¤·¤Þ¤¹¡£ - -Win32 libpq ¥é¥¤¥Ö¥é¥ê¤È psql ¤òºî¤ë¤¿¤á¤Ë¡¢win31.mak ¤¬ÇÛÉÛ¤Ë´Þ¤Þ¤ì¤Æ¤Þ¤¹¡£ -PostgreSQL¤Ï ODBC ¥¯¥é¥¤¥¢¥ó¥È¤È¤âÄÌ¿®¤Ç¤­¤Þ¤¹¡£ - -¥µ¡¼¥Ð - -¸½ºß¡¢Cygnus Unix/NT °Ü¿¢¥é¥¤¥Ö¥é¥ê¤Î Cygwin ¤ò»È¤Ã¤Æ¡¢PostgreSQL ¥Ç¡¼¥¿¥Ù¡¼¥¹ -¥µ¡¼¥Ð¤Ï Windows NT ¤È Win2k ¾å¤Ç²ÔƯ¤·¤Æ¤¤¤Þ¤¹¡£ÇÛÉۤ˴ޤޤì¤ëpgsql/doc/ -FAQ_MSWIN¤¢¤ë¤¤¤Ï¥¦¥§¥Ö¥µ¥¤¥È¤Ë¤¢¤ë MS Windows FAQ ¤ò¤´Í÷²¼¤µ¤¤¡£Microsoft ¤ÎÁÇ -¤Î¥×¥é¥Ã¥È¥Û¡¼¥à¤Ë°Ü¿¢¤¹¤ë·×²è¤Ï¤¢¤ê¤Þ¤»¤ó¡£ - - -[ÌõÃí¡§ - -Win32¥Í¥¤¥Æ¥£¡¼¥ÖÈÇ(Win32 Native version) - - Windows-Native ¥µ¡¼¥Ð¡¼ & ¥¯¥é¥¤¥¢¥ó¥È¥Ñ¥Ã¥±¡¼¥¸¤¬ÀÆÆ£¤µ¤ó¤Ë¤è¤ê - °Ý»ý´ÉÍý¤µ¤ì¤Æ¤¤¤Þ¤¹¡£ - http://hp.vector.co.jp/authors/VA023283/PostgreSQL.html - (Windows-Native Server&Client Package for PostgreSQL by Hiroshi Saito) - http://hp.vector.co.jp/authors/VA023283/PostgreSQLe.html - - -] - -1.5) PostgreSQL ¤Ï¤É¤³¤«¤éÆþ¼ê¤Ç¤­¤Þ¤¹¤«¡© - -PostgreSQL ¤Î¸µ¤Î anonymous ftp ¥µ¥¤¥È¤Ç¤¹¡§ - - - ¡¦ ftp://ftp.PostgreSQL.org/pub/ - -¥ß¥é¡¼¥µ¥¤¥È¤Ë¤Ä¤¤¤Æ¤Ï¡¢²æ¡¹¤Î¥á¥¤¥ó Web ¥Ú¡¼¥¸¤ò¤´Í÷²¼¤µ¤¤¡£ - [ÌõÃí: - - °Ê²¼¤ÏÆüËܤΥߥ顼¥µ¥¤¥È¤Ç¤¹: - - Japan: ftp://mirror.nucba.ac.jp/mirror/postgresql/pub/ - Japan: ftp://ring.ip-kyoto.ad.jp/pub/misc/db/postgresql/ - Japan: ftp://ring.crl.go.jp/pub/misc/db/postgresql/ - Japan: ftp://ring.saitama-u.ac.jp/pub/misc/db/postgresql/ - Japan: ftp://ring.astem.or.jp/pub/misc/db/postgresql/ - Japan: ftp://ring.exp.fujixerox.co.jp/pub/misc/db/postgresql/ - Japan: ftp://ring.jah.ne.jp/pub/misc/db/postgresql/ - Japan: ftp://ring.etl.go.jp.jp/pub/misc/db/postgresql/ - Japan: ftp://ring.asahi-net.or.jp/pub/misc/db/postgresql/ - Japan: ftp://ring.so-net.ne.jp/pub/misc/db/postgresql/ - Japan: ftp://ring.aist.go.jp/pub/misc/db/postgresql/ - ] - - -1.6) ¥µ¥Ý¡¼¥È¤Ï¤É¤³¤Ç¼õ¤±¤é¤ì¤Þ¤¹¤«¡© - -¼çÍפʥ᡼¥ê¥ó¥°¡¦¥ê¥¹¥È¤Ï: pgsql-general@PostgreSQL.org¤Ç¤¹¡£PostgreSQL ¤Ë´Ø¤¹ -¤ë¤³¤È¤Ç¤¢¤ì¤ÐµÄÏÀ¤¬¤Ç¤­¤Þ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ø¤Î»²²Ã¤Î¤Ï¡¢ÅŻҥ᡼¥ë¤ÎËÜʸ(Subject -¹Ô¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó)¤Ë¼¡¤Î£²¹Ô¤ò½ñ¤¤¤Æ¡¢ - subscribe - end - -pgsql-general-request@PostgreSQL.org ¤ØÁ÷¤Ã¤Æ²¼¤µ¤¤¡£ - -¥À¥¤¥¸¥§¥¹¥ÈÈǤΥ᡼¥ê¥ó¥°¡¦¥ê¥¹¥È¤â¤¢¤ê¤Þ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ø¤Î»²²Ã¤Ï "ËÜʸ"¤Ë¡§ - subscribe - end -¤È½ñ¤¤¤Æ pgsql-general-digest-request@PostgreSQL.org ¤ØÅŻҥ᡼¥ë¤òÁ÷¤Ã¤Æ²¼¤µ¤¤ -¡£ - -¥À¥¤¥¸¥§¥¹¥ÈÈǤϡ¢¥á¥¤¥ó¥ê¥¹¥È¤Ç¼õ¿®¤¹¤ë¥á¥Ã¥»¡¼¥¸¤¬ 30k ÄøÅÙί¤ëËè¤Ë¥À¥¤¥¸¥§¥¹ -¥ÈÈǥꥹ¥È¤Î¥á¥ó¥Ð¡¼¤ËÁ÷ÉÕ¤µ¤ì¤Þ¤¹¡£ - -¥Ð¥°¥ì¥Ý¡¼¥ÈÍѤΥ᡼¥ê¥ó¥°¥ê¥¹¥È¤â¤¢¤ê¤Þ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ø¤Î»²²Ã¤Ï "ËÜʸ"¤È¤¤¤Ã¤· -¤ç¤Ë¡§ bugs-request@PostgreSQL.org ¤ØÅŻҥ᡼¥ë¤òÁ÷¤Ã¤Æ²¼¤µ¤¤¡£ - -³«È¯¼Ô¤ÎµÄÏÀ¤Î¤¿¤á¤Î¥á¡¼¥ê¥ó¥°¥ê¥¹¥È¤âÍøÍѤǤ­¤Þ¤¹¡£¤³¤Î¥ê¥¹¥È¤Ø¤Î»²²Ã¤ÏÅŻҥá -¡¼¥ë¤ÎËÜʸ¤Ë¡§ - - subscribe - end - -¤È½ñ¤¤¤Æ¡¢pgsql-hackers-request@PostgreSQL.org¤ØÅŻҥ᡼¥ë¤òÁ÷¤Ã¤Æ²¼¤µ¤¤¡£ - -PostgreSQL ¤Ë¤Ä¤¤¤Æ¤â¤Ã¤È¾Ü¤·¤¯ÃΤꤿ¤±¤ì¤Ð¡¢¼¡¤Î postgreSQL WWW¥Û¡¼¥à¥Ú¡¼¥¸¤« -¤é¤¿¤É¤ì¤Þ¤¹¡§ - - http://www.PostgreSQL.org - -EFNet ¤Ë #PostgreSQL ¤È¤¤¤¦ IRC ¥Á¥ã¥ó¥Í¥ë¤â¤¢¤ê¤Þ¤¹¡£ UNIX ¥³¥Þ¥ó¥É¤Çirc -c '# -PostgreSQL' "$USER" irc.phoenix.net ¤ò»È¤¤¤Þ¤¹¡£ - - [ÌõÃí: - 1999ǯ7·î23Æü¡¢ÆüËÜPostgreSQL¥æ¡¼¥¶¡¼²ñ(¤Ë¤Û¤ó ¤Ý¤¹¤È¤°¤ì¤¹ ¤æ¡¼¤¶¡¼ ¤«¤¤)¡¢Î¬¾ÎJPUG¤¬ÀßΩ¤µ¤ì¤Þ¤·¤¿¡£ - JPUG ¤ÏÈó±ÄÍøÁÈ¿¥¤Ç¡¢PostgreSQL¤òÍøÍѤ¹¤ë¿Íã¤ÎÁê¸ß¶¨ÎϤξì¤Ç¤¹¡£ - Àµ²ñ°÷¤Î²ñÈñ¤Ï̵ÎÁ¤Ç¤¹¤¬¡¢¶¨»¿²ñ°÷¤Î²ñÈñ¤È²ñ°÷¤ÎÀѶËŪ¤Ê¹×¸¥¤¬²ñ¤Î±¿±Ä¤ò½õ¤±¤Æ¤¤¤Þ¤¹¡£ - ¾Ü¤·¤¯¤Ï¡¢JPUG ¤ÎWeb ¥µ¥¤¥È: - http://www.postgresql.jp/ - ¤ò¤´Í÷¤¯¤À¤µ¤¤¡£²ñ°÷ÅÐÏ¿¤â²Äǽ¤È¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£ - 1990ǯÂåÃæ¤´¤í¤è¤ê¡¢¥Ý¥¹¥È¥°¥ì¥¹¤ÎÆüËܸì¥á¡¼¥ê¥ó¥°¡¦¥ê¥¹¥È¤òÀаæ ãÉפµ¤ó¤¬¼çºÅ¤·¤Æ¤¤¤Þ¤¹¡£¾ÜºÙ¤Ï¡¢ - http://www.sra.co.jp/people/t-ishii/PostgreSQL/ML/info.html - ¤ò¤´Í÷²¼¤µ¤¤¡£¥¢¡¼¥«¥¤¥Ö¤ò¡¢¤¤¤ï¤­¤ê¤µ¤ó¤Îpgsql-jp ML¸¡º÷¥·¥¹¥Æ¥à - http://datula.mio.org/~iwakiri/pgsql_jp/ - ¤Ç¸¡º÷¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ - ] - - -¾¦ÍÑ¥µ¥Ý¡¼¥È²ñ¼Ò¤Î¥ê¥¹¥È¤Ïhttp://www.postgresql.org/users-lounge/ -commercial-support.html¤Ë¤¢¤ê¤Þ¤¹¡£ - [ÌõÃí: - ÆüËܤǤϡ¢SRA Inc. ¥ª¡¼¥×¥ó¥·¥¹¥Æ¥à»ö¶ÈÉô ¤Ë¤Æ¾¦ÍÑ¥µ¥Ý¡¼¥È¤¬¹Ô¤Ê¤ï¤ì¤Æ¤¤¤Þ¤¹¡£ - ¥ß¥é¥¯¥ë¡¦¥ê¥Ê¥Ã¥¯¥¹³ô¼°²ñ¼Ò ¤Ç "Miracle Linux for PostgreSQL" ¤ÎÈÎÇä¤È¥µ¥Ý¡¼¥È¤¬ - ³«»Ï¤µ¤ì¤Þ¤·¤¿¡£ - ] - - -1.7) ºÇ¿·ÈǤϤɤì¤Ç¤¹¤« - -PostgreSQL ¤ÎºÇ¿·ÈǤϥС¼¥¸¥ç¥ó 7.2.1 ¤Ç¤¹¡£ - -²æ¡¹¤Ï¡¢4¥«·îËè¤Ë¥á¥¸¥ã¡¼¥ê¥ê¡¼¥¹¤ò¹Ô¤Ê¤¦¤³¤È¤ò·×²è¤·¤Æ¤¤¤Þ¤¹¡£ - -1.8) ¤É¤Î¤è¤¦¤Êʸ½ñ¤¬¤¢¤ê¤Þ¤¹¤«¡© - -ÇÛÉÕ¤ÎÃæ¤Ë¡¢¤¤¤¯¤Ä¤«¤Î¥Þ¥Ë¥å¥¢¥ë¤È¥ª¥ó¥é¥¤¥ó¡¦¥Þ¥Ë¥å¥¢¥ë(¥Þ¥Ë¥å¥¢¥ë¡¦¥Ú¡¼¥¸)¤ª -¤è¤Ó¤¤¤¯¤Ä¤«¤Î¾®¤µ¤Ê¥Æ¥¹¥ÈÎãÂ꤬´Þ¤Þ¤ì¤Þ¤¹¡£/doc ¥Ç¥£¥ì¥¯¥È¥ê¤ò¤´Í÷²¼¤µ¤¤¡£¤Þ¤¿ -¡¢¥Þ¥Ë¥å¥¢¥ë¤Ï¡¢ http://www.PostgreSQL.org/users-lounge/docs/ ¤Ç¥ª¥ó¥é¥¤¥ó¤Ç¤â -±ÜÍ÷¤Ç¤­¤Þ¤¹¡£ - [ÌõÃí: - ¡Ê³ô¡ËSRA¤ÈÆüËܥݥ¹¥È¥°¥ì¥¹¥æ¡¼¥¶¡¼²ñ¤ÇËÝÌõ¤µ¤ì¡¢ - ¡ÖPostgreSQL ¥ª¥Õ¥£¥·¥ã¥ë¥Þ¥Ë¥å¥¢¥ë¡× - ¤È¤·¤Æ½ÐÈǤµ¤ì¤Æ¤¤¤Þ¤¹¡£ - ] - - -¥ª¥ó¥é¥¤¥ó¤Ç»²¾È¤Ç¤­¤ë PostgreSQL ¤ÎËܤâ2ºý¤¢¤ê¤Þ¤¹¡£http://www.PostgreSQL.org/ -docs/awbook.html - [ÌõÃí: - ÆüËܥݥ¹¥È¥°¥ì¥¹¥æ¡¼¥¶¡¼²ñ¤Î ¡ÖPostgreSQL BookËÝÌõʬ²Ê²ñ¡× - ¤Ë¤ÆËÝÌõ¤µ¤ì¤Þ¤·¤¿¡£ - ] -¤ª¤è¤Ó¡¢ http://www.commandprompt.com/ppbook/ ¤Ç¤¹¡£¹ØÆþ²Äǽ¤Ê½ñÀÒ¤ÎÌÜÏ¿¤Ï¡¢ -http://www.postgresql.org/books/ ¤Ë¤¢¤ê¤Þ¤¹¡£ PostgreSQL µ»½Ñ¾ðÊóµ­»ö¤â¡¢http:/ -/techdocs.postgresql.org/ ¤Ë¤¢¤ê¤Þ¤¹¡£ - -psql ¤â¡¢·¿¡¢±é»»»Ò¡¢´Ø¿ô¡¢½¸Ì󡢤½¤Î¾¤Î¾ðÊó¤ò¤ª¸«¤»¤¹¤ë¡¢¤¤¤¯¤Ä¤«¤ÎÁÇÀ²¤é¤·¤¤ -\d ¥³¥Þ¥ó¥É¤ò»ý¤Á¤Þ¤¹¡£ - -²æ¡¹¤Î Web ¥µ¥¤¥È¤Ë¤Ï¡¢¤â¤Ã¤ÈÂô»³¤Îʸ½ñ¤¬¤¢¤ê¤Þ¤¹¡£ - -1.9) ´ûÃΤΥХ°¤ä̤¤À̵¤¤µ¡Ç½¤Ï¤É¤¦¤ä¤Ã¤Æ¸«¤Ä¤±¤Þ¤¹¤«¡© - -PostgreSQL¤Ï³ÈÄ¥¤µ¤ì¤¿SQL-92¤Î¥µ¥Ö¥»¥Ã¥È¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£²æ¡¹¤Î¥Ú¡¼¥¸¤Î TODO -¥ê¥¹¥È¤Ë¡¢´ûÃΤΥХ°¤ä·çÍǽ¤ä¾­Íè·×²è¤Ë¤Ä¤¤¤Æ¤Îµ­½Ò¤¬¤¢¤ê¤Þ¤¹¡£ - -1.10) SQL ¤Ï¤É¤¦¤¹¤ì¤Ð³Ø¤Ù¤Þ¤¹¤«¡© - -http://www.PostgreSQL.org/docs/awbook.html ¤Ë¤¢¤ëPostgreSQLËÜ¤Ç SQL ¤ò¶µ¤¨¤Æ¤¤ -¤Þ¤¹¡£ - [ÌõÃí: - ÆüËܥݥ¹¥È¥°¥ì¥¹¥æ¡¼¥¶¡¼²ñ¤Î ¡ÖPostgreSQL BookËÝÌõʬ²Ê²ñ¡× - ¤Ë¤ÆËÝÌõ¤µ¤ì½ÐÈǤµ¤ì¤Æ¤¤¤Þ¤¹¡£ - ] - - -¤½¤Î¾¤Ë¤â PostgreSQLËܤȤ·¤Æ¡¢http://www.commandprompt.com/ppbook ¤¬¤¢¤ê¤Þ¤¹¡£ -ÁÇÀ²¤é¤·¤¤¼ê°ú½ñ¤Ï¡¢http://www.intermedia.net/support/sql/sqltut.shtm, http:// -ourworld.compuserve.com/homepages/graeme_birchall/HTM_COOK.HTM, ¤½¤·¤Æ¡¢http:// -sqlcourse.com ¤Ë¤¢¤ê¤Þ¤¹¡£ - -¤½¤Î¾¤Ç¤Ï¡¢ "Teach Yourself SQL in 21 Days, Second Edition" ¤¬ http:// -members.tripod.com/er4ebus/sql/index.htm¤Ë¤¢¤ê¤Þ¤¹¡£ - -¿¤¯¤Î¥æ¡¼¥¶¤Ë¡¢ The Practical SQL Handbook, Bowman Judith S. et al., -Addison-Wesley ¤¬¹¥É¾¤Ç¤¹¡£¤½¤Î¾¤Ë¡¢The Complete Reference SQL, Groff et al., -McGraw-Hill ¤Î¤è¤¦¤Ê¤Î¤â¤¢¤ê¤Þ¤¹¡£ - - [ÌõÃí: - ÀаæÃ£É×»á¤Ë¤è¤ëÆüËܸì¤Î»²¹Íʸ¸¥¤Î¾Ò²ð¥Ú¡¼¥¸ - http://www.SRA.co.jp/people/t-ishii/PostgreSQL/doc-jp/index.html - ¤¬¤¢¤ê¤Þ¤¹¡£ - ¶áƣľʸ»á¤Î¡Ö½é¿´¼Ô¸þ¤Î£Ä£ÂÀ߷ׯþÌ硦£Ó£Ñ£ÌÆþÌ绲¹Í½ñ¾Ò²ð¡×¤Î¥³¡¼¥Ê¡¼ - http://www.shonan.ne.jp/~nkon/ipsql/books_SQL.html - ¤¬¤¢¤ê¤Þ¤¹¡£ - ËÙÅÄÎѱѻá¤Î¡ÖPostgreSQLÆüËܸì¥Þ¥Ë¥å¥¢¥ë¡× - http://www.net-newbie.com/ - ¤Ç¤Ï¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤Î¸¡º÷¤¬¤Ç¤­¤Þ¤¹¡£ - ´Ý»³ÉÔÆóÉ×»á¤ÎUNIX ¥Ç¡¼¥¿¥Ù¡¼¥¹ÆþÌç - http://www.wakhok.ac.jp/DB/DB.html - ¤â¥ª¥ó¥é¥¤¥ó¤ÇÆÉ¤à¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ - ] - -1.11) PostgreSQL¤ÏÀ¾Îñ2000ǯÌäÂê(Y2K)¤ËÂбþ¤·¤Æ¤¤¤Þ¤¹¤«¡© - -Âбþ¤·¤Æ¤Þ¤¹¡£À¾Îñ2000ǯ¤è¤ê¸å¤ÎÆüÉդ⡢µª¸µÁ°2000ǯ¤è¤êÁ°¤ÎÆüÉդ⡢´Êñ¤Ë°·¤¨ -¤Þ¤¹¡£ - -1.12) ³«È¯¥Á¡¼¥à¤Ë¤Ï¤É¤Î¤è¤¦¤Ë»²²Ã¤·¤Þ¤¹¤«¡© - -¤Þ¤ººÇ½é(£±ÈÖÌÜ)¤Ë¡¢ºÇ¿·¤Î¥½¡¼¥¹¤ò¥À¥¦¥ó¥í¡¼¥É¤·¡¢²æ¡¹¤Î Web ¥µ¥¤¥È¤«ÇÛÉÛ¤Ë´Þ¤Þ -¤ì¤Æ¤¤¤ë PostgreSQL Developers¤Îʸ½ñ¤òÆÉ¤ß¤Þ¤¹¡££²ÈÖÌܤˡ¢pgsql-hackers ¤È -pgsql-patches ¥á¡¼¥ê¥ó¥°¡¦¥ê¥¹¥È¤ò¹ØÆÉ(subscribe)¤·¤Þ¤¹¡££³ÈÖÌܤˡ¢¹âÉʼÁ¤Î¥Ñ¥Ã -¥Á¤òpgsql-patches¤Ëȯ¿®¤·¤Þ¤¹¡£¤ª¤è¤½½½¿Í¤Á¤ç¤Ã¤È¤Î¿Í㤬¡¢PostgreSQL CVS¥¢¡¼¥« -¥¤¥Ö¤Ë¥³¥ß¥Ã¥È¤¹¤ë¸¢¸Â¤ò»ý¤Ã¤Æ¤¤¤Þ¤¹¡£¤½¤Î¤½¤ì¤¾¤ì¤Î¿Í㤬Âô»³¤Î¹âÉʼÁ¤Ê¥Ñ¥Ã¥Á -¤òȯ¿®¤¹¤ë¤Î¤Ç¡¢¸½ºß¥³¥ß¥Ã¥¿¡¼¤È¤Ê¤Ã¤Æ¤¤¤ë¿Íã¤Ï¤½¤ì¤ËÄɤ¤ÉÕ¤¯¤Î¤¬ÂçÊѤǤ¹¤¬¡¢ -²æ¡¹¤ÏÈà¤é¤¬¥³¥ß¥Ã¥È¤·¤¿¥Ñ¥Ã¥Á¤Ï¹âÉʼÁ¤Ç¤¢¤ë¤È³Î¿®¤·¤Æ¤¤¤Þ¤¹¡£ - -1.13) ¥Ð¥°¥ì¥Ý¡¼¥È¤Ï¤É¤Î¤è¤¦¤Ëȯ¿®¤·¤Þ¤¹¤«¡© - -¥Ð¥°¤òÊó¹ð¤¹¤ë»ÅÊý¤Ë¤Ä¤¤¤Æ¤Î¥¬¥¤¥É¥é¥¤¥ó¤ÈÊý¸þ¤Å¤±¤¬¤¢¤ëPostgreSQL BugTool (¥Ð -¥°¥Ä¡¼¥ë)¤Î¥Ú¡¼¥¸¤òˬ¤ì¤Æ¤ß¤Æ²¼¤µ¤¤¡£ - -¤½¤ÎÁ°¤Ë http://postgreSQL.org¤Ë¤¢¤ëºÇ¿·¤Î FAQ ¤ò¥Á¥§¥Ã¥¯¤·¤Æ²¼¤µ¤¤¡£ - -¤½¤ì¤ÈƱ»þ¤Ë ftp ¥µ¥¤¥È ftp://ftp.postgreSQL.org/pub/¤Ç¡¢¤â¤Ã¤È¿·¤·¤¤¥Ð¡¼¥¸¥ç¥ó -¤Î PostgreSQL ¤¢¤ë¤¤¤Ï¥Ñ¥Ã¥Á¤ò¤µ¤¬¤·¤Æ¤ß¤Æ²¼¤µ¤¤¡£ - -1.14) ¾¤ÎDBMS¤Î¤ÈÈæ¤Ù¤ÆPostgreSQL¤Ï¤É¤¦¤Ê¤Î¤Ç¤¹¤«¡© - -¥½¥Õ¥È¥¦¥§¥¢¤ò·×¤ëÊýË¡¤Ë¤Ï¤¤¤¯¤Ä¤«¤¢¤ê¤Þ¤¹¡£µ¡Ç½¤ÈÀ­Ç½¤È¿®ÍêÀ­¤È¥µ¥Ý¡¼¥È¤È²Á³Ê -¤Ç¤¹¡£ - -µ¡Ç½(Features) - PostgreSQL¤Ï¡¢¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¡¢ÉûÌ䤤¹ç¤ï¤»¡¢¥È¥ê¥¬¡¼¡¢¥Ó¥å¡¼¡¢³°Éô¥­¡¼À° - ¹çÀ­»²¾È¡¢¤ª¤è¤Ó¡¢ÀöÎý¤µ¤ì¤¿¥í¥Ã¥¯µ¡¹½¤Ê¤É¡¢Â絬ÌϾ¦ÍÑ DBMS¤¬»ý¤Äµ¡Ç½¤ò¤Û¤È - ¤ó¤É»ý¤Ã¤Æ¤¤¤Þ¤¹¡£¤µ¤é¤Ë PostgreSQL¤Ï¡¢¥æ¡¼¥¶ÄêµÁ·¿¡¢·Ñ¾µ¡¢¥ë¡¼¥ë¡¢¤½¤ì¤«¤é - ¡¢¥í¥Ã¥¯¶¥¹ç¤ò½Ì¾®¤¹¤ë¥Þ¥ë¥Á¥Ð¡¼¥¸¥ç¥óƱ»þÀ­À©¸æ¤Ê¤É¡¢¾¦ÍÑDBMS¤â»ý¤Á¹ç¤ï¤» - ¤Ê¤¤¤è¤¦¤Êµ¡Ç½¤ò¤¤¤¯¤Ä¤«»ý¤Á¹ç¤ï¤»¤Æ¤¤¤Þ¤¹¡£ - - -À­Ç½(Performance) - PostgreSQL¤ÏÆó¤Ä¤Î¥â¡¼¥É¤ÇÁö¤ê¤Þ¤¹¡£ÉáÄ̤Îfsync¥â¡¼¥É¤Ï¡¢OS¤¬¥¯¥é¥Ã¥·¥å¤·¤¿ - ¤ê¡¢¿ôÉøå¤ËÅŸ»¤¬Íî¤Á¤¿¤ê¤·¤¿¤È¤­¤Î¤¿¤á¤Ë¡¢¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤¬´°Î»¤¹¤ëËè¤Ë - ¥Ç¥£¥¹¥¯¤Ë½ñ¤­¹þ¤ß¡¢¤¹¤Ù¤Æ¤Î¥Ç¡¼¥¿¤ò¥Ç¥£¥¹¥¯¤ËÊݸ¤·¤Þ¤¹¡£¤³¤Î¥â¡¼¥É¤Ç¤Ï¡¢ - ¤Û¤È¤ó¤É¤Î¾¦Íѥǡ¼¥¿¥Ù¡¼¥¹¤è¤ê¤âÃÙ¤¯¤Ê¤ê¤Þ¤¹¤¬¡¢¤½¤ÎÉôʬŪ¤ÊÍýͳ¤È¤·¤Æ¡¢¾¦ - ÍѤΥǡ¼¥¿¥Ù¡¼¥¹¤ÎÃæ¤Ë¤Ï¤³¤Î¤è¤¦¤ËÊݼéŪ¤Ê¥Ç¥£¥¹¥¯½ñ¤­¹þ¤ß¤ò¥Ç¥Õ¥©¥ë¥È¤È¤· - ¤Æ¤¤¤ë¤â¤Î¤¬¾¯¤Ê¤¤¤È¤¤¤¦¤³¤È¤â¤¢¤ê¤Þ¤¹¡£ no-fsync¥â¡¼¥É¤Ç¡¢ÉáÄÌ¡¢PostgreSQL - ¤Ï¾¦Íѥǡ¼¥¿¥Ù¡¼¥¹¤è¤ê¤â®¤¯¤Ê¤ê¤Þ¤¹¤¬¡¢¤·¤«¤·¤Ê¤¬¤é¡¢OS¤Î¥¯¥é¥Ã¥·¥å¤Ç¥Ç¡¼ - ¥¿¤¬Ç˲õ¤µ¤ì¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£²æ¡¹¤Ï¡¢¤½¤ÎÃæ´Ö¥â¡¼¥É¤ò³«È¯Ãæ¤Ç¡¢¤½¤ì¤¬¤¦¤Þ - ¤¯¤æ¤¯¤È¡¢´°Á´fsync ¥â¡¼¥É¤Û¤ÉÀ­Ç½¤òµ¾À·¤Ë¤¹¤ë¤³¤È¤Ê¤¯¡¢OS¤¬¥¯¥é¥Ã¥·¥å¤¹¤ë - 30ÉÃÁ°¤Þ¤Ç¤Î¥Ç¡¼¥¿À°¹çÀ­¤òÊݤƤë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ - - MySQL¤Ê¤É¤ÎÆÃ²½·¿¥Ç¡¼¥¿¥Ù¡¼¥¹¡¦¥·¥¹¥Æ¥à¤Ë¤¯¤é¤Ù¤Æ¡¢PostgreSQL¤ÎÁÞÆþ¡¿¹¹¿·¤¬ - ÃÙ¤¤¤Î¤Ï¡¢¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤Ë¤è¤ë¥ª¡¼¥Ð¡¼¥Ø¥Ã¥É¤¬¤¢¤ë¤«¤é¤Ç¤¹¡£¤â¤Á¤í¤ó¡¢ - MySQL¤Ë¤Ï¾åµ­¤ÎFeatures¤ÎÀá¤Ë¼¨¤¹¤è¤¦¤Êµ¡Ç½¤Ï¤Þ¤Ã¤¿¤¯¤¢¤ê¤Þ¤»¤ó¡£²æ¡¹¤Ï¡¢ - PostgreSQL¤Ë½ÀÆðÀ­¤Èµ¡Ç½À­¤òÁȤ߹þ¤ß¤Ê¤¬¤é¤â¡¢À䤨¤º¡¢¥×¥í¥Õ¥¡¥¤¥é¡¼¤Ë³Ý¤± - ¤¿¤ê¥½¡¼¥¹¥³¡¼¥É¤ò²òÀϤ·¤¿¤ê¤·¤Æ¡¢À­Ç½¤Î²þÁ±¤ò³¤±¤Æ¤¤¤Þ¤¹¡£PostgreSQL ¤È - MySQL ¤È¤òÈæ³Ó¤·¤Æ¤¤¤ëÌÌÇò¤¤ Web ¥Ú¡¼¥¸¤¬ http://openacs.org/ - why-not-mysql.html ¤Ë¤¢¤ê¤Þ¤¹¡£ - - PostgreSQL¤Ï¡¢Unix¥×¥í¥»¥¹¤òµ¯Æ°¤¹¤ë¤³¤È¤Ë¤è¤ê¥æ¡¼¥¶¡¼Àܳ¤òÁàºî¤·¤Þ¤¹¡£Ê£ - ¿ô¤Î¥Ð¥Ã¥¯¥¨¥ó¥É¡¦¥×¥í¥»¥¹¤¬¾ðÊó¤ò¥í¥Ã¥¯¤·¤Ê¤¬¤é¥Ç¡¼¥¿¡¦¥Ð¥Ã¥Õ¥¡¡¼¤ò¶¦Í­¤· - ¤Þ¤¹¡£¥Þ¥ë¥ÁCPU¤Ç¤Ï¡¢´Êñ¤ËÊ£¿ô¤Î¥Ð¥Ã¥¯¥¨¥ó¥É¤ò¤½¤ì¤¾¤ì¤ÎCPU¤ÇÁö¤é¤»¤ë¤³¤È - ¤¬¤Ç¤­¤Þ¤¹¡£ - - -¿®ÍêÀ­(Reliability) - ²æ¡¹¤Ï¡¢DBMS¤Î¿®ÍêÀ­¤¬¹â¤¯¤Ê¤¯¤Æ¤Ï¤½¤Î²ÁÃͤ¬Ìµ¤¤¤³¤È¤òÍý²ò¤·¤Æ¤Þ¤¹¡£½½Ê¬¥Æ - ¥¹¥È¤·¤Æ¡¢°ÂÄꤷ¤¿¥³¡¼¥É¤ò¥Ð¥°¤òºÇ¾®¤Ë¤·¤Æ¤«¤é¥ê¥ê¡¼¥¹¤¹¤ë¤è¤¦¤Ë¶Ð¤á¤Æ¤Þ¤¹ - ¡£¤½¤ì¤¾¤ì¤Î¥ê¥ê¡¼¥¹¤Ï¾¯¤Ê¤¯¤È¤â1¥«·î°Ê¾å¤Î¥Ù¡¼¥¿¡¦¥Æ¥¹¥È¤ò¹Ô¤Ê¤¤¡¢¤³¤ì¤Þ¤Ç - ¤Î¥ê¥ê¡¼¥¹¤ÎÍúÎò¤¬¡¢À½ÉÊÈǤȤ·¤Æ°ÂÄꤷ¤¿·ø¸Ç¤Ê¥ê¥ê¡¼¥¹¤Ç¤¢¤ë¤³¤È¤òʪ¸ì¤Ã¤Æ - ¤¤¤Þ¤¹¡£¤³¤ÎʬÌî¤Ç¤Ï¡¢Â¾¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤ÈÈæ¤Ù¤Æ¤â½¿§¤¬¤Ê¤¤¤³¤È¤Ë¼«¿®¤ò»ý¤Ã - ¤Æ¤¤¤Þ¤¹¡£ -¥µ¥Ý¡¼¥È(Support) - ²æ¡¹¤Î¥á¡¼¥ê¥ó¥°¥ê¥¹¥È¤Ï¡¢Áø¶ø¤¹¤ë¤¤¤«¤Ê¤ëÌäÂê¤Ë¤Ä¤¤¤Æ¤â²ò·è¤Ø¤Î¼ê½õ¤±¤ò¤· - ¤Æ¤¯¤ì¤ë¡¢³«È¯¼Ô¤ä¥æ¡¼¥¶¤ÎÂ礭¤Ê½¸¤Þ¤ê¤òÄ󶡤·¤Æ¤¤¤Þ¤¹¡£²æ¡¹¤ÏÌäÂê¤Î²ò·è¤ò - Êݾڤ¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤»¤ó¤¬¡¢¾¦Íѥǡ¼¥¿¥Ù¡¼¥¹¤Ç¤¢¤Ã¤Æ¤â¾ï¤Ë²ò·è¤µ¤ì¤ë¤ï¤±¤Ç - ¤Ï¤¢¤ê¤Þ¤»¤ó¡£³«È¯¼Ô¤ä¡¢¥æ¡¼¥¶¡¦¥³¥ß¥å¥Ë¥Æ¥£¡¢¥Þ¥Ë¥å¥¢¥ëÎà¡¢¤½¤ì¤Ë¡¢¥½¡¼¥¹ - ¥³¡¼¥É¤Ê¤É¤ØÄ¾ÀÜ¥¢¥¯¥»¥¹¤Ç¤­¤ë¤³¤È¤è¤Ã¤Æ¡¢ PostgreSQL¤Î¥µ¥Ý¡¼¥È¤Ï¡¢Â¾¤ÎDBMS - ¥µ¥Ý¡¼¥È¤è¤ê¤âÍ¥¤ì¤¿¤â¤Î¤È¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£¸æÍ×˾¤ËÅú¤¨¤Æ¡¢»öÊÁËè¤Î¾¦ÍÑ¥µ¥Ý¡¼ - ¥È¤Ê¤É¤â¤¢¤ê¤Þ¤¹¡Ê¥µ¥Ý¡¼¥ÈFAQ¹àÌܤò¤´Í÷²¼¤µ¤¤¡Ë¡£ -²Á³Ê(Price) - PostgreSQL¤ÎÍøÍѤϡ¢¾¦ÍѤǤâÈó¾¦ÍѤǤ⡢¤¹¤Ù¤ÆÌµÎÁ¤Ç¤¹¡£¾åµ­¤Ë¼¨¤·¤Æ¤¢¤ëBSD - ¥¹¥¿¥¤¥ë¤Î»ÈÍѵöÂú¤Ë³°¤ì¤Ê¤¤¸Â¤ê¡¢PostgreSQL¤Î¥³¡¼¥É¤òÀ©¸Â̵¤·¤Ç¾¦ÉʤËÁÈ¤ß - ¹þ¤à¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ - - -1.15) PostgreSQL¤ò»ñ¶âÌ̤DZç½õ¤¹¤ë¤Ë¤Ï¤É¤¦¤¹¤ì¤Ð¤è¤¤¤Ç¤¹¤«¡© - -PostgreSQL¤Ï¡¢²æ¡¹¤¬6ǯÁ°¤Ë»Ï¤á¤¿¤È¤­°ÊÍè¡¢ºÇ¹â¥¯¥é¥¹¤Î´ðÈפò»ý¤Ã¤Æ¤¤¤Þ¤¹¡£¤³¤ì -¤Ï¤¹¤Ù¤Æ¡¢Marc Fournie¤µ¤ó¤Î¤ª¤«¤²¤Ç¡¢Èà¤Ï¤³¤Î´ðÈפò²¿Ç¯¤Ë¤â¤ï¤¿¤Ã¤ÆÁϤ¤·´ÉÍý -¤·¤Æ¤­¤Þ¤·¤¿¡£ - -¼Á¤ÎÎɤ¤´ðÈפϥª¡¼¥×¥ó¥½¡¼¥¹¡¦¥×¥í¥¸¥§¥¯¥È¤Ë¤È¤Ã¤Æ¤Ï¤È¤Æ¤âÂçÀڤʤâ¤Î¤Ç¡¢Á°¿Ê¤¹ -¤ëÀª¤¤¤ò¼º¤¦¥×¥í¥¸¥§¥¯¥È¤ÎʬÎö¤ò²óÈò¤·¤Þ¤¹¡£ - -¤â¤Á¤í¤ó¡¢¤³¤Î´ðÈפϰ¤¤¤â¤Î¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£°Ý»ý¤·Â³¤±¤ë¤¿¤á¤Ë¤ÏËè·î¤¢¤ë¤¤¤Ï°ì -»þ¤Î·ÐÈñ¤¬¤«¤«¤ê¤Þ¤¹¡£¤â¤·¡¢¤¢¤Ê¤¿¤ä¤¢¤Ê¤¿¤Î²ñ¼Ò¤Ë¡¢¤³¤¦¤·¤¿ÅØÎϤΤ¿¤á¤Î»ñ¶â¤ò -½õ¤±¤ë¤¿¤á¤Ë»Ü¤¹¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ç¤·¤¿¤é¡¢http://www.pgsql.com/pg_goodies ¤«¤é -´óÉÕ¤ò¤ª´ê¤¤¤·¤Þ¤¹¡£ - -¤Þ¤¿¡¢Web¥Ú¡¼¥¸¤Ë¤Ï PostgreSQL,Inc ¤È¤¢¤ê¤Þ¤¹¤¬¡¢¤½¤³¤Î"µÁ±ç (contributions)"¥¢ -¥¤¥Æ¥à¤Ï PostgreSQL ¥×¥í¥¸¥§¥¯¥È¤ò¥µ¥Ý¡¼¥È¤¹¤ë¤¿¤á¤À¤±¤Î¤¿¤á¤Ç¡¢·è¤·¤ÆÆÃÄê¤Î²ñ -¼Ò¤Î¤¿¤á¤Î»ñ¶â¤Î¤¿¤á¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤â¤·¡¢¼ê·Á (check)¤ÎÊý¤¬ÅԹ礬¤è¤±¤ì¤ÐÏ¢Íí -Àè¤Î½»½ê¤Ø¤ªÁ÷¤ê²¼¤µ¤¤¡£ -¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬ - - ¥æ¡¼¥¶¡¼¡¦¥¯¥é¥¤¥¢¥ó¥È¤Î¼ÁÌä - -2.1) PostgreSQL ¤Î¤¿¤á¤Î ODBC ¥É¥é¥¤¥Ð¡¼¤Ï¤¢¤ê¤Þ¤¹¤«¡© - -PsqlODBC ¤È OpenLink ODBC ¤ÎÆó¤Ä¤Î ODBC ¥É¥é¥¤¥Ð¡¼¤¬ÍøÍѲÄǽ¤Ç¤¹¡£ - -PsqlODBC ¤Ï PostgreSQL ¤ÎÇÛÉÛ¤Ë´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£¤½¤ì¤Ë¤Ä¤¤¤Æ¤Î¤µ¤é¤Ë¾ÜºÙ¤Ê¾ðÊó¤Ï -ftp://ftp.PostgreSQL.org/pub/odbc/ ¤«¤é¼èÆÀ¤Ç¤­¤Þ¤¹¡£ - - [ÌõÃí: - PsqlODBC ¤Î ÆüËܸì¥Ñ¥Ã¥Á¤òÊÒ²¬ÍµÀ¸¤µ¤ó(kataoka@interwiz.koganei.tokyo.jp)¤¬ºî¤é¤ì¤Þ¤·¤¿: - ¡ühttp://www.interwiz.koganei.tokyo.jp/software/PsqlODBC/index.html - ] - - -OpenLink ODBC ¤Ï http://www.openlinksw.com/¤«¤éÆþ¼ê¤Ç¤­¤Þ¤¹¡£É¸½àŪ¤Ê ODBC ¥¯¥é -¥¤¥¢¥ó¥È¡¦¥½¥Õ¥È¥¦¥§¥¢¤Ç»È¤¨¤Þ¤¹¤Î¤Ç¡¢»Ù±ç¤·¤Æ¤¤¤ë¤¹¤Ù¤Æ¤Î¥×¥é¥Ã¥È¥Û¡¼¥à(Win, -Mac, Unix, VMS)¤«¤é PostgreSQL ¤Î ODBC ¤¬ÍøÍѤǤ­¤Þ¤¹¡£ - -¤¿¤Ö¤óÈà¤é¤Ï¡¢¾¦ÍÑÉʼÁ¤Î¥µ¥Ý¡¼¥È¤ÎɬÍפʿ͡¹¤ËÇä¤Ã¤Æ¤¤¤ë¤È»×¤¤¤Þ¤¹¤¬¡¢¥Õ¥ê¡¼¥¦ -¥§¥¢ÈǤϤ¤¤Ä¤Ç¤âÆþ¼ê²Äǽ¤Î¤è¤¦¤Ç¤¹¡£¼ÁÌä¤Ï¡¢postgres95@openlink.co.uk ¤ØÁ÷¤Ã¤Æ -²¼¤µ¤¤¡£ -Programmer's Guide ¤Î ODBC ¤Î¾Ï¤â¤´Í÷¤¯¤À¤µ¤¤¡£ - -2.2) PostgreSQL ¤ò Web ¥Ú¡¼¥¸¤ÈÏ¢·È¤µ¤»¤ë¤Ë¤Ï¤É¤ó¤Ê¥Ä¡¼¥ë¤¬¤¢¤ê¤Þ¤¹¤«¡© - -¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò΢¤Ë»ý¤Ä Web ¥Ú¡¼¥¸¤Ë¤Ä¤¤¤Æ¤ÎÁÇÀ²¤é¤·¤¤¾Ò²ð¤¬¡¢ -http://www.webreview.com¤Ë¤¢¤ê¤Þ¤¹¡£ - -http://www.phone.net/home/mwm/hotlist/¤Ë¤â¡¢¤â¤¦°ì¤Ä¤¢¤ê¤Þ¤¹¡£ - -Web ¤Ø¤Î³ÈÄ¥¤Î¤¿¤á¤Ë¤Ï¡¢PHP ¤¬Âî±Û¤·¤¿¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤È¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£http:// -www.php.net/¤Ë¤¢¤ê¤Þ¤¹¡£ - [ÌõÃí: - PHP¤Ë´Ø¤¹¤ëÆüËܸì¤Î¾ðÊó¤Ï¡¢2000ǯ4·î19Æü¤Ëȯ­¤·¤¿ÆüËÜPHP¥æ¡¼¥¶²ñ¤Î¥µ¥¤¥È - http://www.php.gr.jp/ - ¤¢¤ë¤¤¤Ï¡¢×¢Àî Îव¤ó¤Î¥µ¥¤¥È - http://www.geocities.jp/rui_hirokawa/php/ - ¤Ë¤«¤Ê¤ê¤Þ¤È¤á¤é¤ì¤Æ¤¤¤Þ¤¹¡£ - Á°ÅÄ ½¼¹¨¤µ¤ó¤Ë¤è¤êºî¤é¤ì¤¿PHP/FI¤ÎÆüËܸì¥Ñ¥Ã¥Á¤¬ÍÍ¡¹¤Ê¿Í¤Î¼ê¤ò·Ð¤ÆPHP3.0.7¤ËŬÍѤµ¤ì¤Þ¤·¤¿¡£ - ¸½ºß¤ÏPHPJ-DEV¤Ë¤Æ¡¢ - http://php.jpnnet.com/ - º´Æ£¤µ¤ó¤òÃæ¿´¤Ë¥Þ¥ë¥Á¥Ð¥¤¥È³ÈÄ¥¤È¤·¤Æºî¤êľ¤µ¤ì¡¢ºÇ¿·ÈǤÏPHP-3.0.18¤ËÂбþ¤·¤Æ¤¤¤Þ¤¹¡£ - ÄÍÅÄ ÂîÌ餵¤ó¤Ï¡¢PHP4 ÍÑ¤ÎÆüËÜ¸ì´Ø·¸¤Î³ÈÄ¥¥â¥¸¥å¡¼¥ë - ftp://night.fminn.nagano.nagano.jp/php4/ - ¤òÍѰդ·¤Æ²¼¤µ¤Ã¤Æ¤Þ¤¹¡£ - ËܲȤÎÊý¤Ç¹ñºÝ²½¤ÎML¤âΩ¤Á¾å¤¬¤Ã¤Æ¤¤¤Þ¤¹¡£ - ] - - -½èÍý¤¬Ê£»¨¤Ê¾ì¹ç¡¢Â¿¤¯¤Î¿Í¤Ï Perl ¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤È CGI.pm ¤ò»È¤¤¤Þ¤¹¡£ - [ÌõÃí: - WDB ¤Ï¡¢Web ¤«¤é DataBase ¤Ø¤Î Perl ¤Î Interface ¤Ç¤¹¡£ - wdb-p95 ¤Ø¤Î¥ê¥ó¥¯¤ÏÀÚ¤ì¤Æ¤·¤Þ¤Ã¤Æ¤¤¤Þ¤¹¡£¤ª¤½¤é¤¯¡¢Perl DBI ·Ðͳ¤Ç DBD::Pg ¤ÎÍøÍѤ¬²Äǽ¤È»×¤ï¤ì¤Þ¤¹¡£ - ¸½ºß¡¢WDBI ¤È¤¤¤¦Ì¾Á°¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤â¤Î - http://www.egroups.com/list/wdb-users/ - ¤È¡¢WDB¤Î̾Á°¤Î¤Þ¤Þ¤Î¤â¤Î - http://www.i-con.dk/wdb/ - ¤È¤¬¤¢¤ê¤Þ¤¹¡£¤½¤Î·Ð°Þ¤Ï¤è¤¯¤ï¤«¤ê¤Þ¤»¤ó¡£ - ] - - -2.3) PostgreSQL ¤Ë¥°¥é¥Õ¥£¥«¥ë¡¦¥æ¡¼¥¶¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Ï¤¢¤ê¤Þ¤¹¤«¡©¥ì¥Ý¡¼¥È¥¸ -¥§¥Í¥ì¡¼¥¿¤äËä¤á¹þ¤ßÌ䤤¹ç¤ï¤»¸À¸ì¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Ï¤¢¤ê¤Þ¤¹¤«¡© - -pgaccess ¤È¸Æ¤Ð¤ì¤ëÁÇÀ²¤é¤·¤¤¥°¥é¥Õ¥£¥«¥ë¡¦¥æ¡¼¥¶¡¦¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤¬¤¢¤ê¡¢¤³¤Î -ÇÛÉۤȶ¦¤Ë½Ð²Ù¤µ¤ì¤Þ¤¹¡£Pgaccess ¤Ë¤Ï¥ì¥Ý¡¼¥È¡¦¥¸¥§¥Í¥ì¡¼¥¿¤â¤¢¤ê¤Þ¤¹¡£Web ¥Ú¡¼ -¥¸¤Ïhttp://www.flex.ro/pgaccess¤Ç¤¹¡£ - -ecpg ¤È¤¤¤¦ C ¸À¸ì¤Î¤¿¤á¤ÎËä¤á¹þ¤ß SQL Ì䤤¹ç¤ï¤»¸À¸ì¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤â¤¢¤ê¤Þ¤¹ -¡£ - -2.4) PostgreSQL ¤ÈÄÌ¿®¤¹¤ë¤Ë¤Ï¤É¤ó¤Ê¸À¸ì¤¬»È¤¨¤Þ¤¹¤«¡© - -°Ê²¼¤Î¤â¤Î¤¬¤¢¤ê¤Þ¤¹: - - - ¡¦ C (libpq) - ¡¦ C++ (libpq++) - ¡¦ Ëä¤á¹þ¤ßC (ecpg) - ¡¦ Java (jdbc) - ¡¦ Perl (perl5) - ¡¦ ODBC (odbc) - ¡¦ Python (PyGreSQL) - ¡¦ TCL (libpgtcl) - ¡¦ C Easy API (libpgeasy) - ¡¦ Ëä¤á¹þ¤ßHTML (PHP from http://www.php.net) - - [ÌõÃí¡§ - ruby¤Îºî¼Ô¤Ç¤¢¤ë¤Þ¤Ä¤â¤È ¤æ¤­¤Ò¤í(matz@ZetaBITS.COM)¤µ¤ó¤È¡¢¤Þ¤Ä¤â¤È ¤¨¤¤¤¸(ematsu@pfu.co.jp)¤µ¤ó¤¬ - ruby ¤Î PostgreSQL ¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤òºî¤ê¤Þ¤·¤¿¡£¸½ºß¤Î°Ý»ý´ÉÍý¤ÏÀÆÆ£ ÅФµ¤ó¤¬¤·¤Æ¤¤¤Þ¤¹¡£ - http://webclub.kcom.ne.jp/mb/noborus/ruby/ - PgBash ¤Ï ¶­ÅÄ ²íÌÀ ¤µ¤ó¤¬ºî¤Ã¤¿ bash ¤Î PostgreSQL ¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤Ç¤¹¡£ - http://www.psn.co.jp/PostgreSQL/pgbash/ - Bash¥³¥Þ¥ó¥É¥é¥¤¥ó¤Çpostgres ¤ËÌ䤤¹ç¤ï¤»¤Ç¤­¤Þ¤¹¡£ - Perl ¤Î¥â¥¸¥å¡¼¥ë¤Ï¸Å¤¯¤«¤é¤¢¤ë Pg ¤È DBI ¥É¥é¥¤¥Ð¤Î DBD::Pg ¤È¤¬¤¢¤ê¡¢ - ¤¤¤º¤ì¤â Edmund Mergl »á¤Ë¤è¤ë¤â¤Î¤Ç CPAN ¥µ¥¤¥È¤Ë¤¢¤ê¤Þ¤¹¡£ - ] - - -¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬ - ´ÉÍý¾å¤Î¼ÁÌä - -3.1) ¤É¤Î¤è¤¦¤Ë¤¹¤ì¤Ð /usr/local/pgsql °Ê³°¤Î¾ì½ê¤Ë¥¤¥ó¥¹¥È¡¼¥ë¤Ç¤­¤Þ¤¹¤«¡© - -´Êñ¤ÊÊýË¡¤Ï¡¢ configure ¤òÁö¤é¤»¤ë¤È¤­¤Ë --prefix ¥ª¥×¥·¥ç¥ó¤ò»ØÄꤹ¤ë¤³¤È¤Ç¤¹ -¡£ - -3.2) postmaster ¤òÁö¤é¤»¤ë¤È¡¢Bad System Call ¤È¤«¥³¥¢¡¦¥À¥ó¥×¤·¤¿¤È¤Î¥á¥Ã¥»¡¼ -¥¸¤¬½Ð¤Þ¤¹¡£¤Ê¤¼¤Ç¤¹¤«¡© - -¤µ¤Þ¤¶¤Þ¤ÊÌäÂ꤬¹Í¤¨¤é¤ì¤Þ¤¹¤¬¡¢¤Þ¤ººÇ½é¤Ë¤¢¤Ê¤¿¤Î¥«¡¼¥Í¥ë¤Ë System V IPC ¤Î³È -Ä¥¤¬¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤Æ¤¤¤ë¤«¤ò³Îǧ¤·¤Æ¸«¤Æ¤¯¤À¤µ¤¤¡£PostgreSQL ¤Ï¥«¡¼¥Í¥ë¤Ë¤è¤ë -¶¦Í­¥á¥â¥ê¡¼¤È¥»¥Þ¥Õ¥©¤Î¥µ¥Ý¡¼¥È¤òɬÍפȤ·¤Þ¤¹¡£ - -3.3) postmaster ¤òÁö¤é¤»¤è¤¦¤È¤¹¤ë¤È¡¢IpcMemoryCreate ¥¨¥é¡¼¤¬½Ð¤Þ¤¹¡£¤Ê¤¼¤Ç¤¹ -¤«¡© - -¥«¡¼¥Í¥ë¤¬¶¦Í­¥á¥â¥ê¡¼¤ò»ý¤ÄÀßÄê¤Ë¤Ê¤Ã¤Æ¤¤¤Ê¤«¤Ã¤¿¤«¡¢¤Ç¤Ê¤±¤ì¤Ð¡¢¥«¡¼¥Í¥ë¤ËÂÐ -¤·¤Æ»È¤¨¤ë¶¦Í­¥á¥â¥ê¡¼¤ÎÂ礭¤µ¤òÂ礭¤¯ÀßÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£¶ñÂÎŪ¤ÊÂ礭¤µ¤Ï -¡¢»È¤Ã¤Æ¤¤¤ë¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Èpostmaster ¤òÁö¤é¤»¤ë¤È¤­¤ËÀßÄꤹ¤ë¥Ð¥Ã¥Õ¥¡¤Î¿ô¤È¥Ð -¥Ã¥¯¥¨¥ó¥É¥×¥í¥»¥¹¤Ë°Í¸¤·¤Þ¤¹¡£¤Û¤È¤ó¤É¤Î¥·¥¹¥Æ¥à¤Ç¤Ï¡¢´ûÄêÃͤΥХåե¡¥µ¥¤¥º -¤Î¤Þ¤Þ¤Ç¡¢¾¯¤Ê¤¯¤È¤âÌó1MB¤¬É¬ÍפǤ¹¡£ PostgreSQL Administrator's Gide ¤Ë¶¦Í­¥á -¥â¥ê¡¼¤È¥»¥Þ¥Õ¥©¤Ë¤Ä¤¤¤Æ¤Î¾ðÊó¤Î¾ÜºÙ¤¬¤¢¤ê¤Þ¤¹¡£ - -3.4) postmaster¤òÁö¤é¤»¤è¤¦¤È¤¹¤ë¤È¡¢IpcSemaphoreCreate ¥¨¥é¡¼¤¬½Ð¤Þ¤¹¡£¤Ê¤¼¤Ç -¤¹¤«¡© - -¤â¤·¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤¬IpcSemaphoreCreate: semget failed (No space left on -device)¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥Í¥ë¤¬½½Ê¬¤Ê¥»¥Þ¥Õ¥©¤ò»È¤¨¤ë¤è¤¦¤Ë¹½À®¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡£ -Postgres¤ÏÀøºßŪ¤Ê¥Ð¥Ã¥¯¥¨¥ó¥É¥×¥í¥»¥¹Ëè¤Ë°ì¤Ä¤Î¥»¥Þ¥Õ¥©¤òɬÍפȤ·¤Þ¤¹¡£¤È¤ê¤¢ -¤¨¤º¤Î²ò·èºö¤Ïpostmaster¤òµ¯Æ°¤¹¤ë¤È¤­¤Ë¡¢¥Ð¥Ã¥¯¥¨¥ó¥É¥×¥í¥»¥¹¤Î¿ô¤ò¤è¤ê¾¯¤Ê¤¯ -À©¸Â¤ò¤¹¤ë¤³¤È¤Ç¤¹¡£´ûÄêÃͤÎ32¤è¤ê¾®¤µ¤Ê¿ô¤Î¥Ñ¥é¥á¡¼¥¿¤ò-N¤Ç»È¤¤¤Þ¤¹¡£¤è¤ê¹±µ× -Ū¤Ê²ò·èºö¤Ï¡¢¥«¡¼¥Í¥ë¤ÎSEMMNS ¤È SEMMNI ¥Ñ¥é¥á¡¼¥¿¤òÁý¤ä¤¹¤³¤È¤Ç¤¹¡£ - -ÁàºîÉÔǽ¤Î¥»¥Þ¥Õ¥©¤â²áÅ٤ʥǡ¼¥¿¥Ù¡¼¥¹¥¢¥¯¥»¥¹¤Î´Ö¤Ë¥¯¥é¥Ã¥·¥å¤òµ¯¤³¤¹²ÄǽÀ­¤¬ -¤¢¤ê¤Þ¤¹¡£ - -¤â¤·¡¢¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤¬¤Ê¤Ë¤«Â¾¤Î¤â¤Î¤Ç¤¢¤ì¤Ð¡¢¥«¡¼¥Í¥ë¤Î¹½À®¤Ç¤Þ¤Ã¤¿¤¯¥»¥Þ¥Õ -¥©¤Î¥µ¥Ý¡¼¥È¤ò¤·¤Æ¤¤¤Ê¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£ PostgreSQL Administrator's Gide ¤Ë¶¦Í­ -¥á¥â¥ê¡¼¤È¥»¥Þ¥Õ¥©¤Ë¤Ä¤¤¤Æ¤Î¾ðÊó¤Î¾ÜºÙ¤¬¤¢¤ê¤Þ¤¹¡£ - -3.5) ¾¤Î¥Û¥¹¥È¤«¤é¤ÎÀܳ¤Ï¤É¤Î¤è¤¦¤ËÀ©¸æ¤·¤Þ¤¹¤«¡© - -´ûÄêÃͤǤϡ¢PostgreSQL ¤Ï unix ¥É¥á¥¤¥ó¥½¥±¥Ã¥È¤ò»È¤¦¥í¡¼¥«¥ë¥Þ¥·¥ó¤«¤é¤ÎÀܳ¤· -¤«µö¤·¤Þ¤»¤ó¡£postmaster µ¯Æ°¤Ë -i ¥Õ¥é¥Ã¥°¤ò²Ã¤¨¡¢$PGDATA/pg_hba.conf ¥Õ¥¡¥¤¥ë -¤òŬÀڤ˾¤·¤Æ¡¢¥Û¥¹¥È¼çƳ·¿¤Îǧ¾Ú¤ò»È¤ï¤Ê¤¤¤«¤®¤ê¤Ï¾¤Î¥Þ¥·¥ó¤«¤é¤ÏÀܳ¤Ç¤­¤Ê -¤¤¤Ç¤·¤ç¤¦¡£¤³¤ì¤Ë¤è¤êTCP/IP¤ÎÀܳ¤¬²Äǽ¤Ë¤Ê¤ê¤Þ¤¹¡£ - -ÁàºîÉÔǽ¤Ê¥»¥Þ¥Õ¥©¤â²áÅ٤Υǡ¼¥¿¥Ù¡¼¥¹¥¢¥¯¥»¥¹Ãæ¤Ë¥¯¥é¥Ã¥·¥å¤ò°ú¤­µ¯¤³¤¹¤³¤È¤¬ -¤¢¤ê¤Þ¤¹¡£ - -3.6) ¤è¤êÎɤ¤À­Ç½¤òÆÀ¤ë¤¿¤á¤Ë¤Ï¡¢¥Ç¡¼¥¿¥Ù¡¼¥¹¡¦¥¨¥ó¥¸¥ó¤ò¤É¤Î¤è¤¦¤ËÄ´À°¤¹¤ì¤ÐÎÉ -¤¤¤Ç¤¹¤«¡© - -³Î¤«¤Ë¥¤¥ó¥Ç¥Ã¥¯¥¹¤ÏÌ䤤¹ç¤ï¤»¤Î®ÅÙ¤òÁý¤·¤Þ¤¹¡£EXPLAIN¥³¥Þ¥ó¥É¤Ç PostgreSQL ¤¬ -¤É¤Î¤è¤¦¤Ë¤¢¤Ê¤¿¤ÎÌ䤤¹ç¤ï¤»¤òËÝÌõ¤·¤Æ¤¤¤ë¤«¤ò¸«¤ë¤³¤È¤¬¤Ç¤­¡¢¤½¤·¤Æ¡¢¤É¤Î¥¤¥ó -¥Ç¥Ã¥¯¥¹¤¬»È¤ï¤ì¤Æ¤¤¤ë¤«¤ò¸«¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ - -¤â¤· INSERT ¤ò¿ÍѤ·¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢COPY ¥³¥Þ¥ó¥É¤ò»È¤Ã¤ÆÂ礭¤Ê¥Ð¥Ã¥Á½èÍý¤Ç¤½¤ì¤ò -¹Ô¤Ê¤¦¤³¤È¤ò¸¡Æ¤¤·¤Æ²¼¤µ¤¤¡£¤³¤ì¤Ï¡¢INSERT ¤òÊÌ¡¹¤Ë¹Ô¤Ê¤¦¤è¤ê¤â¤Ã¤È¹â®¤Ç¤¹¡£¼¡ -¤Ë¡¢BEGIN WORK/COMMIT ¤Î¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¡¦¥Ö¥í¥Ã¥¯¤ÎÃæ¤Ë̵¤¤Ê¸¤Ï¡¢¤½¤ì¤é¼«¿È¤¬ -¤½¤ì¤¾¤ì¤Î¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤ËÆþ¤Ã¤Æ¤¤¤ë¤È¸«¤Ê¤µ¤ì¤Þ¤¹¡£¤¤¤¯¤Ä¤«¤Îʸ¤ò°ì¤Ä¤Î¥È¥é -¥ó¥¶¥¯¥·¥ç¥ó¡¦¥Ö¥í¥Ã¥¯¤ÎÃæ¤Ç¹Ô¤Ê¤¦¤³¤È¤ò¹Í¤¨¤Æ²¼¤µ¤¤¡£¤³¤ì¤Ë¤è¤ê¥È¥é¥ó¥¶¥¯¥·¥ç -¥ó¤Î¥ª¡¼¥Ð¡¼¥Ø¥Ã¥É¤¬¸º¤ê¤Þ¤¹¡£¤Þ¤¿¡¢Â礭¤Ê¥Ç¡¼¥¿¤ÎÊѹ¹¤ò¹Ô¤Ê¤¦ºÝ¤Ï¥¤¥ó¥Ç¥Ã¥¯¥¹ -¤ò°ìÅÙ³°¤·¤Æ¡¢ºî¤êľ¤¹¤³¤È¤ò¹Í¤¨¤Æ¤ß¤Æ²¼¤µ¤¤¡£ - -¥Á¥å¡¼¥Ë¥ó¥°¤Î¥ª¥×¥·¥ç¥ó¤¬¤¤¤¯¤Ä¤«¤¢¤ê¤Þ¤¹¡£postmaster ¤ò -o -F ¥ª¥×¥·¥ç¥ó¤Çµ¯ -ư¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢fsync() ¤ò̵¸ú¤Ë¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤³¤ì¤Ë¤è¤Ã¤Æ¡¢³Æ¥È¥é¥ó -¥¶¥¯¥·¥ç¥óËè¤Ë fsync() ¤Ç¥Ç¥£¥¹¥¯¤ò¹¹¿·¤¹¤ë¤Î¤ò»ß¤á¤µ¤»¤Þ¤¹¡£ - -postmaster -B ¥ª¥×¥·¥ç¥ó¤ò»È¤Ã¤Æ¥Ð¥Ã¥¯¥¨¥ó¥É¡¦¥×¥í¥»¥¹¤Ë¤è¤ê»È¤ï¤ì¤ë¶¦Í­¥á¥â¥ê -¡¼¡¦¥Ð¥Ã¥Õ¥¡¤òÂ礭¤¯¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£¤â¤·¡¢¤³¤Î¥Ñ¥é¥á¡¼¥¿¤ò¹â¤¯¤·¤¹¤®¤ë¤È¡¢ -¥«¡¼¥Í¥ë¤Î¶¦Í­¥á¥â¥ê¡¼¶õ´Ö¤ÎÀ©¸ÂÃͤò±Û¤¨¤Æ¤·¤Þ¤Ã¤¦¤¿¤á¤Ë postmaster ¤¬Áö¤é¤Ê¤¯ -¤Ê¤ë¤Ç¤·¤ç¤¦¡£´ûÄêÃͤǤϡ¢¤½¤ì¤¾¤ì¤Î¥Ð¥Ã¥Õ¥¡¤ÎÂ礭¤µ¤Ï 8K ¤Ç¡¢¥Ð¥Ã¥Õ¥¡¿ô¤Ï 64 -¤Ç¤¹¡£ - -¥Ð¥Ã¥¯¥¨¥ó¥É¤ò -S ¥ª¥×¥·¥ç¥ó¤ò»È¤Ã¤Æ¡¢¤½¤ì¤¾¤ì¤Î¥Ð¥Ã¥¯¥¨¥ó¥É¡¦¥×¥í¥»¥¹¤¬°ì»þŪ -¤ÊʤÙÂØ¤¨¤Ë¤è¤Ã¤Æ»È¤¦¥á¥â¥ê¡¼¤ÎºÇÂ祵¥¤¥º¤òÁý¤ä¤¹¤³¤È¤â¤Ç¤­¤Þ¤¹¡£¤½¤Î -S ¤ÎÃÍ -¤Ï¥­¥í¥Ð¥¤¥Èñ°Ì¤Ç¡¢´ûÄêÃÍ¤Ï 512 (¤¹¤Ê¤ï¤Á¡¢512K)¤Ç¤¹¡£ - -¤Þ¤¿¡¢CLUSTER ¥³¥Þ¥ó¥É¤ò»È¤Ã¤Æ¡¢¥Æ¡¼¥Ö¥ë¤Î¥Ç¡¼¥¿¤ò¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ë¹ç¤ï¤»¤ë¤¿¤á¤Ë -¥°¥ë¡¼¥×²½¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£¾Ü¤·¤¯¤Ï¡¢¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤Ç CLUSTER ¤ò¸«¤Æ²¼ -¤µ¤¤¡£ - -3.7) ¤É¤Î¤è¤¦¤Ê¥Ç¥Ð¥°µ¡Ç½¤¬»È¤¨¤Þ¤¹¤«¡© - -PostgreSQL ¤Ï¡¢¥Ç¥Ð¥°¤Î¤¿¤á¤Ë°ÕÌ£¤Î¤¢¤ë¡¢¾õÂÖ¾ðÊó¤òÊó¹ð¤¹¤ë¤¤¤¯¤Ä¤«¤Îµ¡Ç½¤ò»ý¤Á -¤Þ¤¹¡£ - -¤Þ¤º¡¢--enable-cassert ¥ª¥×¥·¥ç¥ó¤Ç configure ¤òÁö¤é¤»¤Þ¤¹¡£¤½¤¦¤·¤Æ¥³¥ó¥Ñ¥¤¥ë -¤¹¤ë¤³¤È¤Ë¤è¤ê¡¢Âô»³¤Î assert() ¤¬¡¢¥Ð¥Ã¥¯¥¨¥ó¥É¤Î¿ÊĽ¾õ¶·¤ò´Æ»ë¤·¡¢²¿¤«Í½´ü¤» -¤Ì¤³¤È¤¬µ¯¤­¤ë¤È¥×¥í¥°¥é¥à¤òÄä»ß¤¹¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ - -postmaster ¤È postgres ¤ÎξÊý¤Ç¤¤¤¯¤Ä¤«¤Î¥Ç¥Ð¥°¡¦¥ª¥×¥·¥ç¥ó¤ÎÍøÍѤ¬¤Ç¤­¤Þ¤¹¡£¤Þ -¤º¡¢¼¡¤Î¤è¤¦¤Ë postmaster ¤òµ¯Æ°¤¹¤ë¤È¤­¤Ï¤¤¤Ä¤Ç¤â¡¢É¸½à½ÐÎϤȥ¨¥é¡¼½ÐÎϤò¥í¥° -¡¦¥Õ¥¡¥¤¥ë¤ËÁ÷¤ë¤è¤¦¤Ë¤·¤Æ¤¢¤ë¤³¤È¤ò³Î¤«¤á¤Æ²¼¤µ¤¤¡£ - cd /usr/local/pgsql - ./bin/postmaster >server.log 2>&1 & - -¤³¤ì¤Ë¤è¤ê PostgreSQL ¤ÎºÇ¾åÉô¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë server.log ¥Õ¥¡¥¤¥ë¤¬ÃÖ¤«¤ì¤Þ¤¹ -¡£¤³¤Î¥Õ¥¡¥¤¥ë¤Ï¥µ¡¼¥Ð¡¼¤¬Áø¶ø¤·¤¿ÌäÂê¤ä¥¨¥é¡¼¤Ë¤Ä¤¤¤ÆÍ­ÍѤʾðÊó¤ò´Þ¤ß¤Þ¤¹¡£ -Postmaster ¤Ï¹¹¤Ë¾ÜºÙ¤Ê¾ðÊó¤òÊó¹ð¤¹¤ë¤¿¤á¤Î -d ¥ª¥×¥·¥ç¥ó¤ò»ý¤Á¤Þ¤¹¡£¤½¤Î -d ¥ª -¥×¥·¥ç¥ó¤Ï¡¢¥Ç¥Ð¥°¡¦¥ì¥Ù¥ë¤ò»ØÄꤷ¤Þ¤¹¡£¹â¤¤¥Ç¥Ð¥°¡¦¥ì¥Ù¥ë¤Ç¤Ï¡¢Â礭¤Ê¥í¥°¥Õ¥¡ -¥¤¥ë¤òÀ¸À®¤¹¤ë¤³¤È¤ËÃí°Õ¤·¤Ê¤¯¤Æ¤Ï¤Ê¤ê¤Þ¤»¤ó¡£ - -¤â¤·¡¢postmaster¤¬Áö¤Ã¤Æ¤¤¤Ê¤±¤ì¤Ð¡¢postgres¥Ð¥Ã¥¯¥¨¥ó¥É¤ò¥³¥Þ¥ó¥É¹Ô¤«¤éÁö¤é¤» -¤ë¤³¤È¤¬¤Ç¤­¡¢Ä¾ÀÜSQLʸ¤ò¥¿¥¤¥×¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£¤³¤Î¤ä¤ê¤«¤¿¤Ï¡¢¥Ç¥Ð¥°ÌÜŪ¤Î -¤È¤­¤À¤±¤ª¾©¤á¤·¤Þ¤¹¡£¥»¥ß¥³¥í¥ó¤Ç¤Ï¤Ê¤¯¡¢²þ¹Ô¤¬Ì䤤¹ç¤ï¤»¤Î½ª¤ê¤Ë¤Ê¤ë¤³¤È¤ËÃí -°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¤â¤·¡¢¥Ç¥Ð¥°¥·¥ó¥Ü¥ë¤òÆþ¤ì¤Æ¥³¥ó¥Ñ¥¤¥ë¤·¤Æ¤¤¤ì¤Ð¡¢¥Ç¥Ð¥Ã¥¬¤ò»È -¤Ã¤Æ²¿¤¬µ¯¤­¤Æ¤¤¤ë¤«¤ò¸«¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£postmaster ¤«¤é¥Ð¥Ã¥¯¥¨¥ó¥É¤ò³«»Ï¤·¤¿ -¤ï¤±¤Ç¤Ï¤Ê¤¤¤Î¤Ç¡¢ÆÈΩ¤Ê´Ä¶­¤ÇÁö¤Ã¤Æ¤¤¤ë¤Î¤Ç¤Ï¤Ê¤¯¥í¥Ã¥¯¡¿¥Ð¥Ã¥¯¥¨¥ó¥É¤È¤ÎÂÐÏà -¤ÎÌäÂ꤬½ÅÊ£¤¹¤ë¤³¤È¤Ï¤¢¤ê¤Þ¤»¤ó¡£ - -¤â¤·¡¢postmaster¤¬Áö¤Ã¤Æ¤¤¤ì¤Ð¡¢¤¢¤ë¥¦¥£¥ó¥É¥¦¤Ç psql¤ò³«»Ï¤¹¤ë¤È¡¢psql ¤Ç»È¤ï -¤ì¤ë postgres ¥×¥í¥»¥¹¤ÎPID¤¬¸«¤Ä¤«¤ê¤Þ¤¹¡£¥Ç¥Ð¥Ã¥¬¤ò»È¤Ã¤Æ postgres¤ÎPID¤Ë¥¢¥¿ -¥Ã¥Á(attach)¤·¤Þ¤¹¡£¥Ç¥Ð¥Ã¥¬¤ÎÃæ¤«¤é¥Ö¥ì¡¼¥¯¡¦¥Ý¥¤¥ó¥È¤ò¥»¥Ã¥È¤·¡¢psql ¤«¤éÌ䤤 -¹ç¤ï¤»¤òȯ¹Ô¤·¤Þ¤¹¡£¥Ç¥Ð¥°¤Î¤¿¤á¤Ëpostgres¤ò»Ïư¤¹¤ë¾ì¹ç¤Ï¡¢PGOPTIONS="-W n" ¤ò -ÀßÄê¤Ç¤­¡¢¤½¤ì¤«¤é¡¢psql ¤ò³«»Ï¤·¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢n Éó«»Ï¤òÃ٤餻¤ë¤Ï¤º¤Ê¤Î¤Ç -¡¢¥Ç¥Ð¥Ã¥¬¤Ç¥×¥í¥»¥¹¤Ë¥¢¥¿¥Ã¥Á¤·¤Æ¡¢¥Ö¥ì¡¼¥¯¥Ý¥¤¥ó¥È¤òÀßÄꤷ¡¢³«»Ï¤«¤é½ç¤òÄɤà -¤Æ¸«¤Æ¤æ¤¯¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ - -postgreSQL ¥×¥í¥°¥é¥à¤Ë¤Ï¡¢¥Ç¥Ð¥°¤ÈÀ­Ç½Â¬Äê¤Ë¤È¤Æ¤âÌò¤ËΩ¤Ä -s¤ä -A¤ä -t Åù¤Î¥ª -¥×¥·¥ç¥ó¤¬¤¢¤ê¤Þ¤¹¡£ - -²¿¤È¤¤¤¦´Ø¿ô¤¬¤É¤Î¤¯¤é¤¤¼Â¹Ô»þ´Ö¤ò¿©¤Ã¤Æ¤¤¤ë¤«¤ò¸«¤ë¤¿¤á¤Ë¡¢¥×¥í¥Õ¥¡¥¤¥ê¥ó¥°¡Ê -¥×¥í¥Õ¥£¡¼¥ëÉÕ¤­¡Ë¤Ç¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¤³¤È¤â²Äǽ¤Ç¤¹¡£¤½¤Î¥Ð¥Ã¥¯¥¨¥ó¥É¤Î¥×¥í¥Õ¥£¡¼ -¥ë¡¦¥Õ¥¡¥¤¥ë¤Ï pgsql/data/base/dbname ¥Ç¥£¥ì¥¯¥È¥ê¤Ë³ÊǼ¤µ¤ì¤ë¤Ç¤·¤ç¤¦¡£¥¯¥é¥¤ -¥¢¥ó¥È¤Î¥×¥í¥Õ¥£¡¼¥ë¤Ï¥¯¥é¥¤¥¢¥ó¥È¤Î¸½¹Ô¥Ç¥£¥ì¥¯¥È¥ê¤ËÃÖ¤«¤ì¤ë¤Ç¤·¤ç¤¦¡£Linux -¤Ç¤Þ¤È¤â¤Ê¥×¥í¥Õ¥¡¥¤¥ê¥ó¥°¤ò¹Ô¤¦¤Ë¤Ï -DLINUX_PROFILE ¤Ç¥³¥ó¥Ñ¥¤¥ë¤¹¤ëɬÍפ¬¤¢¤ê -¤Þ¤¹¡£ - -3.8) Àܳ¤·¤è¤¦¤È¤¹¤ë¤È¤­¤Ë 'Sorry, too many clients' ¤¬½Ð¤ë¤Î¤Ï¤Ê¤¼¤Ç¤¹¤«¡© - -postmaster¤¬Æ±»þ»Ïư¤Ç¤­¤ë¥Ð¥Ã¥¯¥¨¥ó¥É¥×¥í¥»¥¹¤ËÂФ¹¤ëÀ©¸Â¿ô¤òÁý¤ä¤¹É¬Íפ¬¤¢¤ê -¤Þ¤¹¡£ - -´ûÄê¤ÎºÇÂç¥×¥í¥»¥¹¤Ï32¥×¥í¥»¥¹¤Ç¤¹¡£-N¤ËŬÀÚ¤ÊÃͤò°ú¿ô¤Ë¤·¤Æpostmaster¤òºÆµ¯Æ° -¤¹¤ë¤«¡¢postgresql.conf ¤ò½¤Àµ¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¢¤½¤ÎÃͤòÁý¤ä¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ -¡£´ûÄê¤Î¹½À®¤Ç¤Ï-N¤ÏºÇÂç1024¤Þ¤ÇÀßÄê¤Ç¤­¤Þ¤¹¡£¤â¤·¡¢¤â¤Ã¤ÈɬÍפǤ¢¤ì¤Ðinclude/ -config.h¤ÎÃæ¤ÎMAXBACKENDS¤òÁý²Ã¤µ¤»¡¢ºÆ¹½ÃÛ¤·¤Þ¤¹¡£¤â¤·¡¢Ë¾¤à¤Ê¤éconfigure¤Î ---with-maxbackendsÀÚÂØ¤ò»È¤Ã¤Æ¡¢-N¤Î´ûÄêÃͤò¹½À®»þ¤ËÀßÄê¤Ç¤­¤Þ¤¹¡£ - -¤â¤·¡¢-N ¤ò 32¤è¤ê¤âÂ礭¤¯¤¹¤ë¤Î¤Ç¤¢¤ì¤Ð¡¢-B¤â´ûÄê¤Î64¤è¤êÂ礭¤¤ÃͤËÁý²Ã¤µ¤»¤Ê -¤¯¤Æ¤Ï¤Ê¤é¤Ê¤¤¤·¡¢-B ¤Ï¾¯¤Ê¤¯¤È¤â -N ¤Î2ÇܤϤʤ¯¤Æ¤Ï¤Ê¤é¤º¡¢¤ª¤½¤é¤¯ºÇ¹âÀ­Ç½¤ò -˾¤à¤Ê¤é¤Ð¤½¤ì¤è¤êÂ礭¤¤Ãͤ¬É¬ÍפʤϤº¤Ç¤¹¡£¥Ð¥Ã¥¯¥¨¥ó¥É¥×¥í¥»¥¹¤ò¤¿¤¯¤µ¤ó¤Ë¤¹ -¤ë¤È¡¢¤¤¤í¤¤¤í¤ÊUnix¥«¡¼¥Í¥ë¹½À®¥Ñ¥é¥á¡¼¥¿¤âÁý¤ä¤¹¤³¤È¤¬É¬Íפˤʤ뤫¤â¤·¤ì¤Þ¤» -¤ó¡£¶¦Í­¥á¥â¥ê¡¼¡¦¥Ö¥í¥Ã¥¯¤ÎºÇÂçÃÍ(SHMMAX)¡¢¥»¥Þ¥Õ¥©¤ÎºÇÂç¿ô(SEMMNS¤ÈSEMMNI)¡¢ -¥×¥í¥»¥¹¤ÎºÇÂç¿ô(NPROC)¡¢¥æ¡¼¥¶Ëè¤ÎºÇÂç¥×¥í¥»¥¹¿ô(MAXUPRC)¡¢³«¤¯¥Õ¥¡¥¤¥ë¤ÎºÇÂç -¿ô(NFILE¤ÈNINODE ¤â³Îǧ»ö¹à¤Ë´Þ¤Þ¤ì¤Þ¤¹¡£ PostgreSQL¤Ëµö¤µ¤ì¤ë¥Ð¥Ã¥¯¥¨¥ó¥É¤Î¥× -¥í¥»¥¹¿ô¤¬À©¸Â¤µ¤ì¤Æ¤¤¤ë¤Î¤Ï¡¢¥·¥¹¥Æ¥à¤Î¥ê¥½¡¼¥¹¤ò»È¤¤²Ì¤·¤Æ¤·¤Þ¤¦¤³¤È¤òÈò¤±¤ë -¤¿¤á¤Ç¤¹¡£ - -6.5¤è¤êÁ°¤Î¥Ð¡¼¥¸¥ç¥ó¤ÎPostgreSQL¤Ç¤Ï¥Ð¥Ã¥¯¥¨¥ó¥É¤ÎºÇÂç¿ô¤Ï64¤Ç¤·¤¿¤¬¡¢Êѹ¹¤¹¤ë -¤Ë¤Ï¡¢include/storage/sinvaladt.h¤ÎÃæ¤ÎMaxBackendIdÄê¿ô¤ò½¤Àµ¤·¤¿¸å¤ËºÆ¹½ÃÛ¤¬É¬ -ÍפǤ·¤¿¡£ - -3.9) ¼«Ê¬¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¡¦¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¢¤ë pg_sorttemp.XXX¥Õ¥¡¥¤¥ë¤Ï²¿¤Ç¤¹¤«¡© - -Ì䤤¹ç¤ï¤»¼Â¹Ô¥â¥¸¥å¡¼¥ë¤Ë¤è¤Ã¤ÆÀ¸À®¤µ¤ì¤¿°ì»þŪ¤Ê¥Õ¥¡¥¤¥ë¤Ç¤¹¡£Î㤨¤Ð¡¢¤â¤· -ORDER BY ¶ç¤òËþ¤¿¤¹¤¿¤á¤Ë¥Ð¥Ã¥¯¥¨¥ó¥É¤Î -S ¥Ñ¥é¥á¡¼¥¿¤Çµö²Ä¤·¤¿Ãͤè¤ê¤âÂ礭¤Ê¥¹ -¥Ú¡¼¥¹¤¬¥½¡¼¥È¤ÎºÝ¤ËɬÍפÀ¤È¤¹¤ë¤È¡¢°î¤ì¤¿¥Ç¡¼¥¿¤òÊÝ»ý¤¹¤ë¤¿¤á¤Ë°ì»þŪ¤Ê¥Õ¥¡¥¤ -¥ë¤¬¤¤¤¯¤Ä¤«À¸À®¤µ¤ì¤Þ¤¹¡£ - -°ì»þŪ¤Ê¥Õ¥¡¥¤¥ë¤Ï¼«Æ°Åª¤Ë¾Ã¤·µî¤é¤ì¤ë¤Ï¤º¤Ç¤¹¤¬¡¢¤â¤·¡¢¥½¡¼¥È¤ÎÅÓÃæ¤Ç¥Ð¥Ã¥¯¥¨ -¥ó¥É¤¬¥¯¥é¥Ã¥·¥å¤·¤Æ¤·¤Þ¤¦¤È¤½¤¦¤Ï¤Ê¤ê¤Þ¤»¤ó¡£¤½¤Î¤È¤­¥Ð¥Ã¥¯¥¨¥ó¥É¤¬¤Ò¤È¤Ä¤âÁö -¤Ã¤Æ¤Ê¤±¤ì¤Ð¡¢pg_tempNNN.NN¥Õ¥¡¥¤¥ë¤ò¾Ã¤·¤Æ¤âÂç¾æÉפǤ¹¡£ - [ÌõÃí¡§ - SYSLOGD ·Ðͳ¤Ç¥í¥°¤ò½ÐÎϤ¹¤ë¤Ë¤Ï¡¢¤Þ¤º¡¢configure ¤ò --enable-syslog - ÉÕ¤­¤ÇÁö¤é¤»¤¿¸å¡¢¥³¥ó¥Ñ¥¤¥ë¤È¥¤¥ó¥¹¥È¡¼¥ë¤ò¹Ô¤Ê¤¤¤Þ¤¹¡£ - ¼¡¤Ë¡¢syslog.conf ¤Ë local0.* ¤Î ½ÐÎÏÀè¤ò»ØÄꤷ(´Ä¶­ÊÑ¿ô¤ÇÊѹ¹²Äǽ)¡¢ - syslogd ¤Ë HUP ¥·¥°¥Ê¥ë¤òÁ÷¤Ã¤Æ½é´ü²½¤·¤Æ¤ª¤­¤Þ¤¹¡£¤½¤·¤Æ¡¢ - $PGDATA/pg_options ¤Ë syslog=2 ¤ò²Ã¤¨¤Æ¡¢ postmaster ¤ò -S - ¥ª¥×¥·¥ç¥óÉÕ¤­¤Ë¤Æ¥µ¡¼¥Ð¥â¡¼¥É¤Çµ¯Æ°¤·¤Þ¤¹¡£(¥Ð¡¼¥¸¥ç¥ó 7.1 ¤«¤é¤Ï - pg_options ¤Ï postgresql.conf ¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£) - ] - - -¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬ - Áàºî¾å¤Î¼ÁÌä - -4.1) ¥Ð¥¤¥Ê¥ê¡¦¥«¡¼¥½¥ë¤ÈÄ̾參¡¼¥½¥ë¤È¤Î¸·Ì©¤Ê°ã¤¤¤Ï²¿¤Ç¤¹¤«¡© - -¾Ü½Ò¤Ï¡¢¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤Ç DECLARE ¤ò¸«¤Æ²¼¤µ¤¤¡£ - -4.2) ºÇ½é¤Î¿ô¥í¥¦¤Î¤ß¤ò SELECT ¤¹¤ë¤Ë¤Ï¤É¤¦¤·¤Þ¤¹¤«¡© - -¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤ÇFETCH¤ò¸«¤Æ¤¯¤À¤µ¤¤¡£¤¢¤ë¤¤¤Ï¡¢SELECT ... LIMIT....¤ò»È¤Ã -¤Æ¤ß¤Æ²¼¤µ¤¤¡£ - -¤¿¤È¤¨¡¢Íߤ·¤¤¤Î¤ÏºÇ½é¤Î¿ô¥í¥¦¤À¤±¤Ç¤â¡¢¤¹¤Ù¤Æ¤ÎÌ䤤¹ç¤ï¤»¤òɾ²Á¤·¤Ê¤¯¤Æ¤Ï¤Ê¤é -¤Ê¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£ORDER BY ¤ò»ý¤Ã¤¿Ì䤤¹ç¤ï¤»¤ò¹Í¤¨¤Æ¤ß¤Æ²¼¤µ¤¤¡£¤â¤·¡¢ORDER -BY¤Ë¹ç¤Ã¤¿¥¤¥ó¥Ç¥Ã¥¯¥¹¤¬¤¢¤ë¤È¤¹¤ë¤È PostgreSQL¤ÏÍ׵ᤵ¤ì¤¿ºÇ½é¤Î¿ô¥í¥¦¤À¤±¤Çɾ -²Á¤Ç¤­¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¤¬¡¢¤Ç¤Ê¤ì¤Ð¡¢PostgreSQL ¤Ï°Õ¿Þ¤·¤¿¥í¥¦¤¬À¸À®¤µ¤ì¤ë¤Þ¤Ç¤¹ -¤Ù¤Æ¤Î¥í¥¦¤òɾ²Á¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤«¤â¤·¤ì¤Þ¤»¤ó¡£ - -4.3) ¥Æ¡¼¥Ö¥ë¤ä¤½¤Î¾¤Î¾ðÊó¤Î¥ê¥¹¥È¤ò psql ¤Ç¸«¤ë¤Ë¤Ï¤É¤¦¤·¤Þ¤¹¤«¡© - -psql¤Î¥½¡¼¥¹¥³¡¼¥É¤È¤·¤Æ½ñ¤«¤ì¤¿ pgsql/src/bin/psql/describe.c ¥Õ¥¡¥¤¥ë¤òÆÉ¤à¤³ -¤È¤¬¤½¤ÎÅú¤¨¤Ç¤¹¡£¤½¤³¤Ë¤Ï¡¢psql¤Î¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¥³¥Þ¥ó¥É¤Ë¤è¤ë½ÐÎϤΤ¿¤á¤ÎSQL -¥³¥Þ¥ó¥É¤¬´Þ¤Þ¤ì¤Æ¤¤¤Þ¤¹¡£ psql ¤Ë -E ¥ª¥×¥·¥ç¥ó¤ò¤Ä¤±¤Æµ¯Æ°¤¹¤ì¤Ð¡¢Í¿¤¨¤¿¥³¥Þ -¥ó¥É¤ò¼Â¹Ô¤¹¤ë¤¿¤á¤ÎÌ䤤¹ç¤ï¤»¤¬½ÐÎϤµ¤ì¤Þ¤¹¡£ - -4.4) ¥Æ¡¼¥Ö¥ë¤«¤é¥«¥é¥à¤Îºï½ü¤Ï¤É¤Î¤è¤¦¤Ë¤·¤Þ¤¹¤«¡© - -ALTER TABLE DROP COLUMN ¤Ï¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó¤¬¡¢¤½¤ÎÂå¤ï¤ê¤Ë¤³¤¦¤·¤Þ¤¹: - BEGIN; - LOCK TABLE old_table; - SELECT ... -- ºï½ü¤·¤¿¤¤¥«¥é¥à°Ê³°¤Î¥«¥é¥à¤ò¤¹¤Ù¤ÆÁªÂò¤·¤Þ¤¹¡£ - INTO TABLE new_table - FROM old_table; - DROP TABLE old_table; - ALTER TABLE new_table RENAME TO old_table; - COMMIT; -[ÌõÃí¡§¥«¥é¥à¤ÎÄÉ²Ã¤Ï ALTER TABLE ADD COLUMN ¤Ç¹Ô¤¨¤Þ¤¹¡£] - -4.5) ¥í¥¦¡¢¥Æ¡¼¥Ö¥ë¡¢¥Ç¡¼¥¿¥Ù¡¼¥¹¤ÎºÇÂ祵¥¤¥º¤Ï¡© - -À©¸Â¤Ï°Ê²¼¤Î¤È¤ª¤ê¤Ç¤¹¡£ -¥Ç¡¼¥¿¥Ù¡¼¥¹¤ÎºÇÂ祵¥¤¥º? À©¸Â̵¤· (500GB ¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤â¸ºß¤·¤Þ¤¹) -¥Æ¡¼¥Ö¥ë¤ÎºÇÂ祵¥¤¥º? 16TB -¥í¥¦¤ÎºÇÂ祵¥¤¥º? 7.1°Ê¹ß¤ÇÀ©¸Â̵¤· -¥Õ¥£¡¼¥ë¥É¤ÎºÇÂ祵¥¤¥º? 7.1°Ê¹ß¤Ç1GB -¥Æ¡¼¥Ö¥ëÆâ¤Ç¤ÎºÇÂç¥í¥¦¿ô? À©¸Â̵¤· -¥Æ¡¼¥Ö¥ëÆâ¤Ç¤ÎºÇÂ祫¥é¥à¿ô? ¥«¥é¥à¤Î·¿¤Ë¤è¤ê250-1600 -¥Æ¡¼¥Ö¥ëÆâ¤Ç¤ÎºÇÂ祤¥ó¥Ç¥¯¥¹¿ô? À©¸Â̵¤· - -¤â¤Á¤í¤ó¡¢¤³¤ì¤é¤Ï¼ÂºÝ¤Ï̵À©¸Â¤Ç¤Ï¤Ê¤¯¡¢¥Ç¥£¥¹¥¯ÍÆÎ̤ȥá¥â¥ê¡¼¤ä¥¹¥ï¥Ã¥×¥¹¥Ú¡¼ -¥¹¤ÎÂ礭¤µ¤Ë¤è¤êÀ©¸Â¤µ¤ì¤Þ¤¹¡£À­Ç½¤Ï¤³¤ì¤é¤ÎÃͤ¬¤³¤È¤Î¤Û¤«Â礭¤Ê»þ¤ËÀú¤ê¤ò¼õ¤± -¤Þ¤¹¡£ - -ºÇÂç¥Æ¡¼¥Ö¥ë¥µ¥¤¥º¤Î16TB¤Ï¥ª¥Ú¥ì¡¼¥Æ¥£¥ó¥°¥·¥¹¥Æ¥à¤Ë¤è¤ëµðÂç¥Õ¥¡¥¤¥ë¤Î¥µ¥Ý¡¼¥È -¤ÏɬÍפȤ·¤Þ¤»¤ó¡£µðÂç¤Ê¥Æ¡¼¥Ö¥ë¤ÏÊ£¿ô¤Î1GB¤Î¥Õ¥¡¥¤¥ë¤Ëʬ¤±¤ÆÊݸ¤µ¤ì¤Þ¤¹¤Î¤Ç¡¢ -¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤ÎÀ©¸Â¤Ï½ÅÍפǤϤ¢¤ê¤Þ¤»¤ó¡£ - -¥Ç¥Õ¥©¥ë¥È¤Î¥Ö¥í¥Ã¥¯¥µ¥¤¥º¤ò32k¤Ë¤¹¤ë¤ÈºÇÂç¥Æ¡¼¥Ö¥ë¥µ¥¤¥º¤ÈºÇÂ祫¥é¥à¿ô¤È¤¬Áý²Ã -¤·¤Þ¤¹¡£ - -4.6) °ìÈÌŪ¤Ê¥Æ¥­¥¹¥È¥Õ¥¡¥¤¥ë¤«¤é¥Ç¡¼¥¿¤òÊݸ¤¹¤ë¤Ë¤Ï¡¢¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¥Ç¥£¥¹¥¯ÍÆ -Î̤ϤɤΤ¯¤é¤¤É¬ÍפǤ¹¡© - -ÉáÄ̤Υƥ­¥¹¥È¥Õ¥¡¥¤¥ë¤ò PostgreSQL ¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤ËÊݸ¤¹¤ë¤Ë¤Ï¡¢ºÇÂç¤ÇÌó5ÇܤΠ-¥Ç¥£¥¹¥¯ÍÆÎ̤òɬÍפȤ·¤Þ¤¹¡£ - -ÎãÂê¤È¤·¤Æ¡¢³Æ¹Ô¤ËÀ°¿ô¤È¥Æ¥­¥¹¥Èµ­½Ò¤ò»ý¤Ä 100,000¹Ô¤Î¥Õ¥¡¥¤¥ë¤ò¹Í¤¨¤Æ¤ß¤Þ¤·¤ç -¤¦¡£¥Æ¥­¥¹¥È¤Îʸ»úÎó¤ÎÊ¿¶ÑŤµ¤ò20¥Ð¥¤¥È¤È²¾Äꤹ¤ë¤È¡¢¥Õ¥é¥Ã¥È¥Õ¥¡¥¤¥ë¤ÎÂ礭¤µ -¤ÏÌó2.8MB ¤Ç¤¹¡£¤³¤Î¥Ç¡¼¥¿¤ò´Þ¤à PostgreSQL ¥Ç¡¼¥¿¥Ù¡¼¥¹¥Õ¥¡¥¤¥ë¤ÎÂ礭¤µ¤Ï¼¡¤Î -¤è¤¦¤ËÌó6.4MB¤È¸«ÀѤâ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡§ - 36 bytes: ³Æ¥í¥¦¤Î¥Ø¥Ã¥À(³µ»») - 24 bytes: À°¿ô(int)¥Õ¥£¡¼¥ë¥É¤È¥Æ¥­¥¹¥È(text)¥Õ¥£¡¼¥ë¥É - + 4 bytes: ¥Ú¡¼¥¸¾å¤Î¥¿¥Ã¥×¥ë¤Ø¤Î¥Ý¥¤¥ó¥¿ - ---------------------------------------- - 64 bytes per row - - PostgreSQL ¤Î¥Ç¡¼¥¿¥Ú¡¼¥¸¥µ¥¤¥º¤Ï 8192¥Ð¥¤¥È(8KB)¤Ê¤Î¤Ç: - - 8192 bytes per page - ------------------- = 128 rows per database page (ÀÚ¤ê¾å¤²) - 64 bytes per row - - 100000 data rows - -------------------- = 782 database pages - 128 rows per page - -782 database pages * 8192 bytes per page = 6,406,144 bytes (6.4 MB) - -¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ï¡¢¤³¤ì¤Û¤É¤Î¥ª¡¼¥Ð¥Ø¥Ã¥É¤ÏÍ׵ᤷ¤Þ¤»¤ó¤¬¡¢¥¤¥ó¥Ç¥Ã¥¯¥¹ÉÕ¤±¤µ¤ì¤ë -¥Ç¡¼¥¿¤ò´Þ¤à°Ê¾å¡¢¤½¤ì¤Ê¤ê¤ËÂ礭¤¯¤Ê¤ê¤Þ¤¹¡£ - -4.7) ÄêµÁ¤µ¤ì¤¿¥Æ¡¼¥Ö¥ë¡¢¥¤¥ó¥Ç¥Ã¥¯¥¹¡¢¥Ç¡¼¥¿¥Ù¡¼¥¹¡¢¤ª¤è¤Ó¡¢¥æ¡¼¥¶¤ò¤É¤Î¤è¤¦¤Ë -¤·¤Æ¸«¤Ä¤±½Ð¤·¤Þ¤¹¤«¡© - -psql ¤Ë¤Ï¤¤¤í¤¤¤í¤Ê¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¡¦¥³¥Þ¥ó¥É¤¬¤¢¤ê¡¢¤³¤¦¤·¤¿¾ðÊó¤òɽ¼¨¤·¤Þ¤¹¡£ -¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¡¦¥³¥Þ¥ó¥É¤Î¼ïÎà¤ò¸«¤ë¤Ë¤Ï \? ¤ò»È¤Ã¤Æ²¼¤µ¤¤¡£ - -¤Þ¤¿¡¢pgsql/src/tutorial/syscat.source ¥Õ¥¡¥¤¥ë¤òÁö¤é¤»¤Æ¤ß¤Æ²¼¤µ¤¤¡£¤½¤ì¤Ï¡¢Âô -»³¤Î SELECT ʸ¤Ë¤è¤êɬÍפʾðÊó¤ò¥Ç¡¼¥¿¥Ù¡¼¥¹¤Î¥·¥¹¥Æ¥à¡¦¥Æ¡¼¥Ö¥ë¤«¤é¼è¤ê½Ð¤·¤Æ -Î㼨¤·¤Æ¤¯¤ì¤Þ¤¹¡£¤Þ¤¿¡¢pg_ ¤Ç»Ï¤Þ¤ë¥·¥¹¥Æ¥à¥Æ¡¼¥Ö¥ë¤Ë¤âµ­½Ò¤µ¤ì¤Æ¤¤¤Þ¤¹¡£¤µ¤é -¤Ë¡¢psql -l ¤Ï¤¹¤Ù¤Æ¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò¥ê¥¹¥Èɽ¼¨¤·¤Þ¤¹¡£ - -4.8) Ì䤤¹ç¤ï¤»¤¬ÃÙ¤¤¤¦¤¨¡¢¥¤¥ó¥Ç¥Ã¥¯¥¹¤ò»È¤Ã¤Æ¤¤¤ëÍͻҤ¬¤¢¤ê¤Þ¤»¤ó¡£¤Ê¤¼¤Ç¤¹¤« -¡© - -¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ï¼«Æ°Åª¤Ë¤¹¤Ù¤Æ¤ÎÌ䤤¹ç¤ï¤»¤Ç»È¤ï¤ì¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¥Æ¡¼¥Ö¥ë -¤¬ºÇ¾®¥µ¥¤¥º¤è¤êÂ礭¤¯¡¢Ì䤤¹ç¤ï¤»¤Ç¤½¤Î¤ï¤º¤«¤Ê¥Ñ¡¼¥»¥ó¥Æ¡¼¥¸¤Î¥í¥¦¤òÁªÂò¤¹¤ë -»þ¤À¤±¡¢¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ï»È¤ï¤ì¤Þ¤¹¡£¤³¤ì¤Ï¥¤¥ó¥Ç¥Ã¥¯¥¹¥¹¥­¥ã¥ó¤Ë¤è¤êµ¯¤³¤µ¤ì¤ë¥é -¥ó¥À¥à¤Ê¥Ç¥£¥¹¥¯¥¢¥¯¥»¥¹¤Ï¡¢¥Æ¡¼¥Ö¥ë¤ò¥¹¥È¥ì¡¼¥È¤ËÆÉ¤à½ç¼¡Áöºº¤è¤ê¤âÃÙ¤¯¤Ê¤ë¤³ -¤È¤¬¤È¤­¤É¤­¤¢¤ë¤«¤é¤Ç¤¹¡£ - -¥¤¥ó¥Ç¥Ã¥¯¥¹¤ò»È¤¦¤«¤ò·èÄꤹ¤ë¤¿¤á¤Ë¡¢PostgreSQL ¤Ï¥Æ¡¼¥Ö¥ë¤Ë¤Ä¤¤¤Æ¤ÎÅý·×¾ðÊó¤ò -»ý¤¿¤Ê¤±¤ì¤Ð¤Ê¤ê¤Þ¤»¤ó¡£¤³¤ÎÅý·×¾ðÊó¤Ï¡¢VACUUM ANALYZE¤Þ¤¿¤Ï¡¢Ã±¤Ë ANALYZE ¤ò»È -¤Ã¤Æ¼ý½¸¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£Åý·×¾ðÊó¤ò»È¤Ã¤Æ¥ª¥Ö¥Æ¥£¥Þ¥¤¥¶¤Ï¥Æ¡¼¥Ö¥ë¤ÎÃæ¤Ë¤¢¤ë -¥í¥¦¿ô¤òÃΤꡢ¥¤¥ó¥Ç¥Ã¥¯¥¹¤ò»È¤¦¤Ù¤­¤«¤Î¤Î·èÄê¤ò¤è¤êÀµ¤·¤¯¤Ç¤­¤Þ¤¹¡£Åý·×¾ðÊó¤Ï -ºÇŬ¤Ê·ë¹ç½ç¤ä·ë¹çÊýË¡¤ò·è¤á¤ë¾å¤Ç¤âµ®½Å¤Ê¤â¤Î¤â¤¢¤ê¤Þ¤¹¡£Åý·×¾ðÊó¤Î¼ý½¸¤Ï¡¢¥Æ -¡¼¥Ö¥ë¤ÎÆâÍÆ¤¬¤«¤ï¤ë¤ÈËè¤Ë·«ÊÖ¤·¤Ê¤µ¤ì¤ë¤Ù¤­¤Ç¤¹¡£ - -¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ï¡¢Ä̾ï ORDER BY ¤ä·ë¹ç¤ò¹Ô¤Ê¤¦¤¿¤á¤Ë¤Ï»È¤ï¤ì¤Þ¤»¤ó¡£½ç¼¡¥¹¥­¥ã¥ó -¤Ë³¤¯ÌÀ¼¨Åª¥½¡¼¥È¤Ï¡¢µðÂç¤Ê¥Æ¡¼¥Ö¥ë¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¥¹¥­¥ã¥ó¤è¤ê¤âÉáÄ̤Ϲ⮤Ǥ¹ -¡£ -¤·¤«¤·¡¢ORDER BY¤ÈÁȤ߹ç¤ï¤µ¤ì¤¿LIMIT ¤Ï¡¢¥Æ¡¼¥Ö¥ë¤Î¾®¤µ¤ÊÉôʬ¤òÊÖ¤¹¤¿¤á¤Ë¤¿¤Ó -¤¿¤Ó¥¤¥ó¥Ç¥Ã¥¯¥¹¤ò»È¤¦¤Ç¤·¤ç¤¦¡£ - -LIKE ¤¢¤ë¤¤¤Ï ~ ¤Î¤è¤¦¤Ê¥ï¥¤¥ë¥É¥«¡¼¥É±é»»»Ò¤ò»È¤¦¤È¤­¡¢¸¡º÷¤Î³«»Ï¤¬Ê¸»úÎó¤Î»Ï -¤á¤ÎÉôʬ¤Ë¸ÇÄꤵ¤ì¤Æ¤¤¤ë¤È¤­¤Ë¤Î¤ß¡¢¥¤¥ó¥Ç¥Ã¥¯¥¹¤¬»È¤ï¤ì¤Þ¤¹¡£¤½¤¦¤¤¤¦¤ï¤±¤Ç¡¢ -¥¤¥ó¥Ç¥Ã¥¯¥¹¤ò»È¤¦¤¿¤á¤Ë¤Ï¡¢ LIKE ¥Ñ¥¿¡¼¥ó¤Ï%¤Ç»Ï¤á¤Ê¤¤¤è¤¦¤Ë¤·¤Æ¡¢¤Þ¤¿¡¢ ~(Àµ -µ¬É½¸½)¥Ñ¥¿¡¼¥ó¤Ï^ ¤Ç»Ï¤á¤Ê¤¯¤Æ¤Ï¤Ê¤ê¤Þ¤»¤ó¡£ [ÌõÃí¡§¶¯À©Åª¤Ë¥¤¥ó¥Ç¥Ã¥¯¥¹¤ò»È¤¦ -¤Ë¤Ï SET enable_seqscan = off ¤ò¼Â¹Ô¤·¤Þ¤¹ ] - -4.9) Ì䤤¹ç¤ï¤»¥ª¥Ö¥Æ¥£¥Þ¥¤¥¶¤¬¤É¤Î¤è¤¦¤ËÌ䤤¹ç¤ï¤»¤òɾ²Á¤¹¤ë¤Î¤«¤ò¸«¤ë¤Ë¤Ï¤É¤¦ -¤·¤Þ¤¹¤«¡© - -¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤Ç EXPLAIN ¤ò¸«¤Æ²¼¤µ¤¤¡£ - -4.10) R-tree ¥¤¥ó¥Ç¥Ã¥¯¥¹¤È¤Ï²¿¤Ç¤¹¤«¡© - -R-tree ¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ï¶õ´ÖŪ¤Ê¥Ç¡¼¥¿¤Ë¥¤¥ó¥Ç¥Ã¥¯¥¹¤òÉÕ¤±¤ë¤¿¤á¤Ë»È¤ï¤ì¤Þ¤¹¡£¥Ï¥Ã -¥·¥å¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç¤ÏÈϰϤθ¡º÷¤¬¤Ç¤­¤Þ¤»¤ó¡£¤Þ¤¿¡¢B-tree ¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç¤Ï¡¢£±¼¡ -¸µ¤Ç¤·¤«ÈϰϤθ¡º÷¤¬¤Ç¤­¤Þ¤»¤ó¡£R-tree ¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç¤¢¤ì¤Ð¿¼¡¸µ¤Î¥Ç¡¼¥¿¤ò°·¤¨ -¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢¤â¤· R-tree ¥¤¥ó¥Ç¥Ã¥¯¥¹¤ò point ·¿¤Î°À­¤ËÉÕ¤±¤ë¤³¤È¤¬¤Ç¤­¤ë¤È -¤¹¤ë¤È¥·¥¹¥Æ¥à¤Ï¡¢¡ÖĹÊý·Á¤Ë°Ï¤Þ¤ì¤¿ÅÀ¤ò¤¹¤Ù¤ÆÁªÂò¤¹¤ë¡×¤È¤¤¤¦¤è¤¦¤ÊÌ䤤¹ç¤ï¤» -¤Ë¡¢¤è¤ê¸úΨÎɤ¯Åú¤¨¤é¤ì¤Þ¤¹¡£ - -R-Tree ¤ÎÀ߷פθ¶Åµ¤È¤Ê¤ë¸¢°Ò¤¢¤ëÏÀʸ¤Ï: - -Guttman, A. "R-Trees: A Dynamic Index Structure for Spatial Searching." -Proceedings of the 1984 ACM SIGMOD Int'l Conf on Mgmt of Data, 45-57. - -¤³¤ÎÏÀʸ¤Ï¡¢Stonebraker ¶µ¼ø¤Î "Readings in Database Systems" ¤Ç¤â¼è¤ê¾å¤²¤é¤ì -¤Æ¤¤¤Þ¤¹¡£ - - [ÌõÃí¡§ - ÆàÎÉÀèüÂç¤ÎÀÐÀî²Â¼£¤µ¤ó¤è¤êR-Tree´Ø·¸¤Îʸ¸¥¤ò¾Ò²ð¤·¤ÆÄº¤­¤Þ¤·¤¿¡£ - ÆüËܸì Postgres ML ¤Î¥¢¡¼¥«¥¤¥Ö¤«¤é "Subject: [postgres95 801] spatial data structures" - http://www.sra.co.jp/people/t-ishii/PostgreSQL/mhonarc/pgsql-jp/1996Oct/msg00007.html - ¤ò¤´Í÷²¼¤µ¤¤¡£ - ] - - -Áȹþ¤ß¤Î R-Tree ¤Ç¥Ý¥ê¥´¥ó¤ä¥Ü¥Ã¥¯¥¹¤òÁàºî¤Ç¤­¤Þ¤¹¡£ÍýÏÀŪ¤Ë¤ÏR-Tree ¤Ï¤â¤Ã¤È¹â -¤¤¼¡¸µ¤òÁàºî¤¹¤ë¤è¤¦¤Ë¤â³ÈÄ¥¤Ç¤­¤Þ¤¹¡£¼Â¼ÁŪ¤Ë¤Ï¡¢R-Tree ¤Î³ÈÄ¥¤Ë¤Ï¤Á¤ç¤Ã¤È¤·¤¿ -ºî¶È¤¬É¬ÍפǤ·¤Æ¡¢¸½ºß¡¢²æ¡¹¤Ï¤½¤ì¤ò¤É¤Î¤è¤¦¤Ë¤¹¤ë¤«¤Ë¤Ä¤¤¤Æ¤Îʸ½ñ¤ò»ý¤Ã¤Æ¤¤¤Þ -¤»¤ó¡£ - - [ÌõÃí¡§ - ¥¤¥ó¥¿¡¼¥¦¥£¥º¤ÎÊÒ²¬¤µ¤ó¤¬Â¿¼¡¸µ´ö²¿¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î³ÈÄ¥ºî¶ÈÃæ¤Ç¤¹¡£¾Ü¤·¤¯¤Ï¡¢ - http://www.interwiz.koganei.tokyo.jp/software/geometric/index.html - ¤ò¤´Í÷¤¯¤À¤µ¤¤¡£ - ] - - -4.11) °äÅÁŪÌ䤤¹ç¤ï¤»ºÇŬ²½¤È¤Ï²¿¤Ç¤¹¤«¡© - -GEQO ¥â¥¸¥å¡¼¥ë¤Ï¡¢Âô»³¤Î¥Æ¡¼¥Ö¥ë¤ò·ë¹ç¤¹¤ë¤È¤­¤Ë¡¢°äÅÁŪ¥¢¥ë¥´¥ê¥º¥à(GA)¤ÇÌä¹ç -¤ï¤»¤ò¹â®²½¤·¤Þ¤¹¡£¤³¤ì¤Ë¤è¤ê¡¢¤·¤é¤ß¤Ä¤Ö¤·¤Ëõº÷¤ò¹Ô¤Ê¤ï¤Ê¤¯¤Æ¤â¡¢Â礭¤Ê·ë¹ç -(join queries)¤ò°·¤¦¤³¤È¤¬¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ - -4.12) Àµµ¬É½¸½¤Ç¤Î¸¡º÷¤äÂçʸ»ú¤È¾®Ê¸»ú¤È¤ò¶èÊ̤·¤Ê¤¤Àµµ¬É½¸½¸¡º÷¤Ï¤É¤Î¤è¤¦¤Ë¼Â -¸½¤·¤Þ¤¹¤«¡©Âçʸ»ú¤È¾®Ê¸»ú¤È¤ò¶èÊ̤·¤Ê¤¤¸¡º÷¤Î¤¿¤á¤Î¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ï¤É¤Î¤è¤¦¤Ë»È -¤¤¤Þ¤¹¤«¡© - -~±é»»»Ò¤ÏÀµµ¬É½¸½¾È¹ç¤ò¹Ô¤Ê¤¤¡¢~* ¤ÏÂçʸ»ú¤È¾®Ê¸»ú¤ò¶èÊ̤·¤Ê¤¤ -(case-insensitive)Àµµ¬É½¸½¾È¹ç¤ò¹Ô¤¤¤Þ¤¹¡£ PostgreSQL 7.1 °Ê¹ß¤Ç¤Ï¡¢Âçʸ»ú¤È¾® -ʸ»ú¤ò¶èÊ̤·¤Ê¤¤ LIKE ±é»»»Ò¤ò ILIKE ¤È¤¤¤¤¤Þ¤¹¡£ - -Âçʸ»ú¤È¾®Ê¸»ú¤ò¶èÊ̤·¤Ê¤¤ÅùÃÍÈæ³Ó¼¡¤Î¤è¤¦¤Ëɽ¸½¤Ç¤­¤ë¡§ - SELECT * - FROM tab - WHERE lower(col) = 'abc' - -ɸ½à¥¤¥ó¥Ç¥Ã¥¯¥¹¤Ç¤Ï»È¤ï¤ì¤º¡¢¤·¤«¤·¤Ê¤¬¤é¡¢¤â¤·´Ø¿ô¥¤¥ó¥Ç¥Ã¥¯¥¹¤òºî¤Ã¤¿¤Ê¤é¤½ -¤ì¤¬»È¤ï¤ì¤ë¤Ç¤·¤ç¤¦¡£ - CREATE INDEX tabindex on tab (lower(col)); - - WHERE lower(textfield) LIKE lower(pattern) - -4.13) Ì䤤¹ç¤ï¤»¤ÎÃæ¤Ç¡¢¥Õ¥£¡¼¥ë¥É¤¬ NULL ¤Ç¤¢¤ë¤³¤È¤ò¸¡½Ð¤¹¤ë¤Ë¤Ï¤É¤¦¤·¤Þ¤¹¤« -¡© - -¥«¥é¥à¤ò IS NULL ¤È IS NOT NULL ¤È¤Ç»î¤·¤Æ¤ß¤Þ¤¹¡£ - -4.14) ÍÍ¡¹¤Êʸ»ú·¿¤Î¤½¤ì¤¾¤ì¤Î°ã¤¤¤Ï²¿¤Ç¤¹¤«¡© - -Type Internal Name Notes --------------------------------------------------- -"char" char 1 character -CHAR(#) bpchar »ØÄꤵ¤ì¤¿¸ÇÄêĹ¤È¤Ê¤ë¤è¤¦¤Ë¶õÇò¤¬µÍ¤á¤é¤ì¤ë -VARCHAR(#) varchar Ťµ¤Î¾å¸Â¤Î̵¤¤¥Æ¥­¥¹¥È -TEXT text Ťµ¤ÎÀ©¸Â¤ÏºÇÂç¥í¥¦Ä¹¤Ë¤è¤ë -BYTEA bytea ²ÄÊÑĹ¤Î¥Ð¥¤¥ÈÇÛÎó(null-byte safe) - -ÆâÉô̾¤Ë¤ªÌܤˤ«¤«¤ë¤Î¤Ï¡¢¥·¥¹¥Æ¥à¡¦¥«¥¿¥í¥°¤òÄ´¤Ù¤ë¤È¤­¤ä¡¢¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤ò -¼õ¤±¼è¤ë¤È¤­¤Ç¤¹¡£ - -¾åµ­¤Î·¿¤Î¤¦¤Á¸å¤Î£´¤Ä¤Î·¿¤Ï "varlena" ·¿¤Ç¤¹(¤¹¤Ê¤ï¤Á¡¢¥Ç¥£¥¹¥¯¤ÎºÇ½é¤Î£´¥Ð¥¤ -¥È¤¬¥Ç¡¼¥¿Ä¹¤Ç¡¢¤½¤ì¤Î¸å¤Ë¼ÂºÝ¤Î¥Ç¡¼¥¿¤¬Â³¤­¤Þ¤¹)¡£¤³¤Î¤è¤¦¤Ë¼ÂºÝ¤Î¶õ´Ö¤ÏÀë¸À¤µ -¤ì¤¿Â礭¤µ¤è¤ê¤â¾¯¤·Â礭¤¯¤Ê¤ê¤Þ¤¹¡£¤·¤«¤·¡¢¤³¤ì¤é¤Î¥Ç¡¼¥¿·¿¤ÏTOAST¤Ë¤è¤ê°µ½Ì¤µ -¤ì¤¿¤êÊ£¿ô¥í¥¦¤ËÅϤäÆÊݸ¤µ¤ì¤¿¤ê¤·¤Æ¡¢¥Ç¥£¥¹¥¯¾å¤Î¶õ´Ö¤Ï»×¤Ã¤¿¤è¤ê¾®¤µ¤¯¤Ê¤ê -¤Þ¤¹¡£ - -CHAR()¤Ï¤¤¤Ä¤âŤµ¤¬Æ±¤¸Ê¸»úÎó¤òÊݸ¤¹¤ë¤Î¤ËºÇŬ¤Ç¤¹¡£VARCHAR() ¤Ï²ÄÊÑŤÎʸ»ú -Îó¤òÊݸ¤¹¤ë¤Î¤ËºÇŬ¤Ç¤¹¤¬¡¢Êݸ¤Ç¤­¤ëʸ»úÎó¤ÎŤµ¤ËÀ©¸Â¤¬¤¢¤ê¤Þ¤¹¡£TEXT ¤ÏŤµ -¤ËÀ©¸Â¤Î̵¤¤Ê¸»úÎó¤ÎÊݸ¤¿¤á¤Î¤â¤Î¤Ç¡¢ºÇÂç1¥®¥¬¥Ð¥¤¥È¤Ç¤¹¡£ BYTEA¤Ï¡¢ÉôʬŪ¤Ë -NULL ¤Î¥Ð¥¤¥È¤ò´Þ¤à¥Ð¥¤¥Ê¥ê¥Ç¡¼¥¿¤òÊݸ¤¹¤ë¤¿¤á¤Î¤â¤Î¤Ç¤¹¡£ - -4.15.1) ÄÌÈÖ(serial)¡¿¼«Æ°Áýʬ¥Õ¥£¡¼¥ë¥É¤Ï¤É¤Î¤è¤¦¤Ë¤Ä¤¯¤ê¤Þ¤¹¤«¡© - -PostgreSQL ¤Ï SERIAL ¥Ç¡¼¥¿·¿¤ò¥µ¥Ý¡¼¥È¤·¤Þ¤¹¡£¥«¥é¥à¾å¤ËÄÌÈ֤ȥ¤¥ó¥Ç¥Ã¥¯¥¹¤ò¼« -ưºîÀ®¤·¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢ - CREATE TABLE person ( - id SERIAL, - name TEXT - ); -¤Ï¼«Æ°Åª¤Ë¼¡¤Î¤è¤¦¤ËËÝÌõ¤µ¤ì¤Þ¤¹: - CREATE SEQUENCE person_id_seq; - CREATE TABLE person ( - id INT4 NOT NULL DEFAULT nextval('person_id_seq'), - name TEXT - ); - CREATE UNIQUE INDEX person_id_key ON person ( id ); -ÄÌÈ֤ˤĤ¤¤Æ¤Î¤â¤Ã¤È¾Ü¤·¤¤¾ðÊó¤Ï¡¢¥ª¥ó¥é¥¤¥ó¥Þ¥Ë¥å¥¢¥ë¤Ç create_sequence ¤ò¤´Í÷ -²¼¤µ¤¤¡£ - -¤Þ¤¿¡¢³Æ¥í¥¦¤ÎOID¥Õ¥£¡¼¥ë¥É¤ò°ì°ÕÃͤȤ·¤Æ»È¤¦¤³¤È¤â¤Ç¤­¤Þ¤¹¡£¤·¤«¤·¤Ê¤¬¤é¡¢¤â¤· -¤â¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò¥À¥ó¥×¤·¤Æ¤ê¥í¡¼¥É¤¹¤ëɬÍפ¬¤¢¤ë¾ì¹ç¤Ï¡¢OID¤ò²¹Â¸¤¹¤ë¤¿¤á¤Ë -pg_dump ¤Ç -o¥ª¥×¥·¥ç¥ó¤ò»È¤¦¤«¡¢¤Þ¤¿¤Ï¡¢COPY WITH OIDS¥ª¥×¥·¥ç¥ó¤ò»È¤¦É¬Íפ¬¤¢ -¤ê¤Þ¤¹¡£ Bruce Momjian ¤Î(http://www.PostgreSQL.org/docs/aw_pgsql_book)¤Î -Numbering Rows¤Î¾Ï¤Ë¤¢¤ê¤¢¤Þ¤¹¡£ - -4.15.2) SERIAL¥Ç¡¼¥¿·¿¤ËÁÞÆþ¤µ¤ì¤ëÃͤϡ¢¤É¤¦¤¹¤ì¤ÐÆÀ¤é¤ì¤Þ¤¹¤«¡© - -¤Ò¤È¤Ä¤ÎÊýË¡¤Ï¡¢nextval() ´Ø¿ô¤ò»È¤Ã¤Æ¤½¤ÎÃͤòÁÞÆþ¤¹¤ëÁ°(before)¤Ë SEQUENCE ¥ª -¥Ö¥¸¥§¥¯¥È¤«¤é¼¡¤Î SERIAL Ãͤò¼è¤ê½Ð¤·¡¢¤½¤ì¤«¤é¼ÂºÝ¤ËÁÞÆþ¤ò¤¹¤ë¤³¤È¤Ç¤¹¡£ -4.16.1 ¤ÎÎã¤Ç»È¤Ã¤¿¥Æ¡¼¥Ö¥ë¤ò»È¤¦¤È¤¹¤ë¤È¡¢Perl ¤Ç¤Ï¼¡¤Î¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£ - new_id = output of "SELECT nextval('person_id_seq')" - INSERT INTO person (id, name) VALUES (new_id, 'Blaise Pascal'); -¤½¤¦¤·¤Æ¡¢new_id ¤ËÊݸ¤·¤¿¿·¤·¤¤Ãͤò¾¤ÎÌ䤤¹ç¤ï¤»¤Ë(¤¿¤È¤¨¤Ð¡¢person ¥Æ¡¼¥Ö¥ë -¤ËÂФ¹¤ë³°Éô¥­¡¼(foreign key)¤Î¤è¤¦¤Ë)»È¤¦¤È¤è¤¤¤Ç¤·¤ç¤¦¡£¼«Æ°Åª¤Ëºî¤é¤ì¤¿ -SEQUENCE¥ª¥Ö¥¸¥§¥¯¥È¤Î̾Á°¤Ï¡¢
__seq ¤Î¤è¤¦¤Ë¤Ê¤ê¡¢¤³¤Î¤¦¤Á -¡¢table ¤È serialcolumn ¤Ï¤½¤ì¤¾¤ì¥Æ¡¼¥Ö¥ë¤Î̾Á°¤ÈSERIAL¥«¥é¥à¤Î̾Á°¤Ç¤¹¡£ - -¤¢¤ë¤¤¤Ï¡¢Í¿¤¨¤é¤ì¤¿SERIALÃͤò¡¢¤½¤ì¤¬´ûÄêÃͤȤ·¤ÆÁÞÆþ¤µ¤ì¤¿¸å¤Ç(after)¡¢ -currval() ´Ø¿ô¤ò»È¤Ã¤Æ¼è¤ê½Ð¤¹¤³¤È¤â¤Ç¤­¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢ - INSERT INTO person (name) VALUES ('Blaise Pascal'); - new_id = currval('person_id_seq'); -ºÇ¸å¤Ë¡¢INSERTʸ¤«¤éÊÖ¤ëOID¤ò»È¤Ã¤Æ¡¢´ûÄêÃͤò¤ß¤Ä¤±¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¤¬¡¢¤·¤«¤·¡¢ -¤³¤ì¤ÏºÇ¤â°Ü¿¢À­¤ÎÄ㤤¤ä¤êÊý¤Ç¤·¤ç¤¦¡£Perl¤ÎDBI¤Ç Edmund Mergl ¤Îºî¤Ã¤¿ DBD::Pg -¥â¥¸¥å¡¼¥ë¤ò»È¤¨¤Ð¡¢$sth->execute() ¤Î¸å¤Ë $sth->{pg_oid_status} ¤ò·Ðͳ¤·¤Æ¤½¤Î -OID Ãͤò»È¤¨¤ë¤è¤¦¤Ë¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤¹¡£ - -4.15.3) ¾¤Î¥æ¡¼¥¶¤È¤Î¶¥¹ç¾õÂÖ¤òÈò¤±¤ë¤¿¤á¤Ë¤Ï¡¢currval() ¤È nextval() ¤Ï»È¤ï¤Ê -¤¤¤Û¤¦¤¬¤è¤¤¤Î¤Ç¤·¤ç¤¦¤«¡© - -¤½¤ì¤Ï¤¢¤ê¤Þ¤»¤ó¡£Currval() ¤Ï¡¢¤¹¤Ù¤Æ¤Î¥æ¡¼¥¶¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¤¬¡¢¤¢¤Ê¤¿¤Î¥Ð¥Ã¥¯ -¥¨¥ó¥É¤ËÍ¿¤¨¤é¤ì¤¿¸½ºß¤ÎÃͤòÊÖ¤·¤Þ¤¹¡£ - -4.15.4) ¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤¬ÃæÃǤ·¤¿¤È¤­¤Ë¤â¤¦¤¤¤Á¤É¥·¡¼¥±¥ó¥¹Èֹ椬»È¤ï¤ì¤Ê¤¤¤Î -¤Ï¤Ê¤¼¤Ç¤¹¤«¡©¥·¡¼¥±¥ó¥¹¡¿SERIAL¥«¥é¥à¤Ë¶õ¤­¤¬¤¢¤ë¤Î¤Ï¤Ê¤¼¤Ç¤¹¤«¡© - -Ʊ»þÀ­¤ò²þÁ±¤¹¤ë¤¿¤á¤Ë¡¢¼Â¹ÔÃæ¤Î¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤Ë¡¢É¬Íפǥȥé¥ó¥¶¥¯¥·¥ç¥ó¤¬½ª -λ¤¹¤ë¤Þ¤Ç¥í¥Ã¥¯¤µ¤ì¤Ê¤¤¥·¡¼¥±¥ó¥¹ÃͤòÍ¿¤¨¤Æ¤¤¤Þ¤¹¡£¤³¤Î¤¿¤á¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤¬ -ÃæÃǤµ¤ì¤ë¤ÈÈÖ¹æ³ä¤êÅö¤Æ¤Ë¥®¥ã¥Ã¥×¤òÀ¸¤¸¤Þ¤¹¡£ - -4.16) OID ¤È¤Ï²¿¤Ç¤¹¤«¡© TID ¤È¤Ï²¿¤Ç¤¹¤«¡© - -OID ¤È¤Ï°ì°Õ¤Î¥í¥¦ID ¤ËÂФ¹¤ë PostgreSQL ¤ÎÅú¤¨¤Ç¤¹¡£PostgreSQL ¤ÎÃæ¤Ç¤Ä¤¯¤é¤ì -¤ë¤¹¤Ù¤Æ¤Î¥í¥¦¤Ï°ì°Õ¤Î OID ¤òÆÀ¤Þ¤¹¡£initdb ¤ÇȯÀ¸¤µ¤ì¤ë OID ¤Ï¤¹¤Ù¤Æ 16384 -(backend/access/transam.h ¤«¤é)¤è¤ê¾®¤µ¤ÊÃͤǤ¹¡£initdb ¸å¤Î¤¹¤Ù¤Æ¤Î OID (¥æ¡¼ -¥¶ºîÀ®)¤Ï¤½¤ì°Ê¾å¤ÎÃͤˤʤê¤Þ¤¹¡£´ûÄê¤Ç¤Ï¡¢¤³¤ì¤é¤¹¤Ù¤Æ¤Î OID¤Ï°ì¤Ä¤Î¥Ç¡¼¥Ö¥ë¤ä -¥Ç¡¼¥¿¥Ù¡¼¥¹Æâ¤Ëα¤Þ¤é¤º¡¢PostgreSQL ¥¤¥ó¥¹¥È¥ì¡¼¥·¥ç¥óÁ´ÂΤÎÃæ¤Ç°ì°Õ¤Ç¤¹¡£ - -PostgreSQL ¤Ï¥Æ¡¼¥Ö¥ë´Ö¤Î¥í¥¦¤ò·ë¤Ó¤Ä¤±¤ë¤¿¤á¤Ë¡¢¤½¤Î¥·¥¹¥Æ¥à¥Æ¡¼¥Ö¥ëÆâ¤Ë OID -¤ò»È¤¤¤Þ¤¹¡£¤³¤Î OID ¤ÏÆÃÄê¤Î¥æ¡¼¥¶¤Î¥í¥¦¤ò¼±Ê̤¹¤ë¤¿¤á¤ä·ë¹ç¤ÎÃæ¤Ç»È¤ï¤ì¤ë¤³¤È -¤¬¤Ç¤­¤Þ¤¹¡£OID ¤ÎÃͤòÊݸ¤¹¤ë¤¿¤á¤Ë¤Ï OID ·¿¤ò¥«¥é¥à¤Ë»È¤¦¤³¤È¤ò¾©¤á¤Þ¤¹¡£¤è¤ê -®¤¯¥¢¥¯¥»¥¹¤¹¤ë¤¿¤á¤Ë OID ¥Õ¥£¡¼¥ë¥É¤Ë¥¤¥ó¥Ç¥Ã¥¯¥¹¤òºî¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ OID -¤Ï¡¢Á´¤Æ¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ç»È¤ï¤ì¤ëÃæ±ûÎΰ褫¤é¡¢Á´¤Æ¤Î¿·¤·¤¤¥í¥¦¤Ë³ä¤êÅö¤Æ¤é¤ì¤Þ -¤¹¡£OID ¤ò¾¤Î²¿¤«¤ËÊѤ¨¤¿¤¤¡¢¤¢¤ë¤¤¤Ï¸µ¤Î OID ¤â¥Æ¡¼¥Ö¥ë¤È°ì½ï¤Ë¥³¥Ô¡¼¤·¤¿¤¤¤Î -¤Ê¤é¡¢¤Ç¤­¤Ê¤¯¤Ï¤¢¤ê¤Þ¤»¤ó¡£ - CREATE TABLE new (old_oid oid, mycol int); - SELECT old_oid, mycol INTO new FROM old; - COPY new TO '/tmp/pgtable'; - DELETE FROM new; - COPY new WITH OIDS FROM '/tmp/pgtable'; - - -OID ¤Ï¡¢4¥Ð¥¤¥È¤ÎÀ°¿ô¤È¤·¤ÆÊݸ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ç¡¢40²¯¤ò±Û¤¨¤ë¤È°î¤ì¤Æ¤·¤Þ¤¦¤Ç¤·¤ç -¤¦¡£Ã¯¤â¤³¤ì¤¬µ¯¤­¤¿¤ÈÊó¹ð¤·¤Æ¤¯¤ë¿Í¤Ï¤¤¤Þ¤»¤ó¤Ç¤·¤¿¤¬¡¢¤½¤¦¤Ê¤ëÁ°¤Ë¤³¤ÎÀ©¸Â¤ò -¼è¤ê½ü¤¯¤³¤È¤ò·×²è¤·¤Æ¤¤¤Þ¤¹¡£ - -TID ¤ÏÆÃÄê¤ÎʪÍý¥í¥¦¤ò¤½¤Î¥Ö¥í¥Ã¥¯¤È¥ª¥Õ¥»¥Ã¥ÈÃͤǼ±Ê̤¹¤ë¤¿¤á¤Ë»È¤ï¤ì¤Þ¤¹¡£TID -¤Ï¥í¥¦¤¬½¤Àµ¤µ¤ì¤¿¤êºÆ¥í¡¼¥É¤µ¤ì¤ë¤ÈÊѤï¤ê¤Þ¤¹¡£¤½¤ì¤é¤Î TID ¤Ï¡¢ÊªÍý¥í¥¦¤ò»Ø¤¹ -¤¿¤á¤Ë¥¤¥ó¥Ç¥Ã¥¯¥¹µ­ºÜ¤Ç»È¤ï¤ì¤Þ¤¹¡£ - -4.17) PostgreSQL ¤Ç»È¤ï¤ì¤ë¤¤¤¯¤Ä¤«¤ÎÍѸì¤Î°ÕÌ£¤Ï²¿¤Ç¤¹¤«¡© - -¤¤¤¯¤Ä¤«¤Î¥½¡¼¥¹¥³¡¼¥É¤ä¸Å¤¤Ê¸½ñ¤ÎÃæ¤Ë¤Ï¡¢¤½¤ì¤¾¤ÎÀìÌçʬÌî¤ÎÃæ¤Ç¤â¤Ã¤È°ìÈÌŪ¤Ë -»È¤ï¤ì¤ëÀìÌçÍѸ줬»È¤ï¤ì¤Æ¤¤¤Þ¤¹¡£ - - - ¡¦ ¥Æ¡¼¥Ö¥ë(table)¡¢´Ø·¸(relation)¡¢¥¯¥é¥¹(class) - ¡¦ ¥í¥¦(row)¡¢¥ì¥³¡¼¥É(record)¡¢¥¿¥Ã¥×¥ë(tuple) - ¡¦ ¥«¥é¥à(column)¡¢¥Õ¥£¡¼¥ë¥É(field)¡¢Â°À­(attribute) - ¡¦ ¼èÆÀ(retrieve)¡¢ÁªÂò(select) - ¡¦ ÃÖ´¹(replace)¡¢¹¹¿·(update) - ¡¦ ÄɲÃ(append)¡¢ÁÞÆþ(insert) - ¡¦ OID, Ï¢ÈÖ(serial value) - ¡¦ ¥Ý¡¼¥¿¥ë(portal), ¥«¡¼¥½¥ë(cursor) - ¡¦ ÎΰèÊÑ¿ô(range variable)¡¢¥Æ¡¼¥Ö¥ë̾(table name)¡¢¥Æ¡¼¥Ö¥ëÊÌ̾(table alias) - -°ìÈÌŪ¤Ê¥Ç¡¼¥¿¥Ù¡¼¥¹ÍѸì¤Î¥ê¥¹¥È¤Ï¡§ http://www.comptechnews.com/~reaster/ -dbdesign.html ¤Ç¸«¤Ä¤±¤é¤ì¤Þ¤¹¡£ - -4.18) ¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸ "ERROR: Memory exhausted in AllocSetAlloc()"¤¬½Ð¤ë¤Î¤Ï¤Ê -¤¼¤Ç¤¹¤«¡© - -¤â¤·¡¢7.1 ¤è¤ê¤â¸Å¤¤¥Ð¡¼¥¸¥ç¥ó¤ò¤ª»È¤¤¤Î¾ì¹ç¤Ï¡¢¥¢¥Ã¥×¥Ç¡¼¥È¤Ë¤è¤Ã¤Æ¤³¤ÎÌäÂê¤ò -²ò·è¤Ç¤­¤ë¤Ç¤·¤ç¤¦¡£¤½¤ì¤È¡¢¥·¥¹¥Æ¥à¤Î²¾ÁÛ¥á¥â¥ê¡¼¤òÁ´¤Æ»È¤¤²Ì¤¿¤·¤Æ¤·¤Þ¤Ã¤Æ¤¤ -¤ë²ÄǽÀ­¤¬¤¢¤ë¤«¡¢¥«¡¼¥Í¥ë¤¬¤¢¤ë¥ê¥½¡¼¥¹¤Ë¤Ä¤¤¤Æ¤â¤ÄÀ©¸ÂÃͤ¬Ä㤹¤®¤ë²ÄǽÀ­¤¬¤¢ -¤ê¤Þ¤¹¡£ postmaster ¤ò»Ïư¤¹¤ëÁ°¤Ë¤³¤ì¤ò»î¤·¤Æ¤ß¤Æ²¼¤µ¤¤¡§ - ulimit -d 262144 - limit datasize 256m - -¥·¥§¥ë¤Ë¤è¤Ã¤Æ¡¢¤É¤Á¤é¤«¤Ò¤È¤Ä¤¬À®¸ù¤¹¤ë¤Ç¤·¤ç¤¦¤¬¡¢¤³¤ì¤Ï¥×¥í¥»¥¹¤Î¥Ç¡¼¥¿¥»¥° -¥á¥ó¥ÈÀ©¸Â¤ò¤è¤ê¹â¤¯ÀßÄꤷ¡¢¤¿¤Ö¤óÌ䤤¹ç¤ï¤»¤¬´°·ë¤¹¤ë¤è¤¦¤Ë¤Ê¤ë¤Ç¤·¤ç¤¦¡£¤³¤Î -¥³¥Þ¥ó¥É¤Ï¸½¹Ô¤Î¥×¥í¥»¥¹¤È¡¢¤³¤Î¥³¥Þ¥ó¥É¤òÁö¤é¤»¤¿¸å¤Ëºî¤é¤ì¤ëÁ´¤Æ¤Î¥µ¥Ö¥×¥í¥» -¥¹¤Ë¤Ä¤¤¤ÆÅ¬ÍѤµ¤ì¤Þ¤¹¡£¥Ð¥Ã¥¯¥¨¥ó¥É¤¬¤È¤Æ¤â¿¤¯¤Î¥Ç¡¼¥¿¤òÊÖ¤¹¤¿¤á¤ËSQL ¥¯¥é¥¤ -¥¢¥ó¥È¤ÇÌäÂ꤬³¤¤¤Æ¤¤¤ë¤Î¤Ç¤¢¤ì¤Ð¡¢¥¯¥é¥¤¥¢¥ó¥È¤ò³«»Ï¤¹¤ëÁ°¤Ë¤³¤ì¤ò»î¤·¤Æ¤ß¤Æ -¤¯¤À¤µ¤¤¡£ - -4.19) ¤É¤Î¥Ð¡¼¥¸¥ç¥ó¤Î PostgreSQL ¤òÁö¤é¤»¤Æ¤¤¤ë¤«¤òÄ´¤Ù¤ë¤Ë¤Ï¤É¤¦¤·¤Þ¤¹¤«¡© - -psql ¤«¤é select version(); ¤ò¥¿¥¤¥×¤·¤Þ¤¹¡£ - -4.20) ¥é¡¼¥¸¡¦¥ª¥Ö¥¸¥§¥¯¥È¤ÎÁàºî¤Çinvalid large obj descriptor ¤ò¼õ¤±¼è¤ê¤Þ¤·¤¿ -¡£¤Ê¤¼¤Ç¤·¤ç¤¦¤«¡© - -¥é¡¼¥¸¡¦¥ª¥Ö¥¸¥§¥¯¥ÈÁàºî¤ò¤¹¤ë¤È¤­¤Ï¡¢Á°¸å¤ËBEGIN WORK¤ÈCOMMIT¤òÉÕ¤±¤ëɬÍפ¬¤¢ -¤ê¤Þ¤¹¡£¤¹¤Ê¤ï¤Á¡¢lo_open ... lo_close¤ò¤Ï¤µ¤ß¹þ¤ß¤Þ¤¹¡£ - -¸½ºß¤Ï¡¢PostgreSQL¤Î¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤Î¥³¥ß¥Ã¥È»þ¤Ë¥é¡¼¥¸¡¦¥ª¥Ö¥¸¥§¥¯¥È¡¦¥Ï¥ó¥É -¥ë¤òÊĤ¸¤ë¤³¤È¤Ë¤è¤ê¡¢lo_open¥³¥Þ¥ó¥É¤¬´°Î»¤·¤¿Ä¾¸å¤Ë¶¯À©Åª¤Ë¥ë¡¼¥ë¤ò¼Â¹Ô¤·¤Þ¤¹ -¡£¤³¤Î¤¿¤á¡¢ºÇ½é¤Ë¥Ï¥ó¥É¥ë¤ËÂФ·¤Æ²¿¤«¤ò¤·¤è¤¦¤È¤¹¤ë¤È¡¢invalid large obj -descriptor(¥é¡¼¥¸¡¦¥ª¥Ö¥¸¥§¥¯¥È¤Îµ­½Ò»Ò¤¬ÉÔÀµ)¤È¤Ê¤ê¤Þ¤¹¡£¤½¤ì¤Ç¡¢¤â¤·¡¢¥È¥é¥ó -¥¶¥¯¥·¥ç¥ó¤ò»È¤¦¤Î¤ò˺¤ì¤ë¤È¡¢¡Ê¾¯¤Ê¤¯¤È¤â¤Û¤È¤ó¤É¤Î»þ´Ö¡ËƯ¤¤¤Æ¤¤¤¿¥³¡¼¥É¤¬¥¨ -¥é¡¼¥á¥Ã¥»¡¼¥¸¤ò½Ð¤¹¤Î¤Ç¤¹¡£ - -¤â¤·¡¢ODBC¤Î¤è¤¦¤Ê¥¯¥é¥¤¥¢¥ó¥È¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤ò¤ª»È¤¤¤Ê¤é¡¢auto-commit off¤òÀß -Äꤹ¤ëɬÍפ¬¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡£ - -4.21) ¸½ºß¤Î»þ¹ï¤¬¥Ç¥Õ¥©¥ë¥È¤È¤Ê¤ë¤è¤¦¤Ê¥«¥é¥à¤Ï¤É¤Î¤è¤¦¤Ë¤Ä¤¯¤ê¤Þ¤¹¤«¡© - -CURRENT_TIMESTAMP¤ò»È¤¤¤Þ¤¹: - CREATE TABLE test (x int, modtime timestamp DEFAULT >CURRENT_TIMESTAMP ); - -4.22) ¤Ê¤¼¡¢IN¤ò»È¤¦ÉûÌ䤤¹ç¤ï¤»¤¬¤È¤Æ¤âÃÙ¤¤¤Î¤Ç¤¹¤«¡© - -¸½ºß¡¢³°ÉôÌ䤤¹ç¤ï¤»¤Î³Æ¥í¥¦¤Ë¤Ä¤¤¤ÆÉûÌ䤤¹ç¤ï¤»¤Î·ë²Ì¤ò½çÈ֤˥¹¥­¥ã¥ó¤¹¤ë¤³¤È -¤Ë¤è¤ê¡¢ÉûÌ䤤¹ç¤ï¤»¤ò³°ÉôÌ䤤¹ç¤ï¤»¤Ë·ë¹ç¤·¤Æ¤¤¤Þ¤¹¡£ÅöÌ̤ÏIN¤òEXISTS¤ÇÃÖ¤­´¹ -¤¨¤ë¤³¤È¤Ç¤¹¡§ - SELECT * - FROM tab - WHERE col1 IN (SELECT col2 FROM TAB2) -¤ò¡¢ÃÖ¤­´¹¤¨¤Æ¡§ - SELECT * - FROM tab - WHERE EXISTS (SELECT col2 FROM TAB2 WHERE col1 = col2) -¤È¤·¤Þ¤¹¡£¤³¤ÎÀ©¸Â¤Ï¾­Íè¤Î¥ê¥ê¡¼¥¹¤Çľ¤·¤¿¤¤¤È»×¤Ã¤Æ¤¤¤Þ¤¹¡£ - -4.23) ³°Éô·ë¹ç(outer join)¤Ï¤É¤Î¤è¤¦¤Ë¼Â¸½¤·¤Þ¤¹¤«? - -PostgreSQL 7.1 °Ê¹ß¤Ç¤ÏSQLɸ½à¹½Ê¸¤ò»È¤¦³°Éô·ë¹ç(¥¢¥¦¥¿¡¼¥¸¥ç¥¤¥ó)¤ò¥µ¥Ý¡¼¥È¤· -¤Þ¤¹¡£¤³¤³¤Ë¡¢ÎãÂ꤬2¤Ä¤¢¤ê¤Þ¤¹¡£ -SELECT * - FROM t1 LEFT OUTER JOIN t2 ON (t1.col = t2.col); -¤¢¤ë¤¤¤Ï -SELECT * - FROM t1 LEFT OUTER JOIN t2 USING (col); -¤³¤ì¤é¤Î¾ÝħŪ¤ÊÌ䤤¹ç¤ï¤»¤Ç¤Ï t1.col ¤ò t2.col ¤È·ë¹ç¤·¤Æ¡¢t1 ¤Î·ë¹ç¤µ¤ì¤Ê¤«¤Ã -¤¿¥í¥¦(t2 ¤È°ìÃפ·¤Ê¤«¤Ã¤¿¥í¥¦)¤âÊÖ¤·¤Æ¤¤¤Þ¤¹¡£RIGHT ·ë¹ç¤Ï t2 ¤Î·ë¹ç¤µ¤ì¤Ê¤«¤Ã -¤¿¥í¥¦¤ò²Ã¤¨¤ë¤Ç¤·¤ç¤¦¡£FULL ·ë¹ç¤Ï¡¢°ìÃפ·¤¿¥í¥¦¤Ë t1 ¤È t2 ¤«¤é¤Ï·ë¹ç¤µ¤ì¤Ê¤« -¤Ã¤¿¥í¥¦¤òÊÖ¤¹¤Ç¤·¤ç¤¦¡£OUTER ¤È¤¤¤¦¸ÀÍդϥª¥×¥·¥ç¥ó¤Ç LEFT, RIGHT, ¤Þ¤¿¤Ï FULL -¤Ê¤É¤Î·ë¹ç¤ò²¾Äꤵ¤ì¤Æ¤¤¤Þ¤¹¡£°ÊÁ°¤Î¥ê¥ê¡¼¥¹¤Ç¤Ï³°Éô·ë¹ç(outer join)¤òUNION ¤È -NOT IN ¤ò»È¤Ã¤Æ¥·¥ß¥å¥ì¡¼¥È¤Ç¤­¤Þ¤¹¡£¤¿¤È¤¨¤Ð¡¢tab1 ¤È tab2 ¤ò·ë¹ç¤¹¤ë¤È¤­¤Ï¡¢ -¼¡¤ÎÌ䤤¹ç¤ï¤»¤ÇÆó¤Ä¤Î¥Æ¡¼¥Ö¥ë¤ò³°Éô·ë¹ç¤·¤Þ¤¹¡£ - SELECT tab1.col1, tab2.col2 - FROM tab1, tab2 - WHERE tab1.col1 = tab2.col1 -UNION ALL - SELECT tab1.col1, NULL - FROM tab1 - WHERE tab1.col1 NOT IN (SELECT tab2.col1 FROM tab2) - ORDER BY col1 - -4.24) Ê£¿ô¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò»È¤¦Ì䤤¹ç¤ï¤»¤Ï¤É¤Î¤è¤¦¤Ë¤¹¤ì¤Ð¤Ç¤­¤Þ¤¹¤«¡© - -¸½¹Ô(current)¤ò½ü¤¤¤Æ¡¢¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ø¤ÎÌ䤤¹ç¤ï¤»ÊýË¡¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤È¤¤¤¦¤Î¤â -PostgreSQL¤¬¥Ç¡¼¥¿¥Ù¡¼¥¹»ÅÍͤΥ·¥¹¥Æ¥à¥«¥¿¥í¥°¤òÆÉ¤ß¹þ¤à¤¿¤á¤Ç¡¢¤½¤³¤Ë¤Ï¡¢¤¿¤È -¤¨¤½¤Î¤Õ¤ê¤ò¤¹¤ë¤À¤±¤Ë¤·¤í¡¢¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò±Û¤¨¤ÆÌ䤤¹ç¤ï¤»¤ò¤¹¤ë¤¹¤Ù¤¬¤¢¤ê¤Þ¤» -¤ó¡£ - -¤â¤Á¤í¤ó¡¢¥¯¥é¥¤¥¢¥ó¥È¤ÏƱ»þ¤Ë°Û¤Ê¤ëÊ£¿ô¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤ØÀܳ¤·¤Æ¤½¤³¤Ë¤¢¤ë¾ðÊó -¤ò¥Þ¡¼¥¸¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ¤¹¡£ - -4.25) ´Ø¿ô¤ÇÊ£¿ô¤Î¥í¥¦¤Þ¤¿¤Ï¥«¥é¥à¤òÊÖ¤¹¤Ë¤Ï¤É¤¦¤·¤Þ¤¹¤«¡© - -¤â¤·¡¢PL/pgSQL ´Ø¿ô¤Çrefcursors¤ò»È¤¦¤È·ë²Ì¤ÎÁȤòÊÖ¤¹¤³¤È¤¬¤Ç¤­¤Þ¤¹¡£ http:// -developer.postgresql.org/docs/postgres/plpgsql-cursors.html ¤Î 23.7.3.3 Àá¤ò¤´ -Í÷²¼¤µ¤¤¡£ - -¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬ - PostgreSQL¤Î³ÈÄ¥¤Ë¤Ä¤¤¤Æ¤Î¼ÁÌä - -5.1) ¼«Ê¬¤Ç½ñ¤¤¤¿¥æ¡¼¥¶ÄêµÁ´Ø¿ô¤ò psql ¤ÎÃæ¤Ç¼Â¹Ô¤¹¤ë¤È¥³¥¢¡¦¥À¥ó¥×¤·¤Æ¤·¤Þ¤¦¤Î -¤Ï¤Ê¤¼¤Ç¤¹¤«¡© - -ÌäÂê¤Ï¿§¡¹¤È¹Í¤¨¤é¤ì¤Þ¤¹¤¬¡¢¤Þ¤ººÇ½é¤Ë¡¢ºîÀ®¤·¤¿¥æ¡¼¥¶ÄêµÁ´Ø¿ô¤òñÆÈ¤Î¥Æ¥¹¥È¥× -¥í¥°¥é¥à¤Ë¤·¤Æ»î¤·¤Æ¤ß¤Æ²¼¤µ¤¤¡£ - -5.2) PostgreSQL ÍѤ˽ñ¤¤¤¿¤Á¤ç¤Ã¤ÈÁÇŨ¤Ê¿·¤·¤¤·¿¤ä´Ø¿ô¤òÄ󶡤·¤Æ¥×¥í¥¸¥§¥¯¥È¤Ë -¹×¸¥¤·¤¿¤¤¤Î¤Ç¤¹¤¬¡© - -³§¤µ¤ó¤Î¹Ô¤Ê¤Ã¤¿³ÈÄ¥¤ò¡¢pgsql-hackers ¥á¡¼¥ê¥ó¥°¡¦¥ê¥¹¥È¤ËÁ÷¤Ã¤Æ¤¯¤À¤µ¤¤¡£¤½¤· -¤Æ¡¢¤æ¤¯¤æ¤¯¤Ï¤½¤¦¤·¤¿³ÈÄ¥¤¬ contrib/ ¥µ¥Ö¥Ç¥£¥ì¥¯¥È¥ê¤ÎÃæ¤ËÆþ¤ë¤³¤È¤Ë¤Ê¤ë¤Ç¤· -¤ç¤¦¡£ - -5.3) ¥¿¥×¥ë¤òÊÖ¤¹ C¸À¸ì¤Î´Ø¿ô¤Ï¤É¤Î¤è¤¦¤Ë½ñ¤­¤Þ¤¹¤«¡© - -¸¶ÍýŪ¤Ë¤Ï²Äǽ¤Ç¤¹¤¬¡¢¤³¤ì¤Ë¤Ïµæ¶Ë¤Î̯µ»¤òÍפ·¤Þ¤¹¤Î¤Ç¡¢Ãø¼Ô¤Î¤Þ¤ï¤ê¤Ç¤Ï̤¤Àï -¤â¤ä¤Ã¤¿¤³¤È¤¬¤¢¤ê¤Þ¤»¤ó¡£ - -5.4) ¥½¡¼¥¹¡¦¥Õ¥¡¥¤¥ë¤òÊѹ¹¤·¤Þ¤·¤¿¡£ºÆ¥³¥ó¥Ñ¥¤¥ë¤·¤Æ¤âÊѲ½¤¬¸«¤é¤ì¤Ê¤¤¤Î¤Ï¤Ê¤¼ -¤Ç¤¹¤«¡© - -¤¤¤¯¤Ä¤«¤Î Makefile ¤¬¥¤¥ó¥¯¥ë¡¼¥É¡¦¥Õ¥¡¥¤¥ë¤ËÂФ·¤ÆÅ¬Àڤʰ͸´Ø·¸¤ò»ý¤Ã¤Æ¤¤¤Þ -¤»¤ó¡£make clean ¤ò¤·¤Æ¤«¤é¤â¤¦°ìÅÙ make ¤ò¹Ô¤Ê¤ï¤Ê¤¯¤Æ¤Ï¤Ê¤ê¤Þ¤»¤ó¡£¤â¤·¡¢GCC -¤ò¤ª»È¤¤¤Ç¤¢¤ì¤Ð configure ¤Î --enable-depend ¥ª¥×¥·¥ç¥ó¤ò»È¤Ã¤Æ¡¢¥³¥ó¥Ñ¥¤¥é¤Ë -°Í¸´Ø·¸¤ò¼«Æ°Åª¤ËÄ´¤Ù¤µ¤»¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡£ -¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬¨¬ -[ÌõÃí¡§ - ÆüËܸìÈǤÎÀ½ºî¤Ë¤Ä¤¤¤Æ¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¹¡£ - - ºÇ½ª¹¹¿·Æü: 2002ǯ05·î08Æü - ËÝÌõ¼Ô: ·¬Â¼ ½á (Jun Kuwamura ) - - ¤³¤ÎFAQ¤ÎÏÂÌõ¤ÎºîÀ®¤Ë¤¢¤¿¤ê¶¨ÎϤò¤·¤Æ¤¯¤À¤µ¤Ã¤¿Êý¡¹(·É¾Î¤Ïά¤µ¤»¤Æ¤¤¤¿¤À¤­¤Þ¤¹): - - ÅÄÃç Ì­(Minoru Tanaka ) - Àаæ ãÉ×(Tatsuo Ishii ) - óîÆ£ ÃοÍ(Tomohito Saitoh ) - ÇϾì È¥(Hajime Baba ) - ²¬ËÜ °ì¹¬(Kazuyuki Okamoto ) - ¾®¿û ¾¼°ì(Shoichi Kosuge ) - »³²¼ µÁÇ·(Yoshiyuki Yamashita ) - ¶­ ¿¿ÂÀϺ(Sintaro Sakai ) - À¸±Û ¾»¸Ê(Masami Ogoshi ) - ÀÐÀî ½Ó¹Ô(Toshiyuki Ishikawa ) - ËÜÅÄ Ìй­(Shigehiro Honda ) - ¤»¤» ¤¸¤å¤ó(Jun Sese ) - ¿Àë ±Ñ¹§(Hidetaka Kamiya ) - - ¤ò¤Ï¤¸¤á¡¢¥Ý¥¹¥È¥°¥ì¥¹¤Ë´Ø¤¹¤ëÏÃÂêË­ÉÙ¤ÊÆüËܸì¥Ý¥¹¥È¥°¥ì¥¹¡¦¥á¡¼¥ê¥ó¥°¥ê¥¹¥È¡¢ - ÏÂÌõ¤Î¤­¤Ã¤«¤±¤òºî¤Ã¤Æ¤¯¤ì¤¿ JF(Linux Japanese FAQ Mailing List)¥×¥í¥¸¥§¥¯¥È¡¢¤½¤Î¾¡¢ - ľÀܤ¢¤ë¤¤¤Ï´ÖÀÜŪ¤Ë¤«¤«¤ï¤Ã¤Æ¤¤¤ë¤¹¤Ù¤Æ¤Î¥ª¡¼¥×¥ó¥½¡¼¥¹¥³¥ß¥å¥Ë¥Æ¥£¡¼¤Î - ³§¤µ¤ó¤Ë´¶¼Õ¤·¤Þ¤¹¡£ - - - ÆüËܸìÈǤΤ³¤Îʸ½ñ¤Ï¡¢°Ê²¼¤«¤é¤â¤¿¤É¤ì¤Þ¤¹¡£ - http://www.rccm.co.jp/~juk/pgsql/(FAQÏÂÌõ PostgreSQL ¤Ë¤Ä¤¤¤Æ¤è¤¯¤¢¤ë¼ÁÌä) - http://www.linux.or.jp/JF/(PostgreSQL-FAQ.j) - http://www.sra.co.jp/people/t-ishii/PostgreSQL/doc-jp/ - - ¤Ê¤ª¡¢¤³¤ÎÏÂÌõ¤Ë´Ø¤¹¤ë¤´°Õ¸«¤Ï(juk@postgresql.jp)¤Þ¤Ç¤ª´ó¤»²¼¤µ¤¤¡£ -] diff --git a/doc/FAQ_polish b/doc/FAQ_polish deleted file mode 100644 index d89b8ea7ab..0000000000 --- a/doc/FAQ_polish +++ /dev/null @@ -1,1174 +0,0 @@ - - Frequently Asked Questions (FAQ) o PostgreSQL - - Ostatnia aktualizacja: Thu Apr 18 00:44:51 EDT 2002 - - Obecny maintainer: Bruce Momjian (pgman@candle.pha.pa.us) - - Tl/umaczenie: Marcin Mazurek (m.mazurek@netsync.pl) - - Najbardziej aktualna wersje tego dokumentu mozna znalezc pod adresem: - http://www.PostgreSQL.org/docs/faq-english.html. - - Odpowiedzi na pytania dotyczace konkretnych systemów operacyjnych - mozna znalezc pod adresem: - http://www.PostgreSQL.org/users-lounge/docs/faq.html. - _________________________________________________________________ - - Pytania ogólne - - 1.1) Co to jest PostgreSQL? Jak to wymawiac? - 1.2) Jaka licencja chroniony jest PostgreSQL? - 1.3) Na jakich systemach Unixowych dzial/a PostreSQL? - 1.4) Na jakich nie-Unixowych systemach dzial/a PostgreSQL? - 1.5) Skad moge sciagnac PostgreSQL? - 1.6) Gdzie mozna szukac wsparcia technicznego? - 1.7) Jaka jest ostatnia dostepna wersja? - 1.8) Jaka dokumentacja jest dostepna? - 1.9) Gdzie moge znalezc informacje o znanych bl/edach czy brakujacych - rozwiazanich? - 1.10) Jak moge sie nauczyc SQL? - 1.11) Czy PostgreSQL ma rozwiazany problem Y2K? - 1.12) Jak moge sie przyl/aczyc do grupy osób bezposrednio pracujacych - nad rozwojem PostgreSQL? - 1.13) Jak moge zgl/aszac bl/edy? - 1.14) Jak mozna porównac PostgreSQL w stosunku do innych DBMS? - 1.15) W jaki sposób moge wesprzec finansowo PostgreSQL? - - Pytania uzytkowników - - 2.1) Czy sa jakies driwery ODBC dla PostgreSQL? - 2.2) Jakie istnieja narzedzia pozwalajace na dostep do PostgreSQL - przez www? - 2.3) Czy istnieje jakies GUI dla PostgreSQL? Narzedzie do - raportowania? Interfejs dla "embedded query language"? - 2.4) Za pomoca jakich jezyków programowania mozna sie komunikowac z - PostgreSQL? - - Pytania administratora - - 3.1) Jak moge zainstalowac PostgreSQL w innej lokalizacji niz - /usr/local/pgsql? - 3.2) Podczas startu postmaster'a, otrzymuje komunikat: Bad System Call - lub "core dumped". Dlaczego? - 3.3) Podczas startu postmaster'a, otrzymuje komunikato bl/edzie: - IpcMemoryCreate. Dlaczego? - 3.4) Podczas startu postmaster'a, otrzymuje komunikat o bl/edzie: - IpcSemaphoreCreate. Dlaczego? - 3.5) W jaki sposób moge kontrolowac pol/aczenia z innych hostów? - 3.6) Jak powinienem skonfigurowac system baz danych aby uzyskac lepsza - wydajnosc? - 3.7) Jakie sa mozliwosci wyszukiwania bl/edów? - 3.8) Skad sie bierze komunikat: "Sorry, too many clients" podczas - próby pol/aczenia sie z baza danych? - 3.9) Co to za pliki typu pg_sorttempNNN.NN , które znajduja sie w - katalogu z plikami bazy danych? - - Pytania dotyczace uzytkowania - - 4.1) Jaka jest róznica pomiedzy kursorami binarnymi (binary cursors) i - zwykl/ymi kursorami (normal cursors)? - 4.2) Jak moge pobrac za pomoca SELECT jedynie kilka pierwszych wyników - zapytania? - 4.3) Jak moge uzyskac liste wszystkich tabel czy innych rzeczy pod - psql? - 4.4) Jak usunac kolumne z tabeli? - 4.5) Jaki jest maksymalny rozmiar dla rzedu, tabeli i bazy danych? - 4.6) Jak duzo miejsca w bazie danych jest potrzebne aby przechowac - dane ze zwyczajnego pliku tekstowego? - 4.7) Jak moge sprawdzic jakie tabele, klucze, bazy danych i - uzytkownicy sa utworzeni? - 4.8) Moje zapytania sa wolne lub nie uzywaja kluczy. Dlaczego? - 4.9) Jak moge sprawdzic w jakis sposób "query optimizer" wykonuje moje - zapytanie? - 4.10) Co to jest "R-tree index"? - 4.11) Co to jest "Genetic Query Optimizer"? - 4.12) Jak moge uzywac wyrazen regularnych w zapytaniach i zapytan - case-insensitive w wyrazeniach regularnych? Jak korzystac z indeksów - dla zapytan case-insensitive? - 4.13) Jak sprawdzic w zapytaniu czy pole ma wartosc NULL? - 4.14) Jaka jest róznica pomiedzy róznymi typami tekstowymi (character - types)? - 4.15.1) Jak moge utworzyc pole typu int, które samo zwieksza swoja - wartosc? - 4.15.2) Jak pobrac wartosc pola typu SERIAL po wykonaniu insert'u? - 4.15.3) Czy uzycie currval() i nextval() nie doprowadzi do "race - condition" z innymi uzytkownikami? - 4.15.4) Dlaczego numery sekwencji nie sa ponownie uzywane przy - przerwaniu transakcji? Skad sie biora luki w numerowaniu kolumny - tabeli sekwencjami/SERIALem? - 4.16) Co to jest OID? Co to jest TID? - 4.17) Jakie jest znaczenie niektórych terminów w PostgreSQL? - 4.18) Skad bierze sie ten bl/ad: "ERROR: Memory exhausted in - AllocSetAlloc()"? - 4.19) Jak sprawdzic jakiej wersji PostgreSQL uzywam? - 4.20) Dlaczego operacje, które wykonuje na duzych obiektach - "large-object" zwracaja komunikat: "invalid large obj descriptor"? - 4.21) Jak stworzyc kolumne której domyslna wartoscia bedzie biezacy - czas? - 4.22) Dlaczego zapytania uzywajace IN sa takie wolne? - 4.23) Jak wykonac "outer join"? - 4.24) Jak wykonywac zapytanie uzywajace kilku baz danych jednoczesnie? - 4.25) Jak zwrócic w funkcji wiele rzedów lub kolumn? - - Rozwijanie PostgreSQL - - 5.1) Napisal/em wl/asna funkcje. Kiedy uzyje jej w psql, program - zrzuca pamiec (dump core)? - 5.2) Jak moge dodac/zgl/osic nowe typy czy funkcje do PostgreSQL? - 5.3) Jak napisac funkcje C zwracajaca krotke (tuple)? - 5.4) Zmienil/em plik zródl/owy. Dlaczego po rekompilacji nie widac - zmiany? - _________________________________________________________________ - - Pytania ogólne - - 1.1) Co to jest PostgreSQL? Jak to wymawiac? - - PostgreSQL wymawia sie Post-Gres-kju-el. - - PostgreSQL jest rozszerzeniem systemu zarzadzania bazami danych - - POSTGRES, kolejna generacja rozwojowego prototypu DBMS. Mimo, ze - PostgreSQL zachowal/ bardzo dobrze zbudowany model danych (data model) - i bogaty zestaw typów danych POSTGRES'a, zastapil/ PostQuel'owy jezyk - zapytan z rozbudowanym podzbiorem jezyka SQL. PostgreSQL jest - oprogramowaniem darmowym z dostepnymi cal/ymi zródl/ami. - - Rozwój PostgreSQL jest prowadzony przez grupe ludzi z Internetu, - komunikujacych sie poprzez mailowe listy dyskusyjne PostgreSQL. - Obecnym koordynatorem jest Marc G. Fournier (scrappy@PostgreSQL.org). - (Zobacz ponizej jak sie przyl/aczyc). Ta grupa ludzi jest - odpowiedzialna za cal/y rozwój PostgreSQL. - - Autorami PostgreSQL 1.01 byli Andrew Yu and Jolly Chen. Wiele innych - osób pomogl/o przy portowaniu, testowaniu, debugowaniu, i rozwijaniu - kodu. Oryginalny kod Postgresa, na którym zostal/ oparty PostgreSQL, - byl/ wysil/kiem studentów oraz pracowników pracujacych pod - kierownictwem profesora Michael'a Stonebraker'a z University of - California w Berkeley. - - Oryginalna nazwa oprogramowania w Berkeley byl/ Postgres. Po dodaniu - obsl/ugi SQL w 1995, nazwa zostal/a zmieniona na Postgres95. Pod - koniec roku 1996 nazwa zostal/a zmieniona na PostgreSQL. - - 1.2) Jaka licencja chroniony jest PostgreSQL? - - PostgreSQL objety jest nastepujaca licencja: - - PostgreSQL Data Base Management System - - Portions copyright (c) 1996-2002, PostgreSQL Global Development Group - Portions Copyright (c) 1994-6 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. - - Tekst powyzej, jest klasyczna licencja BSD. Nie posiada ona zadnych - restrykcji co do uzywania kodu zródl/owego. Podoba nam sie i nie - zamierzamy jej zmieniac. - - 1.3) Na jakich systemach Unixowych dzial/a PostreSQL? - - PostgreSQL powinien dzial/ac na wszystkich nowych Unix-podobnych - systemach. Platformy, które zostal/y szczegól/owo przetestowane - podczas publikowania PostgreSQL sa wymienione w dokumentacji - opisujacej instalacje. - - 1.4) Na jakich nie-Unixowych systemach dzial/a PostgreSQL? - - Klient - - Mozliwa jest kompilacja bibliteki C libpq C, psql oraz innych - interfejsów i uruchamianie ich na platformie MS Windows. W tym wypadku - klient jest uruchamiany na MS Windows a z serwerem komunikuje sie - poprzez TCP/IP. Serwer moze dzial/ac na dowolnej wspieranej platformie - Unixowej. Plik win31.mak jest dol/aczony do zródel/, aby mozna byl/o - stworzyc biblioteke libpq oraz program psql dzial/ajace w srodowisku - Win32. PostgreSQL moze sie takze komunikowac z klientami ODBC. - - Serwer - - Serwer moze byc uruchamiany na Windows NT i Win2k uzywajac bibliotek - Cygwin, Cygnus Unix/NT. W pliku pgsql/doc/FAQ_MSWIN znajdujacym sie w - zródl/ach lub pod adresem: MS Windows FAQ na naszych stronach. Nie - planujemy tworzyc portu przeznaczonego docelowo dla platformy - Microsoft. - - 1.5) Skad mozna sciagnac PostgreSQL? - - Gl/ówny serwer ftp z dostepem "anonymous" dla PostgreSQL znajduje sie - ftp://ftp.PostgreSQL.org/pub. jesli szukasz mirrorów sprawdz nasza - gl/ówna strone www. - - 1.6) Gdzie mozna szukac wsparcia technicznego? - - Adres gl/ównej listy mailowej: pgsql-general@PostgreSQL.org. Jest ona - przeznaczona dyskusjom dotyczacym spraw zwiazanych z PostgreSQL. Zeby - zapisac sie na liste, wyslij email z nastepujacymi liniami w tresci - maila (nie w temacie): - subscribe - end - - na adres: pgsql-general-request@PostgreSQL.org. - - Dostepna jest takze lista wysyl/ajaca digesty. Aby zapisac sie na nia, - wyslij email na adres: pgsql-general-digest-request@PostgreSQL.org z - trescia maila zawierajaca: - subscribe - end - - Digesty sa wysyl/ane do czl/onków listy, kiedy na gl/ówna liste dotrze - ok 30k wiadomosci. - - Dostepna jest takze lista poswiecona bl/edom znalezionym w PostgreSQL. - Aby zapisac sie na nia wyslij email na adres: - pgsql-bugs-request@PostgreSQL.org z trescia maila zawierajaca: - subscribe - end - - Lista poswiecona dyskusjom developerów jest dostepna pod adresem: - pgsql-hackers-request@PostgreSQL.org Aby sie na nia zapisac wyslij na - jej adres mail z trescia: - subscribe - end - - Dodatkowe informacje o listach mailowych dotyczacych PostgreSQL mozna - znalezc na stronach WWW PostgreSQL pod adresem: - - http://www.PostgreSQL.org - - W sieci EFNet istnieje kanal/ IRC #PostgreSQL. Ja, do pol/aczenia sie - z kanal/em uzywam Unixowego polecenia irc -c '#PostgreSQL' "$USER" - irc.phoenix.net. - - Lista firm oferujacych wsparcie na zasadach komercyjnych znajduje sie - pod adresem: - http://www.postgresql.org/users-lounge/commercial-support.html. - - 1.7) Jaka jest ostatnia dostepna wersja? - - Ostatnia dostepna wersja PostgreSQL to 7.2.1. - - Planujemy publikowanie kolejnych wersji co cztery miesiace. - - 1.8) Jaka dokumentacja jest dostepna? - - Kilka manuali, stron podecznika man, oraz kilka przykl/adów do - testowania sa zal/aczone w samej dystrybucji. Znajduja sie one w - katalogu /doc. Manual moze byc takze przegladany poprzez strony www - pod adresem http://www.PostgreSQL.org/users-lounge/docs/. - - Istnieja takze dwie ksiazki dostepne online pod adresami - http://www.PostgreSQL.org/docs/awbook.html i - http://www.commandprompt.com/ppbook/. Lista ksiazek o PostgreSQL, - które mozna kupic znajduje sie pod adresem - http://www.postgresql.org/books/. Zbiór technicznych artykul/ów o - PostgreSQL znajduje sie pod adresem http://techdocs.postgresql.org/. - - psql posiada kilka wbudowanych polecen \d, za pomoca których mozna - sprawdzic informacje dotyczace typów, operatorów, funkcji, aggregatów - itd. - - Na naszej stronie mozna znalezc duzo wiecej dokumentacji. - - 1.9) Gdzie mozna znalezc informacje o znanych bl/edach czy brakujacych - rozwiazanich? - - PostgreSQL wspiera rozszerzony podzbiór standardu SQL-92. Sprawdz - nasza liste TODO aby znalezc informacje o znanych problemach, - brakujacych rozwiazaniach czy przyszl/ych planach. - - 1.10) Jak moge sie nauczyc SQL? - - Ksiazka o PostgreSQL http://www.PostgreSQL.org/docs/awbook.html uczy - SQL. Jest jeszcze inna ksiazka o PostgreSQL dostepna pod adresem: - http://www.commandprompt.com/ppbook. Dobry tutorial mozesz znalezc pod - adresem: http://www.intermedia.net/support/sql/sqltut.shtm, oraz - http://ourworld.compuserve.com/homepages/graeme_birchall/HTM_COOK.HTM, - i http://sqlcourse.com. - - Jeszcze inny to "Teach Yourself SQL in 21 Days, Second Edition" pod - adresem: http://members.tripod.com/er4ebus/sql/index.htm - - Wielu z naszych uzytkowników poleca The Practical SQL Handbook, - Bowman, Judith S., et al., Addison-Wesley. Inni polecaja The Complete - Reference SQL, Groff et al., McGraw-Hill. - - 1.11) Czy PostgreSQL ma rozwiazany problem Y2K? - - Tak, bez problemu radzimy sobie z datami po roku 2000 AD, oraz przed - rokiem 2000 BC. - - 1.12) Jak moge sie przyl/aczyc do grupy osób bezposrednio pracujacych nad - rozwojem PostgreSQL? - - Przede wszystkim sciagnij ostatnie dostepne zródl/a i przeczytaj - dokumentacje przeznaczona dla developerów na naszej stronie www lub - dostepna takze w zródl/ach PostgreSQL. Nastepnie zapisz sie na listy - mailowe pgsql-hackers i pgsql-patches. I na koniec, wysyl/aj nam - wysokiej jakosci patch'e na liste pgsql-patches. - - Jest okol/o 12 osób, które maja uprawnienia do commit'owania w CVS - PostgreSQL'a. Kazdy z nich submitowal/ tak wiele wysokiej jakosci - patchy, ze stal/o sie niemozliwe dla obecnych commiterów byc z nimi na - biezaco, majac pewnosc ze sa to poprawki wysokiej jakosci. - - 1.13) Jak moge zgl/aszac bl/edy? - - Zajrzyj na strone PostgreSQL BugTool, na której opisane sa wskazówki - jak zgl/aszac informacje o bl/edach. - - Zajrzyj takze na nasz ftp ftp://ftp.PostgreSQL.org/pub, aby sprawdzic - czy nie ma nowszych wersji PostgreSQL czy patchy. - - 1.14) Jak mozna porównac PostgreSQL w stosunku do innych DBMS? - - Jest kilka sposobów oceny softwaru: mozliwosci, wydajnosc, stabilnosc, - wsparcie i cena. - - Mozliwosci - PostgreSQL posiada mozliwosci dostepne w duzych, komercyjnych - systemach DBMS, takie jak transakcje, podzapytania - (subselects), triggery, widoki, klucze obce, referential - integrity, oraz wyrafinowany system blokowania. Mamy takze - wl/asciowsci których inni nie posiadaja, jak typy definiowane - przez uzytkownika, dziedziczenie, rules, multi-version - concurrency control, która redukuje problemy z blokowaiem (lock - contention). - - Wydajnosc - PostgreSQL dzial/a w dwóch trybach. Standardowy tryb fsync - zrzuca kazda zakonczona transakcje na dysk, gwarantujac w ten - sposób to, ze jesli system operacyjny sie zawiesi lub straci - zasilanie wciagu kilku nastepnych sekund, wszystkie Twoje dane - zostana bezpiecznie zapisane na dysku. W tym trybie, jestesmy - wolniejsi niz wiekszosc komercyjnych baz danych, czesciowo - dlatego ze niewiele z nich wykonuje taki sposób zapisywania - danych jako domyslne ustawienie. W trybie no-fsync z regul/y - jestesmy szybsi niz komercyjne bazy danych, chociaz w tym - wypadku zawieszenie sie systemu moze spowodowac uszkodzenie - danych. Pracujemy nad tym, aby stworzyc posredni tryb, który - powoduje mniejsza redukcje wydajnosci niz tryb fsync i pozwoli - na integralnosc danych w przeciagu 30 sekund do zal/amania sie - systemu operacyjnego. - Porównujac do MySQL czy innych prostych baz danych, jestesmy - wolniejsi przy wykonywaniu insertów/updatów przez narzut - spowodowany przez transakcje. Oczywiscie MySQL nie posiada - zadnej z wymienionych wyzej mozliwosci. PostgreSQL zostal/ - zbudowany aby byc DBMS elastycznym i bogatym z róznorakie - mozliwosci, aczkolwiek dbamy, aby poprawiac jego wydajnosc - poprzez analize kodu zródl/owego i profilowanie. Ciekawe - porównanie PostgreSQL i MySQL mozna znalezc pod adresem - http://openacs.org/why-not-mysql.html - Kazde pol/aczenie klienta jest obsl/ugiwane przez nas poprzez - stworzenie nowego procesu Unixowego. Procesy backendu dziela - bufory danych oraz informacje o blokadach. Uzywajac wielu - procesorów, rózne backendy moga bez problemu dzial/ac na - róznych procesorach. - - Stabilnosc - Zdajemy sobie sprawe, ze DBMS musi byc stabilny, w przeciwnym - wypadku jest bez wartosci. Staramy sie publikowac kod stabilny, - dobrze przetestowany, z minimum mozliwych bl/edów. Kazde - wydanie poprzedza conajmniej miesiac testów wersji beta. - Patrzac na historie wydan PostgreSQL widac, ze dostarczamy - stabilne, dobrze sprawdzone wersje, które sa gotowe do uzycia w - srodowisku produkcyjnym. Myslimy, ze proces publikowania - kolejnych wersji opracowany przez nas jest jednym z lepszych - wsród innych twórców oprogramowania bazodanowego. - - Wsparcie - Dzieki naszym listom mailowym masz dostep do duzej liczby - programistów i uzytkowników, którzy pomagaja rozwiazac kazdy - napotkany problem. Chociaz nie mozemy gwarantowac znalezienia - rozwiazania danego problemu, nie róznimy sie w tym od innych - komercyjnych systemów DBMS. Bezposredni kontakt z - programistami, uzytkownikami, dokumentacja i kodem zródl/owym - sprawiaja, ze wsparcie oferowane PostgreSQL niejednokrotnie - jest lepsze niz w innych systemach DBMS. Istnieje takze - mozliwosc skorzystania z komercyjnego wsparcia dla tych, - których takiego rozwiazania potrzebuja. (Sprawdz ten punkt - FAQ.) - - Cena - Korzystanie z PostgreSQL jest darmowe, zarówno w przypadku - komercyjnym jak i niekomercyjnym. Mozesz korzystac z naszego - kodu zródl/owego w Twoim produkcie bez zadnych ograniczen, poza - tymi wymienionymi w licencji BSD przytoczonej powyzej. - - 1.15) W jaki sposób moge wesprzec finansowo PostgreSQL? - - PostgreSQL korzysta z najlepszej infrastruktury od samego poczatku - istnienia projektu, tzn. szesciu lat. Wszystko to zawdzieczamy - Marc'owi Fournier'owi, który stworzyl/ ta infrastrukture i zarzadza - nia od lat. - - Wysokiej jakosci infrastruktura jest bardzo wazna dla kazdego projektu - open-source. Zapobiega przerwom w rozwoju projektu i jakimkolwiek - przestojom. - - Oczywiscie korzystanie z wysokiej jakosci infrastruktury nie jest - tanie. Istnieje wiele róznych miesiecznych, czy jednorazowych - wydatków, które trzeba ponosic aby wszystko dzial/al/o jak nalezy. - Jesli Ty, badz Twoja firma moze wspomóc finansowo rozwój PostgreSQL - odwiedz adres: http://www.pgsql.com/pg_goodies gdzie opisane jest jak - to zrobic. - - Chociaz na stronie wspomniana jest nazwa PostgreSQL Inc, "datki" sa - przeznaczone jedynie na rozwój projektu PostgreSQL i nie sa - przeznaczane na finansowanie jakiejkolwiek firmy. Jesli wolisz, mozesz - wysl/ac czek na adres kontaktowy. - _________________________________________________________________ - - User Client Questions - - 2.1) Czy sa jakies driwery ODBC dla PostgreSQL? - - Dostepne sa dwa driwery ODBC: PsqlODBC i OpenLink ODBC. - - PsqlODBC jest dol/aczony do zródel/. Wiecej informacji na jego temat - mozesz znalezc pod adresem: ftp://ftp.PostgreSQL.org/pub/odbc/. - - OpenLink ODBC moze byc pobrany z adresu: http://www.openlinksw.com. - Wspól/pracuje ze standardowym oprogramowaniem klienckim ODBC wiec w - ten sposób mozesz korzystac z PostgreSQL ODBC dostepnego na kazdej - plaformie która wspiera (Win, Mac, Unix, VMS). - - Autorzy beda prawdopodobnie sprzedawac ten produkt osobom które - wymagaja komercyjnego wsparcia, ale wersja darmowa bedzie zawsze - dostepna. Wszystkie pytania mozesz wysyl/ac na adres: - postgres95@openlink.co.uk. - - Sprawdz takze rozdzial/ o ODBC w "Programmer's Guide". - - 2.2) Jakie istnieja narzedzia pozwalajace na dostep do PostgreSQL przez - www? - - Dobry podrecznik dla poczatkujacych o dostepie do bazy danych przez - www mozesz znalezc pod adresem: http://www.webreview.com - - Inny znajduje sie pod adresem: http://www.phone.net/home/mwm/hotlist/. - - Do integracji z www, swietnym rozwiazaniem jest PHP. Mozesz znalezc - wiecej informacji na ten temat pod adresem http://www.php.net. - - Wiele osób w przypadku skomplikowanych rozwiazan uzywa Perl'a i - modul/u CGI.pl. - - 2.3) Czy istnieje jakies GUI dla PostgreSQL? Narzedzie do raportowania? - Interfejs dla "embedded query language"? - - Mamy cal/kiem mil/y interfejs graficzny, który zostal/ nazwany - pgaccess i jest on dostarczany jako czesc zródel/. pgaccess posiada - takze generator raportów. Mozna go znalezc pod adresem - http://www.flex.ro/pgaccess - - Udostepnilismy takze ecpg, który jest "embedded SQL query language - interface" dla jezyka C. - - 2.4) Za pomoca jakich jezyków programowania mozna sie komunikowac z - PostgreSQL? - - Mamy wsparcie dla: - * C (libpq) - * C++ (libpq++) - * Embedded C (ecpg) - * Java (jdbc) - * Perl (perl5) - * ODBC (odbc) - * Python (PyGreSQL) - * TCL (libpgtcl) - * C Easy API (libpgeasy) - * Embedded HTML (PHP z http://www.php.net) - _________________________________________________________________ - - Pytania administratora - - 3.1) Jak moge zainstalowac PostgreSQL w innej lokalizacji niz - /usr/local/pgsql? - - Uzyj opcji --prefix podczas uruchamiania skryptu configure. - - 3.2) Podczas startu postmaster'a, otrzymuje komunikat o bl/edzie: Bad - System Call lub "core dumped". Dlaczego? - - Ten bl/ad moze byc wynikiem wielu problemów, ale na poczatek sprawdz - czy masz zainstalowane rozszerzenia systemu V w jadrze systemu. - PostgreSQL wymaga do pracy zainstalowanej obsl/ugi pamieci dzielonej i - semaforów. - - 3.3) Podczas startu postmaster'a, otrzymuje komunikat o bl/edzie: - IpcMemoryCreate. Dlaczego? - - Albo nie masz poprawnie skonfigurowanej obsl/ugi pamieci dzielonej w - jadrze systemu, albo musisz zwiekszyc jej dostepny rozmiar. Dokl/adna - ilosc jaka potrzebujesz jest zalezna od architektury systemu na jakim - pracujesz, jak duzo buforów oraz jak duzo procesów backendu - skonfigurowal/es dla postmaster'a. Dla wiekszosci systemów, z domyslna - liczba buforów i procesów potrzebujesz minimum w przyblizeniu 1MB. - Zobacz PostgreSQL Administrator's Guide gdzie szczegól/owo zostal/o - opisane wykorzystanie pamieci dzielonej i semaforów. - - 3.4) Podczas startu postmaster'a, otrzymuje komunikat o bl/edzie: - IpcSemaphoreCreate. Dlaczego? - - Jesli tresc bl/edu brzmi: IpcSemaphoreCreate: semget failed (No space - left on device) oznacza to, ze jadro systemu nie jest skonfigurowane - do obsl/ugi wystarczajacej liczby semaforów. Postgres wymaga jednego - semafor'a na potencjalny jeden proces backend. Tymczasowym - rozwiazaniem jest uruchomienie programu postmaster z mniejsza - maksymalna liczba procesów backend. Uzyj opcji -N z parameterem - mniejszym od domyslnego - 32. Bardziej trwal/ym rozwiazaniem jest - zwiekszenie parametrów SEMMNS i SEMMNI jadra twojego systemu. - - Niedzial/ajace semafory moga spowodowac niepoprawne zamkniecie systemu - w czasie intensywnego korzystania z bazy. - - Jesli tresc bl/edu jest inna, moze to oznaczac, ze obsl/uga semaforów - nie zostal/a wl/aczona do jadra wcale. Zobacz PostgreSQL - Administrator's Guide po bardziej szczegól/owe informacje o pamieci - dzielonej i semaforach. - - 3.5) W jaki sposób moge kontrolowac pol/aczenia z innych hostów? - - Domyslnie PostgreSQL pozwala jedynie na pol/aczenia za pomoca socketów - Unixowych z lokalnego hosta. Inne hosty nie beda mogl/y sie pol/aczyc - z serwerem dopóki nie zostanie dodana opcja -i do postmaster'a, oraz - nie umozliwi sie autoryzacji na podstawie adresu hostów modyfikujac - odpowiednio plik $PGDATA/pg_hba.conf. To zmiany pozwola na pol/aczenia - TCP/IP. - - 3.6) Jak powinienem skonfigurowac system baz danych aby uzyskac lepsza - wydajnosc? - - Indeksy bez watpienia moga przyspieszyc wykonywanie zapytan. Polecenie - EXPLAIN pozwala zobaczyc jak PostgreSQL interpretuje Twoje zapytanie i - które indeksy sa uzywane. - - Jesli wykonujesz bardzo duzo INSERTów, moze warto je wykonac za pomoca - jednego duzego pliku uzywajac polecenia COPY. Jest to duzo szybsze niz - pojedyncze INSERTy. Po drugie polecenia SQL nie zawarte w bloku - okreslajacym transakcje - BEGIN WORK/COMMIT, sa traktowane jako - pojedyncza transakcja. Rozwaz wykonanie kilku polecen/zdan SQL w - jednym bloku transakcji. To redukuje narzut powodowany przez - transakcje. Przy duzych zmianach w danych, warto usunac i stworzyc na - nowo indeksy. - - Jest kilka opcji pozwalajacych na poprawienie wydajnosci. Mozesz - wyl/aczyc fsync() poprzez uruchomienie postmaster'a z opcjami -o -F. - To spowoduje, ze fsync() nie bedzie zrzucal/ danych na dysk po kazdej - transakcji. - - Mozesz takze uruchomic postmaster'a z opcja -B aby zwiekszyc wielkosc - pamieci dzielonej uzywanej przez procesy backendów. Jesli ustawisz ta - wartosc zbyt wysoko i przekroczysz limity ustawione przez kernel na - pamiec dzielona, postmaster moze sie nie uruchomic. Kazdy bufor - zajmuje 8K a domyslna ilosc buforów to 64. - - Mozesz takze uzyc opcji -S dla backendu aby zwiekszyc maksymalna - wartosc pamieci uzywana przez proces backendu podczas sortowania. - Opcja -S jest ustawiana wartoscia podawana w kilobajtach, domyslna - wartosc to 512K. - - Mozesz takze uzyc polecenia CLUSTER aby pogrupowac dane w tabelach wg - indeksu. Zobacz opis polecenia CLUSTER w manualu zeby dowiedziec sie - wiecej. - - 3.7) Jakie sa mozliwosci wyszukiwania bl/edów? - - PostgreSQL ma kilka mozliwosci na raportowanie informacji o jego - statusie, które moga byc przydatne przy debugowaniu procesu. - - Przede wszystkim uruchom skrypt configure z opcja --enable-cassert, - wiele funkcji assert() monitoruja postep procesu backend i zatrzymuja - program kiedy wydarzy sie cos nieoczekiwanego. - - Zarówno postmaster jak i postgres maja kilka opcji do debugowania. Za - kazdym razem kiedy uruchamiasz postmaster'a, upewnij sie, ze wysyl/asz - standardowe wyjscie i error do pliku z logami, np. w ten sposób: - cd /usr/local/pgsql - ./bin/postmaster >server.log 2>&1 & - - To utworzy plik server.log w gl/ównym katalogu PostgreSQL. Ten plik - zawiera pozyteczne informacje o problemach i bl/edach, które - wydarzyl/y sie podczas pracy serwera. Postmaster posiada opcje -d, - która pozwala na raportowanie bardzo szczególowych informacji. Do - opcji -d podajemy liczbe, która okresla szczegól/owosc wysyl/anych - informacji. Musisz miec swiadomosc, ze wysoki poziom logowania bedzie - powodowal/ tworzenie bardzo duzych plików z logami. - - Jesli postmaster nie zostal/ uruchomiony, mozesz uruchomic - postgres'owy backend z linii polecen, i uruchomic Twoje polecenie SQL - bezposrednio na nim. Taki sposób jest polecany jedynie w przypadku - debugowania. Zwróc uwage, ze w tym wypadku zapytanie konczy znak nowej - linii a nie srednik. Jesli skompilowal/es z opcjami debugowania mozesz - uzyc debuggera aby sprawdzic co sie dzieje. Poniewz backend nie - zostal/ uruchomiony przez postmaster'a, nie dzial/a w identycznym - srodowisku, co oznacza ze powtórzenie warunków w jakich wystapil/y - problemy moze byc problemem. - - Jesli postmaster dzial/a, uruchom psql w jednym z okien, nastepnie - znajdz PID procesu postgres uzywanego przez psql. Uzyj debuggera aby - do PID'u postgres'a. Mozesz ustawiac pul/apki (breakpoints) w - debuggerze i wykonywac zapytania z psql. Jesli debugujesz uruchamianie - postgres'a, mozesz ustawic zmienna PGOPTIONS="-W n", nastepnie - uruchomic psql. Opcja ta pozwoli spowolnic uruchomienie na n sekund - abys mógl/ sie pol/aczyc z procesem za pomoca debugera, ustawic - jakiekolwiek pul/apki i kontynuowac proces uruchamiania. - - postgres moze byc uruchamiany z opcjami -s, -A i -t, które moga byc - bardzo przydatne przy debuggowaniu i ocenie wydajnosci. - - Mozesz takze skompilowac z profilingiem aby zobaczyc jakie funkcje ile - czasu wykonuja sie. Pliki profilowane dla backendu zostana umieszczone - w katalogu pgsql/data/base/dbname. Pliki profilu klienta zostana - umieszczone w biezacym katalogu klienta. Linux wymaga aby kompilowac z - opcja -DLINUX_PROFILE aby profilowanie odbywal/o sie poprawnie. - - 3.8) Skad sie bierze komunikat: "Sorry, too many clients" podczas próby - pol/aczenia sie z baza danych? - - Musisz zwiekszyc limit ilosci jednoczesnych procesów bacekendu dla - procesu postmaster'a. - - Domyslny limit to 32 procesy. Mozesz go zwiekszyc przez restart - postmaster z odpowiednia wartoscia ustawiana opcje -N w pliku - postgresql.conf. - - Wez pod uwage, ze jesli zwiekszysz wartosc podana w opcji -N na wiecej - niz 32 musisz takze zwiekszyc wartosc w opcji -B ponad jej domyslna - wartosc 64; wartosc -B musi byc co najmniej dwa razy wieksza od - wartosci podanej w opcji -N, a prawdopodobnie powinna byc w - rzeczywistosci jeszcze wieksza dla optymalnej wydajnosci. Dla duzej - liczby procesów backendu na pewno zauwazysz, ze trzeba zwiekszyc rózne - parametry jadra Unixa. Rzeczy, które pownienes sprawdzic to maksymalna - liczba bloków pamieci dzielonej, SHMMAX; maksymalna liczba semaforów, - SEMMNS oraz SEMMNI; maksymalna liczba procesów, NPROC; maksymalna - liczba procesów na jednego uzytkownika, MAXUPRC; i maksymalna liczba - otwartych plików, NFILE oraz NINODE. Powód dla którego PostgreSQL ma - limit na maksymalna liczbe procesów backendu to obawa o wyczerpanie - zasobów systemu. - - W wersjach PostgreSQL wczesniejszych niz 6.5, maksymalna liczba - backendów byl/a ustawiona na 64, a zmiana tej wartosci wymaga - rekompliacji po zmianie stal/ej MaxBackendId w pliku - include/storage/sinvaladt.h. - - 3.9) Co to sa za pliki typu: pg_sorttempNNN.NN, które znajduja sie w - katalogu z plikami bazy danych? - - Sa to tymczasowe pliki utworzone przez executor. Dla przykl/adu, jesli - jakas operacja sortowania jest wymagana do wykonania ORDER BY, a samo - sortowanie wymaga wiecej miejsca niz paratmetr backendu -S ustawil/ do - wykorzystania, wtedy tymczasowe pliki sa uzywane do przechowywania - tych danych. - - Pliki tymczasowe powinny byc usuniete automatycznie, ale mogl/o sie to - nie stac jesli proces backendu w miedzyczasie nie zakonczyl/ sie - poprawnie podczas operacji sortowania. Jesli w danym momencie nie - dzial/aja zadne procesy backendów mozesz spokojnie usunac pliki - pg_tempNNN.NN. - _________________________________________________________________ - - Pytania dotyczace uzywania - - 4.1) Jaka jest róznica pomiedzy kursorami binarnymi (binary cursors) i - zwykl/ymi kursorami (normal cursors)? - - Zobacz w manualu opis polecenia DECLARE. - - 4.2) Jak moge pobrac za pomoca SELECT jedynie kilka pierwszych wyników - zapytania? - - Zobacz w manualu opis polecenia FETCH lub uzyj polecenia SELECT ... - LIMIT.... - - Nawet jesli chesz pobrac kilka pierwszych rzedów z wyniku zapytania, - cal/e zapytanie musi zostac wykonane. Byc moze powinienes skorzystac z - polecenia ORDER BY. Jesli istnieje indeks który odpowiada polom - okreslonym przez ORDER BY, PostgreSQL moze wykorzystac jedynie kilka - pierwszych rzedów, byc moze bedzie koniecznosc wykonania zapytania do - momentu az zostana znalezione pozadane wyniki. - - 4.3) Jak moge uzyskac liste wszystkich tabel czy innych rzeczy pod psql? - - Mozesz sprawdzic zawartosc zródel/ psql, a konkretnie plik - pgsql/src/bin/psql/describe.c. Zawiera on polecenia SQL które generuja - wyniki komend z backslashem. Mozesz takze uruchomic psql z opcja -E - wtedy po wykonaniu polecenia z backslashem wyswietlane bedzie - zapytanie, które w rzeczywistosci jest wykonywane. - - 4.4) Jak usunac kolumne z tabeli? - - Nie mamy zaimplementowanego ALTER TABLE DROP COLUMN, ale mozesz zrobic - tak: - SELECT ... -- wybierz zawartosc wszystkich kolumn poza ta jedna której chc -esz sie pozbyc - INTO TABLE new_table - FROM old_table; - DROP TABLE old_table; - ALTER TABLE new_table RENAME TO old_table; - - 4.5) Jaki jest maksymalny rozmiar dla rzedu, tabeli i bazy danych? - - Oto wszystkie ograniczenia: - Maksymalny rozmiar dla bazdy danych? nieograniczony ( istnieja bazy dan -ych o wielkosci 500 GB databases ) - Maksymalny rozmiar dla tabeli? 16 TB - Maksymalny rozmiar dla rzedu? nieograniczony w 7.1 i pózniejszyc -h - Maksymalny rozmiar pola? 1 GB w 7.1 and later - Maksymalna liczba rzedów w tabeli? nieograniczona - Maksymalna liczba kolumn w tabeli? 250-1600 w zalezonosci od typów kolum -n - Makasymalna liczba indeksów na tabeli? nieograniczona - - Oczywiscie "nieograniczony" nie jest prawda tak do konca, istnieja - ograniczenia wynikajace z dostepnego miejsca na dysku, pamieci/swapa. - Kiedy wielkosci te beda bardzo duze moze odbic sie to na wydajnosci. - - Maksymalny rozmiar tabeli, czyli 16 TB nie wymaga od systemu - operacyjnego wsparcia dla duzych plików. Duze tabele sa przechowywane - jako pliki o rozmiarze 1 GB, wiec ograniczenia co do wielkosci plików - narzucone przez system plików nie sa istotne. - - Masymalny rozmiar tabeli i maksymalna liczba kolumn moze byc - zwiekszona jesli zwiekszymy domyslny rozmiar bloku (block size) do - 32k. - - 4.6) Jak duzo miejsca w bazie danych jest konieczne aby przechowywac dane - ze zwyczajnego pliku tekstowego? - - Baza danych PostgreSQL moze potrzebowac do pieciu razy wiecej miejsca - na przechowywanie danych z plików tekstowych niz ich objetosc. - - Jako przykl/ad mozemy rozwazyc plik skl/adajacy sie z 100,000 linii - zbudowanych z liczby cal/kowitej oraz opisu tekstowego w kazdej. - Zal/ózmy, ze srednio kazdy l/ancuch tekstu w linii zajmuje 20 bajtów. - Cal/y plik powinien zajmowac ok. 2.8 MB. Rozmiar pliku bazy danych w - PostgreSQL zawierajacego te dane mozna oszacowac na okol/o 6.4MB: - 36 bajtów: nagl/ówek kazdego rzedu w przyblizeniu) - 24 bajty: jedno pole int i jedno pole typu text - + 4 bajty: wkaznik na stronie do krotki - -------------------------------------------------- - 64 bajty w jednym rzedzie - - Strona danych w PostgreSQL zajmuje 8192 bajtów (8 KB), wiec: - - 8192 bajtów na strone - --------------------- = 128 rzedów na jedna strone w bazie (zaokraglone w - dól/) - 64 bajtów na rzad - - 100000 rzedów danych - ----------------------- = 782 stron w bazie danych (zaokraglone w góre) - 128 rzedów na strone - -782 stron w bazie * 8192 bajtów na strone = 6,406,144 bajtów (6.4 MB) - - Indeksy nie powoduja duzego narzutu na zajmowane miejsce, ale - zawieraja pewne dane, wiec w pewnych przypadkach moga byc cal/kiem - duze. - - 4.7) Jak moge sprawdzic jakie tabele, klucze, bazy danych i uzytkownicy sa - utworzeni? - - psql ma cal/kiem duza ilosc polecen z backslashem aby wydobyc takie - informacje. Wprowadz \? aby zobaczyc ich spis. Istnieja takze tablice - systemowe rozpoczynajace sie od pg_, zawierajace interesujace Ciebie - informacje. Wykonanie psql -l pokaze spis wszystkich baz danych. - - Obejrzyj takze plik pgsql/src/tutorial/syscat.source. Zawiera on wiele - z zapytan typu SELECT, które sa potrzebne aby wydobyc informacje z - tablic systemowych. - - 4.8) Moje zapytania sa wolne lub nie uzywaja kluczy. Dlaczego? - - Indeksy nie sa uzywane automatycznie przez kazde z zapytan. Ideksy sa - uzywane jedynie gdy tabela jest odpowiedniego rozmiaru, wiekszego niz - wymagany minimalny, a zapytanie wybiera jedynie mal/y procent - zawartosci tabeli. Wynika to z tego, ze losowy dostep do dysku - powodowany przez ideksowane poszukiwanie jest czasami wolniejsze niz - poszukiwanie sekwencyjne bez uzycia kluczy. - - Zeby zdecydowac czy indeks powinien byc uzywany, PostgreSQL musi miec - statystyki dotyczace danej tabeli. Sa one gromadzone przez uzycie - polecenia VACUUM ANALYZE, lub poprostu ANALYZE. uzywajac statystyk, - optymalizator wie ile rzedów jest w tabeli i moze lepiej okreslic czy - indeksy powinny byc uzyte. Statystyki moga byc takze pomocne w - okresleniu najlepszej kolejnosci wykonania zl/aczenia (join) i jego - sposobu. Gromadzenie statystyk powinno sie odbywac w okreslonych - interwal/ach czasu poniewaz dane w tabelach zmieniaja sie. - - Indeksy nie sa zazwyczaj uzywane przez ORDER BY lub przy wykonywaniu - zl/aczen (join). Sekwencyjne przeszukiwanie po którym nastepuje - sortowanie jest zazwyczaj szybsze nie wyszukiwanie za pomoca indeksu - na duzej tabeli. - Jakkolwiek LIMIT w pol/aczeniu z ORDER BY czesto bedzie wykorzystywal/ - indeksów poniewaz jedynie mal/a czesc z tabeli jest zwracana. - - Kiedy uzywa sie operatorów dopasujacych takich jak LIKE lub ~, indeksy - beda uzywane jedynie jesli poczatek wyszukiwania jest oparty na - poczatku l/ancucha tekstu. Dlatego, aby uzywac indeksów, dopasowania - operatorem LIKE nie moga sie zaczynac %, a dopasowania operatorem ~ - (dopasowania regularne) musza sie zaczynac znakiem specjalnym ^. - - 4.9) Jak moge sprawdzic w jakis sposób "query optimizer" wykonuje moje - zapytanie? - - Zobacz manual dla polecenia EXPLAIN. - - 4.10) Co to jest "R-tree index"? - - Indeks R-tree jest uzywany do indeksowania danych przestrzennych. - Indeks hasuujacy nie nadaje sie do wyszukiwania odlegl/osci. Natomiast - indeks typu B-tree moze wyszukiwac odleglosci jedynie w - jednowymiarowych przestrzeniach. R-tree indeks radzi sobie z - przestrzeniami wielo-wymiarowymi. Dla przykl/adu, jesli zostanie - zal/ozony indeks typu R-tree na polu typu point, system moze bardziej - wydajnie odpowiadac na zapytania typu "select all points within a - bounding rectangle." - - Zródl/owym dokumentem opisujacym oryginalnie projektowanie R-tree - indeksów jest: - - Guttman, A. "R-trees: A Dynamic Index Structure for Spatial - Searching." Proceedings of the 1984 ACM SIGMOD Int'l Conf on Mgmt of - Data, 45-57. - - Ten dokument mozesz znalezc takze w pracy Stonebraker'a "Readings in - Database Systems". - - Wbudowane indeksy R-trees radza sobie w wielobokami i boxes. - Teoretycznie, indeksy R-tree moga byc rozszerzone o mozliwosci - indeksowania w wiecej wymiarowych przestrzeniach. W praktyce, - rozbudowa indeksów R-tree wymaga troche pracy, a w tej chwili nie - dysponujemy jakakolwiek dokumentacja jak to zrobic. - - 4.11) Co to jest "Genetic Query Optimizer"? - - Modul/ GEQO ma za zadanie przyspieszenie optymalizacji zapytan l/aczac - wiele tabel za pomoca algorytmów genetycznych (Genetic Algorithm - (GA)). Pozwala na uzywanie duzych zapytan l/aczacych tabele (join - queries) bez wykorzystywania zasobozernego wyszukiwania. - - 4.12) Jak moge uzywac wyrazen regularnych w zapytaniach i zapytan - case-insensitive w wyrazeniach regularnych? jak korzystac z indeksów dla - zapytan case-insensitive? - - Operator ~ moze byc wykorzystywany do wyszukiwania za pomoca wyrazen - regularnych, a ~* do wyszukiwania case-insensitive z wyrazeniami - regularnymi. Wariant case-insensitive dla LIKE zostal/ nazwany ILIKE i - jest dostepny w PostgreSQL 7.1 i pózniejszych wersjach. - - Porównania case-insensitive sa zazwyczaj wykonywane w nastepujacy - sposób: - SELECT * - FROM tab - WHERE lower(col) = 'abc' - - W tym wypadku standardowe indeksy nie beda uzywane. Mozesz utworzyc - indeks funkcyjny, poprzez: - CREATE INDEX tabindex on tab (lower(col)); - - 4.13) Jak sprawdzic w zapytaniu czy pole ma wartosc NULL? - - Mozesz to sprawdzic, testujac wartosc kolumny warunkiem IS NULL albo - IS NOT NULL. - - 4.14) Jaka jest róznica pomiedzy róznymi typami tekstowymi (character - types)? - -Type Nazwa wewnetrzna Uwagi --------------------------------------------------- -"char" char 1 znak -CHAR(#) bpchar wypel/niane pustymi znakami do podanej dl/ug -osci -VARCHAR(#) varchar rozmiar okresla maksymalna dl/ugosc, nie ma -tutaj wypel/niania -TEXT text bez limitu na dl/ugosc l/ancucha -BYTEA bytea zmiennej dl/ugosci tablica bajtów (null-byte - safe) - - Jesli bedziesz przegladac katalogi systemowe lub komunikaty o bl/edach - czesto spotkasz sie z podanymi powyzej nazwami wewnetrznymi. - - Ostatnie cztery typy powyzej to tzw typy "varlena" (np. pierwsze - cztery bajty na dysku to dl/ugosc, po których jest data). Dlatego - faktyczna dl/ugosc takiego l/ancucha jest troche wieksza niz - zadeklarowany rozmiar. Te typy takze podlegaja kompresji lub moga byc - przechowywane out-of-line jako TOAST, wiec faktyczne zuzycie miejsca - na dysku moze byc mniejsze niz oczekiwane. - - CHAR() jast najlepszym typem do przechowywania l/ancuchów o tej samej - dl/ugosci. VARCHAR() jest najodpowiedniejszy do przechowywania - l/ancuchów o róznej dl/ugosci ale okresla on maksymalna jego dl/ugosc. - TEXT jest najlepszy dla l/ancuchów o dowolnej dl/ugosci, nie - przekraczajacej 1GB. BYTEA sl/uzy do przechowywania danych binarnych, - w szczególnosci dla danych zawierajacych NULL bajty. - - 4.15.1) Jak moge utworzyc pole które samo zwieksza swoja wartosc? - - PostgreSQL ma zaimplementowany typ SERIAL. Automatycznie tworzy - sekwencje i indeks na tej kolumnie. Dla przykladu: - CREATE TABLE person ( - id SERIAL, - name TEXT - ); - - zostanie automatycznie prztl/umaczone na: - CREATE SEQUENCE person_id_seq; - CREATE TABLE person ( - id INT4 NOT NULL DEFAULT nextval('person_id_seq'), - name TEXT - ); - CREATE UNIQUE INDEX person_id_key ON person ( id ); - - Wiecej informacji o sekwencjach znajdziesz w manualu o - create_sequence. Mozesz takze uzyc pola OID jako unikalnej wartosci - dla kazdego rzedu danych. Jesli bedziesz potrzebowal/ z backupowac - dane robiac dump bazy i odtworzyc ja, musisz uzyc pg_dump z opcja -o - lub polecenia COPY WITH OIDS aby zachowac OIDy. - - 4.15.2) Jak pobrac wartosc pola typu SERIAL po wykonaniu insert'u? - - Jednym z podejsc jest pobranie kolejnej wartosci typu SERIAL z - sekwencji za pomoca funkcji nextval() zanim zostanie wstawiona, a - pózniej nalezy jej uzyc. Uzywajac przykl/adu z tabeli z punktu 4.15.1, - moze to wygladac w Perlu na przykl/ad w ten sposób: - new_id = output of "SELECT nextval('person_id_seq')" - INSERT INTO person (id, name) VALUES (new_id, 'Blaise Pascal'); - - Bedziesz mial/ wtedy ta wartosc przechowana w zmiennej new_id do - uzytku w innych zapytaniach (np. jako klucz obcy do tabeli person). - Warto zwrócic uwage, ze nazwa automatycznie utworzonej sekwencji - SEQUENCE bedzie nastepujaca: __seq, gdzie - tabela i kolumnatypuserial sa nazwami Twojej tabeli i Twojej kolumny - typu SERIAL. - - Inne rozwiazanie to uzycie funkcji currval() na pola typu SERIAL po - dodaniu nowej wartosci do rzedu zawierajacego kolumne typu SERIAL z - wstawiona domyslnie wartoscia, np. - INSERT INTO person (name) VALUES ('Blaise Pascal'); - new_id = output of "SELECT currval('person_id_seq')"; - - Ostatecznie mozesz uzyc OID zwracanej po wykonaniu INSERT, chociaz to - jest najmniej przenosne rozwiazanie. W Perlu, wykorzystujac biblioteke - DBI z modul/em Edmunda Mergla DBD::Pg, oid jest dostepny poprzez - $sth->{pg_oid_status} po wykonaniu $sth->execute(). - - 4.15.3) Czy uzycie currval() i nextval() nie doprowadzi do race condition z - innymi uzytkownikami? - - Nie. currval() zwraca biezaca wartosc przypisana przez Twój backend, a - nie przez wszystkich uzytkowników. - - 4.15.4) Dlaczego numery sekwencji nie sa ponownie uzywane przy przerwaniu - transakcji? Skad sie biora luki w numerowaniu kolumny tabeli - sekwancjami/SERIALem? - - Aby poprawic zbieznosc (concurrency), wartosci sekwencji sa podawane - dzial/ajacym transakcjom kiedy tego potrzebuja i nie sa blokowane - dopóki transakcja sie nie zakonczy. To spowoduje przerwy w numerowaniu - z przerwanych transakcji. - - 4.16) Co to jest OID? Co to jest TID? - - OID sa PostgreSQL'owym rozwiazaniem problemu unikalnych numerów - rzedów. Kazdy rzad tworzony przez PostgreSQL otrzymuje unikalny OID. - Wszystkie OIDy generowane podczas procesu uruchamianego przez skrypt - initdb maja mniejsza wartosc niz 16384 (na podstawie pliku - backend/access/transam.h). Wszystkie OIDy tworzone przez uzytkownika - sa równe lub wieksze podanej wczesniej wartosci. Domyslnie wszystkie - OIDy sa unikalne nie tylko w pojedynczej tabeli czy bazie danych ale w - cal/ej instalacji PostgreSQL. - - PostgreSQL uzywa OIDów w swoim wewnetrznym systemie tabel, aby mozna - byl/o je l/aczyc. Te OIDy moga byc uzywane aby identyfikowac rzedy w - tabelach i wykorzystywac je w zl/aczeniach tych tabel. Zaleca sie abys - uzywal/ typu OID aby przechowywac wartosci OID. Mozesz utworzyc indeks - na polu OID aby dostep do niego byl/ szybszy. - - OID sa przypisane do wszystkich rzedów z jednego gl/ównego miejsca i - uzywane sa przez wszystkie bazy danych. Jesli chcial/bys zmienic OID - na cos innego, lub jesli chcial/bys zrobic kopie tabeli, z orginalnymi - OIDami nie ma zadnego przeciwwskazania abys to zrobil/: - CREATE TABLE new_table(old_oid oid, mycol int); - SELECT old_oid, mycol INTO new FROM old; - COPY new TO '/tmp/pgtable'; - DELETE FROM new; - COPY new WITH OIDS FROM '/tmp/pgtable'; - - OIDy sa przechowywane jako cztero-bajtowe liczby cal/kowite i skoncza - sie po osiagnieciu czterech miliardów. Nikt jak dotad nie zgl/osil/ - aby cos takiego sie stalo, ale mamy zamiar pozbyc sie tego - ograniczenia zanim ktos to zgl/osi. - - TID sa uzywane aby zidentyfikowac konkretne rzedy z blokami i - wartoscia ofsetów. TIDy zmieniaja sie wraz ze zmianami rzedów. Sa - uzywane przez indeksy, aby wskazywac do fizycznych rzedów. - - 4.17) Jakie jest znaczenie niektórych terminów w PostgreSQL? - - W czesci kodu zródl/owego i starszej dokumentacji uzywamy terminów, - które maja bardziej ogólne znaczenie. Oto niektóre z nich: - * table, relation, class - * row, record, tuple - * column, field, attribute - * retrieve, select - * replace, update - * append, insert - * OID, serial value - * portal, cursor - * range variable, table name, table alias - - Liste terminów zwiazanych z bazami danych mozesz znalezc pod tym - adresem:http://www.comptechnews.com/~reaster/dbdesign.html - - 4.18) Skad bierze sie ten bl/ad "ERROR: Memory exhausted in - AllocSetAlloc()"? - - Jesli uzywasz wersji starszej niz 7.1, upgrade moze rozwiazac ten - problem. Jest takze mozliwe, ze po prostu wyczerpal/a Ci sie pamiec - wirtualna (virtual memory) w systemie lub Twój kernel ma zbyt nisko - ustawione limity dla pewnych zasobów. Spróbuj wykonac nastepujace - polecenia zanim uruchomisz postmaster'a: - ulimit -d 262144 - limit datasize 256m - - W zaleznosci od shell'a jakiego uzywasz jedno z tych polecen moze nie - zadzial/ac, ale to ustawienie pozwoli ustawic segment danych dla - procesu znacznie wiekszy i byc moze pozwoli wykonac zapytanie. To - polecenie zadzial/a dla biezacego procesu oraz wszytkich podprocesów - utworzonych po wykonaniu polecenia. Jesli ten problem wystepuje z - klientem SQL, poniewaz backend zwraca zbyt duzo danych, spróbuj - wykonac to polecenie przed uruchomieniem klienta. - - 4.19) Jak sprawdzic jakiej wersji PostgreSQL uzywam? - - W psql, wpisz select version(); - - 4.20) Dlaczego operacje, które wykonuje na duzych obiektach "large-object" - zwracaja komunikat: "invalid large obj descriptor"? - - Musisz uzyc BEGIN WORK i COMMIT przed i po uzyciu uchwytu do duzego - obiektu, tzn. musisz nimi otoczyc funkcje lo_open ... lo_close. - - Obecnie PostgreSQL uzywjac "rule" zamyka uchwyt do duzego obiektu przy - kazdym wywol/aniu "commit". Wiec pierwsze próba zrobienia czegokolwiek - z uchwytem spowoduje wypisanie: invalid large obj descriptor. Kod, - który do tej pory dzial/al/ (przynajmniej wiekszosc razy) bedzie teraz - generowal/ informacje o bl/edzie jesli nie bedziesz korzystal/ z - transakcji. - - Jesli uzywasz interfejsu klienta jak ODBC byc moze bedziesz musial/ - ustawic auto-commit off. - - 4.21) Jak stworzyc kolumne której domyslna wartoscia bedzie biezacy czas? - - Uzyj CURRENT_TIMESTAMP: -CREATE TABLE test (x int, modtime timestamp DEFAULT CURRENT_TIMESTAMP ); - - 4.22) Dlaczego zapytania uzywajace IN sa takie wolne? - - Obecnie l/aczymy podzapytania w outer queries poprzez sekwencyjne - przeszukiwanie wyników podzapytania dla kazdego rzedu z outer query. - Mozna to ominac zastepujac IN przez EXISTS: -SELECT * - FROM tab - WHERE col1 IN (SELECT col2 FROM TAB2) - - na: -SELECT * - FROM tab - WHERE EXISTS (SELECT col2 FROM TAB2 WHERE col1 = col2) - - Mamy zamiar poprawic to ograniczenie w przyszl/ych wydaniach. - - 4.23) Jak wykonac "outer join"? - - PostgreSQL 7.1 i pózniejsze wersje maja zaimplementowane outer join - wykorzystujac standardowa skl/adnie SQL. Ponizej dwa przykl/ady: - SELECT * - FROM t1 LEFT OUTER JOIN t2 ON (t1.col = t2.col); - - or - SELECT * - FROM t1 LEFT OUTER JOIN t2 USING (col); - - Te dwa identyczne zapytania l/acza kolumne t1.col z kolumna t2.col, - ale takze zwróca niepol/aczone rzedy w t1 (te które nie pasuja w t2). - RIGHT join dodal/by niepol/aczone rzedy z tabeli t2. FULL join - zwrócil/by rzedy plus dodatkowo wszystkie rzedy z tabel t1 i t2. - Sl/owo OUTER jest opcjonalne i jest dodawane domyslnie przy LEFT, - RIGHT, i FULL join'ach. Zwykl/e join'y sa nazywane INNER joins. - - W poprzednich wersjach "outer joins" moga byc zasymulowane poprzez - uzycie slowa kluczowego UNION i NOT IN. Dla przykl/adu, l/aczac tabele - tab1 i tab2, nastepujace zapytanie wykonuje outer join: - SELECT tab1.col1, tab2.col2 - FROM tab1, tab2 - WHERE tab1.col1 = tab2.col1 - UNION ALL - SELECT tab1.col1, NULL - FROM tab1 - WHERE tab1.col1 NOT IN (SELECT tab2.col1 FROM tab2) - ORDER BY col1 - - 4.24) Jak wykonywac zapytanie uzywajace kilku baz danych jednoczesnie? - - Nie ma takiej mozliwosci aby w zapytaniu odpytawac inna baze danych - poza biezaca. Poniewaz PostgreSQL l/aduje specyficzne dla bazy danych - katalogi systemowe, nie jest do konca jasne jak zapytanie pomiedzy - róznymi bazami danych powinno sie zachowywac. - - Oczywiscie klient moze l/aczyc sie z róznymi bazami danych i l/aczyc - informacje w ten sposób uzyskana. - - 4.25) Jak zwrócic w funkcji wiele rzedów lub kolumn? - - Mozesz zwracac zbiory z funkcji PL/pgSQL uzywajac refcursors. Zobacz - http://developer.postgresql.org/docs/postgres/plpgsql-cursors.html, - sekcje 23.7.3.3. - - Rozwijanie PostgreSQL - - 5.1) Napisal/em wl/asna funkcje. Kiedy uzyje jej w psql, program zrzuca - pamiec (dump core)? - - Problem moze byc spowodowany przez bardzo wiele rzeczy. Spróbuj - najpierw przetestowac Twoja funkcje w samodzielnie dzial/ajacym - programie. - - 5.2) Jak moge dodac/zgl/osic nowe typy czy funkcje do PostgreSQL? - - Wyslij Twoje propozycje na liste mailowa pgsql-hackers, wtedy - prawdopodobnie Twój kod znajdzie sie w katalogu contrib/. - - 5.3) Jak napisac funkcje C zwracajaca krotke (tuple)? - - To wymaga wysil/ku tak olbrzymiego, ze nawet autorzy nigdy tego nie - prubowali, chociaz z zalozen wynika, ze jest to mozliwe. - - 5.4) Zmienil/em plik zródl/owy. Dlaczego po rekompilacji nie widac zmiany? - - Pliki Makefiles nie maja dorzuconych odpowiednich zaleznosci dla - plików nagl/ówkowych (include files). Wykonaj najpierw make clean, a - nastepnie ponownie make. Jesli uzywasz GCC mozesz uzyc opcji - --enable-depend przy wykonywaniu configure aby diff --git a/doc/FAQ_russian b/doc/FAQ_russian deleted file mode 100644 index 45d2ea6025..0000000000 --- a/doc/FAQ_russian +++ /dev/null @@ -1,1161 +0,0 @@ - - ïÔ×ÅÔÙ ÎÁ ÞÁÓÔÏ ÚÁÄÁ×ÁÅÍÙÅ ×ÏÐÒÏÓÙ ÐÏ PostgreSQL - - äÁÔÁ ÐÏÓÌÅÄÎÅÇÏ ÏÂÎÏ×ÌÅÎÉÑ: þÅÔ×ÅÒÇ 11 éÀÎÑ 06:36:10 EDT 2002 - - áÎÇÌÉÊÓËÉÊ ×ÁÒÉÁÎÔ ÓÏÐÒÏ×ÏÖÄÁÅÔ: âÒÀÓ íÏÍØÑÎ (Bruce Momjian) - (pgman@candle.pha.pa.us) - - ðÅÒÅ×ÅÌ ÎÁ ÒÕÓÓËÉÊ: ÷ÉËÔÏÒ ÷ÉÓÌÏÂÏËÏ× (victor_v@permonline.ru) - - óÁÍÕÀ Ó×ÅÖÕÀ ÁÎÇÌÉÊÓËÕÀ ×ÅÒÓÉÀ ÄÏËÕÍÅÎÔÁ ÍÏÖÎÏ ÎÁÊÔÉ ÎÁ - http://www.PostgreSQL.org/docs/faq-english.html. - - ïÔ×ÅÔÙ ÎÁ ×ÏÐÒÏÓÙ ÓÐÅÃÉÆÉÞÎÙÅ ÄÌÑ ËÏÎËÒÅÔÎÙÈ ÐÌÁÔÆÏÒÍ ÍÏÖÎÏ ÎÁÊÔÉ ÎÁ - http://www.PostgreSQL.org/users-lounge/docs/faq.html. - _________________________________________________________________ - - ïÂÝÉÅ ×ÏÐÒÏÓÙ - - 1.1) þÔÏ ÔÁËÏÅ PostgreSQL? ëÁË ÐÒÏÉÚÎÏÓÉÔÓÑ ÜÔÏ ÎÁÚ×ÁÎÉÅ? - 1.2) ëÁËÏ×Ù Á×ÔÏÒÓËÉÅ ÐÒÁ×Á ÎÁ PostgreSQL? - 1.3) îÁ ËÁËÉÈ Unix ÐÌÁÔÆÏÒÍÁÈ ÒÁÂÏÔÁÅÔ PostgreSQL? - 1.4) óÕÝÅÓÔ×ÕÀÔ ÌÉ ×ÅÒÓÉÉ ÐÏÒÔÉÒÏ×ÁÎÎÙÅ ÎÅ ÎÁ Unix ÓÉÓÔÅÍÙ? - 1.5) çÄÅ ÍÏÖÎÏ ×ÚÑÔØ PostgreSQL? - 1.6) çÄÅ ÐÏÌÕÞÉÔØ ÐÏÄÄÅÒÖËÕ? - 1.7) ëÁËÁÑ ÐÏÓÌÅÄÎÑÑ ×ÅÒÓÉÑ? - 1.8) ëÁËÁÑ ÄÏËÕÍÅÎÔÁÃÉÑ ÉÍÅÅÔÓÑ × ÎÁÌÉÞÉÉ? - 1.9) ëÁË ÎÁÊÔÉ ÉÎÆÏÒÍÁÃÉÀ Ï ÉÚ×ÅÓÔÎÙÈ ÏÛÉÂËÁÈ ÉÌÉ ÏÔÓÕÔÓÔ×ÕÀÝÉÈ - ×ÏÚÍÏÖÎÏÓÔÑÈ? - 1.10) ëÁË ÎÁÕÞÉÔØÓÑ SQL? - 1.11) òÅÛÅÎÁ ÌÉ × PostgreSQL ÐÒÏÂÌÅÍÁ 2000-ÇÏ ÇÏÄÁ (Y2K)? - 1.12) ëÁË ÐÒÉÓÏÅÄÉÎÉÔÓÑ Ë ËÏÍÁÎÄÅ ÒÁÚÒÁÂÏÔÞÉËÏ×? - 1.13) ëÁË ÏÔÒÁ×ÉÔØ ÓÏÏÂÝÅÎÉÅ Ï ÏÛÉÂËÅ? - 1.14) ëÁË ÓÒÁ×ÎÉ×ÁÔØ PostgreSQL Ó ÄÒÕÇÉÍÉ óõâä? - 1.15) ëÁË ÏËÁÚÁÔØ ÆÉÎÁÎÓÏ×ÕÀ ÐÏÍÏÝØ PostgreSQL? - - ÷ÏÐÒÏÓÙ ÐÏÌØÚÏ×ÁÔÅÌÅÊ ÐÏ ËÌÉÅÎÔÓËÏÊ ÞÁÓÔÉ - - 2.1) óÕÝÅÓÔ×ÕÀÔ ÌÉ ODBC ÄÒÁÊ×ÅÒÁ ÄÌÑ PostgreSQL? - 2.2) ëÁËÉÅ ÉÎÓÔÒÕÍÅÎÔÙ ÓÕÝÅÓÔ×ÕÀÔ ÄÌÑ ÉÓÐÏÌØÚÏ×ÁÎÉÑ PostgreSQL ÞÅÒÅÚ - Web? - 2.3) åÓÔØ ÌÉ Õ PostgreSQL ÇÒÁÆÉÞÅÓËÉÊ ÉÎÔÅÒÆÅÊÓ ÐÏÌØÚÏ×ÁÔÅÌÑ? - çÅÎÅÒÁÔÏÒ ÏÔÞÅÔÏ×? ÷ÓÔÒÏÅÎÎÙÊ ÉÎÔÅÒÆÅÊÓ ÄÌÑ ÑÚÙËÁ ÚÁÐÒÏÓÏ×? - 2.4) ëÁËÉÅ ÑÚÙËÉ ÍÏÇÕÔ ×ÚÁÉÍÏÄÅÊÓÔ×Ï×ÁÔØ Ó PostgreSQL? - - ÷ÏÐÒÏÓÙ ÁÄÍÉÎÉÓÔÒÉÒÏ×ÁÎÉÑ - - 3.1) ëÁË ÍÎÅ ÕÓÔÁÎÏ×ÉÔØ PostgreSQL × ÍÅÓÔÏ ÏÔÌÉÞÎÏÅ ÏÔ - /usr/local/pgsql? - 3.2) ëÏÇÄÁ Ñ ÚÁÐÕÓËÁÀ postmaster, Ñ ÐÏÌÕÞÁÀ ÓÏÏÂÝÅÎÉÅ Bad System Call - ÉÌÉ ÓÏÏÂÝÅÎÉÅ core dumped. ðÏÞÅÍÕ? - 3.3) ëÏÇÄÁ Ñ ÐÙÔÁÀÓØ ÚÁÐÕÓÔÉÔØ postmaster, Ñ ÐÏÌÕÞÁÀ ÏÛÉÂËÉ - IpcMemoryCreate. ðÏÞÅÍÕ? - 3.4) ëÏÇÄÁ Ñ ÐÙÔÁÀÓØ ÚÁÐÕÓÔÉÔØ postmaster, Ñ ÐÏÌÕÞÁÀ ÏÛÉÂËÉ - IpcSemaphoreCreate. ðÏÞÅÍÕ? - 3.5) ëÁË ÍÎÅ ÕÐÒÁ×ÌÑÔØ ÓÏÅÄÉÎÅÎÉÑÍÉ Ó ÄÒÕÇÉÈ ËÏÍÐØÀÔÅÒÏ×? - 3.6) ëÁËÉÅ ÎÁÓÔÒÏÊËÉ ÍÎÅ ÎÕÖÎÏ ÓÄÅÌÁÔØ ÄÌÑ ÕÌÕÞÛÅÎÉÑ - ÐÒÏÉÚ×ÏÄÉÔÅÌØÎÏÓÔÉ? - 3.7) ëÁËÉÅ ×ÏÚÍÏÖÎÏÓÔÉ ÄÌÑ ÏÔÌÁÄËÉ ÅÓÔØ × ÎÁÌÉÞÉÉ? - 3.8) ðÏÞÅÍÕ Ñ ÐÏÌÕÞÁÀ ÓÏÏÂÝÅÎÉÅ "Sorry, too many clients" ËÏÇÄÁ - ÐÙÔÁÀÓØ ÐÏÄËÌÀÞÉÔØÓÑ Ë ÂÁÚÅ? - 3.9) þÔÏ ÜÔÏ ÚÁ ÆÁÊÌÙ pg_sorttempNNN.NN × ÍÏÅÍ ËÁÔÁÌÏÇÅ Ó ÂÁÚÏÊ - ÄÁÎÎÙÈ? - - ÷ÏÐÒÏÓÙ ÜËÓÐÌÕÁÔÁÃÉÉ - - 4.1) ÷ ÞÅÍ ÏÔÌÉÞÉÅ ÍÅÖÄÕ ÂÉÎÁÒÎÙÍ É ÎÏÒÍÁÌØÎÙÍ ËÕÒÓÏÒÏÍ? - 4.2) ëÁË ×ÙÐÏÌÎÉÔØ SELECT ÔÏÌØËÏ ÄÌÑ ÎÅÓËÏÌØËÉÈ ÐÅÒ×ÙÈ ÓÔÒÏÞÅË - ÚÁÐÒÏÓÁ? - 4.3) ëÁË ÐÏÌÕÞÉÔØ ÓÐÉÓÏË ÔÁÂÌÉà ÉÌÉ ÄÒÕÇÉÈ ËÏÍÐÏÎÅÎÔÏ× × psql? - 4.4) ëÁË ÕÄÁÌÉÔØ ËÏÌÏÎËÕ ÉÚ ÔÁÂÌÉÃÙ? - 4.5) ëÁËÏ×Ù ÍÁËÓÉÍÁÌØÎÙÅ ÒÁÚÍÅÒÙ ÄÌÑ ÚÁÐÉÓÅÊ, ÔÁÂÌÉÃ É ÂÁÚÙ ÄÁÎÎÙÈ? - 4.6) ëÁË ÍÎÏÇÏ ÄÉÓËÏ×ÏÇÏ ÐÒÏÓÔÒÁÎÓÔ×Á × ÂÁÚÅ ÄÁÎÎÙÈ ÎÕÖÎÏ ÄÌÑ - ÓÏÈÒÁÎÅÎÉÑ ÄÁÎÎÙÈ ÉÚ ÏÂÙÞÎÏÇÏ ÔÅËÓÔÏ×ÏÇÏ ÆÁÊÌÁ? - 4.7) ëÁË ÍÎÅ ÕÂÅÄÉÔØÓÑ, ÞÔÏ ÓÕÝÅÓÔ×ÕÀÔ ÎÕÖÎÙÅ ÍÎÅ ÔÁÂÌÉÃÙ, ÉÎÄÅËÓÙ, - ÂÁÚÙ ÄÁÎÎÙÈ É ÐÏÌØÚÏ×ÁÔÅÌÉ? - 4.8) õ ÍÅÎÑ ÍÅÄÌÅÎÎÏ ÒÁÂÏÔÁÀÔ ÚÁÐÒÏÓÙ ÉÌÉ ÎÅ ÐÒÏÉÓÈÏÄÉÔ ÉÓÐÏÌØÚÏ×ÁÎÉÑ - ÉÎÄÅËÓÏ×. ðÏÞÅÍÕ? - 4.9) ëÁË ÐÏÓÍÏÔÒÅÔØ ÎÁ ÔÏ, ËÁË ÏÐÔÉÍÉÚÁÔÏÒ ×ÙÐÏÌÎÑÅÔ ÍÏÊ ÚÁÐÒÏÓ? - 4.10) þÔÏ ÔÁËÏÅ R-tree ÉÎÄÅËÓ? - 4.11) þÔÏ ÔÁËÏÅ Genetic Query Optimizer? - 4.12) ëÁË ÍÎÅ ×ÙÐÏÌÎÉÔØ ÐÏÉÓË ÒÅÇÕÌÑÒÎÏÇÏ ×ÙÒÁÖÅÎÉÑ É ÐÏÉÓË - ÎÅÚÁ×ÉÓÉÍÙÊ ÏÔ ÒÅÇÉÓÔÒÁ ÂÕË× ÐÏÉÓË ÒÅÇÕÌÑÒÎÏÇÏ ×ÙÒÁÖÅÎÉÑ? ëÁË ÍÎÅ - ÉÓÐÏÌØÚÏ×ÁÔØ ÉÎÄÅËÓ ÄÌÑ ÐÏÉÓËÁ ÎÅÚÁ×ÉÓÉÍÏÇÏ ÏÔ ÒÅÇÉÓÔÒÁ ÂÕË×? - 4.13) ëÁË Ñ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ, ÞÔÏ ÚÎÁÞÅÎÉÅ ÐÏÌÑ ÒÁ×ÎÏ NULL × ËÁËÏÍ-ÌÉÂÏ - ÚÁÐÒÏÓÅ? - 4.14) ëÁËÏ×Ù ÏÔÌÉÞÉÑ ÍÅÖÄÕ ÒÁÚÎÙÍÉ ÓÉÍ×ÏÌØÎÙÍÉ ÔÉÐÁÍÉ? - 4.15.1) ëÁË ÍÎÅ ÓÏÚÄÁÔØ ÐÏÌÅ serial/Ó-Á×ÔÏ-Õ×ÅÌÉÞÅÎÉÅÍ? - 4.15.2) ëÁË ÍÎÅ ÐÏÌÕÞÉÔØ ÚÎÁÞÅÎÉÅ ÐÒÉ ×ÓÔÁ×ËÅ SERIAL? - 4.15.3) îÅ ÍÏÖÅÔ ÌÉ ÐÏÌÕÞÉÔØÓÑ ÔÁË, ÞÔÏ ÉÓÐÏÌØÚÏ×ÁÎÉÅ currval() É - nextval() ÐÒÉ×ÅÄÅÔ Ë ÚÁÃÉËÌÉÒÏ×ÁÎÉÀ Ó ÄÒÕÇÉÍÉ ÐÏÌØÚÏ×ÁÔÅÌÑÍÉ? - 4.15.4) ðÏÞÅÍÕ ÞÉÓÌÁ ÉÚ ÍÏÅÊ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔÉ ÎÅ ÉÓÐÏÌØÚÕÀÔÓÑ ÓÎÏ×Á - ÐÒÉ ÏÔÍÅÎÅ ÔÒÁÎÚÁËÃÉÉ? ðÏÞÅÍÕ ÓÏÚÄÁÀÔÓÑ ÒÁÚÒÙ×Ù ÐÒÉ ÎÕÍÅÒÁÃÉÉ × - ËÏÌÏÎËÅ, ÇÄÅ Ñ ÉÓÐÏÌØÚÕÀ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ/SERIAL? - 4.16) þÔÏ ÔÁËÏÅ OID? þÔÏ ÔÁËÏÅ TID? - 4.17) þÔÏ ÏÚÎÁÞÁÀÔ ÎÅËÏÔÏÒÙÅ ÔÅÒÍÉÎÙ ÉÓÐÏÌØÚÕÅÍÙÅ × PostgreSQL? - 4.18) ðÏÞÅÍÕ Ñ ÐÏÌÕÞÁÀ ÏÛÉÂËÕ "ERROR: Memory exhausted in - AllocSetAlloc()"? - 4.19) ëÁË ÍÎÅ ÕÚÎÁÔØ, ËÁËÁÑ ×ÅÒÓÉÑ PostgreSQL ÚÁÐÕÝÅÎÁ? - 4.20) ðÏÞÅÍÕ ÐÒÉ ÒÁÂÏÔÅ Ó ÍÏÉÍ ÂÏÌØÛÉÍ ÏÂßÅËÔÏÍ Ñ ÐÏÌÕÞÁÀ ÏÛÉÂËÕ - "invalid large obj descriptor"? - 4.21) ëÁË ÍÎÅ ÓÏÚÄÁÔØ ËÏÌÏÎËÕ ËÏÔÏÒÁÑ ÐÏ ÕÍÏÌÞÁÎÉÀ ÂÕÄÅÔ ÓÏÄÅÒÖÁÔØ - ÔÅËÕÝÅÅ ×ÒÅÍÑ? - 4.22) ðÏÞÅÍÕ ÍÏÉ ÐÏÄÚÁÐÒÏÓÙ, ÉÓÐÏÌØÚÕÀÝÉÅ IN ÔÁË ÍÅÄÌÅÎÎÏ ÒÁÂÏÔÁÅÀÔ? - 4.23) ëÁË ×ÙÐÏÌÎÉÔØ ×ÎÅÛÎÅÅ Ó×ÑÚÙ×ÁÎÉÅ? - 4.24) ëÁË ×ÙÐÏÌÎÑÔØ ÚÁÐÒÏÓÙ, ÉÓÐÏÌØÚÕÀÝÉÅ ÎÅÓËÏÌØËÏ ÂÁÚ ÄÁÎÎÙÈ? - 4.25) ëÁË ÍÎÅ ×ÅÒÎÕÔØ ÉÚ ÆÕÎËÃÉÉ ÎÅÓËÏÌØËÏ ÚÁÐÉÓÅÊ? - 4.26) ðÏÞÅÍÕ Ñ ÎÅ ÍÏÇÕ ÎÁÄÅÖÎÏ ÓÏÚÄÁ×ÁÔØ/ÕÄÁÌÑÔØ ×ÒÅÍÅÎÎÙÅ ÔÁÂÌÉÃÙ × - ÆÕÎËÃÉÑÈ PL/PgSQL? - - òÁÓÛÉÒÅÎÉÑ PostgreSQL - - 5.1) ñ ÎÁÐÉÓÁÌ ÆÕÎËÃÉÀ ÏÐÒÅÄÅÌÑÅÍÕÀ ÐÏÌØÚÏ×ÁÔÅÌÅÍ. ëÏÇÄÁ Ñ ÚÁÐÕÓËÁÀ ÅÅ - × psql, ÐÏÞÅÍÕ Ñ ÐÏÌÕÞÁÀ dump core? - 5.2) ëÁË Ñ ÍÏÇÕ ×ÎÅÓÔÉ ÎÅËÏÔÏÒÙÅ ËÌÁÓÓÎÙÅ ÎÏ×ÙÅ ÔÉÐÙ É ÆÕÎËÃÉÉ × - PostgreSQL? - 5.3) ëÁË ÍÎÅ ÎÁÐÉÓÁÔØ C ÆÕÎËÃÉÀ, ×ÏÚ×ÒÁÝÁÀÝÕÀ ÚÁÐÉÓØ? - 5.4) ñ ÉÚÍÅÎÉÌ ÉÓÈÏÄÎÙÊ ÆÁÊÌ. ðÏÞÅÍÕ ÐÏÓÌÅ ÐÅÒÅËÏÍÐÉÌÑÃÉÉ Ñ ÎÅ ×ÉÖÕ - ÉÚÍÅÎÅÎÉÊ? - _________________________________________________________________ - - ïÂÝÉÅ ×ÏÐÒÏÓÙ - - 1.1) þÔÏ ÔÁËÏÅ PostgreSQL? - - PostgreSQL ÐÒÏÉÚÎÏÓÉÔÓÑ Post-Gres-Q-L (ðÏÓÔ-çÒÅÓ-ëØÀ-üÌ). - - PostgreSQL - ÜÔÏ ÒÁÓÛÉÒÅÎÉÅ óõâä POSTGRES, ÉÓÓÌÅÄÏ×ÁÔÅÌØÓËÉÊ ÐÒÏÔÏÔÉÐ - ÎÏ×ÏÇÏ ÐÏËÏÌÅÎÉÑ óõâä. PostgreSQL ÏÄÎÏ×ÒÅÍÅÎÎÏ ÓÏÈÒÁÎÑÅÔ ÍÏÝÎÕÀ ÍÏÄÅÌØ - ÄÁÎÎÙÈ É ÏÂÝÉÒÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÔÉÐÏ× POSTGRES, É ÚÁÍÅÝÁÅÔ ÑÚÙË ÚÁÐÒÏÓÏ× - PostQuel ÎÁ ÒÁÓÛÉÒÅÎÎÏÅ ÐÏÄÍÎÏÖÅÓÔ×Ï SQL. PostgreSQL - ÜÔÏ Ó×ÏÂÏÄÎÏÅ É - ÐÏÌÎÏÓÔØÀ ÏÔËÒÙÔÏÅ ÐÒÏÇÒÁÍÍÎÏÅ ÏÂÅÓÐÅÞÅÎÉÅ. - - òÁÚÒÁÂÏÔËÕ PostgreSQL ×ÙÐÏÌÎÑÅÔ ËÏÍÁÎÄÁ, Ó×ÑÚÁÎÎÁÑ ÞÅÒÅÚ Internet, ×ÓÅ - ÕÞÁÓÔÎÉËÉ ËÏÔÏÒÏÊ ÐÏÄÐÉÓÁÎÙ ÎÁ ÓÐÉÓÏË ÒÁÓÓÙÌËÉ ÒÁÚÒÁÂÏÔÞÉËÏ×. ÷ - ÎÁÓÔÏÑÝÅÅ ×ÒÅÍÑ, ÉÈ ËÏÏÒÄÉÎÁÔÏÒÏÍ Ñ×ÌÑÅÔÓÑ íÁÒË æÏÒÎÁÊ (Marc G. - Fournier) (scrappy@PostgreSQL.org). (óÍ. ÎÉÖÅ Ï ÔÏÍ, ËÁË ÐÏÄËÌÀÞÉÔØÓÑ - Ë ÒÁÚÒÁÂÏÔËÅ). üÔÁ ËÏÍÁÎÄÁ ÔÅÐÅÒØ ÏÔ×ÅÞÁÅÔ ÚÁ ×ÓÀ ÒÁÚÒÁÂÏÔËÕ - PostgreSQL. - - á×ÔÏÒÁÍÉ PostgreSQL 1.01 Ñ×ÌÑÀÔÓÑ üÎÄÒÀ à (Andrew Yu) É äÖÏÌÉ þÅÎ - (Jolly Chen). íÎÏÇÉÅ ÄÒÕÇÉÅ ×ÎÅÓÌÉ Ó×ÏÊ ×ËÌÁÄ × ÐÅÒÅÎÏÓ ÎÁ ÄÒÕÇÉÅ - ÐÌÁÔÆÏÒÍÙ, ÔÅÓÔÉÒÏ×ÁÎÉÅ, ÏÔÌÁÄËÕ É ÒÁÓÛÉÒÅÎÉÅ ÜÔÏÇÏ ËÏÄÁ. - ðÅÒ×ÏÎÁÞÁÌØÎÙÊ ËÏÄ Postgres, ÉÚ ËÏÔÏÒÏÇÏ ÐÏÑ×ÉÌÓÑ PostgreSQL, ÂÙÌ - ÉÔÏÇÏÍ ÕÓÉÌÉÊ ÍÎÏÇÉÈ ÁËÁÄÅÍÉÞÅÓËÉÈ ÓÔÕÄÅÎÔÏ×, ÎÅÁËÁÄÅÍÉÞÅÓËÉÈ - ÓÔÕÄÅÎÔÏ× É ÍÎÏÖÅÓÔ×Á ÒÁÚÎÙÈ ÐÒÏÇÒÁÍÍÉÓÔÏ×, ÒÁÂÏÔÁ×ÛÉÈ ÐÏÄ - ÒÕËÏ×ÏÄÓÔ×ÏÍ ÐÒÏÆÅÓÓÏÒÁ íÁÊËÌÁ óÔÏÕÎÂÒÅÊËÅÒÁ (Michael Stonebraker) × - ëÁÌÉÆÏÒÎÉÊÓËÏÍ ÕÎÉ×ÅÒÓÉÔÅÔÅ, âÅÒËÌÉ. - - ðÅÒ×ÏÎÁÞÁÌØÎÏÅ ÉÍÑ, ÄÁÎÎÏÅ × âÅÒËÌÉ, ÂÙÌÏ Postgres. ëÏÇÄÁ × 1995 ÇÏÄÕ - ÂÙÌÁ ÄÏÂÁ×ÌÅÎÁ ÆÕÎËÃÉÏÎÁÌØÎÏÓÔØ SQL, ÜÔÏ ÉÍÑ ÂÙÌÏ ÉÚÍÅÎÅÎÏ ÎÁ - Postgres95. îÏ É ÜÔÏ ÉÍÑ ÂÙÌÏ ÉÚÍÅÎÅÎÏ × ËÏÎÃÅ 1996 ÎÁ PostgreSQL. - - 1.2) ëÁËÏ×Ù Á×ÔÏÒÓËÉÅ ÐÒÁ×Á ÎÁ PostgreSQL? - - PostgreSQL ÐÏÐÁÄÁÅÔ ÐÏÄ ÄÅÊÓÔ×ÉÅ ÓÌÅÄÕÀÝÅÇÏ COPYRIGHT: - - óÉÓÔÅÍÁ õÐÒÁ×ÌÅÎÉÑ âÁÚÁÍÉ äÁÎÎÙÈ PostgreSQL - - Portion copyright (c) 1996-2002, PostgreSQL Global Development Group - Portions Copyright (c) 1994-6 Regents of the University of California - - ðÒÅÄÏÓÔÁ×ÌÑÀÔÓÑ ÐÒÁ×Á ÎÁ ÉÓÐÏÌØÚÏ×ÁÎÉÅ, ËÏÐÉÒÏ×ÁÎÉÅ, ÉÚÍÅÎÅÎÉÅ É - ÒÁÓÐÒÏÓÔÒÁÎÅÎÉÅ ÄÁÎÎÏÇÏ ÐÒÏÇÒÁÍÍÎÏÇÏ ÏÂÅÓÐÅÞÅÎÉÑ É ÅÇÏ ÄÏËÕÍÅÎÔÁÃÉÉ - ÄÌÑ ÌÀÂÙÈ ÃÅÌÅÊ, ÂÅÓÐÌÁÔÎÏ É ÂÅÚ ÐÏÄÐÉÓÁÎÉÑ ËÁËÏÇÏ-ÌÉÂÏ ÓÏÇÌÁÛÅÎÉÑ, - ÐÒÉ ÕÓÌÏ×ÉÉ ÞÔÏ ÄÌÑ ËÁÖÄÏÊ ËÏÐÉÉ ÂÕÄÕÔ ÐÒÅÄÏÓÔÁ×ÌÅÎÙ ÄÁÎÎÏÅ ×ÙÛÅ - ÚÁÍÅÞÁÎÉÅ Ï Á×ÔÏÒÓËÉÈ ÐÒÁ×ÁÈ, ÔÅËÕÝÉÊ ÐÁÒÁÇÒÁÆ É Ä×Á ÓÌÅÄÕÀÝÉÈ - ÐÁÒÁÇÒÁÆÁ. - - ëáìéæïòîéêóëéê õîé÷åòóéôåô îå îåóåô îéëáëïê ïô÷åôóô÷åîîïóôé úá ìàâùå - ðï÷òåöäåîéñ, ÷ëìàþáñ ðïôåòà äïèïäá, îáîåóåîîùå ðòñíùí éìé îåðòñíùí, - óðåãéáìøîùí éìé óìõþáêîùí éóðïìøúï÷áîéåí äáîîïçï ðòïçòáííîïçï - ïâåóðåþåîéñ éìé åçï äïëõíåîôáãéé, äáöå åóìé ëáìéæïòîéêóëéê õîé÷åòóéôåô - âùì éú÷åýåî ï ÷ïúíïöîïóôé ôáëéè ðï÷òåöäåîéê. - - ëáìéæïòîéêóëéê õîé÷åòóéôåô óðåãéáìøîï ïôëáúù÷áúù÷áåôóñ ðòåäïóôá÷ìñôø - ìàâùå çáòáîôéé, ÷ëìàþáñ, îï îå ïçòáîéþé÷áñóø ôïìøëï üôéíé çáòáîôéñíé: - îåñ÷îùå çáòáîôéé ðòéçïäîïóôé ôï÷áòá éìé ðòéçïäîïóôé äìñ ïôäåìøîïê - ãåìé. äáîîïå ðòïçòáííîïå ïâåóðåþåîéå ðòåäïóôá÷ìñåôóñ îá ïóîï÷å ðòéãéðá - "ëáë åóôø" é ëáìéæïòîéêóëéê õîé÷åòóéôåô îå ïâñúáî ðòåäïóôá÷ìñôø - óïðòï÷ïöäåîéå, ðïääåòöëõ, ïâîï÷ìåîéñ, òáóûéòåîéñ éìé éúíåîåîéñ. - - ÷ÙÛÅÉÚÌÏÖÅÎÎÏÅ Ñ×ÌÑÅÔÓÑ BSD ÌÉÃÅÎÚÉÅÊ, ËÌÁÓÓÉÞÅÓËÏÊ ÌÉÃÅÎÚÉÅÊ - ÐÒÏÇÒÁÍÍÎÏÇÏ ÏÂÅÓÐÅÞÅÎÉÑ Ó ÏÔËÒÙÔÙÍ ËÏÄÏÍ. üÔÁ ÌÉÃÅÎÚÉÑ ÎÅ ÎÁËÌÁÄÙ×ÁÅÔ - ÏÇÒÁÎÉÞÅÎÉÊ ÎÁ ÉÓÐÏÌØÚÏ×ÁÎÉÅ ÉÓÈÏÄÎÏÇÏ ËÏÄÁ. îÁÍ ÎÒÁ×ÉÔÓÑ ÜÔÁ ÌÉÃÅÎÚÉÑ - É ÍÙ ÎÅ ÓÏÂÉÒÁÅÍÓÑ Å£ ÍÅÎÑÔØ. - - 1.3) îÁ ËÁËÉÈ Unix ÐÌÁÔÆÏÒÍÁÈ ÒÁÂÏÔÁÅÔ PostgreSQL? - - ïÂÙÞÎÏ, PostgreSQL ÍÏÖÅÔ ÒÁÂÏÔÁÔØ ÎÁ ÌÀÂÏÊ ÓÏ×ÒÅÍÅÎÎÏÊ ÐÌÁÔÆÏÒÍÅ - ÓÏ×ÍÅÓÔÉÍÏÊ Ó Unix. ÷ ÉÎÓÔÒÕËÃÉÉ ÐÏ ÕÓÔÁÎÏ×ËÅ, ×Ù ÎÁÊÄÅÔÅ ÓÐÉÓÏË ÔÅÈ - ÐÌÁÔÆÏÒÍ, ÎÁ ËÏÔÏÒÙÈ ÂÙÌÉ ÐÒÏ×ÅÄÅÎÙ ÔÅÓÔÏ×ÙÅ ÚÁÐÕÓËÉ PostgreSQL Ë - ÍÏÍÅÎÔÕ ×ÙÈÏÄÁ ÄÁÎÎÏÊ ×ÅÒÓÉÉ. - - 1.4) óÕÝÅÓÔ×ÕÀÔ ÌÉ ×ÅÒÓÉÉ ÐÅÒÅÎÅÓÅÎÎÙÅ ÎÅ ÎÁ Unix ÓÉÓÔÅÍÙ? - - ëÌÉÅÎÔ - - äÌÑ ÚÁÐÕÓËÁ ÎÁ ÐÌÁÔÆÏÒÍÁÈ MS Windows ×ÏÚÍÏÖÎÁ ËÏÍÐÉÌÑÃÉÑ C ÂÉÂÌÉÏÔÅËÉ - libpq, psql É ÄÒÕÇÉÈ ÉÎÔÅÒÆÅÓÏ× É ÂÉÎÁÒÎÙÈ ÆÁÊÌÏ×. ÷ ÜÔÏÍ ÓÌÕÞÁÅ, - ËÌÉÅÎÔ ÚÁÐÕÓËÁÅÔÓÑ ÎÁ MS Windows É Ó×ÑÚÙ×ÁÅÔÓÑ ÐÏ TCP/IP Ó ÓÅÒ×ÅÒÏÍ, - ÚÁÐÕÝÅÎÎÙÍ ÎÁ ÏÄÎÏÊ ÉÚ ÐÏÄÄÅÒÖÉ×ÁÅÍÙÈ Unix ÐÌÁÔÆÏÒÍ. ÷ ÄÉÓÔÒÉÂÕÔÉ× - ×ËÌÀÞÁÅÔÓÑ ÆÁÊÌ win31.mak ÄÌÑ ÔÏÇÏ, ÞÔÏÂÙ ÍÏÖÎÏ ÂÙÌÏ ÐÒÏ×ÅÓÔÉ ÓÂÏÒËÕ - ÂÉÂÌÉÏÔÅËÉ libpq É psql ÄÌÑ Win32. PostgreSQL ÔÁËÖÅ ÒÁÂÏÔÁÅÔ ÞÅÒÅÚ - ODBC. - - óÅÒ×ÅÒ - - óÅÒ×ÅÒ âä ÍÏÖÅÔ ÂÙÔØ ÚÁÐÕÝÅÎ ÎÁ Windows NT É Win2k, ÉÓÐÏÌØÚÕÑ - ÂÉÂÌÉÏÔÅËÕ Cygwin, ÒÁÚÒÁÂÏÔÁÎÎÕÀ ÄÌÑ ÐÅÒÅÎÏÓÁ ÐÒÏÇÒÁÍÍÎÏÇÏ ÏÂÅÓÐÅÞÅÎÉÑ - Unix × NT. óÍÏÔÒÉÔÅ pgsql/doc/FAQ_MSWIN × ÄÉÓÔÒÉÂÕÔÉ×Å ÉÌÉ MS Windows - FAQ ÎÁ ÎÁÛÅÍ ÓÁÊÔÅ. íÙ ÎÅ ÐÌÁÎÉÒÕÅÍ ÓÐÅÃÉÁÌØÎÏ ÐÅÒÅÎÏÓÉÔØ PostgreSQL - ÎÁ ËÁËÕÀ-ÌÉÂÏ ÐÌÁÔÆÏÒÍÕ Microsoft. - - 1.5) çÄÅ ÍÏÖÎÏ ×ÚÑÔØ PostgreSQL? - - îÁÐÒÉÍÅÒ, ×ÏÓÐÏÌØÚÏ×Á×ÛÉÓØ ÁÎÏÎÉÍÎÙÍ ÄÏÓÔÕÐÏÍ ÎÁ ftp ÓÁÊÔ PostgreSQL - ftp://ftp.PostgreSQL.org/pub. óÐÉÓÏË ÚÅÒËÁÌ ×Ù ÎÁÊÄÅÔÅ ÎÁ ÎÁÛÅÍ - ÏÓÎÏ×ÎÏÍ ÓÁÊÔÅ. - - 1.6) çÄÅ ÐÏÌÕÞÉÔØ ÐÏÄÄÅÒÖËÕ? - - ïÓÎÏ×ÎÏÊ ÓÐÉÓÏË ÒÁÓÓÙÌËÉ: pgsql-general@PostgreSQL.org. ÷ ÎÅÍ ÍÏÖÎÏ - ÏÂÓÕÖÄÁÔØ ÌÀÂÙÅ ÔÅÍÙ, ËÁÓÁÀÝÉÅÓÑ PostgreSQL. þÔÏÂÙ ÐÏÄÐÉÓÁÔØÓÑ, - ÏÔÐÒÁרÔÅ ÐÉÓØÍÏ ÐÏ ÜÌÅËÔÒÏÎÎÏÊ ÐÏÞÔÅ, × ËÏÔÏÒÏÍ × ÔÅÌÅ ÐÉÓØÍÁ (ÎÅ × - ÔÅÍÅ) ÎÁÐÉÛÉÔÅ ÓÌÅÄÕÀÝÉÅ ÓÔÒÏËÉ: - subscribe - end - - ÎÁ ÁÄÒÅÓ pgsql-general-request@PostgreSQL.org. - - óÕÝÅÓÔ×ÕÅÔ ÄÁÊÖÅÓÔ ÓÐÉÓÏË. þÔÏÂÙ ÐÏÄÐÉÓÁÔØÓÑ ÎÁ ÎÅÇÏ, ÏÔÐÒÁרÔÅ ÐÉÓØÍÏ - ÐÏ ÜÌÅËÔÒÏÎÎÏÊ ÐÏÞÔÅ ÎÁ ÁÄÒÅÓ: - pgsql-general-digest-request@PostgreSQL.org É × ÔÅÌÅ ÐÉÓØÍÁ ÎÁÐÉÛÉÔÅ - ÓÔÒÏÞËÉ ÓÔÒÏÞËÉ: - subscribe - end - - äÁÊÖÅÓÔÙ ÏÔÐÒÁ×ÌÑÀÔÓÑ ÐÏÄÐÉÓÞÉËÁÍ, ËÏÇÄÁ × ÏÓÎÏ×ÎÏÍ ÓÐÉÓËÅ ÒÁÓÓÙÌËÉ - ÎÁËÏÐÉÔÓÑ ÏËÏÌÏ 30 ËÉÌÏÂÁÊÔ ÓÏÏÂÝÅÎÉÊ. - - äÏÓÔÕÐÅÎ É ÓÐÉÓÏË ÒÁÓÓÙÌËÉ ÓÏÏÂÝÅÎÉÊ Ï ÏÛÉÂËÁÈ. þÔÏÂÙ ÐÏÄÐÉÓÁÔØÓÑ ÎÁ - ÜÔÏÔ ÓÐÉÓÏË, ÏÔÐÒÁרÔÅ ÐÏ ÜÌÅËÔÒÏÎÎÏÊ ÐÏÞÔÅ ÐÉÓØÍÏ ÎÁ ÁÄÒÅÓ - pgsql-bugs-request@PostgreSQL.org É × ÔÅÌÅ ÐÉÓØÍÁ ÎÁÐÉÛÉÔÅ ÓÔÒÏÞËÉ - ÓÔÒÏÞËÉ: - subscribe - end - - ôÁËÖÅ ÉÍÅÅÔÓÑ ÓÐÉÓÏË ÒÁÓÓÙÌËÉ Ó ÄÉÓËÕÓÓÉÑÍÉ ÒÁÚÒÁÂÏÔÞÉËÏ×. þÔÏÂÙ - ÐÏÄÐÉÓÁÔØÓÑ ÎÁ ÜÔÏÔ ÓÐÉÓÏË, ÏÔÐÒÁרÔÅ ÐÏ ÜÌÅËÔÒÏÎÎÏÊ ÐÏÞÔÅ ÐÉÓØÍÏ ÎÁ - ÁÄÒÅÓ pgsql-hackers-request@PostgreSQL.org É × ÔÅÌÅ ÐÉÓØÍÁ ÎÁÐÉÛÉÔÅ - ÓÔÒÏÞËÉ ÓÔÒÏÞËÉ: - subscribe - end - - äÏÐÏÌÎÉÔÅÌØÎÙÅ ÓÐÉÓËÉ ÒÁÓÓÙÌËÉ É ÉÎÆÏÍÁÃÉÀ Ï PostgreSQL ÍÏÖÎÏ ÎÁÊÔÉ ÎÁ - ÄÏÍÁÛÎÅÊ ÓÔÒÁÎÉÞËÅ PostgreSQL ÐÏ ÁÄÒÅÓÕ: - - http://www.PostgreSQL.org - - åÝÅ ÓÕÝÅÓÔ×ÕÅÔ IRC ËÁÎÁÌ ÎÁ EFNet, Ó ÎÁÚ×ÁÎÉÅÍ #PostgreSQL. ñ - ÉÓÐÏÌØÚÕÀ ÄÌÑ ÐÏÄËÌÀÞÅÎÉÑ Ë ÜÔÏÍÕ ËÁÎÁÌÕ ËÏÍÁÎÄÕ Unix irc -c - '#PostgreSQL' "$USER" irc.phoenix.net. - - óÐÉÓÏË ËÏÍÍÅÒÞÅÓËÏÊ ÐÏÄÄÅÒÖËÉ ËÏÍÐÁÎÉÊ ÄÏÓÔÕÐÅÎ ÎÁ - http://www.postgresql.org/users-lounge/commercial-support.html. - - 1.7) ëÁËÁÑ ÐÏÓÌÅÄÎÑÑ ×ÅÒÓÉÑ? - - ðÏÓÌÅÄÎÉÊ ×ÙÐÕÓË PostgreSQL - ÜÔÏ ×ÅÒÓÉÑ 7.2. - - íÙ ÐÌÁÎÉÒÕÅÍ ×ÙÐÕÓËÁÔØ ÎÏ×ÙÅ ×ÅÒÓÉÉ ËÁÖÄÙÅ ÞÅÔÙÒÅ ÍÅÓÑÃÁ. - - 1.8) ëÁËÁÑ ÄÏËÕÍÅÎÔÁÃÉÑ ÉÍÅÅÔÓÑ × ÎÁÌÉÞÉÉ? - - ÷ ÄÉÓÔÒÉÂÕÔÉ× ×ËÌÀÞÁÀÔÓÑ ÒÁÚÌÉÞÎÙÅ ÒÕËÏ×ÏÄÓÔ×Á, ÓÔÒÁÎÉÃÙ ÜÌÅËÔÒÏÎÎÏÇÏ - ÒÕËÏ×ÏÄÓÔ×Á man É ÎÅËÏÔÏÒÙÅ ÍÁÌÅÎØËÉÅ ÔÅÓÔÏ×ÙÅ ÐÒÉÍÅÒÙ. óÍÏÔÒÉÔÅ × - ËÁÔÁÌÏÇ /doc. ÷Ù ÔÁËÖÅ ÍÏÖÅÔÅ ÐÒÏÓÍÁÔÒÉ×ÁÔØ ÄÏËÕÍÅÎÔÁÃÉÀ × éÎÔÅÒÎÅÔ ÐÏ - ÁÄÒÅÓÕ http://www.PostgreSQL.org/users-lounge/docs/. - - óÕÝÅÓÔ×ÕÅÔ Ä×Å ËÎÉÇÉ ÐÏ PostgreSQL ÄÏÓÔÕÐÎÙÅ ÐÏ ÁÄÒÅÓÁÍ - http://www.PostgreSQL.org/docs/awbook.html É - http://www.commandprompt.com/ppbook/. óÐÉÓÏË ËÎÉÇ ÐÏ PostgreSQL, - ËÏÔÏÒÙÅ ÍÏÖÎÏ ËÕÐÉÔØ ÄÏÓÔÕÐÅÎ ÐÏ ÁÄÒÅÓÕ - http://www.postgresql.org/books/. ëÒÏÍÅ ÔÏÇÏ, ÐÏ ÁÄÒÅÓÕ - http://techdocs.postgresql.org/ ×Ù ÍÏÖÅÔÅ ÎÁÊÔÉ ËÏÌÌÅËÃÉÀ ÔÅÈÎÉÞÅÓËÉÈ - ÓÔÁÔÅÊ ÐÏÓ×ÑÝÅÎÎÙÈ PostgreSQL. - - psql ÉÍÅÅÔ ÎÅÓËÏÌØËÏ ÐÒÅËÒÁÓÎÙÈ ËÏÍÁÎÄ \d ÄÌÑ ÏÔÏÂÒÁÖÅÎÉÑ ÉÎÆÏÒÍÁÃÉÉ - ÐÏ ÔÉÐÁÍ, ÏÐÅÒÁÔÏÒÁÍ, ÆÕÎËÃÉÑÍ, ÁÇÒÅÇÁÔÁÍ É Ô.Ä. - - îÁÛ ÓÁÊÔ ÓÏÄÅÒÖÉÔ ÅÝÅ ÂÏÌØÛÅ ÉÎÆÏÒÍÁÃÉÉ. - - 1.9) ëÁË ÎÁÊÔÉ ÉÎÆÏÒÍÁÃÉÀ Ï ÉÚ×ÅÓÔÎÙÈ ÏÛÉÂËÁÈ ÉÌÉ ÏÔÓÕÔÓÔ×ÕÀÝÉÈ - ×ÏÚÍÏÖÎÏÓÔÑÈ? - - PostgreSQL ÐÏÄÄÅÒÖÉ×ÁÅÔ ÒÁÓÛÉÒÅÎÎÙÊ ÐÏÄËÌÁÓÓ SQL-92. óÍÏÔÒÉÔÅ ÎÁÛ - ÓÐÉÓÏË TODO ÎÁ ÐÒÅÄÍÅÔ ÉÚ×ÅÓÔÎÙÈ ÏÛÉÂÏË, ÏÔÓÕÔÓÔ×ÕÀÝÉÈ ÏÓÏÂÅÎÎÏÓÔÑÈ É - ÂÕÄÕÝÉÈ ÐÌÁÎÏ×. - - 1.10) ëÁË ÍÎÅ ÎÁÕÞÉÔØÓÑ SQL? - - ëÎÉÇÁ ÐÏ PostgreSQL ÎÁ http://www.PostgreSQL.org/docs/awbook.html - ÎÁÕÞÉÔ SQL. óÕÝÅÓÔ×ÕÅÔ ÄÒÕÇÁÑ ËÎÉÇÁ ÐÏ PostgreSQL ÎÁ - http://www.commandprompt.com/ppbook. åÓÔØ ÐÒÅËÒÁÓÎÙÊ ÕÞÅÂÎÉË ÎÁ - http://www.intermedia.net/support/sql/sqltut.shtm, ÎÁ - http://ourworld.compuserve.com/homepages/graeme_birchall/HTM_COOK.HTM, - É ÎÁ http://sqlcourse.com. - - åÝÅ ÏÄÉÎ ÕÞÅÂÎÉË - ÜÔÏ ËÎÉÇÁ "Teach Yourself SQL in 21 Days, Second - Edition" (ïÓ×ÏÊ ÓÁÍÏÓÔÏÑÔÅÌØÎÏ SQL ÚÁ 21 ÄÅÎØ, ÷ÔÏÒÁÑ ÒÅÄÁËÃÉÑ) ÎÁ - http://members.tripod.com/er4ebus/sql/index.htm - - íÎÏÇÉÍ ÉÚ ÎÁÛÉÈ ÐÏÌØÚÏ×ÁÔÅÌÅÊ ÎÒÁ×ÉÔÓÑ ËÎÉÇÁ The Practical SQL - Handbook, Bowman, Judith S., et al., Addison-Wesley. äÒÕÇÉÍ ÎÒÁ×ÉÔÓÑ - The Complete Reference SQL, Groff et al., McGraw-Hill. - - 1.11) òÅÛÅÎÁ ÌÉ × PostgreSQL ÐÒÏÂÌÅÍÁ 2000-ÇÏ ÇÏÄÁ (Y2K)? - - äÁ, ÍÙ ÌÅÇËÏ ÍÁÎÉÐÕÌÉÒÕÅÍ ÄÁÔÁÍÉ ÐÏÓÌÅ 2000 ÇÏÄÁ É ÐÅÒÅÄ 2000 ÇÏÄÏÍ. - - 1.12) ëÁË ÐÒÉÓÏÅÄÉÎÉÔÓÑ Ë ËÏÍÁÎÄÅ ÒÁÚÒÁÂÏÔÞÉËÏ×? - - äÌÑ ÎÁÞÁÌÁ, ÓËÁÞÁÊÔÅ ÐÏÓÌÅÄÎÀÀ ×ÅÒÓÉÀ ÉÓÈÏÄÎÙÈ ÔÅËÓÔÏ× É ÐÒÏÞÔÉÔÅ - ÄÏËÕÍÅÎÔÁÃÉÀ ÒÁÚÒÁÂÏÔÞÉËÏ× PostgreSQL ÎÁ ÎÁÛÅÍ ÓÁÊÔÅ ÉÌÉ × - ÄÉÓÔÒÉÂÕÔÉ×Å. úÁÔÅÍ, ÐÏÄÐÉÛÉÔÅÓØ ÎÁ ÓÐÉÓËÉ ÒÁÓÓÙÌËÉ pgsql-hackers É - pgsql-patches. äÁÌÅÅ, ÏÔÐÒÁ×ÌÑÊÔÅ ÉÓÐÒÁ×ÌÅÎÉÑ (patches) ×ÙÓÏËÏÇÏ - ËÁÞÅÓÔ×Á × ÓÐÉÓÏË pgsql-patches. - - óÕÝÅÓÔ×ÕÅÔ ÏÇÒÁÎÉÞÅÎÎÙÊ ÓÐÉÓÏË ÌÀÄÅÊ, ËÏÔÏÒÙÊ ÉÍÅÀÔ ÐÒÉ×ÅÌÅÇÉÀ ×ÎÏÓÉÔØ - ÉÚÍÅÎÅÎÉÑ × CVS ÁÒÈÉ× PostgreSQL. ëÁÖÄÙÊ ÉÚ ÜÔÉÈ ÌÀÄÅÊ × Ó×ÏÅ ×ÒÅÍÑ - ÏÔÐÒÁ×ÉÌ ÔÁË ÍÎÏÇÏ ×ÙÓÏËÏËÁÞÅÓÔ×ÅÎÎÙÈ ÉÓÐÒÁ×ÌÅÎÉÊ, ÞÔÏ ÉÈ ÂÙÌÏ - ÎÅ×ÏÚÍÏÖÎÏ ÏÓÔÁ×ÉÔØ ÂÅÚ ×ÎÉÍÁÎÉÑ É ÏÎÉ ÂÙÌÉ ÕÄÏÓÔÏÅÎÙ ÐÒÅ×ÉÌÅÇÉÉ - ×ÎÏÓÉÔØ ÉÚÍÅÎÅÎÉÑ, É ÍÙ Õ×ÅÒÅÎÙ, ÞÔÏ ÔÅ ÉÓÐÒÁ×ÌÅÎÉÑ, ËÏÔÏÒÙÅ ÏÎÉ - ×ÎÅÓÕÔ ÂÕÄÕÔ ×ÙÓÏËÏÇÏ ËÁÞÅÓÔ×Á. - - 1.13) ëÁË ÏÔÒÁ×ÉÔØ ÓÏÏÂÝÅÎÉÅ Ï ÏÛÉÂËÅ?? - - ðÏÖÁÌÕÊÓÔÁ ÐÏÓÅÔÉÔÅ ÓÔÒÁÎÉÞËÕ PostgreSQL BugTool, ÎÁ ËÏÔÏÒÏÊ - ÐÒÅÄÏÓÔÁ×ÌÅÎÙ ÄÅÔÁÌØÎÙÅ ÉÎÓÔÒÕËÃÉÉ Ï ÔÏÍ ËÁË ÏÔÐÒÁ×ÉÔØ ÓÏÏÂÝÅÎÉÅ Ï - ÏÛÉÂËÅ. - - ôÁËÖÅ ÎÅ ÚÁÂÕÄØÔÅ ÐÏÓÍÏÔÒÅÔØ ÎÁ ftp://ftp.PostgreSQL.org/pub ÎÁ - ÐÒÅÄÍÅÔ ÂÏÌÅÅ Ó×ÅÖÉÈ ×ÅÒÓÉÊ PostgreSQL ÉÌÉ ÚÁÐÌÁÔ. - - 1.14) ëÁË ÓÒÁ×ÎÉ×ÁÔØ PostgreSQL Ó ÄÒÕÇÉÍÉ óõâä? - - óÕÝÅÓÔ×ÕÅÔ ÎÅÓËÏÌØËÏ ÍÅÔÏÄÏ× ÓÒÁ×ÎÅÎÉÑ ÐÒÏÇÒÁÍÍÎÏÇÏ ÏÂÅÓÐÅÞÅÎÉÑ: - ×ÏÚÍÏÖÎÏÓÔÉ, ÐÒÏÉÚ×ÏÄÉÔÅÌØÎÏÓÔØ, ÎÁÄÅÖÎÏÓÔØ, ÐÏÄÄÅÒÖËÁ É ÃÅÎÁ. - - ÷ÏÚÍÏÖÎÏÓÔÉ - PostgreSQL ÉÍÅÅÔ ÂÏÌØÛÉÎÓÔ×Ï ×ÏÚÍÏÖÎÏÓÔÅÊ ÐÒÅÄÓÔÁ×ÌÅÎÎÙÈ × - ÂÏÌØÛÉÈ ËÏÍÍÅÒÞÅÓËÉÈ óõâä, ÔÁËÉÅ ËÁË: ÔÒÁÎÚÁËÃÉÉ, ÐÏÄÚÁÐÒÏÓÙ, - ÔÒÉÇÇÅÒÙ, ÏÂÚÏÒÙ (views), ×ÎÅÛÎÉÊ ËÌÀÞ ÓÓÙÌÏÞÎÏÊ ÃÅÌÏÓÔÎÏÓÔÉ É - ÒÁÚÎÙÅ ÂÌÏËÉÒÏ×ËÉ. õ ÎÁÓ ÅÓÔØ ÎÅËÏÔÏÒÙÅ ×ÏÚÍÏÖÎÏÓÔÉ, ËÏÔÏÒÙÈ - ÎÅÔ Õ ÎÉÈ: ÔÉÐÙ, ÏÐÒÅÄÅÌÑÅÍÙÅ ÐÏÌØÚÏ×ÁÔÅÌÅÍ, ÍÅÈÁÎÉÚÍ - ÎÁÓÌÅÄÏ×ÁÎÉÑ, ÐÒÁ×ÉÌÁ É ËÏÎËÕÒÅÔÎÏÅ ÍÎÏÇÏ×ÅÒÓÉÏÎÎÏÅ ÕÐÒÁ×ÌÅÎÉÅ - ÄÌÑ ÒÁÂÏÔÙ Ó ÓÏÄÅÒÖÉÍÙÍ ÂÌÏËÉÒÏ×ÏË. - - ðÒÏÉÚ×ÏÄÉÔÅÌØÎÏÓÔØ - PostgreSQL ÉÍÅÅÔ ÐÒÏÉÚ×ÏÄÉÔÅÌØÎÏÓÔØ ÓÈÏÖÕÀ Ó ÄÒÕÇÉÍÉ - ËÏÍÍÅÒÞÅÓËÉÍÉ óõâä É Ó óõâä Ó ÏÔËÒÙÔÙÍ ÉÓÈÏÄÎÙÍ ËÏÄÏÍ, × - ËÁËÉÈ-ÔÏ ÁÓÐÅËÔÁÈ ÒÁÂÏÔÁÑ ÂÙÓÔÒÅÅ ÞÅÍ ÏÎÉ, × ËÁËÉÈ-ÔÏ ÍÅÄÌÅÎÅÅ. - ÷ ÓÒÁ×ÎÅÎÉÉ Ó MySQL ÉÌÉ ÌÉÎÅÊÎÙÍÉ óõâä, ÍÙ ÍÅÄÌÅÎÅÅ ÐÒÉ - ÏÐÅÒÁÃÉÑÈ ×ÓÔÁ×ËÉ/ÏÂÎÏ×ÌÅÎÉÑ, ÐÏÔÏÍÕ ÞÔÏ ÕÐÒÁ×ÌÑÅÍ - ÔÒÁÎÚÁËÃÉÑÍÉ. é ÒÁÚÕÍÅÅÔÓÑ, MySQL ÎÅ ÉÍÅÅÔ ËÁËÉÈ-ÌÉÂÏ - ×ÏÚÍÏÖÎÏÓÔÅÊ ÉÚ ÐÅÒÅÞÉÓÌÅÎÙÈ ×ÙÛÅ, × ÓÅËÃÉÉ ÷ÏÚÍÏÖÎÏÓÔÉ. íÙ - ÄÅÌÁÅÍ ÕÐÏÒ ÎÁ ÎÁÄÅÖÎÏÓÔØ É ÒÁÓÛÉÒÅÎÎÙÅ ×ÏÚÍÏÖÎÏÓÔÉ, ÎÏ ÍÙ - ÔÁËÖÅ ÐÒÏÄÏÌÖÁÅÍ Õ×ÅÌÉÞÉ×ÁÔØ ÐÒÏÉÚ×ÏÄÉÔÅÌØÎÏÓÔØ Ó ËÁÖÄÙÍ - ×ÙÐÕÓËÏÍ. óÕÝÅÓÔ×ÕÅÔ ÉÎÔÅÒÅÓÎÁÑ ÓÔÒÁÎÉÞËÁ × éÎÔÅÒÎÅÔ, - ÓÒÁ×ÎÉ×ÁÀÝÁÑ PostgreSQL É MySQL ÎÁ - http://openacs.org/why-not-mysql.html - - îÁÄÅÖÎÏÓÔØ - íÙ ÐÏÎÉÍÁÌÉ, ÞÔÏ ÎÁÛÁ óõâä ÄÏÌÖÎÁ ÂÙÔØ ÎÁÄÅÖÎÏÊ ÉÌÉ ÏÎÁ ÎÉÞÅÇÏ - ÎÅ ÂÕÄÅÔ ÓÔÏÉÔØ. íÙ ÓÔÁÒÁÅÍÓÑ ×ÙÐÕÓËÁÔØ ÈÏÒÏÛÏ ÐÒÏ×ÅÒÅÎÎÙÊ, - ÓÔÁÂÉÌØÎÙÊ ËÏÄ, ËÏÔÏÒÙÊ ÓÏÄÅÒÖÉÔ ÍÉÎÉÍÕÍ ÏÛÉÂÏË. ëÁÖÄÙÊ ×ÙÐÕÓË - ÐÒÏÈÏÄÉÔ ÓÔÁÄÉÀ ÂÅÔÁ-ÔÅÓÔÉÒÏ×ÁÎÉÑ ÐÏ ËÒÁÊÎÅÊ ÍÅÒÅ × ÔÅÞÅÎÉÉ - ÏÄÎÏÇÏ ÍÅÓÑÃÁ É ÎÁÛÁ ÉÓÔÏÒÉÑ ×ÙÐÕÓËÏ× ÐÏËÁÚÙ×ÁÅÔ ÞÔÏ ÍÙ ÍÏÖÅÍ - ÐÒÅÄÏÓÔÁ×ÌÑÔØ ÓÔÁÂÉÌØÎÙÅ, ÍÏÎÏÌÉÔÎÙÅ ×ÙÐÕÓËÉ, ËÏÔÏÒÙÅ ÇÏÔÏ×Ù Ë - ÐÒÏÄÕËÔÉ×ÎÏÍÕ ÉÓÐÏÌØÚÏ×ÁÎÉÀ. íÙ ×ÅÒÉÍ, ÞÔÏ ÍÙ ÐÒÏÉÚ×ÏÄÉÍ - ÐÒÏ×ÅÒËÕ ÎÅ ÈÕÖÅ, ÞÅÍ Õ ÄÒÕÇÉÈ óõâä. - - ðÏÄÄÅÒÖËÁ - îÁÛ ÓÐÉÓÏË ÒÁÓÓÙÌËÉ ÐÒÅÄÓÔÁ×ÌÅÎ ÂÏÌØÛÏÊ ÇÒÕÐÐÏÊ ÒÁÚÒÁÂÏÔÞÉËÏ× É - ÐÏÌØÚÏ×ÁÔÅÌÅÊ, ËÏÔÏÒÙÅ ÍÏÇÕÔ ÐÏÍÏÞØ ÒÅÛÉÔØ ÌÀÂÙÅ ×ÏÚÎÉËÛÉÅ - ÐÒÏÂÌÅÍÙ. ÷ ÔÏ ÖÅ ×ÒÅÍÑ, ÍÙ ÎÅ ÇÁÒÁÎÔÉÒÕÅÍ ËÁËÉÅ-ÌÉÂÏ - ÉÓÐÒÁ×ÌÅÎÉÑ, ÎÏ É ÒÁÚÒÁÂÏÔÞÉËÉ ËÏÍÍÅÒÞÅÓËÉÈ óõâä ÎÅ ×ÓÅÇÄÁ - ÄÅÌÁÀÔ ÉÓÐÒÁ×ÌÅÎÉÑ. ðÒÑÍÏÊ ÄÏÓÔÕÐ Ë ÒÁÚÒÁÂÏÔÞÉËÁÍ, ÓÏÏÂÝÅÓÔ×Õ - ÐÏÌØÚÏ×ÁÔÅÌÅÊ, ÒÕËÏ×ÏÄÓÔ×ÁÍ É ÉÓÈÏÄÎÙÍ ÔÅËÓÔÁÍ ÞÁÓÔÏ ÄÅÌÁÀÔ - ÐÏÄÄÅÒÖËÕ PostgreSQL ÐÒÅ×ÏÓÈÏÄÑÝÅÊ ÄÒÕÇÉÅ óõâä. óÕÝÅÓÔ×ÕÅÔ - ËÏÍÍÅÒÞÅÓËÁÑ ÐÏÄÄÅÒÖËÁ ÐÏ ÒÅÚÕÌØÔÁÍ ×ÏÚÎÉËÛÉÈ ÉÎÃÉÄÅÎÔÏ×, - ËÏÔÏÒÁÑ ÄÏÓÔÕÐÎÁ ÄÌÑ ÔÅÈ ËÏÍÕ ÏÎÁ ÎÕÖÎÁ. (óÍÏÔÒÉÔÅ ëÁË ÐÏÌÕÞÉÔØ - ÐÏÄÄÅÒÖËÕ?.) - - ãÅÎÁ - îÁÛ ÐÒÏÄÕËÔ ÂÅÓÐÌÁÔÅÎ ËÁË ÄÌÑ ËÏÍÍÅÒÞÅÓËÏÇÏ ÔÁË, É ÎÅ ÄÌÑ - ËÏÍÍÅÒÞÅÓËÏÇÏ ÉÓÐÏÌØÚÏ×ÁÎÉÑ. ÷Ù ÍÏÖÅÔÅ ÄÏÂÁ×ÌÑÔØ Ó×ÏÊ ËÏÄ × ÎÁÛ - ÐÒÏÄÕËÔ ÂÅÚ ÏÇÒÁÎÉÞÅÎÉÊ, ÚÁ ÉÓËÌÀÞÅÎÉÅÍ ÔÅÈ, ÞÔÏ ÏÐÉÓÙ×ÁÀÔÓÑ × - ÎÁÛÅÊ ÌÉÃÅÎÚÉÉ ÓÔÉÌÑ BSD, ËÏÔÏÒÁÑ ÐÒÉ×ÅÄÅÎÁ ×ÙÛÅ. - - 1.15) ëÁË ÏËÁÚÁÔØ ÆÉÎÁÎÓÏ×ÕÀ ÐÏÍÏÝØ PostgreSQL? - - PostgreSQL ÉÍÅÅÔ ÏÄÎÏÒÁÎÇÏ×ÕÀ ÉÎÆÒÁÓÔÒÕËÔÕÒÕ Ó ÔÏÇÏ ÓÁÍÏÇÏ ×ÒÅÍÅÎÉ ËÁË - ÍÙ ÎÁÞÁÌÉ ÒÁÚÒÁÂÏÔËÕ 6 ÌÅÔ ÎÁÚÁÄ. íÙ ÄÏÌÖÎÙ ÂÌÁÇÏÄÁÒÉÔØ ÚÁ ÜÔÏ íÁÒËÁ - æÏÎÁÑ (Marc Fournier), ËÏÔÏÒÙÊ ÓÏÚÄÁÌ ÜÔÕ ÉÎÆÒÁÓÔÒÕËÔÕÒÕ É ÕÐÒÁ×ÌÑÅÔ - ÅÊ ÎÁ ÐÒÏÔÑÖÅÎÉÉ ÜÔÉÈ ÌÅÔ. - - ëÁÞÅÓÔ×ÅÎÎÁÑ ÉÎÆÒÁÓÔÒÕËÔÕÒÁ ÏÞÅÎØ ×ÁÖÎÁ ÄÌÑ ÐÒÏÅËÔÏ× Ó ÏÔËÒÙÔÙÍ - ÉÓÈÏÄÎÙÍ ËÏÄÏÍ. ïÎÁ ÐÒÅÄÏÔ×ÒÁÝÁÅÔ ÒÁÓËÏÌÙ, ËÏÔÏÒÙÅ ÍÏÇÕÔ ÓÉÌØÎÏ - ÚÁÄÅÒÖÁÔØ ÐÏÓÔÕÐÁÔÅÌØÎÏÅ Ä×ÉÖÅÎÉÅ ÐÒÏÅËÔÁ. - - òÁÚÕÍÅÅÔÓÑ, ÜÔÁ ÉÎÆÒÁÓÔÒÕËÔÕÒÁ ÎÅ Ñ×ÌÑÅÔÓÑ ÄÅÛÅ×ÏÊ. óÕÝÅÓÔ×ÕÅÔ - ÎÅËÏÔÏÒÏÅ ËÏÌÉÞÅÓÔ×Ï ÅÖÅÍÅÓÑÞÎÙÈ É ÏÄÎÏÒÁÚÏ×ÙÈ ÒÁÓÈÏÄÏ×, ËÏÔÏÒÙÅ - ÔÒÅÂÕÀÔ ÄÅÎÅÇ. åÓÌÉ ×Ù ÉÌÉ ×ÁÛÁ ËÏÍÐÁÎÉÑ ÉÍÅÅÔ ÄÅÎØÇÉ, ËÏÔÏÒÙÅ ÍÏÖÎÏ - ÐÅÒÅÄÁÔØ × ÐÏÍÏÝØ ÎÁÛÉÍ ÕÓÉÌÉÑÍ, ÐÏÖÁÌÕÊÓÔÁ ÐÏÓÅÔÉÔÅ ÓÔÒÁÎÉÞËÕ - http://www.pgsql.com/pg_goodies É ÓÄÅÌÁÊÔÅ Ó×ÏÊ ×ËÌÁÄ. - - èÏÔÑ ÎÁ ÓÔÒÁÎÉÞËÅ ÇÏ×ÏÒÉÔÓÑ Ï PostgreSQL, Inc, ÐÕÎËÔ "contributions" - ÐÒÅÄÎÁÚÎÁÞÅÎ ÉÓËÌÀÞÉÔÅÌØÎÏ ÄÌÑ ÐÏÄÄÅÒÖËÉ ÐÒÏÅËÔÁ PostgreSQL É ÎÅ - ÐÅÒÅÄÁÅÔÓÑ ËÁËÏÊ-ÌÉÂÏ ËÏÎËÒÅÔÎÏÊ ËÏÍÐÁÎÉÉ. åÓÌÉ ÈÏÔÉÔÅ, ÔÏ ÍÏÖÅÔÅ ÜÔÏ - ÐÒÏ×ÅÒÉÔØ, ÎÁÐÉÓÁ× ÐÉÓØÍÏ ÎÁ ËÏÎÔÁËÔÎÙÊ ÁÄÒÅÓ. - _________________________________________________________________ - - ÷ÏÐÒÏÓÙ ÐÏÌØÚÏ×ÁÔÅÌÅÊ ÐÏ ËÌÉÅÎÔÓËÏÊ ÞÁÓÔÉ - - 2.1) óÕÝÅÓÔ×ÕÀÔ ÌÉ ODBC ÄÒÁÊ×ÅÒÁ ÄÌÑ PostgreSQL? - - óÕÝÅÓÔ×ÕÅÔ Ä×Á ODBC ÄÒÁÊ×ÅÒÁ, PsqlODBC É OpenLink ODBC. - - PsqlODBC ×ËÌÀÞÁÅÔÓÑ × ÄÉÓÔÒÉÂÕÔÉ×. âÏÌØÛÅ ÉÎÆÏÒÍÁÃÉÉ Ï ÜÔÏÍ ÄÒÁÊ×ÅÒÅ - ÍÏÖÎÏ ÎÁÊÔÉ ÎÁ ftp://ftp.PostgreSQL.org/pub/odbc/. - - OpenLink ODBC ÍÏÖÎÏ ×ÚÑÔØ ÎÁ http://www.openlinksw.com. üÔÏÔ ÄÒÁÊ×ÅÒ - ÒÁÂÏÔÁÅÔ Ó ÉÈ ÓÔÁÎÄÁÒÔÎÙÍ ËÌÉÅÎÔÓËÉÍ ÐÒÏÇÒÁÍÍÎÙÍ ÏÂÅÓÐÅÞÅÎÉÅÍ, - ÉÓÐÏÌØÚÕÀÝÉÍ ODBC, É ÔÁËÉÍ ÏÂÒÁÚÏÍ, ODBC ÄÒÁÊ×ÅÒÙ ÄÌÑ PostgreSQL - ÄÏÓÔÕÐÎÙ ÄÌÑ ËÁÖÄÏÊ ÉÚ ÐÏÄÄÅÒÖÉ×ÁÅÍÙÈ ÉÍÉ ÐÌÁÔÆÏÒÍ (Win, Mac, Unix, - VMS). - - ÷ÏÚÍÏÖÎÏ ÏÎÉ ÂÕÄÕÔ ÐÒÏÄÁ×ÁÔØ Ó×ÏÊ ÐÒÏÄÕËÔ ÔÅÍ ËÏÍÕ ÎÕÖÎÁ ËÏÍÍÅÒÞÅÓËÁÑ - ÐÏÄÄÅÒÖËÁ, ÎÏ ÂÅÓÐÌÁÔÎÁÑ ×ÅÒÓÉÑ ×ÓÅÇÄÁ ÂÕÄÅÔ ÄÏÓÔÕÐÎÁ. ðÏÖÁÌÕÊÓÔÁ, - ÎÁÐÒÁ×ÌÑÊÔÅ ×ÏÐÒÏÓÙ ÎÁ ÁÄÒÅÓ postgres95@openlink.co.uk. - - ôÁËÖÅ ÐÏÓÍÏÔÒÉÔÅ ODBC ÒÁÚÄÅÌ × ÒÕËÏ×ÏÄÓÔ×Å ÐÒÏÇÒÁÍÍÉÓÔÁ. - - 2.2) ëÁËÉÅ ÉÎÓÔÒÕÍÅÎÔÙ ÓÕÝÅÓÔ×ÕÀÔ ÄÌÑ ÉÓÐÏÌØÚÏ×ÁÎÉÑ PostgreSQL ÞÅÒÅÚ Web? - - ðÒÅËÒÁÓÎÏÅ ××ÅÄÅÎÉÅ ×Ï ×ÚÁÉÍÏÄÅÊÓÔ×ÉÅ ÂÁÚ ÄÁÎÎÙÈ É Web ÍÏÖÎÏ ÎÁÊÔÉ ÎÁ: - http://www.webreview.com - - ôÁËÖÅ ÚÁÇÌÑÎÉÔÅ ÎÁ http://www.phone.net/home/mwm/hotlist/. - - äÌÑ ÉÎÔÅÇÒÁÃÉÉ Ó Web, ÏÄÎÉÍ ÉÚ ÐÒÅ×ÏÓÈÏÄÎÙÈ ÉÎÓÔÒÕÍÅÎÔÏ× Ñ×ÌÑÅÔÓÑ PHP. - äÏÍÁÛÎÑÑ ÓÔÁÎÉÞËÁ http://www.php.net. - - äÌÑ ËÏÍÐÌÅËÓÎÙÈ ÒÅÛÅÎÉÊ, ÍÎÏÇÉÅ ÐÏÌØÚÕÀÔÓÑ Perl ÉÎÔÅÒÆÅÊÓÏÍ É CGI.pm. - - 2.3) åÓÔØ ÌÉ Õ PostgreSQL ÇÒÁÆÉÞÅÓËÉÊ ÉÎÔÅÒÆÅÊÓ ÐÏÌØÚÏ×ÁÔÅÌÑ? çÅÎÅÒÁÔÏÒ - ÏÔÞÅÔÏ×? ÷ÓÔÒÏÅÎÎÙÊ ÉÎÔÅÒÆÅÊÓ ÄÌÑ ÑÚÙËÁ ÚÁÐÒÏÓÏ×? - - õ ÎÁÓ ÅÓÔØ ÐÒÅËÒÁÓÎÙÊ ÇÏÒÁÆÉÞÅÓËÉÊ ÉÎÔÅÒÆÅÊÓ, ÎÁÚÙ×ÁÅÍÙÊ pgaccess, - ËÏÔÏÒÙÊ Ñ×ÌÑÅÔÓÑ ÞÁÓÔØÀ ÄÉÓÔÒÉÂÕÔÉ×Á. pgaccess ÔÁËÖÅ ÅÍÅÅÔ ÇÅÎÅÒÁÔÏÒ - ÏÔÞÅÔÏ×. åÇÏ ÓÔÒÁÎÉÞËÁ http://www.flex.ro/pgaccess - - íÙ ÔÁËÖÅ ×ËÌÀÞÁÅÍ ecpg, ËÏÔÏÒÙÊ ÐÒÅÄÏÓÔÁ×ÌÑÅÔ ×ÓÔÒÏÅÎÎÙÊ ÉÎÔÅÒÆÅÊÓ Ë - ÑÚÙËÕ ÚÁÐÒÏÓÏ× SQL ÉÚ C. - - 2.4) ëÁËÉÅ ÑÚÙËÉ ÍÏÇÕÔ ×ÚÁÉÍÏÄÅÊÓÔ×Ï×ÁÔØ Ó PostgreSQL? - - ÷ÏÔ ÜÔÉ: - * C (libpq) - * C++ (libpq++) - * Embedded C (ecpg) - * Java (jdbc) - * Perl (perl5) - * ODBC (odbc) - * Python (PyGreSQL) - * TCL (libpgtcl) - * C Easy API (libpgeasy) - * Embedded HTML (PHP from http://www.php.net) - _________________________________________________________________ - - ÷ÏÐÒÏÓÙ ÁÄÍÉÎÉÓÔÒÉÒÏ×ÁÎÉÑ - - 3.1) ëÁË ÍÎÅ ÕÓÔÁÎÏ×ÉÔØ PostgreSQL × ÍÅÓÔÏ ÏÔÌÉÞÎÏÅ ÏÔ /usr/local/pgsql? - - úÁÄÁÊÔÅ ÏÐÃÉÀ --prefix ËÏÇÄÁ ÚÁÐÕÓËÁÅÔÅ configure. - - 3.2) ëÏÇÄÁ Ñ ÚÁÐÕÓËÁÀ postmaster, Ñ ÐÏÌÕÞÁÀ ÓÏÏÂÝÅÎÉÅ Bad System Call ÉÌÉ - ÓÏÏÂÝÅÎÉÅ core dumped. ðÏÞÅÍÕ? - - üÔÏ ÍÏÖÅÔ ÂÙÔØ ×ÙÚ×ÁÎÏ ÒÁÚÎÙÍÉ ÐÒÏÂÌÅÍÁÍÉ, ÎÏ ÐÅÒ×ÏÅ, ÞÔÏ ÎÕÖÎÏ - ÓÄÅÌÁÔØ - ÜÔÏ ÕÂÅÄÉÔØÓÑ × ÔÏÍ, ÞÔÏ × ×ÁÛÅÍ ÑÄÒÅ ÕÓÔÁÎÏ×ÌÅÎÏ ÒÁÓÛÉÒÅÎÉÅ - System V. PostgreSQL ÔÒÅÂÕÅÔ, ÞÔÏÂÙ ÑÄÒÏ ÐÏÄÄÅÒÖÉ×ÁÌÏ ÒÁÚÄÅÌÑÅÍÕÀ - ÐÁÍÑÔØ É ÓÅÍÁÆÏÒÙ. - - 3.3) ëÏÇÄÁ Ñ ÐÙÔÁÀÓØ ÚÁÐÕÓÔÉÔØ postmaster, Ñ ÐÏÌÕÞÁÀ ÏÛÉÂËÉ - IpcMemoryCreate. ðÏÞÅÍÕ? - - ìÉÂÏ Õ ×ÁÓ × ÑÄÒÅ ÎÅÐÒÁ×ÉÌØÎÙÅ ÎÁÓÔÒÏÊËÉ ÒÁÚÄÅÌÑÅÍÏÊ ÐÁÍÑÔÉ, ÌÉÂÏ - ×ÁÛÅÍÕ ÑÄÒÕ ÎÕÖÎÏ ÂÏÌØÛÅÅ ËÏÌÉÞÅÓÔ×Ï ÄÏÓÔÕÐÎÏÊ ÒÁÚÄÅÌÑÅÍÏÊ ÐÁÍÑÔÉ. ôÅ - ËÏÎËÒÅÔÎÙÅ ÄÅÊÓÔ×ÉÑ, ËÏÔÏÒÙÅ ×ÁÍ ÎÕÖÎÏ ÐÒÏÉÚ×ÅÓÔÉ ÚÁ×ÉÓÑÔ ÏÔ - ÁÒÈÉÔÅËÔÕÒÙ ×ÁÛÅÊ ÍÁÛÉÎÙ É ÏÔ ÔÏÇÏ ËÁË ÍÎÏÇÏ ÂÕÆÅÒÏ× É backend - ÐÒÏÃÅÓÓÏ× ×Ù ÎÁÓÔÒÏÉÌÉ ÄÌÑ postmaster. äÌÑ ÂÏÌØÛÉÎÓÔ×Á ÓÉÓÔÅÍ, Ó - ËÏÌÉÞÅÓÔ×ÏÍ ÂÕÆÅÒÏ× É ÐÒÏÃÅÓÓÏ× ÐÏ ÕÍÏÌÞÁÎÉÀ, ÎÅÏÂÈÏÄÉÍÙÊ ÍÉÎÉÍÕÍ - - ÜÔÏ ÏËÏÌÏ 1 ÍÅÇÁÂÁÊÔÁ. ðÏÄÒÏÂÎÏÓÔÉ Ï ÒÁÚÄÅÌÑÅÍÏÊ ÐÁÍÑÔÉ É ÓÅÍÁÆÏÒÁÈ - ÓÍÏÔÒÉÔÅ × òÕËÏ×ÏÄÓÔ×Å ÁÄÍÉÎÉÓÔÒÁÔÏÒÁ PostgreSQL. - - 3.4) ëÏÇÄÁ Ñ ÐÙÔÁÀÓØ ÚÁÐÕÓÔÉÔØ postmaster, Ñ ÐÏÌÕÞÁÀ ÏÛÉÂËÉ - IpcSemaphoreCreate. ðÏÞÅÍÕ? - - åÓÌÉ ÜÔÏ ÓÏÏÂÝÅÎÉÅ IpcSemaphoreCreate: semget failed (No space left on - device) ÔÏ ÎÁÓÔÒÏÊËÉ ×ÁÛÅÇÏ ÑÄÒÁ ÔÁËÏ×Ù, ÞÔÏ ÅÍÕ ÎÅ È×ÁÔÁÅÔ ÓÅÍÁÆÏÒÏ×. - Postgres ÔÒÅÂÕÅÔ ÏÄÉÎ ÓÅÍÁÆÏÒ ÎÁ ÐÏÔÅÎÃÉÁÌØÎÙÊ backend ÐÒÏÃÅÓÓ. - ÷ÒÅÍÅÎÎÙÍ ÒÅÛÅÎÉÅÍ Ñ×ÌÑÅÔÓÑ ÚÁÐÕÓË postmaster Ó ÎÁÓÔÒÏÊËÁÍÉ ÎÁ ÍÅÛØÛÅÅ - ËÏÌÉÞÅÓÔ×Ï backend ÐÒÏÃÅÓÓÏ×. éÓÐÏÌØÚÕÊÔÅ -N Ó ÚÎÁÞÅÎÉÅÍ ÍÅÎØÛÉÍ ÞÅÍ - 32, ËÏÔÏÒÏÅ ÐÒÉÎÑÔÏ ÐÏ ÕÍÏÌÞÁÎÉÀ. âÏÌÅÅ ÐÒÁ×ÉÌØÎÏÅ ÒÅÛÅÎÉÅ - ÜÔÏ - Õ×ÅÌÉÞÉÔØ ÚÎÁÞÅÎÉÑ SEMMNS É SEMMNI × ÎÁÓÔÒÊËÁÈ ÑÄÒÁ. - - îÅÉÓÐÒÁ×ÎÙÅ ÓÅÍÁÆÏÒÙ ÔÁËÖÅ ÍÏÇÕÔ ÐÒÉ×ÅÓÔÉ Ë ÐÁÄÅÎÉÀ óõâä ×Ï ×ÒÅÍÑ - ÄÏÓÔÕÐÁ Ë ÂÁÚÅ ÄÁÎÎÙÈ. - - åÓÌÉ ×Ù ÐÏÌÕÞÉÌÉ ËÁËÏÅ-ÌÉÂÏ ÄÒÕÇÏÅ ÓÏÏÂÝÅÎÉÅ Ï ÏÛÉÂËÅ, ÔÏ ×ÐÏÌÎÅ - ×ÏÚÍÏÖÎÏ, ÞÔÏ × ×ÁÛÅÍ ÑÄÒÅ ×ÏÏÂÝÅ ÎÅ ÎÁÓÔÒÏÅÎÁ ÐÏÄÄÅÒÖËÁ ÓÅÍÁÆÏÒÏ×. - óÍÏÔÒÉÔÅ ÐÏÄÒÏÂÎÏÓÔÉ Ï ÒÁÚÄÅÌÑÅÍÏÊ ÐÁÍÑÔÉ É ÓÅÍÁÆÏÒÁÈ × òÕËÏ×ÏÄÓÔ×Å - áÄÍÉÎÉÓÔÒÁÔÏÒÁ PostgreSQL. - - 3.5) ëÁË ÍÎÅ ÕÐÒÁ×ÌÑÔØ ÓÏÅÄÉÎÅÎÉÑÍÉ Ó ÄÒÕÇÉÈ ËÏÍÐØÀÔÅÒÏ×? - - ðÏ ÕÍÏÌÞÁÎÉÀ, PostgreSQL ÒÁÚÒÅÛÁÅÔ ÔÏÌØËÏ ÓÏÅÄÉÎÅÎÉÑ ÎÁ ÌÏËÁÌØÎÏÊ - ÍÁÛÉÎÅ ÞÅÒÅÚ ÓÏËÅÔÙ ÄÏÍÅÎÁ Unix. äÒÕÇÉÅ ÍÁÛÉÎÙ ÎÅ ÓÍÏÇÕÔ ÐÏÄËÌÀÞÉÔØÓÑ - Ë ÂÁÚÅ ÐÏËÁ ÄÌÑ postmaster ÎÅ ÂÕÄÅÔ ÚÁÄÁÎ ÆÌÁÇ -i É ÐÏËÁ ÎÅ ÂÕÄÅÔ - ÒÁÚÒÅÛÅÎÁ host-Á×ÔÏÒÉÚÁÃÉÑ × ÆÁÊÌÅ $PGDATA/pg_hba.conf. üÔÉ ÄÅÊÓÔ×ÉÑ - ÄÅÌÁÀÔ ×ÏÚÍÏÖÎÙÍÉ TCP/IP ÓÏÅÄÉÎÅÎÉÑ. - - 3.6) ëÁËÉÅ ÎÁÓÔÒÏÊËÉ ÍÎÅ ÎÕÖÎÏ ÓÄÅÌÁÔØ ÄÌÑ ÕÌÕÞÛÅÎÉÑ ÐÒÏÉÚ×ÏÄÉÔÅÌØÎÏÓÔÉ? - - îÅÓÏÍÎÅÎÎÏ, ÉÎÄÅËÓÙ ÍÏÇÕÔ Õ×ÅÌÉÞÉÔØ ÓËÏÒÏÓÔØ ×ÙÐÏÌÎÅÎÉÑ ÚÁÐÒÏÓÏ×. - ëÏÍÁÎÄÁ EXPLAIN ÐÏÚ×ÏÌÑÅÔ ×ÁÍ ÐÏÓÍÏÔÒÅÔØ ËÁË PostgreSQL ÉÎÔÅÒÐÒÅÔÉÒÕÅÔ - ×ÁÛ ÚÁÐÒÏÓ É ËÁËÉÅ ÉÎÄÅËÓÙ ÉÓÐÏÌØÚÕÀÔÓÑ. - - åÓÌÉ ×Ù ×ÙÐÏÌÎÑÅÔÅ ÍÎÏÇÏ ÏÐÅÒÁÔÏÒÏ× INSERT, ÒÁÓÓÍÏÔÒÉÔÅ ×ÏÚÍÏÖÎÏÓÔØ - ×ÙÐÏÌÎÑÔØ ÉÈ × ÂÏÌØÛÏÊ ÐÁÞËÅ, ÉÓÐÏÌØÚÕÑ ËÏÍÁÎÄÕ COPY. üÔÏ ÚÎÁÞÉÔÅÌØÎÏ - ÂÙÓÔÒÅÅ, ÞÅÍ ÏÔÄÅÌØÎÙÅ INSERT. ÷Ï-×ÔÏÒÙÈ, ÏÐÅÒÁÔÏÒÙ ×ÎÅ ÂÌÏËÁ - ÔÒÁÎÚÁËÃÉÉ BEGIN WORK/COMMIT ÓÁÍÉ ×ÙÐÏÌÎÑÀÔ ÔÒÁÎÚÁËÃÉÀ. ðÏÄÕÍÁÊÔÅ ÎÁÄ - ×ÙÐÏÌÎÅÎÉÅÍ ÎÅÓËÏÌØËÉÈ ÏÐÅÒÁÔÏÒÏ× × ÏÄÎÏÍ ÂÌÏËÅ ÔÒÁÎÚÁËÃÉÉ. üÔÏ - ÕÍÅÎØÛÉÔ ËÏÌÉÞÅÓÔ×Ï ÔÒÁÎÚÁËÃÉÊ. ôÁËÖÅ, ÚÁÄÕÍÁÊÔÅÓØ ÎÁÄ ÕÄÁÌÅÎÉÅÍ É - ÐÅÒÅÓÏÚÄÁÎÉÅÍ ÉÎÄÅËÓÏ×, ËÏÇÄÁ ×Ù ×ÙÐÏÌÎÑÅÔÅ ÂÏÌØÛÉÅ ÉÚÍÅÎÅÎÉÑ ÄÁÎÎÙÈ. - - óÕÝÅÓÔ×ÕÅÔ ÎÅÓËÏÌØËÏ ÏÐÃÉÊ ÎÁÓÔÒÏÊËÉ. ÷Ù ÍÏÖÅÔÅ ÚÁÐÒÅÔÉÔØ fsync() ÐÒÉ - ÓÔÁÒÔÅ postmaster Ó ÏÐÃÉÅÊ -o -F. üÔÏ ÐÒÅÄÏÔ×ÒÁÔÉÔ ×ÙÚÏ×Ù fsync(), - ËÏÔÏÒÙÅ ÐÒÉ×ÏÄÑÔ Ë ÓÂÒÏÓÕ ÄÁÎÎÙÈ ÎÁ ÄÉÓË ÐÏÓÌÅ ËÁÖÄÏÊ ÔÒÁÎÚÁËÃÉÉ. - - ÷Ù ÍÏÖÅÔÅ ÔÁËÖÅ ÉÓÐÏÌØÚÏ×ÁÔØ ÄÌÑ postmaster ÏÐÃÉÀ -B ÄÌÑ Õ×ÅÌÉÞÅÎÉÑ - ËÏÌÉÞÅÓÔ×Á ÂÕÆÅÒÏ× ÒÁÚÄÅÌÑÅÍÏÊ ÐÁÍÑÔÉ, ËÏÔÏÒÁÑ ÉÓÐÏÌØÚÕÅÔÓÑ backend - ÐÒÏÃÅÓÓÁÍÉ. åÓÌÉ ×Ù ÓÄÅÌÁÅÔÅ ÚÎÁÞÅÎÉÅ ÜÔÏÇÏ ÐÁÒÁÍÅÔÒÁ ÓÌÉÛËÏÍ ÂÏÌØÛÉÍ, - ÔÏ postmaster ÍÏÖÅÔ ÎÅ ÚÁÐÕÓÔÉÔÓÑ ÐÏÔÏÍÕ ÞÔÏ ×Ù ÉÓÞÅÒÐÁÅÔÅ ÏÇÒÁÎÉÞÅÎÉÅ - ÑÄÒÁ ÎÁ ÏÂßÅÍ ÒÁÚÄÅÌÑÅÍÏÊ ÐÁÍÑÔÉ. ëÁÖÄÙÊ ÂÕÆÅÒ ÉÍÅÅÔ ÒÁÚÍÅÒ × 8 - ËÉÌÏÂÁÊÔ É ÐÏ ÕÍÏÌÞÁÎÉÀ ×ÙÄÅÌÑÅÔÓÑ 64 ÂÕÆÅÒÁ. - - ÷Ù ÍÏÖÅÔÅ ÔÁËÖÅ ÉÓÐÏÌØÚÏ×ÁÔØ backend ÏÐÃÉÀ -S ÄÌÑ Õ×ÅÌÉÞÅÎÉÑ - ÍÁËÓÉÍÁÌØÎÏÇÏ ËÏÌÉÞÅÓÔ×Á ÐÁÍÑÔÉ, ËÏÔÏÒÏÅ ÉÓÐÏÌØÚÕÅÔÓÑ backend - ÐÒÏÃÅÓÓÏÍ ÄÌÑ ×ÒÅÍÅÎÎÙÈ ÓÏÒÔÉÒÏ×ÏË. úÎÁÞÅÎÉÅ ÄÌÑ ÏÐÃÉÉ -S ÚÁÄÁÅÔÓÑ × - ËÉÌÏÂÁÊÔÁÈ É ÐÏ ÕÍÏÌÞÁÎÉÀ ÒÁ×ÎÏ 512 (Ô.Å. 512K). - - ÷Ù ÔÁËÖÅ ÍÏÖÅÔÅ ÉÓÐÏÌØÚÏ×ÁÔØ ËÏÍÁÎÄÕ CLUSTER ÄÌÑ ÇÒÕÐÐÉÒÏ×ËÉ ÄÁÎÎÙÈ × - ÔÁÂÌÉÃÁÈ ÎÁ ÓÏ×ÐÁÄÁÀÝÉÊ ÉÎÄÅËÓ. ðÏÄÒÏÂÎÏÓÔÉ ÓÍÏÔÒÉÔÅ ÎÁ ÓÔÒÁÎÉÃÅ - ÒÕËÏ×ÏÄÓÔ×Á ÐÏ ËÏÍÁÎÄÅ CLUSTER. - - 3.7) ëÁËÉÅ ×ÏÚÍÏÖÎÏÓÔÉ ÄÌÑ ÏÔÌÁÄËÉ ÅÓÔØ × ÎÁÌÉÞÉÉ? - - PostgreSQL ÉÍÅÅÔ ÎÅÓËÏÌØËÏ ×ÏÚÍÏÖÎÏÓÔÅÊ, ÐÏÚ×ÏÌÑÀÝÉÅ ÐÏÌÕÞÉÔØ - ÉÎÆÏÒÍÁÃÉÀ Ï ÓÏÓÔÏÑÎÉÉ, ËÏÔÏÒÁÑ ÍÏÖÅÔ ÂÙÔØ ÉÓÐÏÌØÚÏ×ÁÎÁ × ÏÔÌÁÄÏÞÎÙÈ - ÃÅÌÑÈ. - - ÷Ï-ÐÅÒ×ÙÈ, ÐÒÉ ÚÁÐÕÓËÅ configure Ó ÏÐÃÉÅÊ --enable-cassert, ÍÎÏÇÉÅ - ×ÙÚÏ×Ù assert() ÐÏÚ×ÏÌÑÀÔ ÏÔÓÌÅÖÉ×ÁÔØ ÒÁÂÏÔÕ backend ÐÒÏÃÅÓÓÁ É - ÏÓÔÁÎÏ×ËÕ ÐÒÏÇÒÁÍÍÙ ÐÒÉ ×ÏÚÎÉËÎÏ×ÅÎÉÉ ËÁËÉÈ-ÌÉÂÏ ÎÅÏÖÉÄÁÎÎÏÓÔÅÊ. - - é postmaster, É postgres ÉÍÅÀÔ ÎÅÓËÏÌØËÏ ÏÔÌÁÄÏÞÎÙÈ ÏÐÃÉÊ. ÷Ï-ÐÅÒ×ÙÈ, - ÐÒÉ ÚÁÐÕÓËÅ postmaster, ÕÂÅÄÉÔÅÓØ, ÞÔÏ ÓÔÁÎÄÁÒÔÎÙÊ ×Ù×ÏÄ É ×Ù×ÏÄ - ÏÛÉÂÏË ÏÓÕÝÅÓÔ×ÌÑÀÔÓÑ × ÆÁÊÌ ÖÕÒÎÁÌÁ: - cd /usr/local/pgsql - ./bin/postmaster >server.log 2>&1 & - - üÔÏ ÐÒÉ×ÅÄÅÔ Ë ÐÏÑ×ÌÅÎÉÀ ÆÁÊÌÁ server.log × ÇÌÁ×ÎÏÍ ËÁÔÁÌÏÇÅ - PostgreSQL. üÔÏÔ ÆÁÊÌ ÓÏÄÅÒÖÉÔ ÐÏÌÅÚÎÕÀ ÉÎÆÏÒÍÁÃÉÀ Ï ÐÒÏÂÌÅÍÁÈ ÉÌÉ - ÏÛÉÂËÁÈ, ×ÏÚÎÉËÛÉÈ ÎÁ ÓÅÒ×ÅÒÅ. Postmaster ÉÍÅÅÔ ÏÐÃÉÀ -d, ËÏÔÏÒÁÑ - ÐÏÚ×ÏÌÑÅÔ ÐÏÌÕÞÁÔØ ÐÒÉ ÐÒÏÔÏËÏÌÉÒÏ×ÁÎÉÉ ÂÏÌÅÅ ÄÅÔÁÌØÎÕÀ ÉÎÆÒÍÁÃÉÀ. äÌÑ - ÏÐÃÉÉ -d ÕËÁÚÙ×ÁÅÔÓÑ ÞÉÓÌÏ, ËÏÔÏÒÏÅ ÚÁÄÁÅÔ ÕÒÏ×ÅÎØ ÏÔÌÁÄËÉ. âÕÄØÔÅ - ÏÓÔÏÒÏÖÎÙ, ÔÁË ËÁË ×ÙÓÏËÉÊ ÕÒÏ×ÅÎØ ÏÔÌÁÄËÉ ÐÒÉ×ÏÄÉÔ Ë ÇÅÎÅÒÁÃÉÉ ÆÁÊÌÏ× - ÖÕÒÎÁÌÁ ÂÏÌØÛÏÇÏ ÒÁÚÍÅÒÁ. - - åÓÌÉ postmaster ÎÅ ÚÁÐÕÝÅÎ, ×Ù ÍÏÖÅÔÅ ÚÁÐÕÓÔÉÔØ postgres backend ÉÚ - ËÏÍÁÎÄÎÏÊ ÓÔÒÏËÉ É ××ÅÓÔÉ ×ÁÛ ÏÐÅÒÁÔÏÒ SQL ÎÁÐÒÑÍÕÀ. üÔÏ ÒÅËÏÍÅÎÄÕÅÔÓÑ - ÔÏÌØËÏ ÄÌÑ ÃÅÌÅÊ ÏÔÌÁÄËÉ. úÁÍÅÔÉÍ, ÞÔÏ × ÜÔÏÍ ÒÅÖÉÍÅ, ÚÁÐÒÏÓ - ÚÁ×ÅÒÛÁÅÔÓÑ ÓÉÍ×ÏÌÏÍ ÎÏ×ÏÊ ÓÔÒÏËÉ, Á ÎÅ ÔÏÞËÏÊ Ó ÚÁÐÑÔÏÊ. åÓÌÉ ×Ù - ÐÒÏÉÚ×ÏÄÉÌÉ ËÏÍÐÉÌÑÃÉÀ Ó ÏÔÌÁÄÏÞÎÙÍÉ ÓÉÍ×ÏÌÏÁÍÉ, ×Ù ÍÏÖÅÔÅ - ÉÓÐÏÌØÚÏ×ÁÔØ ÌÀÂÏÊ ÏÔÌÁÄÞÉË, ÞÔÏÂÙ ÐÏÓÍÏÔÒÅÔØ, ÞÔÏ ÓÌÕÞÉÌÏÓØ. - ðÏÓËÏÌØËÕ backend ÚÁÐÕÓËÁÅÔÓÑ ÎÅ ÉÚ postmaster, ÏÎ ÎÅ ÚÁÐÕÓËÁÅÔÓÑ × - ÉÄÅÎÔÉÞÎÏÍ ÏËÒÕÖÅÎÉÉ É ÚÎÁÞÉÔ ÐÒÏÂÌÅÍÙ ÉÔÅÒÁÃÉÊ ÂÌÏËÉÒÏ×ÏË/backend ÎÅ - ÍÏÇÕÔ ÂÙÔØ ×ÏÓÐÒÏÉÚ×ÅÄÅÎÙ. - - åÓÌÉ postmaster ÚÁÐÕÝÅÎ, ÚÁÐÕÓÔÉÔÅ psql × ÏÄÎÏÍ ÏËÎÅ, ÚÁÔÅÍ ÎÁÊÄÉÔÅ - PID ÐÒÏÃÅÓÓÁ postgres, ÉÓÐÏÌØÚÕÅÍÙÊ psql. éÓÐÏÌØÚÕÊÔÅ ÏÔÄÁÄÞÉË ÄÌÑ - ÐÏÄËÌÀÞÅÎÉÑ Ë postgres PID. ÷Ù ÍÏÖÅÔÅ ÕÓÔÁÎÏ×ÉÔØ ÔÏÞËÉ ÐÒÅÒÙ×ÁÎÉÑ × - ÏÔÌÁÄÞÉËÅ É ÚÁÐÕÓÔÉÔØ ÚÁÐÒÏÓ ÉÚ psql. åÓÌÉ ×Ù ÐÒÏÉÚ×ÏÄÉÔÅ ÏÔÌÁÄËÕ - ÚÁÐÕÓËÁ postgres, ×Ù ÍÏÖÅÔÅ ÕÓÔÁÎÏ×ÉÔØ PGOPTIONS="-W n", É ÚÁÔÅÍ - ÚÁÐÕÓÔÉÔØ psql. üÔÁ ÏÐÃÉÑ ÐÒÉ×ÏÄÉÔ Ë ÚÁÄÅÒÖËÅ ÐÒÏÃÅÓÓÁ ÚÁÐÕÓËÁ ÎÁ n - ÓÅËÕÎÄ, × ÔÅÞÅÎÉÅ ËÏÔÏÒÙÈ ×Ù ÍÏÖÅÔÅ ÐÏÄËÌÀÞÉÔØ Ë ÐÒÏÃÅÓÓÕ ÏÔÌÁÄÞÉË, - ÕÓÔÁÎÏ×ÉÔØ ÌÀÂÙÅ ÔÏÞËÉ ÐÒÅÒÙ×ÁÎÉÑ É ÐÒÏÄÏÌÖÉÔØ ÚÁÐÕÓË. - - ðÒÏÇÒÁÍÍÁ postgres ÉÍÅÅÔ ÏÐÃÉÉ -s, -A, É -t ËÏÔÏÒÙÅ ÍÏÇÕÔ ÂÙÔØ ÏÞÅÎØ - ÐÏÌÅÚÎÙÍÉ ÄÌÑ ÏÔÌÁÄËÉ É ÉÚÍÅÒÅÎÉÑ ÐÒÏÉÚ×ÏÄÉÔÅÌØÎÏÓÔÉ. - - ÷Ù ÔÁËÖÅ ÍÏÖÅÔÅ ÓËÏÍÐÉÌÉÒÏ×ÁÔØ PostgreSQL Ó ÐÒÏÆÉÌÉÒÏ×ÁÎÉÅÍ ÄÌÑ ÔÏÇÏ, - ÞÔÏÂÙ Õ×ÉÄÅÔØ ËÁËÉÅ ÆÕÎËÃÉÉ ÓËÏÌØËÏ ×ÒÅÍÅÎÉ ×ÙÐÏÌÎÑÀÔÓÑ. æÁÊÌÙ - ÐÒÏÆÉÌÉÒÏ×ÁÎÉÑ backend'Á ÎÁÈÏÄÑÔÓÑ × ËÁÔÁÌÏÇÅ pgsql/data/base/dbname. - æÁÊÌ ÐÒÏÆÉÌÉÒÏ×ÁÎÉÑ ËÌÉÅÎÔÁ ÂÕÄÅÔ ÐÏÍÅÝÅÎ × ÔÅËÕÝÉÊ ËÁÔÁÌÏÇ ËÌÉÅÎÔÁ. ÷ - Linux ÄÌÑ ×ÙÐÏÌÎÅÎÉÑ ÐÒÏÆÉÌÉÒÏ×ÁÎÉÑ ÔÒÅÂÕÅÔÓÑ ËÏÍÐÉÌÑÃÉÉ Ó - -DLINUX_PROFILE. - - 3.8) ðÏÞÅÍÕ Ñ ÐÏÌÕÞÁÀ ÓÏÏÂÝÅÎÉÅ "Sorry, too many clients" ËÏÇÄÁ ÐÙÔÁÀÓØ - ÐÏÄËÌÀÞÉÔØÓÑ Ë ÂÁÚÅ? - - ÷ÁÍ ÎÕÖÎÏ Õ×ÅÌÉÞÉÔØ ÏÇÒÁÎÉÞÅÎÉÅ ÎÁ ËÏÌÉÞÅÓÔ×Ï ËÏÎËÕÒÅÔÎÙÈ backend - ÐÒÏÃÅÓÓÏ× ÐÒÉ ÚÁÐÕÓËÅ postmaster. - - ðÏ ÕÍÏÌÞÁÎÉÀ ÕÓÔÁÎÏ×ÌÅÎ ÌÉÍÉÔ ÎÁ 32 ÐÒÏÃÅÓÓÁ. ÷Ù ÍÏÖÅÔÅ Õ×ÅÌÉÞÉÔØ ÜÔÏÔ - ÌÉÍÉÔ ÐÅÒÅÚÁÐÕÓÔÉ× postmaster Ó ÎÕÖÎÙÍ ÚÎÁÞÅÎÉÅÍ ÐÒÏÃÅÓÓÏ×, ËÏÔÏÒÏÅ - ÕËÁÚÙ×ÁÅÔÓÑ × ÏÐÃÉÉ -N ÉÌÉ ÉÚÍÅÎÉ× ÆÁÊÌ postgresql.conf. - - úÁÍÅÔÉÍ, ÞÔÏ ÅÓÌÉ ×Ù ÚÁÄÁÄÉÔÅ × ÏÐÃÉÉ -N ÚÎÁÞÅÎÉÅ ÂÏÌØÛÅ 32, ÔÏ ×Ù - ÔÁËÖÅ ÄÏÌÖÎÙ Õ×ÅÌÉÞÉÔØ ÚÎÁÞÅÎÉÅ × ÏÐÃÉÉ -B ËÏÔÏÒÏÅ ÐÏ ÕÍÏÌÞÁÎÉÀ - ÕÓÔÁÎÏ×ÌÅÎÏ × 64; úÎÁÞÅÎÉÅ ÏÐÃÉÉ -B ÄÏÌÖÎÏ ÂÙÔØ ÐÏ ËÒÁÊÎÅÊ ÍÅÒÅ ×Ä×ÏÅ - ÂÏÌØÛÅ ÚÎÁÞÅÎÉÑ ÏÐÃÉÉ -N, É ×ÏÚÍÏÖÎÏ ÅÝ£ ÂÏÌØÛÅ ÄÌÑ ÌÕÞÛÅÊ - ÐÒÏÉÚ×ÏÄÉÔÅÌØÎÏÓÔÉ. äÌÑ ÂÏÌØÛÅÇÏ ËÏÌÉÞÅÓÔ×Á backend ÐÒÏÃÅÓÓÏ×, ×ÁÍ - ÔÁËÖÅ ÎÅÐÌÏÈÏ ÂÙÌÏ ÂÙ Õ×ÅÌÉÞÉÔØ ÎÅËÏÔÏÒÙÅ ÐÁÒÁÍÅÔÒÙ ÑÄÒÁ Unix. üÔÏ - ÔÁËÉÅ ÐÁÒÁÍÅÔÒÙ, ËÁË ÍÁËÓÉÍÁÌØÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÂÌÏËÏ× ÒÁÚÄÅÌÑÅÍÏÊ - ÐÁÍÑÔÉ, SHMMAX; ÍÁËÓÉÍÁÌØÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÓÅÍÁÆÏÒÏ×, SEMMNS É SEMMNI; - ÍÁËÓÉÍÁÌØÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÐÒÏÃÅÓÓÏ×, NPROC; ÍÁËÓÉÍÁÌØÎÏÅ ËÏÌÉÞÅÓÔ×Ï - ÐÒÏÃÅÓÓÏ× ÎÁ ÐÏÌØÚÏ×ÁÔÅÌÑ, MAXUPRC; É ÍÁËÓÉÍÁÌØÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÏÔËÒÙÔÙÈ - ÆÁÊÌÏ×, NFILE É NINODE. ðÒÉÞÉÎÁ ÓÏÚÄÁÎÉÑ ÏÇÒÁÎÉÞÅÎÉÑ ÎÁ ËÏÌÉÞÅÓÔ×Ï - backend ÐÒÏÃÅÓÓÏ× ËÁË ÒÁÚ É ÓÏÓÔÏÉÔ × ÔÏÍ, ÞÔÏÂÙ ×ÁÛÅÊ ÓÉÓÔÅÍÅ È×ÁÔÉÌÏ - ÒÅÓÕÒÓÏ×. - - ÷ PostgreSQL ÄÏ ×ÅÒÓÉÉ 6.5, ÍÁËÓÉÍÁÌØÎÏÅ ËÏÌÉÞÅÓÔ×Ï backend ÐÒÏÃÅÓÓÏ× - ÂÙÌÏ 64, É ÉÚÍÅÎÅÎÉÅ ÜÔÏÇÏ ËÏÌÉÞÅÓÔ×Á ÔÒÅÂÏ×ÁÌÏ ÐÅÒÅËÏÍÐÉÌÑÃÉÉ ÐÏÓÌÅ - ÕÓÔÁÎÏ×ËÉ ËÏÎÓÔÁÎÔÙ MaxBackendId × include/storage/sinvaladt.h. - - 3.9) þÔÏ ÜÔÏ ÚÁ ÆÁÊÌÙ pg_sorttempNNN.NN × ÍÏÅÍ ËÁÔÁÌÏÇÅ Ó ÂÁÚÏÊ ÄÁÎÎÙÈ? - - üÔÏ ×ÒÅÍÅÎÎÙÅ ÆÁÊÌÙ, ÇÅÎÅÒÉÒÕÅÍÙÅ ×Ï ×ÒÅÍÑ ×ÙÐÏÌÎÅÎÉÑ ÚÁÐÒÏÓÁ. - îÁÐÒÉÍÅÒ, ÅÓÌÉ ÄÌÑ ÏÐÅÒÁÔÏÒÁ ORDER BY ÄÏÌÖÎÁ ÂÙÔØ ×ÙÐÏÌÎÅÎÁ - ÓÏÒÔÉÒÏ×ËÁ, ËÏÔÏÒÁÑ ÔÒÅÂÕÅÔ ÂÏÌØÛÅ ÍÅÓÔÁ ÞÅÍ ×ÙÄÅÌÅÎÎÏ ÄÌÑ backend - ÐÒÏÃÅÓÓÁ × ÏÐÃÉÉ -S, ÔÏ ÓÏÚÄÁÅÔÓÑ ×ÒÅÍÅÎÎÙÊ ÆÁÊÌ ÄÌÑ ÈÒÁÎÅÎÉÑ - ÄÏÐÏÌÎÉÔÅÌØÎÙÈ ÄÁÎÎÙÈ. - - ÷ÒÅÍÅÎÎÙÅ ÆÁÊÌÙ ÄÏÌÖÎÙ ÕÄÁÌÑÔØÓÑ Á×ÔÏÍÁÔÉÞÅÓËÉ, ÎÏ ÜÔÏÇÏ ÍÏÖÅÔ ÎÅ - ÐÒÏÉÓÈÏÄÉÔØ, ÅÓÌÉ backend ÐÒÏÃÅÓÓ ÐÁÄÁÅÔ ×Ï ×ÒÅÍÑ ÓÏÒÔÉÒÏ×ËÉ. åÓÌÉ Õ - ×ÁÓ ÎÅ ÚÁÐÕÝÅÎÏ ÎÉ ÏÄÎÏÇÏ backend ÐÒÏÃÅÓÓÁ, ÔÏ ×Ù ÍÏÖÅÔÅ ÓÐÏËÏÊÎÏ - ÕÄÁÌÉÔØ ÆÁÊÌÙ pg_tempNNN.NN. - _________________________________________________________________ - - ÷ÏÐÒÏÓÙ ÜËÓÐÌÕÁÔÁÃÉÉ - - 4.1) ÷ ÞÅÍ ÏÔÌÉÞÉÅ ÍÅÖÄÕ ÂÉÎÁÒÎÙÍ É ÎÏÒÍÁÌØÎÙÍ ËÕÒÓÏÒÏÍ? - - óÍÏÔÒÉÔÅ ÏÐÉÓÁÎÉÅ ÎÁ ÓÔÒÁÎÉÃÁÈ ÒÕËÏ×ÏÄÓÔ×Á ÐÏÓ×ÑÝÅÎÎÙÍ DECLARE. - - 4.2) ëÁË ×ÙÐÏÌÎÉÔØ SELECT ÔÏÌØËÏ ÄÌÑ ÎÅÓËÏÌØËÉÈ ÐÅÒ×ÙÈ ÓÔÒÏÞÅË ÚÁÐÒÏÓÁ? - - óÍÏÔÒÉÔÅ ÓÔÁÎÉÃÕ ÒÕËÏ×ÏÄÓÔ×Á ÐÏÓ×ÑÝÅÎÎÕÀ FETCH ÉÌÉ ÉÓÐÏÌØÚÕÊÔÅ SELECT - ... LIMIT.... - - äÁÖÅ ÅÓÌÉ ×Ù ÈÏÔÉÔÅ ÐÏÌÕÞÉÔØ ÔÏÌØËÏ ÐÅÒ×ÙÅ ÎÅÓËÏÌØËÏ ÚÁÐÉÓÅÊ, ÂÕÄÅÔ - ×ÙÐÏÌÎÅÎ ×ÅÓØ ÚÁÐÒÏÓ. òÁÓÓÍÏÔÒÉÍ ÚÁÐÒÏÓ, ËÏÔÏÒÙÊ ÉÍÅÅÔ ORDER BY. åÓÌÉ - ÅÓÔØ ËÁËÏÊ-ÌÉÂÏ ÉÎÄÅËÓ, ËÏÔÏÒÙÊ ÓÏ×ÐÁÄÁÅÔ Ó ORDER BY, PostgreSQL ÍÏÖÅÔ - ×ÙÄÁÔØ ÔÏÌØËÏ ÎÅÓËÏÌØËÏ ÐÅÒ×ÙÈ ÚÁÐÒÏÛÅÎÎÙÈ ÚÁÐÉÓÅÊ ÉÌÉ ÍÏÖÅÔ ×ÙÐÏÌÎÑÔØ - ÚÁÐÒÏÓ ÐÏËÁ ÎÅ ÂÕÄÕÔ ×ÙÄÁÎÙ ÖÅÌÁÅÍÙÅ ÚÁÐÉÓÉ. - - 4.3) ëÁË ÐÏÌÕÞÉÔØ ÓÐÉÓÏË ÔÁÂÌÉà ÉÌÉ ÄÒÕÇÉÈ ËÏÍÐÏÎÅÎÔÏ× × psql? - - ÷Ù ÍÏÖÅÔÅ ÐÏÓÍÏÔÒÅÔØ ÉÓÈÏÄÎÙÊ ËÏÄ psql × ÆÁÊÌÅ - pgsql/src/bin/psql/describe.c. ïÎ ÓÏÄÅÒÖÉÔ ËÏÍÁÎÄÙ SQL ËÏÔÏÒÙÅ - ÇÅÎÅÒÉÒÕÀÔÓÑ ÐÒÉ ××ÏÄÅ × psql ËÏÍÁÎÄ, ÎÁÞÉÎÁÀÝÉÈÓÑ Ó ÏÂÒÁÔÎÏÊ ËÏÓÏÊ - ÞÅÒÔÙ. ÷Ù ÔÁËÖÅ ÍÏÅÖÅÔÅ ÚÁÐÕÓÔÉÔØ psql Ó ÏÐÃÉÅÊ -E ÔÁË, ÞÔÏÂÙ ÜÔÁ - ÐÒÏÇÒÁÍÍÁ ×ÙÄÁ×ÁÌÁ ÚÁÐÒÏÓÙ, ËÏÔÏÒÙÅ ÏÎÁ ÉÓÐÏÌØÚÕÅÔ ÄÌÑ ×ÙÐÏÌÎÅÎÉÑ - ÚÁÄÁÎÎÙÈ ×ÁÍÉ ËÏÍÁÎÄ. - - 4.4) ëÁË ÕÄÁÌÉÔØ ËÏÌÏÎËÕ ÉÚ ÔÁÂÌÉÃÙ? - - íÙ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÍ ALTER TABLE DROP COLUMN, ÎÏ ÍÏÖÎÏ ÓÄÅÌÁÔØ ÔÁË: - BEGIN; - LOCK TABLE old_table; - SELECT ... -- ×ÙÂÏÒËÁ ×ÓÅÈ ËÏÌÏÎÏË ÚÁ ÉÓËÌÀÞÅÎÉÅÍ ÔÏÊ, ËÏÔÏÒÕÀ ÈÏÔÉÔÅ ÕÄÁÌ -ÉÔØ - INTO TABLE new_table - FROM old_table; - DROP TABLE old_table; - ALTER TABLE new_table RENAME TO old_table; - COMMIT; - - 4.5) ëÁËÏ×Ù ÍÁËÓÉÍÁÌØÎÙÅ ÒÁÚÍÅÒÙ ÄÌÑ ÚÁÐÉÓÅÊ, ÔÁÂÌÉÃ É ÂÁÚÙ ÄÁÎÎÙÈ? - - óÕÝÅÓÔ×ÕÀÔ ÓÌÅÄÕÀÝÉÅ ÏÇÒÁÎÉÞÅÎÉÑ: - íÁËÓÉÍÁÌØÎÙÊ ÒÁÚÍÅÒ ÂÁÚÙ? ÎÅÏÇÒÁÎÉÞÅÎ (ÓÕÝÅÓÔ×ÕÀÔ ÂÁÚÙ ÎÁ 60 G -B) - íÁËÓÉÍÁÌØÎÙÊ ÒÁÚÍÅÒ ÔÁÂÌÉÃÙ? 16 TB - íÁËÓÉÍÁÌØÎÙÊ ÒÁÚÍÅÒ ÚÁÐÉÓÉ? ÎÅÏÇÒÁÎÉÞÅÎ ÎÁÞÉÎÁÑ Ó ×ÅÒÓÉÉ 7.1 - íÁËÓÉÍÁÌØÎÙÊ ÒÁÚÍÅÒ ÐÏÌÑ? 1 GB ÎÁÞÉÎÁÑ Ó ×ÅÒÓÉÉ 7.1 - íÁËÓÉÍÁÌØÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÚÁÐÉÓÅÊ × ÔÁÂÌÉÃÅ? ÎÅÏÇÒÁÎÉÞÅÎÏ - íÁËÓÉÍÁÌØÎÏÅ ËÏÌÉÞÅÓÔ×Ï ËÏÌÏÎÏË × ÔÁÂÌÉÃÅ? 250-1600 × ÚÁ×ÉÓÉÍÏÓÔÉ ÏÔ ÔÉÐ -Á - íÁËÓÉÍÁÌØÎÏÅ ËÏÌÉÞÅÓÔ×Ï ÉÎÄÅËÓÏ× × ÔÁÂÌÉÃÅ? ÎÅÏÇÒÁÎÉÞÅÎÏ - - òÁÚÕÍÅÅÔÓÑ, ÐÏÎÑÔÉÅ "ÎÅÏÇÒÁÎÉÞÅÎÏ" ÎÁ ÓÁÍÏÍ ÄÅÌÅ ÏÇÒÁÎÉÞÉ×ÁÅÔÓÑ - ÄÏÓÔÕÐÎÙÍ ÄÉÓËÏ×ÙÍ ÐÒÏÓÔÒÁÎÉÓÔ×ÏÍ É ÒÁÚÍÅÒÁÍÉ ÐÁÍÑÔÉ/Ó×ÏÐÐÉÎÇÁ. ëÏÇÄÁ - ÚÎÁÞÅÎÉÑ ÐÅÒÅÞÉÓÌÅÎÎÙÅ ×ÙÛÅ ÎÅÏÐÒÁ×ÄÁÎÏ ÂÏÌØÛÉÅ, ÍÏÖÅÔ ÐÏÓÔÒÁÄÁÔØ - ÐÒÏÉÚ×ÏÄÉÔÅÌØÎÏÓÔØ. - - íÁËÓÉÍÁÌØÎÙÊ ÒÁÚÍÅÒ ÔÁÂÌÉÃÙ × 16 TB ÎÅ ÔÒÅÂÕÅÔ ÞÔÏÂÙ ÏÐÅÒÁÃÉÏÎÎÁÑ - ÓÉÓÔÅÍÁ ÐÏÄÄÅÒÖÉ×ÁÌÁ ÆÁÊÌÙ ÂÏÌØÛÉÈ ÒÁÚÍÅÒÏ×. âÏÌØÛÉÅ ÔÁÂÌÉÃÙ ÈÒÁÎÑÔÓÑ - ËÁË ÍÎÏÖÅÓÔ×Ï ÆÁÊÌÏ× ÒÁÚÍÅÒÏÍ × 1 GB, ÔÁË ÞÔÏ ÏÇÒÁÎÉÞÅÎÉÑ, ËÏÔÏÒÙÅ - ÎÁËÌÁÄÙ×ÁÅÔ ÆÁÊÌÏ×ÁÑ ÓÉÓÔÅÍÁ ÎÅ ×ÁÖÎÙ. - - íÁËÓÉÍÁÌØÎÙÊ ÒÁÚÍÅÒ ÔÁÂÌÉÃÙ É ÍÁËÓÉÍÁÌØÎÏÅ ËÏÌÉÞÅÓÔ×Ï ËÏÌÏÎÏË ÍÏÇÕÔ - ÂÙÔØ Õ×ÅÌÉÞÅÎÙ, ÅÓÌÉ ÒÁÚÍÅÒ ÂÌÏËÁ ÐÏ ÕÍÏÌÞÁÎÉÀ ÂÕÄÅÔ Õ×ÅÌÉÞÅÎ ÄÏ 32k. - - 4.6) ëÁË ÍÎÏÇÏ ÄÉÓËÏ×ÏÇÏ ÐÒÏÓÔÒÁÎÓÔ×Á × ÂÁÚÅ ÄÁÎÎÙÈ ÎÕÖÎÏ ÄÌÑ ÓÏÈÒÁÎÅÎÉÑ - ÄÁÎÎÙÈ ÉÚ ÏÂÙÞÎÏÇÏ ÔÅËÓÔÏ×ÏÇÏ ÆÁÊÌÁ? - - óõâä PostgreSQL ÍÏÖÅÔ ÐÏÔÒÅÂÏ×ÁÔØÓÑ ÄÉÓËÏ×ÏÇÏ ÐÒÏÓÔÒÁÎÓÔ×Á ÄÏ 5 ÒÁÚ - ÂÏÌØÛÅ ÄÌÑ ÓÏÈÒÁÎÅÎÉÑ ÄÁÎÎÙÈ ÉÚ ÐÒÏÓÔÏÇÏ ÔÅËÓÔÏ×ÏÇÏ ÆÁÊÌÁ. - - ÷ ËÁÞÅÓÔ×Å ÐÒÉÍÅÒÁ, ÒÁÓÓÍÏÔÒÉÍ ÆÁÊÌ × 100,000 ÓÔÒÏË × ËÁÖÄÏÊ, ÉÚ - ËÏÔÏÒÙÈ ÃÅÌÏÅ ÞÉÓÌÏ É ÔÅËÓÔÏ×ÏÅ ÏÐÉÓÁÎÉÅ. ðÒÉ ÜÔÏÍ ÄÌÉÎÁ ÔÅËÓÔÁ, × - ÓÒÅÄÎÅÍ, ÓÏÓÔÁ×ÌÑÅÔ 20 ÂÁÊÔ. òÁÚÍÅÒ ÐÒÏÓÔÏÇÏ ÆÁÊÌÁ ÓÏÓÔÁ×ÉÔ 2.8 MB. - òÁÚÍÅÒ ÂÁÚÙ PostgreSQL, ÓÏÄÅÒÖÁÝÅÊ ÜÔÉ ÖÅ ÄÁÎÎÙÅ ÓÏÓÔÁ×ÉÔ - ÐÒÉÂÌÉÚÉÔÅÌØÎÏ 6.4 MB ÉÚ ËÏÔÏÒÙÈ: - 36 ÂÁÊÔ: ÎÁ ËÁÖÄÙÊ ÚÁÇÏÌÏ×ÏË ÚÁÐÉÓÉ (ÐÒÉÂÌÉÚÉÔÅÌØÎÏ) - + 24 ÂÁÊÔÁ: ÏÄÎÏ ÐÏÌÅ Ó ÃÅÌÏÞÉÓÌÅÎÎÙÍ ÔÉÐÏÍ É ÏÄÎÏ ÔÅËÓÔÏ×ÏÅ ÐÏÌÅ - + 4 ÂÁÊÔÁ: ÕËÁÚÁÔÅÌØ ÎÁ ÓÔÒÁÎÉÃÅ ÄÌÑ ×ÓÅÊ ÚÁÐÉÓÉ - ---------------------------------------- - 64 ÂÁÊÔ ÎÁ ÚÁÐÉÓØ - - òÁÚÍÅÒ ÓÔÒÁÎÉÃÙ ÄÁÎÎÙÈ × PostgreSQL ÓÏÓÔÁ×ÌÑÅÔ 8192 ÂÁÊÔ (8 KB), ÔÁË ÞÔÏ: - - 8192 ÂÁÊÔ ÎÁ ÓÔÒÁÎÉÃÕ - ------------------- = 128 ÚÁÐÉÓÅÊ ÎÁ ÓÔÒÁÎÉÃÕ âä (Ó ÏËÒÕÇÌÅÎÉÅÍ) - 64 ÂÁÊÔ ÎÁ ÚÁÐÉÓØ - - 100000 ÓÔÒÏË ÄÁÎÎÙÈ - -------------------- = 782 ÓÔÒÁÎÉÃÙ × âä - 128 ÚÁÐÉÓÅÊ ÎÁ ÓÔÒÁÎÉÃÕ - -782 ÓÔÒÁÎÉÃÙ âä * 8192 ÂÁÊÔ ÎÁ ÓÔÒÁÎÉÃÕ = 6,406,144 ÂÁÊÔ (6.4 MB) - - éÎÄÅËÓÙ ÎÅ ÔÒÅÂÕÀÔ ÔÁË ÍÎÏÇÏ, ÎÏ ÐÏÓËÏÌØËÕ ÏÎÉ ÓÏÚÄÁÀÔÓÑ ÄÌÑ ÂÏÌØÛÏÇÏ - ËÏÌÉÞÅÓÔ×Á ÄÁÎÎÙÈ, ÏÎÉ ÔÁËÖÅ ÍÏÇÕÔ ÂÙÔØ ×ÅÌÉËÉ. - - 4.7) ëÁË ÍÎÅ ÕÂÅÄÉÔØÓÑ, ÞÔÏ ÓÕÝÅÓÔ×ÕÀÔ ÎÕÖÎÙÅ ÍÎÅ ÔÁÂÌÉÃÙ, ÉÎÄÅËÓÙ, ÂÁÚÙ - ÄÁÎÎÙÈ É ÐÏÌØÚÏ×ÁÔÅÌÉ? - - psql ÉÍÅÅÔ ÎÅÓËÏÌØËÏ ËÏÍÁÎÄ, ÎÁÞÉÎÁÀÝÉÈÓÑ Ó ÏÂÒÁÔÎÏÊ ËÏÓÏÊ ÞÅÒÔÙ, ÄÌÑ - ÔÏÇÏ ÞÔÏÂÙ ÐÒÏÓÍÁÔÒÉ×ÁÔØ ÔÁËÕÀ ÉÎÆÏÒÍÁÃÉÀ. éÓÐÏÌØÚÕÊÔÅ \? ÄÌÑ ÔÏÇÏ, - ÞÔÏÂÙ Õ×ÉÄÅÔØ ÜÔÉ ËÏÍÁÎÄÙ. ôÁËÖÅ ÓÕÝÅÓÔ×ÕÀÔ ÓÉÓÔÅÍÎÙÅ ÔÁÂÌÉÃÙ, ÉÍÑ - ËÏÔÏÒÙÈ ÎÁÞÉÎÁÅÔÓÑ ÎÁ pg_ É × ËÏÔÏÒÙÈ ÔÁËÖÅ ÓÏÄÅÒÖÉÔÓÑ ÜÔÁ ÉÎÆÏÒÍÁÃÉÑ. - åÝ£, psql -l ÐÏËÁÖÅÔ ÓÐÉÓÏË ×ÓÅÈ ÂÁÚ ÄÁÎÎÙÈ. - - ôÁËÖÅ ÓÍÏÔÒÉÔÅ ÆÁÊÌ pgsql/src/tutorial/syscat.source. ÷ ÎÅÍ - ÐÒÅÄÓÔÁ×ÌÅÎÙ ÍÎÏÇÉÅ ÏÐÅÒÁÔÏÒÙ SELECT ËÏÔÏÒÙÅ ÎÕÖÎÙ ÄÌÑ ÐÏÌÕÞÅÎÉÑ - ÉÎÆÏÒÍÁÃÉÉ ÉÚ ÓÉÓÔÅÍÎÙÈ ÔÁÂÌÉà ÂÁÚÙ ÄÁÎÎÙÈ. - - 4.8) õ ÍÅÎÑ ÍÅÄÌÅÎÎÏ ÒÁÂÏÔÁÀÔ ÚÁÐÒÏÓÙ ÉÌÉ ÎÅ ÐÒÏÉÓÈÏÄÉÔ ÉÓÐÏÌØÚÏ×ÁÎÉÑ - ÉÎÄÅËÓÏ×. ðÏÞÅÍÕ? - - éÎÄÅËÓÙ ÎÅ ÉÓÐÏÌØÚÕÀÔÓÑ ÄÌÑ ËÁÖÄÏÇÏ ÚÁÐÒÏÓÁ Á×ÔÏÍÁÔÉÞÅÓËÉ. ïÎÉ - ÉÓÐÏÌØÚÕÀÔÓÑ ÔÏÌØËÏ ÅÓÌÉ ÔÁÂÌÉÃÁ ÂÏÌØÛÅ ÍÉÎÉÍÁÌØÎÏÇÏ ÒÁÚÍÅÒÁ É ÚÁÐÒÏÓ - ×ÙÂÉÒÁÅÔ ÔÏÌØËÏ ÍÁÌÅÎØËÉÊ ÐÒÏÃÅÎÔ ÚÁÐÉÓÅÊ × ÔÁÂÌÉÃÅ. ôÁË ÕÓÔÒÏÅÎÏ, - ÐÏÔÏÍÕ ÞÔÏ ÄÏÓÔÕÐ Ë ÄÉÓËÕ Ó ÐÒÉÍÅÎÅÎÉÅÍ ÒÁÎÄÏÍÉÚÁÃÉÉ ÐÒÉ ÓËÁÎÉÒÏ×ÁÎÉÉ - ÉÎÄÅËÓÏ× ÉÎÏÇÄÁ ÍÅÄÌÅÎÎÅÅ, ÞÅÍ ÐÒÏÓÔÏÅ ÞÔÅÎÉÅ ÔÁÂÌÉÃÙ ÉÌÉ ÅÅ - ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÅ ÓËÁÎÉÒÏ×ÁÎÉÅ. - - þÔÏÂÙ ÏÐÒÅÄÅÌÉÔØ ÎÅÏÂÈÏÄÉÍÏÓÔØ ÉÓÐÏÌØÚÏ×ÁÎÉÑ ÉÎÄÅËÓÁ ÄÌÑ ËÁËÏÊ-ÌÉÂÏ - ÔÁÂÌÉÃÙ, PostgreSQL ÄÏÌÖÅÎ ÉÍÅÔØ ÓÔÁÔÉÓÔÉËÕ ÐÏ ÜÔÏÊ ÔÁÂÌÉÃÅ. üÔÁ - ÓÔÁÔÉÓÔÉËÁ ÓÏÂÉÒÁÅÔÓÑ ÐÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ VACUUM ANALYZE ÉÌÉ ÐÒÏÓÔÏ - ANALYZE. éÓÐÏÌØÚÕÑ ÓÔÁÔÉÓÔÉËÕ, ÏÐÔÉÍÉÚÁÔÏÒ ÕÚÎÁÅÔ Ï ÔÏÍ ËÁË ÍÎÏÇÏ - ÚÁÐÉÓÅÊ × ÔÁÂÌÉÃÅ É ÅÓÌÉ ÏÎ ÄÏÌÖÅÎ ÉÓÐÏÌØÚÏ×ÁÔØ ÉÎÄÅËÓÙ, ÔÏ ÏÎ ÍÏÖÅÔ - ÐÒÉÎÉÍÁÔØ ÌÕÞÛÉÅ ÒÅÛÅÎÉÑ. óÔÁÔÉÓÔÉËÁ ÔÁËÖÅ ×ÌÉÑÅÔ ÎÁ ÏÐÒÅÄÅÌÅÎÉÅ - ÏÐÔÉÍÁÌØÎÏÇÏ ÐÏÒÑÄËÁ Ó×ÑÚÙ×ÁÎÉÑ É ÍÅÔÏÄÁ Ó×ÑÚÙ×ÁÎÉÑ. óÂÏÒ ÓÔÁÔÉÓÔÉËÉ - ÄÏÌÖÅÎ ÐÅÒÉÏÄÉÞÅÓËÉ ×ÙÐÏÌÎÑÔÓÑ ÐÒÉ ÉÚÍÅÎÅÎÉÉ ÓÏÄÅÒÖÉÍÏÇÏ ÔÁÂÌÉÃÙ. - - ïÂÙÞÎÏ ÉÎÄÅËÓÙ ÎÅ ÉÓÐÏÌØÚÕÀÔÓÑ ÄÌÑ ORDER BY ÉÌÉ ÄÌÑ ×ÙÐÏÌÎÅÎÉÑ - Ó×ÑÚÙ×ÁÎÉÊ. ðÏÓÌÅÄÏ×ÁÔÅÌØÎÙÊ ÐÅÒÅÂÏÒ ÓÌÅÄÕÀÝÉÊ ÚÁ Ñ×ÎÏÊ ÓÏÒÔÉÒÏ×ËÏÊ - ÏÂÙÞÎÏ ÂÙÓÔÒÅÅ, ÞÅÍ ÐÏÉÓË ÐÏ ÉÎÄÅËÓÁÍ × ÂÏÌØÛÏÊ ÔÁÂÌÉÃÅ. ïÄÎÁËÏ, ORDER - BY ÞÁÓÔÏ ËÏÍÂÉÎÉÒÕÅÔÓÑ Ó LIMIT É × ÜÔÏÍ ÓÌÕÞÁÅ ÉÎÄÅËÓ ÂÕÄÅÔ - ÉÓÐÏÌØÚÏ×ÁÔØÓÑ, ÐÏÓËÏÌØËÕ ÐÒÉ ×ÙÐÏÌÎÅÎÉÉ ÂÕÄÅÔ ×ÏÚ×ÒÁÝÁÔØÓÑ ÎÅÂÏÌØÛÁÑ - ÞÁÓÔØ ÔÁÂÌÉÃÙ. - - ëÏÇÄÁ ÉÓÐÏÌØÚÕÀÔÓÑ ÏÐÅÒÁÃÉÉ Ó ÛÁÂÌÏÎÁÍÉ, ÎÁÐÒÉÍÅÒ LIKE ÉÌÉ ~, ÉÎÄÅËÓÙ - ÍÏÇÕÔ ÂÙÔØ ÉÓÐÏÌØÚÏ×ÁÎÙ ÔÏÌØËÏ ÅÓÌÉ ÎÁÞÁÌÏ ÓÔÒÏËÉ-ÛÁÂÌÏÎÁ ÄÌÑ ÐÏÉÓËÁ, - ÓÏÏÔ×ÅÔÓÔ×ÕÅÔ ÎÁÞÁÌÕ ÉÓËÏÍÏÊ ÓÔÒÏËÉ. óÌÅÄÏ×ÁÔÅÌØÎÏ, ÄÌÑ ÔÏÇÏ, ÞÔÏÂÙ - ÉÓÐÏÌØÚÏ×ÁÔØ ÉÎÄÅËÓÙ, ÛÁÂÌÏÎ × LIKE ÎÅ ÄÏÌÖÅÎ ÎÁÞÉÎÁÔØÓÑ ÎÁ %, Á × ~ - (ÐÏÉÓË ÒÅÇÕÌÑÒÎÏÇÏ ×ÙÒÁÖÅÎÉÑ) ÄÏÌÖÅÎ ÎÁÞÉÎÁÔØÓÑ ÎÁ ^. - - 4.9) ëÁË ÐÏÓÍÏÔÒÅÔØ ÎÁ ÔÏ, ËÁË ÏÐÔÉÍÉÚÁÔÏÒ ×ÙÐÏÌÎÑÅÔ ÍÏÊ ÚÁÐÒÏÓ? - - óÍÏÔÒÉÔÅ ÓÔÒÁÎÉÃÕ ÒÕËÏ×ÏÄÓÔ×Á ÐÏÓ×ÑÝÅÎÎÕÀ EXPLAIN. - - 4.10) þÔÏ ÔÁËÏÅ R-tree ÉÎÄÅËÓ? - - R-tree ÉÎÄÅËÓ ÉÓÐÏÌØÚÕÅÔÓÑ ÄÌÑ ÉÎÄÅËÓÉÒÏ×ÁÎÉÑ ÐÒÏÓÔÒÁÎÓÔ×ÅÎÎÙÈ ÄÁÎÎÙÈ. - éÎÄÅËÓ ÈÜÛÁ ÎÅ ÍÏÖÅÔ ÕÐÒÁ×ÌÑÔØ ÐÏÉÓËÁÍÉ ÄÉÁÐÁÚÏÎÁ. B-tree ÉÎÄÅËÓ - ÕÐÒÁ×ÌÑÅÔ ÔÏÌØËÏ ÐÏÉÓËÁÍÉ ÄÉÁÐÁÚÏÎÁ × ÏÄÎÏÍ ÉÚÍÅÒÅÎÉÉ. R-tree ÉÎÄÅËÓ - ÍÏÖÅÔ ÕÐÒÁ×ÌÑÔØ ÍÎÏÇÏÒÁÚÍÅÒÎÙÍÉ ÄÁÎÎÙÍÉ. îÁÐÒÉÍÅÒ, ÅÓÌÉ R-tree ÉÎÄÅËÓ - ÍÏÖÅÔ ÂÙÔØ ×ÓÔÒÏÅÎ × ÁÔÒÉÂÕÔ ÔÉÐÁ point, ÔÏ ÓÉÓÔÅÍÁ ÍÏÖÅÔ ÂÏÌÅÅ - ÜÆÆÅËÔÉ×ÎÏ ÏÔ×ÅÔÉÔØ ÎÁ ÚÁÐÒÏÓ ÔÉÐÁ "×ÙÂÒÁÔØ ×ÓÅ ÔÏÞËÉ ×ÎÕÔÒÉ ÚÁÄÁÎÎÏÇÏ - ÞÅÔÙÒÅÈÕÇÏÌØÎÉËÁ." - - ëÁÎÏÎÉÞÅÓËÉÊ ÉÓÔÏÞÎÉË, ÏÐÉÓÙ×ÁÀÝÉÊ ÐÅÒ×ÏÎÁÞÁÌØÎÏÅ ÓÏÚÄÁÎÉÅ R-tree ÜÔÏ: - - Guttman, A. "R-trees: A Dynamic Index Structure for Spatial - Searching." Proceedings of the 1984 ACM SIGMOD Int'l Conf on Mgmt of - Data, 45-57. - - ÷Ù ÍÏÖÅÔÅ ÎÁÊÔÉ ÜÔÏÔ ÄÏËÕÍÅÎÔ × ËÎÉÇÅ Stonebraker'Á "Readings in - Database Systems". - - ÷ÓÔÒÏÅÎÎÎÙÅ R-tree ÍÏÇÕÔ ÕÐÒÁ×ÌÑÔØ ÐÏÌÉÇÏÎÁÍÉ É ÂÏËÓÁÍÉ. ÷ ÔÅÏÒÉÉ, - R-tree ÍÏÇÕÔ ÂÙÔØ ÒÁÓÛÉÒÅÎÙ ÄÌÑ ÕÐÒÁ×ÌÅÎÉÑ ÂÏÌØÛÉÍ ËÏÌÉÞÅÓÔ×ÏÍ - ÉÚÍÅÒÅÎÉÊ. îÁ ÐÒÁËÔÉËÅ, ÒÁÓÛÉÒÅÎÉÅ R-tree ÔÒÅÂÕÅÔ ÎÅËÏÔÏÒÙÈ ÕÓÉÌÉÊ É Õ - ÎÁÓ, × ÄÁÎÎÙÊ ÍÏÍÅÎÔ, ÎÅÔ ËÁËÏÊ-ÌÉÂÏ ÄÏËÕÍÅÎÔÁÃÉÉ Ï ÔÏÍ, ËÁË ÜÔÏ - ÓÄÅÌÁÔØ. - - 4.11) þÔÏ ÔÁËÏÅ Genetic Query Optimizer? - - íÏÄÕÌØ GEQO ÐÒÏÉÚ×ÏÄÉÔ ÂÙÓÔÒÕÀ ÏÐÔÉÍÉÚÁÃÉÀ ÚÁÐÒÏÓÁ, ËÏÇÄÁ ÐÒÏÉÓÈÏÄÉÔ - Ó×ÑÚÙ×ÁÎÉÅ ÍÎÏÇÉÈ ÔÁÂÌÉà ÞÅÒÅÚ Genetic Algorithm (GA). üÔÏ ÐÏÚ×ÏÌÑÅÔ - ÕÐÒÁ×ÌÑÔØ ÂÏÌØÛÉÍÉ ÚÁÐÒÏÓÁÍÉ ÎÁ Ó×ÑÚÙ×ÁÎÉÅ ÞÅÒÅÚ ÎÅÉÓÔÏÝÁÀÝÉÊ ÐÏÉÓË. - - 4.12) ëÁË ÍÎÅ ×ÙÐÏÌÎÉÔØ ÐÏÉÓË ÒÅÇÕÌÑÒÎÏÇÏ ×ÙÒÁÖÅÎÉÑ É ÐÏÉÓË ÎÅÚÁ×ÉÓÉÍÙÊ ÏÔ - ÒÅÇÉÓÔÒÁ ÂÕË× ÐÏÉÓË ÒÅÇÕÌÑÒÎÏÇÏ ×ÙÒÁÖÅÎÉÑ? ëÁË ÍÎÅ ÉÓÐÏÌØÚÏ×ÁÔØ ÉÎÄÅËÓ ÄÌÑ - ÐÏÉÓËÁ ÎÅÚÁ×ÉÓÉÍÏÇÏ ÏÔ ÒÅÇÉÓÔÒÁ ÂÕË×? - - ïÐÅÒÁÔÏÒ ~ ÐÒÏÉÚ×ÏÄÉÔ ÐÏÉÓË ÒÅÇÕÌÑÒÎÏÇÏ ×ÙÒÁÖÅÎÉÑ, Á ÏÐÅÒÁÔÏÒ ~* - ÐÒÏÉÚ×ÏÄÉÔ ÎÅÚÁ×ÉÓÉÍÙÊ ÏÔ ÒÅÇÉÓÔÒÁ ÂÕË× ÐÏÉÓË ÒÅÇÕÌÑÒÎÏÇÏ ×ÙÒÁÖÅÎÉÑ. - îÅÚÁ×ÉÓÉÍÙÊ ÏÔ ÒÅÇÉÓÔÒÁ ×ÁÒÉÁÎÔ LIKE ÎÁÚÙ×ÁÅÔÓÑ ILIKE × PostgreSQL - ÎÁÞÉÎÁÑ Ó ×ÅÒÓÉÉ 7.1. - - îÅÚÁ×ÉÓÉÍÏÅ ÏÔ ÒÅÇÉÓÔÒÁ ÓÒÁ×ÎÅÎÉÅ ÏÂÙÞÎÏ ×ÙÒÁÖÁÅÔÓÑ ÔÁË: - SELECT * - FROM tab - WHERE lower(col) = 'abc' - - üÔÁ ËÏÎÓÔÒÕËÃÉÑ ÎÅ ÂÕÄÅÔ ÉÓÐÏÌØÚÏ×ÁÔØ ÓÔÁÎÄÁÒÔÎÙÊ ÉÎÄÅËÓ. ïÄÎÁËÏ, ÅÓÌÉ - ×Ù ÓÏÚÄÁÄÉÔÅ ÆÕÎËÃÉÏÎÁÌØÎÙÊ ÉÎÄÅËÓ, ÏÎ ÂÕÄÅÔ ÉÓÐÏÌØÚÏ×ÁÎ: - CREATE INDEX tabindex on tab (lower(col)); - - 4.13) ëÁË Ñ ÍÏÇÕ ÏÐÒÅÄÅÌÉÔØ, ÞÔÏ ÚÎÁÞÅÎÉÅ ÐÏÌÑ ÒÁ×ÎÏ NULL × ËÁËÏÍ-ÌÉÂÏ - ÚÁÐÒÏÓÅ? - - ÷Ù ÐÒÏÓÔÏ ÓÒÁ×ÎÉ×ÁÅÔÅ ÚÎÁÞÅÎÉÅ Ó IS NULL É IS NOT NULL. - - 4.14) ëÁËÏ×Ù ÏÔÌÉÞÉÑ ÍÅÖÄÕ ÒÁÚÎÙÍÉ ÓÉÍ×ÏÌØÎÙÍÉ ÔÉÐÁÍÉ? - -ôÉÐ ÷ÎÕÔÒÅÎÎÅÅ ÉÍÑ úÁÍÅÞÁÎÉÑ --------------------------------------------------- -"char" char 1 ÓÉÍ×ÏÌ -CHAR(#) bpchar ÚÁÐÏÌÎÑÅÔÓÑ ÐÕÓÔÏÔÏÊ ÄÏ ÆÉËÓÉÒÏ×ÁÎÎÏÊ ÄÌÉÎÙ -VARCHAR(#) varchar ÒÁÚÍÅÒ ÚÁÄÁÅÔ ÍÁËÓÉÍÁÌØÎÕÀ ÄÌÉÎÕ, ÎÅÔ ÚÁÐÏÌÎÅÎÉ -Ñ -TEXT text ÎÅÔ ÚÁÄÁ×ÁÅÍÏÇÏ ×ÅÒÈÎÅÇÏ ÏÇÒÁÎÉÞÅÎÉÑ ÉÌÉ ÄÌÉÎÙ -BYTEA bytea ÍÁÓÓÉ× ÂÁÊÔ ÐÅÒÅÍÅÎÎÏÊ ÄÌÉÎÙ (ÍÏÖÎÏ ÉÓÐÏÌØÚÏ×ÁÔ -Ø null-ÂÁÊÔ ÂÅÚ ÏÐÁÓËÉ) - - ÷ÎÕÔÒÅÎÎÅÅ ÉÍÑ ×Ù ÍÏÖÅÔÅ Õ×ÉÄÅÔØ, ËÏÇÄÁ ÓÍÏÔÒÉÔÅ ÓÉÓÔÅÍÎÙÅ ËÁÔÁÌÏÇÉ É - × ÎÅËÏÔÏÒÙÈ ÓÏÏÂÝÅÎÉÑÈ Ï ÏÛÉÂËÁÈ. - - ðÏÓÌÅÄÎÉÅ ÞÅÔÙÒÅ ÔÉÐÁ Ñ×ÌÑÀÔÓÑ "varlena" ÔÉÐÁÍÉ (Ô.Å., ÐÅÒ×ÙÅ ÞÅÔÙÒÅ - ÂÁÊÔÁ ÎÁ ÄÉÓËÅ Ñ×ÌÑÀÔÓÑ ÄÌÉÎÎÏÊ, ÚÁ ËÏÔÏÒÏÊ ÓÌÅÄÕÀÔ ÄÁÎÎÙÅ). ôÁËÉÍ - ÏÂÒÁÚÏÍ, ÆÁËÔÉÞÅÓËÉ ÉÓÐÏÌØÚÕÅÍÏÅ ÐÒÏÓÔÒÁÎÓÔ×Ï ÂÏÌØÛÅ, ÞÅÍ ÏÂÏÚÎÁÞÅÎÎÙÊ - ÒÁÚÍÅÒ. ïÄÎÁËÏ, ÜÔÉ ÔÉÐÙ ÄÁÎÎÙÈ ÔÁËÖÅ ÐÏÄÄÁÀÔÓÑ ÓÖÁÔÉÀ ÉÌÉ ÍÏÇÕÔ ÂÙÔØ - ÓÏÈÒÁÎÅÎÙ ÎÅ × ÓÔÒÏËÏÍ ×ÉÄÅ ÞÅÒÅÚ TOAST, ÔÁË ÞÔÏ ÚÁÎÉÍÁÅÍÏÅ ÄÉÓËÏ×ÏÅ - ÐÒÏÓÔÒÁÎÓÔ×Ï ÍÏÖÅÔ ÔÁËÖÅ ÂÙÔØ É ÍÅÎØÛÅ, ÞÅÍ ÏÖÉÄÁÌÏÓØ. - - CHAR() - ÜÔÏ ÌÕÞÛÅÅ ÒÅÛÅÎÉÅ ÄÌÑ ÈÒÁÎÅÎÉÑ ÓÔÒÏË, ËÏÔÏÒÙÅ ÏÂÙÞÎÏ ÉÍÅÀÔ - ÏÄÉÎÁËÏ×ÕÀ ÄÌÉÎÕ. VARCHAR() - ÜÔÏ ÌÕÞÛÅÅ ÒÅÛÅÎÉÅ, ËÏÇÄÁ ÎÕÖÎÏ ÈÒÁÎÉÔØ - ÓÔÒÏËÉ ÐÅÒÅÍÅÎÎÏÊ ÄÌÉÎÙ, ÎÏ ÎÅ ÐÒÅ×ÙÛÁÀÝÉÅ ÏÐÒÅÄÅÌÅÎÎÏÇÏ ÒÁÚÍÅÒÁ. TEXT - - ÜÔÏ ÌÕÞÛÅÅ ÒÅÛÅÎÉÅ ÄÌÑ ÓÔÒÏË ÎÅÏÇÒÁÎÉÞÅÎÎÏÊ ÄÌÉÎÙ, Ó ÍÁËÓÉÍÁÌØÎÏ - ÄÏÐÕÓÔÉÍÏÊ ÄÌÉÎÏÊ × 1 ÇÉÇÁÂÁÊÔ. BYTEA ÄÌÑ ÈÒÁÎÅÎÉÑ ÂÉÎÁÒÎÙÈ ÄÁÎÎÙÈ, - ÚÎÁÞÅÎÉÑ ËÏÔÏÒÙÈ ÍÏÇÕÔ ×ËÌÀÞÁÔØ NULL ÂÁÊÔÙ. - - 4.15.1) ëÁË ÍÎÅ ÓÏÚÄÁÔØ ÐÏÌÅ serial/Ó-Á×ÔÏ-Õ×ÅÌÉÞÅÎÉÅÍ? - - PostgreSQL ÐÏÄÄÅÒÖÉ×ÁÅÔ ÔÉÐ ÄÁÎÎÙÈ SERIAL. ïÎ Á×ÔÏÍÁÔÉÞÅÓËÉ ÓÏÚÄÁÅÔ - ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ É ÉÎÄÅËÓ ÄÌÑ ËÏÌÏÎËÉ. îÁÐÒÉÍÅÒ: - CREATE TABLE person ( - id SERIAL, - name TEXT - ); - - Á×ÔÏÍÁÔÉÞÅÓËÉ ÔÒÁÎÓÌÉÒÕÅÔÓÑ ×: - CREATE SEQUENCE person_id_seq; - CREATE TABLE person ( - id INT4 NOT NULL DEFAULT nextval('person_id_seq'), - name TEXT - ); - CREATE UNIQUE INDEX person_id_key ON person ( id ); - - óÍÏÔÒÉÔÅ ÐÏÄÒÏÂÎÏÓÔÉ Ï ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔÑÈ ÎÁ ÓÔÒÁÎÉÃÅ ÒÕËÏ×ÏÄÓÔ×Á - ÐÏÓ×ÑÝÅÎÎÏÊ create_sequence. ÷Ù ÔÁËÖÅ ÍÏÖÅÔÅ ÉÓÐÏÌØÚÏ×ÁÔØ ËÁÖÄÏÅ ÐÏÌÅ - OID × ÚÁÐÉÓÉ ËÁË ÕÎÉËÁÌØÎÏÅ ÚÎÁÞÅÎÉÅ. ïÄÎÁËÏ, ÅÓÌÉ ×ÁÍ ÎÕÖÅÎ ÄÁÍÐ É - ÐÅÒÅÚÁÇÒÕÚËÁ ÂÁÚÙ ÄÁÎÎÙÈ, ×ÁÍ ÎÅÏÂÈÏÄÉÍÏ ÉÓÐÏÌØÚÏ×ÁÔØ ËÏÍÁÎÄÕ pg_dump - Ó ÏÐÃÉÅÊ -o ÉÌÉ ÏÐÃÉÀ COPY WITH OIDS ÄÌÑ ÓÏÈÒÁÎÅÎÉÑ ÚÎÁÞÅÎÉÊ ÐÏÌÑ OID. - - 4.15.2) ëÁË ÍÎÅ ÐÏÌÕÞÉÔØ ÚÎÁÞÅÎÉÅ ÐÒÉ ×ÓÔÁ×ËÅ SERIAL? - - ïÄÉÎ ÉÚ ÓÐÏÓÏÂÏ× ÓÏÓÔÏÉÔ × ÐÏÌÕÞÅÎÉÉ ÓÌÅÄÕÀÝÅÇÏ ÚÎÁÞÅÎÉÑ SERIAL ÉÚ - ÏÂßÅËÔÁ sequence Ó ÐÏÍÏÝØÀ ÆÕÎËÃÉÉ nextval() ÐÅÒÅÄ ×ÓÔÁ×ËÏÊ É ÚÁÔÅÍ - ×ÓÔÁ×ÌÑÔØ ÜÔÏ ÚÎÁÞÅÎÉÅ Ñ×ÎÏ. éÓÐÏÌØÚÕÊÔÅ ÔÁÂÌÉÃÕ-ÐÒÉÍÅÒ × 4.15.1, - ÞÔÏÂÙ Õ×ÉÄÅÔØ ËÁË ÜÔÏ ÄÅÌÁÅÔÓÑ × Perl: - new_id = output of "SELECT nextval('person_id_seq')" - INSERT INTO person (id, name) VALUES (new_id, 'Blaise Pascal'); - - úÁÔÅÍ ×Ù ÄÏÌÖÎÙ ÔÁËÖÅ ÓÏÈÒÁÎÉÔØ ÎÏ×ÏÅ ÚÎÁÞÅÎÉÅ × ÐÅÒÅÍÅÎÎÏÊ new_id ÄÌÑ - ÅÇÏ ÉÓÐÏÌØÚÏ×ÁÎÉÑ × ÄÒÕÇÉÈ ÚÁÐÒÏÓÁÈ (ÎÁÐÒÉÍÅÒ ÔÁËÉÈ ËÁË ×ÎÅÛÎÉÊ ËÌÀÞ - ÄÌÑ ÔÁÂÌÉÃÙ person). úÁÍÅÔÉÍ, ÞÔÏ ÉÍÑ Á×ÔÏÍÁÔÉÞÅÓËÉ ÓÏÚÄÁÎÎÏÇÏ ÏÂßÅËÔÁ - SEQUENCE ÂÕÄÅÔ
__seq, ÇÄÅ table É serialcolumn - Ñ×ÌÑÀÔÓÑ ÓÏÏÔ×ÅÔÓÔ×ÅÎÎÏ ÉÍÅÎÁÍÉ ×ÁÛÅÊ ÔÁÂÌÉÃÙ É ×ÁÛÅÊ ËÏÌÏÎËÉ SERIAL. - - ÷ ËÁÞÅÓÔ×Å ÁÌØÔÅÒÎÁÔÉ×Ù, ×Ù ÍÏÖÅÔÅ ÐÏÌÕÞÉÔØ ÎÁÚÎÁÞÅÎÎÏÅ ÚÎÁÞÅÎÉÅ - SERIAL Ó ÐÏÍÏÝØÀ ÆÕÎËÃÉÉ currval() ÐÏÓÌÅ ÐÒÏ×ÅÄÅÎÉÑ ÏÂÙÞÎÏÊ ÏÐÅÒÁÃÉÉ - ×ÓÔÁ×ËÉ, ÎÁÐÒÉÍÅÒ - INSERT INTO person (name) VALUES ('Blaise Pascal'); - new_id = output of "SELECT currval('person_id_seq')"; - - é ÎÁËÏÎÅÃ, ×Ù ÍÏÖÅÔÅ ÉÓÐÏÌØÚÏ×ÁÔØ ÚÎÁÞÅÎÉÅ OID, ×ÏÚÒÁÝÁÅÍÏÅ ÉÚ - ÏÐÅÒÔÏÒÁ INSERT ÞÔÏÂÙ Õ×ÉÄÅÔØ ÚÎÁÞÅÎÉÅ ÐÏ ÕÍÏÌÞÁÎÉÀ, ÞÔÏ - ÐÒÅÄÐÏÌÏÖÉÔÅÌØÎÏ Ñ×ÌÑÅÔÓÑ ÎÁÉÍÅÎÅÅ ÐÅÒÅÎÏÓÉÍÙÍ ÎÁ ÄÒÕÇÉÅ ÐÌÁÔÆÏÒÍÙ - ÒÅÛÅÎÉÅÍ. ÷ Perl, ÉÓÐÏÌØÚÕÑ DBI Ó ÍÏÄÕÌÅÉ Edmund Mergl'Ñ DBD::Pg, - ÚÎÁÞÅÎÉÅ oid ÓÔÁÎÏ×ÉÔÓÑ ÄÏÓÔÕÐÎÙÍ ÞÅÒÅÚ $sth->{pg_oid_status} ÐÏÓÌÅ - $sth->execute(). - - 4.15.3) îÅ ÍÏÖÅÔ ÌÉ ÐÏÌÕÞÉÔØÓÑ ÔÁË, ÞÔÏ ÉÓÐÏÌØÚÏ×ÁÎÉÅ currval() É nextval() - ÐÒÉ×ÅÄÅÔ Ë ÚÁÃÉËÌÉÒÏ×ÁÎÉÀ Ó ÄÒÕÇÉÍÉ ÐÏÌØÚÏ×ÁÔÅÌÑÍÉ? - - îÅÔ. Currval() ×ÏÚ×ÒÁÝÁÅÔ ÔÅËÕÝÅÅ ÚÎÁÞÅÎÉÅ, ÎÁÚÎÁÞÅÎÎÏÅ ×ÁÛÅÍ - backend'ÏÍ, Á ÎÅ ÄÒÕÇÉÍÉ ÐÏÌØÚÏ×ÁÔÅÌÑÍÉ. - - 4.15.4) ðÏÞÅÍÕ ÞÉÓÌÁ ÉÚ ÍÏÅÊ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔÉ ÎÅ ÉÓÐÏÌØÚÕÀÔÓÑ ÓÎÏ×Á ÐÒÉ - ÏÔÍÅÎÅ ÔÒÁÎÚÁËÃÉÉ? ðÏÞÅÍÕ ÓÏÚÄÁÀÔÓÑ ÒÁÚÒÙ×Ù ÐÒÉ ÎÕÍÅÒÁÃÉÉ × ËÏÌÏÎËÅ, ÇÄÅ Ñ - ÉÓÐÏÌØÚÕÀ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔØ/SERIAL? - - äÌÑ ÒÅÁÌÉÚÁÃÉÉ ËÏÎËÕÒÅÔÎÏÓÔÉ, ÚÎÁÞÅÎÉÑ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÓÔÅÊ, ÐÒÉ - ÎÅÏÂÈÏÄÉÍÏÓÔÉ ×ÙÄÁÀÔÓÑ ×Ï ×ÒÅÍÑ ÚÁÐÕÓËÁ ÔÒÁÎÚÁËÃÉÊ É ÎÅ ÂÌÏËÉÒÕÀÔÓÑ ÄÏ - ÐÏÌÎÏÇÏ ×ÙÐÏÌÎÅÎÉÑ ÔÒÁÎÚÁËÃÉÊ. üÔÏ ÍÏÖÅÔ ×ÙÚÙ×ÁÔØ ÒÁÚÒÙ×Ù × ÎÕÍÅÒÁÃÉÉ - ÐÒÉ ÏÔÍÅÎÅ ÔÒÁÎÚÁËÃÉÊ. - - 4.16) þÔÏ ÔÁËÏÅ OID? þÔÏ ÔÁËÏÅ TID? - - ðÏÌÑ OID ÓÌÕÖÁÔ ÕÎÉËÁÌØÎÙÍÉ ÉÄÅÔÉÆÉËÁÔÏÒÁÍÉ ÚÁÐÉÓÅÊ × PostgreSQL. - ëÁÖÄÁÑ ÚÁÐÉÓØ, ËÏÔÏÒÁÑ ÓÏÚÄÁ£ÔÓÑ × PostgreSQL ÐÏÌÕÞÁÅÔ ÕÎÉËÁÌØÎÙÊ OID. - ÷ÓÅ ÚÎÁÞÅÎÉÑ OID ÇÅÎÅÒÉÒÕÅÍÙÅ ×Ï ×ÒÅÍÑ initdb ÉÍÅÀÔ ÚÎÁÞÅÎÉÑ ÍÅÎØÛÅ - 16384 (ÉÚ backend/access/transam.h). ÷ÓÅ ÓÏÚÄÁÎÎÙÅ ÐÏÌØÚÏ×ÁÔÅÌÅÍ OID - ÉÍÅÀÔ ÂïÌØÛÉÅ ÚÎÁÞÅÎÉÅ. ðÏ ÕÍÏÌÞÁÎÉÀ, ×ÓÅ ÜÔÉ OID Ñ×ÌÑÀÔÓÑ ÕÎÉËÁÌØÎÙÍÉ - ÎÅ ÔÏÌØËÏ ×ÎÕÔÒÉ ËÁËÏÊ-ÌÉÂÏ ÔÁÂÌÉÃÙ ÉÌÉ ÂÁÚÙ ÄÁÎÎÙÈ, ÎÏ É ×ÎÕÔÒÉ ×ÓÅÊ - óõâä PostgreSQL. - - PostgreSQL ÉÓÐÏÌØÚÕÅÔ OID × Ó×ÏÉÈ ×ÎÕÔÒÅÎÎÉÈ ÓÉÓÔÅÍÎÙÈ ÔÁÂÌÉÃÁÈ ÄÌÑ - Ó×ÑÚÉ ÚÁÐÉÓÅÊ É ÔÁÂÌÉÃ. úÎÁÞÅÎÉÑ OID ÍÏÇÕÔ ÂÙÔØ ÉÓÐÏÌØÚÏ×ÁÎÙ ÄÌÑ - ÉÄÅÎÔÉÆÉËÁÃÉÉ ÚÁÄÁÎÎÙÈ ÐÏÌØÚÏ×ÁÔÅÌÅÍ ÚÁÐÉÓÅÊ, Á ÔÁËÖÅ ÉÓÐÏÌØÚÏ×ÁÔØÓÑ - ÐÒÉ Ó×ÑÚÙ×ÁÎÉÑÈ. òÅËÏÍÅÎÄÕÅÔÓÑ ÉÓÐÏÌØÚÏ×ÁÔØ ÔÉÐ ËÏÌÏÎËÉ OID ÄÌÑ - ÈÒÁÎÅÎÉÑ ÚÎÁÞÅÎÉÊ OID ÷Ù ÍÏÖÅÔÅ ÓÏÚÄÁÔØ ÉÎÄÅËÓ ÎÁ ÐÏÌÅ OID ÄÌÑ ÂÏÌÅÅ - ÂÙÓÔÒÏÇÏ ÄÏÓÔÕÐÁ. - - úÎÁÞÅÎÉÑ OID ÎÁÚÎÁÞÁÀÔÓÑ ÄÌÑ ×ÓÅÈ ÎÏ×ÙÈ ÚÁÐÉÓÅÊ ÉÚ ÃÅÎÔÒÁÌØÎÏÊ - ÏÂÌÁÓÔÉ, ËÏÔÏÒÙÅ ÉÓÐÏÌØÚÕÀÔÓÑ ×ÓÅÍÉ ×ÓÅÍÉ ÂÁÚÁÍÉ ÄÁÎÎÙÈ. åÓÌÉ ×Ù - ÈÏÔÉÔÅ ÉÚÍÅÎÉÔØ OID ÎÁ ËÁËÏÅ-ÌÉÂÏ ÄÒÕÇÏÅ ÚÎÁÞÅÎÉÅ ÉÌÉ ÅÓÌÉ ×Ù ÈÏÔÉÔÅ - ÓÏÚÄÁÔØ ËÏÐÉÀ ÔÁÂÌÉÃÙ Ó ÔÁËÉÍÉÖÅ OID, ÔÏ ÜÔÏ ÍÏÖÎÏ ÓÄÅÌÁÔØ ÔÁË: - CREATE TABLE new_table(old_oid oid, mycol int); - SELECT old_oid, mycol INTO new FROM old; - COPY new TO '/tmp/pgtable'; - DELETE FROM new; - COPY new WITH OIDS FROM '/tmp/pgtable'; - - OID ÈÒÁÎÉÔÓÑ ËÁË 4-È ÂÁÊÔÎÏÅ ÃÅÌÏÅ É ÎÅ ÍÏÖÅÔ ÐÒÅ×ÙÛÁÔØ ÚÎÁÞÅÎÉÅ × 4 - ÍÉÌÌÉÁÒÄÁ. ïÄÎÁËÏ, ÅÝÅ ÎÉËÔÏ ÎÅ ÓÏÏÂÝÉÌ Ï ÔÏÍ, ÞÔÏ ÔÁËÏÅ ÐÒÏÉÚÏÛÌÏ, ÎÏ - ÍÙ ÐÌÁÎÉÒÕÅÍ ÄÏ ÔÏÇÏ ËÁË ÜÔÏ ÓÌÕÞÉÔØÓÑ ÉÚÂÁ×ÉÔÓÑ ÏÔ ÜÔÏÇÏ ÏÇÒÁÎÉÞÅÎÉÑ. - - TID ÉÓÐÏÌØÚÕÅÔÓÑ ÄÌÑ ÉÄÅÎÔÉÆÉËÁÃÉÉ ÓÐÅÃÉÁÌØÎÙÈ ÆÉÚÉÞÅÓËÉÈ ÚÁÐÉÓÅÊ Ó - ÂÌÏÞÎÙÍÉ É offset ÚÎÁÞÅÎÉÑÍÉ. TID ÉÚÍÅÎÑÅÔÓÑ ÐÏÓÌÅ ÔÏÇÏ ËÁË ÚÁÐÉÓÉ - ÂÙÌÉ ÉÚÍÅÎÅÎÙ ÉÌÉ ÐÅÒÅÇÒÕÖÅÎÙ. - - TID ÉÓÐÏÌØÚÕÅÔÓÑ ÉÎÄÅËÓÎÙÍÉ ÚÁÐÉÓÑÍÉ × ËÁÞÅÓÔ×Å ÕËÁÚÁÔÅÌÑ ÎÁ - ÆÉÚÉÞÅÓËÉÅ ÚÁÐÉÓÉ. - - 4.17) þÔÏ ÏÚÎÁÞÁÀÔ ÎÅËÏÔÏÒÙÅ ÔÅÒÍÉÎÙ ÉÓÐÏÌØÚÕÅÍÙÅ × PostgreSQL? - - îÅËÏÔÏÒÙÊ ÉÓÈÏÄÎÙÊ ËÏÄ É ÓÔÁÒÁÑ ÄÏËÕÍÅÎÔÁÃÉÑ ÉÓÐÏÌØÚÕÀÔ - ÏÂÝÅÕÐÏÔÒÅÂÉÔÅÌØÎÙÅ ÔÅÒÍÉÎÙ. ÷ÏÔ ÎÅËÏÔÏÒÙÅ ÉÚ ÎÉÈ: - * table, relation, class - * row, record, tuple - * column, field, attribute - * retrieve, select - * replace, update - * append, insert - * OID, serial value - * portal, cursor - * range variable, table name, table alias - - óÐÉÓÏË ÏÂÝÉÈ ÔÅÒÍÉÎÏ× ÐÏ ÂÁÚÁÍ ÄÁÎÎÙÈ ÍÏÖÎÏ ÎÁÊÔÉ ÎÁ - http://www.comptechnews.com/~reaster/dbdesign.html - - 4.18) ðÏÞÅÍÕ Ñ ÐÏÌÕÞÁÀ ÏÛÉÂËÕ "ERROR: Memory exhausted in AllocSetAlloc()"? - - åÓÌÉ Õ ×ÁÓ ×ÅÒÓÉÑ ÎÉÖÅ 7.1, ÔÏ ÏÂÎÏ×ÌÅÎÉÅ ×ÅÒÓÉÉ ÍÏÖÅÔ ÒÅÛÉÔØ ÜÔÕ - ÐÒÏÂÌÅÍÕ. ôÁËÖÅ ×ÏÚÍÏÖÎÏ, ÞÔÏ Õ ×ÁÓ ÚÁËÏÎÞÉÌÁÓØ ×ÉÒÔÕÁÌØÎÁÑ ÐÁÍÑÔØ ÉÌÉ - ÞÔÏ ×ÁÛÅ ÑÄÒÏ ÉÍÅÅÔ ÍÁÌÅÎØËÉÊ ÌÉÍÉÔ ÎÁ ÏÐÒÅÄÅÌÅÎÎÙÅ ÒÅÓÕÒÓÙ. - ðÏÐÙÔÁÊÔÅÓØ ÐÅÒÅÄ ÚÁÐÕÓËÏÍ postmaster ×ÙÐÏÌÎÉÔØ ÓÌÅÄÕÀÝÉÅ ËÏÍÁÎÄÙ: - ulimit -d 262144 - limit datasize 256m - - ÷ ÚÁ×ÉÓÉÍÏÓÔÉ ÏÔ ËÏÍÁÎÄÎÏÇÏ ÉÎÔÅÒÐÒÅÔÁÔÏÒÁ shell, ÔÏÌØËÏ ÏÄÎÁ ÉÚ - ÄÁÎÎÙÈ ËÏÍÁÎÄ ×ÙÐÏÌÎÉÔÓÑ ÕÓÐÅÛÎÏ, ÎÏ ÏÎÁ ÐÏÚ×ÏÌÉÔ ×ÁÍ ÕÓÔÁÎÏ×ÉÔØ - ÂÏÌØÛÉÊ ÓÅÇÍÅÎÔ ÄÁÎÎÙÈ ÐÒÏÃÅÓÓÁ É ×ÏÚÍÏÖÎÏ ÒÅÛÉÔ ÐÒÏÂÌÅÍÕ. üÔÁ ËÏÍÁÎÄÁ - ÉÚÍÅÎÑÅÔ ÐÁÒÁÍÅÔÒÙ ÔÅËÕÝÅÇÏ ÐÒÏÃÅÓÓÁ É ×ÓÅÈ ÅÇÏ ÐÏÔÏÍËÏ×, ÓÏÚÄÁÎÎÙÈ - ÐÏÓÌŠţ ÚÁÐÕÓËÁ. åÓÌÉ Õ ×ÁÓ ×ÏÚÎÉËÌÁ ÐÒÏÂÌÅÍÁ Ó SQL ËÌÉÅÎÔÏÍ, ÐÏÔÏÍÕ - ÞÔÏ backend ×ÏÚ×ÒÁÝÁÅÔ ÓÌÉÛËÏÍ ÂÏÌØÛÏÊ ÏÂßÅÍ ÄÁÎÎÙÈ, ÐÏÐÙÔÁÊÔÅÓØ - ×ÙÐÏÌÎÉÔØ ÜÔÕ ËÏÍÁÎÄÕ ÐÅÒÅÄ ÚÁÐÕÓËÏÍ ËÌÉÅÎÔÁ. - - 4.19) ëÁË ÍÎÅ ÕÚÎÁÔØ, ËÁËÁÑ ×ÅÒÓÉÑ PostgreSQL ÚÁÐÕÝÅÎÁ? - - éÚ psql, ÎÁÂÅÒÉÔÅ select version(); - - 4.20) ðÏÞÅÍÕ ÐÒÉ ÒÁÂÏÔÅ Ó ÍÏÉÍ ÂÏÌØÛÉÍ ÏÂßÅËÔÏÍ Ñ ÐÏÌÕÞÁÀ ÏÛÉÂËÕ "invalid - large obj descriptor"? - - ÷ÁÍ ÎÕÖÎÏ ÐÒÉ ÉÓÐÏÌØÚÏ×ÁÎÉÉ ÂÏÌØÛÏÇÏ ÏÂßÅËÔÁ ÐÏÍÅÓÔÉÔØ × ÎÁÞÁÌÅ BEGIN - WORK É × ËÏÎÃÅ COMMIT, Á ×ÎÕÔÒÉ ÐÏÌÕÞÉ×ÛÅÇÏÓÑ ÂÌÏËÁ lo_open ... - lo_close. - - ÷ ÎÁÓÔÏÑÝÉÊ ÍÏÍÅÎÔ PostgreSQL ÔÒÅÂÕÅÔ, ÞÔÏÂÙ ÐÒÉ ÚÁËÒÙÔÉÉ ÂÏÌØÛÏÇÏ - ÏÂßÅËÔÁ ÐÒÏÉÓÈÏÄÉÌÏ ×ÙÐÏÌÎÅÎÉÅ ÔÒÁÎÚÁËÃÉÉ. ôÁËÉÍ ÏÂÒÁÚÏÍ, ÐÅÒ×ÁÑ ÖÅ - ÐÏÐÙÔËÁ ÓÄÅÌÁÔØ ÞÔÏ-ÌÉÂÏ Ó ÂÏÌØÛÉÍ ÏÂßÅËÔÏÍ, ÎÅ ÓÏÂÌÀÄÁÑ ÄÁÎÎÏÇÏ - ÐÒÁ×ÉÌÁ ÐÒÉ×ÅÄÅÔ Ë ÓÏÏÂÝÅÎÉÀ invalid large obj descriptor, ÔÁË ËÁË ËÏÄ - ×ÙÐÏÌÎÑÀÝÉÊ ÒÁÂÏÔÕ ÎÁÄ ÂÏÌØÛÉÍ ÏÂßÅËÔÏÍ (ÐÏ ËÒÁÊÎÅÊ ÍÅÒÅ × ÎÁÓÔÏÑÝÉÊ - ÍÏÍÅÎÔ) ÂÕÄÅÔ ÇÅÎÅÒÉÒÏ×ÁÔØ ÓÏÏÂÝÅÎÉÅ Ï ÏÛÉÂËÅ ÅÓÌÉ ×Ù ÎÅ ÉÓÐÏÌØÚÕÅÔÅ - ÔÒÁÎÚÁËÃÉÀ. - - åÓÌÉ ×Ù ÉÓÐÏÌØÚÕÅÔÅ ÔÁËÏÊ ÉÎÔÅÒÆÅÊÓ ËÌÉÅÎÔÁ ËÁË ODBC, ×ÁÍ ×ÏÚÍÏÖÎÏ - ÐÏÎÁÄÏÂÉÔÓÑ ÕÓÔÁÎÏ×ÉÔØ auto-commit off. - - 4.21) ëÁË ÍÎÅ ÓÏÚÄÁÔØ ËÏÌÏÎËÕ ËÏÔÏÒÁÑ ÐÏ ÕÍÏÌÞÁÎÉÀ ÂÕÄÅÔ ÓÏÄÅÒÖÁÔØ ÔÅËÕÝÅÅ - ×ÒÅÍÑ? - - éÓÐÏÌØÚÕÊÔÅ CURRENT_TIMESTAMP: -CREATE TABLE test (x int, modtime timestamp DEFAULT CURRENT_TIMESTAMP ); - - 4.22) ðÏÞÅÍÕ ÍÏÉ ÐÏÄÚÁÐÒÏÓÙ, ÉÓÐÏÌØÚÕÀÝÉÅ IN ÔÁË ÍÅÄÌÅÎÎÏ ÒÁÂÏÔÁÅÀÔ? - - ÷ ÎÁÓÔÏÑÝÉÊ ÍÏÍÅÎÔ, ÍÙ Ó×ÑÚÙ×ÁÅÍ ÐÏÚÁÐÒÏÓÙ ÄÌÑ ×ÎÅÛÎÉÈ ÚÁÐÒÏÓÏ× ÞÅÒÅÚ - ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÙÊ ÐÅÒÅÂÏÒ ÒÅÚÕÌØÔÁÔÁ ÐÏÄÚÁÐÒÏÓÁ ÄÌÑ ËÁÖÄÏÊ ÚÁÐÉÓÉ - ×ÎÅÛÎÅÇÏ ÚÁÐÒÏÓÁ. ðÏÐÒÏÂÕÊÔÅ ÚÁÍÅÎÉÔØ IN ÎÁ EXISTS: -SELECT * - FROM tab - WHERE col1 IN (SELECT col2 FROM TAB2) - - ÎÁ: -SELECT * - FROM tab - WHERE EXISTS (SELECT col2 FROM TAB2 WHERE col1 = col2) - - íÙ ÎÁÄÅÅÍÓÑ ÕÂÒÁÔØ ÜÔÏ ÏÇÒÁÎÉÞÅÎÉÅ × ÂÕÄÕÝÅÍ ×ÙÐÕÓËÅ. - - 4.23) ëÁË ÍÎÅ ×ÙÐÏÌÎÉÔØ ×ÎÅÛÎÅÅ Ó×ÑÚÙ×ÁÎÉÅ? - - PostgreSQL ÎÁÞÉÎÁÑ Ó ×ÅÒÓÉÉ 7.1 ÐÏÄÄÅÒÖÉ×ÁÅÔ ×ÎÅÛÎÅÅ Ó×ÑÚÙ×ÁÎÉÅ, - ÉÓÐÏÌØÚÕÑ ÓÔÁÎÄÁÒÔÎÙÊ ÓÉÎÔÁËÓÉÓ SQL. ÷ÏÔ Ä×Á ÐÒÉÍÅÒÁ: - SELECT * - FROM t1 LEFT OUTER JOIN t2 ON (t1.col = t2.col); - - or - SELECT * - FROM t1 LEFT OUTER JOIN t2 USING (col); - - üÔÏ ÉÄÅÎÔÉÞÎÙÅ ÚÁÐÒÏÓÙ Ó×ÑÚÙ×ÁÎÉÑ t1.col É t2.col, ÔÁËÖÅ ×ÏÚ×ÒÁÝÁÀÔ - ÌÀÂÙÅ ÎÅÓ×ÑÚÁÎÎÙÅ ÚÁÐÉÓÉ × t1 (ËÏÔÏÒÙÅ ÎÅ ÓÏ×ÐÁÄÁÀÔ Ó t2). RIGHT - Ó×ÑÚÙ×ÁÎÉÅ ÄÏÌÖÎÏ ÄÏÂÁ×ÉÔØ ÎÅÓ×ÑÚÁÎÎÙÅ ÚÁÐÉÓÉ t2. FULL Ó×ÑÚÙ×ÁÎÉÅ - ÄÏÌÖÎÏ ×ÏÚ×ÒÁÔÉÔØ ÓÏ×ÐÁ×ÛÉÅ ÚÁÐÉÓÉ ÐÌÀÓ ×ÓÅ ÎÅÓ×ÑÚÁÎÎÙÅ ÚÁÐÉÓÉ ÉÚ t1 É - t2. óÌÏ×Ï OUTER Ñ×ÌÑÅÔÓÑ ÎÅÏÂÑÚÁÔÅÌØÎÙÍ É ÎÁÚÎÁÞÁÅÔÓÑ × LEFT, RIGHT É - FULL Ó×ÑÚÙ×ÁÎÉÑÈ. ïÂÙÞÎÙÅ Ó×ÑÚÙ×ÁÎÉÑ ÎÁÚÙ×ÁÀÔÓÑ INNER Ó×ÑÚÙ×ÁÎÉÑ. - - ÷ ÐÒÅÄÙÄÕÝÉÈ ×ÅÒÓÉÑÈ, ×ÎÅÛÎÉÅ Ó×ÑÚÙ×ÁÎÉÑ ÍÏÇÌÉ ÂÙÔØ ÜÍÕÌÉÒÏ×ÁÎÙ - ÉÓÐÏÌØÚÕÑ UNION É NOT IN. îÁÐÒÉÍÅÒ, ËÏÇÄÁ ÐÒÏÉÓÈÏÄÉÔ Ó×ÑÚÙ×ÁÎÉÅ tab1 É - tab2, ÓÌÅÄÕÀÝÉÊ ÚÁÐÒÏÓ ×ÙÐÏÌÎÑÅÔ ×ÎÅÛÎÅÅ Ó×ÑÚÙ×ÁÎÉÅ Ä×ÕÈ ÔÁÂÌÉÃ: - SELECT tab1.col1, tab2.col2 - FROM tab1, tab2 - WHERE tab1.col1 = tab2.col1 - UNION ALL - SELECT tab1.col1, NULL - FROM tab1 - WHERE tab1.col1 NOT IN (SELECT tab2.col1 FROM tab2) - ORDER BY col1 - - 4.24) ëÁË ×ÙÐÏÌÎÑÔØ ÚÁÐÒÏÓÙ, ÉÓÐÏÌØÚÕÀÝÉÅ ÎÅÓËÏÌØËÏ ÂÁÚ ÄÁÎÎÙÈ? - - îÅ ÓÕÝÅÓÔ×ÕÅÔ ÓÐÏÓÏÂÁ ÓÏÚÄÁÔØ ÚÁÐÒÏÓ Ë ÂÁÚÁÍ ÄÁÎÎÙÈ ÏÔÌÉÞÎÙÍ ÏÔ - ÔÅËÕÝÅÊ. ðÏÓËÏÌØËÕ PostgreSQL ÚÁÇÒÕÖÁÅÔ ÓÉÓÔÅÍÎÙÅ ËÁÔÁÌÏÇÉ ÓÐÅÃÉÆÉÞÎÙÅ - ÄÌÑ ÂÁÚÙ ÄÁÎÎÙÈ, ÎÅÐÏÎÑÔÎÏ ÄÁÖÅ, ËÁË ÄÏÌÖÅÎ ÓÅÂÑ ×ÅÓÔÉ ÔÁËÏÊ - ÍÅÖÂÁÚÏ×ÙÊ ÚÁÐÒÏÓ. - - òÁÚÕÍÅÅÔÓÑ, ËÌÉÅÎÔ ÍÏÖÅÔ ÏÄÎÏ×ÒÅÍÅÎÎÏ ÕÓÔÁÎÁ×ÌÉ×ÁÔØ ÓÏÅÄÉÅÎÅÎÉÑ Ó - ÒÁÚÌÉÞÎÙÍÉ ÂÁÚÁÍÉ ÄÁÎÎÙÈ É ÔÁËÉÈ ÏÂÒÁÚÏÍ ÏÂßÅÄÉÎÑÔØ ÉÎÆÏÒÍÁÃÉÀ ÉÚ ÎÉÈ. - - 4.25) ëÁË ÍÎÅ ×ÅÒÎÕÔØ ÉÚ ÆÕÎËÃÉÉ ÎÅÓËÏÌØËÏ ÚÁÐÉÓÅÊ? - - ÷Ù ÍÏÖÅÔÅ ×ÏÚ×ÒÁÝÁÔØ ÉÚ ÆÕÎËÃÉÊ PL/pgSQL ÓÐÉÓËÉ ÒÅÚÕÌØÔÁÔÏ×, ÉÓÐÏÌØÚÕÑ - refcursors. óÍÏÔÒÉÔÅ - http://developer.postgresql.org/docs/postgres/plpgsql-cursors.html, - ÓÅËÃÉÀ 23.7.3.3. - - 4.26) ðÏÞÅÍÕ Ñ ÎÅ ÍÏÇÕ ÎÁÄÅÖÎÏ ÓÏÚÄÁ×ÁÔØ/ÕÄÁÌÑÔØ ×ÒÅÍÅÎÎÙÅ ÔÁÂÌÉÃÙ × - ÆÕÎËÃÉÑÈ PL/PgSQL? - - PL/PgSQL ËÜÛÉÒÕÅÔ ÓÏÄÅÒÖÉÍÏÅ ÆÕÎËÃÉÉ É ÏÄÉÎ ÉÚ ÎÅÇÁÔÉ×ÎÙÈ ÜÆÆÅËÔÏ× - ÜÔÏÇÏ ÓÏÓÔÏÉÔ × ÔÏÍ, ÞÔÏ ÅÓÌÉ ÆÕÎËÃÉÑ PL/PgSQL ÏÂÒÁÝÁÅÔÓÑ Ë ×ÒÅÍÅÎÎÏÊ - ÔÁÂÌÉÃÅ É ÜÔÁ ÔÁÂÌÉÃÁ ÐÏÚÄÎÅÅ ÕÄÁÌÑÅÔÓÑ É ÐÅÒÅÓÏÚÄÁÅÔÓÑ, Á ÆÕÎËÃÉÑ - ÚÁÔÅÍ ×ÙÚÙ×ÁÅÔÓÑ ÓÎÏ×Á, ÔÏ ÅÅ ×ÙÚÏ× ÐÒÉ×ÅÄÅÔ Ë ÏÛÉÂËÅ, ÐÏÔÏÍÕ ÞÔÏ - ÓËÜÛÉÒÏ×ÁÎÎÏÅ ÓÏÄÅÒÖÉÍÏÅ ÆÕÎËÃÉÉ ÓÏÄÅÒÖÉÔ ÕËÁÚÁÔÅÌØ ÎÁ ÓÔÁÒÕÀ - ×ÒÅÍÅÎÎÕÀ ÔÁÂÌÉÃÕ. þÔÏÂÙ ÒÅÛÉÔØ ÜÔÕ ÐÒÏÂÌÅÍÕ, ÉÓÐÏÌØÚÕÊÔÅ EXECUTE ÄÌÑ - ÄÏÓÔÕÐÁ Ë ×ÒÅÍÅÎÎÙÍ ÔÁÂÌÉÃÁÍ × PL/PgSQL. éÓÐÏÌØÚÏ×ÁÎÉÅ ÜÔÏÇÏ ÏÐÅÒÁÔÏÒÁ - ÚÁÓÔÁ×ÉÔ ÚÁÐÒÏÓ ÐÅÒÅÇÅÎÅÒÉÒÏ×ÁÔØÓÑ ËÁÖÄÙÊ ÒÁÚ. - _________________________________________________________________ - - òÁÓÛÉÒÅÎÉÑ PostgreSQL - - 5.1) ñ ÎÁÐÉÓÁÌ ÆÕÎËÃÉÀ ÏÐÒÅÄÅÌÑÅÍÕÀ ÐÏÌØÚÏ×ÁÔÅÌÅÍ. ëÏÇÄÁ Ñ ÚÁÐÕÓËÁÀ ÅÅ × - psql, ÐÏÞÅÍÕ Ñ ÐÏÌÕÞÁÀ dump core? - - ðÒÏÂÌÅÍÁ ÍÏÖÅÔ ÚÁËÌÀÞÁÔØÓÑ × ÎÅÓËÏÌØËÉÈ ×ÅÝÁÈ. ðÏÐÙÔÁÊÔÅÓØ ÓÐÅÒ×Á - ÐÒÏÔÅÓÔÉÒÏ×ÁÔØ ×ÁÛÕ ÆÕÎËÃÉÀ × ÏÔÄÅÌØÎÏÊ ÓÁÍÏÓÔÏÑÔÅÌØÎÏÊ ÐÒÏÇÒÁÍÍÅ. - - 5.2) ëÁË Ñ ÍÏÇÕ ×ÎÅÓÔÉ ÎÅËÏÔÏÒÙÅ ËÌÁÓÓÎÙÅ ÎÏ×ÙÅ ÔÉÐÙ É ÆÕÎËÃÉÉ × - PostgreSQL? - - ïÔÐÒÁרÔÅ ×ÁÛÉ ÒÁÓÛÉÒÅÎÉÑ × ÓÐÉÓÏË ÒÁÓÓÙÌËÉ pgsql-hackers É ÏÎÉ ÐÏ - ×ÏÚÍÏÖÎÏÓÔÉ ÂÕÄÕÔ ÐÏÍÅÝÅÎÙ × ÐÏÄËÁÔÁÌÏÇ contrib/. - - 5.3) ëÁË ÍÎÅ ÎÁÐÉÓÁÔØ C ÆÕÎËÃÉÀ, ×ÏÚ×ÒÁÝÁÀÝÕÀ ÚÁÐÉÓØ? - - üÔÏ ÔÒÅÂÕÅÔ ÎÅËÏÅÇÏ ÛÁÍÁÎÓÔ×Á ÔÁË ËÁË Á×ÔÏÒÙ ÎÉËÏÇÄÁ ÎÅ ÐÒÏÂÏ×ÁÌÉ - ÄÅÌÁÔØ ÜÔÏ, ÈÏÔÑ × ÐÒÉÎÉÃÐÅ ÜÔÏ ×ÏÚÍÏÖÎÏ. - - 5.4) ñ ÉÚÍÅÎÉÌ ÉÓÈÏÄÎÙÊ ÆÁÊÌ. ðÏÞÅÍÕ ÐÏÓÌÅ ÐÅÒÅËÏÍÐÉÌÑÃÉÉ Ñ ÎÅ ×ÉÖÕ - ÉÚÍÅÎÅÎÉÊ? - - æÁÊÌÙ Makefile ÎÅ ÉÍÅÀÔ ÐÒÁ×ÉÌØÎÙÈ ÚÁ×ÉÓÉÍÏÓÔÅÊ ÄÌÑ include ÆÁÊÌÏ×. ÷Ù - ÄÏÌÖÎÙ ×ÙÐÏÌÎÉÔØ make clean É ÚÁÔÅÍ make. åÓÌÉ ×Ù ÉÓÐÏÌØÚÕÅÔÅ GCC ×Ù - ÍÏÖÅÔÅ ÉÓÐÏÌØÚÏ×ÁÔØ ÏÐÃÉÀ --enable-depend × configure ÞÔÏÂÙ ÐÏÒÕÞÉÔØ - ËÏÍÐÉÌÑÔÏÒÕ Á×ÔÏÍÁÔÉÞÅÓËÉ ÏÔÓÌÅÖÉ×ÁÔØ ÚÁ×ÉÓÉÍÏÓÔÉ. diff --git a/doc/KNOWN_BUGS b/doc/KNOWN_BUGS deleted file mode 100644 index b30f5a52a5..0000000000 --- a/doc/KNOWN_BUGS +++ /dev/null @@ -1,4 +0,0 @@ -PostgreSQL has a single combined bugs, missing features, and todo list -simply called TODO, in this directory. A current copy is always -available on our web site. - diff --git a/doc/MISSING_FEATURES b/doc/MISSING_FEATURES deleted file mode 100644 index b30f5a52a5..0000000000 --- a/doc/MISSING_FEATURES +++ /dev/null @@ -1,4 +0,0 @@ -PostgreSQL has a single combined bugs, missing features, and todo list -simply called TODO, in this directory. A current copy is always -available on our web site. - diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index 555e0056c4..0000000000 --- a/doc/Makefile +++ /dev/null @@ -1,103 +0,0 @@ -#---------------------------------------------------------------------------- -# -# PostgreSQL documentation installation makefile -# -# Copyright (c) 1994, Regents of the University of California -# -# $Header: /cvsroot/pgsql/doc/Makefile,v 1.22 2002/02/06 20:29:35 petere Exp $ -# -#---------------------------------------------------------------------------- - -# This makefile is responsible for installing the documentation. The -# files to be installed are prepared specially and are placed in this -# directory during distribution bundling. In CVS-based trees these -# files don't exist, so we skip the installation in that case. -# -# Before we install the man pages, we massage the section numbers to -# follow the local conventions. -# -# To actually build the documenation, look into the src/ and src/sgml -# subdirectories. - -subdir = doc -top_builddir = .. -include $(top_builddir)/src/Makefile.global - -.NOTPARALLEL: - -ifneq ($(wildcard $(srcdir)/postgres.tar.gz),) -found_html := yes -endif - -ifneq ($(wildcard $(srcdir)/man.tar.gz),) -# SCO OpenServer's man system is sufficiently different to not bother. -ifneq ($(PORTNAME), sco) -found_man := yes -endif -endif - - -ifdef found_man -ifndef sqlmansect -sqlmansect = 7 -endif -sqlmansectnum = $(shell expr X'$(sqlmansect)' : X'\([0-9]\)') - -all: man1/.timestamp man$(sqlmansectnum)/.timestamp - -man1/.timestamp: man$(sqlmansect_dummy)/.timestamp - @echo timestamp >$@ - -man$(sqlmansect_dummy)/.timestamp: man.tar.gz - gzip -d -c $< | $(TAR) xf - - for file in man1/*.1; do \ - mv $$file $$file.bak && \ - sed -e 's/\\fR($(sqlmansect_dummy))/\\fR($(sqlmansectnum))/' $$file.bak >$$file && \ - rm $$file.bak || exit; \ - done - @echo timestamp >$@ - -man$(sqlmansectnum)/.timestamp: man$(sqlmansect_dummy)/.timestamp - $(mkinstalldirs) man$(sqlmansectnum) - for file in man$(sqlmansect_dummy)/*.$(sqlmansect_dummy); do \ - sed -e '/^\.TH/s/"$(sqlmansect_dummy)"/"$(sqlmansect)"/' \ - -e 's/\\fR($(sqlmansect_dummy))/\\fR($(sqlmansectnum))/' \ - $$file >man$(sqlmansectnum)/`basename $$file | sed 's/.$(sqlmansect_dummy)$$/.$(sqlmansect)/'` || exit; \ - done - @echo timestamp >$@ -endif # found_man - - -install: all installdirs -ifdef found_html - gzip -d -c postgres.tar.gz | ( cd $(DESTDIR)$(docdir)/html && $(TAR) xf - ) -endif -ifdef found_man - for file in man1/*.1 man$(sqlmansectnum)/*.$(sqlmansect) ; do \ - $(INSTALL_DATA) $$file $(DESTDIR)$(mandir)/$$file || exit; \ - done -endif - - -installdirs: -ifdef found_html - $(mkinstalldirs) $(DESTDIR)$(docdir)/html -endif -ifdef found_man - $(mkinstalldirs) $(addprefix $(DESTDIR)$(mandir)/man, 1 $(sqlmansectnum)) -endif - - -uninstall: -ifdef found_html - -rm -f $(addprefix $(DESTDIR)$(docdir)/html/, $(shell gunzip -c $(srcdir)/postgres.tar.gz | tar tf -)) -endif -ifdef found_man - -rm -f $(addprefix $(DESTDIR)$(mandir)/, $(shell gunzip -c $(srcdir)/man.tar.gz | tar tf - | sed -e 's,man$(sqlmansect_dummy)/,man$(sqlmansectnum)/,' -e 's/.$(sqlmansect_dummy)$$/.$(sqlmansect)/')) -endif - - -clean: - rm -rf man1/ man$(sqlmansectnum)/ man$(sqlmansect_dummy)/ - -distclean maintainer-clean: clean diff --git a/doc/README.mb.big5 b/doc/README.mb.big5 deleted file mode 100644 index eabbcc42e4..0000000000 --- a/doc/README.mb.big5 +++ /dev/null @@ -1,326 +0,0 @@ -PostgreSQL 7.0.1 multi-byte (MB) support README May 20 2000 - - Tatsuo Ishii - ishii@postgresql.org - http://www.sra.co.jp/people/t-ishii/PostgreSQL/ - -[µù] 1. ·PÁÂ¥Û¤«¹F¤Ò (Tatsuo Ishii) ¥ý¥Í! - 2. µùÄÀ³¡¥÷­ì¤å©ÒµL, ¤¤Ä¶­Y¦³¿ù»~, ½ÐÁpµ¸ cch@cc.kmu.edu.tw - - -0. ²¤¶ - -MB ¤ä´©¬O¬°¤FÅý PostgreSQL ¯à³B²z¦h¦ì¤¸²Õ¦r¤¸ (multi-byte character), -¨Ò¦p: EUC (Extended Unix Code), Unicode (²Î¤@½X) ©M Mule internal code -(¦h°ê»y¨¥¤º½X). ¦b MB ªº¤ä´©¤U, §A¥i¥H¦b¥¿³Wªí¥Ü¦¡ (regexp), LIKE ¤Î -¨ä¥L¤@¨Ç¨ç¦¡¤¤¨Ï¥Î¦h¦ì¤¸²Õ¦r¤¸. ¹w³]ªº½s½X¨t²Î¥i¨ú¨M©ó§A¦w¸Ë PostgreSQL -®Éªº initdb(1) ©R¥O, ¥ç¥i¥Ñ createdb(1) ©R¥O©Î«Ø¥ß¸ê®Æ®wªº SQL ©R¥O¨M©w. -©Ò¥H§A¥i¥H¦³¦h­Ó¤£¦P½s½X¨t²Îªº¸ê®Æ®w. - -MB ¤ä´©¤]¸Ñ¨M¤F¤@¨Ç 8 ¦ì¤¸³æ¦ì¤¸²Õ¦r¤¸¶° (¥]§t ISO-8859-1) ªº¬ÛÃö°ÝÃD, -(§Ú¨Ã¨S¦³»¡©Ò¦³ªº¬ÛÃö°ÝÃD³£¸Ñ¨M¤F, §Ú¥u¬O½T»{¤F°jÂk´ú¸Õ°õ¦æ¦¨¥\, -¦Ó¤@¨Çªk»y¦r¤¸¦b MB ­×¸É¤U¥i¥H¨Ï¥Î. ¦pªG§A¦b¨Ï¥Î 8 ¦ì¤¸¦r¤¸®Éµo²{¤F -¥ô¦ó°ÝÃD, ½Ð³qª¾§Ú) - -1. ¦p¦ó¨Ï¥Î - -½sĶ PostgreSQL «e, °õ¦æ configure ®É¨Ï¥Î multibyte ªº¿ï¶µ - - % ./configure --enable-multibyte[=encoding_system] - % ./configure --enable-multibyte[=½s½X¨t²Î] - -¨ä¤¤ªº½s½X¨t²Î¥i¥H«ü©w¬°¤U­±¨ä¤¤¤§¤@: - - SQL_ASCII ASCII - EUC_JP Japanese EUC - EUC_CN Chinese EUC - EUC_KR Korean EUC - EUC_TW Taiwan EUC - UNICODE Unicode(UTF-8) - MULE_INTERNAL Mule internal - LATIN1 ISO 8859-1 English and some European languages - LATIN2 ISO 8859-2 English and some European languages - LATIN3 ISO 8859-3 English and some European languages - LATIN4 ISO 8859-4 English and some European languages - LATIN5 ISO 8859-5 English and some European languages - KOI8 KOI8-R - WIN Windows CP1251 - ALT Windows CP866 - -¨Ò¦p: - - % ./configure --enable-multibyte=EUC_JP - -¦pªG¬Ù²¤«ü©w½s½X¨t²Î, ¨º»ò¹w³]­È´N¬O SQL_ASCII. - -2. ¦p¦ó³]©w½s½X - -initdb ©R¥O©w¸q PostgresSQL ¦w¸Ë«áªº¹w³]½s½X, ¨Ò¦p: - - % initdb -E EUC_JP - -±N¹w³]ªº½s½X³]©w¬° EUC_JP (Extended Unix Code for Japanese), ¦pªG§A³ßÅw -¸ûªøªº¦r¦ê, §A¤]¥i¥H¥Î "--encoding" ¦Ó¤£¥Î "-E". ¦pªG¨S¦³¨Ï¥Î -E ©Î ---encoding ªº¿ï¶µ, ¨º»ò½sö®Éªº³]©w·|¦¨¬°¹w³]­È. - -§A¥i¥H«Ø¥ß¨Ï¥Î¤£¦P½s½Xªº¸ê®Æ®w: - - % createdb -E EUC_KR korean - -³o­Ó©R¥O·|«Ø¥ß¤@­Ó¥s°µ "korean" ªº¸ê®Æ®w, ¦Ó¨ä±Ä¥Î EUC_KR ½s½X. -¥t¥~¦³¤@­Ó¤èªk, ¬O¨Ï¥Î SQL ©R¥O, ¤]¥i¥H¹F¨ì¦P¼Ëªº¥Øªº: - - CREATE DATABASE korean WITH ENCODING = 'EUC_KR'; - -¦b pg_database ¨t²Î³W®æªí (system catalog) ¤¤¦³¤@­Ó "encoding" ªºÄæ¦ì, -´N¬O¥Î¨Ó¬ö¿ý¤@­Ó¸ê®Æ®wªº½s½X. §A¥i¥H¥Î psql -l ©Î¶i¤J psql «á¥Î \l ªº -©R¥O¨Ó¬d¬Ý¸ê®Æ®w±Ä¥Î¦óºØ½s½X: - -$ psql -l - List of databases - Database | Owner | Encoding ----------------+---------+--------------- - euc_cn | t-ishii | EUC_CN - euc_jp | t-ishii | EUC_JP - euc_kr | t-ishii | EUC_KR - euc_tw | t-ishii | EUC_TW - mule_internal | t-ishii | MULE_INTERNAL - regression | t-ishii | SQL_ASCII - template1 | t-ishii | EUC_JP - test | t-ishii | EUC_JP - unicode | t-ishii | UNICODE -(9 rows) - -3. «eºÝ»P«áºÝ½s½Xªº¦Û°ÊÂà´« - -[µù: «eºÝªx«ü«È¤áºÝªºµ{¦¡, ¥i¯à¬O psql ©R¥O¸Ñ;¹, ©Î±Ä¥Î libpq ªº C -µ{¦¡, Perl µ{¦¡, ©ÎªÌ¬O³z¹L ODBC ªºµøµ¡À³¥Îµ{¦¡. ¦Ó«áºÝ´N¬O«ü PostgreSQL -¸ê®Æ®wªº¦øªAµ{¦¡] - -PostgreSQL ¤ä´©¬Y¨Ç½s½X¦b«eºÝ»P«áºÝ¶¡°µ¦Û°ÊÂà´«: [µù: ³o¸Ì©Ò¿×ªº¦Û°Ê -Âà´«¬O«ü§A¦b«eºÝ¤Î«áºÝ©Ò«Å§i±Ä¥Îªº½s½X¤£¦P, ¦ý¥u­n PostgreSQL ¤ä´©³o -¨âºØ½s½X¶¡ªºÂà´«, ¨º»ò¥¦·|À°§A¦b¦s¨ú«e°µÂà´«] - - encoding of backend available encoding of frontend - -------------------------------------------------------------------- - EUC_JP EUC_JP, SJIS - - EUC_TW EUC_TW, BIG5 - - LATIN2 LATIN2, WIN1250 - - LATIN5 LATIN5, WIN, ALT - - MULE_INTERNAL EUC_JP, SJIS, EUC_KR, EUC_CN, - EUC_TW, BIG5, LATIN1 to LATIN5, - WIN, ALT, WIN1250 - -¦b±Ò°Ê¦Û°Ê½s½XÂà´«¤§«e, §A¥²¶·§i¶D PostgreSQL §A­n¦b«eºÝ±Ä¥Î¦óºØ½s½X. -¦³¦n´X­Ó¤èªk¥i¥H¹F¨ì³o­Ó¥Øªº: - -o ¦b psql ©R¥O¸Ñ;¹¤¤¨Ï¥Î \encoding ³o­Ó©R¥O - -\encoding ³o­Ó©R¥O¥i¥HÅý§A°¨¤W¤Á´««eºÝ½s½X, ¨Ò¦p, §A­n±N«eºÝ½s½X¤Á´«¬° SJIS, -¨º»ò½Ð¥´: - - \encoding SJIS - -o ¨Ï¥Î libpq [µù: PostgreSQL ¸ê®Æ®wªº C API µ{¦¡®w] ªº¨ç¦¡ - -psql ªº \encoding ©R¥O¨ä¹ê¥u¬O¥h©I¥s PQsetClientEncoding() ³o­Ó¨ç¦¡¨Ó¹F¨ì¥Øªº. - - int PQsetClientEncoding(PGconn *conn, const char *encoding) - -¤W¦¡¤¤ conn ³o­Ó°Ñ¼Æ¥Nªí¤@­Ó¹ï«áºÝªº³s½u, encoding ³o­Ó°Ñ¼Æ­n©ñ§A·Q¥Îªº½s½X, -°²¦p¥¦¦¨¥\¦a³]©w¤F½s½X, «K·|¶Ç¦^ 0 ­È, ¥¢±Ñªº¸Ü¶Ç¦^ -1. ¦Ü©ó¥Ø«e³s½uªº½s½X¥i -§Q¥Î¥H¤U¨ç¦¡¬dª¾: - - int PQclientEncoding(const PGconn *conn) - -³o¸Ì­nª`·Nªº¬O: ³o­Ó¨ç¦¡¶Ç¦^ªº¬O½s½Xªº¥N¸¹ (encoding id, ¬O­Ó¾ã¼Æ­È), -¦Ó¤£¬O½s½Xªº¦WºÙ¦r¦ê (¦p "EUC_JP"), ¦pªG§A­n¥Ñ½s½X¥N¸¹±oª¾½s½X¦WºÙ, -¥²¶·©I¥s: - -char *pg_encoding_to_char(int encoding_id) - -o ¨Ï¥Î PGCLIENTENCODING ³o­ÓÀô¹ÒÅÜ¼Æ - -¦pªG«eºÝ©³³]©w¤F PGCLIENTENCODING ³o¤@­ÓÀô¹ÒÅܼÆ, ¨º»ò«áºÝ·|°µ½s½X¦Û°ÊÂà´«. - -[µù] PostgreSQL 7.0.0 ~ 7.0.3 ¦³­Ó bug -- ¤£»{³o­ÓÀô¹ÒÅÜ¼Æ - -o ¨Ï¥Î SET CLIENT_ENCODING TO ³o­Ó SQL ªº©R¥O - -­n³]©w«eºÝªº½s½X¥i¥H¥Î¥H¤U³o­Ó SQL ©R¥O: - - SET CLIENT_ENCODING TO 'encoding'; - -§A¤]¥i¥H¨Ï¥Î SQL92 ªº»yªk "SET NAMES" ¹F¨ì¦P¼Ëªº¥Øªº: - - SET NAMES 'encoding'; - -¬d¸ß¥Ø«eªº«eºÝ½s½X¥i¥H¥Î¥H¤U³o­Ó SQL ©R¥O: - - SHOW CLIENT_ENCODING; - -¤Á´«¬°­ì¨Ó¹w³]ªº½s½X, ¥Î¥H¤U³o­Ó SQL ©R¥O: - - RESET CLIENT_ENCODING; - -[µù] ¨Ï¥Î psql ©R¥O¸Ñ;¹®É, «ØÄ³¤£­n¥Î³o­Ó¤èªk, ½Ð¥Î \encoding - -4. Ãö©ó Unicode (²Î¤@½X) - -²Î¤@½X©M¨ä¥L½s½X¶¡ªºÂà´«¥i¯à­n¦b 7.1 ª©«á¤~·|¹ê²{. - -5. ¦pªGµLªkÂà´«·|µo¥Í¤°»ò¨Æ? - -°²³]§A¦b«áºÝ¿ï¾Ü¤F EUC_JP ³o­Ó½s½X, «eºÝ¨Ï¥Î LATIN1, (¬Y¨Ç¤é¤å¦r¤¸µLªkÂà´«¦¨ -LATIN1) ¦b³o­Óª¬ªp¤U, ¬Y­Ó¦r¤¸­Y¤£¯àÂন LATIN1 ¦r¤¸¶°, ´N·|³QÂন¥H¤Uªº«¬¦¡: - - (¤Q¤»¶i¦ì­È) - -6. °Ñ¦Ò¸ê®Æ - -These are good sources to start learning various kind of encoding -systems. - -ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/cjk.inf - Detailed explanations of EUC_JP, EUC_CN, EUC_KR, EUC_TW - appear in section 3.2. - -Unicode: http://www.unicode.org/ - The homepage of UNICODE. - - RFC 2044 - UTF-8 is defined here. - -5. History - -May 20, 2000 - * SJIS UDC (NEC selection IBM kanji) support contributed - by Eiji Tokuya - * Changes above will appear in 7.0.1 - -Mar 22, 2000 - * Add new libpq functions PQsetClientEncoding, PQclientEncoding - * ./configure --with-mb=EUC_JP - now deprecated. use - ./configure --enable-multibyte=EUC_JP - instead - * Add SQL_ASCII regression test case - * Add SJIS User Defined Character (UDC) support - * All of above will appear in 7.0 - -July 11, 1999 - * Add support for WIN1250 (Windows Czech) as a client encoding - (contributed by Pavel Behal) - * fix some compiler warnings (contributed by Tomoaki Nishiyama) - -Mar 23, 1999 - * Add support for KOI8(KOI8-R), WIN(CP1251), ALT(CP866) - (thanks Oleg Broytmann for testing) - * Fix problem with MB and locale - -Jan 26, 1999 - * Add support for Big5 for fronend encoding - (you need to create a database with EUC_TW to use Big5) - * Add regression test case for EUC_TW - (contributed by Jonah Kuo ) - -Dec 15, 1998 - * Bugs related to SQL_ASCII support fixed - -Nov 5, 1998 - * 6.4 release. In this version, pg_database has "encoding" - column that represents the database encoding - -Jul 22, 1998 - * determine encoding at initdb/createdb rather than compile time - * support for PGCLIENTENCODING when issuing COPY command - * support for SQL92 syntax "SET NAMES" - * support for LATIN2-5 - * add UNICODE regression test case - * new test suite for MB - * clean up source files - -Jun 5, 1998 - * add support for the encoding translation between the backend - and the frontend - * new command SET CLIENT_ENCODING etc. added - * add support for LATIN1 character set - * enhance 8 bit cleaness - -April 21, 1998 some enhancements/fixes - * character_length(), position(), substring() are now aware of - multi-byte characters - * add octet_length() - * add --with-mb option to configure - * new regression tests for EUC_KR - (contributed by "Soonmyung. Hong" ) - * add some test cases to the EUC_JP regression test - * fix problem in regress/regress.sh in case of System V - * fix toupper(), tolower() to handle 8bit chars - -Mar 25, 1998 MB PL2 is incorporated into PostgreSQL 6.3.1 - -Mar 10, 1998 PL2 released - * add regression test for EUC_JP, EUC_CN and MULE_INTERNAL - * add an English document (this file) - * fix problems concerning 8-bit single byte characters - -Mar 1, 1998 PL1 released - -Appendix: - -[Here is a good documentation explaining how to use WIN1250 on -Windows/ODBC from Pavel Behal. Please note that Installation step 1) -is not necceary in 6.5.1 -- Tatsuo] - -Version: 0.91 for PgSQL 6.5 -Author: Pavel Behal -Revised by: Tatsuo Ishii -Email: behal@opf.slu.cz -Licence: The Same as PostgreSQL - -Sorry for my Eglish and C code, I'm not native :-) - -!!!!!!!!!!!!!!!!!!!!!!!!! NO WARRANTY !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -Instalation: ------------- -1) Change three affected files in source directories - (I don't have time to create proper patch diffs, I don't know how) -2) Compile with enabled locale and multibyte set to LATIN2 -3) Setup properly your instalation, do not forget to create locale - variables in your profile (environment). Ex. (may not be exactly true): - LC_ALL=cs_CZ.ISO8859-2 - LC_COLLATE=cs_CZ.ISO8859-2 - LC_CTYPE=cs_CZ.ISO8859-2 - LC_MONETARY=cs_CZ.ISO8859-2 - LC_NUMERIC=cs_CZ.ISO8859-2 - LC_TIME=cs_CZ.ISO8859-2 -4) You have to start the postmaster with locales set! -5) Try it with Czech language, it have to sort -5) Install ODBC driver for PgSQL into your M$ Windows -6) Setup properly your data source. Include this line in your ODBC - configuration dialog in field "Connect Settings:" : - SET CLIENT_ENCODING = 'WIN1250'; -7) Now try it again, but in Windows with ODBC. - -Description: ------------- -- Depends on proper system locales, tested with RH6.0 and Slackware 3.6, - with cs_CZ.iso8859-2 loacle -- Never try to set-up server multibyte database encoding to WIN1250, - always use LATIN2 instead. There is not WIN1250 locale in Unix -- WIN1250 encoding is useable only for M$W ODBC clients. The characters are - on thy fly re-coded, to be displayed and stored back properly - -Important: ----------- -- it reorders your sort order depending on your LC_... setting, so don't be - confused with regression tests, they don't use locale -- "ch" is corectly sorted only in some newer locales (Ex. RH6.0) -- you have to insert money as '162,50' (with comma in aphostrophes!) -- not tested properly diff --git a/doc/README.mb.jp b/doc/README.mb.jp deleted file mode 100644 index 876dcb0b86..0000000000 --- a/doc/README.mb.jp +++ /dev/null @@ -1,760 +0,0 @@ -PostgreSQL 7.2 multi-byte (MB) support README 2001/9/18 $B:n@.(B - - $B@P0fC#IW(B - ishii@postgresql.org - http://www.sra.co.jp/people/t-ishii/PostgreSQL/ - -$B"#$O$8$a$K(B - - PostgreSQL $B$K$*$1$k%^%k%A%P%$%H%5%]!<%H$O0J2<$N$h$&$JFCD'$r;}$C$F$$$^$9!%(B - - 1. $B%^%k%A%P%$%HJ8;z$H$7$F!$F|K\8l!$Cf9q8l$J$I$N3F9q$N(B EUC$B!$(BUnicode$B!$(B - mule internal code, ISO-8859-* $B$,%G!<%?%Y!<%9:n@.;~$KA*Br2DG=!%(B - $B%G!<%?%Y!<%9$K$O$3$N%3!<%I$N$^$^3JG<$5$l$^$9!%(B - 2. $B%F!<%V%kL>$K%^%k%A%P%$%HJ8;z$,;HMQ2DG=(B - 3. $B%+%i%`L>$K%^%k%A%P%$%HJ8;z$,;HMQ2DG=(B - 4. $B%G!<%?$=$N$b$N$K$b%^%k%A%P%$%HJ8;z$,;HMQ2DG=(B - 5. $B%^%k%A%P%$%HJ8;z$N@55,I=8=8!:w$,;HMQ2DG=(B - 6. $B%^%k%A%P%$%HJ8;z$N(B LIKE $B8!:w$,;HMQ2DG=(B - 7. character_length(), position(), substring() $B$J$I$NJ8;zNs4X?t$G(B - $B$N%^%k%A%P%$%H%5%]!<%H(B - 8. $B%U%m%s%H%(%s%IB&$N%(%s%3!<%G%#%s%0$,%P%C%/%(%s%IB&$H0[$k>l9g$K!$(B - $B<+F0E*$K%3!<%IJQ49$r9T$J$$$^$9!%(B - -$B"#%$%s%9%H!<%k(B - - $B%G%U%)%k%H$N%3%s%U%#%.%e%l!<%7%g%s$G$O(B PostgreSQL $B$O%^%k%A%P%$%H$r(B - $B%5%]!<%H$7$F$$$^$;$s!%%^%k%A%P%$%H%5%]!<%H$rM-8z$K$9$kJ}K!$r@bL@$7$^$9!%(B - - $B$?$H$($PF|K\8l(B EUC $B$rl9g$O!$(Bconfigure $B5/F0;~$K0J2<$N$h(B - $B$&$K;XDj$7$^$9!%(B - - $ ./configure --enable-multibyte=EUC_JP - - 7.1 $B$G$O!$(B--enable-unicode-conversion $B$r;XDj$7$J$$$H(B Unicode $B$H$=$l(B - $B0J30$N%(%s%3!<%G%#%s%0$N4V$NJQ49$,$G$-$^$;$s$G$7$?$,!$(B7.2 $B0J9_$G$OC1(B - $B$K(B --enable-multibyte $B$r;XDj$7$?$@$1$G<+F0E*$K(B - --enable-unicode-conversion $B$,M-8z$K$J$j$^$9!%$?$@$7!$(B - --enable-multibyte $B$r;XDj$7$J$,$i!$(B--enable-unicode-conversion $B$@$1(B - $B$rL58z$K$9$k$3$H$O$G$-$^$;$s!%(B - - $B%(%s%3!<%G%#%s%0$H$7$F$O(B EUC_JP $B$NB>!$0J2<$,;XDj$G$-$^$9!%(B - - SQL_ASCII ASCII - EUC_JP $BF|K\8l(B EUC - EUC_CN GB $B$r%Y!<%9$K$7$?CfJ8(BEUC$B!%(Bcode set 2 $B$O(B - SS2+2$B%P%$%H%3!<%I(B = 3$B%P%$%HI=8=$G$9!%(B - EUC_KR $B4Z9q8l(B EUC$B!%(B - JOHAB $B%O%s%0%k%Y!<%9$N4Z9q8l(BEUC. - EUC_TW $BBfOQ$N(B EUC$B!%(Bcode set 2 $B$O(B - SS2+$BLLHV9f(B+2$B%P%$%H%3!<%I(B = 4$B%P%$%HI=8=$G$9!%(B - UNICODE UTF-8$B!%$?$@$7%5%]!<%H$9$k$N$O(B UCS-2 $B$NHO0O!$(B - $B$9$J$o$A(B 0xffff $B$^$G$G$9!%(B - MULE_INTERNAL mule $B$NFbIt%3!<%I!%$?$@$7!$(BType N $B$NITDjD9J8;z$O(B - $B%5%]!<%H$7$F$$$^$;$s!%(B - LATIN* ISO8859 Latin $B%7%j!<%:!%(B* $B$O(B 1 $B$+$i(B 5 $B$^$G;XDj(B - $B$G$-$^$9!%(B - $B%-%j%kJ8;z(B KOI8(KOI8-R), WIN(CP1251), ALT(CP866)$B$r%5%]!<%H(B - $B$7$F$$$^$9!%$b$A$m$s(B ISO 8859-5 $B$b;HMQ2DG=$G$9!%(B - $B$3$N>l9g!$(B"LATIN5" $B$H$7$F;XDj$7$F2<$5$$!%(B - WIN1256 $B%"%i%V=t9q8l(BWindows$BMQ%(%s%3!<%G%#%s%0(B. - TCVN $B%Y%H%J%`8l(B."ABC"$B$d(B"VSCII"$B$b;HMQ2DG=(B. - WIN874 $B%?%$8l(B. - - $BA*Br$NL\0B$H$7$F$O!$1Q8l$HF|K\8l$7$+;H$o$J$$>l9g$O(B EUC_JP($BF1MM$K!$Cf(B - $B9q8l$7$+;H$o$J$$>l9g$O(B EUC_CN... $B$J$I$H$J$j$^$9(B)$B!$$=$NB>$N8@8l$b;H$$$?(B - $B$$>l9g$O(B UNICODE $B$b$7$/$O(B MULE_INTERNAL $B$H$J$k$G$7$g$&!%(B - - $B%(%s%3!<%G%#%s%0$r>JN,$7$?>l9g!$%G%U%)%k%HCM$H$7$F(B SQL_ASCII $B$,:NMQ(B - $B$5$l$^$9!%(B - - $B$J$*!$(Bconfigure $B$GA*Br$7$?%(%s%3!<%G%#%s%0$O!$$"$/$^$G(B initdb $B$N$?$a$N(B - $B%G%U%)%k%HCMDxEY$N0UL#$7$+$"$j$^$;$s(B(initdb $B$G$O0z?t$G%(%s%3!<%G%#%s%0$,(B - $B;XDj$G$-$^$9(B)$B!%$7$?$,$C$F!$0[$J$k%(%s%3!<%G%#%s%0$r;HMQ$9$k$?$a$K(B - $B$o$6$o$6(B PostgreSQL $B$r%j%3%s%Q%$%k$9$kI,MW$"$j$^$;$s!%(B - - initdb $B$O(B shell script $B$J$N$G!$%G%U%)%k%H$N%(%s%3!<%G%#%s%0$O(B script $B$r(B - $BE,Ev$J%(%G%#%?$GJT=8$9$k$3$H$K$h$j4JC1$KJQ99$G$-$^$9!%(Binitdb $B$N(B 61$B9TL\(B - $BIU6a$K!$(B - - MULTIBYTE=EUC_JP - - $B$N$h$&$J9T$,$"$k$N$G!$(B= $B0J9_$r4uK>$9$k%(%s%3!<%G%#%s%0$KJQ$($k$@$1$G$9!%(B - - $BCm0U!'(BMULE_INTERNAL $B$rA*$V$H!$$?$/$5$s$NJ8;z=89g$KBP1~$G$-$FJXMx$G$9(B - $B$,!$@55,I=8=$GJ#?t$NJ8;z=89g$K$^$?$,$k$h$&$JHO0O;XDj(B($B$?$H$($P!$(B[a-$BHO(B] - $B$H$+!$(B[abc$BHO0O(B]$B$N$h$&$J(B)$B$O;H$($^$;$s!%J#?t$NHO0O;XDj$G0[$J$kJ8;z=89g(B - $B$r;H$&$N$O9=$$$^$;$s(B($B$?$H$($P(B [abc][$BHO(B-$B0O(B])$B!%$^$?!$(B[^a] $B$N$h$&$JI=8=(B - $B$O!$(B"a" $B$NB0$9$kJ8;z=89g(B($B$3$N>l9g!$(BUS-ASCII)$B$K$*$$$F(B "a" $B0J30$G$"$k(B - $B$3$H$rI=$7$^$9!%7h$7$F4A;z$dJ?2>L>$J$I(B "a" $B0J30$r$9$Y$FI=$9$o$1$G$O(B - $B$J$$$3$H$KCm0U$7$F2<$5$$!%(B - - $B%$%s%9%H!<%k$O(B --enable-multibye $B$J$7$N>l9g$HF1MM$K9T$J$$$^$9!%%$%s(B - $B%9%H!<%k$N>\:Y$O(B INSTALL $B$H$$$&%F%-%9%H%U%!%$%k$r8fMw2<$5$$!%$^$?!$(B - http://www.sra.co.jp/people/t-ishii/PostgreSQL/ $B$G$b4JC1$J%$%s%9%H!<(B - $B%kJ}K!$r>R2p$7$F$$$^$9!%(B - -$B"#(Binitdb/createdb/create database $B$K$*$1$k%(%s%3!<%G%#%s%0$N;XDj$K$D$$$F(B - - initdb $B$G$O0J2<$N%*%W%7%g%s$G%(%s%3!<%G%#%s%0$,;XDj$G$-$^$9!%(B - - -E $B%(%s%3!<%G%#%s%0(B - --encoding=$B%(%s%3!<%G%#%s%0(B - - $B$3$3$G;XDj$7$?%(%s%3!<%G%#%s%0$O!$0J8e(B createdb/create database $B$G%((B - $B%s%3!<%G%#%s%0$r>JN,$7$?>l9g$K@_Dj$5$l$k%(%s%3!<%G%#%s%0$K$J$j$^$9!%(B - -E $B$^$?$O(B --encoding $B%*%W%7%g%s$r>JN,$7$?>l9g$O!$(Bconfigure $B$G;XDj$7(B - $B$?%(%s%3!<%G%#%s%0$,:NMQ$5$l$^$9!%(B - - createdb $B$G$O0J2<$N%*%W%7%g%s$G%(%s%3!<%G%#%s%0$,;XDj$G$-$^$9!%(B - - -E $B%(%s%3!<%G%#%s%0(B - --encoding=$B%(%s%3!<%G%#%s%0(B - - create database $B$G$O0J2<$N%*%W%7%g%s$G%(%s%3!<%G%#%s%0$,;XDj$G$-$^$9!%(B - - CREATE DATABASE dbanme WITH ENCODING = '$B%(%s%3!<%G%#%s%0(B'; - - LOCATION $B$rF1;~$K;XDj$9$k>l9g$O0J2<$N$h$&$K$J$j$^$9!%(B - - CREATE DATABASE dbanme WITH LOCATION = 'path' ENCODING = '$B%(%s%3!<%G%#%s%0(B'; - - createdb/create database $B$G$O!$%(%s%3!<%G%#%s%0;XDj$r>JN,$7$?>l9g$O!$(Binitdb - $B$G;XDj$7$?%(%s%3!<%G%#%s%0$,:NMQ$5$l$^$9!%$3$l$O!$(Binitdb $B$,:n@.$9$k(B - $B%F%s%W%l!<%H%G!<%?%Y!<%9(B(template1)$B$N(B encoding $B%"%H%j%S%e!<%H$r7Q>5(B - $B$9$k$+$i$G$9!%(B - - $B%G!<%?%Y!<%9$N%(%s%3!<%G%#%s%0$O!$(Bpsql -l$B!$(Bpsql $B$N(B \l $B$G;2>H$G$-$^$9!%(B - -$ psql -l - List of databases - Database | Owner | Encoding ----------------+---------+--------------- - euc_cn | t-ishii | EUC_CN - euc_jp | t-ishii | EUC_JP - euc_kr | t-ishii | EUC_KR - euc_tw | t-ishii | EUC_TW - mule_internal | t-ishii | MULE_INTERNAL - regression | t-ishii | SQL_ASCII - template1 | t-ishii | EUC_JP - test | t-ishii | EUC_JP - unicode | t-ishii | UNICODE -(9 rows) - -$B"#J8;z7?$N%G!<%?7?$K$D$$$F(B - - 7.2$B$G$O!$(BCHAR(n)$B$H(BVARCHAR(n)$B$N(B n $B$OJ8;z?t$r0UL#$7$^$9!%(Bn $B$,%P%$%H?t$r(B - $B0UL#$9$k(B 7.1 $B0JA0$H$O0[$J$j$^$9$N$G$4Cm0U2<$5$$!%(B - - $BNc$r<($7$^$9!%(B - - 7.2$B$G$O!$(BCHAR(1)$B$K(B"$B$"(B"$B$r3JG<$G$-$^$9$,!$(B7.1$B0JA0$G$O3JG<$G$-$^$;$s$3(B - $B$l$O!$(B"$B$"(B"$B$r3JG<$9$k$?$a$K>/$J$/$H$b(B2$B%P%$%H0J>e$rMW$9$k$+$i$G$9!%(B - $B5U$K!$(B"a" $B$O(B1$B%P%$%H$7$+>CHq$7$J$$$?$a!$(B7.1$B$G$b(B CHAR(1) $B$K3JG<$G$-$^(B - $B$9!%(B - - $B$J$*!$(B7.2$B$G$O!$(B7.1$B$^$G$H0[$J$j!$(BCHAR(n)$B$K3JG<$G$-$J$$(B n $BJ8;z$h$jBg$-(B - $B$$J8;zNs$O(B n $BJ8;z$G@Z$jl9g!$<+F0E*$K%P%C%/%(%s%I$G%(%s%3!<%G%#%s%0JQ49$,9T$o$l$^$9!%(B - - $B%P%C%/%(%s%I$N%(%s%3!<%G%#%s%0(B $B5vMF$5$l$k%U%m%s%H%(%s%I$N(B - $B%(%s%3!<%G%#%s%0(B - ---------------------------------------------------------------- - EUC_JP EUC_JP, SJIS, UNICODE - - EUC_TW EUC_TW, BIG5, UNICODE - - EUC_CN EUC_CN, UNICODE - - EUC_KR EUC_KR, UNICODE - - JOHAB JOHAB, UNICODE - - LATIN1,3,4 LATIN1,3,4, UNICODE - - LATIN2 LATIN2, WIN1250, UNICODE - - LATIN5 LATIN5, WIN, ALT, UNICODE - - LATIN6,7,8,9,10 LATIN6,7,8,9,10, UNICODE - - ISO_8859_5,6,7,8 ISO_8859_5,6,7,8, UNICODE - - WIN1256 WIN1256, UNICODE - - TCVN TCVN, UNICODE - - WIN874 WIN874, UNICODE - - MULE_INTERNAL EUC_JP, SJIS, EUC_KR, EUC_CN, - EUC_TW, BIG5, LATIN1$B$+$i(B5, - WIN, ALT, WIN1250 - - UNICODE EUC_JP, SJIS, EUC_KR, UHC, - EUC_CN, GBK, EUC_TW, BIG5, - LATIN1$B$+$i(B10, ISO_8859_5$B$+$i(B8, - WIN, ALT, WIN1250, WIN1256, - TCVN, WIN874, JOHAB - ---------------------------------------------------------------- - - $B%P%C%/%(%s%I$H%U%m%s%H%(%s%I$N%(%s%3!<%G%#%s%0$,0[$J$k>l9g!$$=$N$3$H(B - $B$r%P%C%/%(%s%I$KEA$($kI,MW$,$"$j$^$9!%$=$N$?$a$NJ}K!$,$$$/$D$+$"$j$^(B - $B$9!%(B - -o psql $B$N(B \encoding $B%3%^%s%I$r;H$&J}K!(B - - psql$B$G$O!$(B\encoding$B%3%^%s%I$r;H$C$FF0E*$K%U%m%s%H%(%s%IB&$NJ8;z%3!<(B - $B%I$r@ZBX$($k$3$H$,$G$-$^$9!%Nc(B: - - \encoding SJIS - -o libpq $B$N4X?t(B PQsetClientEncoding $B$r;H$&J}K!(B - - 7.0 $B$+$i?7$7$$(B libpq $B4X?t(B PQsetClientEncoding $B$,DI2C$5$l$F$$$^$9!%(B - - PQsetClientEncoding(PGconn *conn, const char *encoding) - - $B$3$N4X?t$r;H$($P!$%3%M%/%7%g%sKh$K%(%s%3!<%G%#%s%0$r@ZBX$($k$3$H$,$G(B - $B$-$^$9!%8=:_$N%(%s%3!<%G%#%s%0$NLd$$9g$o$;$O(B - - int PQclientEncoding(const PGconn *conn) - - $B$G$9!%(B - -o $B4D6-JQ?t(B PGCLIENTENCODING $B$r;H$&J}K!(B - - $B>e5-J}K!$GBP1~$G$-$J$$>l9g!$$"$k$$$O%U%m%s%H%(%s%I$G;H$o$l$k%(%s%3!<(B - $B%G%#%s%0$,$"$i$+$8$aJ,$+$C$F$$$k>l9g$O4D6-JQ?t(B PGCLIENTENCODING $B$r;H(B - $B$&$N$,JXMx$G$9!%$3$NJ}K!$O99$KBg$-$/(B2$B$D$KJ,$+$l$^$9!%(B - - (1) postmaster $B5/F0;~$K4D6-JQ?t$r@_Dj$9$kJ}K!(B - - $B$9$Y$F$N%/%i%$%"%s%H(B($B%U%m%s%H%(%s%I(B)$B$,F1$8%(%s%3!<%G%#%s%0$r;H$&$N$,(B - $BJ,$+$C$F$$$k>l9g!$(Bpostmaster $B5/F0;~$K4D6-JQ?t(B PGCLIENTENCODING $B$r@_(B - $BDj$7$^$9!%$3$N>l9g$G$b!$(B(2)$B$NJ}K!$G8D!9$N%/%i%$%"%s%HKh$KJL$N%(%s%3!<(B - $B%G%#%s%0$r@_Dj$9$k$3$H$,$G$-$^$9!%(B - - (2) $B%/%i%$%"%s%H!$%U%m%s%H%(%s%IKh$K%(%s%3!<%G%#%s%0$r@_Dj$7$?$$>l9g(B - - $B$3$N>l9g$O$=$N%U%m%s%H%(%s%I(B($B$?$H$($P(B psql)$B$r5/F0$9$kA0$K4D6-JQ?t(B - PGCLIENTENCODING $B$r@_Dj$7$^$9!%(B - -o set client_encoding $B%3%^%s%I$r;H$&J}K!(B - - $B>e5-(B(2)$B$NJ}K!$O!$(Blibpq $B$r;H$C$F$$$J$$(B JDBC $B$d(B ODBC $B$G$O;HMQ$G$-$^$;(B - $B$s!%$3$N>l9g!$(BSQL$B%3%^%s%I$G$"$k(B set client_encoding $B%3%^%s%I$rMxMQ$7(B - $B$^$9!%Nc!'(B - - set client_encoding to 'sjis'; - -$B"#8=:_@_Dj$5$l$F$$$k%U%m%s%H%(%s%IB&$N%(%s%3!<%G%#%s%0$rD4$Y$k(B - - $B8=:_@_Dj$5$l$F$$$k%U%m%s%H%(%s%IB&$N%(%s%3!<%G%#%s%0$O(B - - show client_encoding; - - $B$G;2>H$G$-$^$9!%(B - -$B"#%G%U%)%k%H$N%(%s%3!<%G%#%s%0$X$NI|5"(B - - SQL$B%3%^%s%I(B: - - reset client_encoding; - - $B$O!$%G%U%)%k%H$N%U%m%s%H%(%s%I%(%s%3!<%G%#%s%0@_Dj$KI|5"$5$;$^$9!%(B - postmaster$B$rN)$A>e$2$k$H$-$K4D6-JQ?t(B PGCLIENTENCODING $B$,@_Dj$5$l$F$$(B - $B$k$H$=$N%(%s%3!<%G%#%s%0$K!$$=$&$G$J$1$l$P%G!<%?%Y!<%9$N%(%s%3!<%G%#(B - $B%s%0$HF1$8$K$J$j$^$9!%(B - -$B"#L@<(E*$J%(%s%3!<%G%#%s%0JQ49(B - - 7.2$B$G$O!$(Bconvert$B$H$$$&4X?t$r;H$$!$L@<(E*$J%(%s%3!<%G%#%s%0JQ49$,$G$-(B - $B$^$9!%(B - - convert(string text, [src_encoding name,] dest_encoding name) - - $B$3$3$G(Bsrc_encoding$B$O(Btext$B$N%(%s%3!<%G%#%s%0L>$G$9!%>JN,$9$k$H!$%G!<%?(B - $B%Y!<%9%(%s%3!<%G%#%s%0L>$HF1$8$G$"$k$H8+$J$5$l$^$9!%(Bdest_encoding$B$O!$(B - $BJQ498e$N%(%s%3!<%G%#%s%0L>$G$9!%(B - - $BNc$r<($7$^$9!%(B - - SELECT convert(text, EUC_JP) FROM unicode_tbl; - - $B$O!$(BUnicode$B$N%F!<%V%k(Bunicode_tbl$B$N(Btext$BNs$r(BEUC_JP$B$KJQ49$7$FJV$7$^$9!%(B - -$B"#%(%s%3!<%G%#%s%0JQ49ITG=$N>l9g$N=hM}(B - - $B%P%C%/%(%s%IB&$N%(%s%3!<%G%#%s%0$H%U%m%s%H%(%s%IB&$N%(%s%3!<%G%#%s%0(B - $B$,$$$D$bAj8_JQ49$G$-$k$H$O8B$j$^$;$s!%6KC<$JOC!$%P%C%/%(%s%IB&$,(B - EUC_JP $B$J$N$K!$%U%m%s%H%(%s%IB&$,(B EUC_KR $B$@$C$?$i$I$&$J$k$G$7$g$&!%(B - $B$3$N>l9g(B PostgreSQL $B$OJQ49$G$-$J$$%3!<%I$r(B 16$B?JI=8=$KJQ49$7$^$9!%(B - $B$?$H$($P!$(B"(bdae)" $B$N$h$&$K!%$J$*!$$3$N(B 16$B?JI=8=$O(B mule - internal code $B$N%3!<%I$G$"$k$3$H$KCm0U$7$F2<$5$$!%$3$l$O!$D>@\%U%m%s(B - $B%H%(%s%I(B <--> $B%P%C%/%(%s%I$N%(%s%3!<%G%#%s%0$rJQ49$9$k$N$G$O$J$/!$0l(B - $BEYFbItI=8=$G$"$k(B mule internal code $B$r7PM3$7$F$$$k$?$a$G$9!%(B - - $B$J$*!$(BUnicode$B$H$=$l0J30$N%(%s%3!<%G%#%s%0$NJQ49$@$1$ONc30$G!$(BNOTICE - $B%a%C%;!<%8$,I=<($5$l!$JQ49ITG=$NJ8;z$OL5;k$5$l$^$9!%(B - -$B"#(BSJIS$B%f!<%6Dj5AJ8;z$X$NBP1~(B - - 7.0 $B$+$i(B SJIS$B%f!<%6Dj5AJ8;z(B (UDC) $B$KBP1~$7$F$$$^$9!%(BUDC $B$r$I$&07$&$+(B - $B$H8@$&$3$H$K$D$$$FCf>r$5$s(B(nak@email.com)$B$+$iLdBjDs5/$H>\:Y$J2r@b$r(B - $BD:$-$^$7$?$N$G!$;29M$N$?$a$K$3$N%I%-%e%a%s%H$N:G8e$KIU$1$F$*$-$^$9!%(B - $B$^$?!$$3$NLdBj$K$D$$$F$O!$(BPostgreSQL$BF|K\8l%a!<%j%s%0%j%9%H$N(B - [pgsql-jp 12288] (1999/12/17$BIU(B)$B$H(B [pgsql-jp 12486] (2000/1/5$BIU(B) $B$+$i(B - $B;O$^$k%9%l%C%I$G5DO@$r8+$k$3$H$,$G$-$^$9(B($B%a!<%k$N%"!<%+%$%V$O(B - http://www.sra.co.jp/people/t-ishii/PostgreSQL/ $B$G;2>H$G$-$^$9(B)$B!%(B - - $B$3$3$G$O!$$=$l$i$N5DO@$r$U$^$(!$4JC1$K2r@b$7$^$9!%(B - - PostgreSQL$B$G$O!$F|K\8l$r;HMQ$9$k:]$K%P%C%/%(%s%IB&$N%(%s%3!<%G%#%s%0(B - $B$r(B EUC_JP $B$^$?$O(B MULE_INTERNAL or Unicode $B$K$9$kI,MW$,$"$j$^$9!%(B - MULE_INTERNAL $B$O(B EUC_JP $B$KJ8;z=89g$rI=$9%3!<%I$rIU$1$?$b$N$J$N$G!$K\(B - $B SJIS $BJQ49$O8=:_$N$H$3$m%5%]!<%H(B - $B$5$l$F$$$^$;$s$N$GL5;k$7$^$9!%$7$?$,$C$F!$$3$3$G$O(B EUC_JP $B$H(B SJIS $B$N(B - $BAj8_JQ49$N$_$r9M$($^$9!%(B - - $BM=HwCN<1(B - - $B0l8}$K(B EUC_JP $B$H$$$C$F$b!$e5-(B JIS $B5,3J$GDj5A$5$l$F$$(B - $B$J$$J8;z%3!<%I$,0lItMxMQ$5$l$F$*$j!$$3$NItJ,(B (UDC) $B$O=>Mh(B PostgreSQL - $B$G$OA4$/9MN8$5$l$F$$$^$;$s$G$7$?!%>N(B) - 95$B!A(B104 $B6h(B $B"+"*(B $BF|K\8l(B EUC / G1 (JIS X 0208) 85$B!A(B95 $B6h(B - - - SJIS $B%f!<%6Dj5AJ8;zNN0h(B B ($B2>>N(B) - 105$B!A(B114 $B6h(B $B"+"*(B $BF|K\8l(B EUC / G3 (JIS X 0212) 85$B!A(B95 $B6h(B - - (2) IBM $B3HD%J8;zNN0h(B (SJIS 115$B!A(B120 $B6h(B) - - $BJQ49%F!<%V%k$K$h$C$F(B G1 (JIS X 0208)$B$H!$(BG3 (JIS X 0212)$B$KJQ49$5$l$^(B - $B$9!%$J$*!$$3$NJQ49$K$*$$$F$O!$(BSJIS --> EUC_JP $B$GJQ49$7!$:F$S(B EUC_JP -- - > SJIS $B$KJQ49$9$k$H85$N(B SJIS $B$KLa$i$J$$$3$H$,$"$j$^$9!%$^$?!$(BEUC_JP -- - > SJIS $B$NJQ49$G$O!$$9$Y$F$NJ8;z$rJQ49$G$-$k$o$1$G$O$J$$$N$G!$$=$N>l(B - $B9g$OJQ49ITG=J8;z$H$7$F!V".!W$KCV$-49$($^$9!%(B - - *$B6H3&CDBN$Nr$5$s(B - (nak@email.com)$B$+$iLdBjDs5/$H>\:Y$J2r@b$rD:$-$^$7$?!%(B - -$B"#(BUnicode$B$H$=$l0J30$N%(%s%3!<%G%#%s%0$H$NAj8_JQ49$K$D$$$F(B - - PostgreSQL 7.1$B$+$i(BUnicode$B$H$=$l0J30$N%(%s%3!<%G%#%s%0$H$NAj8_JQ49$,(B - $B2DG=$K$J$j$^$7$?!%$3$NJQ49$O$4$/0lIt$NJ8;z%3!<%I(B(ISO 8859-1)$B$r$N$>$-!$(B - $B%m%8%C%/$K$h$kJQ49$,$G$-$J$$$?$a!$JQ49$N:]$K$O%F!<%V%k$,I,MW$K$J$j$^(B - $B$9!%(BPostgreSQL$B$Ne!$MxMQ$7$F$$$^$9(B)$B!%(BUnicode - organization$B$NDs6!$9$kJQ49%F!<%V%k$O:FG[I[$,5v2D$5$l$F$$$J$$$?$a!$(B - PostgreSQL$B$N%=!<%9%3!<%I$K$O4^$^$l$F$$$^$;$s!%0J2r$5$s(B - (nak@email.com)$B$+$i$$$?$@$$$?LdBjDs5/$H2r@b$G$9!%(B - --------------------------- $B0zMQ3+;O(B ---------------------------------- ---- -1. SJIS $B%3!<%I$NHO0O(B - - 1 $B%P%$%HL\(B 0x81 - 0x9F$B!$(B0xE0 - 0xFC - 2 $B%P%$%HL\(B 0x40 - 0x7E$B!$(B0x80 - 0xFC - - $B$$$o$f$k!V30;zNN0h!W$NHO0O(B: - - - X0208 $B6&DL<+M3NN0h(B - - |-------------------- - | 85 $B6h(B 0xEB40 $B!A(B - |... - |-------------------- - | 89 $B6h(B 0xED40 $B!A(B ; 89$B!A(B92 $B6h$O(B - |... ; $B!V(BNEC $BA*Dj(B IBM $B3HD%J8;zNN0h!W(B - |-------------------- ; $B$H8F$P$l$k(B - | 93 $B6h(B 0xEF40 $B!A(B - | 94 $B6h(B 0xEF9F $B!A(B 0xEFFC - - - $B%f!<%6Dj5AJ8;zNN0h(B - - |-------------------- - | 95 $B6h(B 0xF040 $B!A(B ; 95$B!A(B104 $B6h(B - |... ; $B!V%f!<%6Dj5AJ8;zNN0h(B A$B!W(B($B2>>N(B) - |-------------------- - |105 $B6h(B 0xF540 $B!A(B ; 105$B!A(B114 $B6h(B - |... ; $B!V%f!<%6Dj5AJ8;zNN0h(B B$B!W(B($B2>>N(B) - |-------------------- - |115 $B6h(B 0xFA40 $B!A(B ; 115$B!A(B120 $B6h$O0lHL$K(B - |... ; $B!V(BIBM $B3HD%J8;zNN0h!W(B - |120 $B6h(B ... ; $B$H8F$P$l$k(B - |-------------------- - ---- -2. i-mode $BC\:Y$O(B -$B8e=R$N;29M;qNA$r$4Mw$$$?$@$/$H$7$F!$$3$3$G$O$=$N%k!<%k$r(B -$B4JC1$K$4@bL@$$$?$7$^$9!%(B - - - SJIS $B%f!<%6Dj5AJ8;zNN0h(B A ($B2>>N(B) - 95$B!A(B104 $B6h(B $B"+"*(B $BF|K\8l(B EUC / G1 85$B!A(B95 $B6h(B - - $B$?$H$($P(B SJIS $B$N(B (95, 1) = 0xF040 $B$O(B - EUC $B$N(B 0xF5A1 $B$K$J$j$^$9!%(B - - - SJIS $B%f!<%6Dj5AJ8;zNN0h(B B ($B2>>N(B) - 105$B!A(B114 $B6h(B $B"+"*(B $BF|K\8l(B EUC / G3 85$B!A(B95 $B6h(B - - $B$?$H$($P(B SJIS $B$N(B (105, 1) = 0xF540 $B$O(B - EUC $B$N(B 0x8FF5A1 $B$K$J$j$^$9!%(B - - - IBM $B3HD%J8;zNN0h(B - 115$B!A(B120 $B6h(B - - JIS X 0208 ($BF|K\8l(B EUC / G1)$B!$(BJIS X 0212 - ($BF|K\8l(B EUC / G3) $B$K3:Ev$9$kJ8;z$,$"$k>l9g(B - $B$O$=$NJ8;z$K%^%C%T%s%0!%$=$&$G$J$$>l9g$O(B - $BF|K\8l(B EUC / G3 83$B!A(B84 $B6h$r!$6hE@%3!<%I$N>e0L(B - $B$+$i=g$K3d$jEv$F$F$$$/(B ($BJQ49%F!<%V%kJ}<0(B) - -$B$3$N;EMM$O!$9-$/;H$o$l$F$$$k(B SJIS $B$H(B EUC $B$N%^%C%T%s%0$,%Y%s%@$K(B -$B$h$C$F0[$J$k$?$a!$Aj8_1?MQ$N:]$KLdBj$K$J$C$F$$$k$3$H$+$i!$(B1996 -$BG/$K(B OSF $BF|K\%Y%s%@6(5D2q$,8!F$:n@.$7$?Js9p=q$,%Y!<%9$K$J$C$F$$(B -$B$k$h$&$G$9!%(B - -Solaris $B$N%I%-%e%a%s%H$K$O!V(BTOG $BF|K\%Y%s%@6(5D2q?d>)(B EUC$B!&%7%U%H(B -JIS $B%3!<%IJQ49;EMM!W$K$b$H$E$/$H=q$$$F$"$j!$(BSolaris 2.6 $B$+$iF3F~(B -$B$7$F$$$k$N$@$=$&$G!$;d$+$i8+$l$P;ve$NI8=`$H9M$($F$bIT<+A3$G$O(B -$B$J$$$H46$8$^$9!%(B - -$B$J$*!$>/$J$/$H$b(B 1996 $BG/Ev;~$K$*$$$F$O!$(BOracle $B$d(B Sybase $B$O(B -SJIS $B$N%f!<%6Dj5A(B/$B%Y%s%@Dj5AJ8;zNN0h$r(B EUC $B$KJQ49$9$k:]!$H=JLIT(B -$B2DG=J8;z$H$7$F07$C$F$$$k$i$7$$$H$$$&$3$H$bJdB-$7$F$*$-$^$9!%(B - ---- -[$B;29M;qNA(B] - -// URL $B$,D9$$$N$G!$ESCf$G@Z$l$J$$$H$$$$$N$G$9$,(B... - --$B!VF|K\8l(B EUC$B!&%7%U%H(B JIS $B%3!<%IJQ49;EMM$H%3!<%I7Oe!$(B7.2$B$KH?1G$5$l$^$9!%(B - - 2001/2/15 - * $BFA2H(B@$B;06(1?M"%5!<%S%9$5$s$+$i!$(BCP932.TXT$B$h$j@8@.$7$?(BSJIS$BMQ$N(B - $BJQ49%F!<%V%k$rDs6!$7$F$$$?$@$-$^$7$?!%(B7.1$B$KH?1G$5$l$^$9!%(B - - 2001/1/6 - * UNICODE$B$HB>$N%(%s%3!<%G%#%s%0$H$NAj8_JQ495!G=$rDI2C!%(B - * 7.1$B$KH?1G$5$l$^$9!%(B - - 2000/5/20 - * NEC $BA*Dj(B IBM $B4A;zBP1~$rDI2C$7$^$7$?!%$3$l$O(B $BFA2H(B@$B;06(1?M"%5!<%S%9(B - $B$5$s$+$i$N(B contribute $B$G$9!%(B - * $B$3$l$i$O!$(B7.0.1 $B$KH?1G$5$l$^$9!%(B - - 2000/3/22 - * PQsetClientEncoding, PQclientEncoding $B$r(Blibpq $B4X?t$KDI2C!$(B - $B%3%M%/%7%g%sKh$K%(%s%3!<%G%#%s%0$rJQ992DG=$K!%(B - * SJIS $B%f!<%6Dj5AJ8;z(B (UDC) $B$X$NBP1~(B - * ./configure --with-mb=EUC_JP $B$+$i(B - ./configure --enable-multibyte=EUC_JP $B$KJQ99(B - * SQL_ASCII $B$N(B regression test $BDI2C(B - * $B$3$l$i$O(B 7.0 $B$KH?1G$5$l$^$9!%(B - - 1999/7/11 WIN1250(Windows$BMQ$N%A%'%38l(B)$B%5%]!<%H$rDI2C$7$^$7$?!%(B - * WIN1250 $B$,%U%m%s%H%(%s%IB&$N%(%s%3!<%G%#%s%0$H$7$FMxMQ$G$-$k$h(B - $B$&$K$J$j$^$7$?!%$3$N>l9g!$%P%C%/%(%s%IB&$N%(%s%3!<%G%#%s%0$O(B - LATIN2 $B$^$?$O(B MULE_INTERNAL $B$H$7$^$9!%(B - (contributed by Pavel Behal) - * backend/utils/mb/conv.c$B$K$*$1$k7?$NIT@09g$r=$@5$7$^$7$?!%(B - (contributed by Tomoaki Nishiyama) - * $B$3$l$i$O(B6.5.1$B$KH?1G$5$l$^$9!%(B - - 1999/3/23 $B%-%j%kJ8;z%5%]!<%HDI2CB>(B(6.5 $B$KH?1G:Q(B) - * $B%(%s%3!<%G%#%s%0$H$7$F(B KOI8(KOI8-R), WIN(CP1251), ALT(CP866) $B$r(B - $B%5%]!<%H$7$F$$$^$9!%$3$l$i$O!$%U%m%s%H%(%s%I!$%P%C%/%(%s%I!$(B - $B$I$A$i$N%(%s%3!<%G%#%s%0$H$7$F$b;HMQ2DG=$G$"$j!$%(%s%3!<%G%#%s%0$N(B - $BAj8_JQ49$,2DG=$G$9!%$^$?!$=>Mh$+$i%5%]!<%H$7$F$$$k(B ISO 8859-5 $B$b(B - $BF1MM$K;HMQ2DG=$G$9!%(B - $B%-%j%kJ8;z%5%]!<%H$O!$(BOleg Broytmann $B;a$N(B - $B%j%/%(%9%H5Z$S6(NO$K$h$jMh$+$i$"$k(B - RCODE $B%5%]!<%H$N5!G=$rl9g$KBgJ8;z!?>.J8;z$rL5;k$7$?(B - $B@55,I=8=8!:w$,@5>o$KF0:n$7$J$$%P%0$r=$@5(B - - 1999/1/26 Big5 $B%5%]!<%HDI2C(B(6.4.2-patched/6.5 $B$KH?1G:Q(B) - * Big5 $B$,%U%m%s%H%(%s%IB&$N%(%s%3!<%G%#%s%0$H$7$FMxMQ$G$-$k$h(B - $B$&$K$J$j$^$7$?!%$3$N>l9g!$%P%C%/%(%s%IB&$N%(%s%3!<%G%#%s%0$O(B - EUC_TW $B$^$?$O(B MULE_INTERNAL $B$H$7$^$9!%(B - * EUC_TW $B$N(B regression test $B%1!<%9$rDI2C(B - (contributed by Jonah Kuo ) - - 1998/12/16 $BK\%I%-%e%a%s%H=$@5(B(6.4.2 $B$KH?1G:Q(B)$B!%(B - * Makefile.custom $B$G(B MB=EUC_JP $B$J$I$H@_Dj$9$kJ}K!$O(B 6.4 $B0J9_(B - $B%5%]!<%H$5$l$F$$$J$$$N$G:o=|$7$?!%(B - * $BJ8;z%3!<%I(B $B"*(B $B%(%s%3!<%G%#%s%0!$%/%i%$%"%s%H"*%U%m%s%H%(%s%I(B - $B%5!<%P"*%P%C%/%(%s%I(B $B$K$=$l$>$l8l6g$r=$@5!%(B - - 1998/12/15 6.4 $B8~$1%P%0=$@5%Q%C%A%j%j!<%9(B(6.4.2 $B$KH?1G:Q(B)$B!%(B - * SQL_ASCII $B%5%]!<%H$N%P%0=$@5(B - - 1998/11/21 6.4 $B8~$1%P%0=$@5%Q%C%A%j%j!<%9(B(6.4.2 $B$KH?1G:Q(B)$B!%(B - * BINARY CURSOR $B$NLdBj$r=$@5(B - * pg_dumpall $B$N%P%0=$@5(B - - 1998/11/5 6.4 $B%j%j!<%9!%(B - * pg_database $B$N(B encoding $B%+%i%`$,(B MB $B$,M-8z$G$J$$$H$-$K$b(B - $BDI2C$5$l$k$h$&$K$J$C$?!%$=$N$?$a!$(BMB $B$,M-8z$G$J$$$H$-$K$O!$(B - ASCII $B$N%(%s%3!<%G%#%s%0$rI=$9(B SQL_ASCII $B$r?7$7$$%(%s%3!<%G%#%s%0(B - $B$H$7$FDI2C$7$?!%$3$l$K$H$b$J$$!$%(%s%3!<%G%#%s%0L>$KBP1~$9$k(B - $B%(%s%3!<%G%#%s%0(BID$B$,(B SQL_ASCII $B$r(B 0 $B$H$9$kHV9f$KJQ99$K$J$C$?!%(B - - 1998/7/22 6.4 $B&A8~$1$K%Q%C%A$r%j%j!<%9!%(B - * initdb/createdb/create database $B$G%P%C%/%(%s%IB&$N(B - $B%(%s%3!<%G%#%s%0$r@_Dj$-$k5!G=l=j$rBgI}8+D>$7!%(BMB $B4X78$O(B - include/mb, backend/utils/mb $B$KCV$/$h$&$K$7$?(B - - 1998/5/25 $B%P%0=$@5(B(mb_b3.patch $B$H$7$F(B pgsql-jp ML $B$K%j%j!<%9!$(B - $BK\2H$G$O(B 6.4 snapshot $B$K$7I,MW(B - * configure $B$N%*%W%7%g%s$K(B MB $B%5%]!<%HDI2C(B - (ex. configure --with-mb=EUC_JP) - * EUC_KR $B$N(B regression test $BDI2C(B - ("Soonmyung. Hong" $B$5$sDs6!(B) - * EUC_JP $B$N(B regression test $B$K(B character_length(), position(), - substring(), octet_length() $BDI2C(B - * regress.sh $B$N(B SystemV $B$K$*$1$kHs8_49@-=$@5(B - * toupper(), tolower() $B$K(B 8bit $BJ8;z$,EO$k$HMn$A$k$3$H$,(B - $B$"$k$N$r=$@5(B - - 1998/3/25 PostgreSQL 6.3.1 $B%j%j!<%9!$(BMB PL2 $B$,l9g$KH/@8$9$k%P%0$r=$@5(B - - 1998/3/1 PL1 $B$r%j%j!<%9(B - -$B0J>e!%(B diff --git a/doc/TODO b/doc/TODO deleted file mode 100644 index f8ce3e0569..0000000000 --- a/doc/TODO +++ /dev/null @@ -1,533 +0,0 @@ -TODO list for PostgreSQL -======================== -Last updated: Thu Jun 20 12:54:59 EDT 2002 - -Current maintainer: Bruce Momjian (pgman@candle.pha.pa.us) - -The most recent version of this document can be viewed at -the PostgreSQL web site, http://www.PostgreSQL.org. - -A dash (-) marks changes that will appear in the upcoming 7.3 release. - -Bracketed items "[]" have more detailed. - - -Urgent -====== - -* Add replication of distributed databases [replication] - o automatic failover - o load balancing - o master/slave replication - o multi-master replication - o partition data across servers - o sample implementation in contrib/rserv - o queries across databases or servers (two-phase commit) - o allow replication over unreliable or non-persistent links - o http://gborg.postgresql.org/project/pgreplication/projdisplay.php -* Point-in-time data recovery using backup and write-ahead log - - -Reporting -========= - -* Allow elog() to return error codes, module name, file name, line - number, not just messages (Peter E) -* Add error codes (Peter E) -* -Change DEBUG startup tag to LOG (Bruce) -* Show location of syntax error in query [yacc] -* Add getpid() function to backend - - -Permissions -=========== - -* Improve control over user privileges, including table creation and - lock use [privileges] (Karel, others) -* -Allow user/group names to be specified directly in pg_hba.conf (Bruce) -* Add PGPASSWORDFILE environment variable or ~/.pgpass to store - user/host/password combinations -* Remove PGPASSWORD because it is insecure on some OS's -* Make single-user local access permissions the default by limiting - permissions on the socket file (Peter E) -* -Allow permissions for functions (Peter E) -* -Allow object creation to be disabled for specific users - -Administration -============== - -* Incremental backups -* -Make it easier to create a database owned by someone who can't createdb, - perhaps CREATE DATABASE dbname WITH OWNER = "user" (Gavin) -* -Make equals sign optional in CREATE DATABASE WITH param = 'val' -* Remove unreferenced table files and temp tables during database vacuum - or postmaster startup (Bruce) -* Add table name mapping for numeric file names (Bruce) -* Remove behavior of postmaster -o after making postmaster/postgres - flags unique -* Allow logging of query durations -* -Prevent SIGHUP and 'pg_ctl reload' from changing command line - specified parameters to postgresql.conf defaults (Peter E) -* Allow easy display of usernames in a group - -Data Types -========== - -* -Add domain capability (Rod Taylor) -* Add IPv6 capability to INET/CIDR types -* Remove Money type, add money formatting for decimal type -* SELECT cash_out(2) crashes because of opaque -* Declare typein/out functions in pg_proc with a special "C string" data type -* Functions returning sets do not totally work -* Change factorial to return a numeric -* Change NUMERIC data type to use base 10,000 internally -* Change NUMERIC to enforce the maximum precision, and increase it -* Add function to return compressed length of TOAST data values (Tom) -* Add GUC parameter for DATESTYLE - -* CONVERSION - o Store binary-compatible type information in the system - o Allow better handling of numeric constants, type conversion - [typeconv] - o SELECT col FROM tab WHERE numeric_col = 10.1 fails, requires quotes - -* ARRAYS - o Allow nulls in arrays - o Allow arrays to be ORDER'ed - o Ensure we have array-eq operators for every built-in array type - o Support construction of array result values in expressions - -* BINARY DATA - o Improve vacuum of large objects, like /contrib/vacuumlo - o Add security checking for large objects - o Make file in/out interface for TOAST columns, similar to large object - interface (force out-of-line storage and no compression) - o Auto-delete large objects when referencing row is deleted - - -Multi-Language Support -====================== - -* Add NCHAR (as distinguished from ordinary varchar), -* Allow LOCALE on a per-column basis, default to ASCII -* Support multiple simultaneous character sets, per SQL92 -* Allow setting database character set without multibyte enabled -* Improve Unicode combined character handling -* Optimize locale to have minimal performance impact when not used (Peter E) -* Add octet_length_server() and octet_length_client() (Thomas, Tatsuo) -* Make octet_length_client the same as octet_length() (?) - - -Views / Rules -============= - -* Automatically create rules on views so they are updateable, per SQL92 [view] -* Add the functionality for WITH CHECK OPTION clause of CREATE VIEW -* Allow NOTIFY in rules involving conditionals -* Allow temporary views -* Require view using temporary tables to be temporary views -* Move psql backslash information into views -* Allow RULE recompilation -* -Remove brackets as multi-statement rule grouping, must use parens (Bruce) -* Prevent aggregates from being used in rule WHERE clauses - - -Indexes -======= - -* Allow CREATE INDEX zman_index ON test (date_trunc( 'day', zman ) datetime_ops) - fails index can't store constant parameters -* Order duplicate index entries by tid for faster heap lookups -* Allow inherited tables to inherit index, UNIQUE constraint, and primary - key, foreign key [inheritance] -* UNIQUE INDEX on base column not honored on inserts from inherited table - INSERT INTO inherit_table (unique_index_col) VALUES (dup) should fail - [inheritance] -* Allow UPDATE/DELETE on inherited table -* Have UPDATE/DELETE clean out indexes -* Add UNIQUE capability to non-btree indexes -* Add btree index support for reltime, tinterval, regproc -* Add rtree index support for line, lseg, path, point -* Certain indexes will not shrink, e.g. indexes on ever-increasing - columns and indexes with many duplicate keys -* Use indexes for min() and max() or convert to SELECT col FROM tab ORDER - BY col DESC LIMIT 1 if appropriate index exists and WHERE clause acceptible -* Allow LIKE indexing optimization for non-ASCII locales -* Use index to restrict rows returned by multi-key index when used with - non-consecutive keys or OR clauses, so fewer heap accesses -* Be smarter about insertion of already-ordered data into btree index -* -Add deleted bit to index tuples to reduce heap access -* Prevent index uniqueness checks when UPDATE does not modifying column -* Add bitmap indexes [performance] -* Improve handling of index scans for NULL -* Allow SELECT * FROM tab WHERE int2col = 4 to use int2col index, int8, - float4, numeric/decimal too [optimizer] -* Add FILLFACTOR to btree index creation -* Improve concurrency in GIST -* Improve concurrency of hash indexes (Neil Conway) -* Test hash index performance and recommend or discourage usage - -Commands -======== - -* -Add SIMILAR TO to allow character classes, 'pg_[a-c]%' -* Add BETWEEN ASYMMETRIC/SYMMETRIC (Christopher) -* -Remove LIMIT #,# and force use LIMIT and OFFSET clauses in 7.3 (Bruce) -* Allow LIMIT/OFFSET to use expressions -* Disallow TRUNCATE on tables that are involved in referential constraints -* Add OR REPLACE clauses to non-FUNCTION object creation -* CREATE TABLE AS can not determine column lengths from expressions [atttypmod] -* Allow UPDATE to handle complex aggregates [update] -* -Prevent create/drop scripts from allowing extra args (Bruce) -* Allow command blocks to ignore certain types of errors -* Add checks for missing parameters to shell script, to prevent - over-shifting -* Allow backslash handling in quoted strings to be disabled for portability - -* ALTER - o ALTER TABLE ADD COLUMN does not honor DEFAULT and non-CHECK CONSTRAINT - o ALTER TABLE ADD COLUMN to inherited table put column in wrong place - [inheritance] - o Add ALTER TABLE DROP COLUMN feature [drop] - o Add ALTER FUNCTION - o Add ALTER TABLE DROP non-CHECK CONSTRAINT - o -ALTER TABLE ADD PRIMARY KEY (Tom) - o -ALTER TABLE ADD UNIQUE (Tom) - o -ALTER TABLE ALTER COLUMN SET/DROP NOT NULL (Christopher Kings-Lynne) - o ALTER TABLE ADD COLUMN column SERIAL doesn't create sequence - o ALTER TABLE ADD COLUMN column SET DEFAULT should fill existing - rows with DEFAULT value - o -Have ALTER TABLE OWNER change all dependant objects like indexes - -* CLUSTER - o Cluster all tables at once - o Prevent loss of indexes, permissions, inheritance - o Automatically maintain clustering on a table - -* COPY - o Allow specification of column names - o Allow dump/load of CSV format - o Change syntax to WITH DELIMITER, (keep old syntax around?) - o Allow COPY to report error lines and continue; optionally - allow error codes to be specified; requires savepoints or can - not be run in a multi-statement transaction - o Generate failure on short COPY lines rather than pad NULLs - -* CURSOR - o Allow BINARY option to SELECT, just like DECLARE - o MOVE 0 should not move to end of cursor - o Allow UPDATE/DELETE WHERE CURRENT OF cursor using per-cursor tid - stored in the backend - o Prevent DROP of table being referenced by our own open cursor - o Allow cursors outside transactions [cursor] - -* INSERT - o Allow INSERT/UPDATE of system-generated oid value for a row - o Allow INSERT INTO tab (col1, ..) VALUES (val1, ..), (val2, ..) - o -Allow INSERT INTO my_table VALUES (a, b, c, DEFAULT, x, y, z, ...) - o -Disallow missing columns in INSERT ... VALUES, per ANSI - o Allow INSERT/UPDATE ... RETURNING new.col or old.col; handle - RULE cases (Philip) - -* SHOW/SET - o Add SHOW command to display locks - o Add SET or BEGIN timeout parameter to cancel query - o Add SET REAL_FORMAT and SET DOUBLE_PRECISION_FORMAT using printf args - o Remove SET KSQO option now that OR processing is improved (Tom) - o Add SET PERFORMANCE_TIPS option to suggest INDEX, VACUUM, VACUUM - ANALYZE, and CLUSTER - o Add SHOW command to see locale - o Allow SHOW to output as a query result, like EXPLAIN - o -Abort all SET changes made in an aborted transaction - -* SERVER-SIDE LANGUAGES - o Allow PL/PgSQL's RAISE function to take expressions - o Fix PL/PgSQL to handle quoted mixed-case identifiers - o Change PL/PgSQL to use palloc() instead of malloc() - o Add untrusted version of plpython - o Add plsh server-side shell language (Peter E) - o Allow Java server-side programming, http://pljava.sourceforge.net - [java] - o Fix problems with complex temporary table creation/destruction - without using PL/PgSQL EXECUTE, needs cache prevention/invalidation - o Fix PL/pgSQL RENAME to work on variables other than OLD/NEW - - -Clients -======= - -* Have pg_dump use LEFT OUTER JOIN in multi-table SELECTs - or multiple SELECTS to avoid bad system catalog entries -* -Have pg_dump -C dump database location and encoding information -* Allow psql \d to show foreign keys -* Allow psql \d to show temporary table structure -* Allow psql to show transaction status if backend protocol changes made -* Add XML interface: psql, pg_dump, COPY, separate server (?) -* Add config file check for $ODBCINI, $HOME/.odbc.ini, installpath/etc/odbc.ini -* -Have pg_dump use ADD PRIMARY KEY after COPY, for performance (Neil Conway) - -* JDBC - o Comprehensive test suite. This may be available already. - o -Updateable resultSet - o JDBC-standard BLOB support - o Error Codes (pending backend implementation) - o Support both 'make' and 'ant' - o Fix LargeObject API to handle OIDs as unsigned ints - o -Implement cancel() method on Statement - o Use cursors implicitly to avoid large results (see setCursorName()) - o Add support for CallableStatements - o Add LISTEN/NOTIFY support to the JDBC driver (Barry) - o Compile under jdk 1.4 - -* ECPG - o Implement set descriptor, using descriptor - o Make casts work in variable initializations - o Implement SQLDA - o Allow multi-threaded use of SQLCA - o Solve cardinality > 1 for input descriptors / variables - o Understand structure definitions outside a declare section - o sqlwarn[6] should be 'W' if the PRECISION or SCALE value specified - o Improve error handling - o Allow :var[:index] or :var[] as cvariable for an array var - o Add a semantic check level, e.g. check if a table really exists - o Fix nested C comments - o Add SQLSTATE - o fix handling of DB attributes that are arrays - -* ODBC - o ODBC 3.0 support - o Unicode(UCS-2) support - o Updatable cursors support - - -Referential Integrity -===================== - -* Add MATCH PARTIAL referential integrity [foreign] -* Add deferred trigger queue file (Jan) -* -Allow oid to act as a foreign key -* Implement dirty reads and use them in RI triggers -* Make triggers refer to columns by number, not name -* Enforce referential integrity for system tables -* -Allow user to control trigger firing order (Tom) -* Add ALTER TRIGGER ... RENAME -* Change foreign key constraint for array -> element to mean element - in array -* Fix foreign key constraints to not error on intermediate db states (Stephan) -* Allow DEFERRABLE UNIQUE constraints - -Dependency Checking -=================== - -* Add pg_depend table for dependency recording; use sysrelid, oid, - depend_sysrelid, depend_oid, name -* Auto-destroy sequence on DROP of table with SERIAL; perhaps a separate - SERIAL type -* Have SERIAL generate non-colliding sequence names when we have - auto-destruction -* Prevent column dropping if column is used by foreign key -* Propagate column or table renaming to foreign key constraints -* Automatically drop constraints/functions when object is dropped -* Make constraints clearer in dump file -* Make foreign keys easier to identify -* Flush cached query plans when their underlying catalog data changes - - -Transactions -============ - -* Allow autocommit so always in a transaction block -* Overhaul bufmgr/lockmgr/transaction manager -* Allow savepoints / nested transactions [transactions] - - -Exotic Features -=============== - -* Add sql3 recursive unions -* Add the concept of dataspaces/tablespaces [tablespaces] -* Allow SQL92 schemas (Tom) [schema] -* Allow queries across multiple databases [crossdb] -* Add pre-parsing phase that converts non-ANSI features to supported features -* Allow plug-in modules to emulate features from other databases -* SQL*Net listener that makes PostgreSQL appear as an Oracle database - to clients - - -PERFORMANCE -=========== - - -Fsync -===== - -* Delay fsync() when other backends are about to commit too [fsync] - o Determine optimal commit_delay value -* Determine optimal fdatasync/fsync, O_SYNC/O_DSYNC options - o Allow multiple blocks to be written to WAL with one write() - - -Cache -===== -* Cache most recent query plan(s) (Neil) [prepare] -* Shared catalog cache, reduce lseek()'s by caching table size in shared area -* Add free-behind capability for large sequential scans (Bruce) -* Allow binding query args over FE/BE protocol -* Consider use of open/fcntl(O_DIRECT) to minimize OS caching -* Make blind writes go through the file descriptor cache - - -Vacuum -====== - -* Improve speed with indexes (perhaps recreate index instead) [vacuum] -* Reduce lock time by moving tuples with read lock, then write - lock and truncate table [vacuum] -* Provide automatic running of vacuum in the background (Tom) - - -Locking -======= - -* Make locking of shared data structures more fine-grained -* Add code to detect an SMP machine and handle spinlocks accordingly - from distributted.net, http://www1.distributed.net/source, - in client/common/cpucheck.cpp -* Research use of sched_yield() for spinlock acquisition failure - - -Startup Time -============ - -* Experiment with multi-threaded backend [thread] -* Add connection pooling [pool] -* Allow persistent backends [persistent] -* Create a transaction processor to aid in persistent connections and - connection pooling -* Do listen() in postmaster and accept() in pre-forked backend -* Have pre-forked backend pre-connect to last requested database or pass - file descriptor to backend pre-forked for matching database -* -Cache system catalog information in per-database files (Tom) - - -Write-Ahead Log -=============== - -* Have after-change WAL write()'s write only modified data to kernel -* Reduce number of after-change WAL writes; they exist only to gaurd against - partial page writes -* Turn off after-change writes if fsync is disabled (?) -* Add WAL index reliability improvement to non-btree indexes -* -Reorder postgresql.conf WAL items in order of importance (Bruce) -* Remove wal_files postgresql.conf option because WAL files are now recycled -* Find proper defaults for postgresql.conf WAL entries -* Add checkpoint_min_warning postgresql.conf option to warn about checkpoints - that are too frequent - - -Optimizer / Executor -==================== - -* Improve Subplan list handling -* Allow Subplans to use efficient joins(hash, merge) with upper variable -* Improve dynamic memory allocation by introducing tuple-context memory - allocation (Tom) -* Add hash for evaluating GROUP BY aggregates -* Nested FULL OUTER JOINs don't work (Tom) -* Allow merge and hash joins on expressions not just simple variables (Tom) -* -Add new pg_proc cachable settings to specify whether function can be - evaluated only once or once per query -* -Change FIXED_CHAR_SEL to 0.20 from 0.04 to give better selectivity (Bruce) -* Make IN/NOT IN have similar performance to EXISTS/NOT EXISTS [exists] -* Missing optimizer selectivities for date, r-tree, etc. [optimizer] -* Allow ORDER BY ... LIMIT to select top values without sort or index - using a sequential scan for highest/lowest values (Oleg) -* Inline simple SQL functions to avoid overhead (Tom) -* Precompile SQL functions to avoid overhead (Neil Conway) -* Add utility to compute accurate random_page_cost value -* Improve ability to display optimizer analysis using OPTIMIZER_DEBUG - -Miscellaneous -============= - -* Do async I/O for faster random read-ahead of data -* Get faster regex() code from Henry Spencer - when it is available -* Use mmap() rather than SYSV shared memory or to write WAL files (?) [mmap] -* Improve caching of attribute offsets when NULLs exist in the row -* Add Intimate Shared Memory(ISM) for Solaris -* Add documentation to lock shared memory into RAM for each OS, if possible -* -Use faster flex flags for performance improvement (Peter E) -* Add BSD-licensed qsort() for Solaris - -Source Code -=========== - -* Add use of 'const' for variables in source tree -* -Fix problems with libpq non-blocking/async code -* Make sure all block numbers are unsigned to increase maximum table size -* Use BlockNumber rather than int where appropriate -* Merge LockMethodCtl and LockMethodTable into one shared structure (Bruce) -* HOLDER/HOLDERTAB rename to PROCLOCK/PROCLOCKTAG (Bruce) -* Remove LockMethodTable.prio field, not used (Bruce) -* Add version file format stamp to heap and other table types -* Rename some /contrib modules from pg* to pg_* -* Move some things from /contrib into main tree -* Remove warnings created by -Wcast-align -* Move platform-specific ps status display info from ps_status.c to ports -* Make one version of simple_prompt() in code (Bruce, Tom) -* -Compile in syslog functionaility by default (Tatsuo) -* Modify regression tests to prevent failures do to minor numeric rounding -* Use our own getopt() for FreeBSD/OpenBSD to allow --xxx flags (Bruce) -* Add OpenBSD's getpeereid() call for local socket authentication (Bruce) -* Improve access-permissions check on data directory in Cygwin (Tom) -* Report failure to find readline or zlib at end of configure run -* Add --port flag to regression tests -* Increase identifier length (NAMEDATALEN) if small performance hit, - perhaps to standard length of 128; change struct pgNotify to use pid - first, breaks notify API; [namedatalen] -* Increase maximum number of function parameters if little wasted space -* Add documentation for perl, including mention of DBI/DBD perl location -* Add optional CRC checksum to heap and index pages -* Change representation of whole-tuple parameters to functions -* Evaluate AIX cs() spinlock macro for performance optimizations (Tatsuo) -* Clarify use of 'application' and 'command' tags in SGML docs -* Better document ability to build only certain interfaces (Marc) -* Remove or relicense modules that are not under the BSD license, if possible -* Remove memory/file descriptor freeing befor elog(ERROR) (Bruce) -* Create native Win32 port [win32] - ---------------------------------------------------------------------------- - - -Developers who have claimed items are: --------------------------------------- -* Barry is Barry Lind -* Billy is Billy G. Allie -* Bruce is Bruce Momjian -* Christopher is Christopher Kings-Lynne -* D'Arcy is D'Arcy J.M. Cain -* Dave is Dave Cramer -* Edmund is Edmund Mergl -* Hiroshi is Hiroshi Inoue -* Karel is Karel Zak -* Jan is Jan Wieck -* Liam is Liam Stewart -* Marc is Marc Fournier -* Mark is Mark Hollomon -* Marko is Marko Kreen -* Michael is Michael Meskes -* Neil is Neil Conway -* Oleg is Oleg Bartunov -* Peter M is Peter T Mount -* Peter E is Peter Eisentraut -* Philip is Philip Warner -* Rod is Rod Taylor -* Ross is Ross J. Reedstrom -* Ryan is Ryan Bradetich -* Stephan is Stephan Szabo -* Tatsuo is Tatsuo Ishii -* Thomas is Thomas Lockhart -* Tom is Tom Lane -* TomH is Tom I Helbekkmo -* Vadim is Vadim B. Mikheev diff --git a/doc/TODO.detail/README b/doc/TODO.detail/README deleted file mode 100644 index 96686217ea..0000000000 --- a/doc/TODO.detail/README +++ /dev/null @@ -1,3 +0,0 @@ -These files are in standard Unix mailbox format, and contain detailed -information related to the TODO list. - diff --git a/doc/TODO.detail/atttypmod b/doc/TODO.detail/atttypmod deleted file mode 100644 index f9a17fcab7..0000000000 --- a/doc/TODO.detail/atttypmod +++ /dev/null @@ -1,278 +0,0 @@ -From tgl@sss.pgh.pa.us Wed Nov 21 22:51:02 2001 -Return-path: -Received: from sss.pgh.pa.us (root@[192.204.191.242]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fAM3p2v12831 - for ; Wed, 21 Nov 2001 22:51:02 -0500 (EST) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id fAM3p4c27978; - Wed, 21 Nov 2001 22:51:04 -0500 (EST) -To: Bruce Momjian -cc: Peter Eisentraut , - PostgreSQL Development , - stiening@cannon.astro.umass.edu, pgsql-bugs@postgresql.org -Subject: Re: [BUGS] Bug #513: union all changes char(3) column definition -In-Reply-To: <200111220310.fAM3A2V08766@candle.pha.pa.us> -References: <200111220310.fAM3A2V08766@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Wed, 21 Nov 2001 22:10:02 -0500" -Date: Wed, 21 Nov 2001 22:51:04 -0500 -Message-ID: <27975.1006401064@sss.pgh.pa.us> -From: Tom Lane -Status: ORr - -Bruce Momjian writes: -> Added to TODO: -> * CREATE TABLE AS can not determine column lengths from expressions -> Seems it should be documented. Do we throw an error in these cases? - -No. What we do right now is to generate non-length-constrained column -types for the created table. - -Your TODO item is too pessimistic: we *do* determine the column length -in simple cases. For example: - -regression=# create table foo (f1 char(3)); -CREATE -regression=# create table bar as select * from foo; -SELECT -regression=# \d bar - Table "bar" - Column | Type | Modifiers ---------+--------------+----------- - f1 | character(3) | - -However, in more complex cases we don't know the column length: - -regression=# create table baz as select f1 || 'z' as f1 from foo; -SELECT -regression=# \d baz - Table "baz" - Column | Type | Modifiers ---------+--------+----------- - f1 | bpchar | - -The argument here is about how much intelligence it's reasonable to -expect the system to have. It's very clearly not feasible to derive -a length limit automagically in every case. How hard should we try? - - regards, tom lane - -From pgsql-bugs-owner+M2695=candle.pha.pa.us=pgman@postgresql.org Wed Nov 21 23:16:19 2001 -Return-path: -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fAM4GJv15505 - for ; Wed, 21 Nov 2001 23:16:19 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fAM4CxN38340 - for ; Wed, 21 Nov 2001 22:12:59 -0600 (CST) - (envelope-from pgsql-bugs-owner+M2695=candle.pha.pa.us=pgman@postgresql.org) -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fAM48em84313; - Wed, 21 Nov 2001 23:08:40 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id fAM48bc28082; - Wed, 21 Nov 2001 23:08:37 -0500 (EST) -To: Bruce Momjian -cc: Peter Eisentraut , - PostgreSQL Development , - stiening@cannon.astro.umass.edu, pgsql-bugs@postgresql.org -Subject: Re: [BUGS] Bug #513: union all changes char(3) column definition -In-Reply-To: <200111220353.fAM3rRg12994@candle.pha.pa.us> -References: <200111220353.fAM3rRg12994@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Wed, 21 Nov 2001 22:53:27 -0500" -Date: Wed, 21 Nov 2001 23:08:37 -0500 -Message-ID: <28079.1006402117@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-bugs-owner@postgresql.org -Status: OR - -Bruce Momjian writes: -> However, I don't think creating a bpchar -> with no length is a proper solution. Should we just punt to text in -> these cases? - -How many special cases like that do you want to put into the allegedly -datatype-independent CREATE TABLE code? - -If I thought this were the only case then I'd not object ... but it -looks like a slippery slope from here. - -And --- it's not like replacing "bpchar" with "text" actually buys us -any useful new functionality. AFAICS it's just a cosmetic thing. - - regards, tom lane - -PS: On the other hand, we might consider attacking the problem from -the reverse direction, ie *removing* code. For example, if there -weren't redundant || operators for char and varchar, then every || -operation would yield text, and the example we're looking at would -work the way you want for free. I've thought for awhile that we -could use a pass through pg_proc and pg_operator to remove some -entries we don't really need. - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From tgl@sss.pgh.pa.us Wed Nov 21 23:08:36 2001 -Return-path: -Received: from sss.pgh.pa.us (root@[192.204.191.242]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fAM48av14412 - for ; Wed, 21 Nov 2001 23:08:36 -0500 (EST) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id fAM48bc28082; - Wed, 21 Nov 2001 23:08:37 -0500 (EST) -To: Bruce Momjian -cc: Peter Eisentraut , - PostgreSQL Development , - stiening@cannon.astro.umass.edu, pgsql-bugs@postgresql.org -Subject: Re: [BUGS] Bug #513: union all changes char(3) column definition -In-Reply-To: <200111220353.fAM3rRg12994@candle.pha.pa.us> -References: <200111220353.fAM3rRg12994@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Wed, 21 Nov 2001 22:53:27 -0500" -Date: Wed, 21 Nov 2001 23:08:37 -0500 -Message-ID: <28079.1006402117@sss.pgh.pa.us> -From: Tom Lane -Status: ORr - -Bruce Momjian writes: -> However, I don't think creating a bpchar -> with no length is a proper solution. Should we just punt to text in -> these cases? - -How many special cases like that do you want to put into the allegedly -datatype-independent CREATE TABLE code? - -If I thought this were the only case then I'd not object ... but it -looks like a slippery slope from here. - -And --- it's not like replacing "bpchar" with "text" actually buys us -any useful new functionality. AFAICS it's just a cosmetic thing. - - regards, tom lane - -PS: On the other hand, we might consider attacking the problem from -the reverse direction, ie *removing* code. For example, if there -weren't redundant || operators for char and varchar, then every || -operation would yield text, and the example we're looking at would -work the way you want for free. I've thought for awhile that we -could use a pass through pg_proc and pg_operator to remove some -entries we don't really need. - -From pgsql-bugs-owner+M2696=candle.pha.pa.us=pgman@postgresql.org Wed Nov 21 23:26:07 2001 -Return-path: -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fAM4Q6v16612 - for ; Wed, 21 Nov 2001 23:26:06 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fAM4MwN38618 - for ; Wed, 21 Nov 2001 22:22:58 -0600 (CST) - (envelope-from pgsql-bugs-owner+M2696=candle.pha.pa.us=pgman@postgresql.org) -Received: from candle.pha.pa.us (candle.navpoint.com [162.33.245.46]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fAM4DUm84443; - Wed, 21 Nov 2001 23:13:30 -0500 (EST) - (envelope-from pgman@candle.pha.pa.us) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.11.6/8.10.1) id fAM4DSH15042; - Wed, 21 Nov 2001 23:13:28 -0500 (EST) -From: Bruce Momjian -Message-ID: <200111220413.fAM4DSH15042@candle.pha.pa.us> -Subject: Re: [BUGS] Bug #513: union all changes char(3) column definition -In-Reply-To: <28079.1006402117@sss.pgh.pa.us> "from Tom Lane at Nov 21, 2001 - 11:08:37 pm" -To: Tom Lane -Date: Wed, 21 Nov 2001 23:13:28 -0500 (EST) -cc: Peter Eisentraut , - PostgreSQL Development , - stiening@cannon.astro.umass.edu, pgsql-bugs@postgresql.org -X-Mailer: ELM [version 2.4ME+ PL90 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -Precedence: bulk -Sender: pgsql-bugs-owner@postgresql.org -Status: OR - -> How many special cases like that do you want to put into the allegedly -> datatype-independent CREATE TABLE code? -> -> If I thought this were the only case then I'd not object ... but it -> looks like a slippery slope from here. -> -> And --- it's not like replacing "bpchar" with "text" actually buys us -> any useful new functionality. AFAICS it's just a cosmetic thing. -> -> regards, tom lane -> -> PS: On the other hand, we might consider attacking the problem from -> the reverse direction, ie *removing* code. For example, if there -> weren't redundant || operators for char and varchar, then every || -> operation would yield text, and the example we're looking at would -> work the way you want for free. I've thought for awhile that we -> could use a pass through pg_proc and pg_operator to remove some -> entries we don't really need. - -Can we convert bpchar to text in create table if no typmod is supplied? - --- - Bruce Momjian | http://candle.pha.pa.us - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From peter_e@gmx.net Thu Nov 22 12:14:01 2001 -Return-path: -Received: from mout02.kundenserver.de (mout02.kundenserver.de [195.20.224.133]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fAMHE0v13505 - for ; Thu, 22 Nov 2001 12:14:00 -0500 (EST) -Received: from [195.20.224.204] (helo=mrvdom00.schlund.de) - by mout02.kundenserver.de with esmtp (Exim 2.12 #2) - id 166xQB-0005p4-00; Thu, 22 Nov 2001 18:13:55 +0100 -Received: from p3e9e70dc.dip0.t-ipconnect.de ([62.158.112.220]) - by mrvdom00.schlund.de with esmtp (Exim 2.12 #2) - id 166xQ9-00065m-00; Thu, 22 Nov 2001 18:13:53 +0100 -Date: Thu, 22 Nov 2001 18:21:17 +0100 (CET) -From: Peter Eisentraut -X-Sender: -To: Tom Lane -cc: Bruce Momjian , - PostgreSQL Development -Subject: Re: [BUGS] Bug #513: union all changes char(3) column definition -In-Reply-To: <27975.1006401064@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Status: OR - -Tom Lane writes: - -> The argument here is about how much intelligence it's reasonable to -> expect the system to have. It's very clearly not feasible to derive -> a length limit automagically in every case. How hard should we try? - -I would like to know what Proprietary database #1 does with - -CREATE TABLE one ( a bit(6) ); -INSERT INTO one VALUES ( b'101101' ); -CREATE TABLE two ( b bit(4) ); -INSERT INTO two VALUES ( b'0110' ); -CREATE TABLE three AS SELECT a FROM one UNION SELECT b FROM two; - -According to SQL92, clause 9.3, the result type of the union is bit(6). -However, it's not possible to store a bit(4) value into a bit(6) field. -Our current solution, "bit()" is even worse because it has no -real semantics at all (but you can store bit() in it, -interestingly). - --- -Peter Eisentraut peter_e@gmx.net - - diff --git a/doc/TODO.detail/crossdb b/doc/TODO.detail/crossdb deleted file mode 100644 index a68fb19828..0000000000 --- a/doc/TODO.detail/crossdb +++ /dev/null @@ -1,771 +0,0 @@ -From pgsql-hackers-owner+M16329=candle.pha.pa.us=pgman@postgresql.org Thu Dec 6 13:31:28 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB6IVRZ13376 - for ; Thu, 6 Dec 2001 13:31:27 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB6IVQa26949 - for ; Thu, 6 Dec 2001 13:31:26 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB6IRvR61959 - for ; Thu, 6 Dec 2001 12:29:06 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16329=candle.pha.pa.us=pgman@postgresql.org) -Received: from gromit.dotclick.com (ipn9-f8366.net-resource.net [216.204.83.66]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB6IQ2m78192 - for ; Thu, 6 Dec 2001 13:26:05 -0500 (EST) - (envelope-from markw@mohawksoft.com) -Received: from mohawksoft.com (IDENT:markw@localhost.localdomain [127.0.0.1]) - by gromit.dotclick.com (8.9.3/8.9.3) with ESMTP id NAA10076 - for ; Thu, 6 Dec 2001 13:28:04 -0500 -Message-ID: <3C0FB8B4.382C7736@mohawksoft.com> -Date: Thu, 06 Dec 2001 13:28:04 -0500 -From: mlw -X-Mailer: Mozilla 4.75 [en] (X11; U; Linux 2.4.16 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: "pgsql-hackers@postgresql.org" -Subject: [HACKERS] Remote connections? -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -I just found out something about Oracle which that looks like something -that could be doable in PostgreSQL. - -What do you all think: - -Oracle's version is something like this: - -create [public] database link using [...] - -select * from sometable@remotelink - - -I was thinking how this could be done with postgreSQL. How hard would it -be to make something that is similar to a view, but executes a query -remotely? I envision something like this: - -create [public] link name query using [...] - -The table link will be similar to a view. It could be used like this: - -CREATE LINK test as select * from test WITH 'user=postgres host=remote -db=data'; - -SELECT * from test; - -or - -SELECT * from fubar join test on (fubar.id = test.id) ; - -So, what do you think? Impossible, possible, too hard? too easy? - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M16331=candle.pha.pa.us=pgman@postgresql.org Thu Dec 6 15:12:28 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB6KCQZ19987 - for ; Thu, 6 Dec 2001 15:12:27 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB6KCQa13967 - for ; Thu, 6 Dec 2001 15:12:26 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB6K6nR65020 - for ; Thu, 6 Dec 2001 14:07:54 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16331=candle.pha.pa.us=pgman@postgresql.org) -Received: from ece.rice.edu (ece.rice.edu [128.42.4.34]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB6K6Im96910 - for ; Thu, 6 Dec 2001 15:06:18 -0500 (EST) - (envelope-from reedstrm@rice.edu) -Received: from localhost (localhost [127.0.0.1]) - by ece.rice.edu (Postfix) with ESMTP - id A9E4E68A1D; Thu, 6 Dec 2001 14:06:17 -0600 (CST) -Received: from wallace.ece.rice.edu (wallace.ece.rice.edu [128.42.12.154]) - by ece.rice.edu (Postfix) with ESMTP - id EA06668A17; Thu, 6 Dec 2001 14:06:16 -0600 (CST) -Received: from reedstrm by wallace.ece.rice.edu with local (Exim 3.22 #1 (Debian)) - id 16C4me-0002uX-00; Thu, 06 Dec 2001 14:06:16 -0600 -Date: Thu, 6 Dec 2001 14:06:16 -0600 -From: "Ross J. Reedstrom" -To: mlw -cc: "pgsql-hackers@postgresql.org" -Subject: Re: [HACKERS] Remote connections? -Message-ID: <20011206140616.C10995@rice.edu> -Mail-Followup-To: "Ross J. Reedstrom" , - mlw , - "pgsql-hackers@postgresql.org" -References: <3C0FB8B4.382C7736@mohawksoft.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <3C0FB8B4.382C7736@mohawksoft.com> -User-Agent: Mutt/1.3.18i -X-Virus-Scanned: by AMaViS snapshot-20010714 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Thu, Dec 06, 2001 at 01:28:04PM -0500, mlw wrote: -> I just found out something about Oracle which that looks like something -> that could be doable in PostgreSQL. -> -> What do you all think: -> -> Oracle's version is something like this: -> -> create [public] database link using [...] -> -> select * from sometable@remotelink -> -> -> I was thinking how this could be done with postgreSQL. How hard would it -> be to make something that is similar to a view, but executes a query -> remotely? I envision something like this: -> -> create [public] link name query using [...] -> -> The table link will be similar to a view. It could be used like this: -> -> CREATE LINK test as select * from test WITH 'user=postgres host=remote -> db=data'; -> -> SELECT * from test; -> -> or -> -> SELECT * from fubar join test on (fubar.id = test.id) ; -> -> So, what do you think? Impossible, possible, too hard? too easy? - -Here we come, full circle. This is just about where I came on board. -Many moons ago, I started looking at Mariposa, in the hopes of forward -patching it into PostgreSQL, and generalizing the 'remote' part to allow -exactly the sort of access you described above. - -The biggest problem with this is transactional semantics: you need -two-stage commits to get this right, and we don't hav'em. (Has there -been an indepth discussion concerning what how hard it would be to do -that with postgresql?) - -The _actual_ biggest problem was my lack of knowledge of the PostgreSQL -codebase ;-) - -Ross --- -Ross Reedstrom, Ph.D. reedstrm@rice.edu -Executive Director phone: 713-348-6166 -Gulf Coast Consortium for Bioinformatics fax: 713-348-6182 -Rice University MS-39 -Houston, TX 77005 - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M16332=candle.pha.pa.us=pgman@postgresql.org Thu Dec 6 15:31:27 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB6KVQZ21158 - for ; Thu, 6 Dec 2001 15:31:26 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB6KVQa22900 - for ; Thu, 6 Dec 2001 15:31:26 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB6KRrR65596 - for ; Thu, 6 Dec 2001 14:28:55 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16332=candle.pha.pa.us=pgman@postgresql.org) -Received: from gromit.dotclick.com (ipn9-f8366.net-resource.net [216.204.83.66]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB6KJXm97564 - for ; Thu, 6 Dec 2001 15:19:33 -0500 (EST) - (envelope-from markw@mohawksoft.com) -Received: from mohawksoft.com (IDENT:markw@localhost.localdomain [127.0.0.1]) - by gromit.dotclick.com (8.9.3/8.9.3) with ESMTP id PAA10771; - Thu, 6 Dec 2001 15:21:13 -0500 -Message-ID: <3C0FD339.6F663329@mohawksoft.com> -Date: Thu, 06 Dec 2001 15:21:13 -0500 -From: mlw -X-Mailer: Mozilla 4.75 [en] (X11; U; Linux 2.4.16 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: "Ross J. Reedstrom" -cc: "pgsql-hackers@postgresql.org" -Subject: Re: [HACKERS] Remote connections? -References: <3C0FB8B4.382C7736@mohawksoft.com> <20011206140616.C10995@rice.edu> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -"Ross J. Reedstrom" wrote: -> -> On Thu, Dec 06, 2001 at 01:28:04PM -0500, mlw wrote: -> > I just found out something about Oracle which that looks like something -> > that could be doable in PostgreSQL. -> > -> > What do you all think: -> > -> > Oracle's version is something like this: -> > -> > create [public] database link using [...] -> > -> > select * from sometable@remotelink -> > -> > -> > I was thinking how this could be done with postgreSQL. How hard would it -> > be to make something that is similar to a view, but executes a query -> > remotely? I envision something like this: -> > -> > create [public] link name query using [...] -> > -> > The table link will be similar to a view. It could be used like this: -> > -> > CREATE LINK test as select * from test WITH 'user=postgres host=remote -> > db=data'; -> > -> > SELECT * from test; -> > -> > or -> > -> > SELECT * from fubar join test on (fubar.id = test.id) ; -> > -> > So, what do you think? Impossible, possible, too hard? too easy? -> -> Here we come, full circle. This is just about where I came on board. -> Many moons ago, I started looking at Mariposa, in the hopes of forward -> patching it into PostgreSQL, and generalizing the 'remote' part to allow -> exactly the sort of access you described above. -> -> The biggest problem with this is transactional semantics: you need -> two-stage commits to get this right, and we don't hav'em. (Has there -> been an indepth discussion concerning what how hard it would be to do -> that with postgresql?) -> -> The _actual_ biggest problem was my lack of knowledge of the PostgreSQL -> codebase ;-) - -I think we can we can dispense worrying about two stage commits, if we -assume that remote connections are treated as views with no rules. As -long as remote tables are "read only" then the implementation is much -easier. - -I too find the internals of PostgreSQL virtually incomprehensible at the -internal level. If there were a document somewhere which published how a -function could return multiple tuples, remote views would be a trivial -undertaking. It could look like: - -select * from remote('select *from table', 'user=postgres host=outland -db=remote'); - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M16335=candle.pha.pa.us=pgman@postgresql.org Thu Dec 6 17:11:29 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB6MBSZ06676 - for ; Thu, 6 Dec 2001 17:11:28 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB6MBSq07059 - for ; Thu, 6 Dec 2001 17:11:28 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB6M6sR68489 - for ; Thu, 6 Dec 2001 16:08:16 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16335=candle.pha.pa.us=pgman@postgresql.org) -Received: from mx1.relaypoint.net (ns2.generalbroadband.com [64.32.62.5]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB6M3Im04451 - for ; Thu, 6 Dec 2001 17:03:18 -0500 (EST) - (envelope-from joseph.conway@home.com) -Received: from [206.19.64.3] (account jconway@wwc.com HELO home.com) - by mx1.relaypoint.net (CommuniGate Pro SMTP 3.4.8) - with ESMTP id 1707032; Thu, 06 Dec 2001 14:03:14 -0800 -Message-ID: <3C0FEB2C.70000@home.com> -Date: Thu, 06 Dec 2001 14:03:24 -0800 -From: Joe Conway -User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:0.9.6+) Gecko/20011126 -X-Accept-Language: en-us -MIME-Version: 1.0 -To: mlw -cc: "Ross J. Reedstrom" , - "pgsql-hackers@postgresql.org" -Subject: Re: [HACKERS] Remote connections? -References: <3C0FB8B4.382C7736@mohawksoft.com> <20011206140616.C10995@rice.edu> <3C0FD339.6F663329@mohawksoft.com> -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -mlw wrote: - -> I too find the internals of PostgreSQL virtually incomprehensible at the -> internal level. If there were a document somewhere which published how a -> function could return multiple tuples, remote views would be a trivial -> undertaking. It could look like: -> -> select * from remote('select *from table', 'user=postgres host=outland -> db=remote'); -> - -See contrib/dblink in the 7.2 beta. It was my attempt inspired by -Oracle's dblink and some code that you (mlw) posted a while back. Based -on the limitations wrt returning muliple tuples, I wound up with -something like: - -lt_lcat=# select dblink_tok(t1.dblink_p,0) as f1 from (select -dblink('hostaddr=127.0.0.1 dbname=template1 user=postgres -password=postgres','select proname from pg_proc') as dblink_p) as t1; - -Which, as has been pointed out more than once, is pretty ugly, but at -least it's a start ;-) - - -Joe - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M16336=candle.pha.pa.us=pgman@postgresql.org Thu Dec 6 18:41:31 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB6NfPZ12249 - for ; Thu, 6 Dec 2001 18:41:25 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB6NfQq03244 - for ; Thu, 6 Dec 2001 18:41:26 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB6NbOR70960 - for ; Thu, 6 Dec 2001 17:38:19 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16336=candle.pha.pa.us=pgman@postgresql.org) -Received: from spider.pilosoft.com (p55-222.acedsl.com [160.79.55.222]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB6NIgm07232 - for ; Thu, 6 Dec 2001 18:18:43 -0500 (EST) - (envelope-from alex@pilosoft.com) -Received: from localhost (alexmail@localhost) - by spider.pilosoft.com (8.9.3/8.9.3) with ESMTP id SAA23999; - Thu, 6 Dec 2001 18:23:22 -0500 (EST) -Date: Thu, 6 Dec 2001 18:23:22 -0500 (EST) -From: Alex Pilosov -To: mlw -cc: "pgsql-hackers@postgresql.org" -Subject: Re: [HACKERS] Remote connections? -In-Reply-To: <3C0FD339.6F663329@mohawksoft.com> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Thu, 6 Dec 2001, mlw wrote: - -> I too find the internals of PostgreSQL virtually incomprehensible at the -> internal level. If there were a document somewhere which published how a -> function could return multiple tuples, remote views would be a trivial -> undertaking. It could look like: -> -> select * from remote('select *from table', 'user=postgres host=outland -> db=remote'); -This isn't possible yet. I was working on implementation of this, about -80% done, but never finished. Now I'm out of time to work more on this for -a while. :( - -Let me know if you want my code. - --alex - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M16340=candle.pha.pa.us=pgman@postgresql.org Fri Dec 7 00:32:59 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB75WsZ06911 - for ; Fri, 7 Dec 2001 00:32:54 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB75Wtq16801 - for ; Fri, 7 Dec 2001 00:32:55 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB75SCR80525 - for ; Thu, 6 Dec 2001 23:29:17 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16340=candle.pha.pa.us=pgman@postgresql.org) -Received: from snoopy.mohawksoft.com (h0050bf7a618d.ne.mediaone.net [24.218.67.153]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB7593m27913 - for ; Fri, 7 Dec 2001 00:09:03 -0500 (EST) - (envelope-from markw@mohawksoft.com) -Received: from mohawksoft.com (localhost [127.0.0.1]) - by snoopy.mohawksoft.com (8.11.6/8.11.6) with ESMTP id fB7561030613; - Fri, 7 Dec 2001 00:06:01 -0500 -Message-ID: <3C104E38.DA19C867@mohawksoft.com> -Date: Fri, 07 Dec 2001 00:06:01 -0500 -From: mlw -X-Mailer: Mozilla 4.78 [en] (X11; U; Linux 2.4.14ext3 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Joe Conway -cc: "Ross J. Reedstrom" , - "pgsql-hackers@postgresql.org" -Subject: Re: [HACKERS] Remote connections? -References: <3C0FB8B4.382C7736@mohawksoft.com> <20011206140616.C10995@rice.edu> <3C0FD339.6F663329@mohawksoft.com> <3C0FEB2C.70000@home.com> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Hey this looks really cool. It looks like something I was thinking about doing. -I have a couple suggestions that could make it a little better, I hope you will -not be offended. (If you want my help, I'll chip in!) - -Why not use a binary cursor? That way native types can slip through without the -overhead of conversion. - -Right now you get all rows up front, you may be able to increase overall -performance by fetching only a few rows at a time, rather than get everything -all at once. (Think on the order of 4 million rows from your remote query!) -Execute the commit at the end of processing. There are even some asynchronous -functions you may be able to utilize to reduce the I/O bottleneck. Use the -synchronous function first, then before you return initiate an asynchronous -read. Every successive pass through the function, read the newly arrived tuple, -and initiate the next asynchronous read. (The two machine could be processing -the query simultaneously, and this could even IMPROVE performance over a single -system for heavy duty queries.) - -Setup a hash table for field names, rather than requiring field numbers. (Keep -field number for efficiency, of course.) - -You could eliminate having to pass the result pointer around by keeping a -static array in your extension. Use something like Oracle's "contains" notation -of result number. Where each instantiation of "contains()" and "score()" -require an id. i.e. 1,2,3,40 etc. Then hash those numbers into an array. I have -some code that does this for a PostgreSQL extension (it implements contains) on -my website (pgcontains, under download). It is ugly but works for the most -part. - -Seriously, your stuff looks great. I think it could be the beginning of a -fairly usable system for my company. Any help you need/want, just let me know. - - -Joe Conway wrote: -> -> mlw wrote: -> -> > I too find the internals of PostgreSQL virtually incomprehensible at the -> > internal level. If there were a document somewhere which published how a -> > function could return multiple tuples, remote views would be a trivial -> > undertaking. It could look like: -> > -> > select * from remote('select *from table', 'user=postgres host=outland -> > db=remote'); -> > -> -> See contrib/dblink in the 7.2 beta. It was my attempt inspired by -> Oracle's dblink and some code that you (mlw) posted a while back. Based -> on the limitations wrt returning muliple tuples, I wound up with -> something like: -> -> lt_lcat=# select dblink_tok(t1.dblink_p,0) as f1 from (select -> dblink('hostaddr=127.0.0.1 dbname=template1 user=postgres -> password=postgres','select proname from pg_proc') as dblink_p) as t1; -> -> Which, as has been pointed out more than once, is pretty ugly, but at -> least it's a start ;-) -> -> Joe -> -> ---------------------------(end of broadcast)--------------------------- -> TIP 4: Don't 'kill -9' the postmaster - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M16344=candle.pha.pa.us=pgman@postgresql.org Fri Dec 7 02:51:51 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB77poZ14221 - for ; Fri, 7 Dec 2001 02:51:50 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB77pqq08152 - for ; Fri, 7 Dec 2001 02:51:52 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB77lwR84105 - for ; Fri, 7 Dec 2001 01:49:04 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16344=candle.pha.pa.us=pgman@postgresql.org) -Received: from ra.sai.msu.su (ra.sai.msu.su [158.250.29.2]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB77bmm32783 - for ; Fri, 7 Dec 2001 02:37:49 -0500 (EST) - (envelope-from oleg@sai.msu.su) -Received: from ra (ra [158.250.29.2]) - by ra.sai.msu.su (8.9.3/8.9.3) with ESMTP id KAA04160; - Fri, 7 Dec 2001 10:37:04 +0300 (GMT) -Date: Fri, 7 Dec 2001 10:37:04 +0300 (GMT) -From: Oleg Bartunov -X-X-Sender: -To: mlw -cc: Joe Conway , - "Ross J. Reedstrom" , - "pgsql-hackers@postgresql.org" -Subject: Re: [HACKERS] Remote connections? -In-Reply-To: <3C104E38.DA19C867@mohawksoft.com> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Fri, 7 Dec 2001, mlw wrote: - -> -> You could eliminate having to pass the result pointer around by keeping a -> static array in your extension. Use something like Oracle's "contains" notation -> of result number. Where each instantiation of "contains()" and "score()" -> require an id. i.e. 1,2,3,40 etc. Then hash those numbers into an array. I have -> some code that does this for a PostgreSQL extension (it implements contains) on -> my website (pgcontains, under download). It is ugly but works for the most -> part. - -contrib/intarray does this job very well - -> -> Seriously, your stuff looks great. I think it could be the beginning of a -> fairly usable system for my company. Any help you need/want, just let me know. -> -> -> Joe Conway wrote: -> > -> > mlw wrote: -> > -> > > I too find the internals of PostgreSQL virtually incomprehensible at the -> > > internal level. If there were a document somewhere which published how a -> > > function could return multiple tuples, remote views would be a trivial -> > > undertaking. It could look like: -> > > -> > > select * from remote('select *from table', 'user=postgres host=outland -> > > db=remote'); -> > > -> > -> > See contrib/dblink in the 7.2 beta. It was my attempt inspired by -> > Oracle's dblink and some code that you (mlw) posted a while back. Based -> > on the limitations wrt returning muliple tuples, I wound up with -> > something like: -> > -> > lt_lcat=# select dblink_tok(t1.dblink_p,0) as f1 from (select -> > dblink('hostaddr=127.0.0.1 dbname=template1 user=postgres -> > password=postgres','select proname from pg_proc') as dblink_p) as t1; -> > -> > Which, as has been pointed out more than once, is pretty ugly, but at -> > least it's a start ;-) -> > -> > Joe -> > -> > ---------------------------(end of broadcast)--------------------------- -> > TIP 4: Don't 'kill -9' the postmaster -> -> ---------------------------(end of broadcast)--------------------------- -> TIP 3: if posting/reading through Usenet, please send an appropriate -> subscribe-nomail command to majordomo@postgresql.org so that your -> message can get through to the mailing list cleanly -> - - Regards, - Oleg -_____________________________________________________________ -Oleg Bartunov, sci.researcher, hostmaster of AstroNet, -Sternberg Astronomical Institute, Moscow University (Russia) -Internet: oleg@sai.msu.su, http://www.sai.msu.su/~megera/ -phone: +007(095)939-16-83, +007(095)939-23-83 - - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M16412=candle.pha.pa.us=pgman@postgresql.org Mon Dec 10 12:35:01 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fBAHZ0Z09772 - for ; Mon, 10 Dec 2001 12:35:00 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fBAHZ0a11739 - for ; Mon, 10 Dec 2001 12:35:00 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fBAHRAR20284 - for ; Mon, 10 Dec 2001 11:32:00 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16412=candle.pha.pa.us=pgman@postgresql.org) -Received: from snoopy.mohawksoft.com (h0050bf7a618d.ne.mediaone.net [24.218.67.153]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB7DhOm75114 - for ; Fri, 7 Dec 2001 08:43:24 -0500 (EST) - (envelope-from markw@mohawksoft.com) -Received: from mohawksoft.com (localhost [127.0.0.1]) - by snoopy.mohawksoft.com (8.11.6/8.11.6) with ESMTP id fB7De0000437; - Fri, 7 Dec 2001 08:40:01 -0500 -Message-ID: <3C10C6B0.865669C1@mohawksoft.com> -Date: Fri, 07 Dec 2001 08:40:00 -0500 -From: mlw -X-Mailer: Mozilla 4.78 [en] (X11; U; Linux 2.4.14ext3 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Oleg Bartunov -cc: Joe Conway , - "Ross J. Reedstrom" , - "pgsql-hackers@postgresql.org" -Subject: Re: [HACKERS] Remote connections? -References: -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -The dblink code is a very cool idea. - -It got me thinking, what if, just thinking out load here, it was redesigned as -something a little more grandeous. - -Imagine this: - - -select dblink('select * from table', 'table_name', 'db=oracle.test user=chris -passwd=knight', 1) as t1, dblink('table2_name', 1) as t2 - - -Just something to think about. - -The first instance of dblink would take 4 parameters: query, table which it -returns, connect string, and link token. - -The second instance of dblink would just take the name of the table which it -returns and a link token. - -The cool bit is the notion that the query string could specify different -databases or even .DBF libraries. - -Just something to think about. - -It would REALLY be great if functions could return multiple tuples! - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M16365=candle.pha.pa.us=pgman@postgresql.org Fri Dec 7 12:32:26 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB7HWMZ26245 - for ; Fri, 7 Dec 2001 12:32:22 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB7HWLB14472 - for ; Fri, 7 Dec 2001 12:32:21 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB7HSHR01506 - for ; Fri, 7 Dec 2001 11:29:07 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16365=candle.pha.pa.us=pgman@postgresql.org) -Received: from mx1.relaypoint.net (ns2.generalbroadband.com [64.32.62.5]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB7HQfm90424 - for ; Fri, 7 Dec 2001 12:26:42 -0500 (EST) - (envelope-from joseph.conway@home.com) -Received: from [206.19.64.3] (account jconway@wwc.com HELO home.com) - by mx1.relaypoint.net (CommuniGate Pro SMTP 3.4.8) - with ESMTP id 1722339; Fri, 07 Dec 2001 09:26:46 -0800 -Message-ID: <3C10FBD7.4070602@home.com> -Date: Fri, 07 Dec 2001 09:26:47 -0800 -From: Joe Conway -User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:0.9.6+) Gecko/20011126 -X-Accept-Language: en-us -MIME-Version: 1.0 -To: mlw -cc: "Ross J. Reedstrom" , - "pgsql-hackers@postgresql.org" -Subject: Re: [HACKERS] Remote connections? -References: <3C0FB8B4.382C7736@mohawksoft.com> <20011206140616.C10995@rice.edu> <3C0FD339.6F663329@mohawksoft.com> <3C0FEB2C.70000@home.com> <3C104E38.DA19C867@mohawksoft.com> -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -mlw wrote: - -> Hey this looks really cool. It looks like something I was thinking about doing. -> I have a couple suggestions that could make it a little better, I hope you will -> not be offended. (If you want my help, I'll chip in!) -> - - -Thanks! Suggestions welcomed. - -> Why not use a binary cursor? That way native types can slip through without the -> overhead of conversion. -> - - -I wasn't sure that would work. Would you create dblink_tok as returning -opaque then? - - -> Right now you get all rows up front, you may be able to increase overall -> performance by fetching only a few rows at a time, rather than get everything -> all at once. (Think on the order of 4 million rows from your remote query!) -> Execute the commit at the end of processing. There are even some asynchronous -> functions you may be able to utilize to reduce the I/O bottleneck. Use the -> synchronous function first, then before you return initiate an asynchronous -> read. Every successive pass through the function, read the newly arrived tuple, -> and initiate the next asynchronous read. (The two machine could be processing -> the query simultaneously, and this could even IMPROVE performance over a single -> system for heavy duty queries.) - - -Interesting . . . but aren't there some issues with the asynch functions? - -> -> Setup a hash table for field names, rather than requiring field numbers. (Keep -> field number for efficiency, of course.) -> -> You could eliminate having to pass the result pointer around by keeping a -> static array in your extension. Use something like Oracle's "contains" notation -> of result number. Where each instantiation of "contains()" and "score()" -> require an id. i.e. 1,2,3,40 etc. Then hash those numbers into an array. I have -> some code that does this for a PostgreSQL extension (it implements contains) on -> my website (pgcontains, under download). It is ugly but works for the most -> part. -> - - -I thought about the static array, but I'm not familiar with Oracle -contains() and score() -- I'm only fluent enough with Oracle to be -dangerous. Guess I'll have to dig out the books . . . - - -> Seriously, your stuff looks great. I think it could be the beginning of a -> fairly usable system for my company. Any help you need/want, just let me know. -> - -I am planning to improve dblink during the next release cycle, so I'll -keep all this in mind (and might take you up on the help offer too!). I -was hoping we'd have functions returning tuples by now, which would -improve this extension dramatically. Unfortunately, it sounds like Alex -won't have time to finish that even for 7.3 :( - -Alex, can we get a look at your latest code? Is it any different the -your last submission to PATCHES? - -Joe - - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - diff --git a/doc/TODO.detail/cursor b/doc/TODO.detail/cursor deleted file mode 100644 index c87c57476e..0000000000 --- a/doc/TODO.detail/cursor +++ /dev/null @@ -1,530 +0,0 @@ -From pgsql-general-owner+M19848=candle.pha.pa.us=pgman@postgresql.org Fri Jan 25 10:36:36 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0PFaZe16098 - for ; Fri, 25 Jan 2002 10:36:36 -0500 (EST) -Received: (qmail 35750 invoked by alias); 25 Jan 2002 15:34:38 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 15:34:38 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0PFDAl28120 - for ; Fri, 25 Jan 2002 10:13:10 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0PFCqf25364; - Fri, 25 Jan 2002 10:12:52 -0500 (EST) -To: Hiroshi Inoue -cc: Bruce Momjian , - Florian Wunderlich , pgsql-general@postgresql.org -Subject: Re: [GENERAL] persistent portals/cursors (between transactions) -In-Reply-To: <3C510D24.8E1FDF7F@tpf.co.jp> -References: <200201250319.g0P3Jq022575@candle.pha.pa.us> <23244.1011932544@sss.pgh.pa.us> <3C510D24.8E1FDF7F@tpf.co.jp> -Comments: In-reply-to Hiroshi Inoue - message dated "Fri, 25 Jan 2002 16:45:40 +0900" -Date: Fri, 25 Jan 2002 10:12:51 -0500 -Message-ID: <25361.1011971571@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-general-owner@postgresql.org -Status: OR - -Hiroshi Inoue writes: -> Tom Lane wrote: ->> If it's not holding any locks, I can guarantee you it's not insensitive. ->> Consider VACUUM, or even DROP TABLE. - -> It's already possible to keep a lock accross transactions. -> So it would keep an AccessShareLock across transactions. - -AccessShareLock would fend off DROP/ALTER TABLE, but not VACUUM anymore. -We'd need to invent Yet Another lock type that would prevent VACUUM. -Clearly that's perfectly doable. - -But: having just finished a lot of work to ensure that VACUUM could run -in parallel with all "normal" database operations, I'm not that thrilled -at the prospect of introducing a new mechanism that will block VACUUM. -Especially not one that's *designed* to hold its lock for a long period -of time. This will just get us right back into all the operational -problems that lazy VACUUM was intended to get around. For example, this -one: if transaction A has an insensitive-cursor lock on table T, and a -VACUUM comes along to vacuum T and blocks waiting for the lock, then -when subsequent transaction B wants to create an insensitive cursor on T -it's going to be forced to queue up behind the VACUUM. - -While temp tables may seem like an ugly, low-tech way to support -insensitive cursors, I think they may have more merit than you realize. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-general-owner+M19849=candle.pha.pa.us=pgman@postgresql.org Fri Jan 25 11:21:44 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0PGLhe19804 - for ; Fri, 25 Jan 2002 11:21:44 -0500 (EST) -Received: (qmail 65425 invoked by alias); 25 Jan 2002 16:15:14 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 16:15:14 -0000 -Received: from post.webmailer.de (natpost.webmailer.de [192.67.198.65]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0PG5il56844 - for ; Fri, 25 Jan 2002 11:05:44 -0500 (EST) - (envelope-from fwunderlich@devbrain.de) -Received: from faxdial.hq.factor3.com (p3E9ED0CC.dip.t-dialin.net [62.158.208.204]) - by post.webmailer.de (8.9.3/8.8.7) with ESMTP id RAA07886; - Fri, 25 Jan 2002 17:05:46 +0100 (MET) -Received: from hq.factor3.com (florian@main.hq.factor3.com [192.168.1.2]) - by faxdial.hq.factor3.com (8.11.1/8.11.0) with ESMTP id g0PG4P210606; - Fri, 25 Jan 2002 17:04:25 +0100 -Message-ID: <3C518231.F65DC636@hq.factor3.com> -Date: Fri, 25 Jan 2002 17:05:05 +0100 -From: Florian Wunderlich -X-Mailer: Mozilla 4.76 [en] (X11; U; Linux 2.4.17 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Tom Lane -cc: Hiroshi Inoue , Bruce Momjian , - pgsql-general@postgresql.org -Subject: Re: [GENERAL] persistent portals/cursors (between transactions) -References: <200201250319.g0P3Jq022575@candle.pha.pa.us> <23244.1011932544@sss.pgh.pa.us> <3C510D24.8E1FDF7F@tpf.co.jp> <25361.1011971571@sss.pgh.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-general-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> -> Hiroshi Inoue writes: -> > Tom Lane wrote: -> >> If it's not holding any locks, I can guarantee you it's not insensitive. -> >> Consider VACUUM, or even DROP TABLE. -> -> > It's already possible to keep a lock accross transactions. -> > So it would keep an AccessShareLock across transactions. -> -> AccessShareLock would fend off DROP/ALTER TABLE, but not VACUUM anymore. -> We'd need to invent Yet Another lock type that would prevent VACUUM. -> Clearly that's perfectly doable. -> -> But: having just finished a lot of work to ensure that VACUUM could run -> in parallel with all "normal" database operations, I'm not that thrilled -> at the prospect of introducing a new mechanism that will block VACUUM. -> Especially not one that's *designed* to hold its lock for a long period -> of time. This will just get us right back into all the operational -> problems that lazy VACUUM was intended to get around. For example, this -> one: if transaction A has an insensitive-cursor lock on table T, and a -> VACUUM comes along to vacuum T and blocks waiting for the lock, then -> when subsequent transaction B wants to create an insensitive cursor on T -> it's going to be forced to queue up behind the VACUUM. - -Why do you have to lock the whole table when all you want is just one -set of rows from a set of versions? Am I missing something here? - -When you're talking about in-transaction cursors for the above example, -why would the cursor need anything more than the transaction A needs -anyway? And for cross-transaction cursors, why lock the whole table when -you could use the transaction information from the transaction in which -the cursor was declared? - -Generally spoken, where's the difference between an insensitive -persistent cursor and a still running transaction? - -> While temp tables may seem like an ugly, low-tech way to support -> insensitive cursors, I think they may have more merit than you realize. - -Obviously, that's the easy way to do it, and lots of other databases -make use of that already to implement insensitive cursors (see my other -post). But as the long-term goal should be updateable insensitive -persistent cursors, I think the temp table solution will get really -messy. - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-general-owner+M19851=candle.pha.pa.us=pgman@postgresql.org Fri Jan 25 11:50:42 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0PGoge22600 - for ; Fri, 25 Jan 2002 11:50:42 -0500 (EST) -Received: (qmail 80652 invoked by alias); 25 Jan 2002 16:45:09 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 16:45:09 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0PGOUl75295 - for ; Fri, 25 Jan 2002 11:24:30 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0PGOFf25891; - Fri, 25 Jan 2002 11:24:15 -0500 (EST) -To: Florian Wunderlich -cc: Hiroshi Inoue , Bruce Momjian , - pgsql-general@postgresql.org -Subject: Re: [GENERAL] persistent portals/cursors (between transactions) -In-Reply-To: <3C518231.F65DC636@hq.factor3.com> -References: <200201250319.g0P3Jq022575@candle.pha.pa.us> <23244.1011932544@sss.pgh.pa.us> <3C510D24.8E1FDF7F@tpf.co.jp> <25361.1011971571@sss.pgh.pa.us> <3C518231.F65DC636@hq.factor3.com> -Comments: In-reply-to Florian Wunderlich - message dated "Fri, 25 Jan 2002 17:05:05 +0100" -Date: Fri, 25 Jan 2002 11:24:15 -0500 -Message-ID: <25888.1011975855@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-general-owner@postgresql.org -Status: OR - -Florian Wunderlich writes: -> When you're talking about in-transaction cursors for the above example, -> why would the cursor need anything more than the transaction A needs -> anyway? - -It wouldn't. - -> And for cross-transaction cursors, why lock the whole table when -> you could use the transaction information from the transaction in which -> the cursor was declared? - -The problem is to keep the rows that are supposed to be still visible to -you from disappearing. If other backends think that transaction A is -history, they will not think that they need to preserve rows that would -have been visible to A, but are not visible to any still-running -transaction. - -[ ... thinks for awhile ... ] Maybe we could extend the notion of -"oldest XMIN" a little. Perhaps what each backend should record in the -PROC array is not just the oldest XMIN visible to its current -transaction, but the oldest XMIN visible to either its current xact or -any of its open cross-transaction cursors. That together with an -AccessShareLock on tables referenced by the cursors might work. - -A drawback of this approach is that opening a cursor and sitting on it -for a long time would effectively defeat VACUUM activity --- it wouldn't -be blocked, but it wouldn't be able to reclaim rows either. Anywhere, -not only in the tables actually used by the cursor. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From Inoue@tpf.co.jp Fri Jan 25 11:58:04 2002 -Return-path: -Received: from p2272.nsk.ne.jp ([210.145.18.145]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g0PGw3e24273 - for ; Fri, 25 Jan 2002 11:58:03 -0500 (EST) -Received: from mcadnote1 (ppm139.noc.fukui.nsk.ne.jp [61.198.95.39]) - by p2272.nsk.ne.jp (8.9.3/3.7W-20000722) with SMTP id BAA07477; - Sat, 26 Jan 2002 01:57:47 +0900 (JST) -From: "Hiroshi Inoue" -To: "Tom Lane" -cc: "Bruce Momjian" , - "Florian Wunderlich" , - -Subject: RE: [GENERAL] persistent portals/cursors (between transactions) -Date: Sat, 26 Jan 2002 01:57:54 +0900 -Message-ID: -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-2022-jp" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2910.0) -In-Reply-To: <25361.1011971571@sss.pgh.pa.us> -X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200 -Importance: Normal -Status: OR - -> -----Original Message----- -> From: Tom Lane [mailto:tgl@sss.pgh.pa.us] -> -> Hiroshi Inoue writes: -> > Tom Lane wrote: -> >> If it's not holding any locks, I can guarantee you it's not -> insensitive. -> >> Consider VACUUM, or even DROP TABLE. -> -> > It's already possible to keep a lock accross transactions. -> > So it would keep an AccessShareLock across transactions. -> -> AccessShareLock would fend off DROP/ALTER TABLE, but not VACUUM anymore. - -Really ? VACUUM FULL conflicts with AccessShareLock from the -first. If new vacuum does wrong thing with persistent read-only cursors -it would do the wrong thing with the current cursors as well. -Of cource as Vadim mentioned before, HeapTupleSatisfiesVacuum() -should take the transaction id in which the cursor was opened into -account. - -regards, -Hiroshi Inoue - - - -From pgsql-general-owner+M19852=candle.pha.pa.us=pgman@postgresql.org Fri Jan 25 12:04:58 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0PH4ve25258 - for ; Fri, 25 Jan 2002 12:04:57 -0500 (EST) -Received: (qmail 91567 invoked by alias); 25 Jan 2002 17:04:25 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 17:04:25 -0000 -Received: from post.webmailer.de (natpost.webmailer.de [192.67.198.65]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0PGxNl89850 - for ; Fri, 25 Jan 2002 11:59:23 -0500 (EST) - (envelope-from fwunderlich@devbrain.de) -Received: from faxdial.hq.factor3.com (p3E9ED0CC.dip.t-dialin.net [62.158.208.204]) - by post.webmailer.de (8.9.3/8.8.7) with ESMTP id RAA15976; - Fri, 25 Jan 2002 17:59:27 +0100 (MET) -Received: from hq.factor3.com (florian@main.hq.factor3.com [192.168.1.2]) - by faxdial.hq.factor3.com (8.11.1/8.11.0) with ESMTP id g0PGwC210992; - Fri, 25 Jan 2002 17:58:12 +0100 -Message-ID: <3C518EC9.FDE6DDC3@hq.factor3.com> -Date: Fri, 25 Jan 2002 17:58:49 +0100 -From: Florian Wunderlich -X-Mailer: Mozilla 4.76 [en] (X11; U; Linux 2.4.17 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Tom Lane -cc: Hiroshi Inoue , Bruce Momjian , - pgsql-general@postgresql.org -Subject: Re: [GENERAL] persistent portals/cursors (between transactions) -References: <200201250319.g0P3Jq022575@candle.pha.pa.us> <23244.1011932544@sss.pgh.pa.us> <3C510D24.8E1FDF7F@tpf.co.jp> <25361.1011971571@sss.pgh.pa.us> <3C518231.F65DC636@hq.factor3.com> <25888.1011975855@sss.pgh.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-general-owner@postgresql.org -Status: OR - -> > And for cross-transaction cursors, why lock the whole table when -> > you could use the transaction information from the transaction in which -> > the cursor was declared? -> -> The problem is to keep the rows that are supposed to be still visible to -> you from disappearing. If other backends think that transaction A is -> history, they will not think that they need to preserve rows that would -> have been visible to A, but are not visible to any still-running -> transaction. -> -> [ ... thinks for awhile ... ] Maybe we could extend the notion of -> "oldest XMIN" a little. Perhaps what each backend should record in the -> PROC array is not just the oldest XMIN visible to its current -> transaction, but the oldest XMIN visible to either its current xact or -> any of its open cross-transaction cursors. That together with an -> AccessShareLock on tables referenced by the cursors might work. -> -> A drawback of this approach is that opening a cursor and sitting on it -> for a long time would effectively defeat VACUUM activity --- it wouldn't -> be blocked, but it wouldn't be able to reclaim rows either. Anywhere, -> not only in the tables actually used by the cursor. - -Isn't that exactly what beginning a transaction and keeping it -uncommitted for a long time would do too? - -I see the problem - your last sentence - but getting rid of that would -mean to not only save an oldest XMIN, but also a reference to all tables -that this not-quite-a-xact uses, kind of like a "selective transaction". -I doubt that there really are any problems in the real world though, so -having a naive implementation first would be fine too. - -So from the vacuum perspective, it looks like more than just one -transaction is running per backend, right? Probably I don't understand -anything at all, or that's what I suggested way back in my second or -third mail. Whatever. Assuming I understood a bit here, a read-write -cross-transaction cursor shouldn't be too hard to implement then either. - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-general-owner+M19855=candle.pha.pa.us=pgman@postgresql.org Fri Jan 25 12:21:10 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0PHLAe26624 - for ; Fri, 25 Jan 2002 12:21:10 -0500 (EST) -Received: (qmail 97865 invoked by alias); 25 Jan 2002 17:15:35 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 17:15:35 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0PH6Nl94616 - for ; Fri, 25 Jan 2002 12:06:23 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0PH69f26446; - Fri, 25 Jan 2002 12:06:09 -0500 (EST) -To: "Hiroshi Inoue" -cc: "Bruce Momjian" , - "Florian Wunderlich" , - pgsql-general@postgresql.org -Subject: Re: [GENERAL] persistent portals/cursors (between transactions) -In-Reply-To: -References: -Comments: In-reply-to "Hiroshi Inoue" - message dated "Sat, 26 Jan 2002 01:57:54 +0900" -Date: Fri, 25 Jan 2002 12:06:08 -0500 -Message-ID: <26443.1011978368@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-general-owner@postgresql.org -Status: OR - -"Hiroshi Inoue" writes: ->> AccessShareLock would fend off DROP/ALTER TABLE, but not VACUUM anymore. - -> Really ? VACUUM FULL conflicts with AccessShareLock from the -> first. - -I was speaking of lazy VACUUM, of course. - -> If new vacuum does wrong thing with persistent read-only cursors -> it would do the wrong thing with the current cursors as well. - -No, because current cursors don't span transactions. - -> Of cource as Vadim mentioned before, HeapTupleSatisfiesVacuum() -> should take the transaction id in which the cursor was opened into -> account. - -I haven't read all of that thread yet; maybe Vadim already had the idea -I just had of playing games with oldest-XMIN. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From tgl@sss.pgh.pa.us Fri Jan 25 12:07:42 2002 -Return-path: -Received: from sss.pgh.pa.us (root@[192.204.191.242]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g0PH7fe25517 - for ; Fri, 25 Jan 2002 12:07:41 -0500 (EST) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0PH7Pf26466; - Fri, 25 Jan 2002 12:07:25 -0500 (EST) -To: Florian Wunderlich -cc: Hiroshi Inoue , Bruce Momjian , - pgsql-general@postgresql.org -Subject: Re: [GENERAL] persistent portals/cursors (between transactions) -In-Reply-To: <3C518EC9.FDE6DDC3@hq.factor3.com> -References: <200201250319.g0P3Jq022575@candle.pha.pa.us> <23244.1011932544@sss.pgh.pa.us> <3C510D24.8E1FDF7F@tpf.co.jp> <25361.1011971571@sss.pgh.pa.us> <3C518231.F65DC636@hq.factor3.com> <25888.1011975855@sss.pgh.pa.us> <3C518EC9.FDE6DDC3@hq.factor3.com> -Comments: In-reply-to Florian Wunderlich - message dated "Fri, 25 Jan 2002 17:58:49 +0100" -Date: Fri, 25 Jan 2002 12:07:24 -0500 -Message-ID: <26463.1011978444@sss.pgh.pa.us> -From: Tom Lane -Status: OR - -Florian Wunderlich writes: -> Isn't that exactly what beginning a transaction and keeping it -> uncommitted for a long time would do too? - -Sure, but then you haven't got a cross-transaction cursor, only a plain -cursor. - - regards, tom lane - -From Inoue@tpf.co.jp Fri Jan 25 12:23:39 2002 -Return-path: -Received: from p2272.nsk.ne.jp (p2272.nsk.ne.jp [210.145.18.145]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g0PHNce26772 - for ; Fri, 25 Jan 2002 12:23:38 -0500 (EST) -Received: from mcadnote1 (ppm103.noc.fukui.nsk.ne.jp [61.198.95.3]) - by p2272.nsk.ne.jp (8.9.3/3.7W-20000722) with SMTP id CAA08121; - Sat, 26 Jan 2002 02:23:18 +0900 (JST) -From: "Hiroshi Inoue" -To: "Florian Wunderlich" -cc: "Bruce Momjian" , "Tom Lane" , - , "Jan Wieck" -Subject: RE: [GENERAL] persistent portals/cursors (between transactions) -Date: Sat, 26 Jan 2002 02:23:26 +0900 -Message-ID: -MIME-Version: 1.0 -Content-Type: text/plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2910.0) -In-Reply-To: <3C515739.74CCA819@hq.factor3.com> -X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200 -Importance: Normal -Status: OR - -> -----Original Message----- -> From: florian@hq.factor3.com [mailto:florian@hq.factor3.com]On -> -> -> Hiroshi, that's exactly what I need, though I am not sure if we are all -> really talking about the same thing. -> -> In case I misunderstood something: as far as I know, SQL92 defines that -> a cursor is by default sensitive, which means that it displays the data -> from all comitted transactions at any time. If the data changes, so does -> what the cursor returns. - -AFAIK SQL92's default is indeterminate which guarantees nothing -about sensitivity. Though we don't have insensitive cursors yet -INSENSITIVE cursors are very natural for MVCC and it's not hard -to implement. In reality the current cursors see no changes after -the cursor was opened other than the ones made by the bakend -itself. - -regards, -Hiroshi Inoue - -From pgsql-general-owner+M19860=candle.pha.pa.us=pgman@postgresql.org Fri Jan 25 13:16:18 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0PIGHe03507 - for ; Fri, 25 Jan 2002 13:16:17 -0500 (EST) -Received: (qmail 25543 invoked by alias); 25 Jan 2002 18:14:36 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 18:14:36 -0000 -Received: from post.webmailer.de (natpost.webmailer.de [192.67.198.65]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0PHjpl13108 - for ; Fri, 25 Jan 2002 12:45:51 -0500 (EST) - (envelope-from fwunderlich@devbrain.de) -Received: from faxdial.hq.factor3.com (p3E9ED0CC.dip.t-dialin.net [62.158.208.204]) - by post.webmailer.de (8.9.3/8.8.7) with ESMTP id SAA01771; - Fri, 25 Jan 2002 18:45:55 +0100 (MET) -Received: from hq.factor3.com (florian@main.hq.factor3.com [192.168.1.2]) - by faxdial.hq.factor3.com (8.11.1/8.11.0) with ESMTP id g0PHiO211360; - Fri, 25 Jan 2002 18:44:24 +0100 -Message-ID: <3C51999B.260171D6@hq.factor3.com> -Date: Fri, 25 Jan 2002 18:44:59 +0100 -From: Florian Wunderlich -X-Mailer: Mozilla 4.76 [en] (X11; U; Linux 2.4.17 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Tom Lane -cc: Hiroshi Inoue , Bruce Momjian , - pgsql-general@postgresql.org -Subject: Re: [GENERAL] persistent portals/cursors (between transactions) -References: <200201250319.g0P3Jq022575@candle.pha.pa.us> <23244.1011932544@sss.pgh.pa.us> <3C510D24.8E1FDF7F@tpf.co.jp> <25361.1011971571@sss.pgh.pa.us> <3C518231.F65DC636@hq.factor3.com> <25888.1011975855@sss.pgh.pa.us> <3C518EC9.FDE6DDC3@hq.factor3.com> <26463.1011978444@sss.pgh.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-general-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> > Isn't that exactly what beginning a transaction and keeping it -> > uncommitted for a long time would do too? -> -> Sure, but then you haven't got a cross-transaction cursor, only a plain -> cursor. - -Sorry for being unclear - I wanted to say that this problem obviously -already exists, so there's not a new (conceptual) problem here. - -I'm sure you read the second part of my post where I suggested what a -possible solution could look like. - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - diff --git a/doc/TODO.detail/drop b/doc/TODO.detail/drop deleted file mode 100644 index 43b72df9cd..0000000000 --- a/doc/TODO.detail/drop +++ /dev/null @@ -1,2222 +0,0 @@ -From pgsql-hackers-owner+M3040@hub.org Thu Jun 8 00:31:01 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id AAA13157 - for ; Thu, 8 Jun 2000 00:31:00 -0400 (EDT) -Received: from hub.org (root@hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.6 $) with ESMTP id AAA01089 for ; Thu, 8 Jun 2000 00:17:19 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5846ib99782; - Thu, 8 Jun 2000 00:06:44 -0400 (EDT) -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5846Xb99707 - for ; Thu, 8 Jun 2000 00:06:33 -0400 (EDT) -Received: from cadzone ([126.0.1.40] (may be forged)) - by sd.tpf.co.jp (2.5 Build 2640 (Berkeley 8.8.6)/8.8.4) with SMTP - id NAA01145; Thu, 08 Jun 2000 13:05:42 +0900 -From: "Hiroshi Inoue" -To: "Bruce Momjian" -Cc: "PostgreSQL-development" -Subject: RE: [HACKERS] DROP COLUMN status -Date: Thu, 8 Jun 2000 13:07:44 +0900 -Message-ID: <000d01bfd0ff$194d56c0$2801007e@tpf.co.jp> -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 -In-Reply-To: <200006080309.XAA10305@candle.pha.pa.us> -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 -Importance: Normal -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: OR - -> -----Original Message----- -> From: pgsql-hackers-owner@hub.org [mailto:pgsql-hackers-owner@hub.org]On -> Behalf Of Bruce Momjian -> -> Can someone comment on where we are with DROP COLUMN? -> - -I've already committed my trial implementation 3 months ago. -They are $ifdef'd by _DROP_COLUMN_HACK__. -Please enable the feature and evaluate it. -You could enable the feature without initdb. - -Regards. - -Hiroshi Inoue -Inoue@tpf.co.jp - - -From Inoue@tpf.co.jp Thu Jun 8 02:03:27 2000 -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id CAA14243 - for ; Thu, 8 Jun 2000 02:03:25 -0400 (EDT) -Received: from cadzone ([126.0.1.40] (may be forged)) - by sd.tpf.co.jp (2.5 Build 2640 (Berkeley 8.8.6)/8.8.4) with SMTP - id PAA01221; Thu, 08 Jun 2000 15:03:23 +0900 -From: "Hiroshi Inoue" -To: "Bruce Momjian" -Cc: "PostgreSQL-development" -Subject: RE: [HACKERS] DROP COLUMN status -Date: Thu, 8 Jun 2000 15:05:24 +0900 -Message-ID: <000f01bfd10f$893798a0$2801007e@tpf.co.jp> -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 -In-Reply-To: <200006080457.AAA13430@candle.pha.pa.us> -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 -Importance: Normal -Status: OR - -> -----Original Message----- -> From: Bruce Momjian [mailto:pgman@candle.pha.pa.us] -> Sent: Thursday, June 08, 2000 1:58 PM -> -> [ Charset ISO-8859-1 unsupported, converting... ] -> > > -----Original Message----- -> > > From: pgsql-hackers-owner@hub.org -> [mailto:pgsql-hackers-owner@hub.org]On -> > > Behalf Of Bruce Momjian -> > > -> > > Can someone comment on where we are with DROP COLUMN? -> > > -> > -> > I've already committed my trial implementation 3 months ago. -> > They are $ifdef'd by _DROP_COLUMN_HACK__. -> > Please enable the feature and evaluate it. -> > You could enable the feature without initdb. -> -> OK, can you explain how it works, and add any needed documentation so we -> can enable it. -> - -First it's only a trial so I don't implement it completely. -Especially I don't completely drop related objects -(FK_constraint,triggers,views etc). I don't know whether -we could drop them properly or not. - -The implementation makes the dropped column invisible by -changing its attnum to -attnum - offset(currently 20) and -attnam to ("*already Dropped%d",attnum). It doesn't touch -the table at all. After dropping a column insert/update -operation regards the column as NULL and other related -stuff simply ignores the column. - -Regards. - -Hiroshi Inoue -Inoue@tpf.co.jp - -From tgl@sss.pgh.pa.us Thu Jun 8 10:20:34 2000 -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id KAA29148 - for ; Thu, 8 Jun 2000 10:20:33 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id KAA15725; - Thu, 8 Jun 2000 10:20:11 -0400 (EDT) -To: "Hiroshi Inoue" -cc: "Bruce Momjian" , - "PostgreSQL-development" -Subject: Re: [HACKERS] DROP COLUMN status -In-reply-to: <000f01bfd10f$893798a0$2801007e@tpf.co.jp> -References: <000f01bfd10f$893798a0$2801007e@tpf.co.jp> -Comments: In-reply-to "Hiroshi Inoue" - message dated "Thu, 08 Jun 2000 15:05:24 +0900" -Date: Thu, 08 Jun 2000 10:20:11 -0400 -Message-ID: <15722.960474011@sss.pgh.pa.us> -From: Tom Lane -Status: ORr - -"Hiroshi Inoue" writes: -> The implementation makes the dropped column invisible by -> changing its attnum to -attnum - offset(currently 20) and -> attnam to ("*already Dropped%d",attnum). - -Ugh. No wonder you had to hack so many places in such an ugly fashion. -Why not leave the attnum as-is, and just add a bool saying "column is -dropped" to pg_attribute? As long as the parser ignores columns marked -that way for field lookup and expansion of *, it seems the rest of the -system wouldn't need to treat dropped columns specially in any way. - - regards, tom lane - -From pgsql-hackers-owner+M3094@hub.org Thu Jun 8 15:58:30 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id PAA25109 - for ; Thu, 8 Jun 2000 15:58:28 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e58JrqT91713; - Thu, 8 Jun 2000 15:53:52 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.10.1/8.10.1) with ESMTP id e58JqpT91436 - for ; Thu, 8 Jun 2000 15:52:51 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id PAA19690; - Thu, 8 Jun 2000 15:52:43 -0400 (EDT) -To: Bruce Momjian -cc: Hiroshi Inoue , - PostgreSQL-development -Subject: Re: [HACKERS] DROP COLUMN status -In-reply-to: <200006081541.LAA01566@candle.pha.pa.us> -References: <200006081541.LAA01566@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Thu, 08 Jun 2000 11:41:43 -0400" -Date: Thu, 08 Jun 2000 15:52:43 -0400 -Message-ID: <19687.960493963@sss.pgh.pa.us> -From: Tom Lane -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: OR - ->>>> The implementation makes the dropped column invisible by ->>>> changing its attnum to -attnum - offset(currently 20) and ->>>> attnam to ("*already Dropped%d",attnum). ->> ->> Ugh. No wonder you had to hack so many places in such an ugly fashion. ->> Why not leave the attnum as-is, and just add a bool saying "column is ->> dropped" to pg_attribute? As long as the parser ignores columns marked ->> that way for field lookup and expansion of *, it seems the rest of the ->> system wouldn't need to treat dropped columns specially in any way. - -> If we leave it as positive, don't we have to change user applications -> that query pg_attribute so they also know to skip it? - -Good point, but I think user applications that query pg_attribute -are likely to have trouble anyway: if they're expecting a consecutive -series of attnums then they're going to lose no matter what. - - regards, tom lane - -From hannu@tm.ee Sat Jun 10 01:02:57 2000 -Received: from me.tm.ee (ppp15.tele2.ee [212.107.33.15]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id BAA10377 - for ; Sat, 10 Jun 2000 01:02:55 -0400 (EDT) -Received: from tm.ee (IDENT:hannu@localhost.localdomain [127.0.0.1]) - by me.tm.ee (8.9.3/8.9.3) with ESMTP id GAA00940; - Sat, 10 Jun 2000 06:59:33 +0300 -Sender: hannu@me.tm.ee -Message-ID: <3941BD25.96760D2E@tm.ee> -Date: Sat, 10 Jun 2000 06:59:33 +0300 -From: Hannu Krosing -X-Mailer: Mozilla 4.72 [en] (X11; U; Linux 2.2.12-20 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Bruce Momjian -CC: Tom Lane , Peter Eisentraut , - PostgreSQL Development -Subject: Re: [HACKERS] ALTER TABLE DROP COLUMN -References: <200006091249.IAA18730@candle.pha.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Status: OR - -Bruce Momjian wrote: -> -> Seems we have 4 DROP COLUMN ideas: -> -> Method Advantage -> ----------------------------------------------------------------- -> 1 invisible column marked by negative attnum fast -> 2 invisible column marked by is_dropped column fast -> 3 make copy of table without column col removed -> 4 make new tuples in existing table without column col removed - -IIRC there was a fifth idea, a variation of 2 that would work better -with -inheritance - - -5 all columns have is_real_column attribute that is true for all -coluns -present in that relation, so situations like - -create table tab_a(a_i int); -create table tab_b(b_i int) inherits(tab_a); -alter table tab_a add column c_i int; - -can be made to work. - -It would also require clients to ignore all missing columns that backend -can -pass to them as nulls (which is usually quite cheap in bandwith usage) -in -case of "SELECT **" queries. - -We could even rename attno to attid to make folks aware that it is not -be -assumed to be continuous. - -> Folks, we had better choose one and get started. -> -> Number 1 Hiroshi has ifdef'ed out in the code. Items 1 and 2 have -> problems with backend code and 3rd party code not seeing the dropped -> columns, or having gaps in the attno numbering. - -If we want to make ADD COLUMN to work with inheritance wihout having to -rewrite every single tuple in both parent and inherited tables, we will -have to accept the fact that there are caps in in attno numbering. - -> Number 3 has problems -> with making it an atomic operation, and number 4 is described below. - -Nr 4 has still problems with attno numbering _changing_ during drop -which -could either be better or worse for client software than having gaps - -in both cases client must be prepared to deal with runtime changes in -attribute definition. - --------------- -Hannu - -From Inoue@tpf.co.jp Sat Jun 10 01:01:01 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id BAA10355 - for ; Sat, 10 Jun 2000 01:01:00 -0400 (EDT) -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) by renoir.op.net (o1/$Revision: 1.6 $) with ESMTP id AAA25467 for ; Sat, 10 Jun 2000 00:41:32 -0400 (EDT) -Received: from mcadnote1 (ppm110.noc.fukui.nsk.ne.jp [210.161.188.29] (may be forged)) - by sd.tpf.co.jp (2.5 Build 2640 (Berkeley 8.8.6)/8.8.4) with SMTP - id NAA03125; Sat, 10 Jun 2000 13:40:40 +0900 -From: "Hiroshi Inoue" -To: "Bruce Momjian" , "Tom Lane" -Cc: "Peter Eisentraut" , - "PostgreSQL Development" -Subject: RE: [HACKERS] ALTER TABLE DROP COLUMN -Date: Sat, 10 Jun 2000 13:43:26 +0900 -Message-ID: -MIME-Version: 1.0 -Content-Type: text/plain; - charset="US-ASCII" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2910.0) -In-Reply-To: <200006091249.IAA18730@candle.pha.pa.us> -Importance: Normal -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2919.6700 -Status: ORr - -> -----Original Message----- -> From: pgsql-hackers-owner@hub.org -> [mailto:pgsql-hackers-owner@hub.org]On Behalf Of Bruce Momjian -> -> Seems we have 4 DROP COLUMN ideas: -> -> Method Advantage -> ----------------------------------------------------------------- -> 1 invisible column marked by negative attnum fast -> 2 invisible column marked by is_dropped column fast -> 3 make copy of table without column col removed -> 4 make new tuples in existing table without column col removed -> -> Folks, we had better choose one and get started. -> -> Number 1 Hiroshi has ifdef'ed out in the code. Items 1 and 2 have -> problems with backend code and 3rd party code not seeing the dropped -> columns, - -Hmm,doesn't *not seeing* mean the column is dropped ? - -> or having gaps in the attno numbering. Number 3 has problems -> with making it an atomic operation, and number 4 is described below. -> - -Don't forget another important point. - -Currently even DROP TABLE doesn't remove related objects completely. -And I don't think I could remove objects related to the dropping column -completely using 1)2) in ALTER TABLE DROP COLUMN implementation. - -Using 3)4) we should not only remove objects as 1)2) but also -change attnum-s in all objects related to the relation. Otherwise -PostgreSQL would do the wrong thing silently. - -Regards. - -Hiroshi Inoue -Inoue@tpf.co.jp - -From dhogaza@pacifier.com Sat Jun 10 01:01:06 2000 -Received: from smtp.pacifier.com (comet.pacifier.com [199.2.117.155]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id BAA10370 - for ; Sat, 10 Jun 2000 01:01:04 -0400 (EDT) -Received: from desktop (dsl-dhogaza.pacifier.net [207.202.226.68]) - by smtp.pacifier.com (8.9.3/8.9.3pop) with SMTP id WAA08521; - Fri, 9 Jun 2000 22:01:00 -0700 (PDT) -Message-Id: <3.0.1.32.20000609215758.0116d850@mail.pacifier.com> -X-Sender: dhogaza@mail.pacifier.com -X-Mailer: Windows Eudora Pro Version 3.0.1 (32) -Date: Fri, 09 Jun 2000 21:57:58 -0700 -To: "Hiroshi Inoue" , - "Bruce Momjian" , - "Tom Lane" -From: Don Baccus -Subject: RE: [HACKERS] ALTER TABLE DROP COLUMN -Cc: "Peter Eisentraut" , - "PostgreSQL Development" -In-Reply-To: -References: <200006091249.IAA18730@candle.pha.pa.us> -Mime-Version: 1.0 -Content-Type: text/plain; charset="us-ascii" -Status: OR - -At 01:43 PM 6/10/00 +0900, Hiroshi Inoue wrote: ->> -----Original Message----- ->> From: pgsql-hackers-owner@hub.org ->> [mailto:pgsql-hackers-owner@hub.org]On Behalf Of Bruce Momjian ->> ->> Seems we have 4 DROP COLUMN ideas: ->> ->> Method Advantage ->> ----------------------------------------------------------------- ->> 1 invisible column marked by negative attnum fast ->> 2 invisible column marked by is_dropped column fast ->> 3 make copy of table without column col removed ->> 4 make new tuples in existing table without column col removed ->> ->> Folks, we had better choose one and get started. - -Oracle gives you the choice between the "cheating" fast method(s) and -the "real" slow (really slow?) real method. - -So there's at least real world experience by virtue of example by -the world's most successful database supplier that user control -over "hide the column" and "really delete the column" is valuable. - -It really makes a lot of sense to give such a choice. If one -does so by "hiding", at a later date one would think the choice -of "really deleting" would be a possibility. I don't know if -Oracle does this... - -If not, they might not care. In today's world, there are bazillions -of dollars for Oracle to scoop up from users who could just as easily -be PG users - all those "we'll fail if don't IPO 'cause we'll never -have any customers" database-backed websites :) - - - -- Don Baccus, Portland OR - Nature photos, on-line guides, Pacific Northwest - Rare Bird Alert Service and other goodies at - http://donb.photo.net. - -From tgl@sss.pgh.pa.us Sat Jun 10 01:31:04 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id BAA10922 - for ; Sat, 10 Jun 2000 01:31:03 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) by renoir.op.net (o1/$Revision: 1.6 $) with ESMTP id BAA27265 for ; Sat, 10 Jun 2000 01:16:07 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id BAA06206; - Sat, 10 Jun 2000 01:14:37 -0400 (EDT) -To: Don Baccus -cc: "Hiroshi Inoue" , - "Bruce Momjian" , - "Peter Eisentraut" , - "PostgreSQL Development" -Subject: Re: [HACKERS] ALTER TABLE DROP COLUMN -In-reply-to: <3.0.1.32.20000609215758.0116d850@mail.pacifier.com> -References: <200006091249.IAA18730@candle.pha.pa.us> <3.0.1.32.20000609215758.0116d850@mail.pacifier.com> -Comments: In-reply-to Don Baccus - message dated "Fri, 09 Jun 2000 21:57:58 -0700" -Date: Sat, 10 Jun 2000 01:14:37 -0400 -Message-ID: <6203.960614077@sss.pgh.pa.us> -From: Tom Lane -Status: OR - -Don Baccus writes: -> Oracle gives you the choice between the "cheating" fast method(s) and -> the "real" slow (really slow?) real method. - -> So there's at least real world experience by virtue of example by -> the world's most successful database supplier that user control -> over "hide the column" and "really delete the column" is valuable. - -Sure, but you don't need any help from the database to do "really delete -the column". SELECT INTO... is enough, and it's not even any slower -than the implementations under discussion. - -So I'm satisfied if we offer the "hide the column" approach. - -Has anyone thought about what happens to table constraints that use the -doomed column? Triggers, RI rules, yadda yadda? - -Has anyone thought about undoing a DELETE COLUMN? The data is still -there, at least in tuples that have not been updated, so it's not -totally unreasonable. - - regards, tom lane - -From dhogaza@pacifier.com Sat Jun 10 09:30:59 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id JAA25987 - for ; Sat, 10 Jun 2000 09:30:58 -0400 (EDT) -Received: from smtp.pacifier.com (comet.pacifier.com [199.2.117.155]) by renoir.op.net (o1/$Revision: 1.6 $) with ESMTP id JAA18716 for ; Sat, 10 Jun 2000 09:15:08 -0400 (EDT) -Received: from desktop (dsl-dhogaza.pacifier.net [207.202.226.68]) - by smtp.pacifier.com (8.9.3/8.9.3pop) with SMTP id GAA15799; - Sat, 10 Jun 2000 06:14:28 -0700 (PDT) -Message-Id: <3.0.1.32.20000610054306.0115f020@mail.pacifier.com> -X-Sender: dhogaza@mail.pacifier.com -X-Mailer: Windows Eudora Pro Version 3.0.1 (32) -Date: Sat, 10 Jun 2000 05:43:06 -0700 -To: Tom Lane -From: Don Baccus -Subject: Re: [HACKERS] ALTER TABLE DROP COLUMN -Cc: "Hiroshi Inoue" , - "Bruce Momjian" , - "Peter Eisentraut" , - "PostgreSQL Development" -In-Reply-To: <6203.960614077@sss.pgh.pa.us> -References: <3.0.1.32.20000609215758.0116d850@mail.pacifier.com> - <200006091249.IAA18730@candle.pha.pa.us> - <3.0.1.32.20000609215758.0116d850@mail.pacifier.com> -Mime-Version: 1.0 -Content-Type: text/plain; charset="us-ascii" -Status: OR - -At 01:14 AM 6/10/00 -0400, Tom Lane wrote: ->Don Baccus writes: ->> Oracle gives you the choice between the "cheating" fast method(s) and ->> the "real" slow (really slow?) real method. -> ->> So there's at least real world experience by virtue of example by ->> the world's most successful database supplier that user control ->> over "hide the column" and "really delete the column" is valuable. -> ->Sure, but you don't need any help from the database to do "really delete ->the column". SELECT INTO... is enough, and it's not even any slower ->than the implementations under discussion. -> ->So I'm satisfied if we offer the "hide the column" approach. - - I wouldn't put a "real" drop column at the top of my list -of priorities, but there is something to be said for user convenience. - - - -- Don Baccus, Portland OR - Nature photos, on-line guides, Pacific Northwest - Rare Bird Alert Service and other goodies at - http://donb.photo.net. - -From tgl@sss.pgh.pa.us Sun Jun 11 12:31:03 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id MAA05771 - for ; Sun, 11 Jun 2000 12:31:01 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) by renoir.op.net (o1/$Revision: 1.6 $) with ESMTP id MAA19315 for ; Sun, 11 Jun 2000 12:24:06 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id MAA09503; - Sun, 11 Jun 2000 12:22:42 -0400 (EDT) -To: "Hiroshi Inoue" -cc: "Bruce Momjian" , - "Peter Eisentraut" , - "PostgreSQL Development" -Subject: Re: [HACKERS] ALTER TABLE DROP COLUMN -In-reply-to: -References: -Comments: In-reply-to "Hiroshi Inoue" - message dated "Sat, 10 Jun 2000 13:43:26 +0900" -Date: Sun, 11 Jun 2000 12:22:42 -0400 -Message-ID: <9500.960740562@sss.pgh.pa.us> -From: Tom Lane -Status: ORr - ->> Seems we have 4 DROP COLUMN ideas: ->> Method Advantage ->> ----------------------------------------------------------------- ->> 1 invisible column marked by negative attnum fast ->> 2 invisible column marked by is_dropped column fast ->> 3 make copy of table without column col removed ->> 4 make new tuples in existing table without column col removed - -Bruce and I talked about this by phone yesterday, and we realized that -none of these are very satisfactory. #1 and #2 both have the flaw that -applications that examine pg_attribute will probably break: they will -see a sequence of attnum values with gaps in it. And what should the -rel's relnatts field be set to? #3 and #4 are better on that point, -but they leave us with the problem of renumbering references to columns -after the dropped one in constraints, rules, PL functions, etc. - -Furthermore, there is a closely related problem that none of these -approaches give us much help on: recursive ALTER TABLE ADD COLUMN. -Right now, ADD puts the new column at the end of each table it's added -to, which often means that it gets a different column number in child -tables than in parent tables. That leads to havoc for pg_dump. - -I think the only clean solution is to create a clear distinction between -physical and logical column numbers. Each pg_attribute tuple would need -two attnum fields, and pg_class would need two relnatts fields as well. -A column once created would never change its physical column number, but -its logical column number might change as a consequence of adding or -dropping columns before it. ADD COLUMN would ensure that a column added -to child tables receives the same logical column number as it has in the -parent table, thus solving the dump/reload problem. DROP COLUMN would -assign an invalid logical column number to dropped columns. They could -be numbered zero except that we'd probably still want a unique index on -attrelid+attnum, and the index would complain. I'd suggest using -Hiroshi's idea: give a dropped column a logical attnum equal to --(physical_attnum + offset). - -With this approach, internal operations on tuples would all use -physical column numbers, but operations that interface to the outside -world would present a view of only the valid logical columns. For -example, the parser would only allow logical columns to be referenced -by name; "SELECT *" would expand to valid logical columns in logical- -column-number order; COPY would send or receive valid logical columns -in logical-column-number order; etc. - -Stored rules and so forth probably should store physical column numbers -so that they need not be modified during column add/drop. - -This would require looking at all the places in the backend to determine -whether they should be working with logical or physical column numbers, -but the design is such that most all places would want to be using -physical numbers, so I don't think it'd be too painful. - -Although I'd prefer to give the replacement columns two new names -(eg, "attlnum" and "attpnum") to ensure we find all uses, this would -surely break applications that examine pg_attribute. For compatibility -we'd have to recycle "attnum" and "relnatts" to indicate logical column -number and logical column count, while adding new fields (say "attpnum" -and "relnpatts") for the physical number and count. - -Comments? - - regards, tom lane - -From pgsql-hackers-owner+M3184@hub.org Mon Jun 12 09:29:17 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id JAA16538 - for ; Mon, 12 Jun 2000 09:29:15 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5C9RxT92685; - Mon, 12 Jun 2000 05:27:59 -0400 (EDT) -Received: from clio.trends.ca (root@clio.trends.ca [209.47.148.2]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5C8YWT89945 - for ; Mon, 12 Jun 2000 04:34:32 -0400 (EDT) -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by clio.trends.ca (8.9.3+Sun/8.9.3) with ESMTP id VAA17711 - for ; Sun, 11 Jun 2000 21:40:28 -0400 (EDT) -Received: from cadzone ([126.0.1.40] (may be forged)) - by sd.tpf.co.jp (2.5 Build 2640 (Berkeley 8.8.6)/8.8.4) with SMTP - id KAA03734; Mon, 12 Jun 2000 10:38:42 +0900 -From: "Hiroshi Inoue" -To: "Tom Lane" -Cc: "Bruce Momjian" , - "Peter Eisentraut" , - "PostgreSQL Development" -Subject: RE: [HACKERS] ALTER TABLE DROP COLUMN -Date: Mon, 12 Jun 2000 10:40:47 +0900 -Message-ID: <000b01bfd40f$3b3091e0$2801007e@tpf.co.jp> -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-2022-jp" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 -In-Reply-To: <9500.960740562@sss.pgh.pa.us> -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 -Importance: Normal -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: OR - -> -----Original Message----- -> From: Tom Lane [mailto:tgl@sss.pgh.pa.us] -> -> >> Seems we have 4 DROP COLUMN ideas: -> >> Method Advantage -> >> ----------------------------------------------------------------- -> >> 1 invisible column marked by negative attnum fast -> >> 2 invisible column marked by is_dropped column fast -> >> 3 make copy of table without column col removed -> >> 4 make new tuples in existing table without column col removed -> - -Hmm,I've received no pg-ML mails for more than 1 day. -What's happened with pgsql ML ? - -> Bruce and I talked about this by phone yesterday, and we realized that -> none of these are very satisfactory. #1 and #2 both have the flaw that -> applications that examine pg_attribute will probably break: they will -> see a sequence of attnum values with gaps in it. And what should the -> rel's relnatts field be set to? #3 and #4 are better on that point, -> but they leave us with the problem of renumbering references to columns -> after the dropped one in constraints, rules, PL functions, etc. -> -> Furthermore, there is a closely related problem that none of these -> approaches give us much help on: recursive ALTER TABLE ADD COLUMN. -> Right now, ADD puts the new column at the end of each table it's added -> to, which often means that it gets a different column number in child -> tables than in parent tables. That leads to havoc for pg_dump. -> - -Inheritance is one of the reason why I didn't take #2. I don't understand -marking is_dropped is needed or not when pg_attribute is overhauled -for inheritance. -I myself have never wanted to use current inheritance functionality -mainly because of this big flaw. Judging from the recent discussion -about oo(though I don't understand details),the change seems to be -needed in order to make inheritance functionality really useful. - -> I think the only clean solution is to create a clear distinction between -> physical and logical column numbers. Each pg_attribute tuple would need -> two attnum fields, and pg_class would need two relnatts fields as well. -> A column once created would never change its physical column number, but - -I don't understand inheritance well. In the near future wouldn't the -implementation require e.g. attid which is common to all children -of a parent and is never changed ? If so,we would need the third -attid field which is irrevalent to physical/logical position. If not, -physical column number would be sufficient . - -> its logical column number might change as a consequence of adding or -> dropping columns before it. ADD COLUMN would ensure that a column added -> to child tables receives the same logical column number as it has in the -> parent table, thus solving the dump/reload problem. DROP COLUMN would -> assign an invalid logical column number to dropped columns. They could -> be numbered zero except that we'd probably still want a unique index on -> attrelid+attnum, and the index would complain. I'd suggest using -> Hiroshi's idea: give a dropped column a logical attnum equal to -> -(physical_attnum + offset). -> -> With this approach, internal operations on tuples would all use -> physical column numbers, but operations that interface to the outside -> world would present a view of only the valid logical columns. For -> example, the parser would only allow logical columns to be referenced -> by name; "SELECT *" would expand to valid logical columns in logical- -> column-number order; COPY would send or receive valid logical columns -> in logical-column-number order; etc. -> -> Stored rules and so forth probably should store physical column numbers -> so that they need not be modified during column add/drop. -> -> This would require looking at all the places in the backend to determine -> whether they should be working with logical or physical column numbers, -> but the design is such that most all places would want to be using -> physical numbers, so I don't think it'd be too painful. -> -> Although I'd prefer to give the replacement columns two new names -> (eg, "attlnum" and "attpnum") to ensure we find all uses, this would -> surely break applications that examine pg_attribute. For compatibility -> we'd have to recycle "attnum" and "relnatts" to indicate logical column -> number and logical column count, while adding new fields (say "attpnum" -> and "relnpatts") for the physical number and count. -> - -I agree with you that we would add attpnum and change the meaing of -attnum as logical column number for backward compatibility. - -Regards. - -Hiroshi Inoue -Inoue@tpf.co.jp - -From pgsql-hackers-owner+M3050@postgresql.org Thu Jan 11 21:49:43 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id VAA20277 - for ; Thu, 11 Jan 2001 21:49:42 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f0C2lhp74989; - Thu, 11 Jan 2001 21:47:43 -0500 (EST) - (envelope-from pgsql-hackers-owner+M3050@postgresql.org) -Received: from dynworks.com (adsl-63-206-168-198.dsl.sktn01.pacbell.net [63.206.168.198]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id f0C2lNp74855 - for ; Thu, 11 Jan 2001 21:47:23 -0500 (EST) - (envelope-from jdavis@dynworks.com) -Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) - by dynworks.com (Postfix) with ESMTP id CC44F31FAB - for ; Thu, 11 Jan 2001 18:48:36 -0800 (PST) -Date: Thu, 11 Jan 2001 18:48:36 PST -From: Jeff Davis -To: pgsql-hackers@postgresql.org -Subject: [HACKERS] alter table drop column -Reply-To: jdavis@dynworks.com -X-Mailer: Spruce 0.6.5 for X11 w/smtpio 0.7.9 -MIME-Version: 1.0 -Content-Type: text/plain; charset="iso-8859-1" -Content-Transfer-Encoding: 8bit -Message-Id: <20010112024836.CC44F31FAB@dynworks.com> -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -I read the transcript of the alter table drop column discussion (old -discussion) at http://www.postgresql.org/docs/pgsql/doc/TODO.detail/drop, -and I have something to add: - -People mentioned such ideas as a hidden column and a really deleted column, -and it occurred to me that perhaps "vacuum" would be a good option to use. -When a delete was issued, the column would be hidden (by a negative/invalid -logical column number, it appears was the consensus). Upon issuing a -vacuum, it could perform a complete deletion. This method would allow users -to know that the process may take a while (I think the agreed method for a -complete delete was to "select into..." the right columns and leave out the -deleted ones, then delete the old table). - -Furthermore, I liked the idea of some kind of "undelete", as long as it was -just hidden. This could apply to anything that is cleaned out with a vacuum -(before it is cleaned out), although I am not sure how feasible this is, -and it isn't particularly important to me. - -Regards, - Jeff - --- -Jeff Davis -Dynamic Works -jdavis@dynworks.com -http://dynworks.com - - -From owner-pgsql-hackers@hub.org Sat Feb 26 01:07:45 2000 -Received: from hub.org (hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id BAA17776 - for ; Sat, 26 Feb 2000 01:07:43 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id BAA06232; - Sat, 26 Feb 2000 01:03:53 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Sat, 26 Feb 2000 01:03:26 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id BAA05808 - for pgsql-hackers-outgoing; Sat, 26 Feb 2000 01:02:28 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.9.3/8.9.3) with ESMTP id BAA05426 - for ; Sat, 26 Feb 2000 01:01:46 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id BAA14228; - Sat, 26 Feb 2000 01:01:34 -0500 (EST) -To: Bruce Momjian -cc: Peter Eisentraut , - PostgreSQL Development -Subject: Re: [HACKERS] ALTER TABLE DROP COLUMN -In-reply-to: <200002260412.XAA14752@candle.pha.pa.us> -References: <200002260412.XAA14752@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Fri, 25 Feb 2000 23:12:26 -0500" -Date: Sat, 26 Feb 2000 01:01:33 -0500 -Message-ID: <14225.951544893@sss.pgh.pa.us> -From: Tom Lane -Sender: owner-pgsql-hackers@postgreSQL.org -Status: ORr - -Bruce Momjian writes: -> You can exclusively lock the table, then do a heap_getnext() scan over -> the entire table, remove the dropped column, do a heap_insert(), then a -> heap_delete() on the current tuple, making sure to skip over the tuples -> inserted by the current transaction. When completed, remove the column -> from pg_attribute, mark the transaction as committed (if desired), and -> run vacuum over the table to remove the deleted rows. - -Hmm, that would work --- the new tuples commit at the same instant that -the schema updates commit, so it should be correct. You have the 2x -disk usage problem, but there's no way around that without losing -rollback ability. - -A potentially tricky bit will be persuading the tuple-reading and tuple- -writing subroutines to pay attention to different versions of the tuple -structure for the same table. I haven't looked to see if this will be -difficult or not. If you can pass the TupleDesc explicitly then it -shouldn't be a problem. - -I'd suggest that the cleanup vacuum *not* be an automatic part of -the operation; just recommend that people do it ASAP after dropping -a column. Consider needing to drop several columns... - - regards, tom lane - -************ - -From pgsql-hackers-owner+M18768=candle.pha.pa.us=pgman@postgresql.org Wed Feb 13 03:52:00 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g1D8pxP21056 - for ; Wed, 13 Feb 2002 03:52:00 -0500 (EST) -Received: (qmail 97959 invoked by alias); 13 Feb 2002 08:51:46 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 13 Feb 2002 08:51:46 -0000 -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g1D8mRE97432 - for ; Wed, 13 Feb 2002 03:48:28 -0500 (EST) - (envelope-from Inoue@tpf.co.jp) -Received: (qmail 26891 invoked from network); 13 Feb 2002 08:48:27 -0000 -Received: from unknown (HELO viscomail.tpf.co.jp) (100.0.0.108) - by sd2.tpf-fw-c.co.jp with SMTP; 13 Feb 2002 08:48:27 -0000 -Received: from tpf.co.jp (3dgateway1 [126.0.1.60]) - by viscomail.tpf.co.jp (8.8.8+Sun/8.8.8) with ESMTP id RAA01019; - Wed, 13 Feb 2002 17:48:20 +0900 (JST) -Message-ID: <3C6A2861.6E71A124@tpf.co.jp> -Date: Wed, 13 Feb 2002 17:48:33 +0900 -From: Hiroshi Inoue -X-Mailer: Mozilla 4.73 [ja] (Windows NT 5.0; U) -X-Accept-Language: ja -MIME-Version: 1.0 -To: Christopher Kings-Lynne -cc: Tom Lane , - Kovacs Zoltan , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] alter table drop column status -References: -Content-Type: text/plain; charset=iso-2022-jp -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Christopher Kings-Lynne wrote: -> -> > No there was an unapplied hack which uses logical/physical -> > attribute numbers. I have synchronized it with cvs for a -> > year or so but stop it now. Though it had some flaws It -> > solved the following TODOs. -> > -> > * Add ALTER TABLE DROP COLUMN feature -> > * ALTER TABLE ADD COLUMN to inherited table put column in wrong place -> > * Prevent column dropping if column is used by foreign key -> -> This seems fantastic - why can't this be committed? Surely if it's -> committed then the flaws will fairly quickly be ironed out? Even if it has -> flaws, then if we say 'this function is not yet stable' at least people can -> start testing it and reporting the problems? -> -> > I gave up to apply the hack mainly because it may introduce -> > the maintenance headache. -> -> Is it a maintenance headache just for you to keep it up to date, or how -> would it be a maintenance headache if it were committed? - -Probably(oops I don't remember well now sorry) the main -reason why I didn't insist to apply the patch was that -it wasn't so clean as I had expected. -My trial implementation uses logical(for clients) and -physical (for backend internal) attribute numbers but -there were many places where I wasn't able to judge which -to use immediately. I'm pretty suspicious if a developer -could be careful about the choise when he is implementing -an irrevant feature. (Un)fortunately the numbers have -the same values mostly and he could hardly notice the -mistake even if he chose the wrong attribute numbers. -I'm not sure if I myself chose the right attribute numbers -everywhere in my implementation. -In addtion (probably) there were some pretty essential -flaws. I intended to manage the backend internal -object references without the logical attribute -numbers but I found it difficult in some cases -(probably the handling of virtual(not existent -in any real table) tuples). - -Sorry it was more than 1 year ago when I implemented -it and I can't remember well what I'd thougth then. -Though I'd kept my local branch up to date for -about a year, it's about half a year since I touched -the stuff last. - -regards, -Hiroshi Inoue - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From chriskl@familyhealth.com.au Thu Apr 11 12:00:22 2002 -Return-path: -Received: from houston.familyhealth.com.au (root@i231-006.nv.iinet.net.au [203.59.231.6]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3BG0KS02910 - for ; Thu, 11 Apr 2002 12:00:20 -0400 (EDT) -Received: from localhost (chriskl@localhost) - by houston.familyhealth.com.au (8.11.6/8.11.6) with ESMTP id g3BG0GJ70765; - Fri, 12 Apr 2002 00:00:16 +0800 (WST) - (envelope-from chriskl@familyhealth.com.au) -Date: Fri, 12 Apr 2002 00:00:16 +0800 (WST) -From: Christopher Kings-Lynne -To: Bruce Momjian -cc: Hiroshi Inoue , Tom Lane , - -Subject: Re: [HACKERS] RFC: Restructuring pg_aggregate -In-Reply-To: <200204110419.g3B4J8v29682@candle.pha.pa.us> -Message-ID: <20020411233659.O69846-100000@houston.familyhealth.com.au> -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Status: OR - -> Actually, what we need to do to reclaim space is to enable table -> recreation without the column, now that we have relfilenode for file -> renaming. It isn't hard to do, but no one has focused on it. I want to -> focus on it, but have not had the time, obviously, and would be very -> excited to assist someone else. -> -> Hiroshi's fine idea of marking certain columns as unused would not have -> reclaimed the missing space, just as my idea of physical/logical column -> distinction would not reclaim the space either. Again, my -> physical/logical idea is more for fixing other problems and -> optimization, not DROP COLUMN. - -Hmmm. Personally, I think that a DROP COLUMN that cannot reclaim space is -kinda useless - you may as well just use a view!!! - -So how would this occur?: - -1. Lock target table for writing (allow reads) -2. Begin a table scan on target table, writing - a new file with a particular filenode -3. Delete the attribute row from pg_attribute -4. Point the table in the catalog to the new filenode -5. Release locks -6. Commit transaction -7. Delete orhpan filenode - -i. Upon postmaster startup, remove any orphaned filenodes - -The real problem here is the fact that there are now missing attnos in -pg_attribute. Either that's handled or we renumber the attnos - which is -also quite hard? - -This, of course, suffers from the double size data problem - but I believe -that it does not matter - we just need to document it. - -Interestingly enough, Oracle support - -ALTER TABLE foo SET UNUSED col; - -Which invalidates the attribute entry, and: - -ALTER TABLE foo DROP col CHECKPOINT 1000; - -Which actually reclaims the space. The optional CHECKPOINT [n] clause -tells Oracle to do a checkpoint every [n] rows. - -"Checkpointing cuts down the amount of undo logs accumulated during the -drop column operation to avoid running out of rollback segment space. -However, if this statement is interrupted after a checkpoint has been -applied, the table remains in an unusable state. While the table is -unusable, the only operations allowed on it are DROP TABLE, TRUNCATE -TABLE, and ALTER TABLE DROP COLUMNS CONTINUE (described below). " - -Chris - - - -From pgsql-hackers-owner+M21180@postgresql.org Thu Apr 11 12:02:54 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3BG2sS03611 - for ; Thu, 11 Apr 2002 12:02:54 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 6446B478F0A; Thu, 11 Apr 2002 12:01:19 -0400 (EDT) -Received: from houston.familyhealth.com.au (i231-006.nv.iinet.net.au [203.59.231.6]) - by postgresql.org (Postfix) with ESMTP id B6271478E4C - for ; Thu, 11 Apr 2002 12:00:24 -0400 (EDT) -Received: from localhost (chriskl@localhost) - by houston.familyhealth.com.au (8.11.6/8.11.6) with ESMTP id g3BG0GJ70765; - Fri, 12 Apr 2002 00:00:16 +0800 (WST) - (envelope-from chriskl@familyhealth.com.au) -Date: Fri, 12 Apr 2002 00:00:16 +0800 (WST) -From: Christopher Kings-Lynne -To: Bruce Momjian -cc: Hiroshi Inoue , Tom Lane , - -Subject: Re: [HACKERS] RFC: Restructuring pg_aggregate -In-Reply-To: <200204110419.g3B4J8v29682@candle.pha.pa.us> -Message-ID: <20020411233659.O69846-100000@houston.familyhealth.com.au> -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: ORr - -> Actually, what we need to do to reclaim space is to enable table -> recreation without the column, now that we have relfilenode for file -> renaming. It isn't hard to do, but no one has focused on it. I want to -> focus on it, but have not had the time, obviously, and would be very -> excited to assist someone else. -> -> Hiroshi's fine idea of marking certain columns as unused would not have -> reclaimed the missing space, just as my idea of physical/logical column -> distinction would not reclaim the space either. Again, my -> physical/logical idea is more for fixing other problems and -> optimization, not DROP COLUMN. - -Hmmm. Personally, I think that a DROP COLUMN that cannot reclaim space is -kinda useless - you may as well just use a view!!! - -So how would this occur?: - -1. Lock target table for writing (allow reads) -2. Begin a table scan on target table, writing - a new file with a particular filenode -3. Delete the attribute row from pg_attribute -4. Point the table in the catalog to the new filenode -5. Release locks -6. Commit transaction -7. Delete orhpan filenode - -i. Upon postmaster startup, remove any orphaned filenodes - -The real problem here is the fact that there are now missing attnos in -pg_attribute. Either that's handled or we renumber the attnos - which is -also quite hard? - -This, of course, suffers from the double size data problem - but I believe -that it does not matter - we just need to document it. - -Interestingly enough, Oracle support - -ALTER TABLE foo SET UNUSED col; - -Which invalidates the attribute entry, and: - -ALTER TABLE foo DROP col CHECKPOINT 1000; - -Which actually reclaims the space. The optional CHECKPOINT [n] clause -tells Oracle to do a checkpoint every [n] rows. - -"Checkpointing cuts down the amount of undo logs accumulated during the -drop column operation to avoid running out of rollback segment space. -However, if this statement is interrupted after a checkpoint has been -applied, the table remains in an unusable state. While the table is -unusable, the only operations allowed on it are DROP TABLE, TRUNCATE -TABLE, and ALTER TABLE DROP COLUMNS CONTINUE (described below). " - -Chris - - - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From tgl@sss.pgh.pa.us Thu Apr 11 12:22:44 2002 -Return-path: -Received: from sss.pgh.pa.us (root@[192.204.191.242]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3BGMhS05541 - for ; Thu, 11 Apr 2002 12:22:43 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g3BGMaF01827; - Thu, 11 Apr 2002 12:22:36 -0400 (EDT) -To: Christopher Kings-Lynne -cc: Bruce Momjian , Hiroshi Inoue , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFC: Restructuring pg_aggregate -In-Reply-To: <20020411233659.O69846-100000@houston.familyhealth.com.au> -References: <20020411233659.O69846-100000@houston.familyhealth.com.au> -Comments: In-reply-to Christopher Kings-Lynne - message dated "Fri, 12 Apr 2002 00:00:16 +0800" -Date: Thu, 11 Apr 2002 12:22:35 -0400 -Message-ID: <1824.1018542155@sss.pgh.pa.us> -From: Tom Lane -Status: ORr - -Christopher Kings-Lynne writes: -> The real problem here is the fact that there are now missing attnos in -> pg_attribute. Either that's handled or we renumber the attnos - which is -> also quite hard? - -Updating pg_attribute per se is not so hard --- just store new copies of -all the rows for the table. However, propagating the changes into other -places could be quite painful (I'm thinking of column numbers in stored -constraints, rules, etc). - -It seems to me that reducing the column to NULLs already gets you the -majority of the space savings. I don't think there is a case to be made -that getting back that last bit is worth the pain involved, either in -implementation effort or direct runtime costs (do you really want a DROP -COLUMN to force an immediate rewrite of the whole table?) - - regards, tom lane - -From pgsql-hackers-owner+M21186@postgresql.org Thu Apr 11 13:03:13 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3BH3DS08942 - for ; Thu, 11 Apr 2002 13:03:13 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 517ED479415; Thu, 11 Apr 2002 12:29:32 -0400 (EDT) -Received: from sss.pgh.pa.us (unknown [192.204.191.242]) - by postgresql.org (Postfix) with ESMTP id B87BC479327 - for ; Thu, 11 Apr 2002 12:22:51 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g3BGMaF01827; - Thu, 11 Apr 2002 12:22:36 -0400 (EDT) -To: Christopher Kings-Lynne -cc: Bruce Momjian , Hiroshi Inoue , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFC: Restructuring pg_aggregate -In-Reply-To: <20020411233659.O69846-100000@houston.familyhealth.com.au> -References: <20020411233659.O69846-100000@houston.familyhealth.com.au> -Comments: In-reply-to Christopher Kings-Lynne - message dated "Fri, 12 Apr 2002 00:00:16 +0800" -Date: Thu, 11 Apr 2002 12:22:35 -0400 -Message-ID: <1824.1018542155@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Christopher Kings-Lynne writes: -> The real problem here is the fact that there are now missing attnos in -> pg_attribute. Either that's handled or we renumber the attnos - which is -> also quite hard? - -Updating pg_attribute per se is not so hard --- just store new copies of -all the rows for the table. However, propagating the changes into other -places could be quite painful (I'm thinking of column numbers in stored -constraints, rules, etc). - -It seems to me that reducing the column to NULLs already gets you the -majority of the space savings. I don't think there is a case to be made -that getting back that last bit is worth the pain involved, either in -implementation effort or direct runtime costs (do you really want a DROP -COLUMN to force an immediate rewrite of the whole table?) - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M21187@postgresql.org Thu Apr 11 13:25:05 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3BHP4S10960 - for ; Thu, 11 Apr 2002 13:25:05 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 2BC27479442; Thu, 11 Apr 2002 12:30:28 -0400 (EDT) -Received: from candle.pha.pa.us (216-55-132-35.dsl.san-diego.abac.net [216.55.132.35]) - by postgresql.org (Postfix) with ESMTP id 265E5479340 - for ; Thu, 11 Apr 2002 12:23:30 -0400 (EDT) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.11.6/8.10.1) id g3BGNS405576; - Thu, 11 Apr 2002 12:23:28 -0400 (EDT) -From: Bruce Momjian -Message-ID: <200204111623.g3BGNS405576@candle.pha.pa.us> -Subject: Re: [HACKERS] RFC: Restructuring pg_aggregate -In-Reply-To: <20020411233659.O69846-100000@houston.familyhealth.com.au> -To: Christopher Kings-Lynne -Date: Thu, 11 Apr 2002 12:23:28 -0400 (EDT) -cc: Hiroshi Inoue , Tom Lane , - pgsql-hackers@postgresql.org -X-Mailer: ELM [version 2.4ME+ PL97 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Christopher Kings-Lynne wrote: -> > Actually, what we need to do to reclaim space is to enable table -> > recreation without the column, now that we have relfilenode for file -> > renaming. It isn't hard to do, but no one has focused on it. I want to -> > focus on it, but have not had the time, obviously, and would be very -> > excited to assist someone else. -> > -> > Hiroshi's fine idea of marking certain columns as unused would not have -> > reclaimed the missing space, just as my idea of physical/logical column -> > distinction would not reclaim the space either. Again, my -> > physical/logical idea is more for fixing other problems and -> > optimization, not DROP COLUMN. -> -> Hmmm. Personally, I think that a DROP COLUMN that cannot reclaim space is -> kinda useless - you may as well just use a view!!! - -Yep, kind of a problem. It is a tradeoff between double diskspace/speed -and removing column from disk. I guess that's why Oracle has both. - -> -> So how would this occur?: -> -> 1. Lock target table for writing (allow reads) -> 2. Begin a table scan on target table, writing -> a new file with a particular filenode -> 3. Delete the attribute row from pg_attribute -> 4. Point the table in the catalog to the new filenode -> 5. Release locks -> 6. Commit transaction -> 7. Delete orhpan filenode - -Yep, something like that. CLUSTER is a good start. DROP COLUMN just -deals with the attno too. You would have to renumber them to fill the -gap. - -> i. Upon postmaster startup, remove any orphaned filenodes - -Actually, we don't have a good solution for finding orphaned filenodes -right now. I do have some code that tries to do this as part of VACUUM -but it was not 100% perfect, so it was rejected. I am willing to open -the discussion to see if a perfect solution can be found. - - --- - Bruce Momjian | http://candle.pha.pa.us - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M21190@postgresql.org Thu Apr 11 13:40:34 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3BHeXS12137 - for ; Thu, 11 Apr 2002 13:40:33 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 2BD6C479604; Thu, 11 Apr 2002 12:35:51 -0400 (EDT) -Received: from candle.pha.pa.us (216-55-132-35.dsl.san-diego.abac.net [216.55.132.35]) - by postgresql.org (Postfix) with ESMTP id 2DF9D47946A - for ; Thu, 11 Apr 2002 12:31:25 -0400 (EDT) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.11.6/8.10.1) id g3BGVM806114; - Thu, 11 Apr 2002 12:31:22 -0400 (EDT) -From: Bruce Momjian -Message-ID: <200204111631.g3BGVM806114@candle.pha.pa.us> -Subject: Re: [HACKERS] RFC: Restructuring pg_aggregate -In-Reply-To: <1824.1018542155@sss.pgh.pa.us> -To: Tom Lane -Date: Thu, 11 Apr 2002 12:31:22 -0400 (EDT) -cc: Christopher Kings-Lynne , - Hiroshi Inoue , pgsql-hackers@postgresql.org -X-Mailer: ELM [version 2.4ME+ PL97 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> Christopher Kings-Lynne writes: -> > The real problem here is the fact that there are now missing attnos in -> > pg_attribute. Either that's handled or we renumber the attnos - which is -> > also quite hard? -> -> Updating pg_attribute per se is not so hard --- just store new copies of -> all the rows for the table. However, propagating the changes into other -> places could be quite painful (I'm thinking of column numbers in stored -> constraints, rules, etc). -> -> It seems to me that reducing the column to NULLs already gets you the -> majority of the space savings. I don't think there is a case to be made -> that getting back that last bit is worth the pain involved, either in -> implementation effort or direct runtime costs (do you really want a DROP -> COLUMN to force an immediate rewrite of the whole table?) - -That is an excellent point about having to fix all the places that refer -to attno. In fact, we have been moving away from attname references to -attno references for a while, so it only gets worse. Tom is also -correct that setting it to NULL removes the problem of disk space usage -quite easily. - -That only leaves the problem of having gaps in the pg_attribute for that -relation, and as I remember, that was the problem for Hiroshi's DROP -COLUMN change, but at this point, after years of delay with no great -solution on the horizon, we may as well just get this working. - --- - Bruce Momjian | http://candle.pha.pa.us - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From Inoue@tpf.co.jp Thu Apr 11 19:55:08 2002 -Return-path: -Received: from sd.tpf.co.jp (IDENT:qmailr@sd.tpf.co.jp [210.161.239.34]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g3BNt6S19759 - for ; Thu, 11 Apr 2002 19:55:06 -0400 (EDT) -Received: (qmail 31013 invoked from network); 11 Apr 2002 23:55:06 -0000 -Received: from unknown (HELO viscomail.tpf.co.jp) (100.0.0.108) - by sd2.tpf-fw-c.co.jp with SMTP; 11 Apr 2002 23:55:06 -0000 -Received: from tpf.co.jp (3dgateway1 [126.0.1.60]) - by viscomail.tpf.co.jp (8.8.8+Sun/8.8.8) with ESMTP id IAA22335; - Fri, 12 Apr 2002 08:55:05 +0900 (JST) -Message-ID: <3CB62298.88565A54@tpf.co.jp> -Date: Fri, 12 Apr 2002 08:56:08 +0900 -From: Hiroshi Inoue -X-Mailer: Mozilla 4.73 [ja] (Windows NT 5.0; U) -X-Accept-Language: ja -MIME-Version: 1.0 -To: Christopher Kings-Lynne -cc: Bruce Momjian , Tom Lane , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFC: Restructuring pg_aggregate -References: <20020411233659.O69846-100000@houston.familyhealth.com.au> -Content-Type: text/plain; charset=iso-2022-jp -Content-Transfer-Encoding: 7bit -Status: OR - -Christopher Kings-Lynne wrote: -> -> Hmmm. Personally, I think that a DROP COLUMN that cannot reclaim space is -> kinda useless - you may as well just use a view!!! -> -> So how would this occur?: -> -> 1. Lock target table for writing (allow reads) -> 2. Begin a table scan on target table, writing -> a new file with a particular filenode -> 3. Delete the attribute row from pg_attribute -> 4. Point the table in the catalog to the new filenode -> 5. Release locks -> 6. Commit transaction -> 7. Delete orhpan filenode -> -> i. Upon postmaster startup, remove any orphaned filenodes -> -> The real problem here is the fact that there are now missing attnos in -> pg_attribute. Either that's handled or we renumber the attnos - which is -> also quite hard? - -The attnos should be renumbered and it's easy. -But the above seems only 20% of the total implementation. -If the attnos are renumbered, all objects which refer to -the numbers must be invalidated or re-compiled ... -For example the parameters of foreign key constraints -triggers are consist of relname and colnames currently. -There has been a proposal that change to use relid or -column numbers instead. Certainly it makes RENAME happy -but DROP COLUMN unhappy. If there's a foreign key a_rel/1/3 -and the second column of the relation is dropped the -parameter must be changed to be a_rel/1/2. If neither -foreign key stuff nor DROP COLUMN take the other into -account, the consistency is easily broken. - -regards, -Hiroshi Inoue - -From pgsql-hackers-owner+M21205@postgresql.org Thu Apr 11 19:56:20 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3BNuJS19855 - for ; Thu, 11 Apr 2002 19:56:19 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 2B38A47656E; Thu, 11 Apr 2002 19:55:57 -0400 (EDT) -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by postgresql.org (Postfix) with SMTP id 6C92E475C96 - for ; Thu, 11 Apr 2002 19:55:04 -0400 (EDT) -Received: (qmail 31013 invoked from network); 11 Apr 2002 23:55:06 -0000 -Received: from unknown (HELO viscomail.tpf.co.jp) (100.0.0.108) - by sd2.tpf-fw-c.co.jp with SMTP; 11 Apr 2002 23:55:06 -0000 -Received: from tpf.co.jp (3dgateway1 [126.0.1.60]) - by viscomail.tpf.co.jp (8.8.8+Sun/8.8.8) with ESMTP id IAA22335; - Fri, 12 Apr 2002 08:55:05 +0900 (JST) -Message-ID: <3CB62298.88565A54@tpf.co.jp> -Date: Fri, 12 Apr 2002 08:56:08 +0900 -From: Hiroshi Inoue -X-Mailer: Mozilla 4.73 [ja] (Windows NT 5.0; U) -X-Accept-Language: ja -MIME-Version: 1.0 -To: Christopher Kings-Lynne -cc: Bruce Momjian , Tom Lane , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFC: Restructuring pg_aggregate -References: <20020411233659.O69846-100000@houston.familyhealth.com.au> -Content-Type: text/plain; charset=iso-2022-jp -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: ORr - -Christopher Kings-Lynne wrote: -> -> Hmmm. Personally, I think that a DROP COLUMN that cannot reclaim space is -> kinda useless - you may as well just use a view!!! -> -> So how would this occur?: -> -> 1. Lock target table for writing (allow reads) -> 2. Begin a table scan on target table, writing -> a new file with a particular filenode -> 3. Delete the attribute row from pg_attribute -> 4. Point the table in the catalog to the new filenode -> 5. Release locks -> 6. Commit transaction -> 7. Delete orhpan filenode -> -> i. Upon postmaster startup, remove any orphaned filenodes -> -> The real problem here is the fact that there are now missing attnos in -> pg_attribute. Either that's handled or we renumber the attnos - which is -> also quite hard? - -The attnos should be renumbered and it's easy. -But the above seems only 20% of the total implementation. -If the attnos are renumbered, all objects which refer to -the numbers must be invalidated or re-compiled ... -For example the parameters of foreign key constraints -triggers are consist of relname and colnames currently. -There has been a proposal that change to use relid or -column numbers instead. Certainly it makes RENAME happy -but DROP COLUMN unhappy. If there's a foreign key a_rel/1/3 -and the second column of the relation is dropped the -parameter must be changed to be a_rel/1/2. If neither -foreign key stuff nor DROP COLUMN take the other into -account, the consistency is easily broken. - -regards, -Hiroshi Inoue - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M21209@postgresql.org Thu Apr 11 22:27:40 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3C2ReS27660 - for ; Thu, 11 Apr 2002 22:27:40 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id A89AF4766D0; Thu, 11 Apr 2002 22:27:35 -0400 (EDT) -Received: from candle.pha.pa.us (216-55-132-35.dsl.san-diego.abac.net [216.55.132.35]) - by postgresql.org (Postfix) with ESMTP id 4CE13475EB9 - for ; Thu, 11 Apr 2002 22:26:25 -0400 (EDT) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.11.6/8.10.1) id g3C2Q5I27551; - Thu, 11 Apr 2002 22:26:05 -0400 (EDT) -From: Bruce Momjian -Message-ID: <200204120226.g3C2Q5I27551@candle.pha.pa.us> -Subject: Re: [HACKERS] RFC: Restructuring pg_aggregate -In-Reply-To: <3CB62298.88565A54@tpf.co.jp> -To: Hiroshi Inoue -Date: Thu, 11 Apr 2002 22:26:05 -0400 (EDT) -cc: Christopher Kings-Lynne , - Tom Lane , pgsql-hackers@postgresql.org -X-Mailer: ELM [version 2.4ME+ PL97 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Hiroshi Inoue wrote: -> Christopher Kings-Lynne wrote: -> > -> > Hmmm. Personally, I think that a DROP COLUMN that cannot reclaim space is -> > kinda useless - you may as well just use a view!!! -> > -> > So how would this occur?: -> > -> > 1. Lock target table for writing (allow reads) -> > 2. Begin a table scan on target table, writing -> > a new file with a particular filenode -> > 3. Delete the attribute row from pg_attribute -> > 4. Point the table in the catalog to the new filenode -> > 5. Release locks -> > 6. Commit transaction -> > 7. Delete orhpan filenode -> > -> > i. Upon postmaster startup, remove any orphaned filenodes -> > -> > The real problem here is the fact that there are now missing attnos in -> > pg_attribute. Either that's handled or we renumber the attnos - which is -> > also quite hard? -> -> The attnos should be renumbered and it's easy. -> But the above seems only 20% of the total implementation. -> If the attnos are renumbered, all objects which refer to -> the numbers must be invalidated or re-compiled ... -> For example the parameters of foreign key constraints -> triggers are consist of relname and colnames currently. -> There has been a proposal that change to use relid or -> column numbers instead. Certainly it makes RENAME happy -> but DROP COLUMN unhappy. If there's a foreign key a_rel/1/3 -> and the second column of the relation is dropped the -> parameter must be changed to be a_rel/1/2. If neither -> foreign key stuff nor DROP COLUMN take the other into -> account, the consistency is easily broken. - -I think that is why Tom was suggesting making all the column values NULL -and removing the pg_attribute row for the column. With a NULL value, it -doesn't take up any room in the tuple, and with the pg_attribute column -gone, no one will see that row. The only problem is the gap in attno -numbering. How big a problem is that? - --- - Bruce Momjian | http://candle.pha.pa.us - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M21211@postgresql.org Thu Apr 11 22:55:44 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3C2tiS29394 - for ; Thu, 11 Apr 2002 22:55:44 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id B86AF476739; Thu, 11 Apr 2002 22:55:39 -0400 (EDT) -Received: from sss.pgh.pa.us (unknown [192.204.191.242]) - by postgresql.org (Postfix) with ESMTP id 56D8747593C - for ; Thu, 11 Apr 2002 22:54:26 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g3C2s1F24007; - Thu, 11 Apr 2002 22:54:01 -0400 (EDT) -To: Bruce Momjian -cc: Hiroshi Inoue , - Christopher Kings-Lynne , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFC: Restructuring pg_aggregate -In-Reply-To: <200204120226.g3C2Q5I27551@candle.pha.pa.us> -References: <200204120226.g3C2Q5I27551@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Thu, 11 Apr 2002 22:26:05 -0400" -Date: Thu, 11 Apr 2002 22:54:01 -0400 -Message-ID: <24004.1018580041@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Bruce Momjian writes: -> I think that is why Tom was suggesting making all the column values NULL -> and removing the pg_attribute row for the column. - -That was not my suggestion. - -> With a NULL value, it -> doesn't take up any room in the tuple, and with the pg_attribute column -> gone, no one will see that row. The only problem is the gap in attno -> numbering. How big a problem is that? - -You can't do it that way unless you're intending to rewrite all rows of -the relation before committing the ALTER; which would be the worst of -both worlds. The pg_attribute row *must* be retained to show the -datatype of the former column, so that we can correctly skip over it -in tuples where the column isn't yet nulled out. - -Hiroshi did this by renumbering the attnum; I propose leaving attnum -alone and instead adding an attisdropped flag. That would avoid -creating a gap in the column numbers, but either way is likely to affect -some applications that inspect pg_attribute. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M21214@postgresql.org Fri Apr 12 00:09:26 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3C49PS05093 - for ; Fri, 12 Apr 2002 00:09:25 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id B1BE6476810; Fri, 12 Apr 2002 00:09:20 -0400 (EDT) -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by postgresql.org (Postfix) with SMTP id A8E07476444 - for ; Fri, 12 Apr 2002 00:08:22 -0400 (EDT) -Received: (qmail 25808 invoked from network); 12 Apr 2002 04:08:26 -0000 -Received: from unknown (HELO viscomail.tpf.co.jp) (100.0.0.108) - by sd2.tpf-fw-c.co.jp with SMTP; 12 Apr 2002 04:08:26 -0000 -Received: from tpf.co.jp (3dgateway1 [126.0.1.60]) - by viscomail.tpf.co.jp (8.8.8+Sun/8.8.8) with ESMTP id NAA22497; - Fri, 12 Apr 2002 13:08:24 +0900 (JST) -Message-ID: <3CB65DF7.8FCFC024@tpf.co.jp> -Date: Fri, 12 Apr 2002 13:09:28 +0900 -From: Hiroshi Inoue -X-Mailer: Mozilla 4.73 [ja] (Windows NT 5.0; U) -X-Accept-Language: ja -MIME-Version: 1.0 -To: Bruce Momjian -cc: Christopher Kings-Lynne , - Tom Lane , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFC: Restructuring pg_aggregate -References: <200204120226.g3C2Q5I27551@candle.pha.pa.us> -Content-Type: text/plain; charset=iso-2022-jp -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Bruce Momjian wrote: -> -> Hiroshi Inoue wrote: -> > Christopher Kings-Lynne wrote: -> > > -> I think that is why Tom was suggesting making all the column values NULL -> and removing the pg_attribute row for the column. With a NULL value, it -> doesn't take up any room in the tuple, and with the pg_attribute column -> gone, no one will see that row. The only problem is the gap in attno -> numbering. How big a problem is that? - -There's no problem with applications which don't inquire -of system catalogs(pg_attribute). Unfortunately we have -been very tolerant of users' access on system tables and -there would be pretty many applications which inquire of -pg_attribute. - -regards, -Hiroshi Inoue - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M21221@postgresql.org Fri Apr 12 05:11:00 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3C9AxS28516 - for ; Fri, 12 Apr 2002 05:11:00 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 28FF0476B9D; Fri, 12 Apr 2002 04:35:54 -0400 (EDT) -Received: from tele-post-20.mail.demon.net (tele-post-20.mail.demon.net [194.217.242.20]) - by postgresql.org (Postfix) with ESMTP id BFDE74769AC - for ; Fri, 12 Apr 2002 04:30:29 -0400 (EDT) -Received: from mailgate.vale-housing.co.uk ([193.195.77.162] helo=dogbert.vale-housing.co.uk) - by tele-post-20.mail.demon.net with esmtp (Exim 3.35 #1) - id 16vwRc-0006GP-0K; Fri, 12 Apr 2002 08:30:08 +0000 -Received: by dogbert.vale-housing.co.uk with Internet Mail Service (5.5.2650.21) - id <2H2ZS6HB>; Fri, 12 Apr 2002 09:35:53 +0100 -Message-ID: -From: Dave Page -To: "'Tom Lane'" , Bruce Momjian -cc: Hiroshi Inoue , - Christopher Kings-Lynne , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFC: Restructuring pg_aggregate -Date: Fri, 12 Apr 2002 09:35:52 +0100 -MIME-Version: 1.0 -X-Mailer: Internet Mail Service (5.5.2650.21) -Content-Type: text/plain -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - - -> -----Original Message----- -> From: Tom Lane [mailto:tgl@sss.pgh.pa.us] -> Sent: 12 April 2002 03:54 -> To: Bruce Momjian -> Cc: Hiroshi Inoue; Christopher Kings-Lynne; -> pgsql-hackers@postgresql.org -> Subject: Re: RFC: Restructuring pg_aggregate -> -> -> Bruce Momjian writes: -> > I think that is why Tom was suggesting making all the column values -> > NULL and removing the pg_attribute row for the column. -> -> That was not my suggestion. -> -> > With a NULL value, it -> > doesn't take up any room in the tuple, and with the pg_attribute -> > column gone, no one will see that row. The only problem is -> the gap in -> > attno numbering. How big a problem is that? -> -> You can't do it that way unless you're intending to rewrite -> all rows of the relation before committing the ALTER; which -> would be the worst of both worlds. The pg_attribute row -> *must* be retained to show the datatype of the former column, -> so that we can correctly skip over it in tuples where the -> column isn't yet nulled out. -> -> Hiroshi did this by renumbering the attnum; I propose leaving -> attnum alone and instead adding an attisdropped flag. That -> would avoid creating a gap in the column numbers, but either -> way is likely to affect some applications that inspect pg_attribute. - -Applications like pgAdmin that inspect pg_attribute are being seriously -hacked to incorporate schema support anyway for 7.3. Personnally I'd be glad -to spend some time re-coding to allow for this, just to not have to answer -the numerous 'how do I drop a column' emails I get reguarly. - -Regards, Dave. - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From chriskl@familyhealth.com.au Sat Apr 13 02:25:23 2002 -Return-path: -Received: from mail.iinet.net.au (symphony-01.iinet.net.au [203.59.3.33]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g3D6PLS06807 - for ; Sat, 13 Apr 2002 02:25:22 -0400 (EDT) -Received: (qmail 7569 invoked by uid 666); 13 Apr 2002 06:25:20 -0000 -Received: from unknown (HELO SOL) (203.59.103.193) - by mail.iinet.net.au with SMTP; 13 Apr 2002 06:25:20 -0000 -Message-ID: <001701c1e2b2$e7b10a40$0200a8c0@SOL> -From: "Christopher Kings-Lynne" -To: "Tom Lane" -cc: "Bruce Momjian" , - "Hiroshi Inoue" , -References: <20020411233659.O69846-100000@houston.familyhealth.com.au> <1824.1018542155@sss.pgh.pa.us> -Subject: Re: [HACKERS] RFC: Restructuring pg_aggregate -Date: Sat, 13 Apr 2002 14:17:34 +0800 -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook Express 5.50.4522.1200 -X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200 -Status: OR - -> Updating pg_attribute per se is not so hard --- just store new copies of -> all the rows for the table. However, propagating the changes into other -> places could be quite painful (I'm thinking of column numbers in stored -> constraints, rules, etc). -> -> It seems to me that reducing the column to NULLs already gets you the -> majority of the space savings. I don't think there is a case to be made -> that getting back that last bit is worth the pain involved, either in -> implementation effort or direct runtime costs (do you really want a DROP -> COLUMN to force an immediate rewrite of the whole table?) - -OK, sounds fair. However, is there a more aggressive way of reclaiming the -space? The problem with updating all the rows to null for that column is -that the on-disk size is doubled anyway, right? So, could a VACUUM FULL -process do the nulling for us? Vacuum works outside of normal transaction -constraints anyway...? - -Also, it seems to me that at some point we are forced to break client -compatibility. Either we add attisdropped field to pg_attribute, or we use -Hiroshi's (-1 * attnum - offset) idea. Both Tom and Hiroshi have good -reasons for each of these - would it be possible for you guys to post with -your reasons for and against both the techniques. I just want to get to an -implementation specification we all agree on that can be written up and then -the coding can proceed. Maybe we should add it to the 'Postgres Major -Projects' page - and remove those old ones that have already been -implemented. - -Chris - - - -From Inoue@tpf.co.jp Sun Apr 14 23:47:08 2002 -Return-path: -Received: from sd.tpf.co.jp (IDENT:qmailr@sd.tpf.co.jp [210.161.239.34]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g3F3l6S23155 - for ; Sun, 14 Apr 2002 23:47:07 -0400 (EDT) -Received: (qmail 9638 invoked from network); 15 Apr 2002 03:47:06 -0000 -Received: from unknown (HELO viscomail.tpf.co.jp) (100.0.0.108) - by sd2.tpf-fw-c.co.jp with SMTP; 15 Apr 2002 03:47:06 -0000 -Received: from tpf.co.jp (3dgateway1 [126.0.1.60]) - by viscomail.tpf.co.jp (8.8.8+Sun/8.8.8) with ESMTP id MAA24068; - Mon, 15 Apr 2002 12:47:04 +0900 (JST) -Message-ID: <3CBA4D7A.9E61DECA@tpf.co.jp> -Date: Mon, 15 Apr 2002 12:48:10 +0900 -From: Hiroshi Inoue -X-Mailer: Mozilla 4.73 [ja] (Windows NT 5.0; U) -X-Accept-Language: ja -MIME-Version: 1.0 -To: Christopher Kings-Lynne -cc: Tom Lane , Bruce Momjian , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFC: Restructuring pg_aggregate -References: <20020411233659.O69846-100000@houston.familyhealth.com.au> <1824.1018542155@sss.pgh.pa.us> <001701c1e2b2$e7b10a40$0200a8c0@SOL> -Content-Type: text/plain; charset=iso-2022-jp -Content-Transfer-Encoding: 7bit -Status: OR - -Christopher Kings-Lynne wrote: -> -> Also, it seems to me that at some point we are forced to break client -> compatibility. - -It's not a users' consensus at all. I'm suspicious if -DROP COLUMN is such a significant feature to break -client compatibility at our ease. - -> Either we add attisdropped field to pg_attribute, or we use -> Hiroshi's (-1 * attnum - offset) idea. Both Tom and Hiroshi have good -> reasons for each of these - would it be possible for you guys to post with -> your reasons for and against both the techniques. - -I don't object to adding attisdropped field. What -I meant to say is that the differene is very small. - -regards, -Hiroshi Inoue - -From tgl@sss.pgh.pa.us Sat Apr 13 11:30:17 2002 -Return-path: -Received: from sss.pgh.pa.us (root@[192.204.191.242]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3DFUGS26218 - for ; Sat, 13 Apr 2002 11:30:16 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g3DFTjF15655; - Sat, 13 Apr 2002 11:29:45 -0400 (EDT) -To: "Christopher Kings-Lynne" -cc: "Bruce Momjian" , - "Hiroshi Inoue" , pgsql-hackers@postgresql.org -Subject: Re: DROP COLUMN (was RFC: Restructuring pg_aggregate) -In-Reply-To: <001701c1e2b2$e7b10a40$0200a8c0@SOL> -References: <20020411233659.O69846-100000@houston.familyhealth.com.au> <1824.1018542155@sss.pgh.pa.us> <001701c1e2b2$e7b10a40$0200a8c0@SOL> -Comments: In-reply-to "Christopher Kings-Lynne" - message dated "Sat, 13 Apr 2002 14:17:34 +0800" -Date: Sat, 13 Apr 2002 11:29:45 -0400 -Message-ID: <15652.1018711785@sss.pgh.pa.us> -From: Tom Lane -Status: OR - -[ way past time to change the title of this thread ] - -"Christopher Kings-Lynne" writes: -> OK, sounds fair. However, is there a more aggressive way of reclaiming the -> space? The problem with updating all the rows to null for that column is -> that the on-disk size is doubled anyway, right? So, could a VACUUM FULL -> process do the nulling for us? Vacuum works outside of normal transaction -> constraints anyway...? - -No, VACUUM has the same transactional constraints as everyone else -(unless you'd like a crash during VACUUM to trash your table...) - -I do not think that we necessarily need to provide a special mechanism -for this at all. The docs for DROP COLUMN could simply explain that -the DROP itself doesn't reclaim the space, but that the space will be -reclaimed over time as extant rows are updated or deleted. If you want -to hurry the process along you could do - UPDATE table SET othercol = othercol - VACUUM FULL -to force all the rows to be updated and then reclaim space. But given -the peak-space-is-twice-as-much behavior, this is not obviously a win. -I'd sure object to an implementation that *forced* that approach on me, -whether during DROP itself or the next VACUUM. - -> Also, it seems to me that at some point we are forced to break client -> compatibility. Either we add attisdropped field to pg_attribute, or we use -> Hiroshi's (-1 * attnum - offset) idea. Both Tom and Hiroshi have good -> reasons for each of these - would it be possible for you guys to post with -> your reasons for and against both the techniques. - -Er, didn't we do that already? - - regards, tom lane - -From chriskl@familyhealth.com.au Sun Apr 14 01:06:31 2002 -Return-path: -Received: from mail.iinet.net.au (symphony-03.iinet.net.au [203.59.3.35]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g3E56TS03274 - for ; Sun, 14 Apr 2002 01:06:30 -0400 (EDT) -Received: (qmail 20365 invoked by uid 666); 14 Apr 2002 05:06:31 -0000 -Received: from unknown (HELO SOL) (203.59.168.230) - by mail.iinet.net.au with SMTP; 14 Apr 2002 05:06:31 -0000 -Message-ID: <00c601c1e371$0e324670$0200a8c0@SOL> -From: "Christopher Kings-Lynne" -To: "Tom Lane" -cc: "Bruce Momjian" , - "Hiroshi Inoue" , -References: <20020411233659.O69846-100000@houston.familyhealth.com.au> <1824.1018542155@sss.pgh.pa.us> <001701c1e2b2$e7b10a40$0200a8c0@SOL> <15652.1018711785@sss.pgh.pa.us> -Subject: Re: DROP COLUMN (was RFC: Restructuring pg_aggregate) -Date: Sun, 14 Apr 2002 12:58:43 +0800 -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook Express 5.50.4522.1200 -X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200 -Status: OR - -> No, VACUUM has the same transactional constraints as everyone else -> (unless you'd like a crash during VACUUM to trash your table...) - -Seriously, you can run VACUUM in a transaction and rollback the movement of -a tuple on disk? What do you mean by same transactional constraints? - -Chris - - -From pgsql-hackers-owner+M21278@postgresql.org Sat Apr 13 12:21:20 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3DGLKS29823 - for ; Sat, 13 Apr 2002 12:21:20 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 9B4AF475CA6; Sat, 13 Apr 2002 12:21:12 -0400 (EDT) -Received: from sss.pgh.pa.us (unknown [192.204.191.242]) - by postgresql.org (Postfix) with ESMTP id 1ED76474E71 - for ; Sat, 13 Apr 2002 12:20:07 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g3DGJeF15983; - Sat, 13 Apr 2002 12:19:40 -0400 (EDT) -To: Hannu Krosing -cc: Christopher Kings-Lynne , - Bruce Momjian , Hiroshi Inoue , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] DROP COLUMN (was RFC: Restructuring pg_aggregate) -In-Reply-To: <1018716432.3360.9.camel@taru.tm.ee> -References: <20020411233659.O69846-100000@houston.familyhealth.com.au> <1824.1018542155@sss.pgh.pa.us> <001701c1e2b2$e7b10a40$0200a8c0@SOL> <15652.1018711785@sss.pgh.pa.us> <1018716432.3360.9.camel@taru.tm.ee> -Comments: In-reply-to Hannu Krosing - message dated "13 Apr 2002 18:47:07 +0200" -Date: Sat, 13 Apr 2002 12:19:40 -0400 -Message-ID: <15980.1018714780@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Hannu Krosing writes: ->> No, VACUUM has the same transactional constraints as everyone else ->> (unless you'd like a crash during VACUUM to trash your table...) - -> But can't it do the SET TO NULL thing if it knows that the transaction -> that dropped the column has committed. - -Hmm, you're thinking of allowing VACUUM to overwrite tuples in-place? -Strikes me as unsafe, but I'm not really sure. - -In any case it's not that easy. If the column is wide enough -that reclaiming its space is actually worth doing, then presumably -most of its entries are just TOAST links, and what has to be done is -not just rewrite the main tuple but mark the TOAST rows deleted. -This is not something that VACUUM does now; I'd be rather concerned -about the locking implications (especially for lightweight VACUUM). - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M21277@postgresql.org Sat Apr 13 11:51:02 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3DFp1S28016 - for ; Sat, 13 Apr 2002 11:51:01 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id B76F5475D68; Sat, 13 Apr 2002 11:47:59 -0400 (EDT) -Received: from gw.itmeedia.ee (gw.itmeedia.ee [213.180.3.226]) - by postgresql.org (Postfix) with SMTP id 0635E475C6F - for ; Sat, 13 Apr 2002 11:47:01 -0400 (EDT) -Received: (qmail 12309 invoked from network); 13 Apr 2002 15:47:06 -0000 -Received: from taru.itmeedia.ee (HELO taru.tm.ee) (213.180.3.230) - by gw.itmeedia.ee with SMTP; 13 Apr 2002 15:47:06 -0000 -Subject: Re: [HACKERS] DROP COLUMN (was RFC: Restructuring pg_aggregate) -From: Hannu Krosing -To: Tom Lane -cc: Christopher Kings-Lynne , - Bruce Momjian , Hiroshi Inoue , - pgsql-hackers@postgresql.org -In-Reply-To: <15652.1018711785@sss.pgh.pa.us> -References: <20020411233659.O69846-100000@houston.familyhealth.com.au> - <1824.1018542155@sss.pgh.pa.us> <001701c1e2b2$e7b10a40$0200a8c0@SOL> - <15652.1018711785@sss.pgh.pa.us> -Content-Type: text/plain -Content-Transfer-Encoding: 7bit -X-Mailer: Ximian Evolution 1.0.3.99 -Date: 13 Apr 2002 18:47:07 +0200 -Message-ID: <1018716432.3360.9.camel@taru.tm.ee> -MIME-Version: 1.0 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Sat, 2002-04-13 at 17:29, Tom Lane wrote: -> [ way past time to change the title of this thread ] -> -> "Christopher Kings-Lynne" writes: -> > OK, sounds fair. However, is there a more aggressive way of reclaiming the -> > space? The problem with updating all the rows to null for that column is -> > that the on-disk size is doubled anyway, right? So, could a VACUUM FULL -> > process do the nulling for us? Vacuum works outside of normal transaction -> > constraints anyway...? -> -> No, VACUUM has the same transactional constraints as everyone else -> (unless you'd like a crash during VACUUM to trash your table...) - -But can't it do the SET TO NULL thing if it knows that the transaction -that dropped the column has committed. - -This could probably even be done in the light version of vacuum with a -special flag (VACUUM RECLAIM). - -Of course running this this makes sense only if the dropped column had -some significant amount of data . - -> I do not think that we necessarily need to provide a special mechanism -> for this at all. The docs for DROP COLUMN could simply explain that -> the DROP itself doesn't reclaim the space, but that the space will be -> reclaimed over time as extant rows are updated or deleted. If you want -> to hurry the process along you could do -> UPDATE table SET othercol = othercol -> VACUUM FULL - -If only we could do it in namageable chunks: - -FOR i IN 0 TO (size(table)/chunk) DO - UPDATE table SET othercol = othercol OFFSET i*chunk LIMIT chunk - VACUUM FULL; -END FOR; - -or even better - "VACUUM FULL OFFSET i*chunk LIMIT chunk" and then make -chunk == 1 :) - --------------- -Hannu - - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M21292@postgresql.org Sun Apr 14 01:07:16 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3E57FS03403 - for ; Sun, 14 Apr 2002 01:07:15 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 78A86475DD7; Sun, 14 Apr 2002 01:07:12 -0400 (EDT) -Received: from mail.iinet.net.au (symphony-03.iinet.net.au [203.59.3.35]) - by postgresql.org (Postfix) with SMTP id DA1D447593E - for ; Sun, 14 Apr 2002 01:06:32 -0400 (EDT) -Received: (qmail 20365 invoked by uid 666); 14 Apr 2002 05:06:31 -0000 -Received: from unknown (HELO SOL) (203.59.168.230) - by mail.iinet.net.au with SMTP; 14 Apr 2002 05:06:31 -0000 -Message-ID: <00c601c1e371$0e324670$0200a8c0@SOL> -From: "Christopher Kings-Lynne" -To: "Tom Lane" -cc: "Bruce Momjian" , - "Hiroshi Inoue" , -References: <20020411233659.O69846-100000@houston.familyhealth.com.au> <1824.1018542155@sss.pgh.pa.us> <001701c1e2b2$e7b10a40$0200a8c0@SOL> <15652.1018711785@sss.pgh.pa.us> -Subject: Re: [HACKERS] DROP COLUMN (was RFC: Restructuring pg_aggregate) -Date: Sun, 14 Apr 2002 12:58:43 +0800 -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook Express 5.50.4522.1200 -X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -> No, VACUUM has the same transactional constraints as everyone else -> (unless you'd like a crash during VACUUM to trash your table...) - -Seriously, you can run VACUUM in a transaction and rollback the movement of -a tuple on disk? What do you mean by same transactional constraints? - -Chris - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From tgl@sss.pgh.pa.us Sun Apr 14 14:13:33 2002 -Return-path: -Received: from sss.pgh.pa.us (root@[192.204.191.242]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3EIDWS18224 - for ; Sun, 14 Apr 2002 14:13:32 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g3EIDMF22681; - Sun, 14 Apr 2002 14:13:22 -0400 (EDT) -To: "Christopher Kings-Lynne" -cc: "Bruce Momjian" , - "Hiroshi Inoue" , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] DROP COLUMN (was RFC: Restructuring pg_aggregate) -In-Reply-To: <00c601c1e371$0e324670$0200a8c0@SOL> -References: <20020411233659.O69846-100000@houston.familyhealth.com.au> <1824.1018542155@sss.pgh.pa.us> <001701c1e2b2$e7b10a40$0200a8c0@SOL> <15652.1018711785@sss.pgh.pa.us> <00c601c1e371$0e324670$0200a8c0@SOL> -Comments: In-reply-to "Christopher Kings-Lynne" - message dated "Sun, 14 Apr 2002 12:58:43 +0800" -Date: Sun, 14 Apr 2002 14:13:21 -0400 -Message-ID: <22678.1018808001@sss.pgh.pa.us> -From: Tom Lane -Status: OR - -"Christopher Kings-Lynne" writes: ->> No, VACUUM has the same transactional constraints as everyone else ->> (unless you'd like a crash during VACUUM to trash your table...) - -> Seriously, you can run VACUUM in a transaction and rollback the movement of -> a tuple on disk? What do you mean by same transactional constraints? - -In VACUUM FULL, tuples moved to compact the table aren't good until you -commit. In this hypothetical column-drop-implementing VACUUM, I think -there'd need to be some similar rule --- otherwise it's not clear what -happens to TOASTED data if you crash partway through. (In particular, -if we tried overwriting main tuples in place as Hannu was suggesting, -we'd need a way of being certain the deletion of the corresponding TOAST -rows occurs *before* we overwrite the only reference to them.) - - regards, tom lane - -From pgsql-hackers-owner+M21305@postgresql.org Sun Apr 14 14:14:46 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3EIEkS18333 - for ; Sun, 14 Apr 2002 14:14:46 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 8FA74475C4C; Sun, 14 Apr 2002 14:14:43 -0400 (EDT) -Received: from sss.pgh.pa.us (unknown [192.204.191.242]) - by postgresql.org (Postfix) with ESMTP id 8AC04475892 - for ; Sun, 14 Apr 2002 14:13:52 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g3EIDMF22681; - Sun, 14 Apr 2002 14:13:22 -0400 (EDT) -To: "Christopher Kings-Lynne" -cc: "Bruce Momjian" , - "Hiroshi Inoue" , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] DROP COLUMN (was RFC: Restructuring pg_aggregate) -In-Reply-To: <00c601c1e371$0e324670$0200a8c0@SOL> -References: <20020411233659.O69846-100000@houston.familyhealth.com.au> <1824.1018542155@sss.pgh.pa.us> <001701c1e2b2$e7b10a40$0200a8c0@SOL> <15652.1018711785@sss.pgh.pa.us> <00c601c1e371$0e324670$0200a8c0@SOL> -Comments: In-reply-to "Christopher Kings-Lynne" - message dated "Sun, 14 Apr 2002 12:58:43 +0800" -Date: Sun, 14 Apr 2002 14:13:21 -0400 -Message-ID: <22678.1018808001@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -"Christopher Kings-Lynne" writes: ->> No, VACUUM has the same transactional constraints as everyone else ->> (unless you'd like a crash during VACUUM to trash your table...) - -> Seriously, you can run VACUUM in a transaction and rollback the movement of -> a tuple on disk? What do you mean by same transactional constraints? - -In VACUUM FULL, tuples moved to compact the table aren't good until you -commit. In this hypothetical column-drop-implementing VACUUM, I think -there'd need to be some similar rule --- otherwise it's not clear what -happens to TOASTED data if you crash partway through. (In particular, -if we tried overwriting main tuples in place as Hannu was suggesting, -we'd need a way of being certain the deletion of the corresponding TOAST -rows occurs *before* we overwrite the only reference to them.) - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - diff --git a/doc/TODO.detail/exists b/doc/TODO.detail/exists deleted file mode 100644 index 1758f708cb..0000000000 --- a/doc/TODO.detail/exists +++ /dev/null @@ -1,191 +0,0 @@ -From pgsql-sql-owner+M5999=candle.pha.pa.us=pgman@postgresql.org Mon Dec 17 01:39:56 2001 -Return-path: -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fBH6du410376 - for ; Mon, 17 Dec 2001 01:39:56 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fBH6VoR80062 - for ; Mon, 17 Dec 2001 00:36:11 -0600 (CST) - (envelope-from pgsql-sql-owner+M5999=candle.pha.pa.us=pgman@postgresql.org) -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fBH6Lgm62418 - for ; Mon, 17 Dec 2001 01:21:42 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id fBH6LHi29550; - Mon, 17 Dec 2001 01:21:17 -0500 (EST) -To: "Christopher Kings-Lynne" -cc: "Stephan Szabo" , - "MindTerm" , pgsql-sql@postgresql.org -Subject: Re: [SQL] performance tuning in large function / transaction -In-Reply-To: -References: -Comments: In-reply-to "Christopher Kings-Lynne" - message dated "Mon, 17 Dec 2001 12:06:14 +0800" -Date: Mon, 17 Dec 2001 01:21:16 -0500 -Message-ID: <29547.1008570076@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-sql-owner@postgresql.org -Status: OR - -"Christopher Kings-Lynne" writes: -> Is it true that the IN command is implemented sort of as a linked list -> linear time search? Is there any plan for a super-fast implementation of -> 'IN'? - -This deserves a somewhat long-winded answer. - -Postgres presently supports two kinds of IN (I'm not sure whether SQL92 -allows any additional kinds): - -1. Scalar-list IN: foo IN ('bar', 'baz', 'quux', ...) - -2. Sub-select IN: foo IN (SELECT bar FROM ...) - -In the scalar-list form, a variable is compared to an explicit list of -constants or expressions. This form is exactly equivalent to - foo = 'bar' OR foo = 'baz' OR foo = 'quux' OR ... -and is converted into that form by the parser. The planner is capable -of converting a WHERE clause of this kind into multiple passes of -indexscan, when foo is an indexed column and all the IN-list elements -are constants. Whether it actually will make that conversion depends -on the usual vagaries of pg_statistic entries, etc. But if it's a -unique or fairly-selective index, and there aren't a huge number of -entries in the IN list, a multiple indexscan should be a good plan. - -In the sub-select form, we pretty much suck: for each tuple in the outer -query, we run the inner query until we find a matching value or the -inner query ends. This is basically a nested-loop scenario, with the -only (minimally) redeeming social value being that the planner realizes -it should pick a fast-start plan for the inner query. I think it should -be possible to convert this form into a modified kind of join (sort of -the reverse of an outer join: rather than at least one result per -lefthand row, at most one result per lefthand row), and then we could -use join methods that are more efficient than nested-loop. But no one's -tried to make that happen yet. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-sql-owner+M6000=candle.pha.pa.us=pgman@postgresql.org Mon Dec 17 01:49:56 2001 -Return-path: -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fBH6nu410869 - for ; Mon, 17 Dec 2001 01:49:56 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fBH6fLR80303 - for ; Mon, 17 Dec 2001 00:45:51 -0600 (CST) - (envelope-from pgsql-sql-owner+M6000=candle.pha.pa.us=pgman@postgresql.org) -Received: from mail.iinet.net.au (symphony-05.iinet.net.au [203.59.3.37]) - by postgresql.org (8.11.3/8.11.4) with SMTP id fBH6XFm62784 - for ; Mon, 17 Dec 2001 01:33:15 -0500 (EST) - (envelope-from chriskl@familyhealth.com.au) -Received: (qmail 30765 invoked by uid 666); 17 Dec 2001 06:33:10 -0000 -Received: from unknown (HELO houston.familyhealth.com.au) (203.59.231.6) - by mail.iinet.net.au with SMTP; 17 Dec 2001 06:33:10 -0000 -Received: (from root@localhost) - by houston.familyhealth.com.au (8.11.6/8.11.6) id fBH6XBH96532 - for pgsql-sql@postgresql.org; Mon, 17 Dec 2001 14:33:11 +0800 (WST) - (envelope-from chriskl@familyhealth.com.au) -Received: from mariner (mariner.internal [192.168.0.101]) - by houston.familyhealth.com.au (8.11.6/8.9.3) with SMTP id fBH6X7p96337; - Mon, 17 Dec 2001 14:33:07 +0800 (WST) -From: "Christopher Kings-Lynne" -To: "Tom Lane" -cc: "Stephan Szabo" , - "MindTerm" , -Subject: [SQL] 'IN' performance -Date: Mon, 17 Dec 2001 14:33:40 +0800 -Message-ID: -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2910.0) -X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000 -Importance: Normal -In-Reply-To: <29547.1008570076@sss.pgh.pa.us> -X-scanner: scanned by Inflex 0.1.5c - (http://www.inflex.co.za/) -Precedence: bulk -Sender: pgsql-sql-owner@postgresql.org -Status: OR - -> In the sub-select form, we pretty much suck: for each tuple in the outer -> query, we run the inner query until we find a matching value or the -> inner query ends. This is basically a nested-loop scenario, with the -> only (minimally) redeeming social value being that the planner realizes -> it should pick a fast-start plan for the inner query. I think it should -> be possible to convert this form into a modified kind of join (sort of -> the reverse of an outer join: rather than at least one result per -> lefthand row, at most one result per lefthand row), and then we could -> use join methods that are more efficient than nested-loop. But no one's -> tried to make that happen yet. - -That's what I was thinking...where abouts does all that activity happen? - -I assume the planner knows that it doesn't have to reevaluate the subquery -if it's not correlated? - -Chris - - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-sql-owner+M6001=candle.pha.pa.us=pgman@postgresql.org Mon Dec 17 02:00:10 2001 -Return-path: -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fBH709411405 - for ; Mon, 17 Dec 2001 02:00:09 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fBH6psR80624 - for ; Mon, 17 Dec 2001 00:56:15 -0600 (CST) - (envelope-from pgsql-sql-owner+M6001=candle.pha.pa.us=pgman@postgresql.org) -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fBH6iCm63171 - for ; Mon, 17 Dec 2001 01:44:12 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id fBH6i3i29733; - Mon, 17 Dec 2001 01:44:03 -0500 (EST) -To: "Christopher Kings-Lynne" -cc: "Stephan Szabo" , - "MindTerm" , pgsql-sql@postgresql.org -Subject: Re: [SQL] 'IN' performance -In-Reply-To: -References: -Comments: In-reply-to "Christopher Kings-Lynne" - message dated "Mon, 17 Dec 2001 14:33:40 +0800" -Date: Mon, 17 Dec 2001 01:44:03 -0500 -Message-ID: <29730.1008571443@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-sql-owner@postgresql.org -Status: OR - -"Christopher Kings-Lynne" writes: -> That's what I was thinking...where abouts does all that activity happen? - -The infrastructure for different join rules already exists. There'd -need to be a new JOIN_xxx type added to the various join nodes in the -executor, but AFAICS that's just a minor extension. The part that is -perhaps not trivial is in the planner. All the existing inner and outer -join types start out expressed as joins in the original query. To make -IN into a join, the planner would have to hoist up a clause from WHERE -into the join-tree structure. I think it can be done, but I have not -thought hard about where and how, nor about what semantic restrictions -might need to be checked. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - diff --git a/doc/TODO.detail/foreign b/doc/TODO.detail/foreign deleted file mode 100644 index f05cf35f1c..0000000000 --- a/doc/TODO.detail/foreign +++ /dev/null @@ -1,542 +0,0 @@ -From fjoe@iclub.nsu.ru Tue Jan 23 03:38:45 2001 -Received: from mx.nsu.ru (root@mx.nsu.ru [193.124.215.71]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id DAA14458 - for ; Tue, 23 Jan 2001 03:38:24 -0500 (EST) -Received: from iclub.nsu.ru (root@iclub.nsu.ru [193.124.222.66]) - by mx.nsu.ru (8.9.1/8.9.0) with ESMTP id OAA29153; - Tue, 23 Jan 2001 14:31:27 +0600 (NOVT) -Received: from localhost (fjoe@localhost) - by iclub.nsu.ru (8.11.1/8.11.1) with ESMTP id f0N8VOr15273; - Tue, 23 Jan 2001 14:31:25 +0600 (NS) - (envelope-from fjoe@iclub.nsu.ru) -Date: Tue, 23 Jan 2001 14:31:24 +0600 (NS) -From: Max Khon -To: Bruce Momjian -cc: PostgreSQL-development -Subject: Re: [HACKERS] Bug in FOREIGN KEY -In-Reply-To: <200101230416.XAA04293@candle.pha.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Status: RO - -hi, there! - -On Mon, 22 Jan 2001, Bruce Momjian wrote: - -> -> > This problem with foreign keys has been reported to me, and I have confirmed -> > the bug exists in current sources. The DELETE should succeed: -> > -> > --------------------------------------------------------------------------- -> > -> > CREATE TABLE primarytest2 ( -> > col1 INTEGER, -> > col2 INTEGER, -> > PRIMARY KEY(col1, col2) -> > ); -> > -> > CREATE TABLE foreigntest2 (col3 INTEGER, -> > col4 INTEGER, -> > FOREIGN KEY (col3, col4) REFERENCES primarytest2 -> > ); -> > test=> BEGIN; -> > BEGIN -> > test=> INSERT INTO primarytest2 VALUES (5,5); -> > INSERT 27618 1 -> > test=> DELETE FROM primarytest2 WHERE col1 = 5 AND col2 = 5; -> > ERROR: triggered data change violation on relation "primarytest2" - -I have another (slightly different) example: ---- cut here --- -test=> CREATE TABLE pr(obj_id int PRIMARY KEY); -NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'pr_pkey' for -table 'pr' -CREATE -test=> CREATE TABLE fr(obj_id int REFERENCES pr ON DELETE CASCADE); -NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY -check(s) -CREATE -test=> BEGIN; -BEGIN -test=> INSERT INTO pr (obj_id) VALUES (1); -INSERT 200539 1 -test=> INSERT INTO fr (obj_id) SELECT obj_id FROM pr; -INSERT 200540 1 -test=> DELETE FROM fr; -ERROR: triggered data change violation on relation "fr" -test=> ---- cut here --- - -we are running postgresql 7.1 beta3 - -/fjoe - - -From sszabo@megazone23.bigpanda.com Tue Jan 23 13:41:55 2001 -Received: from megazone23.bigpanda.com (rfx-64-6-210-138.users.reflexcom.com [64.6.210.138]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id NAA19924 - for ; Tue, 23 Jan 2001 13:41:54 -0500 (EST) -Received: from localhost (sszabo@localhost) - by megazone23.bigpanda.com (8.11.1/8.11.1) with ESMTP id f0NIfLa41018; - Tue, 23 Jan 2001 10:41:21 -0800 (PST) -Date: Tue, 23 Jan 2001 10:41:21 -0800 (PST) -From: Stephan Szabo -To: Bruce Momjian -cc: Jan Wieck , Peter Eisentraut , - PostgreSQL-development -Subject: Re: [HACKERS] Bug in FOREIGN KEY -In-Reply-To: <200101230417.XAA04332@candle.pha.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Status: RO - - -> > Think I misinterpreted the SQL3 specs WR to this detail. The -> > checks must be made per statement, not at the transaction -> > level. I'll try to fix it, but we need to define what will -> > happen with referential actions in the case of conflicting -> > actions on the same key - there are some possible conflicts: -> > -> > 1. DEFERRED ON DELETE NO ACTION or RESTRICT -> > -> > Do the referencing rows reference to the new PK row with -> > the same key now, or is this still a constraint -> > violation? I would say it's not, because the constraint -> > condition is satisfied at the end of the transaction. How -> > do other databases behave? -> > -> > 2. DEFERRED ON DELETE CASCADE, SET NULL or SET DEFAULT -> > -> > Again I'd say that the action should be suppressed -> > because a matching PK row is present at transaction end - -> > it's not the same old row, but the constraint itself is -> > still satisfied. - -I'm not actually sure on the cascade, set null and set default. The -way they are written seems to imply to me that it's based on the state -of the database before/after the command in question as opposed to the -deferred state of the database because of the stuff about updating the -state of partially matching rows immediately after the delete/update of -the row which wouldn't really make sense when deferred. Does anyone know -what other systems do with a case something like this all in a -transaction: - -create table a (a int primary key); -create table b (b int references a match full on update cascade - on delete cascade deferrable initially deferred); -insert into a values (1); -insert into a values (2); -insert into b values (1); -delete from a where a=1; -select * from b; -commit; - - -From pgsql-hackers-owner+M3901@postgresql.org Fri Jan 26 17:00:24 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id RAA10576 - for ; Fri, 26 Jan 2001 17:00:24 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f0QLtVq53019; - Fri, 26 Jan 2001 16:55:31 -0500 (EST) - (envelope-from pgsql-hackers-owner+M3901@postgresql.org) -Received: from smtp1b.mail.yahoo.com (smtp3.mail.yahoo.com [128.11.68.135]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f0QLqmq52691 - for ; Fri, 26 Jan 2001 16:52:48 -0500 (EST) - (envelope-from janwieck@yahoo.com) -Received: from j13.us.greatbridge.com (HELO jupiter.greatbridge.com) (216.54.52.153) - by smtp.mail.vip.suc.yahoo.com with SMTP; 26 Jan 2001 22:49:57 -0000 -X-Apparently-From: -Received: (from janwieck@localhost) - by jupiter.greatbridge.com (8.9.3/8.9.3) id RAA04701; - Fri, 26 Jan 2001 17:02:32 -0500 -From: Jan Wieck -Message-Id: <200101262202.RAA04701@jupiter.greatbridge.com> -Subject: Re: [HACKERS] Bug in FOREIGN KEY -In-Reply-To: <200101262110.QAA06902@candle.pha.pa.us> from Bruce Momjian at "Jan - 26, 2001 04:10:22 pm" -To: Bruce Momjian -Date: Fri, 26 Jan 2001 17:02:32 -0500 (EST) -CC: Jan Wieck , Peter Eisentraut , - PostgreSQL-development -X-Mailer: ELM [version 2.4ME+ PL68 (25)] -MIME-Version: 1.0 -Content-Type: text/plain; charset=US-ASCII -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: RO - -Bruce Momjian wrote: -> Here is another bug: -> -> test=> begin; -> BEGIN -> test=> INSERT INTO primarytest2 VALUES (5,5); -> INSERT 18757 1 -> test=> UPDATE primarytest2 SET col2=1 WHERE col1 = 5 AND col2 = 5; -> ERROR: deferredTriggerGetPreviousEvent: event for tuple (0,10) not -> found - - Schema? - - -Jan - --- - -#======================================================================# -# It's easier to get forgiveness for being wrong than for being right. # -# Let's break this rule - forgive me. # -#================================================== JanWieck@Yahoo.com # - - - -_________________________________________________________ -Do You Yahoo!? -Get your free @yahoo.com address at http://mail.yahoo.com - - -From pgsql-hackers-owner+M3864@postgresql.org Fri Jan 26 10:07:36 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id KAA17732 - for ; Fri, 26 Jan 2001 10:07:35 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f0QF3lq12782; - Fri, 26 Jan 2001 10:03:47 -0500 (EST) - (envelope-from pgsql-hackers-owner+M3864@postgresql.org) -Received: from mailout00.sul.t-online.com (mailout00.sul.t-online.com [194.25.134.16]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id f0QF0Yq12614 - for ; Fri, 26 Jan 2001 10:00:34 -0500 (EST) - (envelope-from peter_e@gmx.net) -Received: from fwd01.sul.t-online.com - by mailout00.sul.t-online.com with smtp - id 14MALp-0006Im-00; Fri, 26 Jan 2001 15:59:45 +0100 -Received: from peter.localdomain (520083510237-0001@[212.185.245.73]) by fmrl01.sul.t-online.com - with esmtp id 14MALQ-1Z0gkaC; Fri, 26 Jan 2001 15:59:20 +0100 -Date: Fri, 26 Jan 2001 16:07:27 +0100 (CET) -From: Peter Eisentraut -To: Hiroshi Inoue -cc: Bruce Momjian , - PostgreSQL-development -Subject: Re: [HACKERS] Open 7.1 items -In-Reply-To: <3A70FA87.933B3D51@tpf.co.jp> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -X-Sender: 520083510237-0001@t-dialin.net -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: RO - -Hiroshi Inoue writes: - -> What does this item mean ? -> Is it the following ? -> -> begin; -> insert into pk (id) values (1); -> update(delete from) pk where id=1; -> ERROR: triggered data change violation on relation pk" -> -> If so, isn't it a simple bug ? - -Depends on the definition of "bug". It's not spec compliant and it's not -documented and it's annoying. But it's been like this for a year and the -issue is well known and can normally be avoided. It looks like a -documentation to-do to me. - --- -Peter Eisentraut peter_e@gmx.net http://yi.org/peter-e/ - - -From pgsql-hackers-owner+M3876@postgresql.org Fri Jan 26 13:07:10 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id NAA26086 - for ; Fri, 26 Jan 2001 13:07:09 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f0QI4Vq30248; - Fri, 26 Jan 2001 13:04:31 -0500 (EST) - (envelope-from pgsql-hackers-owner+M3876@postgresql.org) -Received: from sectorbase2.sectorbase.com ([208.48.122.131]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f0QI3Aq30098 - for ; Fri, 26 Jan 2001 13:03:11 -0500 (EST) - (envelope-from vmikheev@SECTORBASE.COM) -Received: by sectorbase2.sectorbase.com with Internet Mail Service (5.5.2653.19) - id ; Fri, 26 Jan 2001 09:41:23 -0800 -Message-ID: <8F4C99C66D04D4118F580090272A7A234D32C1@sectorbase1.sectorbase.com> -From: "Mikheev, Vadim" -To: "'Jan Wieck'" , - PostgreSQL HACKERS - , - Bruce Momjian -Subject: RE: [HACKERS] Open 7.1 items -Date: Fri, 26 Jan 2001 10:02:59 -0800 -MIME-Version: 1.0 -X-Mailer: Internet Mail Service (5.5.2653.19) -Content-Type: text/plain; - charset="iso-8859-1" -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: RO - -> > FOREIGN KEY INSERT & UPDATE/DELETE in transaction "change violation" -> -> A well known issue, and I've asked multiple times how exactly -> we want to define the behaviour for deferred constraints. Do -> foreign keys reference just to a key value and are happy with -> it's existance, or do they refer to a particular row? - -I think first. The last is closer to OODBMS world, not to [O]RDBMS one. - -> Consider you have a deferred "ON DELETE CASCADE" constraint -> and do a DELETE, INSERT of a PK. Do the FK rows need to be -> deleted or not? - -Good example. I think FK should not be deleted. If someone really -want to delete "old" FK then he can do - -DELETE PK; -SET CONSTRAINT ... IMMEDIATE; -- FK need to be deleted here -INSERT PK; - -> Consider you have a deferred "ON DELETE RESTRICT" and "ON -> UPDATE CASCADE" constraint. If you DELETE PK1 and UPDATE PK2 -> to PK1, the FK2 rows need to follow, but does PK2 inherit all -> FK1 rows now so it's the master of both groups? - -Yes. Again one can use SET CONSTRAINT to achieve desirable results. -It seems that SET CONSTRAINT was designed for these purposes - ie -for better flexibility. - -Though, it would be better to look how other DBes handle all these -cases -:) - -Vadim - -From janwieck@yahoo.com Fri Jan 26 12:20:27 2001 -Received: from smtp6.mail.yahoo.com (smtp6.mail.yahoo.com [128.11.69.103]) - by candle.pha.pa.us (8.9.0/8.9.0) with SMTP id MAA22158 - for ; Fri, 26 Jan 2001 12:20:27 -0500 (EST) -Received: from j13.us.greatbridge.com (HELO jupiter.greatbridge.com) (216.54.52.153) - by smtp.mail.vip.suc.yahoo.com with SMTP; 26 Jan 2001 17:20:26 -0000 -X-Apparently-From: -Received: (from janwieck@localhost) - by jupiter.greatbridge.com (8.9.3/8.9.3) id MAA03196; - Fri, 26 Jan 2001 12:30:05 -0500 -From: Jan Wieck -Message-Id: <200101261730.MAA03196@jupiter.greatbridge.com> -Subject: Re: [HACKERS] Open 7.1 items -To: PostgreSQL HACKERS , - Bruce Momjian -Date: Fri, 26 Jan 2001 12:30:05 -0500 (EST) -X-Mailer: ELM [version 2.4ME+ PL68 (25)] -MIME-Version: 1.0 -Content-Type: text/plain; charset=US-ASCII -Content-Transfer-Encoding: 7bit -Status: RO - -Bruce Momjian wrote: -> Here are my open 7.1 items. Thanks for shrinking the list so far. -> -> --------------------------------------------------------------------------- -> -> FreeBSD locale bug -> Reorder INSERT firing in rules - - I don't recall why this is wanted. AFAIK there's no reason - NOT to do so, except for the actual state of beeing far too - close to a release candidate. - -> Philip Warner UPDATE crash -> JDBC LargeObject short read return value missing -> SELECT cash_out(1) crashes all backends -> LAZY VACUUM -> FOREIGN KEY INSERT & UPDATE/DELETE in transaction "change violation" - - A well known issue, and I've asked multiple times how exactly - we want to define the behaviour for deferred constraints. Do - foreign keys reference just to a key value and are happy with - it's existance, or do they refer to a particular row? - - Consider you have a deferred "ON DELETE CASCADE" constraint - and do a DELETE, INSERT of a PK. Do the FK rows need to be - deleted or not? - - Consider you have a deferred "ON DELETE RESTRICT" and "ON - UPDATE CASCADE" constraint. If you DELETE PK1 and UPDATE PK2 - to PK1, the FK2 rows need to follow, but does PK2 inherit all - FK1 rows now so it's the master of both groups? - - These are only two possible combinations. There are many to - think of. As said, I've asked before, but noone voted yet. - Move the item to 7.2 anyway, because changing this behaviour - would require massive changes in the trigger queue *and* the - generic RI triggers, which cannot be tested enough any more. - - -Jan - -> Usernames limited in length -> Does pg_dump preserve COMMENTs? -> Failure of nested cursors in JDBC -> JDBC setMaxRows() is global variable affecting other objects -> Does JDBC Makefile need current dir? -> Fix for pg_dump of bad system tables -> Steve Howe failure query with rules -> ODBC/JDBC not disconnecting properly? -> Magnus Hagander ODBC issues? -> Merge MySQL/PgSQL translation scripts -> Fix ipcclean on Linux -> Merge global and template BKI files? -> -> -> -- -> Bruce Momjian | http://candle.pha.pa.us -> pgman@candle.pha.pa.us | (610) 853-3000 -> + If your life is a hard drive, | 830 Blythe Avenue -> + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 -> - - --- - -#======================================================================# -# It's easier to get forgiveness for being wrong than for being right. # -# Let's break this rule - forgive me. # -#================================================== JanWieck@Yahoo.com # - - -_________________________________________________________ -Do You Yahoo!? -Get your free @yahoo.com address at http://mail.yahoo.com - - -From pgsql-general-owner+M590@postgresql.org Tue Nov 14 16:30:40 2000 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id RAA22313 - for ; Tue, 14 Nov 2000 17:30:39 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id eAEMSJs66979; - Tue, 14 Nov 2000 17:28:21 -0500 (EST) - (envelope-from pgsql-general-owner+M590@postgresql.org) -Received: from megazone23.bigpanda.com (138.210.6.64.reflexcom.com [64.6.210.138]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id eAEMREs66800 - for ; Tue, 14 Nov 2000 17:27:14 -0500 (EST) - (envelope-from sszabo@megazone23.bigpanda.com) -Received: from localhost (sszabo@localhost) - by megazone23.bigpanda.com (8.11.1/8.11.0) with ESMTP id eAEMPpH69059; - Tue, 14 Nov 2000 14:25:51 -0800 (PST) -Date: Tue, 14 Nov 2000 14:25:51 -0800 (PST) -From: Stephan Szabo -To: "Beth K. Gatewood" -cc: pgsql-general@postgresql.org -Subject: Re: [GENERAL] a request for some experienced input..... -In-Reply-To: <3A11ACA1.E5D847DD@mbt.washington.edu> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-general-owner@postgresql.org -Status: OR - - -On Tue, 14 Nov 2000, Beth K. Gatewood wrote: - -> > -> -> Stephan- -> -> Thank you so much for taking the effort to answer this these questions. You -> help is truly appreciated.... -> -> I just have a few points for clarification. -> -> > -> > MATCH PARTIAL is a specific match type which describes which rows are -> > considered matching rows for purposes of meeting or failing the -> > constraint. (In match partial, a fktable (NULL, 2) would match a pk -> > table (1,2) as well as a pk table (2,2). It's different from match -> > full in which case (NULL,2) would be invalid or match unspecified -> > in which case it would match due to the existance of the NULL in any -> > case). There are some bizarre implementation details involved with -> > it and it's different from the others in ways that make it difficult. -> > It's in my list of things to do, but I haven't come up with an acceptable -> > mechanism in my head yet. -> -> Does this mean, currently that I can not have foreign keys with null values? - -Not exactly... - -Match full = In FK row, all columns must be NULL or the value of each - column must not be null and there is a row in the PK table where - each referencing column equals the corresponding referenced - column. - -Unspecified = In FK row, at least one column must be NULL or each - referencing column shall be equal to the corresponding referenced - column in some row of the referenced table - -Match partial is similar to match full except we ignore the null columns - for purposes of the each referencing column equals bit. - -For example: - PK Table Key values: (1,2), (1,3), (3,3) - Attempted FK Table Key values: (1,2), (1,NULL), (5,NULL), (NULL, NULL) - (hopefully I get this right)... - In match full, only the 1st and 4th fk values are valid. - In match partial, the 1st, 2nd, and 4th fk values are valid. - In match unspecified, all the fk values are valid. - -The other note is that generally speaking, all three are basically the -same for the single column key. If you're only doing references on one -column, the match type is mostly meaningless. - -> > PENDANT adds that for each row of the referenced table the values of -> > the specified column(s) are the same as the values of the specified -> > column(s) in some row of the referencing tables. -> -> I am not sure I know what you mean here.....Are you saying that the value for -> the FK column must match the value for the PK column? - -I haven't really looked at PENDANT, the above was just a small rewrite of -some descriptive text in the sql99 draft I have. There's a whole bunch -of rules in the actual text of the referential constraint definition. - -The base stuff seems to be: (Rf is the referencing columns, T is the -referenced table) - - 3) If PENDANT is specified, then: - a) For a given row in the referencing table, let pendant - reference designate an instance in which all Rf are - non-null. - - b) Let number of pendant paths be the number of pendant - references to the same referenced row in a referenced table - from all referencing rows in all base tables. - - c) For every row in T, the number of pendant paths is equal to - or greater than 1. - -So, I'd read it as every row in T must have at least one referencing row -in some base table. - -There are some details about updates and that you can't mix PENDANT and -MATCH PARTIAL or SET DEFAULT actions. - -> > The main issues in 7.0 are that older versions (might be fixed in -> > 7.0.3) would fail very badly if you used alter table to rename tables that -> > were referenced in a fk constraint and that you need to give update -> > permission to the referenced table. For the former, 7.1 will (and 7.0.3 -> > may) give an elog(ERROR) to you rather than crashing the backend and the -> > latter should be fixed for 7.1 (although you still need to have write -> > perms to the referencing table for referential actions to work properly) -> -> Are the steps to this outlined somewhere then? - -The permissions stuff is just a matter of using GRANT and REVOKE to set -the permissions that a user has to a table. - - diff --git a/doc/TODO.detail/fsync b/doc/TODO.detail/fsync deleted file mode 100644 index 6163dc4319..0000000000 --- a/doc/TODO.detail/fsync +++ /dev/null @@ -1,129 +0,0 @@ -From pgsql-hackers-owner+M908@postgresql.org Sun Nov 19 14:27:43 2000 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id OAA10885 - for ; Sun, 19 Nov 2000 14:27:42 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id eAJJSMs83653; - Sun, 19 Nov 2000 14:28:22 -0500 (EST) - (envelope-from pgsql-hackers-owner+M908@postgresql.org) -Received: from candle.pha.pa.us (candle.navpoint.com [162.33.245.46] (may be forged)) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id eAJJQns83565 - for ; Sun, 19 Nov 2000 14:26:49 -0500 (EST) - (envelope-from pgman@candle.pha.pa.us) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.9.0/8.9.0) id OAA06790; - Sun, 19 Nov 2000 14:23:06 -0500 (EST) -From: Bruce Momjian -Message-Id: <200011191923.OAA06790@candle.pha.pa.us> -Subject: Re: [HACKERS] WAL fsync scheduling -In-Reply-To: <002101c0525e$2d964480$b97a30d0@sectorbase.com> "from Vadim Mikheev - at Nov 19, 2000 11:23:19 am" -To: Vadim Mikheev -Date: Sun, 19 Nov 2000 14:23:06 -0500 (EST) -CC: Tom Samplonius , Alfred@candle.pha.pa.us, - Perlstein , Larry@candle.pha.pa.us, - Rosenman , - PostgreSQL-development -X-Mailer: ELM [version 2.4ME+ PL77 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -[ Charset ISO-8859-1 unsupported, converting... ] -> > There are two parts to transaction commit. The first is writing all -> > dirty buffers or log changes to the kernel, and second is fsync of the -> ^^^^^^^^^^^^ -> Backend doesn't write any dirty buffer to the kernel at commit time. - -Yes, I suspected that. - -> -> > log file. -> -> The first part is writing commit record into WAL buffers in shmem. -> This is what XLogInsert does. After that XLogFlush is called to ensure -> that entire commit record is on disk. XLogFlush does *both* write() and -> fsync() (single slock is used for both writing and fsyncing) if it needs to -> do it at all. - -Yes, I realize there are new steps in WAL. - -> -> > I suggest having a per-backend shared memory byte that has the following -> > values: -> > -> > START_LOG_WRITE -> > WAIT_ON_FSYNC -> > NOT_IN_COMMIT -> > backend_number_doing_fsync -> > -> > I suggest that when each backend starts a commit, it sets its byte to -> > START_LOG_WRITE. -> ^^^^^^^^^^^^^^^^^^^^^^^ -> Isn't START_COMMIT more meaningful? - -Yes. - -> -> > When it gets ready to fsync, it checks all backends. -> ^^^^^^^^^^^^^^^^^^^^^^^^^^ -> What do you mean by this? The moment just after XLogInsert? - -Just before it calls fsync(). - -> -> > If all are NOT_IN_COMMIT, it does fsync and continues. -> -> 1st edition: -> > If one or more are in START_LOG_WRITE, it waits until no one is in -> > START_LOG_WRITE. It then checks all WAIT_ON_FSYNC, and if it is the -> > lowest backend in WAIT_ON_FSYNC, marks all others with its backend -> > number, and does fsync. It then clears all backends with its number to -> > NOT_IN_COMMIT. Other backend will see they are not the lowest -> > WAIT_ON_FSYNC and will wait for their byte to be set to NOT_IN_COMMIT -> > so they can then continue, knowing their data was synced. -> -> 2nd edition: -> > I have another idea. If a backend gets to the point that it needs -> > fsync, and there is another backend in START_LOG_WRITE, it can go to an -> > interuptable sleep, knowing another backend will perform the fsync and -> > wake it up. Therefore, there is no busy-wait or timed sleep. -> > -> > Of course, a backend must set its status to WAIT_ON_FSYNC to avoid a -> > race condition. -> -> The 2nd edition is much better. But I'm not sure do we really need in -> these per-backend bytes in shmem. Why not just have some counters? -> We can use a semaphore to wake-up all waiters at once. - -Yes, that is much better and clearer. My idea was just to say, "if no -one is entering commit phase, do the commit. If someone else is coming, -sleep and wait for them to do the fsync and wake me up with a singal." - -> -> > This allows a single backend not to sleep, and allows multiple backends -> > to bunch up only when they are all about to commit. -> > -> > The reason backend numbers are written is so other backends entering the -> > commit code will not interfere with the backends performing fsync. -> -> Being waked-up backend can check what's written/fsynced by calling XLogFlush. - -Seems that may not be needed anymore with a counter. The only issue is -that other backends may enter commit while fsync() is happening. The -process that did the fsync must be sure to wake up only the backends -that were waiting for it, and not other backends that may be also be -doing fsync as a group while the first fsync was happening. I leave -those details to people more experienced. :-) - -I am just glad people liked my idea. - --- - Bruce Momjian | http://candle.pha.pa.us - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - diff --git a/doc/TODO.detail/inheritance b/doc/TODO.detail/inheritance deleted file mode 100644 index b3112d6077..0000000000 --- a/doc/TODO.detail/inheritance +++ /dev/null @@ -1,1111 +0,0 @@ -From owner-pgsql-hackers@hub.org Tue Jun 1 22:31:18 1999 -Received: from renoir.op.net (root@renoir.op.net [209.152.193.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id WAA09988 - for ; Tue, 1 Jun 1999 22:31:17 -0400 (EDT) -Received: from hub.org (hub.org [209.167.229.1]) by renoir.op.net (o1/$ Revision: 1.18 $) with ESMTP id WAA18944 for ; Tue, 1 Jun 1999 22:08:09 -0400 (EDT) -Received: from hub.org (hub.org [209.167.229.1]) - by hub.org (8.9.3/8.9.3) with ESMTP id WAA75604; - Tue, 1 Jun 1999 22:01:31 -0400 (EDT) - (envelope-from owner-pgsql-hackers@hub.org) -Received: by hub.org (TLB v0.10a (1.23 tibbs 1997/01/09 00:29:32)); Tue, 01 Jun 1999 22:01:11 +0000 (EDT) -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id WAA75519 - for pgsql-hackers-outgoing; Tue, 1 Jun 1999 22:01:09 -0400 (EDT) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -X-Authentication-Warning: hub.org: majordom set sender to owner-pgsql-hackers@postgreSQL.org using -f -Received: from localhost.localdomain (h246.ozemail2.ozemail.com.au [203.108.14.246]) - by hub.org (8.9.3/8.9.3) with ESMTP id WAA75452 - for ; Tue, 1 Jun 1999 22:00:50 -0400 (EDT) - (envelope-from chris.bitmead@bigfoot.com) -Received: from bigfoot.com (localhost [127.0.0.1]) - by localhost.localdomain (8.8.7/8.8.7) with ESMTP id KAA04059 - for ; Wed, 2 Jun 1999 10:50:11 +1000 -Message-ID: <37547FC3.40106A5E@bigfoot.com> -Date: Wed, 02 Jun 1999 10:50:11 +1000 -From: Chris Bitmead -X-Mailer: Mozilla 4.6 [en] (X11; I; Linux 2.2.6 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: pgsql-hackers@hub.org -Subject: Re: [HACKERS] ALTER TABLE ADD COLUMN -References: <199906011436.KAA23479@candle.pha.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Sender: owner-pgsql-hackers@postgreSQL.org -Precedence: bulk -Status: RO - -Bruce Momjian wrote: - -> Our TODO now has: -> -> * ALTER TABLE ADD COLUMN to inherited table put column in wrong place -> -> I don't think any of us understand the issues on this one. - -Let me guess at the problem. When you add a column, it doesn't change -all the records, therefore the column must be added at the end. This -means that the columns will not be in the same order as if you had -created them from scratch. - -There seem to be three solutions: -a) Go to a much more sophisticated schema system, with versions and -version numbers (fairly hard but desirable to fix other schema change -problems). Then insert the column in the position it is supposed to be -in. - -b) Fix the copy command to input and output the columns, not in the -order they are in, but in the order they would be in on re-creation. - -c) make the copy command take arguments specifying the field names, like -INSERT can do. - -I think it would be good if Postgres had all 3 features. Probably (b) is -the least work. - - -From owner-pgsql-general@hub.org Fri Jul 9 04:01:16 1999 -Received: from renoir.op.net (root@renoir.op.net [209.152.193.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id EAA22565 - for ; Fri, 9 Jul 1999 04:01:15 -0400 (EDT) -Received: from hub.org (hub.org [209.167.229.1]) by renoir.op.net (o1/$ Revision: 1.18 $) with ESMTP id DAA10238 for ; Fri, 9 Jul 1999 03:56:46 -0400 (EDT) -Received: from hub.org (hub.org [209.167.229.1]) - by hub.org (8.9.3/8.9.3) with ESMTP id DAA79895; - Fri, 9 Jul 1999 03:53:13 -0400 (EDT) - (envelope-from owner-pgsql-general@hub.org) -Received: by hub.org (TLB v0.10a (1.23 tibbs 1997/01/09 00:29:32)); Fri, 09 Jul 1999 03:47:45 +0000 (EDT) -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id DAA79076 - for pgsql-general-outgoing; Fri, 9 Jul 1999 03:47:43 -0400 (EDT) - (envelope-from owner-pgsql-general@postgreSQL.org) -X-Authentication-Warning: hub.org: majordom set sender to owner-pgsql-general@postgreSQL.org using -f -Received: from ns.idianet.net ([195.154.201.1]) - by hub.org (8.9.3/8.9.3) with ESMTP id DAA79054 - for ; Fri, 9 Jul 1999 03:47:37 -0400 (EDT) - (envelope-from haj@idianet.net) -Received: from kosovo (ppp150-paris2.isdnet.net [194.149.182.150]) - by ns.idianet.net (8.9.1/8.9.1) with SMTP id JAA08143; - Fri, 9 Jul 1999 09:43:35 +0200 (CEST) -Message-ID: <000c01bec9df$3704bd20$0601a8c0@kosovo.idianet.net> -Reply-To: "Jonathan davis" -From: "Jonathan davis" -To: "Bruce Momjian" -Cc: "Pgsql-General@Postgresql. Org" -Subject: Re: [GENERAL] just little BUG -Date: Fri, 9 Jul 1999 09:46:42 +0200 -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook Express 4.72.3110.5 -X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.3 -Sender: owner-pgsql-general@postgreSQL.org -Precedence: bulk -Status: ROr - - - ->[Charset iso-8859-1 unsupported, filtering to ASCII...] ->> hello all ->> ->> normaly a UNIQUE PRIMARY KEY is unique but ->> when you use a heritage, you can insert a duplicate key !!!! -> ->I assume you mean inheritance. -> ->Can you send us a little test sample please? -> ->-- -hello all - -this is the problem: - -example: - -test=> CREATE TABLE MAN(name char(10) UNIQUE PRIMARY KEY);T - -test=> CREATE TABLE PROFESSOR(scool char(20))INHERITS(MAN); - -test=> INSERT INTO PROFESSOR(name) VALUES('DAVIS'); -INSERT 54424 1 - -test=> INSERT INTO PROFESSOR(name) VALUES('DAVIS'); -INSERT 54425 1 - - - - - - - - - -From owner-pgsql-hackers@hub.org Tue Apr 20 10:34:34 1999 -Received: from hub.org (hub.org [209.47.145.100]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id KAA28480 - for ; Tue, 20 Apr 1999 10:34:31 -0400 (EDT) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.1) with SMTP id KAA12281; - Tue, 20 Apr 1999 10:33:22 -0400 (EDT) - (envelope-from owner-pgsql-hackers@hub.org) -Received: by hub.org (TLB v0.10a (1.23 tibbs 1997/01/09 00:29:32)); Tue, 20 Apr 1999 10:32:04 +0000 (EDT) -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.1) id KAA11432 - for pgsql-hackers-outgoing; Tue, 20 Apr 1999 10:32:01 -0400 (EDT) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from tech.com.au (IDENT:root@techpt.lnk.telstra.net [139.130.75.122]) - by hub.org (8.9.3/8.9.1) with ESMTP id KAA11378 - for ; Tue, 20 Apr 1999 10:31:52 -0400 (EDT) - (envelope-from chris.bitmead@bigfoot.com) -Received: from bigfoot.com (chris@localhost [127.0.0.1]) - by tech.com.au (8.8.7/8.8.7) with ESMTP id AAA21255 - for ; Wed, 21 Apr 1999 00:31:32 +1000 -Message-ID: <371C8FC3.4804CF87@bigfoot.com> -Date: Tue, 20 Apr 1999 14:31:31 +0000 -From: Chris Bitmead -X-Mailer: Mozilla 4.51 [en] (X11; I; Linux 2.0.36 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: hackers@postgreSQL.org -Subject: Re: [HACKERS] Heads up: does RULES regress test still work for you? -References: <199904151054.UAA07367@tech.com.au> <3715C69E.AE517ADB@bigfoot.com> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Sender: owner-pgsql-hackers@postgreSQL.org -Precedence: bulk -Status: RO - - -Does the following indicate a bug? It sure is wierd. Maybe some of these -statements aren't supported by postgresql (??), but the outcome doesn't -make sense to me. - -httpd=> CREATE TABLE x (y text); -CREATE -httpd=> CREATE VIEW z AS select * from x; -CREATE -httpd=> CREATE TABLE a (b text) INHERITS(z); -CREATE -httpd=> INSERT INTO x VALUES ('foo'); -INSERT 168602 1 -httpd=> select * from z*; -y ---- -foo -foo -(2 rows) - -How did we suddenly get two rows?? - --- -Chris Bitmead -http://www.bigfoot.com/~chris.bitmead -mailto:chris.bitmead@bigfoot.com - - -From owner-pgsql-hackers@hub.org Tue May 25 11:01:16 1999 -Received: from renoir.op.net (root@renoir.op.net [209.152.193.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id LAA15867 - for ; Tue, 25 May 1999 11:01:16 -0400 (EDT) -Received: from hub.org (hub.org [209.167.229.1]) by renoir.op.net (o1/$ Revision: 1.18 $) with ESMTP id KAA10712 for ; Tue, 25 May 1999 10:55:17 -0400 (EDT) -Received: from hub.org (hub.org [209.167.229.1]) - by hub.org (8.9.3/8.9.3) with ESMTP id KAA07206; - Tue, 25 May 1999 10:45:50 -0400 (EDT) - (envelope-from owner-pgsql-hackers@hub.org) -Received: by hub.org (TLB v0.10a (1.23 tibbs 1997/01/09 00:29:32)); Tue, 25 May 1999 10:43:02 +0000 (EDT) -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id KAA06706 - for pgsql-hackers-outgoing; Tue, 25 May 1999 10:43:01 -0400 (EDT) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -X-Authentication-Warning: hub.org: majordom set sender to owner-pgsql-hackers@postgreSQL.org using -f -Received: from sss.sss.pgh.pa.us (sss.pgh.pa.us [206.210.65.6]) - by hub.org (8.9.3/8.9.3) with ESMTP id KAA06690 - for ; Tue, 25 May 1999 10:42:57 -0400 (EDT) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss.sss.pgh.pa.us (localhost [127.0.0.1]) - by sss.sss.pgh.pa.us (8.9.1/8.9.1) with ESMTP id KAA02984 - for ; Tue, 25 May 1999 10:42:39 -0400 (EDT) -To: pgsql-hackers@postgreSQL.org -Subject: [HACKERS] INSERT INTO view means what exactly? -Date: Tue, 25 May 1999 10:42:39 -0400 -Message-ID: <2981.927643359@sss.pgh.pa.us> -From: Tom Lane -Sender: owner-pgsql-hackers@postgreSQL.org -Precedence: bulk -Status: ROr - -With current sources: - -regression=> CREATE TABLE x (y text); -CREATE -regression=> CREATE VIEW z AS select * from x; -CREATE -regression=> INSERT INTO x VALUES ('foo'); -INSERT 411635 1 -regression=> INSERT INTO z VALUES ('bar'); -INSERT 411636 1 -regression=> select * from x; -y ---- -foo -(1 row) - -regression=> select * from z; -y ---- -foo -(1 row) - -OK, where'd tuple 411636 go? Seems to me that the insert should either -have been rejected or caused an insert into x, depending on how -transparent you think views are (I always thought they were -read-only?). Dropping the data into never-never land and giving a -misleading success response code is not my idea of proper behavior. - - regards, tom lane - - -From owner-pgsql-hackers@hub.org Mon Jan 24 23:46:25 2000 -Received: from hub.org (hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id XAA25453 - for ; Mon, 24 Jan 2000 23:46:24 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id XAA81794; - Mon, 24 Jan 2000 23:01:22 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Mon, 24 Jan 2000 22:59:46 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id WAA80721 - for pgsql-hackers-outgoing; Mon, 24 Jan 2000 22:58:59 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.9.3/8.9.3) with ESMTP id WAA80619 - for ; Mon, 24 Jan 2000 22:58:33 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id WAA11576; - Mon, 24 Jan 2000 22:57:12 -0500 (EST) -To: Don Baccus -cc: "Hiroshi Inoue" , "Peter Eisentraut" , - "PostgreSQL Development" -Subject: Re: [HACKERS] Happy column dropping -In-reply-to: <3.0.1.32.20000124184137.01069490@mail.pacifier.com> -References: <001001bf66d7$b531ba00$2801007e@tpf.co.jp> <001001bf66d7$b531ba00$2801007e@tpf.co.jp> <3.0.1.32.20000124184137.01069490@mail.pacifier.com> -Comments: In-reply-to Don Baccus - message dated "Mon, 24 Jan 2000 18:41:37 -0800" -Date: Mon, 24 Jan 2000 22:57:12 -0500 -Message-ID: <11573.948772632@sss.pgh.pa.us> -From: Tom Lane -Sender: owner-pgsql-hackers@postgreSQL.org -Status: RO - -Don Baccus writes: -> Just a reality check for my learning of the internals. Out of curiousity -> I coincidently have spent the last hour looking to see how add column's -> implemented. It doesn't appear to do anything other than the new attribute -> to the proper system table. heap_getattr() just returns null if you ask -> for an attribute past the end of the tuple. - -> This would appear to be (at least one reason) why you can't add a "not null" -> constraint to a column you're adding to an existing relation, or set the -> new column to some non-null default value. - -> Correct? (again, to see if my eyeballs and brain are working in synch -> tonight) - -Yup, that's about the size of it. ADD COLUMN doesn't actually touch the -table itself, so it can only add a column that's initially all NULLs. -And even this depends on some uncomfortable assumptions about the -robustness of heap_getattr(). I have always wondered whether it works -if you ADD COLUMN a 33'rd column (or anything that is just past the -next padding boundary for the null-values bitmap). - -Another problem with it is seen when you do a recursive ADD COLUMN in -an inheritance tree. The added column has the first free column number -in each table, which generally means that it has different numbers in -the children than in the parent. There are some kluges to make this -sort-of-work for simple cases, but a lot of stuff fails unpleasantly ---- Chris Bitmead can show you some scars from that, IIRC. - -> Does your comment imply that it's planned to change this, i.e. actually -> add the new column to each tuple in the relation rather than use the -> existing, somewhat elegant hack? - -That's what I would like to see: all the children should have the -same column numbers for all columns that they inherit from the parent. - -(Now, this would mean not only physically altering the tuples of -the children, but also renumbering their added columns, which has -implications on stored rules and triggers and so forth. It'd be -painful, no doubt about it. Still, I'd rather pay the price in the -seldom-used ADD COLUMN case than try to deal with out-of-sync column -numbers in many other, more commonly exercised, code paths.) - - regards, tom lane - -************ - -From owner-pgsql-hackers@hub.org Tue Jan 25 18:34:14 2000 -Received: from hub.org (hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id TAA04935 - for ; Tue, 25 Jan 2000 19:34:13 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id TAA31870; - Tue, 25 Jan 2000 19:22:44 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Tue, 25 Jan 2000 19:21:06 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id TAA31364 - for pgsql-hackers-outgoing; Tue, 25 Jan 2000 19:20:07 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from hu.tm.ee (ppp809.tele2.ee [212.107.37.109]) - by hub.org (8.9.3/8.9.3) with ESMTP id TAA31158 - for ; Tue, 25 Jan 2000 19:19:04 -0500 (EST) - (envelope-from hannu@tm.ee) -Received: from tm.ee (localhost [127.0.0.1]) - by hu.tm.ee (Postfix) with ESMTP - id 46B6213469; Wed, 26 Jan 2000 02:25:13 +0200 (EET) -Message-ID: <388E3EE9.46880647@tm.ee> -Date: Wed, 26 Jan 2000 02:25:13 +0200 -From: Hannu Krosing -Organization: Trust-O-Matic =?iso-8859-1?Q?O=DC?= -X-Mailer: Mozilla 4.7 [en] (X11; I; Linux 2.2.13-7mdk i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Don Baccus -Cc: Tom Lane , - "Ross J. Reedstrom" , - PostgreSQL Development -Subject: Re: Happy column adding (was RE: [HACKERS] Happy columndropping) -References: <3.0.1.32.20000125113001.00f8acb0@mail.pacifier.com> - <20000125114453.E423@rice.edu> - <001401bf6704$5ca7e3a0$2801007e@tpf.co.jp> - - <3.0.1.32.20000125080125.00f7f160@mail.pacifier.com> - <20000125114453.E423@rice.edu> - <3.0.1.32.20000125113001.00f8acb0@mail.pacifier.com> <3.0.1.32.20000125151022.00f8c4c0@mail.pacifier.com> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Sender: owner-pgsql-hackers@postgreSQL.org -Status: OR - -Don Baccus wrote: -> -> Ahhh...yes. I haven't looked at the inheritance code, yet, but I see -> what you're saying. I think. Do child-table columns follow parent-table -> columns by some chance (in today's absolute column number scheme)? -> -> >If we were willing to hardwire the assumption that DROP COLUMN never -> >physically drops a column, but only hides it and adjusts logical column -> >numbers, then the physical column numbers could serve as permanent IDs; -> >so we'd only need two numbers not three. This might be good, or not. -> -> Yes. But if I'm right about how child-table columns are numbered, -> wouldn't add column still cause a problem, i.e. you'd still have to -> change their physical column number? - -If we allow deleted column as a basic feature of postgres, -it could be like that - -base: COL1 | COL2 | COL3 -child: COL1 | COL2 | COL3 | COL4 - -after add column 5 to base table - -base: COL1 | COL2 | COL3 | del4 | COL5 -child: COL1 | COL2 | COL3 | COL4 | COL5 - -after add column 6 to child - -base: COL1 | COL2 | COL3 | del4 | COL5 -child: COL1 | COL2 | COL3 | COL4 | COL5 | COL6 - -after drop column 2 from base table - -base: COL1 | del2 | COL3 | del4 | COL5 -child: COL1 | del2 | COL3 | COL4 | COL5 | COL6 - -dropping column from child table that is not a deleted column in -parent is not allowed. - -The delN columns are always NULLed on reading tuple and are written as proper -null columns (taking up space only in NULL bitmask) - -multiple inheritance is tricky and _requires_ unique column ids maybe oids -from pg_attribute to be doable. - ------------------ -Hannu - -************ - -From owner-pgsql-hackers@hub.org Thu Jan 27 11:48:26 2000 -Received: from hub.org (hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id MAA25953 - for ; Thu, 27 Jan 2000 12:48:25 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id MAA22723; - Thu, 27 Jan 2000 12:39:27 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Thu, 27 Jan 2000 12:36:16 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id MAA22021 - for pgsql-hackers-outgoing; Thu, 27 Jan 2000 12:35:23 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from merganser.its.uu.se (merganser.its.uu.se [130.238.6.236]) - by hub.org (8.9.3/8.9.3) with ESMTP id MAA21886 - for ; Thu, 27 Jan 2000 12:34:47 -0500 (EST) - (envelope-from peter@localhost.its.uu.se) -Received: from regulus.its.uu.se ([130.238.7.19]:61911 "EHLO regulus.its.uu.se") - by merganser.its.uu.se with ESMTP id ; - Thu, 27 Jan 2000 18:34:06 +0100 -Received: from peter (helo=localhost) - by regulus.its.uu.se with local-esmtp (Exim 3.02 #2) - id 12DsvR-0000HH-00; Thu, 27 Jan 2000 18:41:45 +0100 -Date: Thu, 27 Jan 2000 18:41:45 +0100 (CET) -From: Peter Eisentraut -To: Tom Lane -cc: PostgreSQL Development -Subject: Re: [HACKERS] Column ADDing issues -In-Reply-To: <15550.948845404@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=ISO-8859-1 -Content-Transfer-Encoding: 8BIT -Sender: owner-pgsql-hackers@postgreSQL.org -Status: ORr - -On 2000-01-25, Tom Lane mentioned: - -> > Everything has its order and it's not like the inheritance as such is -> > broken. -> -> Yes, a whole bunch of stuff is broken after this happens. Go back and -> consult the archives --- or maybe Chris Bitmead will fill you in; he's -> got plenty of scars to show for this set of problems. (All I recall -> offhand is that pg_dump and reload can fail to generate a working -> database.) The bottom line is that it would be a lot nicer if column c -> had the same column position in both the parent table and the child -> table(s). - -This should be fixed in pg_dump by infering something via the oids of the -pg_attribute entries. No need to mess up the backend for it. - -Maybe pg_dump should optionally dump schemas in terms of insert into -pg_something commands rather than actual DDL. ;) - -> -> I suggest you be very cautious about messing with ALTER TABLE until you -> understand why inheritance makes it such a headache ;-) - -I'm just trying to get the defaults and constraints working. If -inheritance stays broken the way it previously was, it's beyond my -powers. But I get the feeling that people rather not alter their tables -unless they have *perfect* alter table commands. I don't feel like arguing -with them, they'll just have to do without then. - - --- -Peter Eisentraut Sernanders väg 10:115 -peter_e@gmx.net 75262 Uppsala -http://yi.org/peter-e/ Sweden - - - -************ - -From pgsql-general-owner+M2136@hub.org Sat Jun 3 23:31:02 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id WAA28683 - for ; Sat, 3 Jun 2000 22:31:01 -0400 (EDT) -Received: from news.tht.net (news.hub.org [216.126.91.242]) by renoir.op.net (o1/$Revision: 1.2 $) with ESMTP id WAA20977 for ; Sat, 3 Jun 2000 22:05:07 -0400 (EDT) -Received: from hub.org (majordom@hub.org [216.126.84.1]) - by news.tht.net (8.9.3/8.9.3) with ESMTP id VAD35811; - Sat, 3 Jun 2000 21:54:36 -0400 (EDT) - (envelope-from pgsql-general-owner+M2136@hub.org) -Received: from merganser.its.uu.se (merganser.its.uu.se [130.238.6.236]) - by hub.org (8.9.3/8.9.3) with ESMTP id VAA12118 - for ; Sat, 3 Jun 2000 21:41:27 -0400 (EDT) - (envelope-from peter@localhost.its.uu.se) -Received: from regulus.student.UU.SE ([130.238.5.2]:61160 "EHLO - regulus.its.uu.se") by merganser.its.uu.se with ESMTP - id ; Sun, 4 Jun 2000 03:41:02 +0200 -Received: from peter (helo=localhost) - by regulus.its.uu.se with local-esmtp (Exim 3.02 #2) - id 12yPV7-0002Tp-00; Sun, 04 Jun 2000 03:46:53 +0200 -Date: Sun, 4 Jun 2000 03:46:53 +0200 (CEST) -From: Peter Eisentraut -To: ldm@apartia.com -cc: pgsql-general@postgresql.org -Subject: Re: [GENERAL] child table doesn't inherit PRIMARY KEY? -In-Reply-To: <20000603172256.A3435@styx> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=ISO-8859-1 -Content-Transfer-Encoding: 8BIT -X-Mailing-List: pgsql-general@postgresql.org -Precedence: bulk -Sender: pgsql-general-owner@hub.org -Status: ORr - -Louis-David Mitterrand writes: - -> When creating a child (through CREATE TABLE ... INHERIT (parent)) it -> seems the child gets all of the parent's contraints _except_ its PRIMARY -> KEY. Is this normal? - -It's kind of a bug. - - --- -Peter Eisentraut Sernanders väg 10:115 -peter_e@gmx.net 75262 Uppsala -http://yi.org/peter-e/ Sweden - - -From sszabo@megazone23.bigpanda.com Fri Jan 19 12:37:34 2001 -Received: from megazone23.bigpanda.com (rfx-64-6-210-138.users.reflexcom.com [64.6.210.138]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id MAA28247 - for ; Fri, 19 Jan 2001 12:37:33 -0500 (EST) -Received: from localhost (sszabo@localhost) - by megazone23.bigpanda.com (8.11.1/8.11.1) with ESMTP id f0JHb2H05566; - Fri, 19 Jan 2001 09:37:03 -0800 (PST) -Date: Fri, 19 Jan 2001 09:37:02 -0800 (PST) -From: Stephan Szabo -To: Bruce Momjian -cc: pgsql-general@postgresql.org -Subject: Re: [GENERAL] child table doesn't inherit PRIMARY KEY? -In-Reply-To: <200101190457.XAA13895@candle.pha.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Status: OR - - -Probably, since I see it in near recent sources (and it affects -UNIQUE as well. As I remember it, the last discussion on this couldn't -determine what the correct behavior for unique/primary key constraints -was in the inheritance case (is it a single unique hierarchy through -all the tables [would be needed for fk to inheritance trees] or -separate unique constraints for each table [which would be similar -to how many people seem to currently use postgres inheritance as a -shortcut]). - -On Thu, 18 Jan 2001, Bruce Momjian wrote: - -> Does this bug still exist? -> -> [ Charset ISO-8859-1 unsupported, converting... ] -> > Louis-David Mitterrand writes: -> > -> > > When creating a child (through CREATE TABLE ... INHERIT (parent)) it -> > > seems the child gets all of the parent's contraints _except_ its PRIMARY -> > > KEY. Is this normal? - - -From sszabo@megazone23.bigpanda.com Wed Jan 24 14:26:12 2001 -Received: from megazone23.bigpanda.com (rfx-64-6-210-138.users.reflexcom.com [64.6.210.138]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id OAA26091 - for ; Wed, 24 Jan 2001 14:26:10 -0500 (EST) -Received: from localhost (sszabo@localhost) - by megazone23.bigpanda.com (8.11.1/8.11.1) with ESMTP id f0OJPZ858086; - Wed, 24 Jan 2001 11:25:35 -0800 (PST) -Date: Wed, 24 Jan 2001 11:25:35 -0800 (PST) -From: Stephan Szabo -To: Bruce Momjian -cc: PostgreSQL-development -Subject: Re: [GENERAL] child table doesn't inherit PRIMARY KEY? -In-Reply-To: <200101241344.IAA12094@candle.pha.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Status: ORr - -On Wed, 24 Jan 2001, Bruce Momjian wrote: - -> -> OK, what do people want to do with this item? Add to TODO list? -> -> Seems making a separat unique constraint would be easy to do and be of -> value to most users. - -The problem is that doing that will pretty much guarantee that we won't -be doing foreign keys to inheritance trees without changing that behavior -and we've seen people asking about adding that too. I think that this -falls into the general category of "Make inheritance make sense" (Now -there's a todo item :) ) Seriously, I think the work on how inheritance -is going to work will decide this, maybe we end up with a real inheritance -tree system and something that works like the current stuff in which case -I'd say it's probably one unique for the former and one per for the -latter. - - - - -From olly@lfix.co.uk Wed Jan 24 16:41:45 2001 -Received: from anchor-post-31.mail.demon.net (anchor-post-31.mail.demon.net [194.217.242.89]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id QAA05688 - for ; Wed, 24 Jan 2001 16:41:44 -0500 (EST) -Received: from lfix.demon.co.uk ([158.152.59.127] helo=linda.lfix.co.uk) - by anchor-post-31.mail.demon.net with esmtp (Exim 2.12 #1) - id 14LXfg-0007lc-0V; Wed, 24 Jan 2001 21:41:40 +0000 -Received: from lfix.co.uk (olly@localhost [127.0.0.1]) - by linda.lfix.co.uk (8.11.2/8.11.2/Debian 8.11.2-1) with ESMTP id f0OLfdF12876; - Wed, 24 Jan 2001 21:41:39 GMT -Message-Id: <200101242141.f0OLfdF12876@linda.lfix.co.uk> -X-Mailer: exmh version 2.2 06/23/2000 (debian 2.2-1) with nmh-1.0.4+dev -X-URL: http://www.lfix.co.uk/oliver -X-face: "xUFVDj+ZJtL_IbURmI}!~xAyPC"Mrk=MkAm&tPQnNq(FWxv49R}\>0oI8VM?O2VY+N7@F- - KMLl*!h}B)u@TW|B}6 -cc: Stephan Szabo , - PostgreSQL-development -Subject: Re: [HACKERS] Re: [GENERAL] child table doesn't inherit PRIMARY KEY? -In-reply-to: Message from Bruce Momjian - of Wed, 24 Jan 2001 14:31:29 EST. <200101241931.OAA26463@candle.pha.pa.us> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Date: Wed, 24 Jan 2001 21:41:39 +0000 -From: "Oliver Elphick" -Status: OR - -Bruce Momjian wrote: - >> On Wed, 24 Jan 2001, Bruce Momjian wrote: - - >I smell TODO item. In fact, I now see a TODO item: - > - >* Unique index on base column not honored on inserts from inherited table - > INSERT INTO inherit_table (unique_index_col) VALUES (dup) should fail - > [inherit] - > - >So it seems the fact the UNIQUE doesn't apply to the new table is just a - >manifestion of the fact that people expect UNIQUE to span the entire - >inheritance tree. I will add the emails to [inherit] and mark it as - >resolved. - -Bruce, could you add this text to TODO.detail on the subject of -inherited constraints. I first sent it on Christmas Eve, and I -think most people were too busy holidaying to comment. - -================================================================= -Tom Lane wrote: - >Hm. The short-term answer seems to be to modify the queries generated - >by the RI triggers to say "ONLY foo". I am not sure whether we - >understand the semantics involved in allowing a REFERENCES target to be - >taken as an inheritance tree rather than just one table, but certainly - >the current implementation won't handle that correctly. - -May I propose these semantics as a basis for future development: - -1. An inheritance hierarchy (starting at any point in a tree) should be -equivalent to an updatable view of all the tables at the point of -reference and below. By default, all descendant tables are combined -with the ancestor for all purposes. The keyword ONLY must be used to -alter this behaviour. Only inherited columns of descendant tables are -visible from higher in the tree. Columns may not be dropped in descendants. -If columns are added to ancestors, they must be inserted correctly in -descendants so as to preserve column ordering and inheritance. If -a column is dropped in an ancestor, it is dropped in all descendants. - -2. Insertion into a hierarchy means insertion into the table named in -the INSERT statement; updating or deletion affects whichever table(s) -the affected rows are found in. Updating cannot move a row from one -table to another. - -3. Inheritance of a table implies inheriting all its constraints unless -ONLY is used or the constraints are subsequently dropped; again, dropping -operates through all descendant tables. A primary key, foreign key or -unique constraint cannot be dropped or modified for a descendant. A -unique index on a column is shared by all tables below the table for -which it is declared. It cannot be dropped for any descendant. - -In other words, only NOT NULL and CHECK constraints can be dropped in -descendants. - -In multiple inheritance, a column may inherit multiple unique indices -from its several ancestors. All inherited constraints must be satisfied -together (though check constraints may be dropped). - -4. RI to a table implies the inclusion of all its descendants in the -check. Since a referenced column may be uniquely indexed further up -the hierarchy than in the table named, the check must ensure that -the referenced value occurs in the right segment of the hierarchy. RI -to one particular level of the hierarchy, excluding descendants, requires -the use of ONLY in the constraint. - -5. Dropping a table implies dropping all its descendants. - -6. Changes of permissions on a table propagate to all its descendants. -Permissions on descendants may be looser than those on ancestors; they -may not be more restrictive. - - -This scheme is a lot more restrictive than C++'s or Eiffel's definition -of inheritance, but it seems to me to make the concept truly useful, -without introducing excessive complexity. - -============================================================ - --- -Oliver Elphick Oliver.Elphick@lfix.co.uk -Isle of Wight http://www.lfix.co.uk/oliver -PGP: 1024R/32B8FAA1: 97 EA 1D 47 72 3F 28 47 6B 7E 39 CC 56 E4 C1 47 -GPG: 1024D/3E1D0C1C: CA12 09E0 E8D5 8870 5839 932A 614D 4C34 3E1D 0C1C - ======================================== - "If anyone has material possessions and sees his - brother in need but has no pity on him, how can the - love of God be in him?" - I John 3:17 - - - -From pgsql-hackers-owner+M9621@postgresql.org Mon Jun 4 21:53:36 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f551rac27536 - for ; Mon, 4 Jun 2001 21:53:36 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f551prE11747; - Mon, 4 Jun 2001 21:51:53 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9621@postgresql.org) -Received: from mail-smtp01.one.net.au (mail-smtp01.one.net.au [61.12.0.171]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f551h5E09330 - for ; Mon, 4 Jun 2001 21:43:05 -0400 (EDT) - (envelope-from chriskl@familyhealth.com.au) -Received: (qmail 20200 invoked from network); 5 Jun 2001 01:43:02 -0000 -Received: from unknown (HELO houston.familyhealth.com.au) (203.101.44.22) - by mail-smtp01.one.net.au with SMTP; 5 Jun 2001 01:43:02 -0000 -Received: from mariner (MARINER.internal [192.168.0.101]) - by houston.familyhealth.com.au (8.11.2/8.11.2) with SMTP id f551cke95391 - for ; Tue, 5 Jun 2001 09:38:47 +0800 (WST) - (envelope-from chriskl@familyhealth.com.au) -From: "Christopher Kings-Lynne" -To: "Hackers" -Subject: [HACKERS] Question about inheritance -Date: Tue, 5 Jun 2001 09:42:38 +0800 -Message-ID: -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2910.0) -X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200 -Importance: Normal -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Hi guys, - -It's relatively straightforward to allow check constraints to be inherited - -but is it really possible to ever do the same with primary, unique or even -foreign constraints? - -ie. Say a table has a primary key and I inherit from this table. Since the -primary key is an index on the parent table, I could just create another -index on the child table, on the same column. - -However - because we are dealing with two separate indices, it should still -be possible to insert duplicate values into the parent table and the child -table shouldn't it? This means that when a query is run over the parent -table that includes results from the child table then you will get duplicate -results in a supposedly primary index. - -Similar arguments seem to apply to unique and foreign constraints. If you -could use aggregate functions in check constraints - you'd have another -problem. And if asserts were ever implemented - same thing... - -Am I misunderstanding how the mechanism works, or is this a big, not easily -solved, problem? - -Chris - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://www.postgresql.org/search.mpl - -From pgsql-hackers-owner+M9623@postgresql.org Mon Jun 4 22:17:50 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f552Hnc29101 - for ; Mon, 4 Jun 2001 22:17:49 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f552GUE19667; - Mon, 4 Jun 2001 22:16:30 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9623@postgresql.org) -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f55281E16781 - for ; Mon, 4 Jun 2001 22:08:01 -0400 (EDT) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.3/8.11.3) with ESMTP id f5527gR11252; - Mon, 4 Jun 2001 22:07:42 -0400 (EDT) -To: "Christopher Kings-Lynne" -cc: "Hackers" -Subject: Re: [HACKERS] Question about inheritance -In-Reply-To: -References: -Comments: In-reply-to "Christopher Kings-Lynne" - message dated "Tue, 05 Jun 2001 09:42:38 +0800" -Date: Mon, 04 Jun 2001 22:07:42 -0400 -Message-ID: <11249.991706862@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -"Christopher Kings-Lynne" writes: -> Am I misunderstanding how the mechanism works, or is this a big, not easily -> solved, problem? - -The latter. Check the list archives for previous debates about this. -It's not real clear whether an inherited primary key should be expected -to be unique across the whole inheritance tree, or only unique per-table -(IIRC, plausible examples have been advanced for each case). If we want -uniqueness across multiple tables, it'll take considerable work to -create an index mechanism that'd enforce it. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M9664@postgresql.org Tue Jun 5 17:56:17 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f55LuHc05888 - for ; Tue, 5 Jun 2001 17:56:17 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f55LsqE25492; - Tue, 5 Jun 2001 17:54:52 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9664@postgresql.org) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f55JA9E52724 - for ; Tue, 5 Jun 2001 15:10:09 -0400 (EDT) - (envelope-from pgsql-hackers-owner@postgresql.org) -Received: from iolite.sge.net (iolite.sge.net [152.91.14.26]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f5539fE34561 - for ; Mon, 4 Jun 2001 23:09:41 -0400 (EDT) - (envelope-from chris.bitmead@health.gov.au) -Received: from cadmium.sge.net (cadmium.sge.net [152.91.9.5]) - by iolite.sge.net (Postfix) with ESMTP id D8401BF05 - for ; Tue, 5 Jun 2001 13:08:58 +1000 (EST) -Received: from kryptonite2.sge.net (kryptonite2.sge.net [10.1.2.20]) - by cadmium.sge.net (Postfix) with ESMTP id B0AD3C7902 - for ; Tue, 5 Jun 2001 13:08:58 +1000 (EST) -Received: from thorium2.sge.net (thorium2.sge.net [10.1.2.36]) - by kryptonite2.sge.net (Postfix) with SMTP id 4945E3CF05 - for ; Tue, 5 Jun 2001 13:08:58 +1000 (EST) -Received: FROM emerald.sge.net BY thorium2.sge.net ; Tue Jun 05 13:00:12 2001 +1000 -Received: from voggite.sge.net (voggite [163.127.224.126]) - by emerald.sge.net (Postfix) with ESMTP id 66A9AE3818 - for ; Tue, 5 Jun 2001 13:09:52 +1000 (EST) -Received: from mswcbr02.act.health.gov.au (mswcbr02.act.health.gov.au [163.127.224.137]) - by voggite.sge.net (Postfix) with ESMTP id E863AD0484 - for ; Tue, 5 Jun 2001 13:09:52 +1000 (EST) -Received: from mtascbr01.notes.health.gov.au (unverified) by mswcbr02.act.health.gov.au - (Content Technologies SMTPRS 2.0.15) with SMTP id for ; - Tue, 05 Jun 2001 13:18:48 +1000 -Received: by mtascbr01.notes.health.gov.au(Lotus SMTP MTA v4.6.6 (890.1 7-16-1999)) id CA256A62.0011CDDB ; Tue, 5 Jun 2001 13:14:28 +1000 -X-Lotus-FromDomain: HEALTH_GOV_AU -From: chris.bitmead@health.gov.au -Reply-To: chris.bitmead@health.gov.au -To: pgsql-hackers@postgresql.org -Message-ID: -Date: Tue, 5 Jun 2001 13:08:58 +1000 -Subject: Re: [HACKERS] Question about inheritance -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - - - ->It's relatively straightforward to allow check constraints to be inherited - ->but is it really possible to ever do the same with primary, unique or even ->foreign constraints? - -You would either have to check each index in the hierarchy or else have -a single index across the whole hierarchy and check that. Obviously the -latter would be generally more useful. - -As with all things inheritance, it is usually the right thing, and a good -default that things be inherited. So ideally, indexes should work across -whole hierarchies as well as primary, unique and foreign constraints. -It could be argued that not inheriting is of very limited usefulness. - - - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M9627@postgresql.org Mon Jun 4 23:58:36 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f553wac02588 - for ; Mon, 4 Jun 2001 23:58:36 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f553vAE48166; - Mon, 4 Jun 2001 23:57:10 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9627@postgresql.org) -Received: from megazone23.bigpanda.com ([216.136.151.41]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f553ksE45147 - for ; Mon, 4 Jun 2001 23:46:54 -0400 (EDT) - (envelope-from sszabo@megazone23.bigpanda.com) -Received: from localhost (sszabo@localhost) - by megazone23.bigpanda.com (8.11.2/8.11.2) with ESMTP id f553kYc07461; - Mon, 4 Jun 2001 20:46:38 -0700 (PDT) -Date: Mon, 4 Jun 2001 20:46:34 -0700 (PDT) -From: Stephan Szabo -To: Christopher Kings-Lynne -cc: Hackers -Subject: Re: [HACKERS] Question about inheritance -In-Reply-To: -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Tue, 5 Jun 2001, Christopher Kings-Lynne wrote: - -> Hi guys, -> -> It's relatively straightforward to allow check constraints to be inherited - -> but is it really possible to ever do the same with primary, unique or even -> foreign constraints? -> -> ie. Say a table has a primary key and I inherit from this table. Since the -> primary key is an index on the parent table, I could just create another -> index on the child table, on the same column. -> -> However - because we are dealing with two separate indices, it should still -> be possible to insert duplicate values into the parent table and the child -> table shouldn't it? This means that when a query is run over the parent -> table that includes results from the child table then you will get duplicate -> results in a supposedly primary index. -> -> Similar arguments seem to apply to unique and foreign constraints. If you -> could use aggregate functions in check constraints - you'd have another -> problem. And if asserts were ever implemented - same thing... -> -> Am I misunderstanding how the mechanism works, or is this a big, not easily -> solved, problem? - -It's a big deal. Actually check constraints have a similar problem if you -allow inherited constraints to be dropped. "Why does 'select * from -base;' give me rows where value<10 since there's a check value>=10 -on the table?" - -As Tom said, the unique constraint thing is still questionable which is -the more meaningful semantics. If we ever want to allow foreign key -constraints to inheritance trees, we need *some* way to guarantees -uniqueness across the tree even if that isn't through the unique -constraint. - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://www.postgresql.org/search.mpl - -From pgsql-hackers-owner+M9638@postgresql.org Tue Jun 5 06:30:37 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f55AUac21070 - for ; Tue, 5 Jun 2001 06:30:36 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f55AT9E31492; - Tue, 5 Jun 2001 06:29:09 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9638@postgresql.org) -Received: from ajax2.sovam.com (ajax2.sovam.com [194.67.1.173]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f55AJXE27449 - for ; Tue, 5 Jun 2001 06:19:33 -0400 (EDT) - (envelope-from dmitry@taurussoft.org) -Received: from pm14-a43.dial.sovam.com ([195.218.132.43]:1047 "HELO - taurussoft.org" ident: "TIMEDOUT2" whoson: "tttt@online.ru" smtp-auth: - TLS-CIPHER: TLS-PEER: ) by ajax2.sovam.com - with SMTP id ; Tue, 5 Jun 2001 14:19:15 +0400 -Received: (qmail 610 invoked from network); 5 Jun 2001 10:16:54 -0000 -Received: from flame-in-night.taurussoft.org (HELO flameinnight) (192.168.107.1) - by kitezh.taurussoft.org with SMTP; 5 Jun 2001 10:16:54 -0000 -Message-ID: <008901c0eda8$bc6fb520$016ba8c0@taurussoft.org> -From: "Dmitry G. Mastrukov" -To: -Subject: Re: [HACKERS] Question about inheritance -Date: Tue, 5 Jun 2001 14:17:33 +0400 -MIME-Version: 1.0 -Content-Type: text/plain; - charset="koi8-r" -Content-Transfer-Encoding: 7bit -X-Priority: 3 -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook Express 5.00.2615.200 -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2615.200 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - > "Christopher Kings-Lynne" writes: - > > Am I misunderstanding how the mechanism works, or is this a big, not - easily - > > solved, problem? - > - > The latter. Check the list archives for previous debates about this. - > It's not real clear whether an inherited primary key should be expected - > to be unique across the whole inheritance tree, or only unique per-table - > (IIRC, plausible examples have been advanced for each case). If we want - > uniqueness across multiple tables, it'll take considerable work to - > create an index mechanism that'd enforce it. - > - IMHO current behaviour of PostgreSQL with inherited PK, FK, UNIQUE is -simply - bug not only from object-oriented but even object-related point of view. -Now - I can violate parent PK by inserting duplicate key in child! - - Inherited tables should honours all constraints from parent. If I change - some constraint (seems only FK, but not PK or UNIQUE) I should be able to -do - it in more restrictive manner. For example, two base table is connected via - FK. I can change such FK in childs from base1->base2 to child1->child2 (or - child3) but not to child1->not_inherited_from_base2. CHECK, DEFAULT, NOT - NULL are more free to changes, isn't it? - - IMHO last message in doc/TODO.details/inheritance from Oliver Elphick is a - good direction for implementing with exception on more rectrictive child FK - constraint (p.3 of message). - - As for me, I was pushed to rollback to scheme with no inheritance at all in - my project for now. So I'm very interesting in implementing of right - inheritance and I wanted to ask similar question in one of the lists in -near - future. - - Regards, - Dmitry - - - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://www.postgresql.org/search.mpl - diff --git a/doc/TODO.detail/java b/doc/TODO.detail/java deleted file mode 100644 index 040321d157..0000000000 --- a/doc/TODO.detail/java +++ /dev/null @@ -1,2246 +0,0 @@ -From pgsql-hackers-owner+M4145@postgresql.org Sat Feb 3 05:54:06 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id FAA22302 - for ; Sat, 3 Feb 2001 05:54:04 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f13Ap4q95132; - Sat, 3 Feb 2001 05:51:04 -0500 (EST) - (envelope-from pgsql-hackers-owner+M4145@postgresql.org) -Received: from mail.retep.org.uk ([216.126.85.184]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id f13AnIq94863 - for ; Sat, 3 Feb 2001 05:49:18 -0500 (EST) - (envelope-from peter@retep.org.uk) -Received: from heather.retep.org.uk ([193.113.118.193]) - (authenticated) - by mail.retep.org.uk (8.11.1/8.11.1) with ESMTP id f13AlnO94823; - Sat, 3 Feb 2001 05:47:49 -0500 (EST) - (envelope-from peter@retep.org.uk) -Message-Id: <5.0.2.1.0.20010203103036.009efec0@mail.retep.org.uk> -X-Sender: peter@mail.retep.org.uk -X-Mailer: QUALCOMM Windows Eudora Version 5.0.2 -Date: Sat, 03 Feb 2001 10:46:24 +0000 -To: Alex Pilosov , tomasz konefal -From: Peter Mount -Subject: Re: [HACKERS] TODO list: Allow Java server-side programming -Cc: pgsql-hackers@postgresql.org -In-Reply-To: -References: <20010202194049.38902.qmail@web12003.mail.yahoo.com> -Mime-Version: 1.0 -Content-Type: text/plain; charset="us-ascii"; format=flowed -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -At 14:57 02/02/01 -0500, Alex Pilosov wrote: ->On Fri, 2 Feb 2001, tomasz konefal wrote: -> -> > could someone please clarify what "Allow Java -> > server-side programming" actually means? what are the -> > limitations of using java and jdbc with pgsql? -> ->It means to embed Java interpreter inside postgres, and allow writing ->stored procedures and triggers in Java. - -Thats correct. Basically you are talking of something like PL/Java. The -Java side would be simple, but its linking the JVM to the backend that's -the problem. - -It's been a while since I delved into the backend, but unless it's changed -from fork() to threading, I don't really see this happening, unless someone -who knows C that well knows of a portable way of communicating between two -processes - other than RMI. If that could be solved, then you could use JNI -to interface the JVM. - -I know some people think this would slow the backend down, but it's only -the instanciation of the JVM thats slow, hence the other reason fork() is -holding this back. Ideally you would want the JVM to be running with -PostMaster, and then each backend can then use the JVM as and when necessary. - -Obviously you wouldn't want a JVM in every installation, but there are a -lot of good reasons to have this capability. For example, as part of the -course I did this week, we used Tomcat (Servlet/JSP/Web server). Now -there's no reason why Tomcat could run within the same JVM. JBoss is -another good example (EJB Server). The JBoss team have actually got Tomcat -to run within the same JVM. Doesn't hinder performance at all, but does -reduce the memory footprint. - -This is a good future thing to look into (why not for 8.0 ;-) ). If we -could find an _optional_ way of hooking the backend direct into the JVM, we -could get PostgreSQL into a lot of new areas. It also would make things -like CORBA etc a doddle. - -PS: I'm writing down notes of the course to go onto the JDBC web site this -weekend, so there's some nice things for EJB, RMI, Corba etc. - -More later, Peter - - -From pgsql-hackers-owner+M4153@postgresql.org Sat Feb 3 11:54:12 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id LAA13446 - for ; Sat, 3 Feb 2001 11:54:12 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f13GrZq17345; - Sat, 3 Feb 2001 11:53:35 -0500 (EST) - (envelope-from pgsql-hackers-owner+M4153@postgresql.org) -Received: from mailout04.sul.t-online.com (mailout04.sul.t-online.com [194.25.134.18]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id f13GnZq17000 - for ; Sat, 3 Feb 2001 11:49:37 -0500 (EST) - (envelope-from peter_e@gmx.net) -Received: from fwd06.sul.t-online.com - by mailout04.sul.t-online.com with smtp - id 14P5rE-0000zq-00; Sat, 03 Feb 2001 17:48:16 +0100 -Received: from peter.localdomain (520083510237-0001@[212.185.245.12]) by fmrl06.sul.t-online.com - with esmtp id 14P5r6-0YvD60C; Sat, 3 Feb 2001 17:48:08 +0100 -Date: Sat, 3 Feb 2001 17:56:33 +0100 (CET) -From: Peter Eisentraut -To: Peter Mount -cc: Alex Pilosov , tomasz konefal , - -Subject: Re: [HACKERS] TODO list: Allow Java server-side programming -In-Reply-To: <5.0.2.1.0.20010203103036.009efec0@mail.retep.org.uk> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -X-Sender: 520083510237-0001@t-dialin.net -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Peter Mount writes: - -> Thats correct. Basically you are talking of something like PL/Java. The -> Java side would be simple, but its linking the JVM to the backend that's -> the problem. - -I've tried that recently, here's how it looks as far as Linux JVMs go: - -* Kaffe has a very polluted name space. Calls to its own functions get -resolved to PostgreSQL, and vice versa. Crash and burn result. The Kaffe -folks have admitted that this should be fixed but I didn't look farther -yet. - -* The Sun/Blackdown JVM didn't work at all (not even 'java -version') -until I upgraded my libc. Then a simple test run crashes with an "error -external to JVM"; at first it looked like a segfault when referencing a -string constant. In gdb I saw myself faced with about 10 threads running -when nothing was going on yet, at which point I was too exhausted to -proceed. - -* IBM's offering didn't work at all. I don't recall the problem anymore -but I think it didn't even link correctly. - -So currently I don't see how this could become a mainstream project, let -alone across platforms. - -> I know some people think this would slow the backend down, but it's only -> the instanciation of the JVM thats slow, hence the other reason fork() is -> holding this back. Ideally you would want the JVM to be running with -> PostMaster, and then each backend can then use the JVM as and when necessary. - -But how do the other languages cope? Starting up a new Perl for each -backend can't be so cheap either. - --- -Peter Eisentraut peter_e@gmx.net http://yi.org/peter-e/ - - -From pgsql-hackers-owner+M4154@postgresql.org Sat Feb 3 12:37:02 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id MAA00813 - for ; Sat, 3 Feb 2001 12:37:01 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f13Haiq21225; - Sat, 3 Feb 2001 12:36:44 -0500 (EST) - (envelope-from pgsql-hackers-owner+M4154@postgresql.org) -Received: from spider.pilosoft.com (p55-222.acedsl.com [160.79.55.222]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id f13HX9q20913 - for ; Sat, 3 Feb 2001 12:33:09 -0500 (EST) - (envelope-from alex@pilosoft.com) -Received: from localhost (alexmail@localhost) - by spider.pilosoft.com (8.9.3/8.9.3) with ESMTP id MAA09231; - Sat, 3 Feb 2001 12:36:01 -0500 (EST) -Date: Sat, 3 Feb 2001 12:36:01 -0500 (EST) -From: Alex Pilosov -To: Peter Mount -cc: Alex Pilosov , tomasz konefal , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] TODO list: Allow Java server-side programming -In-Reply-To: <5.0.2.1.0.20010203103036.009efec0@mail.retep.org.uk> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Sat, 3 Feb 2001, Peter Mount wrote: - -> It's been a while since I delved into the backend, but unless it's -> changed from fork() to threading, I don't really see this happening, -> unless someone who knows C that well knows of a portable way of -> communicating between two processes - other than RMI. If that could be -> solved, then you could use JNI to interface the JVM. -There are many ways one can do this: -a) each backend will have a JVM linked in (shared object). This is the -way perl/tcl/ruby is embedded, and it works pretty nice. But, Java -['s memory requirement] sucks, therefore, this may not be the optimal -way. - -> I know some people think this would slow the backend down, but it's -> only the instanciation of the JVM thats slow, hence the other reason -> fork() is holding this back. Ideally you would want the JVM to be -> running with PostMaster, and then each backend can then use the JVM as -> and when necessary. -b) since JVM is threaded, it may be more efficient to have a dedicated -process running JVM, and accepting some sort of IPC connections from -postgres processes. The biggest problem here is SPI, there aren't a good -way for that JVM to talk back to database. - -c) temporarily, to have quick working code, you can reach java using hacks -using programming languages already built into postgres. Both TCL (tcl -blend) and Perl (JPL and another hack which name escapes me) are able to -execute java code. SPI is possible, I think both of these bindings are -two-way (you can go perl-java-perl-java). Might be worth a quick try? --alex - - - -From pgsql-hackers-owner+M4164@postgresql.org Sun Feb 4 04:23:42 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id EAA04260 - for ; Sun, 4 Feb 2001 04:23:41 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f149Nhx75443; - Sun, 4 Feb 2001 04:23:43 -0500 (EST) - (envelope-from pgsql-hackers-owner+M4164@postgresql.org) -Received: from me.tm.ee (adsl895.estpak.ee [213.168.23.133]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id f149Mgx75338 - for ; Sun, 4 Feb 2001 04:22:42 -0500 (EST) - (envelope-from hannu@tm.ee) -Received: from tm.ee (IDENT:hannu@localhost.localdomain [127.0.0.1]) - by me.tm.ee (8.9.3/8.9.3) with ESMTP id LAA01488; - Sun, 4 Feb 2001 11:18:09 +0200 -Message-ID: <3A7D1E51.E383AB7F@tm.ee> -Date: Sun, 04 Feb 2001 11:18:09 +0200 -From: Hannu Krosing -X-Mailer: Mozilla 4.72 [en] (X11; U; Linux 2.2.17 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Peter Mount -CC: Alex Pilosov , tomasz konefal , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] TODO list: Allow Java server-side programming -References: <20010202194049.38902.qmail@web12003.mail.yahoo.com> <5.0.2.1.0.20010203103036.009efec0@mail.retep.org.uk> -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Peter Mount wrote: -> -> At 14:57 02/02/01 -0500, Alex Pilosov wrote: -> >On Fri, 2 Feb 2001, tomasz konefal wrote: -> > -> > > could someone please clarify what "Allow Java -> > > server-side programming" actually means? what are the -> > > limitations of using java and jdbc with pgsql? -> > -> >It means to embed Java interpreter inside postgres, and allow writing -> >stored procedures and triggers in Java. -> -> Thats correct. Basically you are talking of something like PL/Java. The -> Java side would be simple, but its linking the JVM to the backend that's -> the problem. -> -> It's been a while since I delved into the backend, but unless it's changed -> from fork() to threading, - -Someone posted here recently his port/tweaks of backend so that it used -threads instead of fork(). IIRC it was done to be used inside a java -client in an embedded system. - ----------------- -Hannu - -From pgsql-hackers-owner+M4168@postgresql.org Sun Feb 4 06:54:27 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id GAA19741 - for ; Sun, 4 Feb 2001 06:54:26 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f14BsOx83329; - Sun, 4 Feb 2001 06:54:24 -0500 (EST) - (envelope-from pgsql-hackers-owner+M4168@postgresql.org) -Received: from mail.retep.org.uk ([216.126.85.184]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id f14Bs9x83240 - for ; Sun, 4 Feb 2001 06:54:09 -0500 (EST) - (envelope-from peter@retep.org.uk) -Received: from heather.retep.org.uk ([193.113.241.180]) - (authenticated) - by mail.retep.org.uk (8.11.1/8.11.1) with ESMTP id f14BqkR83161; - Sun, 4 Feb 2001 06:52:46 -0500 (EST) - (envelope-from peter@retep.org.uk) -Message-Id: <5.0.2.1.0.20010204114942.00a0c8d0@mail.retep.org.uk> -X-Sender: peter@mail.retep.org.uk -X-Mailer: QUALCOMM Windows Eudora Version 5.0.2 -Date: Sun, 04 Feb 2001 11:51:21 +0000 -To: Peter Eisentraut -From: Peter Mount -Subject: Re: [HACKERS] TODO list: Allow Java server-side programming -Cc: Alex Pilosov , tomasz konefal , - -In-Reply-To: -References: <5.0.2.1.0.20010203103036.009efec0@mail.retep.org.uk> -Mime-Version: 1.0 -Content-Type: text/plain; charset="us-ascii"; format=flowed -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -At 17:56 03/02/01 +0100, Peter Eisentraut wrote: ->Peter Mount writes: -> -> > Thats correct. Basically you are talking of something like PL/Java. The -> > Java side would be simple, but its linking the JVM to the backend that's -> > the problem. -> ->I've tried that recently, here's how it looks as far as Linux JVMs go: - -[snip] - - ->So currently I don't see how this could become a mainstream project, let ->alone across platforms. - -I don't think it would be, but it would be a good side-project. Over time -the various JVM's should become better to interface with. - - -> > I know some people think this would slow the backend down, but it's only -> > the instanciation of the JVM thats slow, hence the other reason fork() is -> > holding this back. Ideally you would want the JVM to be running with -> > PostMaster, and then each backend can then use the JVM as and when -> necessary. -> ->But how do the other languages cope? Starting up a new Perl for each ->backend can't be so cheap either. - -But a lot cheaper than Java. - -Peter - - -From pgsql-hackers-owner+M4169@postgresql.org Sun Feb 4 06:57:24 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id GAA19817 - for ; Sun, 4 Feb 2001 06:57:23 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f14BvLx83711; - Sun, 4 Feb 2001 06:57:21 -0500 (EST) - (envelope-from pgsql-hackers-owner+M4169@postgresql.org) -Received: from mail.retep.org.uk ([216.126.85.184]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id f14Bv7x83611 - for ; Sun, 4 Feb 2001 06:57:07 -0500 (EST) - (envelope-from peter@retep.org.uk) -Received: from heather.retep.org.uk ([193.113.241.180]) - (authenticated) - by mail.retep.org.uk (8.11.1/8.11.1) with ESMTP id f14BtjR83557; - Sun, 4 Feb 2001 06:55:45 -0500 (EST) - (envelope-from peter@retep.org.uk) -Message-Id: <5.0.2.1.0.20010204115139.009f1c50@mail.retep.org.uk> -X-Sender: peter@mail.retep.org.uk -X-Mailer: QUALCOMM Windows Eudora Version 5.0.2 -Date: Sun, 04 Feb 2001 11:54:20 +0000 -To: Alex Pilosov -From: Peter Mount -Subject: Re: [HACKERS] TODO list: Allow Java server-side programming -Cc: Alex Pilosov , tomasz konefal , - pgsql-hackers@postgresql.org -In-Reply-To: -References: <5.0.2.1.0.20010203103036.009efec0@mail.retep.org.uk> -Mime-Version: 1.0 -Content-Type: text/plain; charset="us-ascii"; format=flowed -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -At 12:36 03/02/01 -0500, Alex Pilosov wrote: ->On Sat, 3 Feb 2001, Peter Mount wrote: - -[snip] - - -> > I know some people think this would slow the backend down, but it's -> > only the instanciation of the JVM thats slow, hence the other reason -> > fork() is holding this back. Ideally you would want the JVM to be -> > running with PostMaster, and then each backend can then use the JVM as -> > and when necessary. ->b) since JVM is threaded, it may be more efficient to have a dedicated ->process running JVM, and accepting some sort of IPC connections from ->postgres processes. The biggest problem here is SPI, there aren't a good ->way for that JVM to talk back to database. - -That was my other idea, but it is the IPC thats problematical. You would -still need to do some native api to implement some messaging system between -the two. - -However, at the other extreme there is RPC, which is possible now, but -would be a lot slower. - - ->c) temporarily, to have quick working code, you can reach java using hacks ->using programming languages already built into postgres. Both TCL (tcl ->blend) and Perl (JPL and another hack which name escapes me) are able to ->execute java code. SPI is possible, I think both of these bindings are ->two-way (you can go perl-java-perl-java). Might be worth a quick try? - -Might be one way to go... - -Peter - ->-alex -> - - -From pgsql-jdbc-owner+M884@postgresql.org Wed Jun 27 13:36:09 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f5RHa9q05483 - for ; Wed, 27 Jun 2001 13:36:09 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5RHaAa03078 - for ; Wed, 27 Jun 2001 13:36:10 -0400 (EDT) - (envelope-from pgsql-jdbc-owner+M884@postgresql.org) -Received: from net2.micro-automation.com (net2.micro-automation.com [64.7.141.29]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5RHOka96908 - for ; Wed, 27 Jun 2001 13:24:46 -0400 (EDT) - (envelope-from Dave@micro-automation.net) -Received: (qmail 32671 invoked from network); 27 Jun 2001 17:24:39 -0000 -Received: from eboxwest.ebox.com (HELO INSPIRON) (206.51.23.194) - by net2.micro-automation.com with SMTP; 27 Jun 2001 17:24:39 -0000 -Reply-To: -From: "Dave Cramer" -To: "'Barry Lind'" -cc: -Subject: [JDBC] RE: Todo/missing? (was Re: [ADMIN] High memory usage [PATCH]) -Date: Wed, 27 Jun 2001 13:22:42 -0400 -Organization: Micro Automation Inc. -Message-ID: <008301c0ff2d$c885d880$0201a8c0@INSPIRON> -MIME-Version: 1.0 -Content-Type: text/plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook, Build 10.0.2616 -Importance: Normal -In-Reply-To: <3B39352E.6060904@xythos.com> -X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 -X-AntiVirus: scanned for viruses by AMaViS 0.2.1 (http://amavis.org/) -Precedence: bulk -Sender: pgsql-jdbc-owner@postgresql.org -Status: OR - -Barry, - -The getXXXFunctions aren't implemented -Some of the other functions are correct for version 7.1 but not for -previous versions. Ie. The row length, etc. I think the driver should -get the version and determine what is correct for each version. - -I think this is incorrect. - public boolean supportsSelectForUpdate() throws SQLException - { - // XXX-Not Implemented - return false; - } - -There are a number of things here which are hard coded, and possible -wrong. - -I started to work on this, but since I am going on vacation next week I -have a number of fires to get down to a slow burn before I go. - -Dave - ------Original Message----- -From: Barry Lind [mailto:barry@xythos.com] -Sent: June 26, 2001 9:22 PM -To: Dave Cramer -Cc: pgsql-jdbc@postgresql.org -Subject: Re: Todo/missing? (was Re: [ADMIN] High memory usage [PATCH]) - -Dave, - -Can you give a little more detail on what you mean by 'Improved -DatabaseMetaData'? What specific areas are currently lacking? - -thanks, ---Barry - - ->>On Mon, Jun 25, 2001 at 10:56:18PM -0400, Dave Cramer wrote: ->> ->>>I have to agree, we need to compile a todo list. ->>> ->>>Mine would include: ->>> ->>>1) Comprehensive test suite. This may be available already. ->>>2) Updateable resultSet ->>>3) Improved DatabaseMetaData ->>>4) Compatible blob support ->>> -> -> Added to official PostgreSQL TODO: -> -> * JDBC -> * Comprehensive test suite. This may be available already. -> * Updateable resultSet -> * Improved DatabaseMetaData -> * Compatible blob support -> -> - - - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-jdbc-owner+M968@postgresql.org Sun Jul 8 18:59:29 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f68MxTl05403 - for ; Sun, 8 Jul 2001 18:59:29 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f68MxWa07043 - for ; Sun, 8 Jul 2001 18:59:32 -0400 (EDT) - (envelope-from pgsql-jdbc-owner+M968@postgresql.org) -Received: from mailout02.sul.t-online.de (mailout02.sul.t-online.com [194.25.134.17]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f68MrGa05368 - for ; Sun, 8 Jul 2001 18:53:16 -0400 (EDT) - (envelope-from peter_e@gmx.net) -Received: from fwd06.sul.t-online.de - by mailout02.sul.t-online.de with smtp - id 15JNQP-0004x9-00; Mon, 09 Jul 2001 00:53:13 +0200 -Received: from peter.localdomain (520083510237-0001@[212.185.245.47]) by fmrl06.sul.t-online.com - with esmtp id 15JNQH-0xfc00C; Mon, 9 Jul 2001 00:53:05 +0200 -Date: Mon, 9 Jul 2001 00:55:37 +0200 (CEST) -From: Peter Eisentraut -To: -Subject: [JDBC] To do list for DatabaseMetaData -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -X-Sender: 520083510237-0001@t-dialin.net -Precedence: bulk -Sender: pgsql-jdbc-owner@postgresql.org -Status: OR - -Since DatabaseMetaData seems to have been a subject of interest lately I -have composed a list of concrete things that need to be done there. - -The spec of DatabaseMetaData is here: -http://java.sun.com/j2se/1.3/docs/api/java/sql/DatabaseMetaData.html - -All the functions listed in the spec and not listed below I have recently -checked and updated for correctness and compliance. Thus, this list is -complete. Functions marked with '?' I have not checked yet. - -If someone wants to tackle some of the getThings() functions, a -description of the system catalogs is in the Developer's Guide. Also note -that some functions currently incorrectly handle the case of null patterns -vs. "" patterns vs. "%" patterns. - -At least two parameters obtained by a DatabaseMetaData method are -user-tunable on the server side. The only way to get at those numbers -currently is to use SHOW and parse the NOTICE: it sends back (which is -impossible in the days of internationalized messages), so a nice -side-project would be to implement a get_config_variable(text) returns -text (better names possible) function to allow easier access. - -Now the list: - -allProceduresAreCallable() not all procedures listed are - callable (triggers, in/out) -allTablesAreSelectable() should this check access - privileges or what? -getSQLKeywords() outdated, could be automated like - keywords.sgml -getNumericFunctions() decide what exactly is a "numeric function"? -getStringFunctions() ditto -getSystemFunctions() ditto -getTimeDateFunctions() ditto -getExtraNameCharacters() server allows \200 to \377, how - does this fit in with Unicode? -getMaxColumnNameLength() 32 is hard-coded here, maybe query server -getMaxColumnsInIndex() this should be detected from server -getMaxColumnsInTable() this limit is probably shaky -getMaxConnections() could query the server for this - (SHOW, see above) -getMaxCursorNameLength() 32 hard-coded -getMaxSchemaNameLength() will be 32 when done -getMaxProcedureNameLength() 32 hard-coded -getMaxCatalogNameLength() should be NAMEDATALEN -doesMaxRowSizeIncludeBlobs() since we don't have blobs, should - this throw an exception? -getMaxStatements() questionable, see comment there -getMaxTableNameLength() 32 hard-coded -getMaxUserNameLength() 32 hard-coded -getDefaultTransactionIsolation() This is configurable in 7.2. - (SHOW, see above) -getProcedures() missing catalog (database) and - remarks columns -getProcedureColumns() only dummy implementation -getTables() fails to handle pre-7.1 servers - (relkind 'v') -getSchemas() This should throw an exception. -getTableTypes() ? -getColumns() ? -getColumnPrivileges() not implemented -getTablePrivileges() not implemented -getBestRowIdentifier() only dummy implementation -getVersionColumns() not implemented -getPrimaryKeys() ? -getImportedKeys() ? -getExportedKeys() not implemented -getCrossReference() not implemented -getTypeInfo() ? -getIndexInfo() ? -getUDTs() ? - - --- -Peter Eisentraut peter_e@gmx.net http://funkturm.homeip.net/~peter - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://www.postgresql.org/search.mpl - -From pgsql-general-owner+M14602@postgresql.org Sat Sep 1 00:50:49 2001 -Return-path: -Received: from server1.pgsql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id f814onF24433 - for ; Sat, 1 Sep 2001 00:50:49 -0400 (EDT) -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by server1.pgsql.org (8.11.6/8.11.6) with ESMTP id f814pNq39726; - Fri, 31 Aug 2001 23:51:23 -0500 (CDT) - (envelope-from pgsql-general-owner+M14602@postgresql.org) -Received: from ns1.austin.rr.com (ns1.austin.rr.com [24.93.35.62]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id f81439f96700 - for ; Sat, 1 Sep 2001 00:03:09 -0400 (EDT) - (envelope-from rsanford@nolimitsystems.com) -Received: from mightywombat (cs662523-179.houston.rr.com [66.25.23.179]) - by ns1.austin.rr.com (8.12.0.Beta16/8.12.0.Beta16) with SMTP id f813x7pX027417 - for ; Fri, 31 Aug 2001 22:59:07 -0500 -From: "Robert J. Sanford, Jr." -To: -Subject: Re: [GENERAL] PL/java? -Date: Fri, 31 Aug 2001 23:02:04 -0500 -Message-ID: -MIME-Version: 1.0 -Content-Type: text/plain; - charset="US-ASCII" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2910.0) -Importance: Normal -X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200 -In-Reply-To: -Precedence: bulk -Sender: pgsql-general-owner@postgresql.org -Status: OR - -note - i don't work for any of the companies whose products -are mentioned below. i have performed evaluations of these -products and the support provided when attempting to determine -what platform my company's systems should run on. unfortunately, -i did not choose orion and i am suffering for it now... - -some goober blathered thusly: -> Have you ever actually used Java on an enterprise-level -> application? Ever see the Tomcat webserver? It uses -> 100MB of memory, drives the load on our server up to 8, -> and doesn't serve nearly as fast apache. Do you really -> want that in your database? - -first - don't complain about java because you or someone -in your group/department/company made a poor decision on -what tools to use. that's like complaining about mexican -food when the only experience you have is eating an out- -dated frozen burrito from the 7-11 freezer. - -when looking at the performance of java you have to take -a look at two things - first you have to compare various -java implementations against each other and then you have -to compare the best java implementations against native -c/c++ code. the following link does that. the java tests -include tomcat, orion, websphere, and resin. jrun and -weblogic were originally included in the testing but -were both removed at their companies' request. - -the tests also compare orion vs microsoft asp running on -win2k and iis5. all tests run on the same hardware. - -what i believe these tests clearly demonstrate is that -java is not the problem, the implementation applications -based on java is. i also do not believe that tomcat is -a fair representation of java performance in that it is -intended to be a reference implementation. as such, the -code base should sacrifice performance for clarity. - -http://www.orionserver.com/benchmarks/benchmark.html - - -while not in the benchmark i would also like to -recommend jetty as an app server. it is an opensource, -100% java web and application server. in its base form -it is "just" a web, servlet, and jsp engine. it does, -however, have contributed code providing integration -with other j2ee opensource projects such as the JBoss -EJB engine. - -you can find the jetty home page at: - http://jetty.mortbay.com/ - -and then they blathered some more: -> Compare the speed of Oracle 8 with 8i if you don't -> believe me. The stability is also much worse. Ever -> see a JVM on any platform that didn't crash if you -> looked at it cockeyed? Ever really trust the garbage -> collection? I don't. I've found a memory leak in IBM -> developed java libraries. Gotta restart that app -> every once in a while to reclaim system resources it -> gobbled up and never gave back. - -some mention was made regarding the performance of -the oracle8i application server. well, oracle has -realized that their performance was sub-optimal and -rectified the situation by licensing the orion server -for oracle9i. while money and politics most certainly -play a part in any licensing arrangement they must -also realize that making customers happy through the -performance of their applications will lead to more -money. the link to the press release is below. - -http://www.oracle.com/corporate/press/index.html?759347.html - -all of that being said... - -i don't think that the person that started this thread -did anything wrong by making the request they did. that -is what opensource is all about - contributions, even -just contributions of ideas, are welcomed. even so, there -are several options that i see for getting it implemented: -1) its an open source project so implement it yourself. - while i have never worked on modifying the code base - i am extremely confident that the current developers - will be more than willing to give you advice and - pointers. -2) if #1 is not feasible either because you don't have - the time, the inclination, or the experience then - you can write a contract that will pay one of the - postgres developers to implement it for you. -3) if that isn't feasible you can try to get a volunteer - to do so. -4) if that isn't feasible then you either have to live - with what you have, go elsewhere, or be quiet. - -to the person that blathered thusly in response to the -request for java: -> Merits of the language notwithstanding, I'd rather -> not have a buggy, still under development -> (depreciating everything under the sun with every -> new iteration) JVM parasite in my DB. - -informed and intelligent debate is good. given that i -believe such to be true, i would request that you -refrain from blathering such vitriol and uninformed -nonsense. not only is it for the good of the people -on the list who don't want to hear it but it will -also do you good by not telling everyone out there -that you are a very silly person that doesn't deal -with logic and/or facts. - -to everyone else on the list - if we all contribute -a penny we could probably buy enough burritos from -7-11 to make sure that his hands and mouth are busy -for a good long while. - -rjsjr - - - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-general-owner+M14597@postgresql.org Fri Aug 31 23:23:15 2001 -Return-path: -Received: from server1.pgsql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id f813NEF20222 - for ; Fri, 31 Aug 2001 23:23:14 -0400 (EDT) -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by server1.pgsql.org (8.11.6/8.11.6) with ESMTP id f813Njq38048; - Fri, 31 Aug 2001 22:23:46 -0500 (CDT) - (envelope-from pgsql-general-owner+M14597@postgresql.org) -Received: from spider.pilosoft.com (p55-222.acedsl.com [160.79.55.222]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id f812Yuf42942 - for ; Fri, 31 Aug 2001 22:35:04 -0400 (EDT) - (envelope-from alex@pilosoft.com) -Received: from localhost (alexmail@localhost) - by spider.pilosoft.com (8.9.3/8.9.3) with ESMTP id WAA20075; - Fri, 31 Aug 2001 22:35:23 -0400 (EDT) -Date: Fri, 31 Aug 2001 22:35:23 -0400 (EDT) -From: Alex Pilosov -To: Alex Knight -cc: pgsql-general@postgresql.org -Subject: [WAY OT] Re: [GENERAL] PL/java? -In-Reply-To: -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-general-owner@postgresql.org -Status: OR - -On Fri, 31 Aug 2001, Alex Knight wrote: - -> It is generally wiser to split the webservers from the appservers; -> that will save on memory footprints from each respectively. That alone -> can give each machine a specific task to accomplish... generally more -> efficiently. But I would assume you know this. - -And it is wise to split database from middleware, and not try to saddle -PostgreSQL with requirements to support Java in-process. _IF_ java stored -procedures are implemented, it should be via something like a) oracle's -extproc (start a separate process to load the function) b) some of perl -java tools (they start a jdk in a separate process and communicate with it -using RMI). - - -Problem with java-pgsql integration is the threads model: Java really -really wants threads. Postgres doesn't do threads. So if most simple way -is attempted, you will incur overhead of starting up JVM for each backend -(a few seconds as opposed to milliseconds) and non-shared 30M of memory -per backend (as opposed to currently <3 megs of non-shared memory per -backend). - -> Using something like WebLogic, WebSphere, or Orion would be a wiser -> approach. For the company with the low budget, Orion is only something -> like $2000, and it has full J2EE support, including EJBs, etc. Try -> finding that kind of richness in Tomcat. Also, Orion takes up only -> 40-50mb at start, which is really fairly reasonable; ram is cheap -> anyways... a server that has to perform complicated algorithms to a -> large audience but has hardly any ram shouldn't be on the internet -> anyways; unless it can handle it. - -_ONLY_ 40-50Mb?! Egads, I'm hard pressed to find any other piece of -(non-windows, non-java) software that takes 40-50M just to start up! - -I worked with both CrapLogic and CrapSphere. Weblogic takes 20-60 seconds -to start up on P3-800, that, IMHO, is ridiculous. - -It is not only issue of memory, its easy to throw memory at the problem, -its an issue of _incremental use_ of memory. As you scale - -> I feel that you don't really have enough experience with _java_ to -> judge it accurately. Frankly, the JVM is quite small nowadays, -> considering the amount of base classes that sit in memory much of the -> time. And the JVMs are really much faster these days. Java is still -> slow for 2 reasons: 1) Developers who don't optimize their code as -> they write it, 2) Bytecode interpretation is and probably never will -> be as fast as something like C/C++. But it certainly isn't the JVM -> itself slowing it down because of some "extended memory" that it lives -> in. Any reasonable server should have absolutely no problems if the -> jvm is implemented _properly_ (which many packages do not do), etc. If -> you're comparing Java to perl, yes, certainly it's a bit more of a -> beast, but perl quite simply can't keep up in speed and feature -> richness (when was the last time you secured your perl code in a -> redistributable fashion?) -_WHY_ the heck do all base classes need to be in memory all the time? Why -are they so huge? Libc is _far far_ smaller, and libstdc++ is tiny -compared to all the java standard library. - -You know what the answer to it is: Because they are ALL written in java, -as opposed to more sane languages like perl which handcode their "standard -libraries" or the most important pieces of them in C. - -Perl is far faster than java in about any practical application I did. -Again, the issue is not speed of JVM versus PP (perl virtual machine), if -you did number crunching in perl and java, they would probably be at par. -Its an issue of standard libraries. They are _horribly slow_. Perl's -hashtables are a very nice piece of optimized C code. Java's hashtables -are written in Java. Need I say more? Java's AWT was a dog. Swing is a dog -and a half, because they reimplemented all the things that are commonly -done in C in Java. - -> The only mistake the developers can make is poorly implementing the -> jvm, but most certainly not Java itself. I've been working on -> architecting and building enterprise level sites and applications for -> nearly 8 years now, and I've seen too many people try to implement -> perl cgi websites for enterprise sites and watch them choke and crawl -> to their knees because of poor system resource handling, lack of -> scalability, etc... I most certainly don't consider a single webserver -> with an appserver and tiny database to be enterprise level either (not -> that I'm inferring you said it was). -You cannot compare a perl CGI script and a J2EE server. Its like comparing -a webserver you wrote yourself vs apache! There are application servers -(or more closely, code libraries) for perl that match what J2EE provides. - --- -Alex Pilosov | http://www.acedsl.com/home.html -CTO - Acecape, Inc. | AceDSL:The best ADSL in the world -325 W 38 St. Suite 1005 | (Stealth Marketing Works! :) -New York, NY 10018 | - - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M14652=candle.pha.pa.us=pgman@postgresql.org Thu Oct 25 22:24:44 2001 -Return-path: -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id f9Q1Oim04694 - for ; Thu, 25 Oct 2001 21:24:44 -0400 (EDT) -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id f9Q1CeR31737 - for ; Thu, 25 Oct 2001 20:21:26 -0500 (CDT) - (envelope-from pgsql-hackers-owner+M14652=candle.pha.pa.us=pgman@postgresql.org) -Received: from smaug.polygnosis.com (smaug.polygnosis.com [195.139.160.201]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id f9Q16NP39474 - for ; Thu, 25 Oct 2001 21:06:23 -0400 (EDT) - (envelope-from gunnar@smaug.polygnosis.com) -Received: (from gunnar@localhost) - by smaug.polygnosis.com (8.11.0/8.11.0) id f9Q15nC01560; - Fri, 26 Oct 2001 03:05:49 +0200 -To: tweekie -cc: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] java virtual machine -References: <3bd825e2_1@Usenet.com> -From: Gunnar =?iso-8859-1?q?R=F8nning?= -Date: 26 Oct 2001 03:05:49 +0200 -In-Reply-To: <3bd825e2_1@Usenet.com> -Message-ID: -Lines: 19 -User-Agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7 -MIME-Version: 1.0 -Content-Type: text/plain; charset=iso-8859-1 -Content-Transfer-Encoding: 8bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -* tweekie wrote: -| -| I asked this question a while back but got no response - is there any way of -| creating a Java stored procedure in a postgres database ? I can see that -| there is a built-in PL/sql type of environment and a python one but it would -| be nice if I could migrate Java stored procedures in an Oracle database into -| postgres. -| -| Any comments? - - -It would rock ;-) An Hungarian guy just sent a mail indicating that he -had a first prototype version of something with Kaffe up and running. -But I believe there is a lot of issues to be solved, especially -threading issues... - --- -Gunnar Rønning - gunnar@polygnosis.com -Senior Consultant, Polygnosis AS, http://www.polygnosis.com/ - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-general-owner+M18147=candle.pha.pa.us=pgman@postgresql.org Mon Dec 3 13:53:24 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB3IrNS29264 - for ; Mon, 3 Dec 2001 13:53:24 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB3IrO213373 - for ; Mon, 3 Dec 2001 13:53:24 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB3Iq1N35610 - for ; Mon, 3 Dec 2001 12:52:02 -0600 (CST) - (envelope-from pgsql-general-owner+M18147=candle.pha.pa.us=pgman@postgresql.org) -Received: from tiger.tigrasoft (fw.tigrasoft.hu [195.70.42.161]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fAU95km73601 - for ; Fri, 30 Nov 2001 04:05:46 -0500 (EST) - (envelope-from hornyakl@freemail.hu) -Received: from freemail.hu ([192.168.0.200]) - by tiger.tigrasoft (8.9.3/8.9.3/Debian 8.9.3-21) with ESMTP id KAA11457 - for ; Fri, 30 Nov 2001 10:05:45 +0100 -X-Authentication-Warning: tiger.tigrasoft: Host [192.168.0.200] claimed to be freemail.hu -Message-ID: <3C074DE4.9040905@freemail.hu> -Date: Fri, 30 Nov 2001 10:14:12 +0100 -From: Laszlo Hornyak -Reply-To: hornyakl@users.sourceforge.net -User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.4) Gecko/20010913 -X-Accept-Language: hu, en-us -MIME-Version: 1.0 -To: pgsql-general@postgresql.org -Subject: [GENERAL] java stored procedures -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-general-owner@postgresql.org -Status: OR - -Hi! - -A few months ago I asked if anyone started working on PL/JAVA, the -ansver was no. Now I started to write a java stored procedure language -and environment for PostgreSQL. Some code is already working, and it is -geting interresting. So, I would like to ask you to write me your ideas, -suggestions, etc for this environment. -The source code will be available under GPL when it is worth for -distributing it (this will take for a while). -thanks. - -Laszlo Hornyak - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-general-owner+M18182=candle.pha.pa.us=pgman@postgresql.org Tue Dec 4 13:14:09 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB4IE3r15972 - for ; Tue, 4 Dec 2001 13:14:04 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB4IE2Y07122 - for ; Tue, 4 Dec 2001 13:14:02 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB4I9HN76662 - for ; Tue, 4 Dec 2001 12:09:17 -0600 (CST) - (envelope-from pgsql-general-owner+M18182=candle.pha.pa.us=pgman@postgresql.org) -Received: from belphigor.mcnaught.org ([216.151.155.121]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB4Hwsm96365; - Tue, 4 Dec 2001 12:58:59 -0500 (EST) - (envelope-from doug@wireboard.com) -Received: (from doug@localhost) - by belphigor.mcnaught.org (8.11.6/8.9.3) id fB4Hwlo07786; - Tue, 4 Dec 2001 12:58:47 -0500 -X-Authentication-Warning: belphigor.mcnaught.org: doug set sender to doug@wireboard.com using -f -To: Barry Lind -cc: Laszlo Hornyak , pgsql-general@postgresql.org, - pgsql-jdbc@postgresql.org -Subject: Re: [GENERAL] java stored procedures -References: <3C074DE4.9040905@freemail.hu> <3C0BE325.3020809@xythos.com> - <3C0C937E.9000405@freemail.hu> <3C0CFD82.1030600@xythos.com> -From: Doug McNaught -Date: 04 Dec 2001 12:58:47 -0500 -In-Reply-To: Barry Lind's message of "Tue, 04 Dec 2001 08:44:50 -0800" -Message-ID: -Lines: 42 -User-Agent: Gnus/5.0806 (Gnus v5.8.6) XEmacs/21.1 (20 Minutes to Nikko) -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Precedence: bulk -Sender: pgsql-general-owner@postgresql.org -Status: OR - -Barry Lind writes: - -> Having one jvm that all the postgres backend processes communicate with makes -> the whole feature much more complicated, but is necessary in my opinion. - -Agreed. Also, the JVM is a multithreaded app, and running it inside a -non-threaded program (the backend) might cause problems. - -> Then the question becomes how does the jvm process interact with the database -> since they are two different processes. You will need some sort of -> interprocess communication between the two to execute sql statements. This -> could be accomplished by using the existing jdbc driver. But the bigest -> problem here is getting the transaction semantics right. How does a sql -> statement being run by a java stored procedure get access to the same -> connection/transaction as the original client? What you don't want happening -> is that sql issued in a stored java procedure executes in a different -> transaction as the caller, what would rollback of the stored function call -> mean in that case? - -I think you would have to to expose the SPI layer to Java running in a -separate process, either using an RMI server written in C or a custom -protocol over a TCP socket (Java of course can't do Unix sockets). -This raises some thorny issues of authentication and security but I -don't think they're insurmountable. You could, for example, create a -cryptographically strong "cookie" in the backend when a Java function -is called. The cookie would be passed to the Java function when it -gets invoked, and then must be passed back to the SPI layer in order -for the latter to accept the call. A bit clunky but should be safe as -far as I can see. - -The cookie would be needed anyhow, I think, in order for the SPI layer -to be able to find the transaction that the Java function was -originally invoked in. - -You could make the SPI layer stuff look like a normal JDBC driver to -user code--PL/Perl does this kind of thing with the Perl DBI -interface. - --Doug --- -Let us cross over the river, and rest under the shade of the trees. - --T. J. Jackson, 1863 - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-jdbc-owner+M2545@postgresql.org Tue Dec 4 12:49:03 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB4Hn1r09487 - for ; Tue, 4 Dec 2001 12:49:01 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB4HmxY25870 - for ; Tue, 4 Dec 2001 12:48:59 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB4HiLN75867; - Tue, 4 Dec 2001 11:44:21 -0600 (CST) - (envelope-from pgsql-jdbc-owner+M2545@postgresql.org) -Received: from barry.xythos.com ([64.139.0.223]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB4H9bm94568; - Tue, 4 Dec 2001 12:09:38 -0500 (EST) - (envelope-from barry@xythos.com) -Received: from xythos.com (localhost.localdomain [127.0.0.1]) - by barry.xythos.com (8.11.6/8.11.6) with ESMTP id fB4Gior02314; - Tue, 4 Dec 2001 08:44:50 -0800 -Message-ID: <3C0CFD82.1030600@xythos.com> -Date: Tue, 04 Dec 2001 08:44:50 -0800 -From: Barry Lind -User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.6) Gecko/20011120 -X-Accept-Language: en-us -MIME-Version: 1.0 -To: Laszlo Hornyak -cc: pgsql-general@postgresql.org, pgsql-jdbc@postgresql.org -Subject: Re: [JDBC] [GENERAL] java stored procedures -References: <3C074DE4.9040905@freemail.hu> <3C0BE325.3020809@xythos.com> <3C0C937E.9000405@freemail.hu> -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-jdbc-owner@postgresql.org -Status: OR - -Laszlo, - -I think it would help a lot if you could take a little time to write -down what your planned architecture for a pljava would be. It then -becomes much easier for myself and probably others reading these lists -to make suggestions on ways to improve what you are planning (or -possible problems with your strategy). Without knowing what exactly you -are thinking of doing it is difficult to comment. - -But let me try throwing out a few thoughts about how I think this should -be done. - -First question is how will the jvm be run? Since postgres is a -multiprocess implementation (i.e. each connection has a separate process -on the server) and since java is a multithreaded implementation (i.e. -one process supporting multiple threads), what should the pljava -implementation look like? I think there should be a single jvm process -for the entire db server that each postgresql process connects to -through sockets/rmi. It will be too expensive to create a new jvm -process for each postgresql connection (expensive in both terms of -memory and cpu, since the startup time for the jvm is significant and it -requires a lot of memory). - -Having one jvm that all the postgres backend processes communicate with -makes the whole feature much more complicated, but is necessary in my -opinion. - -Then the question becomes how does the jvm process interact with the -database since they are two different processes. You will need some -sort of interprocess communication between the two to execute sql -statements. This could be accomplished by using the existing jdbc -driver. But the bigest problem here is getting the transaction -semantics right. How does a sql statement being run by a java stored -procedure get access to the same connection/transaction as the original -client? What you don't want happening is that sql issued in a stored -java procedure executes in a different transaction as the caller, what -would rollback of the stored function call mean in that case? - -I am very interested in hearing what your plans are for pl/java. I -think this is a very difficult project, but one that would be very -useful and welcome. - -thanks, ---Barry - - - - -Laszlo Hornyak wrote: - -> Hi! -> -> I am such a lame in the licensing area. As much as I know, BSD license -> is more free than GPL. I think it is too early to think about licensing, -> but it`s ok, you won :), when it will be ready(or it will seem to get -> closer to a working thing, currently it looks more like a interresting -> test), I will ask you if you want to distribute it with Postgres, and if -> you say yes, the license will be the same as Postgresql`s license. -> Anyway is this neccessary when it is the part of the distribution? -> Is this ok for you? -> -> thanks, -> Laszlo Hornyak -> -> ps: still waiting for your ideas, suggestions, etc :) I am not memeber -> of the mailing list, please write me dirrectly! -> -> Barry Lind wrote: -> ->> Laszlo, ->> ->> In my mind it would be more useful if this code was under the same ->> license as the rest of postgresql. That way it could become part of ->> the product as opposed to always being a separate component. (Just ->> like plpgsql, pltcl and the other procedural languages). ->> ->> thanks, ->> --Barry ->> ->> -> -> - - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-jdbc-owner+M2555@postgresql.org Thu Dec 6 10:16:31 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB6FGUZ29382 - for ; Thu, 6 Dec 2001 10:16:30 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB6FGTE25863 - for ; Thu, 6 Dec 2001 10:16:29 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB6F9lN55201; - Thu, 6 Dec 2001 09:09:48 -0600 (CST) - (envelope-from pgsql-jdbc-owner+M2555@postgresql.org) -Received: from tiger.tigrasoft (fw.tigrasoft.hu [195.70.42.161]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB4JB2m99252; - Tue, 4 Dec 2001 14:11:03 -0500 (EST) - (envelope-from hornyakl@freemail.hu) -Received: from freemail.hu ([192.168.0.200]) - by tiger.tigrasoft (8.9.3/8.9.3/Debian 8.9.3-21) with ESMTP id UAA07040; - Tue, 4 Dec 2001 20:10:17 +0100 -X-Authentication-Warning: tiger.tigrasoft: Host [192.168.0.200] claimed to be freemail.hu -Message-ID: <3C0D219C.1090804@freemail.hu> -Date: Tue, 04 Dec 2001 20:18:52 +0100 -From: Laszlo Hornyak -Reply-To: hornyakl@users.sourceforge.net -User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.4) Gecko/20010913 -X-Accept-Language: hu, en-us -MIME-Version: 1.0 -To: Barry Lind -cc: pgsql-general@postgresql.org, pgsql-jdbc@postgresql.org -Subject: Re: [JDBC] [GENERAL] java stored procedures -References: <3C074DE4.9040905@freemail.hu> <3C0BE325.3020809@xythos.com> <3C0C937E.9000405@freemail.hu> <3C0CFD82.1030600@xythos.com> -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-jdbc-owner@postgresql.org -Status: OR - -Hi! - -Barry Lind wrote: - -> Laszlo, -> -> I think it would help a lot if you could take a little time to write -> down what your planned architecture for a pljava would be. It then -> becomes much easier for myself and probably others reading these lists -> to make suggestions on ways to improve what you are planning (or -> possible problems with your strategy). Without knowing what exactly -> you are thinking of doing it is difficult to comment. - -> -> -> But let me try throwing out a few thoughts about how I think this -> should be done. -> -> First question is how will the jvm be run? Since postgres is a -> multiprocess implementation (i.e. each connection has a separate -> process on the server) and since java is a multithreaded -> implementation (i.e. one process supporting multiple threads), what -> should the pljava implementation look like? I think there should be a -> single jvm process for the entire db server that each postgresql -> process connects to through sockets/rmi. It will be too expensive to -> create a new jvm process for each postgresql connection (expensive in -> both terms of memory and cpu, since the startup time for the jvm is -> significant and it requires a lot of memory). - -I absolutely agree. OK, it`s done. - -So, a late-night-brainstorming here: -What I would like to see in PL/JAVA is the object oriented features, -that makes postgresql nice. Creating a new table creates a new class in -the java side too. Instantiating an object of the newly created class -inserts a row into the table. In postgresql tables can be inherited, and -this could be easyly done by pl/java too. I think this would look nice. -But this is not the main feature. Why I would like to see a nice java -procedural language inside postgres is java`s advanced communication -features (I mean CORBA, jdbc, other protocols). This is the sugar in the -caffe. - -I am very far from features like this. -PL/JAVA now: --there is a separate process running java (kaffe). this process creates -a sys v message queue, that holds requests. almost forgot, a shared -memory segment too. I didn`t find better way to tell postgres the -informations about the java process. --the java request_handler function on the server side attaches to the -shared memory, reads the key of the message queue., attaches to it, -sends the data of the function, and a signal for the pl/java. after, it -is waiting for a signal from the java thread. --when java thread receives the signal, it reads the message(s) from the -queue, and starts some actions. When done it tells postgres with a -signal that it is ready, and it can come for its results. This will be -rewritten see below problems. --And postgres is runing, while java is waiting for postgres to say -something. - -Threading on the java process side is not done yet, ok, it is not that -hard, I will write it, if it will be realy neccessary. - -The problems, for now: -I had a very simple system, that passed a very limited scale of argument -types, with a very limited quantity of parameters (int, varchar, bool). -Postgres has limits for the argument count too, but not for types. It -had too much limits, so I am working (or to tell the truth now only -thinking) on a new type handling that fits the felxibility of -Postgresql`s type flexibility. For this I will have to learn a lot about -Postgres`s type system. This will be my program this weekend. :) - -thanks, -Laszlo Hornyak - - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-jdbc-owner+M2549@postgresql.org Tue Dec 4 22:34:48 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB53Ykr17433 - for ; Tue, 4 Dec 2001 22:34:47 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB53YkY26794 - for ; Tue, 4 Dec 2001 22:34:46 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB53UcN93073; - Tue, 4 Dec 2001 21:30:38 -0600 (CST) - (envelope-from pgsql-jdbc-owner+M2549@postgresql.org) -Received: from barry.xythos.com (h-64-105-36-191.SNVACAID.covad.net [64.105.36.191]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB53Obm35215; - Tue, 4 Dec 2001 22:24:37 -0500 (EST) - (envelope-from barry@xythos.com) -Received: from xythos.com (localhost.localdomain [127.0.0.1]) - by barry.xythos.com (8.11.6/8.11.6) with ESMTP id fB51YLJ03883; - Tue, 4 Dec 2001 17:34:21 -0800 -Message-ID: <3C0D799D.4010808@xythos.com> -Date: Tue, 04 Dec 2001 17:34:21 -0800 -From: Barry Lind -User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.6) Gecko/20011120 -X-Accept-Language: en-us -MIME-Version: 1.0 -To: hornyakl@users.sourceforge.net -cc: pgsql-general@postgresql.org, pgsql-jdbc@postgresql.org -Subject: Re: [JDBC] [GENERAL] java stored procedures -References: <3C074DE4.9040905@freemail.hu> <3C0BE325.3020809@xythos.com> <3C0C937E.9000405@freemail.hu> <3C0CFD82.1030600@xythos.com> <3C0D219C.1090804@freemail.hu> -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-jdbc-owner@postgresql.org -Status: OR - -Laszlo, - - -> I am very far from features like this. -> PL/JAVA now: -> -there is a separate process running java (kaffe). this process creates -> a sys v message queue, that holds requests. almost forgot, a shared -> memory segment too. I didn`t find better way to tell postgres the -> informations about the java process. - - -Does the mechanism you are planning support running any JVM? In my -opionion Kaffe isn't good enough to be widely useful. I think you -should be able to plugin whatever jvm is best on your platform, which -will likely be either the Sun or IBM JVMs. - -Also, can you explain this a little bit more. How does the jvm process -get started? (I would hope that the postgresql server processes would -start it when needed, as opposed to requiring that it be started -separately.) How does the jvm access these shared memory structures? -Since there aren't any methods in the java API to do such things that I -am aware of. - -> -the java request_handler function on the server side attaches to the -> shared memory, reads the key of the message queue., attaches to it, -> sends the data of the function, and a signal for the pl/java. after, it -> is waiting for a signal from the java thread. - - -I don't understand how you do this in java? I must not be understanding - something correctly here. - -> -when java thread receives the signal, it reads the message(s) from the -> queue, and starts some actions. When done it tells postgres with a -> signal that it is ready, and it can come for its results. This will be -> rewritten see below problems. - - -Are signals the best way to accomplish this? - -> -And postgres is runing, while java is waiting for postgres to say -> something. - - -But in reality if the postgres process is executing a stored function it -needs to wait for the result of that function call before continuing -doesn't it? - -> -> Threading on the java process side is not done yet, ok, it is not that -> hard, I will write it, if it will be realy neccessary. - - -Agreed, this is important. - -> -> The problems, for now: -> I had a very simple system, that passed a very limited scale of argument -> types, with a very limited quantity of parameters (int, varchar, bool). -> Postgres has limits for the argument count too, but not for types. It -> had too much limits, so I am working (or to tell the truth now only -> thinking) on a new type handling that fits the felxibility of -> Postgresql`s type flexibility. For this I will have to learn a lot about -> Postgres`s type system. This will be my program this weekend. :) - - -Shouldn't this code use all or most of the logic found in the FE/BE -protocol? Why invent and code another mechanism to transfer data when -one already exists. (I will admit that the current FE/BE mechanism -isn't the ideal choice, but it seems easier to reuse what exists for now -and improve on it later). - - -> -> thanks, -> Laszlo Hornyak -> - -You didn't mention how you plan to deal with the transaction symantics. - So what happens when the pl/java function calls through jdbc back to -the server to insert some data? That should happen in the same -transaction as the caller correct? - -thanks, ---Barry - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-jdbc-owner+M2559@postgresql.org Thu Dec 6 10:18:55 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB6FIrZ29672 - for ; Thu, 6 Dec 2001 10:18:54 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB6FIrE26972 - for ; Thu, 6 Dec 2001 10:18:53 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB6F9nN55205; - Thu, 6 Dec 2001 09:09:49 -0600 (CST) - (envelope-from pgsql-jdbc-owner+M2559@postgresql.org) -Received: from tiger.tigrasoft (fw.tigrasoft.hu [195.70.42.161]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB58wVm49422; - Wed, 5 Dec 2001 03:58:31 -0500 (EST) - (envelope-from hornyakl@freemail.hu) -Received: from freemail.hu ([192.168.0.200]) - by tiger.tigrasoft (8.9.3/8.9.3/Debian 8.9.3-21) with ESMTP id JAA12365; - Wed, 5 Dec 2001 09:57:35 +0100 -X-Authentication-Warning: tiger.tigrasoft: Host [192.168.0.200] claimed to be freemail.hu -Message-ID: <3C0DE382.1050400@freemail.hu> -Date: Wed, 05 Dec 2001 10:06:10 +0100 -From: Laszlo Hornyak -Reply-To: hornyakl@users.sourceforge.net -User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.4) Gecko/20010913 -X-Accept-Language: hu, en-us -MIME-Version: 1.0 -To: Barry Lind -cc: hornyakl@users.sourceforge.net, pgsql-general@postgresql.org, - pgsql-jdbc@postgresql.org -Subject: Re: [JDBC] [GENERAL] java stored procedures -References: <3C074DE4.9040905@freemail.hu> <3C0BE325.3020809@xythos.com> <3C0C937E.9000405@freemail.hu> <3C0CFD82.1030600@xythos.com> <3C0D219C.1090804@freemail.hu> <3C0D799D.4010808@xythos.com> -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-jdbc-owner@postgresql.org -Status: OR - -Hi! - -Barry Lind wrote: - -> Does the mechanism you are planning support running any JVM? In my -> opionion Kaffe isn't good enough to be widely useful. I think you -> should be able to plugin whatever jvm is best on your platform, which -> will likely be either the Sun or IBM JVMs. - -Ok, I also had problems with caffe, but it may work. I like it becouse -it is small (the source is about 6M). As much as I know Java VM`s has a -somewhat standard native interface called JNI. I use this to start the -VM, and communicate with it. If you think I should change I will do it, -but it may take a long time to get the new VM. For then I have to run kaffe. - -> Also, can you explain this a little bit more. How does the jvm -> process get started? (I would hope that the postgresql server -> processes would start it when needed, as opposed to requiring that it -> be started separately.) How does the jvm access these shared memory -> structures? Since there aren't any methods in the java API to do such -> things that I am aware of. - -JVM does not. 'the java process' does with simple posix calls. I use -debian potatoe, on any other posix system it should work, on any other -somewhat posix compatible system it may work, I am not sure... - -> -> I don't understand how you do this in java? I must not be -> understanding something correctly here. - -My failure. -The 'java request_handler' is not a java function, it is the C -call_handler in the Postgres side, that is started when a function of -language 'pljava' is called. -I made some failure in my previous mail. At home I named the pl/java -language pl/pizza (something that is not caffe, but well known enough -:). The application has two running binaries: --pizza (which was called 'java process' last time) This is a small C -program that uses JNI to start VM and call java methods. --plpizza.so the shared object that contains the call_handler function. - - -> -> ->> -when java thread receives the signal, it reads the message(s) from ->> the queue, and starts some actions. When done it tells postgres with ->> a signal that it is ready, and it can come for its results. This will ->> be rewritten see below problems. -> -> -> -> Are signals the best way to accomplish this? - -I don`t know if it is the best, it is the only way I know :) -Do you know any other ways? - -> -> ->> -And postgres is runing, while java is waiting for postgres to say ->> something. -> -> But in reality if the postgres process is executing a stored function -> it needs to wait for the result of that function call before -> continuing doesn't it? - -Surely, this is done. How could Postgres tell the result anyway ? :) - -> ->> ->> Threading on the java process side is not done yet, ok, it is not ->> that hard, I will write it, if it will be realy neccessary. -> -> Agreed, this is important. -> -> Shouldn't this code use all or most of the logic found in the FE/BE -> protocol? Why invent and code another mechanism to transfer data when -> one already exists. (I will admit that the current FE/BE mechanism -> isn't the ideal choice, but it seems easier to reuse what exists for -> now and improve on it later). - -Well, I am relatively new to Postgres, and I don`t know these protocols. -In the weekend I will start to learn it, and in Sunday or Monday I maybe -I will understand it, if not, next weekend.. - -> -> You didn't mention how you plan to deal with the transaction -> symantics. So what happens when the pl/java function calls through -> jdbc back to the server to insert some data? That should happen in -> the same transaction as the caller correct? - -I don`t think this will be a problem, I have ideas for this. Idea mean: -I know how I will start it, it may be good, or it may be fataly stupid -idea, it will turn out when I tried it. Simply: The same way plpizza -tells pizza the request, pizza can talk back to plpizza. This is planed -to work with similar mechanism I described last time (shm+signals). - -Monday I will try to send a little pieces of code to make thing clear, ok? - -thanks, -Laszlo Hornyak - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-jdbc-owner+M2567@postgresql.org Thu Dec 6 12:05:50 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB6H5nZ07357 - for ; Thu, 6 Dec 2001 12:05:49 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB6H5ma17427 - for ; Thu, 6 Dec 2001 12:05:48 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB6H1DN59312; - Thu, 6 Dec 2001 11:01:13 -0600 (CST) - (envelope-from pgsql-jdbc-owner+M2567@postgresql.org) -Received: from barry.xythos.com (h-64-105-36-191.SNVACAID.covad.net [64.105.36.191]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB6Gtsm73872; - Thu, 6 Dec 2001 11:55:55 -0500 (EST) - (envelope-from barry@xythos.com) -Received: from xythos.com (localhost.localdomain [127.0.0.1]) - by barry.xythos.com (8.11.6/8.11.6) with ESMTP id fB5HWJ902835; - Wed, 5 Dec 2001 09:32:19 -0800 -Message-ID: <3C0E5A23.7060701@xythos.com> -Date: Wed, 05 Dec 2001 09:32:19 -0800 -From: Barry Lind -User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.6) Gecko/20011120 -X-Accept-Language: en-us -MIME-Version: 1.0 -To: hornyakl@users.sourceforge.net -cc: pgsql-hackers@postgresql.org, pgsql-jdbc@postgresql.org -Subject: Re: [JDBC] [GENERAL] java stored procedures -References: <3C074DE4.9040905@freemail.hu> <3C0BE325.3020809@xythos.com> <3C0C937E.9000405@freemail.hu> <3C0CFD82.1030600@xythos.com> <3C0D219C.1090804@freemail.hu> <3C0D799D.4010808@xythos.com> <3C0DE382.1050400@freemail.hu> -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-jdbc-owner@postgresql.org -Status: OR - -Laszlo, - -I have cc'ed the hackers mail list since that group of developers is -probably better able than I to make suggestions on the best interprocess -communication mechanism to use for this. See -http://archives2.us.postgresql.org/pgsql-general/2001-12/msg00092.php -for background on this thread. - -I also stopped cc'ing the general list, since this is getting too -detailed for most of the members on that list. - -Now to your mail: - -Laszlo Hornyak wrote: - -> Hi! -> -> Barry Lind wrote: -> ->> Does the mechanism you are planning support running any JVM? In my ->> opionion Kaffe isn't good enough to be widely useful. I think you ->> should be able to plugin whatever jvm is best on your platform, which ->> will likely be either the Sun or IBM JVMs. -> -> -> Ok, I also had problems with caffe, but it may work. I like it becouse -> it is small (the source is about 6M). As much as I know Java VM`s has a -> somewhat standard native interface called JNI. I use this to start the -> VM, and communicate with it. If you think I should change I will do it, -> but it may take a long time to get the new VM. For then I have to run -> kaffe. -> - - -This seems like a reasonable approach and should work across different -JVMs. It would probably be a good experiment to try this with the Sun -or IBM jvm at some point to verify. What I was afraid of was that you -were hacking the Kaffe code to perform the integration which would limit -this solution to only using Kaffe. - - ->> Also, can you explain this a little bit more. How does the jvm ->> process get started? (I would hope that the postgresql server ->> processes would start it when needed, as opposed to requiring that it ->> be started separately.) How does the jvm access these shared memory ->> structures? Since there aren't any methods in the java API to do such ->> things that I am aware of. -> -> -> JVM does not. 'the java process' does with simple posix calls. I use -> debian potatoe, on any other posix system it should work, on any other -> somewhat posix compatible system it may work, I am not sure... -> ->> ->> I don't understand how you do this in java? I must not be ->> understanding something correctly here. -> -> -> My failure. -> The 'java request_handler' is not a java function, it is the C -> call_handler in the Postgres side, that is started when a function of -> language 'pljava' is called. -> I made some failure in my previous mail. At home I named the pl/java -> language pl/pizza (something that is not caffe, but well known enough -> :). The application has two running binaries: -> -pizza (which was called 'java process' last time) This is a small C -> program that uses JNI to start VM and call java methods. -> -plpizza.so the shared object that contains the call_handler function. -> - - -Just a suggestion: PL/J might be a good name, since as you probably -know it can't be called pl/java because of the trademark restrictions on -the word 'java'. - -I am a little concerned about the stability and complexity of having -this '-pizza' program be responsible for handling the calls on the java -side. My concern is that this will need to be a multithreaded program -since multiple backends will concurrently be needing to interact with -multiple java threads through this one program. It might be simpler if -each postgres process directly communicated to a java thread via a tcpip -socket. Then the "-pizza" program would only need to be responsible for -starting up the jvm and creating java threads and sockets for a postgres -process (it would perform a similar role to postmaster for postgres -client connections). - - -> ->> ->> ->>> -when java thread receives the signal, it reads the message(s) from ->>> the queue, and starts some actions. When done it tells postgres with ->>> a signal that it is ready, and it can come for its results. This will ->>> be rewritten see below problems. ->> ->> ->> ->> ->> Are signals the best way to accomplish this? -> -> -> I don`t know if it is the best, it is the only way I know :) -> Do you know any other ways? -> - - -I don't know, but hopefully someone on the hackers list will chip in -here with a comment. - - ->> ->>> ->>> Threading on the java process side is not done yet, ok, it is not ->>> that hard, I will write it, if it will be realy neccessary. ->> ->> ->> Agreed, this is important. ->> ->> Shouldn't this code use all or most of the logic found in the FE/BE ->> protocol? Why invent and code another mechanism to transfer data when ->> one already exists. (I will admit that the current FE/BE mechanism ->> isn't the ideal choice, but it seems easier to reuse what exists for ->> now and improve on it later). -> -> -> Well, I am relatively new to Postgres, and I don`t know these protocols. -> In the weekend I will start to learn it, and in Sunday or Monday I maybe -> I will understand it, if not, next weekend.. -> ->> ->> You didn't mention how you plan to deal with the transaction ->> symantics. So what happens when the pl/java function calls through ->> jdbc back to the server to insert some data? That should happen in ->> the same transaction as the caller correct? -> -> -> I don`t think this will be a problem, I have ideas for this. Idea mean: -> I know how I will start it, it may be good, or it may be fataly stupid -> idea, it will turn out when I tried it. Simply: The same way plpizza -> tells pizza the request, pizza can talk back to plpizza. This is planed -> to work with similar mechanism I described last time (shm+signals). -> - - -OK, so the same backend process that called the function gets messaged -to process the sql. This should work. However it means you will need a -special version of the jdbc driver that uses this shm+signals -communication mechanism instead of what the current jdbc driver does. -This is something I would be happy to help you with. - - - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M16317=candle.pha.pa.us=pgman@postgresql.org Thu Dec 6 10:11:27 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB6FBQZ28795 - for ; Thu, 6 Dec 2001 10:11:26 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB6FBPE23613 - for ; Thu, 6 Dec 2001 10:11:25 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB6F5MR55091 - for ; Thu, 6 Dec 2001 09:08:01 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16317=candle.pha.pa.us=pgman@postgresql.org) -Received: from tiger.tigrasoft (fw.tigrasoft.hu [195.70.42.161]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB5JWMm92521; - Wed, 5 Dec 2001 14:32:26 -0500 (EST) - (envelope-from hornyakl@freemail.hu) -Received: from freemail.hu ([192.168.0.200]) - by tiger.tigrasoft (8.9.3/8.9.3/Debian 8.9.3-21) with ESMTP id UAA20333; - Wed, 5 Dec 2001 20:30:51 +0100 -X-Authentication-Warning: tiger.tigrasoft: Host [192.168.0.200] claimed to be freemail.hu -Message-ID: <3C0E77F0.5030904@freemail.hu> -Date: Wed, 05 Dec 2001 20:39:28 +0100 -From: Laszlo Hornyak -Reply-To: hornyakl@users.sourceforge.net -User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.4) Gecko/20010913 -X-Accept-Language: hu, en-us -MIME-Version: 1.0 -To: Barry Lind , pgsql-hackers@postgresql.org, - pgsql-jdbc@postgresql.org -Subject: Re: [HACKERS] [GENERAL] java stored procedures -References: <3C074DE4.9040905@freemail.hu> <3C0BE325.3020809@xythos.com> <3C0C937E.9000405@freemail.hu> <3C0CFD82.1030600@xythos.com> <3C0D219C.1090804@freemail.hu> <3C0D799D.4010808@xythos.com> <3C0DE382.1050400@freemail.hu> <3C0E5A23.7060701@xythos.com> -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Barry Lind wrote: - -> -> I also stopped cc'ing the general list, since this is getting too -> detailed for most of the members on that list. - -Ok. - -> Now to your mail: -> -> This seems like a reasonable approach and should work across different -> JVMs. It would probably be a good experiment to try this with the Sun -> or IBM jvm at some point to verify. What I was afraid of was that you -> were hacking the Kaffe code to perform the integration which would -> limit this solution to only using Kaffe. - -I am sure they wont work the same way. I think I have a sun jdk 1.3.0-2, -so I will try to port it soon. The IBM implementation must wait I think -until january. - -> -> Just a suggestion: PL/J might be a good name, since as you probably -> know it can't be called pl/java because of the trademark restrictions -> on the word 'java'. - -Ok, you won, I do not read the licenses. From now it`s name is pl/j. -Isn`t 'j' too short for the name of the process that runns java? :) - -> -> I am a little concerned about the stability and complexity of having -> this '-pizza' program be responsible for handling the calls on the -> java side. My concern is that this will need to be a multithreaded -> program since multiple backends will concurrently be needing to -> interact with multiple java threads through this one program. It -> might be simpler if each postgres process directly communicated to a -> java thread via a tcpip socket. Then the "-pizza" program would only -> need to be responsible for starting up the jvm and creating java -> threads and sockets for a postgres process (it would perform a similar -> role to postmaster for postgres client connections). - -With good design we can solve stability problems. As much as I know, if -postmaster dies, the postgres server becomes unavailable, this looks the -same problem. I do not know if we realy need sockets. Anyway, if 'j' -dies, we can create a new one, and restart calculations. Some watchdog -functionality... -Doing thing with sockets need a lot of rework. It is the best time for -this, while there is not too much thing done. - ->>> ->>>> -when java thread receives the signal, it reads the message(s) from ->>>> the queue, and starts some actions. When done it tells postgres ->>>> with a signal that it is ready, and it can come for its results. ->>>> This will be rewritten see below problems. ->>> ->>> Are signals the best way to accomplish this? ->> ->> I don`t know if it is the best, it is the only way I know :) ->> Do you know any other ways? ->> -> I don't know, but hopefully someone on the hackers list will chip in -> here with a comment. - -After a first developement cycle (if my brain doesn`t burn down), the -signals can be replaced to a plugable communication interface I think. -So maybe we can use CORBA, or sockets, or something else. This will take -a lot of time. - -> OK, so the same backend process that called the function gets messaged -> to process the sql. This should work. However it means you will need -> a special version of the jdbc driver that uses this shm+signals -> communication mechanism instead of what the current jdbc driver does. -> This is something I would be happy to help you with. - - -This is kind of you. :) -For this, I will have to finish the protocol of communication. I have to -learn Postgres enough, so I am not sure this will be done this weekend. -I have ideas, only time is needed to implement them or to recognize the -failures. - -Thanks, -Laszlo Hornyak - - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M16313=candle.pha.pa.us=pgman@postgresql.org Thu Dec 6 10:01:29 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB6F1RZ28000 - for ; Thu, 6 Dec 2001 10:01:27 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB6F1OE19111 - for ; Thu, 6 Dec 2001 10:01:25 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB6EvtR54729 - for ; Thu, 6 Dec 2001 08:59:16 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16313=candle.pha.pa.us=pgman@postgresql.org) -Received: from tiger.tigrasoft (fw.tigrasoft.hu [195.70.42.161]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB6EFfm64066; - Thu, 6 Dec 2001 09:15:41 -0500 (EST) - (envelope-from hornyakl@freemail.hu) -Received: from freemail.hu ([192.168.0.200]) - by tiger.tigrasoft (8.9.3/8.9.3/Debian 8.9.3-21) with ESMTP id PAA29094; - Thu, 6 Dec 2001 15:15:01 +0100 -X-Authentication-Warning: tiger.tigrasoft: Host [192.168.0.200] claimed to be freemail.hu -Message-ID: <3C0F7F6B.2060605@freemail.hu> -Date: Thu, 06 Dec 2001 15:23:39 +0100 -From: Laszlo Hornyak -Reply-To: hornyakl@users.sourceforge.net -User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.4) Gecko/20010913 -X-Accept-Language: hu, en-us -MIME-Version: 1.0 -To: Gunnar =?ISO-8859-1?Q?R=F8nning?= -cc: Barry Lind , pgsql-hackers@postgresql.org, - pgsql-jdbc@postgresql.org -Subject: Re: [HACKERS] [GENERAL] java stored procedures -References: <3C074DE4.9040905@freemail.hu> <3C0BE325.3020809@xythos.com> <3C0C937E.9000405@freemail.hu> <3C0CFD82.1030600@xythos.com> -Content-Type: text/plain; charset=ISO-8859-1; format=flowed -Content-Transfer-Encoding: 8bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Hi! - -Sorry, I have time only for short ansvers, it is company time :((. - -Gunnar Rønning wrote: - ->* Barry Lind wrote: ->| ->| possible problems with your strategy). Without knowing what exactly ->| you are thinking of doing it is difficult to comment. -> ->Agreed. -> -Ok, I will try to bring the code here before Monday, or at least some -pieces. It is full of hardcoded constants from my developement -environment. :( - - -> ->| I am very interested in hearing what your plans are for pl/java. I ->| think this is a very difficult project, but one that would be very ->| useful and welcome. -> ->I would very much like to hear about the plans myself. -> -I do not see so big difficulities yet, am I so lame? It won`t be easy, -realy, we should keep it simple, at least becouse of me. - - -thanks, -Laszlo Hornyak - - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M16334=candle.pha.pa.us=pgman@postgresql.org Thu Dec 6 16:11:23 2001 -Return-path: -Received: from west.navpoint.com (west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fB6LBLZ25078 - for ; Thu, 6 Dec 2001 16:11:22 -0500 (EST) -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by west.navpoint.com (8.11.6/8.10.1) with ESMTP id fB6LBMa12305 - for ; Thu, 6 Dec 2001 16:11:22 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fB6L6wR66812 - for ; Thu, 6 Dec 2001 15:08:01 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16334=candle.pha.pa.us=pgman@postgresql.org) -Received: from rh72.home.ee (adsl895.estpak.ee [213.168.23.133]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fB6Kxtm98840; - Thu, 6 Dec 2001 15:59:55 -0500 (EST) - (envelope-from hannu@tm.ee) -Received: from tm.ee (localhost.localdomain [127.0.0.1]) - by rh72.home.ee (8.11.6/8.11.6) with ESMTP id fB6I2pn02024; - Thu, 6 Dec 2001 23:02:52 +0500 -Message-ID: <3C0FB2CB.90901@tm.ee> -Date: Thu, 06 Dec 2001 23:02:51 +0500 -From: Hannu Krosing -User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.4) Gecko/20011019 Netscape6/6.2 -X-Accept-Language: et, en-us -MIME-Version: 1.0 -To: hornyakl@users.sourceforge.net -cc: Gunnar =?ISO-8859-1?Q?R=F8nning?= , - Barry Lind - , pgsql-hackers@postgresql.org, - pgsql-jdbc@postgresql.org -Subject: Re: [HACKERS] [GENERAL] java stored procedures -References: <3C074DE4.9040905@freemail.hu> <3C0BE325.3020809@xythos.com> <3C0C937E.9000405@freemail.hu> <3C0CFD82.1030600@xythos.com> <3C0F7F6B.2060605@freemail.hu> -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Laszlo Hornyak wrote: - ->> ->> | I am very interested in hearing what your plans are for pl/java. I ->> | think this is a very difficult project, but one that would be very ->> | useful and welcome. ->> ->> I would very much like to hear about the plans myself. -> -> I do not see so big difficulities yet, am I so lame? It won`t be easy, -> realy, we should keep it simple, at least becouse of me. - -Let me propose a very different approach to PL/J - use gcc-java and -figure out the problems -with (dynamic) compiling and dynamic linking. - -This is an approach somewhat similar to .NET/C# that you first compile -things and then run instead -of trying to do both at the same time ;) - -Oracle /may/ be doing something similar with their java stored -procedures, as they claim these to be "compiled". - ------------------ -Hannu - - - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M17140@postgresql.org Thu Jan 3 09:13:32 2002 -Return-path: -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g03EDVc00444 - for ; Thu, 3 Jan 2002 09:13:31 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id g03E41N54463; - Thu, 3 Jan 2002 08:04:01 -0600 (CST) - (envelope-from pgsql-hackers-owner+M17140@postgresql.org) -Received: from tiger.tigrasoft (fw.tigrasoft.hu [195.70.42.161]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g01Csdm40742 - for ; Tue, 1 Jan 2002 07:54:39 -0500 (EST) - (envelope-from hornyakl@freemail.hu) -Received: from freemail.hu ([192.168.0.200]) - by tiger.tigrasoft (8.9.3/8.9.3/Debian 8.9.3-21) with ESMTP id NAA14425; - Tue, 1 Jan 2002 13:54:35 +0100 -X-Authentication-Warning: tiger.tigrasoft: Host [192.168.0.200] claimed to be freemail.hu -Message-ID: <3C31B3B7.6030703@freemail.hu> -Date: Tue, 01 Jan 2002 14:03:51 +0100 -From: Laszlo Hornyak -Reply-To: hornyakl@users.sourceforge.net -User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.4) Gecko/20010913 -X-Accept-Language: hu, en-us -MIME-Version: 1.0 -To: pgsql-hackers@postgresql.org, ssutjiono@wc-group.com -Subject: [HACKERS] PL/(pg)J -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Happy new year for all! - -I would like to tell you about the results of my work on pl/j. -memo: Java and postgres must run in a separate address space. First I -wanted to use the sys v ipc, which was a bad idea becouse of some -problems with java VM-s. Many hackers told me about its bad sides, and -the good sides of the sockets, so I droped the whole code and started a -new one. - -I started to write the java side first, which is maybe almost 10% ready :)) --we have is a communication protocol between the two process. I know -noone will like it, so there is an API for protocols, so it is plugable. -The current implementation is receiveing calls,sends exceptions, but -sending the results is not implemented yet. - --the Postgres side is not yet done. It sends function calls without -arguments, it doesn`t receive sql queries, exceptions or results at all, -and there is no API for it, it is an uggly hardcoded thing. - --there is no JDBC implementation, and I have never written JDBC driver, -so it may take for a while... - -But it says "hello world" :)) - -Todo for me: - --learn more about postgres, jdbc drivers, etc, etc --develop api for the postgres side of the communication. - -This will take for a good while becouse of other todos but I hope next -time I can tell you good news. - -thx, -Laszlo Hornyak - - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-general-owner+M19758=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 11:33:11 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NGXAU13298 - for ; Wed, 23 Jan 2002 11:33:10 -0500 (EST) -Received: (qmail 89931 invoked by alias); 23 Jan 2002 16:32:58 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 16:32:58 -0000 -Received: from barry.xythos.com (h-64-105-36-191.SNVACAID.covad.net [64.105.36.191]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0NG9Tl75462 - for ; Wed, 23 Jan 2002 11:09:29 -0500 (EST) - (envelope-from barry@xythos.com) -Received: from xythos.com (localhost.localdomain [127.0.0.1]) - by barry.xythos.com (8.11.6/8.11.6) with ESMTP id g0N1sGn24841; - Tue, 22 Jan 2002 17:54:16 -0800 -Message-ID: <3C4E17C8.8040909@xythos.com> -Date: Tue, 22 Jan 2002 17:54:16 -0800 -From: Barry Lind -User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.7) Gecko/20011221 -X-Accept-Language: en-us -MIME-Version: 1.0 -To: Nic Ferrier -cc: Doug McNaught , pgsql-general@postgresql.org -Subject: Re: [GENERAL] implemention of calls to stored procs. -References: <87sn8yx6xu.fsf@tf1.tapsellferrier.co.uk> <87n0z5yjer.fsf@tf1.tapsellferrier.co.uk> -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-general-owner@postgresql.org -Status: OR - -Nic, - -Check out http://www.rootshell.be/~hornyakl/download -This has the latest code for pl/pgj. The Java procedure language support -that Laszlo Hornyak (hornyakl@users.sourceforge.net) has been working on -for the last month or so. - -thanks, ---Barry - - -Nic Ferrier wrote: - -> Firstly, thanks for your responses... good to know I was thinking the -> right thing (and, yes, I was taking the process thing into account, -> tho' I didn't realise threads weren't used at all). -> -> -> Doug McNaught writes: -> -> ->>Nic Ferrier writes: ->> ->> ->>>I've been looking at the implementation of the procedural language ->>>support code with a view to writing a java plugin (ie: something to ->>>allow java classes to be used as stored procs). ->>> ->> ->>Someone else has been talking about this--check the archives from the ->>last six months. ->> -> -> I couldn't find any reference but the archive searcher is broken right -> now and a manual search is not very reliable. -> -> It's not terribly difficult to crack this actually... I was going to -> use GCJ as a platform for a base java class that could be used like a -> quick C stored proc. -> -> I envisage having a natively implemented JDBC Connection passed to an -> init method in such a class. -> -> -> GCJ is perfect for this task because it has a native call interface, -> CNI, which is a seamless part of the class heirarchy. -> -> Once I've got something working I'll drop a line here. -> -> -> -> Nic -> -> ---------------------------(end of broadcast)--------------------------- -> TIP 5: Have you checked our extensive FAQ? -> -> http://www.postgresql.org/users-lounge/docs/faq.html -> -> - - - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - diff --git a/doc/TODO.detail/mmap b/doc/TODO.detail/mmap deleted file mode 100644 index 77dc3993af..0000000000 --- a/doc/TODO.detail/mmap +++ /dev/null @@ -1,577 +0,0 @@ -From pgsql-hackers-owner+M5149@postgresql.org Mon Feb 26 03:32:49 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id DAA04497 - for ; Mon, 26 Feb 2001 03:32:48 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f1Q8TSx48319; - Mon, 26 Feb 2001 03:29:28 -0500 (EST) - (envelope-from pgsql-hackers-owner+M5149@postgresql.org) -Received: from store.d.zembu.com (nat.zembu.com [209.128.96.253]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id f1Q8LPx47243 - for ; Mon, 26 Feb 2001 03:21:25 -0500 (EST) - (envelope-from ncm@zembu.com) -Received: by store.d.zembu.com (Postfix, from userid 509) - id 58E39A782; Mon, 26 Feb 2001 00:21:25 -0800 (PST) -Date: Mon, 26 Feb 2001 00:21:25 -0800 -To: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Re: [PATCHES] A patch for xlog.c -Message-ID: <20010226002125.A2430@store.zembu.com> -Reply-To: pgsql-hackers@postgresql.org -References: <200102260200.VAA17397@candle.pha.pa.us> <22318.983161726@sss.pgh.pa.us> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.2.5i -In-Reply-To: <22318.983161726@sss.pgh.pa.us>; from tgl@sss.pgh.pa.us on Sun, Feb 25, 2001 at 11:28:46PM -0500 -From: ncm@zembu.com (Nathan Myers) -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: ORr - -On Sun, Feb 25, 2001 at 11:28:46PM -0500, Tom Lane wrote: -> Bruce Momjian writes: -> > It allows no backing store on disk. - -I.e. it allows you to map memory without an associated inode; the memory -may still be swapped. Of course, there is no problem with mapping an -inode too, so that unrelated processes can join in. Solarix has a flag -to pin the shared pages in RAM so they can't be swapped out. - -> > It is the BSD solution to SysV -> > share memory. Here are all the BSDi flags: -> -> > MAP_ANON Map anonymous memory not associated with any specific -> > file. The file descriptor used for creating MAP_ANON -> > must be -1. The offset parameter is ignored. -> -> Hmm. Now that I read down to the "nonstandard extensions" part of the -> HPUX man page for mmap(), I find -> -> If MAP_ANONYMOUS is set in flags: -> -> o A new memory region is created and initialized to all zeros. -> This memory region can be shared only with descendants of -> the current process. - -This is supported on Linux and BSD, but not on Solarix 7. It's not -necessary; you can just map /dev/zero on SysV systems that don't -have MAP_ANON. - -> While I've said before that I don't think it's really necessary for -> processes that aren't children of the postmaster to access the shared -> memory, I'm not sure that I want to go over to a mechanism that makes it -> *impossible* for that to be done. Especially not if the only motivation -> is to avoid having to configure the kernel's shared memory settings. - -There are enormous advantages to avoiding the need to configure kernel -settings. It makes PG a better citizen. PG is much easier to drop in -and use if you don't need attention from the IT department. - -But I don't know of any reason to avoid mapping an actual inode, -so using mmap doesn't necessarily mean giving up sharing among -unrelated processes. - -> Besides, what makes you think there's not a limit on the size of shmem -> allocatable via mmap()? - -I've never seen any mmap limit documented. Since mmap() is how -everybody implements shared libraries, such a limit would be equivalent -to a limit on how much/many shared libraries are used. mmap() with -MAP_ANONYMOUS (or its SysV /dev/zero equivalent) is a common, modern -way to get raw storage for malloc(), so such a limit would be a limit -on malloc() too. - -The mmap architecture comes to us from the Mach microkernel memory -manager, backported into BSD and then copied widely. Since it was -the fundamental mechanism for all memory operations in Mach, arbitrary -limits would make no sense. That it worked so well is the reason it -was copied everywhere else, so adding arbitrary limits while copying -it would be silly. I don't think we'll see any systems like that. - -Nathan Myers -ncm@zembu.com - -From pgsql-hackers-owner+M6138@postgresql.org Mon Mar 19 07:57:59 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id HAA26926 - for ; Mon, 19 Mar 2001 07:57:59 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f2JCug641835; - Mon, 19 Mar 2001 07:56:42 -0500 (EST) - (envelope-from pgsql-hackers-owner+M6138@postgresql.org) -Received: from fw.wintelcom.net (ns1.wintelcom.net [209.1.153.20]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id f2JCt7641684 - for ; Mon, 19 Mar 2001 07:55:07 -0500 (EST) - (envelope-from bright@fw.wintelcom.net) -Received: (from bright@localhost) - by fw.wintelcom.net (8.10.0/8.10.0) id f2JCt2325289; - Mon, 19 Mar 2001 04:55:02 -0800 (PST) -Date: Mon, 19 Mar 2001 04:55:01 -0800 -From: Alfred Perlstein -To: Rod Taylor -Cc: Hackers List -Subject: Re: [HACKERS] Fw: [vorbis-dev] ogg123: shared memory by mmap() -Message-ID: <20010319045500.T29888@fw.wintelcom.net> -References: <018301c0b070$16049a40$2205010a@jester> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.2.5i -In-Reply-To: <018301c0b070$16049a40$2205010a@jester>; from rod.taylor@inquent.com on Mon, Mar 19, 2001 at 07:28:21AM -0500 -X-all-your-base: are belong to us. -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: ORr - -WOOT WOOT! DANGER WILL ROBINSON! - -> ----- Original Message ----- -> From: "Christian Weisgerber" -> Newsgroups: list.vorbis.dev -> To: -> Sent: Saturday, March 17, 2001 12:01 PM -> Subject: [vorbis-dev] ogg123: shared memory by mmap() -> -> -> > The patch below adds: -> > -> > - acinclude.m4: A new macro A_FUNC_SMMAP to check that sharing -> pages -> > through mmap() works. This is taken from Joerg Schilling's star. -> > - configure.in: A_FUNC_SMMAP -> > - ogg123/buffer.c: If we have a working mmap(), use it to create -> > a region of shared memory instead of using System V IPC. -> > -> > Works on BSD. Should also work on SVR4 and offspring (Solaris), -> > and Linux. - -This is a really bad idea performance wise. Solaris has a special -code path for SYSV shared memory that doesn't require tons of swap -tracking structures per-page/per-process. FreeBSD also has this -optimization (it's off by default, but should work since FreeBSD -4.2 via the sysctl kern.ipc.shm_use_phys=1) - -Both OS's use a trick of making the pages non-pageable, this allows -signifigant savings in kernel space required for each attached -process, as well as the use of large pages which reduce the amount -of TLB faults your processes will incurr. - -Anyhow, if you could make this a runtime option it wouldn't be so -evil, but as a compile time option, it's a really bad idea for -Solaris and FreeBSD. - --- --Alfred Perlstein - [bright@wintelcom.net|alfred@freebsd.org] - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M6255@postgresql.org Tue Mar 20 18:46:33 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id SAA02887 - for ; Tue, 20 Mar 2001 18:46:33 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.3/8.11.1) with SMTP id f2KNjtH22390; - Tue, 20 Mar 2001 18:45:55 -0500 (EST) - (envelope-from pgsql-hackers-owner+M6255@postgresql.org) -Received: from fw.wintelcom.net (ns1.wintelcom.net [209.1.153.20]) - by mail.postgresql.org (8.11.3/8.11.1) with ESMTP id f2KNiFH22033 - for ; Tue, 20 Mar 2001 18:44:15 -0500 (EST) - (envelope-from bright@fw.wintelcom.net) -Received: (from bright@localhost) - by fw.wintelcom.net (8.10.0/8.10.0) id f2KNiAW02417; - Tue, 20 Mar 2001 15:44:10 -0800 (PST) -Date: Tue, 20 Mar 2001 15:44:10 -0800 -From: Alfred Perlstein -To: Bruce Momjian -Cc: Rod Taylor , - Hackers List -Subject: Re: [HACKERS] Fw: [vorbis-dev] ogg123: shared memory by mmap() -Message-ID: <20010320154410.H29888@fw.wintelcom.net> -References: <20010319045500.T29888@fw.wintelcom.net> <200103202210.RAA23981@candle.pha.pa.us> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.2.5i -In-Reply-To: <200103202210.RAA23981@candle.pha.pa.us>; from pgman@candle.pha.pa.us on Tue, Mar 20, 2001 at 05:10:33PM -0500 -X-all-your-base: are belong to us. -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -* Bruce Momjian [010320 14:10] wrote: -> > > > The patch below adds: -> > > > -> > > > - acinclude.m4: A new macro A_FUNC_SMMAP to check that sharing -> > > pages -> > > > through mmap() works. This is taken from Joerg Schilling's star. -> > > > - configure.in: A_FUNC_SMMAP -> > > > - ogg123/buffer.c: If we have a working mmap(), use it to create -> > > > a region of shared memory instead of using System V IPC. -> > > > -> > > > Works on BSD. Should also work on SVR4 and offspring (Solaris), -> > > > and Linux. -> > -> > This is a really bad idea performance wise. Solaris has a special -> > code path for SYSV shared memory that doesn't require tons of swap -> > tracking structures per-page/per-process. FreeBSD also has this -> > optimization (it's off by default, but should work since FreeBSD -> > 4.2 via the sysctl kern.ipc.shm_use_phys=1) -> -> > -> > Both OS's use a trick of making the pages non-pageable, this allows -> > signifigant savings in kernel space required for each attached -> > process, as well as the use of large pages which reduce the amount -> > of TLB faults your processes will incurr. -> -> That is interesting. BSDi has SysV shared memory as non-pagable, and I -> always thought of that as a bug. Seems you are saying that having it -> pagable has a significant performance penalty. Interesting. - -Yes, having it pageable is actually sort of bad. - -It doesn't allow you to do several important optimizations. - --- --Alfred Perlstein - [bright@wintelcom.net|alfred@freebsd.org] - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-general-owner+M14300@postgresql.org Mon Aug 27 13:07:32 2001 -Return-path: -Received: from server1.pgsql.org (server1.pgsql.org [64.39.15.238]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id f7RH7VF04800 - for ; Mon, 27 Aug 2001 13:07:31 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by server1.pgsql.org (8.11.6/8.11.6) with ESMTP id f7RH7Tq17721; - Mon, 27 Aug 2001 12:07:29 -0500 (CDT) - (envelope-from pgsql-general-owner+M14300@postgresql.org) -Received: from svana.org (svana.org [210.9.66.30]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id f7RFE1f13269 - for ; Mon, 27 Aug 2001 11:14:01 -0400 (EDT) - (envelope-from kleptog@svana.org) -Received: from kleptog by svana.org with local (Exim 3.12 #1 (Debian)) - id 15bO5x-0000Fd-00; Tue, 28 Aug 2001 01:14:33 +1000 -Date: Tue, 28 Aug 2001 01:14:33 +1000 -From: Martijn van Oosterhout -To: Andrew Snow -cc: pgsql-general@postgresql.org -Subject: Re: [GENERAL] raw partition -Message-ID: <20010828011433.E32309@svana.org> -Reply-To: Martijn van Oosterhout -References: <20010827233815.B32309@svana.org> <000101c12f00$dc5814b0$fa01b5ca@avon> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.2.5i -In-Reply-To: <000101c12f00$dc5814b0$fa01b5ca@avon>; from andrew@modulus.org on Tue, Aug 28, 2001 at 12:02:08AM +1000 -Precedence: bulk -Sender: pgsql-general-owner@postgresql.org -Status: OR - -On Tue, Aug 28, 2001 at 12:02:08AM +1000, Andrew Snow wrote: -> -> What I think would be better would be moving postgresql to a system of -> using memory-mapped I/O. instead of the shared buffer cache, files -> would be directly memory-mapped and the OS would do the caching. I -> can't see this happening though because of platform dependancy, but I -> think its worth another look soon because many unix platforms support -> mmap(). I think it would improve the performance of disk-intensive -> tasks noticeably. - -Well, this has other problems. Consider tables that are larger than your -system memory. You'd have to continuously map and unmap different sections. -That can have odd side effects (witness mozilla on linux having 15,000 -mapped areas or so...) - -You would still however get the advantage that you wouldn't have to copy the -data from the disk buffers to user space, you simply get the disk buffer -mapped into your address space. - -I think that for commonly used tables that are under 100K in size (most of -the system tables), this is quite a workable idea. If you don't mind keeping -them mapped the whole time. - --- -Martijn van Oosterhout -http://svana.org/kleptog/ -> It would be nice if someone came up with a certification system that -> actually separated those who can barely regurgitate what they crammed over -> the last few weeks from those who command secret ninja networking powers. - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-general-owner+M14319@postgresql.org Mon Aug 27 16:57:10 2001 -Return-path: -Received: from server1.pgsql.org (server1.pgsql.org [64.39.15.238]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id f7RKv9F16849 - for ; Mon, 27 Aug 2001 16:57:09 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by server1.pgsql.org (8.11.6/8.11.6) with ESMTP id f7RKv9q31456; - Mon, 27 Aug 2001 15:57:09 -0500 (CDT) - (envelope-from pgsql-general-owner+M14319@postgresql.org) -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id f7RJrsf55472 - for ; Mon, 27 Aug 2001 15:53:54 -0400 (EDT) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id f7RJrGK19431; - Mon, 27 Aug 2001 15:53:16 -0400 (EDT) -To: Martijn van Oosterhout -cc: Andrew Snow , pgsql-general@postgresql.org -Subject: Re: [GENERAL] raw partition -In-Reply-To: <20010828011433.E32309@svana.org> -References: <20010827233815.B32309@svana.org> <000101c12f00$dc5814b0$fa01b5ca@avon> <20010828011433.E32309@svana.org> -Comments: In-reply-to Martijn van Oosterhout - message dated "Tue, 28 Aug 2001 01:14:33 +1000" -Date: Mon, 27 Aug 2001 15:53:15 -0400 -Message-ID: <19428.998941995@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-general-owner@postgresql.org -Status: OR - -Martijn van Oosterhout writes: -> You would still however get the advantage that you wouldn't have to copy the -> data from the disk buffers to user space, you simply get the disk buffer -> mapped into your address space. - -AFAICS this would be the *only* advantage. While it's not negligible, -it's quite unclear that it's worth the bookkeeping and portability -headaches of managing lots of mmap'd areas, either. - -Before I take this idea seriously at all, I'd want to see a design that -addresses a couple of critical issues: - -1. Postgres' shared buffers are *shared*, potentially across many -processes. How will you deal with buffers for files that have been -mmap'd by only some of the processes? (Maybe this means that the -whole concept of shared buffers goes away, and each process does its -own buffer management based on its own mmaps. Not sure. That would be -a pretty radical restructuring though, and would completely invalidate -our present approach to page-level locking.) - -2. How do you deal with extending a file? My system's mmap man page -says - If the size of the mapped file changes after the call to mmap(), the - effect of references to portions of the mapped region that correspond - to added or removed portions of the file is unspecified. -This suggests that the only portable way to cope is to issue a separate -mmap for every disk page. Will typical Unix systems perform well with -umpteen thousand small mmap requests? - -3. How do you persuade the other backends to drop their mmaps of a table -you are deleting? - -There are probably other gotchas, but without an understanding of how -to address these, I doubt it's worth looking further ... - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M13750=candle.pha.pa.us=pgman@postgresql.org Mon Oct 1 05:59:15 2001 -Return-path: -Received: from server1.pgsql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id f919xF512590 - for ; Mon, 1 Oct 2001 05:59:15 -0400 (EDT) -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by server1.pgsql.org (8.11.6/8.11.6) with ESMTP id f919xA207817 - for ; Mon, 1 Oct 2001 04:59:10 -0500 (CDT) - (envelope-from pgsql-hackers-owner+M13750=candle.pha.pa.us=pgman@postgresql.org) -Received: from mrsgntmail01.mediaring.com.sg (mserver.mediaring.com.sg [203.208.141.175]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id f919rE320926 - for ; Mon, 1 Oct 2001 05:53:15 -0400 (EDT) - (envelope-from jana-reddy@mediaring.com.sg) -Received: by MRSGNTMAIL01 with Internet Mail Service (5.5.2650.21) - id ; Mon, 1 Oct 2001 18:03:34 +0800 -Received: from mediaring.com.sg (10.1.0.131 [10.1.0.131]) by mrsgntmail01.mediaring.com.sg with SMTP (Microsoft Exchange Internet Mail Service Version 5.5.2650.21) - id PMTCM7SH; Mon, 1 Oct 2001 18:03:25 +0800 -From: Janardhana Reddy -To: Bruce Momjian , Tom Lane -cc: PostgreSQL-development , - janareddy - -Message-ID: <3BB83DF0.8946973@mediaring.com.sg> -Date: Mon, 01 Oct 2001 17:57:04 +0800 -X-Mailer: Mozilla 4.75 [en] (X11; U; Linux 2.4.0 i686) -X-Accept-Language: en -MIME-Version: 1.0 -Subject: Re: [HACKERS] PERFORMANCE IMPROVEMENT by mapping WAL FILES -References: <200109282137.f8SLbpm01890@candle.pha.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: ORr - - I have just completed the functional testing the WAL using mmap , it is - - working fine, I have tested by commenting out the "CreateCheckPoint " -functionality so that - when i kill the postgres and restart it will redo all the records from the -WAL log file which - is updated using mmap. - Just i need to clean code and to do some stress testing. - By the end of this week i should able to complete the stress test and -generate the patch file . - As Tom Lane mentioned i see the problem in portability to all platforms, - - what i propose is to use mmap for only WAL for some platforms like - linux,freebsd etc . For other platforms we can use the existing method by -slightly modifying the - write() routine to write only the modified part of the page. - -Regards -jana - -> -> -> OK, I have talked to Tom Lane about this on the phone and we have a few -> ideas. -> -> Historically, we have avoided mmap() because of portability problems, -> and because using mmap() to write to large tables could consume lots of -> address space with little benefit. However, I perhaps can see WAL as -> being a good use of mmap. -> -> First, there is the issue of using mmap(). For OS's that have the -> mmap() MAP_SHARED flag, different backends could mmap the same file and -> each see the changes. However, keep in mind we still have to fsync() -> WAL, so we need to use msync(). -> -> So, looking at the benefits of using mmap(), we have overhead of -> different backends having to mmap something that now sits quite easily -> in shared memory. Now, I can see mmap reducing the copy from user to -> kernel, but there are other ways to fix that. We could modify the -> write() routines to write() 8k on first WAL page write and later write -> only the modified part of the page to the kernel buffers. The old -> kernel buffer is probably still around so it is unlikely to require a -> read from the file system to read in the rest of the page. This reduces -> the write from 8k to something probably less than 4k which is better -> than we can do with mmap. -> -> I will add a TODO item to this effect. -> -> As far as reducing the write to disk from 8k to 4k, if we have to -> fsync/msync, we have to wait for the disk to spin to the proper location -> and at that point writing 4k or 8k doesn't seem like much of a win. -> -> In summary, I think it would be nice to reduce the 8k transfer from user -> to kernel on secondary page writes to only the modified part of the -> page. I am uncertain if mmap() or anything else will help the physical -> write to the disk. -> -> -- -> Bruce Momjian | http://candle.pha.pa.us -> pgman@candle.pha.pa.us | (610) 853-3000 -> + If your life is a hard drive, | 830 Blythe Avenue -> + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M23388@postgresql.org Mon Jun 3 17:54:43 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g53LsgB05125 - for ; Mon, 3 Jun 2002 17:54:42 -0400 (EDT) -Received: from localhost.localdomain (postgresql.org [64.49.215.8]) - by localhost (Postfix) with ESMTP - id 15421475884; Mon, 3 Jun 2002 17:54:14 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 8B89B4761F0; Mon, 3 Jun 2002 17:53:49 -0400 (EDT) -Received: from localhost.localdomain (postgresql.org [64.49.215.8]) - by localhost (Postfix) with ESMTP id D0F90475ECD - for ; Mon, 3 Jun 2002 17:53:38 -0400 (EDT) -Received: from motgate3.mot.com (motgate3.mot.com [144.189.100.103]) - by postgresql.org (Postfix) with ESMTP id 5CE5147593B - for ; Mon, 3 Jun 2002 17:53:13 -0400 (EDT) -Received: [from pobox.mot.com (pobox.mot.com [129.188.137.100]) by motgate3.mot.com (motgate3 2.1) with ESMTP id OAA22235; Mon, 3 Jun 2002 14:52:44 -0700 (MST)] -Received: [from pronto1.comm.mot.com (pronto1.comm.mot.com [173.6.1.22]) by pobox.mot.com (MOT-pobox 2.0) with ESMTP id OAA19166; Mon, 3 Jun 2002 14:52:59 -0700 (MST)] -Received: from kovalenkoigor (idennt19534 [145.1.195.34]) - by pronto1.comm.mot.com (8.9.3/8.9.3) with SMTP id QAA20419; - Mon, 3 Jun 2002 16:52:57 -0500 (CDT) -Message-ID: <0e0a01c20b49$26e90a00$22c30191@comm.mot.com> -From: "Igor Kovalenko" -To: "Bruce Momjian" -cc: "Tom Lane" , "mlw" , - "Marc G. Fournier" , -References: <200206030047.g530lZi21901@candle.pha.pa.us> -Subject: Re: [HACKERS] HEADS UP: Win32/OS2/BeOS native ports -Date: Mon, 3 Jun 2002 16:53:51 -0500 -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook Express 5.00.2919.6600 -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2919.6600 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -That's what Apache does. Note, on most platforms MAP_ANON is equivalent to -mmmap-ing /dev/zero. Solaris for example does not provide MAP_ANON but using - -fd=open(/dev/zero) -mmap(fd, ...) -close(fd) - -works just fine. - ------ Original Message ----- -From: "Bruce Momjian" -To: "Igor Kovalenko" -Cc: "Tom Lane" ; "mlw" ; "Marc G. -Fournier" ; -Sent: Sunday, June 02, 2002 7:47 PM -Subject: Re: [HACKERS] HEADS UP: Win32/OS2/BeOS native ports - - -> Igor Kovalenko wrote: -> > It does not have to be anonymous. POSIX also defines shm_open(same -arguments -> > as open) API which will create named object in whatever location -corresponds -> > to shared memory storage on that platform (object is then grown to -needed -> > size by ftruncate() and the fd is then passed to mmap). The object will -> > exist in name space and can be detected by subsequent calls to -shm_open() -> > with same name. It is not really different from doing open(), but more -> > portable (mmap() on regular files may not be supported). -> -> Actually, I think the best shared memory implemention would be -> MAP_ANON | MAP_SHARED mmap(), which could be called from the postmaster -> and passed to child processes. -> -> While all our platforms have mmap(), many don't have MAP_ANON, but those -> that do could use it. You need MAP_ANON to prevent the shared memory -> from being written to a disk file. -> -> -- -> Bruce Momjian | http://candle.pha.pa.us -> pgman@candle.pha.pa.us | (610) 853-3000 -> + If your life is a hard drive, | 830 Blythe Avenue -> + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 -> - - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - diff --git a/doc/TODO.detail/namedatalen b/doc/TODO.detail/namedatalen deleted file mode 100644 index 24eeeb1abd..0000000000 --- a/doc/TODO.detail/namedatalen +++ /dev/null @@ -1,1070 +0,0 @@ -From pgsql-hackers-owner+M18800=candle.pha.pa.us=pgman@postgresql.org Wed Feb 13 15:25:43 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g1DKPgP09129 - for ; Wed, 13 Feb 2002 15:25:42 -0500 (EST) -Received: (qmail 83025 invoked by alias); 13 Feb 2002 20:25:41 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 13 Feb 2002 20:25:41 -0000 -Received: from h97.c194.tor.velocet.net (H97.C194.tor.velocet.net [216.138.194.97]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g1DK7kE77269 - for ; Wed, 13 Feb 2002 15:07:47 -0500 (EST) - (envelope-from rbt@zort.ca) -Received: (qmail 41141 invoked by uid 0); 13 Feb 2002 20:07:41 -0000 -Received: from h97.c194.tor.velocet.net (HELO jester) (216.138.194.97) - by 192.168.1.11 with RC4-MD5 encrypted SMTP; 13 Feb 2002 20:07:41 -0000 -Message-ID: <003901c1b4ca$1d762500$8001a8c0@jester> -From: "Rod Taylor" -To: "Hackers List" -Subject: [HACKERS] NAMEDATALEN Changes -Date: Wed, 13 Feb 2002 15:07:50 -0500 -MIME-Version: 1.0 -Content-Type: multipart/mixed; - boundary="----=_NextPart_000_0036_01C1B4A0.343E4DF0" -X-Priority: 3 -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook Express 6.00.2600.0000 -X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -This is a multi-part message in MIME format. - -------=_NextPart_000_0036_01C1B4A0.343E4DF0 -Content-Type: text/plain; charset="iso-8859-1" -Content-Transfer-Encoding: 7bit - -NAMEDATALEN's benchmarked are 32, 64, 128 and 512. Attached is the -shell script I used to do it. - -First row of a set is the time(1) for the pgbench -i run, second is -the actual benchmark. Aside from the 'real' time of 64 there is a -distinct increase in time required, but not significant. - -Benchmarks were run for 3000 transactions with scale factor of 5, but -only 1 client. If there is a preferred setting for pgbench I can do -an overnight run with it. Machine is a dual 500Mhz celery with 384MB -ram and 2 IBM Deskstars in Raid 0, and a seperate system drive. - -Anything but 32 fails the 'name' check in the regression tests -- I -assume this is expected? - -Don't know why 64 has a high 'real' time, but the system times are -appropriate. - -NAMEDATALEN: 32 - -158.97 real 1.81 user 0.14 sys - -80.58 real 1.30 user 3.81 sys - - - -NAMEDATALEN: 64 - -248.40 real 1.85 user 0.10 sys - -96.36 real 1.44 user 3.86 sys - - - -NAMEDATALEN: 128 - -156.74 real 1.84 user 0.10 sys - -94.36 real 1.47 user 4.01 sys - - - -NAMEDATALEN: 512 - -157.99 real 1.83 user 0.12 sys - -101.14 real 1.47 user 4.23 sys - --- -Rod Taylor - -Your eyes are weary from staring at the CRT. You feel sleepy. Notice -how restful it is to watch the cursor blink. Close your eyes. The -opinions stated above are yours. You cannot imagine why you ever felt -otherwise. - - -------=_NextPart_000_0036_01C1B4A0.343E4DF0 -Content-Type: application/octet-stream; name="datalenbench.sh" -Content-Transfer-Encoding: quoted-printable -Content-Disposition: attachment; filename="datalenbench.sh" - -#!/bin/sh - -PGSRC=3D/data/buildtree/postgres/postgresql-7.2 -PGBASEPORT=3D5400 -PGBASEBIN=3D/data/buildtree/postgres/postgres72 - -LOG=3D/home/rbt/temp/bench_namedatalen.log - - -for newDATALEN in 32 64 128 512 ; do - - PGBIN=3D${PGBASEBIN}_${newDATALEN} - PGPORT=3D`echo "${PGBASEPORT}+${newDATALEN}" | bc` - - sed -E 's/NAMEDATALEN\s[0-9]+/NAMEDATALEN ${newDATALEN}/g' ${PGSRC}/src/i= -nclude/postgres_ext.h > ${PGSRC}/src/include/postgres_ext.h.tmp - mv ${PGSRC}/src/include/postgres_ext.h.tmp ${PGSRC}/src/include/postgres_= -ext.h - - cd ${PGSRC} - ./configure --prefix=3D${PGBIN} --with-pgport=3D${PGPORT} || (echo "UNABL= -E TO CONFIGURE"; exit) - - make clean - make clean install - - cd ${PGSRC}/contrib/pgbench - - gmake install - - - ${PGBIN}/bin/initdb -D ${PGBIN}/data || (echo "UNABLE TO INITIALIZE"; ex= -it 1) - - ${PGBIN}/bin/pg_ctl -D ${PGBIN}/data start || (echo "UNABLE TO START"; e= -xit 1) - - sleep 5 - - echo "NAMEDATALEN: ${newDATALEN}" >> ${LOG} - echo >> ${LOG} - time -a -o ${LOG} ${PGBIN}/bin/pgbench -i -s 5 -d template1 -p ${PGPORT} - - time -a -o ${LOG} ${PGBIN}/bin/pgbench -t 3000 -s 5 -d template1 -p ${PGP= -ORT} - echo >> ${LOG} - echo >> ${LOG} - - ${PGBIN}/bin/pg_ctl -D ${PGBIN}/data stop - rm -rf ${PGBIN} -done - -------=_NextPart_000_0036_01C1B4A0.343E4DF0 -Content-Type: text/plain -Content-Disposition: inline -Content-Transfer-Encoding: binary -MIME-Version: 1.0 - - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -------=_NextPart_000_0036_01C1B4A0.343E4DF0-- - - -From pgsql-hackers-owner+M18806=candle.pha.pa.us=pgman@postgresql.org Wed Feb 13 17:13:45 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g1DMDiP15852 - for ; Wed, 13 Feb 2002 17:13:44 -0500 (EST) -Received: (qmail 13525 invoked by alias); 13 Feb 2002 22:12:53 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 13 Feb 2002 22:12:53 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g1DLsHE09337 - for ; Wed, 13 Feb 2002 16:54:17 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g1DLrmf00943; - Wed, 13 Feb 2002 16:53:49 -0500 (EST) -To: "Rod Taylor" -cc: "Hackers List" -Subject: Re: [HACKERS] NAMEDATALEN Changes -In-Reply-To: <003901c1b4ca$1d762500$8001a8c0@jester> -References: <003901c1b4ca$1d762500$8001a8c0@jester> -Comments: In-reply-to "Rod Taylor" - message dated "Wed, 13 Feb 2002 15:07:50 -0500" -Date: Wed, 13 Feb 2002 16:53:48 -0500 -Message-ID: <940.1013637228@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -"Rod Taylor" writes: -> [ some hard data ] - -Great! The numbers for namedatalen = 64 seem like an outlier; perhaps -something else going on on your system? Did you try more than one run? - -> Anything but 32 fails the 'name' check in the regression tests -- I -> assume this is expected? - -Right. If you eyeball the actual diffs for the test you should see that -the diff is due to a long name not getting truncated where the test -expects it to be. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M18805=candle.pha.pa.us=pgman@postgresql.org Wed Feb 13 17:13:39 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g1DMDcP15802 - for ; Wed, 13 Feb 2002 17:13:39 -0500 (EST) -Received: (qmail 13545 invoked by alias); 13 Feb 2002 22:12:54 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 13 Feb 2002 22:12:54 -0000 -Received: from h97.c194.tor.velocet.net (H97.C194.tor.velocet.net [216.138.194.97]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g1DM7iE12735 - for ; Wed, 13 Feb 2002 17:07:44 -0500 (EST) - (envelope-from rbt@zort.ca) -Received: (qmail 41562 invoked by uid 0); 13 Feb 2002 22:07:45 -0000 -Received: from h97.c194.tor.velocet.net (HELO jester) (216.138.194.97) - by 192.168.1.11 with RC4-MD5 encrypted SMTP; 13 Feb 2002 22:07:45 -0000 -Message-ID: <00f501c1b4da$e2f7b7c0$8001a8c0@jester> -From: "Rod Taylor" -To: "Tom Lane" -cc: "Hackers List" -References: <003901c1b4ca$1d762500$8001a8c0@jester> <940.1013637228@sss.pgh.pa.us> -Subject: Re: [HACKERS] NAMEDATALEN Changes -Date: Wed, 13 Feb 2002 17:07:54 -0500 -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook Express 6.00.2600.0000 -X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -> > Great! The numbers for namedatalen = 64 seem like an outlier; -perhaps -> something else going on on your system? Did you try more than one -run? - -Ran it again shortly after sending the email. It fell in line (mid -way between 32 and 128) with Real time as would normally be expected. -The times for the other values and 64's system times were very close -to the original so I won't bother posting them again. - - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M18807=candle.pha.pa.us=pgman@postgresql.org Wed Feb 13 17:58:53 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g1DMwqP19126 - for ; Wed, 13 Feb 2002 17:58:52 -0500 (EST) -Received: (qmail 26752 invoked by alias); 13 Feb 2002 22:58:21 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 13 Feb 2002 22:58:21 -0000 -Received: from post.webmailer.de (natwar.webmailer.de [192.67.198.70]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g1DMRoE22486 - for ; Wed, 13 Feb 2002 17:27:51 -0500 (EST) - (envelope-from barwick@gmx.net) -Received: from there (pD9EB1E9E.dip.t-dialin.net [217.235.30.158]) - by post.webmailer.de (8.9.3/8.8.7) with SMTP id XAA22201; - Wed, 13 Feb 2002 23:27:16 +0100 (MET) -Message-ID: <200202132227.XAA22201@post.webmailer.de> -From: Ian Barwick -To: "Rod Taylor" , "Hackers List" -Subject: Re: [HACKERS] NAMEDATALEN Changes -Date: Wed, 13 Feb 2002 23:27:08 +0100 -X-Mailer: KMail [version 1.3.1] -References: <003901c1b4ca$1d762500$8001a8c0@jester> -In-Reply-To: <003901c1b4ca$1d762500$8001a8c0@jester> -MIME-Version: 1.0 -Content-Type: Multipart/Mixed; - boundary="------------Boundary-00=_81THUZ3BONDS8SCE1A8O" -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - ---------------Boundary-00=_81THUZ3BONDS8SCE1A8O -Content-Type: text/plain; charset="iso-2022-jp" -Content-Transfer-Encoding: 8bit - -On Wednesday 13 February 2002 21:07, Rod Taylor wrote: -> NAMEDATALEN's benchmarked are 32, 64, 128 and 512. Attached is the -> shell script I used to do it. - -Attached is a modified version for Linux, if anyone is interested. - -Will run it overnight out of quasi-scientific interest. - -Nice to have an idea what kind of effect my very long NAMEDATALEN setting -(128) has. - - -Yours - -Ian Barwick ---------------Boundary-00=_81THUZ3BONDS8SCE1A8O -Content-Type: application/x-shellscript; name="datalenbench.sh" -Content-Transfer-Encoding: base64 -Content-Disposition: attachment; filename="datalenbench.sh" - -IyEvYmluL3NoCgpQR1NSQz1+cG9zdGdyZXMvcGdiZW5jaC9wb3N0Z3Jlc3Fs -LTcuMgpQR0JBU0VQT1JUPTU0MDAKUEdCQVNFQklOPX5wb3N0Z3Jlcy9ob21l -L3Bvc3RncmVzL3BnYmVuY2gvcG9zdGdyZXM3MgoKTE9HPX5wb3N0Z3Jlcy9i -ZW5jaF9uYW1lZGF0YWxlbi5sb2cKCmZvciBuZXdEQVRBTEVOIGluIDMyIDY0 -IDEyOCA1MTIgOyBkbwoKICBQR0JJTj0ke1BHQkFTRUJJTn1fJHtuZXdEQVRB -TEVOfQogIFBHUE9SVD1gZWNobyAiJHtQR0JBU0VQT1JUfSske25ld0RBVEFM -RU59IiB8IGJjYAoKICBzZWQgInMvTkFNRURBVEFMRU5bWzpzcGFjZTpdXVsw -LTldXHsxLFx9L05BTUVEQVRBTEVOICRuZXdEQVRBTEVOL2ciICR7UEdTUkN9 -L3NyYy9pbmNsdWRlL3Bvc3RncmVzX2V4dC5oID4gJHtQR1NSQ30vc3JjL2lu -Y2x1ZGUvcG9zdGdyZXNfZXh0LmgudG1wCiAgbXYgJHtQR1NSQ30vc3JjL2lu -Y2x1ZGUvcG9zdGdyZXNfZXh0LmgudG1wICR7UEdTUkN9L3NyYy9pbmNsdWRl -L3Bvc3RncmVzX2V4dC5oCgogIGNkICR7UEdTUkN9CgogIC4vY29uZmlndXJl -IC0tcHJlZml4PSR7UEdCSU59IC0td2l0aC1wZ3BvcnQ9JHtQR1BPUlR9IHx8 -IChlY2hvICJVTkFCTEUgVE8gQ09ORklHVVJFIjsgZXhpdCkKCiAgbWFrZSBj -bGVhbgogIG1ha2UgY2xlYW4gaW5zdGFsbAoKICBjZCAke1BHU1JDfS9jb250 -cmliL3BnYmVuY2gKCiAgZ21ha2UgaW5zdGFsbAoKCiAgJHtQR0JJTn0vYmlu -L2luaXRkYiAtRCAke1BHQklOfS9kYXRhICB8fCAoZWNobyAiVU5BQkxFIFRP -IElOSVRJQUxJWkUiOyBleGl0IDEpCgogICR7UEdCSU59L2Jpbi9wZ19jdGwg -LUQgJHtQR0JJTn0vZGF0YSBzdGFydCAgfHwgKGVjaG8gIlVOQUJMRSBUTyBT -VEFSVCI7IGV4aXQgMSkKCiAgc2xlZXAgNQoKICBlY2hvICJOQU1FREFUQUxF -TjogJHtuZXdEQVRBTEVOfSIgPj4gJHtMT0d9CgogICMgcG9pbnQgdG8gR05V -IHRpbWUgKHNob3VsZCB3b3JrIG9uIHJlY2VudCBTdVNFIC8gUmVkSGF0KTsg -WU1NVgogIFRJTUU9L3Vzci9iaW4vdGltZQogIFRJTUVfRk9STUFUPSIlZSBy -ZWFsICVVIHVzZXIgJVMgc3lzIgoKICAkVElNRSAtYSAtbyAke0xPR30gLWYg -IiRUSU1FX0ZPUk1BVCIgJHtQR0JJTn0vYmluL3BnYmVuY2ggLWkgLXMgNSAt -ZCB0ZW1wbGF0ZTEgLXAgJHtQR1BPUlR9CgogICRUSU1FIC1hIC1vICR7TE9H -fSAtZiAiJFRJTUVfRk9STUFUIiAke1BHQklOfS9iaW4vcGdiZW5jaCAtdCAz -MDAwIC1zIDUgLWQgdGVtcGxhdGUxIC1wICR7UEdQT1JUfSAKICBlY2hvICA+ -PiAke0xPR30KICBlY2hvICA+PiAke0xPR30KCiAgJHtQR0JJTn0vYmluL3Bn -X2N0bCAtRCAke1BHQklOfS9kYXRhIHN0b3AKICBybSAtcmYgJHtQR0JJTn0K -ZG9uZQoK - ---------------Boundary-00=_81THUZ3BONDS8SCE1A8O -Content-Type: text/plain -Content-Disposition: inline -Content-Transfer-Encoding: binary -MIME-Version: 1.0 - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - ---------------Boundary-00=_81THUZ3BONDS8SCE1A8O-- - -From pgsql-hackers-owner+M18811=candle.pha.pa.us=pgman@postgresql.org Wed Feb 13 19:13:40 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g1E0DdP24221 - for ; Wed, 13 Feb 2002 19:13:39 -0500 (EST) -Received: (qmail 40165 invoked by alias); 14 Feb 2002 00:13:34 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 14 Feb 2002 00:13:34 -0000 -Received: from student.gvsu.edu ([148.61.7.124]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g1E0ABE39822 - for ; Wed, 13 Feb 2002 19:10:11 -0500 (EST) - (envelope-from peter_e@gmx.net) -Received: from [148.61.250.151] [148.61.250.151] by student.gvsu.edu - with Novonyx SMTP Server $Revision: 1.1 $; Wed, 13 Feb 2002 19:10:16 -0500 (EDT) -Date: Wed, 13 Feb 2002 19:12:57 -0500 (EST) -From: Peter Eisentraut -X-Sender: -To: Rod Taylor -cc: Hackers List -Subject: Re: [HACKERS] NAMEDATALEN Changes -In-Reply-To: <003901c1b4ca$1d762500$8001a8c0@jester> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Rod Taylor writes: - -> NAMEDATALEN's benchmarked are 32, 64, 128 and 512. Attached is the -> shell script I used to do it. - -That's around a 15% performance loss for increasing it to 64 or 128. -Seems pretty scary actually. - --- -Peter Eisentraut peter_e@gmx.net - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M18815=candle.pha.pa.us=pgman@postgresql.org Wed Feb 13 20:02:31 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g1E12TP29895 - for ; Wed, 13 Feb 2002 20:02:29 -0500 (EST) -Received: (qmail 49786 invoked by alias); 14 Feb 2002 01:02:26 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 14 Feb 2002 01:02:26 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g1E10oE49562 - for ; Wed, 13 Feb 2002 20:00:50 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g1E107f04416; - Wed, 13 Feb 2002 20:00:07 -0500 (EST) -To: Peter Eisentraut -cc: Rod Taylor , Hackers List -Subject: Re: [HACKERS] NAMEDATALEN Changes -In-Reply-To: -References: -Comments: In-reply-to Peter Eisentraut - message dated "Wed, 13 Feb 2002 19:12:57 -0500" -Date: Wed, 13 Feb 2002 20:00:06 -0500 -Message-ID: <4413.1013648406@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Peter Eisentraut writes: -> That's around a 15% performance loss for increasing it to 64 or 128. -> Seems pretty scary actually. - -Some of that could be bought back by fixing hashname() to not iterate -past the first \0 when calculating the hash of a NAME datum; and then -cc_hashname could go away. Not sure how much this would buy though. - -Looking closely at Rod's script, I realize that the user+sys times it is -reporting are not the backend's but the pgbench client's. So it's -impossible to tell from this how much of the extra cost is extra I/O and -how much is CPU. I'm actually quite surprised that the client side -shows any CPU-time difference at all; I wouldn't think it ever sees any -null-padded NAME values. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M18817=candle.pha.pa.us=pgman@postgresql.org Thu Feb 14 01:22:04 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g1E6M3P26219 - for ; Thu, 14 Feb 2002 01:22:03 -0500 (EST) -Received: (qmail 83168 invoked by alias); 14 Feb 2002 06:22:05 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 14 Feb 2002 06:22:05 -0000 -Received: from klamath.dyndns.org (CPE002078144ae0.cpe.net.cable.rogers.com [24.102.202.35]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g1E5xfE81904 - for ; Thu, 14 Feb 2002 00:59:41 -0500 (EST) - (envelope-from nconway@klamath.dyndns.org) -Received: from localhost.localdomain (jiro [192.168.40.7]) - by klamath.dyndns.org (Postfix) with ESMTP id 11D2E7007 - for ; Thu, 14 Feb 2002 00:59:41 -0500 (EST) -Subject: Re: [HACKERS] NAMEDATALEN Changes -From: Neil Conway -To: pgsql-hackers@postgresql.org -In-Reply-To: <4413.1013648406@sss.pgh.pa.us> -References: - <4413.1013648406@sss.pgh.pa.us> -Content-Type: multipart/mixed; boundary="=-0nvLRoTY5hWeegGhITre" -X-Mailer: Evolution/1.0.2 -Date: 14 Feb 2002 00:59:40 -0500 -Message-ID: <1013666380.5380.19.camel@jiro> -MIME-Version: 1.0 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: ORr - ---=-0nvLRoTY5hWeegGhITre -Content-Type: text/plain -Content-Transfer-Encoding: 7bit - -On Wed, 2002-02-13 at 20:00, Tom Lane wrote: -> Peter Eisentraut writes: -> > That's around a 15% performance loss for increasing it to 64 or 128. -> > Seems pretty scary actually. -> -> Some of that could be bought back by fixing hashname() to not iterate -> past the first \0 when calculating the hash of a NAME datum; and then -> cc_hashname could go away. Not sure how much this would buy though. - -I've attached a pretty trivial patch that implements this. Instead of -automatically hashing NAMEDATALEN bytes, hashname() uses only strlen() -bytes: this should improve both the common case (small identifers, 5-10 -characters long), as well as reduce the penalty when NAMEDATALEN is -increased. The patch passes the regression tests, FWIW. I didn't remove -cc_hashname() -- I'll tackle that tomorrow unless anyone objects... - -I also did some pretty simple benchmarks; however, I'd appreciate it -anyone could confirm these results. - -pg_bench: scale factor 1, 1 client, 10000 transactions. - -hardware: p3-850, 384 MB RAM, slow laptop IDE disk - -Run 1: Patch applied, NAMEDATALEN = 32 - - number of transactions actually processed: 10000/10000 - tps = 19.940020(including connections establishing) - tps = 19.940774(excluding connections establishing) - -Run 2: Patch applied, NAMEDATALEN = 128 - - number of transactions actually processed: 10000/10000 - tps = 20.849385(including connections establishing) - tps = 20.850010(excluding connections establishing) - -Run 3: Vanilla CVS, NAMEDATALEN = 32 -(This is to check that the patch doesn't cause performance regressions -for the "common case") - - number of transactions actually processed: 10000/10000 - tps = 18.295418(including connections establishing) - tps = 18.296191(excluding connections establishing) - -The performance improvement @ NAMEDATALEN = 128 seems strange. As I -said, these benchmarks may not be particularly accurate, so I'd suggest -waiting for others to contribute results before drawing any conclusions. - -Oh, and this is my first "real" Pg patch, so my apologies if I've -screwed something up. ;-) - -Cheers, - -Neil - --- -Neil Conway -PGP Key ID: DB3C29FC - ---=-0nvLRoTY5hWeegGhITre -Content-Disposition: attachment; filename=hash_len.patch -Content-Transfer-Encoding: quoted-printable -Content-Type: text/x-patch; charset=ISO-8859-1 - -*** ./src/backend/access/hash/hashfunc.c.orig Wed Feb 13 21:09:37 2002 ---- ./src/backend/access/hash/hashfunc.c Thu Feb 14 00:39:42 2002 -*************** -*** 95,101 **** - { - char *key =3D NameStr(*PG_GETARG_NAME(0)); -=20=20 -! return hash_any((char *) key, NAMEDATALEN); - } -=20=20 - /* ---- 95,101 ---- - { - char *key =3D NameStr(*PG_GETARG_NAME(0)); -=20=20 -! return hash_any(key, strlen(key)); - } -=20=20 - /* -*************** -*** 125,131 **** - * - * (Comment from the original db3 hashing code: ) - * -! * "This is INCREDIBLY ugly, but fast. We break the string up into 8 byte - * units. On the first time through the loop we get the 'leftover bytes' - * (strlen % 8). On every later iteration, we perform 8 HASHC's so we ha= -ndle - * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. = - If ---- 125,131 ---- - * - * (Comment from the original db3 hashing code: ) - * -! * This is INCREDIBLY ugly, but fast. We break the string up into 8 byte - * units. On the first time through the loop we get the 'leftover bytes' - * (strlen % 8). On every later iteration, we perform 8 HASHC's so we ha= -ndle - * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. = - If -*************** -*** 134,140 **** - * "OZ's original sdbm hash" - */ - Datum -! hash_any(char *keydata, int keylen) - { - uint32 n; - int loop; ---- 134,140 ---- - * "OZ's original sdbm hash" - */ - Datum -! hash_any(const char *keydata, int keylen) - { - uint32 n; - int loop; -*** ./src/include/access/hash.h.orig Wed Feb 13 22:43:06 2002 ---- ./src/include/access/hash.h Thu Feb 14 00:38:35 2002 -*************** -*** 265,271 **** - extern Datum hashint2vector(PG_FUNCTION_ARGS); - extern Datum hashname(PG_FUNCTION_ARGS); - extern Datum hashvarlena(PG_FUNCTION_ARGS); -! extern Datum hash_any(char *keydata, int keylen); -=20=20 -=20=20 - /* private routines */ ---- 265,271 ---- - extern Datum hashint2vector(PG_FUNCTION_ARGS); - extern Datum hashname(PG_FUNCTION_ARGS); - extern Datum hashvarlena(PG_FUNCTION_ARGS); -! extern Datum hash_any(const char *keydata, int keylen); -=20=20 -=20=20 - /* private routines */ - ---=-0nvLRoTY5hWeegGhITre -Content-Type: text/plain -Content-Disposition: inline -Content-Transfer-Encoding: binary -MIME-Version: 1.0 - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - ---=-0nvLRoTY5hWeegGhITre-- - - -From pgsql-hackers-owner+M18819=candle.pha.pa.us=pgman@postgresql.org Thu Feb 14 09:03:43 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g1EE3gP17661 - for ; Thu, 14 Feb 2002 09:03:42 -0500 (EST) -Received: (qmail 68050 invoked by alias); 14 Feb 2002 14:03:37 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 14 Feb 2002 14:03:37 -0000 -Received: from CopelandConsulting.Net (dsl-24293-ld.customer.centurytel.net [209.142.135.135]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g1EE1FE67720 - for ; Thu, 14 Feb 2002 09:01:15 -0500 (EST) - (envelope-from greg@copelandconsulting.net) -Received: from there (mouse.copelandconsulting.net [192.168.1.2]) - by CopelandConsulting.Net (8.10.1/8.10.1) with SMTP id g1EE1Dk24399; - Thu, 14 Feb 2002 08:01:14 -0600 (CST) -Message-ID: -X-Trade-Id: -Organization: Copeland Computer Consulting -To: Neil Conway , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] NAMEDATALEN Changes -Date: Thu, 14 Feb 2002 08:00:58 -0600 -X-Mailer: KMail [version 1.3.1] -References: <4413.1013648406@sss.pgh.pa.us> <1013666380.5380.19.camel@jiro> -In-Reply-To: <1013666380.5380.19.camel@jiro> -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - -On Wednesday 13 February 2002 23:59, Neil Conway wrote: -> On Wed, 2002-02-13 at 20:00, Tom Lane wrote: - -[perf hit comment removed] - -> -> I've attached a pretty trivial patch that implements this. Instead of -> automatically hashing NAMEDATALEN bytes, hashname() uses only strlen() -> bytes: this should improve both the common case (small identifers, 5-10 -> characters long), as well as reduce the penalty when NAMEDATALEN is -> increased. The patch passes the regression tests, FWIW. I didn't remove -> cc_hashname() -- I'll tackle that tomorrow unless anyone objects... -> -> I also did some pretty simple benchmarks; however, I'd appreciate it -> anyone could confirm these results. -> - -Please bare with me on this as this is my first posting having any real -content.  Please don't hang me out if I've overlooked anything and I'm -pointing out that I'm making a rather large assumption. Please correct as -needed. - -The primary assumption is that the actual key lengths can be less than -NAMEDATALEN. That is, if the string, "shortkey" is a valid input key (??) -which provides a key length of 8-bytes as input to the hash_any() function -even though NAMEDATALEN may be something like 128 or larger. If this -assumption is correct, then wouldn't increasing the default input key size -(NAMEDATALEN) beyond the maximum actual key length be a bug? That is to say, -if we have a key with only 8-bytes of data and we iterrate over 128-bytes, -wouldn't the resulting hash be arbitrary and invalid as it would be hashing -memory which is not reflective of the key being hashed? - -If my assumptions are correct, then it sounds like using the strlen() -implementation (assuming input keys are valid C-strings) is really the proper -implementation short of using an adjusted min(NAMEDATALEN,strlen()) type -approach. - -[snip - var NAMEDATALEN benchmark results] - - -Greg ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.0.6 (GNU/Linux) -Comment: For info see http://www.gnupg.org - -iD8DBQE8a8Mg4lr1bpbcL6kRAlaxAJ47CO+ExL/ZMo/i6LDoetXrul9qqQCfQli3 -AvqN6RJjSuAH/p/mpZ8J4JY= -=wnVM ------END PGP SIGNATURE----- - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M18820=candle.pha.pa.us=pgman@postgresql.org Thu Feb 14 10:14:25 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g1EFEOP25217 - for ; Thu, 14 Feb 2002 10:14:24 -0500 (EST) -Received: (qmail 80096 invoked by alias); 14 Feb 2002 15:14:19 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 14 Feb 2002 15:14:19 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g1EEvpE77298 - for ; Thu, 14 Feb 2002 09:57:51 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g1EEvof08568; - Thu, 14 Feb 2002 09:57:50 -0500 (EST) -To: Greg Copeland -cc: Neil Conway , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] NAMEDATALEN Changes -In-Reply-To: -References: <4413.1013648406@sss.pgh.pa.us> <1013666380.5380.19.camel@jiro> -Comments: In-reply-to Greg Copeland - message dated "Thu, 14 Feb 2002 08:00:58 -0600" -Date: Thu, 14 Feb 2002 09:57:50 -0500 -Message-ID: <8565.1013698670@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Greg Copeland writes: -> if we have a key with only 8-bytes of data and we iterrate over 128-bytes, -> wouldn't the resulting hash be arbitrary and invalid as it would be hashing -> memory which is not reflective of the key being hashed? - -As long as we do it *consistently*, we can do it either way. Using the -trailing nulls in the hash does alter the computed hash value --- but -we're only ever gonna compare the hash value against other hash values -computed on other NAMEs by this same routine. - -This all assumes that the inputs are valid NAMEs, viz strlen < -NAMEDATALEN and no funny business beyond the first \0. In practice, -however, if a bogus NAME were handed to us we would just as soon ignore -any characters beyond the first \0, because the ordering comparison -operators for NAME all do so (they're all based on strncmp), as do the -I/O routines etc. So this change actually makes the system more -self-consistent not less so. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18827=candle.pha.pa.us=pgman@postgresql.org Thu Feb 14 13:53:52 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g1EIrpP17729 - for ; Thu, 14 Feb 2002 13:53:51 -0500 (EST) -Received: (qmail 47648 invoked by alias); 14 Feb 2002 18:53:50 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 14 Feb 2002 18:53:50 -0000 -Received: from klamath.dyndns.org (CPE002078144ae0.cpe.net.cable.rogers.com [24.102.202.35]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g1EIbiE46318 - for ; Thu, 14 Feb 2002 13:37:44 -0500 (EST) - (envelope-from nconway@klamath.dyndns.org) -Received: by klamath.dyndns.org (Postfix, from userid 1000) - id 032E8700C; Thu, 14 Feb 2002 13:37:44 -0500 (EST) -Date: Thu, 14 Feb 2002 13:37:43 -0500 -To: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] NAMEDATALEN Changes -Message-ID: <20020214183743.GA10423@klamath.dyndns.org> -Mail-Followup-To: pgsql-hackers@postgresql.org -References: <4413.1013648406@sss.pgh.pa.us> <1013666380.5380.19.camel@jiro> -MIME-Version: 1.0 -Content-Type: multipart/mixed; boundary="huq684BweRXVnRxX" -Content-Disposition: inline -In-Reply-To: <1013666380.5380.19.camel@jiro> -User-Agent: Mutt/1.3.27i -From: nconway@klamath.dyndns.org (Neil Conway) -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - ---huq684BweRXVnRxX -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline - -On Thu, Feb 14, 2002 at 12:59:40AM -0500, Neil Conway wrote: -> I've attached a pretty trivial patch that implements this. Instead of -> automatically hashing NAMEDATALEN bytes, hashname() uses only strlen() -> bytes: this should improve both the common case (small identifers, 5-10 -> characters long), as well as reduce the penalty when NAMEDATALEN is -> increased. The patch passes the regression tests, FWIW. I didn't remove -> cc_hashname() -- I'll tackle that tomorrow unless anyone objects... - -Okay, I've attached a new version that removes cc_hashname(). As with -the previous patch, this passes the regression tests. Feedback is welcome. - -Cheers, - -Neil - - ---huq684BweRXVnRxX -Content-Type: text/plain; charset=us-ascii -Content-Disposition: attachment; filename="hash_len.patch" - -*** ./src/backend/access/hash/hashfunc.c.orig Wed Feb 13 21:09:37 2002 ---- ./src/backend/access/hash/hashfunc.c Thu Feb 14 00:39:42 2002 -*************** -*** 95,101 **** - { - char *key = NameStr(*PG_GETARG_NAME(0)); - -! return hash_any((char *) key, NAMEDATALEN); - } - - /* ---- 95,101 ---- - { - char *key = NameStr(*PG_GETARG_NAME(0)); - -! return hash_any(key, strlen(key)); - } - - /* -*************** -*** 125,131 **** - * - * (Comment from the original db3 hashing code: ) - * -! * "This is INCREDIBLY ugly, but fast. We break the string up into 8 byte - * units. On the first time through the loop we get the 'leftover bytes' - * (strlen % 8). On every later iteration, we perform 8 HASHC's so we handle - * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If ---- 125,131 ---- - * - * (Comment from the original db3 hashing code: ) - * -! * This is INCREDIBLY ugly, but fast. We break the string up into 8 byte - * units. On the first time through the loop we get the 'leftover bytes' - * (strlen % 8). On every later iteration, we perform 8 HASHC's so we handle - * all 8 bytes. Essentially, this saves us 7 cmp & branch instructions. If -*************** -*** 134,140 **** - * "OZ's original sdbm hash" - */ - Datum -! hash_any(char *keydata, int keylen) - { - uint32 n; - int loop; ---- 134,140 ---- - * "OZ's original sdbm hash" - */ - Datum -! hash_any(const char *keydata, int keylen) - { - uint32 n; - int loop; -*** ./src/backend/utils/cache/catcache.c.orig Thu Feb 14 12:51:00 2002 ---- ./src/backend/utils/cache/catcache.c Thu Feb 14 12:53:05 2002 -*************** -*** 93,99 **** - static Index CatalogCacheComputeTupleHashIndex(CatCache *cache, - HeapTuple tuple); - static void CatalogCacheInitializeCache(CatCache *cache); -- static Datum cc_hashname(PG_FUNCTION_ARGS); - - - /* ---- 93,98 ---- -*************** -*** 109,115 **** - case CHAROID: - return hashchar; - case NAMEOID: -! return cc_hashname; - case INT2OID: - return hashint2; - case INT2VECTOROID: ---- 108,114 ---- - case CHAROID: - return hashchar; - case NAMEOID: -! return hashname; - case INT2OID: - return hashint2; - case INT2VECTOROID: -*************** -*** 129,151 **** - return (PGFunction) NULL; - } - } -- -- static Datum -- cc_hashname(PG_FUNCTION_ARGS) -- { -- /* -- * We need our own variant of hashname because we want to accept -- * null-terminated C strings as search values for name fields. So, we -- * have to make sure the data is correctly padded before we compute -- * the hash value. -- */ -- NameData my_n; -- -- namestrcpy(&my_n, NameStr(*PG_GETARG_NAME(0))); -- -- return DirectFunctionCall1(hashname, NameGetDatum(&my_n)); -- } -- - - /* - * Standard routine for creating cache context if it doesn't exist yet ---- 128,133 ---- -*** ./src/include/access/hash.h.orig Wed Feb 13 22:43:06 2002 ---- ./src/include/access/hash.h Thu Feb 14 00:38:35 2002 -*************** -*** 265,271 **** - extern Datum hashint2vector(PG_FUNCTION_ARGS); - extern Datum hashname(PG_FUNCTION_ARGS); - extern Datum hashvarlena(PG_FUNCTION_ARGS); -! extern Datum hash_any(char *keydata, int keylen); - - - /* private routines */ ---- 265,271 ---- - extern Datum hashint2vector(PG_FUNCTION_ARGS); - extern Datum hashname(PG_FUNCTION_ARGS); - extern Datum hashvarlena(PG_FUNCTION_ARGS); -! extern Datum hash_any(const char *keydata, int keylen); - - - /* private routines */ - ---huq684BweRXVnRxX -Content-Type: text/plain -Content-Disposition: inline -Content-Transfer-Encoding: binary -MIME-Version: 1.0 - - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - ---huq684BweRXVnRxX-- - -From pgsql-hackers-owner+M18833=candle.pha.pa.us=pgman@postgresql.org Thu Feb 14 16:22:34 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g1ELMXP07956 - for ; Thu, 14 Feb 2002 16:22:34 -0500 (EST) -Received: (qmail 80517 invoked by alias); 14 Feb 2002 21:22:29 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 14 Feb 2002 21:22:29 -0000 -Received: from post.webmailer.de (natpost.webmailer.de [192.67.198.65]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g1EL2mE77720 - for ; Thu, 14 Feb 2002 16:02:48 -0500 (EST) - (envelope-from barwick@gmx.net) -Received: from there (pD9EB17D4.dip.t-dialin.net [217.235.23.212]) - by post.webmailer.de (8.9.3/8.8.7) with SMTP id WAA07320 - for ; Thu, 14 Feb 2002 22:02:49 +0100 (MET) -Message-ID: <200202142102.WAA07320@post.webmailer.de> -Content-Type: text/plain; - charset="iso-2022-jp" -From: Ian Barwick -To: "Hackers List" -Subject: Re: [HACKERS] NAMEDATALEN Changes -Date: Thu, 14 Feb 2002 22:02:34 +0100 -X-Mailer: KMail [version 1.3.1] -References: <003901c1b4ca$1d762500$8001a8c0@jester> <200202132227.XAA22201@post.webmailer.de> -In-Reply-To: <200202132227.XAA22201@post.webmailer.de> -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wednesday 13 February 2002 23:27, Ian Barwick wrote: -> On Wednesday 13 February 2002 21:07, Rod Taylor wrote: -> > NAMEDATALEN's benchmarked are 32, 64, 128 and 512. Attached is the -> > shell script I used to do it. -> -> Attached is a modified version for Linux, if anyone is interested. -> -> Will run it overnight out of quasi-scientific interest. -> -> Nice to have an idea what kind of effect my very long NAMEDATALEN setting -> (128) has. - -Below the probably quite uninformative results, run under Linux with 2.2.16 -on an AMD K2 350Mhz with 256MB RAM, EIDE HDs and other run of the mill -hardware. - -I suspect some of the normal system jobs which usually run during the night -caused the wildly varying results. Whatever else, for my purposes at least -any performance issues with differening NAMEDATALENgths are nothing much -to worry about. - - -NAMEDATALEN: 32 -220.73 real 3.39 user 0.10 sys -110.03 real 2.77 user 4.42 sys - - -NAMEDATALEN: 64 -205.31 real 3.55 user 0.08 sys -109.76 real 2.53 user 4.18 sys - - -NAMEDATALEN: 128 -224.65 real 3.35 user 0.10 sys -121.30 real 2.60 user 3.89 sys - - -NAMEDATALEN: 256 -209.48 real 3.62 user 0.11 sys -118.90 real 3.00 user 3.88 sys - - -NAMEDATALEN: 512 -204.65 real 3.36 user 0.14 sys -115.12 real 2.54 user 3.88 sys - - -Ian Barwick - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - diff --git a/doc/TODO.detail/optimizer b/doc/TODO.detail/optimizer deleted file mode 100644 index 194ca349d3..0000000000 --- a/doc/TODO.detail/optimizer +++ /dev/null @@ -1,2005 +0,0 @@ -From owner-pgsql-hackers@hub.org Mon Mar 22 18:43:41 1999 -Received: from renoir.op.net (root@renoir.op.net [209.152.193.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id SAA23978 - for ; Mon, 22 Mar 1999 18:43:39 -0500 (EST) -Received: from hub.org (majordom@hub.org [209.47.145.100]) by renoir.op.net (o1/$ Revision: 1.18 $) with ESMTP id SAA06472 for ; Mon, 22 Mar 1999 18:36:44 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.2/8.9.1) with SMTP id SAA92604; - Mon, 22 Mar 1999 18:34:23 -0500 (EST) - (envelope-from owner-pgsql-hackers@hub.org) -Received: by hub.org (TLB v0.10a (1.23 tibbs 1997/01/09 00:29:32)); Mon, 22 Mar 1999 18:33:50 +0000 (EST) -Received: (from majordom@localhost) - by hub.org (8.9.2/8.9.1) id SAA92469 - for pgsql-hackers-outgoing; Mon, 22 Mar 1999 18:33:47 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from po8.andrew.cmu.edu (PO8.ANDREW.CMU.EDU [128.2.10.108]) - by hub.org (8.9.2/8.9.1) with ESMTP id SAA92456 - for ; Mon, 22 Mar 1999 18:33:41 -0500 (EST) - (envelope-from er1p+@andrew.cmu.edu) -Received: (from postman@localhost) by po8.andrew.cmu.edu (8.8.5/8.8.2) id SAA12894 for pgsql-hackers@postgresql.org; Mon, 22 Mar 1999 18:33:38 -0500 (EST) -Received: via switchmail; Mon, 22 Mar 1999 18:33:38 -0500 (EST) -Received: from cloudy.me.cmu.edu via qmail - ID ; - Mon, 22 Mar 1999 18:27:20 -0500 (EST) -Received: from cloudy.me.cmu.edu via qmail - ID ; - Mon, 22 Mar 1999 18:27:17 -0500 (EST) -Received: from mms.4.60.Jun.27.1996.03.05.56.sun4.41.EzMail.2.0.CUILIB.3.45.SNAP.NOT.LINKED.cloudy.me.cmu.edu.sun4m.412 - via MS.5.6.cloudy.me.cmu.edu.sun4_41; - Mon, 22 Mar 1999 18:27:15 -0500 (EST) -Message-ID: -Date: Mon, 22 Mar 1999 18:27:15 -0500 (EST) -From: Erik Riedel -To: pgsql-hackers@postgreSQL.org -Subject: [HACKERS] optimizer and type question -Sender: owner-pgsql-hackers@postgreSQL.org -Precedence: bulk -Status: RO - - -[last week aggregation, this week, the optimizer] - -I have a somewhat general optimizer question/problem that I would like -to get some input on - i.e. I'd like to know what is "supposed" to -work here and what I should be expecting. Sadly, I think the patch -for this is more involved than my last message. - -Using my favorite table these days: - -Table = lineitem -+------------------------+----------------------------------+-------+ -| Field | Type | Length| -+------------------------+----------------------------------+-------+ -| l_orderkey | int4 not null | 4 | -| l_partkey | int4 not null | 4 | -| l_suppkey | int4 not null | 4 | -| l_linenumber | int4 not null | 4 | -| l_quantity | float4 not null | 4 | -| l_extendedprice | float4 not null | 4 | -| l_discount | float4 not null | 4 | -| l_tax | float4 not null | 4 | -| l_returnflag | char() not null | 1 | -| l_linestatus | char() not null | 1 | -| l_shipdate | date | 4 | -| l_commitdate | date | 4 | -| l_receiptdate | date | 4 | -| l_shipinstruct | char() not null | 25 | -| l_shipmode | char() not null | 10 | -| l_comment | char() not null | 44 | -+------------------------+----------------------------------+-------+ -Index: lineitem_index_ - -and the query: - --- --- Query 1 --- -explain select l_returnflag, l_linestatus, sum(l_quantity) as sum_qty, -sum(l_extendedprice) as sum_base_price, -sum(l_extendedprice*(1-l_discount)) as sum_disc_price, -sum(l_extendedprice*(1-l_discount)*(1+l_tax)) as sum_charge, -avg(l_quantity) as avg_qty, avg(l_extendedprice) as avg_price, -avg(l_discount) as avg_disc, count(*) as count_order -from lineitem -where l_shipdate <= '1998-09-02'::date -group by l_returnflag, l_linestatus -order by l_returnflag, l_linestatus; - - -note that I have eliminated the date calculation in my query of last -week and manually replaced it with a constant (since this wasn't -happening automatically - but let's not worry about that for now). -And this is only an explain, we care about the optimizer. So we get: - -Sort (cost=34467.88 size=0 width=0) - -> Aggregate (cost=34467.88 size=0 width=0) - -> Group (cost=34467.88 size=0 width=0) - -> Sort (cost=34467.88 size=0 width=0) - -> Seq Scan on lineitem (cost=34467.88 size=200191 width=44) - -so let's think about the selectivity that is being chosen for the -seq scan (the where l_shipdate <= '1998-09-02'). - -Turns out the optimizer is choosing "33%", even though the real answer -is somewhere in 90+% (that's how the query is designed). So, why does -it do that? - -Turns out that selectivity in this case is determined via -plancat::restriction_selectivity() which calls into functionOID = 103 -(intltsel) for operatorOID = 1096 (date "<=") on relation OID = 18663 -(my lineitem). - -This all follows because of the description of 1096 (date "<=") in -pg_operator. Looking at local1_template1.bki.source near line 1754 -shows: - -insert OID = 1096 ( "<=" PGUID 0 <...> date_le intltsel intltjoinsel ) - -where we see that indeed, it thinks "intltsel" is the right function -to use for "oprrest" in the case of dates. - -Question 1 - is intltsel the right thing for selectivity on dates? - -Hope someone is still with me. - -So now we're running selfuncs::intltsel() where we make a further call -to selfuncs::gethilokey(). The job of gethilokey is to determine the -min and max values of a particular attribute in the table, which will -then be used with the constant in my where clause to estimate the -selectivity. It is going to search the pg_statistic relation with -three key values: - -Anum_pg_statistic_starelid 18663 (lineitem) -Anum_pg_statistic_staattnum 11 (l_shipdate) -Anum_pg_statistic_staop 1096 (date "<=") - -this finds no tuples in pg_statistic. Why is that? The only nearby -tuple in pg_statistic is: - -starelid|staattnum|staop|stalokey |stahikey ---------+---------+-----+----------------+---------------- - 18663| 11| 0|01-02-1992 |12-01-1998 - -and the reason the query doesn't match anything? Because 1096 != 0. -But why is it 0 in pg_statistic? Statistics are determined near line -1844 in vacuum.c (assuming a 'vacuum analyze' run at some point) - - i = 0; - values[i++] = (Datum) relid; /* 1 */ - values[i++] = (Datum) attp->attnum; /* 2 */ -====> values[i++] = (Datum) InvalidOid; /* 3 */ - fmgr_info(stats->outfunc, &out_function); - out_string = <...min...> - values[i++] = (Datum) fmgr(F_TEXTIN, out_string); - pfree(out_string); - out_string = <...max...> - values[i++] = (Datum) fmgr(F_TEXTIN, out_string); - pfree(out_string); - stup = heap_formtuple(sd->rd_att, values, nulls); - -the "offending" line is setting the staop to InvalidOid (i.e. 0). - -Question 2 - is this right? Is the intent for 0 to serve as a -"wildcard", or should it be inserting an entry for each operation -individually? - -In the case of "wildcard" then gethilokey() should allow a match for - -Anum_pg_statistic_staop 0 - -instead of requiring the more restrictive 1096. In the current code, -what happens next is gethilokey() returns "not found" and intltsel() -returns the default 1/3 which I see in the resultant query plan (size -= 200191 is 1/3 of the number of lineitem tuples). - -Question 3 - is there any inherent reason it couldn't get this right? -The statistic is in the table 1992 to 1998, so the '1998-09-02' date -should be 90-some% selectivity, a much better guess than 33%. - -Doesn't make a difference for this particular query, of course, -because the seq scan must proceed anyhow, but it could easily affect -other queries where selectivities matter (and it affects the -modifications I am trying to test in the optimizer to be "smarter" -about selectivities - my overall context is to understand/improve the -behavior that the underlying storage system sees from queries like this). - -OK, so let's say we treat 0 as a "wildcard" and stop checking for -1096. Not we let gethilokey() return the two dates from the statistic -table. The immediate next thing that intltsel() does, near lines 122 -in selfuncs.c is call atol() on the strings from gethilokey(). And -guess what it comes up with? - -low = 1 -high = 12 - -because it calls atol() on '01-02-1992' and '12-01-1998'. This -clearly isn't right, it should get some large integer that includes -the year and day in the result. Then it should compare reasonably -with my constant from the where clause and give a decent selectivity -value. This leads to a re-visit of Question 1. - -Question 4 - should date "<=" use a dateltsel() function instead of -intltsel() as oprrest? - -If anyone is still with me, could you tell me if this makes sense, or -if there is some other location where the appropriate type conversion -could take place so that intltsel() gets something reasonable when it -does the atol() calls? - -Could someone also give me a sense for how far out-of-whack the whole -current selectivity-handling structure is? It seems that most of the -operators in pg_operator actually use intltsel() and would have -type-specific problems like that described. Or is the problem in the -way attribute values are stored in pg_statistic by vacuum analyze? Or -is there another layer where type conversion belongs? - -Phew. Enough typing, hope someone can follow this and address at -least some of the questions. - -Thanks. - -Erik Riedel -Carnegie Mellon University -www.cs.cmu.edu/~riedel - - - -From owner-pgsql-hackers@hub.org Mon Mar 22 20:31:11 1999 -Received: from renoir.op.net (root@renoir.op.net [209.152.193.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id UAA00802 - for ; Mon, 22 Mar 1999 20:31:09 -0500 (EST) -Received: from hub.org (majordom@hub.org [209.47.145.100]) by renoir.op.net (o1/$ Revision: 1.18 $) with ESMTP id UAA13231 for ; Mon, 22 Mar 1999 20:15:20 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.2/8.9.1) with SMTP id UAA01981; - Mon, 22 Mar 1999 20:14:04 -0500 (EST) - (envelope-from owner-pgsql-hackers@hub.org) -Received: by hub.org (TLB v0.10a (1.23 tibbs 1997/01/09 00:29:32)); Mon, 22 Mar 1999 20:13:32 +0000 (EST) -Received: (from majordom@localhost) - by hub.org (8.9.2/8.9.1) id UAA01835 - for pgsql-hackers-outgoing; Mon, 22 Mar 1999 20:13:28 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from sss.sss.pgh.pa.us (sss.pgh.pa.us [206.210.65.6]) - by hub.org (8.9.2/8.9.1) with ESMTP id UAA01822 - for ; Mon, 22 Mar 1999 20:13:21 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss.sss.pgh.pa.us (localhost [127.0.0.1]) - by sss.sss.pgh.pa.us (8.9.1/8.9.1) with ESMTP id UAA23294; - Mon, 22 Mar 1999 20:12:43 -0500 (EST) -To: Erik Riedel -cc: pgsql-hackers@postgreSQL.org -Subject: Re: [HACKERS] optimizer and type question -In-reply-to: Your message of Mon, 22 Mar 1999 18:27:15 -0500 (EST) - -Date: Mon, 22 Mar 1999 20:12:43 -0500 -Message-ID: <23292.922151563@sss.pgh.pa.us> -From: Tom Lane -Sender: owner-pgsql-hackers@postgreSQL.org -Precedence: bulk -Status: ROr - -Erik Riedel writes: -> [ optimizer doesn't find relevant pg_statistic entry ] - -It's clearly a bug that the selectivity code is not finding this tuple. -If your analysis is correct, then selectivity estimation has *never* -worked properly, or at least not in recent memory :-(. Yipes. -Bruce and I found a bunch of other problems in the optimizer recently, -so it doesn't faze me to assume that this is broken too. - -> the "offending" line is setting the staop to InvalidOid (i.e. 0). -> Question 2 - is this right? Is the intent for 0 to serve as a -> "wildcard", - -My thought is that what the staop column ought to be is the OID of the -comparison function that was used to determine the sort order of the -column. Without a sort op the lowest and highest keys in the column are -not well defined, so it makes no sense to assert "these are the lowest -and highest values" without providing the sort op that determined that. -(For sufficiently complex data types one could reasonably have multiple -ordering operators. A crude example is sorting on "circumference" and -"area" for polygons.) But typically the sort op will be the "<" -operator for the column data type. - -So, the vacuum code is definitely broken --- it's not storing the sort -op that it used. The code in gethilokey might be broken too, depending -on how it is producing the operator it's trying to match against the -tuple. For example, if the actual operator in the query is any of -< <= > >= on int4, then int4lt ought to be used to probe the pg_statistic -table. I'm not sure if we have adequate info in pg_operator or pg_type -to let the optimizer code determine the right thing to probe with :-( - -> The immediate next thing that intltsel() does, near lines 122 -> in selfuncs.c is call atol() on the strings from gethilokey(). And -> guess what it comes up with? -> low = 1 -> high = 12 -> because it calls atol() on '01-02-1992' and '12-01-1998'. This -> clearly isn't right, it should get some large integer that includes -> the year and day in the result. Then it should compare reasonably -> with my constant from the where clause and give a decent selectivity -> value. This leads to a re-visit of Question 1. -> Question 4 - should date "<=" use a dateltsel() function instead of -> intltsel() as oprrest? - -This is clearly busted as well. I'm not sure that creating dateltsel() -is the right fix, however, because if you go down that path then every -single datatype needs its own selectivity function; that's more than we -need. - -What we really want here is to be able to map datatype values into -some sort of numeric range so that we can compute what fraction of the -low-key-to-high-key range is on each side of the probe value (the -constant taken from the query). This general concept will apply to -many scalar types, so what we want is a type-specific mapping function -and a less-specific fraction-computing-function. Offhand I'd say that -we want intltsel() and floatltsel(), plus conversion routines that can -produce either int4 or float8 from a data type as seems appropriate. -Anything that couldn't map to one or the other would have to supply its -own selectivity function. - -> Or is the problem in the -> way attribute values are stored in pg_statistic by vacuum analyze? - -Looks like it converts the low and high values to text and stores them -that way. Ugly as can be :-( but I'm not sure there is a good -alternative. We have no "wild card" column type AFAIK, which is what -these columns of pg_statistic would have to be to allow storage of -unconverted min and max values. - -I think you've found a can of worms here. Congratulations ;-) - - regards, tom lane - - -From owner-pgsql-hackers@hub.org Mon Mar 22 23:31:00 1999 -Received: from renoir.op.net (root@renoir.op.net [209.152.193.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id XAA03384 - for ; Mon, 22 Mar 1999 23:30:58 -0500 (EST) -Received: from hub.org (majordom@hub.org [209.47.145.100]) by renoir.op.net (o1/$ Revision: 1.18 $) with ESMTP id XAA25586 for ; Mon, 22 Mar 1999 23:18:25 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.2/8.9.1) with SMTP id XAA17955; - Mon, 22 Mar 1999 23:17:24 -0500 (EST) - (envelope-from owner-pgsql-hackers@hub.org) -Received: by hub.org (TLB v0.10a (1.23 tibbs 1997/01/09 00:29:32)); Mon, 22 Mar 1999 23:16:49 +0000 (EST) -Received: (from majordom@localhost) - by hub.org (8.9.2/8.9.1) id XAA17764 - for pgsql-hackers-outgoing; Mon, 22 Mar 1999 23:16:46 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from po8.andrew.cmu.edu (PO8.ANDREW.CMU.EDU [128.2.10.108]) - by hub.org (8.9.2/8.9.1) with ESMTP id XAA17745 - for ; Mon, 22 Mar 1999 23:16:39 -0500 (EST) - (envelope-from er1p+@andrew.cmu.edu) -Received: (from postman@localhost) by po8.andrew.cmu.edu (8.8.5/8.8.2) id XAA04273; Mon, 22 Mar 1999 23:16:37 -0500 (EST) -Received: via switchmail; Mon, 22 Mar 1999 23:16:37 -0500 (EST) -Received: from hazy.adsl.net.cmu.edu via qmail - ID ; - Mon, 22 Mar 1999 23:15:09 -0500 (EST) -Received: from hazy.adsl.net.cmu.edu via qmail - ID ; - Mon, 22 Mar 1999 23:15:00 -0500 (EST) -Received: from mms.4.60.Jun.27.1996.03.02.53.sun4.51.EzMail.2.0.CUILIB.3.45.SNAP.NOT.LINKED.hazy.adsl.net.cmu.edu.sun4m.54 - via MS.5.6.hazy.adsl.net.cmu.edu.sun4_51; - Mon, 22 Mar 1999 23:14:55 -0500 (EST) -Message-ID: <4qxlJ0200anI01hK40@andrew.cmu.edu> -Date: Mon, 22 Mar 1999 23:14:55 -0500 (EST) -From: Erik Riedel -To: Tom Lane -Subject: Re: [HACKERS] optimizer and type question -Cc: pgsql-hackers@postgreSQL.org -In-Reply-To: <23292.922151563@sss.pgh.pa.us> -References: <23292.922151563@sss.pgh.pa.us> -Sender: owner-pgsql-hackers@postgreSQL.org -Precedence: bulk -Status: ROr - - -OK, building on your high-level explanation, I am attaching a patch that -attempts to do something "better" than the current code. Note that I -have only tested this with the date type and my particular query. I -haven't run it through the regression, so consider it "proof of concept" -at best. Although hopefully it will serve my purposes. - -> My thought is that what the staop column ought to be is the OID of the -> comparison function that was used to determine the sort order of the -> column. Without a sort op the lowest and highest keys in the column are -> not well defined, so it makes no sense to assert "these are the lowest -> and highest values" without providing the sort op that determined that. -> -> (For sufficiently complex data types one could reasonably have multiple -> ordering operators. A crude example is sorting on "circumference" and -> "area" for polygons.) But typically the sort op will be the "<" -> operator for the column data type. -> -I changed vacuum.c to do exactly that. oid of the lt sort op. - -> So, the vacuum code is definitely broken --- it's not storing the sort -> op that it used. The code in gethilokey might be broken too, depending -> on how it is producing the operator it's trying to match against the -> tuple. For example, if the actual operator in the query is any of -> < <= > >= on int4, then int4lt ought to be used to probe the pg_statistic -> table. I'm not sure if we have adequate info in pg_operator or pg_type -> to let the optimizer code determine the right thing to probe with :-( -> -This indeed seems like a bigger problem. I thought about somehow using -type-matching from the sort op and the actual operator in the query - if -both the left and right type match, then consider them the same for -purposes of this probe. That seemed complicated, so I punted in my -example - it just does the search with relid and attnum and assumes that -only returns one tuple. This works in my case (maybe in all cases, -because of the way vacuum is currently written - ?). - -> What we really want here is to be able to map datatype values into -> some sort of numeric range so that we can compute what fraction of the -> low-key-to-high-key range is on each side of the probe value (the -> constant taken from the query). This general concept will apply to -> many scalar types, so what we want is a type-specific mapping function -> and a less-specific fraction-computing-function. Offhand I'd say that -> we want intltsel() and floatltsel(), plus conversion routines that can -> produce either int4 or float8 from a data type as seems appropriate. -> Anything that couldn't map to one or the other would have to supply its -> own selectivity function. -> -This is what my example then does. Uses the stored sort op to get the -type and then uses typinput to convert from the string to an int4. - -Then puts the int4 back into string format because that's what everyone -was expecting. - -It seems to work for my particular query. I now get: - -(selfuncs) gethilokey() obj 18663 attr 11 opid 1096 (ignored) -(selfuncs) gethilokey() found op 1087 in pg_proc -(selfuncs) gethilokey() found type 1082 in pg_type -(selfuncs) gethilokey() going to use 1084 to convert type 1082 -(selfuncs) gethilokey() have low -2921 high -396 -(selfuncs) intltsel() high -396 low -2921 val -486 -(plancat) restriction_selectivity() for func 103 op 1096 rel 18663 attr -11 const -486 flag 3 returns 0.964356 -NOTICE: QUERY PLAN: - -Sort (cost=34467.88 size=0 width=0) - -> Aggregate (cost=34467.88 size=0 width=0) - -> Group (cost=34467.88 size=0 width=0) - -> Sort (cost=34467.88 size=0 width=0) - -> Seq Scan on lineitem (cost=34467.88 size=579166 width=44) - -including my printfs, which exist in the patch as well. - -Selectivity is now the expected 96% and the size estimate for the seq -scan is much closer to correct. - -Again, not tested with anything besides date, so caveat not-tested. - -Hope this helps. - -Erik - -----------------------[optimizer_fix.sh]------------------------ - -#! /bin/sh -# This is a shell archive, meaning: -# 1. Remove everything above the #! /bin/sh line. -# 2. Save the resulting text in a file. -# 3. Execute the file with /bin/sh (not csh) to create: -# selfuncs.c.diff -# vacuum.c.diff -# This archive created: Mon Mar 22 22:58:14 1999 -export PATH; PATH=/bin:/usr/bin:$PATH -if test -f 'selfuncs.c.diff' -then - echo shar: "will not over-write existing file 'selfuncs.c.diff'" -else -cat << \SHAR_EOF > 'selfuncs.c.diff' -*** -/afs/ece.cmu.edu/project/lcs/lcs-004/er1p/postgres/611/src/backend/utils/adt -/selfuncs.c Thu Mar 11 23:59:35 1999 ---- -/afs/ece.cmu.edu/project/lcs/lcs-004/er1p/postgres/615/src/backend/utils/adt -/selfuncs.c Mon Mar 22 22:57:25 1999 -*************** -*** 32,37 **** ---- 32,40 ---- - #include "utils/lsyscache.h" /* for get_oprrest() */ - #include "catalog/pg_statistic.h" - -+ #include "catalog/pg_proc.h" /* for Form_pg_proc */ -+ #include "catalog/pg_type.h" /* for Form_pg_type */ -+ - /* N is not a valid var/constant or relation id */ - #define NONVALUE(N) ((N) == -1) - -*************** -*** 103,110 **** - bottom; - - result = (float64) palloc(sizeof(float64data)); -! if (NONVALUE(attno) || NONVALUE(relid)) - *result = 1.0 / 3; - else - { - /* XXX val = atol(value); */ ---- 106,114 ---- - bottom; - - result = (float64) palloc(sizeof(float64data)); -! if (NONVALUE(attno) || NONVALUE(relid)) { - *result = 1.0 / 3; -+ } - else - { - /* XXX val = atol(value); */ -*************** -*** 117,130 **** - } - high = atol(highchar); - low = atol(lowchar); - if ((flag & SEL_RIGHT && val < low) || - (!(flag & SEL_RIGHT) && val > high)) - { - float32data nvals; - - nvals = getattdispersion(relid, (int) attno); -! if (nvals == 0) - *result = 1.0 / 3.0; - else - { - *result = 3.0 * (float64data) nvals; ---- 121,136 ---- - } - high = atol(highchar); - low = atol(lowchar); -+ printf("(selfuncs) intltsel() high %d low %d val %d\n",high,low,val); - if ((flag & SEL_RIGHT && val < low) || - (!(flag & SEL_RIGHT) && val > high)) - { - float32data nvals; - - nvals = getattdispersion(relid, (int) attno); -! if (nvals == 0) { - *result = 1.0 / 3.0; -+ } - else - { - *result = 3.0 * (float64data) nvals; -*************** -*** 336,341 **** ---- 342,353 ---- - { - Relation rel; - HeapScanDesc scan; -+ /* this assumes there is only one row in the statistics table for any -particular */ -+ /* relid, attnum pair - could be more complicated if staop is also -used. */ -+ /* at the moment, if there are multiple rows, this code ends up -picking the */ -+ /* "first" one - - er1p */ -+ /* the actual "ignoring" is done in the call to heap_beginscan() -below, where */ -+ /* we only mention 2 of the 3 keys in this array - - er1p */ - static ScanKeyData key[3] = { - {0, Anum_pg_statistic_starelid, F_OIDEQ, {0, 0, F_OIDEQ}}, - {0, Anum_pg_statistic_staattnum, F_INT2EQ, {0, 0, F_INT2EQ}}, -*************** -*** 344,355 **** - bool isnull; - HeapTuple tuple; - - rel = heap_openr(StatisticRelationName); - - key[0].sk_argument = ObjectIdGetDatum(relid); - key[1].sk_argument = Int16GetDatum((int16) attnum); - key[2].sk_argument = ObjectIdGetDatum(opid); -! scan = heap_beginscan(rel, 0, SnapshotNow, 3, key); - tuple = heap_getnext(scan, 0); - if (!HeapTupleIsValid(tuple)) - { ---- 356,377 ---- - bool isnull; - HeapTuple tuple; - -+ HeapTuple tup; -+ Form_pg_proc proc; -+ Form_pg_type typ; -+ Oid which_op; -+ Oid which_type; -+ int32 low_value; -+ int32 high_value; -+ - rel = heap_openr(StatisticRelationName); - - key[0].sk_argument = ObjectIdGetDatum(relid); - key[1].sk_argument = Int16GetDatum((int16) attnum); - key[2].sk_argument = ObjectIdGetDatum(opid); -! printf("(selfuncs) gethilokey() obj %d attr %d opid %d (ignored)\n", -! key[0].sk_argument,key[1].sk_argument,key[2].sk_argument); -! scan = heap_beginscan(rel, 0, SnapshotNow, 2, key); - tuple = heap_getnext(scan, 0); - if (!HeapTupleIsValid(tuple)) - { -*************** -*** 376,383 **** ---- 398,461 ---- - &isnull)); - if (isnull) - elog(DEBUG, "gethilokey: low key is null"); -+ - heap_endscan(scan); - heap_close(rel); -+ -+ /* now we deal with type conversion issues - */ -+ /* when intltsel() calls this routine (who knows what other callers -might do) */ -+ /* it assumes that it can call atol() on the strings and then use -integer */ -+ /* comparison from there. what we are going to do here, then, is try -to use */ -+ /* the type information from Anum_pg_statistic_staop to convert the -high */ -+ /* and low values -- er1p */ -+ -+ /* WARNING: this code has only been tested with the date type and has -NOT */ -+ /* been regression tested. consider it "sample" code of what might -be the */ -+ /* right kind of thing to do -- er1p */ -+ -+ /* get the 'op' from pg_statistic and look it up in pg_proc */ -+ which_op = heap_getattr(tuple, -+ Anum_pg_statistic_staop, -+ RelationGetDescr(rel), -+ &isnull); -+ if (InvalidOid == which_op) { -+ /* ignore all this stuff, try conversion only if we have a valid staop */ -+ /* note that there is an accompanying change to 'vacuum analyze' that */ -+ /* gets this set to something useful. */ -+ } else { -+ /* staop looks valid, so let's see what we can do about conversion */ -+ tup = SearchSysCacheTuple(PROOID, ObjectIdGetDatum(which_op), 0, 0, 0); -+ if (!HeapTupleIsValid(tup)) { -+ elog(ERROR, "selfuncs: unable to find op in pg_proc %d", which_op); -+ } -+ printf("(selfuncs) gethilokey() found op %d in pg_proc\n",which_op); -+ -+ /* use that to determine the type of stahikey and stalokey via pg_type */ -+ proc = (Form_pg_proc) GETSTRUCT(tup); -+ which_type = proc->proargtypes[0]; /* XXX - use left and right -separately? */ -+ tup = SearchSysCacheTuple(TYPOID, ObjectIdGetDatum(which_type), 0, 0, 0); -+ if (!HeapTupleIsValid(tup)) { -+ elog(ERROR, "selfuncs: unable to find type in pg_type %d", which_type); -+ } -+ printf("(selfuncs) gethilokey() found type %d in pg_type\n",which_type); -+ -+ /* and use that type to get the conversion function to int4 */ -+ typ = (Form_pg_type) GETSTRUCT(tup); -+ printf("(selfuncs) gethilokey() going to use %d to convert type -%d\n",typ->typinput,which_type); -+ -+ /* and convert the low and high strings */ -+ low_value = (int32) fmgr(typ->typinput, *low, -1); -+ high_value = (int32) fmgr(typ->typinput, *high, -1); -+ printf("(selfuncs) gethilokey() have low %d high -%d\n",low_value,high_value); -+ -+ /* now we have int4's, which we put back into strings because -that's what out */ -+ /* callers (intltsel() at least) expect - - er1p */ -+ pfree(*low); pfree(*high); /* let's not leak the old strings */ -+ *low = int4out(low_value); -+ *high = int4out(high_value); -+ -+ /* XXX - this probably leaks the two tups we got from -SearchSysCacheTuple() - er1p */ -+ } - } - - float64 -SHAR_EOF -fi -if test -f 'vacuum.c.diff' -then - echo shar: "will not over-write existing file 'vacuum.c.diff'" -else -cat << \SHAR_EOF > 'vacuum.c.diff' -*** -/afs/ece.cmu.edu/project/lcs/lcs-004/er1p/postgres/611/src/backend/commands/ -vacuum.c Thu Mar 11 23:59:09 1999 ---- -/afs/ece.cmu.edu/project/lcs/lcs-004/er1p/postgres/615/src/backend/commands/ -vacuum.c Mon Mar 22 21:23:15 1999 -*************** -*** 1842,1848 **** - i = 0; - values[i++] = (Datum) relid; /* 1 */ - values[i++] = (Datum) attp->attnum; /* 2 */ -! values[i++] = (Datum) InvalidOid; /* 3 */ - fmgr_info(stats->outfunc, &out_function); - out_string = (*fmgr_faddr(&out_function)) (stats->min, -stats->attr->atttypid); - values[i++] = (Datum) fmgr(F_TEXTIN, out_string); ---- 1842,1848 ---- - i = 0; - values[i++] = (Datum) relid; /* 1 */ - values[i++] = (Datum) attp->attnum; /* 2 */ -! values[i++] = (Datum) stats->f_cmplt.fn_oid; /* 3 */ /* get the -'<' oid, instead of 'invalid' - er1p */ - fmgr_info(stats->outfunc, &out_function); - out_string = (*fmgr_faddr(&out_function)) (stats->min, -stats->attr->atttypid); - values[i++] = (Datum) fmgr(F_TEXTIN, out_string); -SHAR_EOF -fi -exit 0 -# End of shell archive - - - -From owner-pgsql-hackers@hub.org Tue Mar 23 12:31:05 1999 -Received: from renoir.op.net (root@renoir.op.net [209.152.193.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id MAA17491 - for ; Tue, 23 Mar 1999 12:31:04 -0500 (EST) -Received: from hub.org (majordom@hub.org [209.47.145.100]) by renoir.op.net (o1/$ Revision: 1.18 $) with ESMTP id MAA08839 for ; Tue, 23 Mar 1999 12:08:14 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.2/8.9.1) with SMTP id MAA93649; - Tue, 23 Mar 1999 12:04:57 -0500 (EST) - (envelope-from owner-pgsql-hackers@hub.org) -Received: by hub.org (TLB v0.10a (1.23 tibbs 1997/01/09 00:29:32)); Tue, 23 Mar 1999 12:03:00 +0000 (EST) -Received: (from majordom@localhost) - by hub.org (8.9.2/8.9.1) id MAA93355 - for pgsql-hackers-outgoing; Tue, 23 Mar 1999 12:02:55 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from sss.sss.pgh.pa.us (sss.pgh.pa.us [206.210.65.6]) - by hub.org (8.9.2/8.9.1) with ESMTP id MAA93336 - for ; Tue, 23 Mar 1999 12:02:43 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss.sss.pgh.pa.us (localhost [127.0.0.1]) - by sss.sss.pgh.pa.us (8.9.1/8.9.1) with ESMTP id MAA24455; - Tue, 23 Mar 1999 12:01:57 -0500 (EST) -To: Erik Riedel -cc: pgsql-hackers@postgreSQL.org -Subject: Re: [HACKERS] optimizer and type question -In-reply-to: Your message of Mon, 22 Mar 1999 23:14:55 -0500 (EST) - <4qxlJ0200anI01hK40@andrew.cmu.edu> -Date: Tue, 23 Mar 1999 12:01:57 -0500 -Message-ID: <24453.922208517@sss.pgh.pa.us> -From: Tom Lane -Sender: owner-pgsql-hackers@postgreSQL.org -Precedence: bulk -Status: RO - -Erik Riedel writes: -> OK, building on your high-level explanation, I am attaching a patch that -> attempts to do something "better" than the current code. Note that I -> have only tested this with the date type and my particular query. - -Glad to see you working on this. I don't like the details of your -patch too much though ;-). Here are some suggestions for making it -better. - -1. I think just removing staop from the lookup in gethilokey is OK for -now, though I'm dubious about Bruce's thought that we could delete that -field entirely. As you observe, vacuum will not currently put more -than one tuple for a column into pg_statistic, so we can just do the -lookup with relid and attno and leave it at that. But I think we ought -to leave the field there, with the idea that vacuum might someday -compute more than one statistic for a data column. Fixing vacuum to -put its sort op into the field is a good idea in the meantime. - -2. The type conversion you're doing in gethilokey is a mess; I think -what you ought to make it do is simply the inbound conversion of the -string from pg_statistic into the internal representation for the -column's datatype, and return that value as a Datum. It also needs -a cleaner success/failure return convention --- this business with -"n" return is ridiculously type-specific. Also, the best and easiest -way to find the type to convert to is to look up the column type in -the info for the given relid, not search pg_proc with the staop value. -(I'm not sure that will even work, since there are pg_proc entries -with wildcard argument types.) - -3. The atol() calls currently found in intltsel are a type-specific -cheat on what is conceptually a two-step process: - * Convert the string stored in pg_statistic back to the internal - form for the column data type. - * Generate a numeric representation of the data value that can be - used as an estimate of the range of values in the table. -The second step is trivial for integers, which may obscure the fact -that there are two steps involved, but nonetheless there are. If -you think about applying selectivity logic to strings, say, it -becomes clear that the second step is a necessary component of the -process. Furthermore, the second step must also be applied to the -probe value that's being passed into the selectivity operator. -(The probe value is already in internal form, of course; but it is -not necessarily in a useful numeric form.) - -We can do the first of these steps by applying the appropriate "XXXin" -conversion function for the column data type, as you have done. The -interesting question is how to do the second one. A really clean -solution would require adding a column to pg_type that points to a -function that will do the appropriate conversion. I'd be inclined to -make all of these functions return "double" (float8) and just have one -top-level selectivity routine for all data types that can use -range-based selectivity logic. - -We could probably hack something together that would not use an explicit -conversion function for each data type, but instead would rely on -type-specific assumptions inside the selectivity routines. We'd need many -more selectivity routines though (at least one for each of int, float4, -float8, and text data types) so I'm not sure we'd really save any work -compared to doing it right. - -BTW, now that I look at this issue it's real clear that the selectivity -entries in pg_operator are horribly broken. The intltsel/intgtsel -selectivity routines are currently applied to 32 distinct data types: - -regression=> select distinct typname,oprleft from pg_operator, pg_type -regression-> where pg_type.oid = oprleft -regression-> and oprrest in (103,104); -typname |oprleft ----------+------- -_aclitem | 1034 -abstime | 702 -bool | 16 -box | 603 -bpchar | 1042 -char | 18 -cidr | 650 -circle | 718 -date | 1082 -datetime | 1184 -float4 | 700 -float8 | 701 -inet | 869 -int2 | 21 -int4 | 23 -int8 | 20 -line | 628 -lseg | 601 -macaddr | 829 -money | 790 -name | 19 -numeric | 1700 -oid | 26 -oid8 | 30 -path | 602 -point | 600 -polygon | 604 -text | 25 -time | 1083 -timespan | 1186 -timestamp| 1296 -varchar | 1043 -(32 rows) - -many of which are very obviously not compatible with integer for *any* -purpose. It looks to me like a lot of data types were added to -pg_operator just by copy-and-paste, without paying attention to whether -the selectivity routines were actually correct for the data type. - -As the code stands today, the bogus entries don't matter because -gethilokey always fails, so we always get 1/3 as the selectivity -estimate for any comparison operator (except = and != of course). -I had actually noticed that fact and assumed that it was supposed -to work that way :-(. But, clearly, there is code in here that -is *trying* to be smarter. - -As soon as we fix gethilokey so that it can succeed, we will start -getting essentially-random selectivity estimates for those data types -that aren't actually binary-compatible with integer. That will not do; -we have to do something about the issue. - - regards, tom lane - - -From tgl@sss.pgh.pa.us Tue Mar 23 12:31:02 1999 -Received: from renoir.op.net (root@renoir.op.net [209.152.193.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id MAA17484 - for ; Tue, 23 Mar 1999 12:31:01 -0500 (EST) -Received: from sss.sss.pgh.pa.us (sss.pgh.pa.us [206.210.65.6]) by renoir.op.net (o1/$ Revision: 1.18 $) with ESMTP id MAA09042 for ; Tue, 23 Mar 1999 12:10:55 -0500 (EST) -Received: from sss.sss.pgh.pa.us (localhost [127.0.0.1]) - by sss.sss.pgh.pa.us (8.9.1/8.9.1) with ESMTP id MAA24474; - Tue, 23 Mar 1999 12:09:52 -0500 (EST) -To: Bruce Momjian -cc: riedel+@CMU.EDU, pgsql-hackers@postgreSQL.org -Subject: Re: [HACKERS] optimizer and type question -In-reply-to: Your message of Mon, 22 Mar 1999 21:25:45 -0500 (EST) - <199903230225.VAA01641@candle.pha.pa.us> -Date: Tue, 23 Mar 1999 12:09:52 -0500 -Message-ID: <24471.922208992@sss.pgh.pa.us> -From: Tom Lane -Status: RO - -Bruce Momjian writes: -> What we really need is some way to determine how far the requested value -> is from the min/max values. With int, we just do (val-min)/(max-min). -> That works, but how do we do that for types that don't support division. -> Strings come to mind in this case. - -What I'm envisioning is that we still apply the (val-min)/(max-min) -logic, but apply it to numeric values that are produced in a -type-dependent way. - -For ints and floats the conversion is trivial, of course. - -For strings, the first thing that comes to mind is to return 0 for a -null string and the value of the first byte for a non-null string. -This would give you one-part-in-256 selectivity which is plenty good -enough for what the selectivity code needs to do. (Actually, it's -only that good if the strings' first bytes are pretty well spread out. -If you have a table containing English words, for example, you might -only get about one part in 26 this way, since the first bytes will -probably only run from A to Z. Might be better to use the first two -characters of the string to compute the selectivity representation.) - -In general, you can apply this logic as long as you can come up with -some numerical approximation to the data type's sorting order. It -doesn't have to be exact. - - regards, tom lane - -From owner-pgsql-hackers@hub.org Tue Mar 23 12:31:03 1999 -Received: from renoir.op.net (root@renoir.op.net [209.152.193.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id MAA17488 - for ; Tue, 23 Mar 1999 12:31:02 -0500 (EST) -Received: from hub.org (majordom@hub.org [209.47.145.100]) by renoir.op.net (o1/$ Revision: 1.18 $) with ESMTP id MAA09987 for ; Tue, 23 Mar 1999 12:21:34 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.2/8.9.1) with SMTP id MAA95155; - Tue, 23 Mar 1999 12:18:33 -0500 (EST) - (envelope-from owner-pgsql-hackers@hub.org) -Received: by hub.org (TLB v0.10a (1.23 tibbs 1997/01/09 00:29:32)); Tue, 23 Mar 1999 12:17:00 +0000 (EST) -Received: (from majordom@localhost) - by hub.org (8.9.2/8.9.1) id MAA94857 - for pgsql-hackers-outgoing; Tue, 23 Mar 1999 12:16:56 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from sss.sss.pgh.pa.us (sss.pgh.pa.us [206.210.65.6]) - by hub.org (8.9.2/8.9.1) with ESMTP id MAA94469 - for ; Tue, 23 Mar 1999 12:11:33 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss.sss.pgh.pa.us (localhost [127.0.0.1]) - by sss.sss.pgh.pa.us (8.9.1/8.9.1) with ESMTP id MAA24474; - Tue, 23 Mar 1999 12:09:52 -0500 (EST) -To: Bruce Momjian -cc: riedel+@CMU.EDU, pgsql-hackers@postgreSQL.org -Subject: Re: [HACKERS] optimizer and type question -In-reply-to: Your message of Mon, 22 Mar 1999 21:25:45 -0500 (EST) - <199903230225.VAA01641@candle.pha.pa.us> -Date: Tue, 23 Mar 1999 12:09:52 -0500 -Message-ID: <24471.922208992@sss.pgh.pa.us> -From: Tom Lane -Sender: owner-pgsql-hackers@postgreSQL.org -Precedence: bulk -Status: RO - -Bruce Momjian writes: -> What we really need is some way to determine how far the requested value -> is from the min/max values. With int, we just do (val-min)/(max-min). -> That works, but how do we do that for types that don't support division. -> Strings come to mind in this case. - -What I'm envisioning is that we still apply the (val-min)/(max-min) -logic, but apply it to numeric values that are produced in a -type-dependent way. - -For ints and floats the conversion is trivial, of course. - -For strings, the first thing that comes to mind is to return 0 for a -null string and the value of the first byte for a non-null string. -This would give you one-part-in-256 selectivity which is plenty good -enough for what the selectivity code needs to do. (Actually, it's -only that good if the strings' first bytes are pretty well spread out. -If you have a table containing English words, for example, you might -only get about one part in 26 this way, since the first bytes will -probably only run from A to Z. Might be better to use the first two -characters of the string to compute the selectivity representation.) - -In general, you can apply this logic as long as you can come up with -some numerical approximation to the data type's sorting order. It -doesn't have to be exact. - - regards, tom lane - - -From owner-pgsql-hackers@hub.org Thu Jul 1 20:39:19 1999 -Received: from hub.org (hub.org [209.167.229.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id UAA15403 - for ; Thu, 1 Jul 1999 20:39:18 -0400 (EDT) -Received: from hub.org (hub.org [209.167.229.1]) - by hub.org (8.9.3/8.9.3) with ESMTP id UAA45018; - Thu, 1 Jul 1999 20:20:27 -0400 (EDT) - (envelope-from owner-pgsql-hackers@hub.org) -Received: by hub.org (TLB v0.10a (1.23 tibbs 1997/01/09 00:29:32)); Thu, 01 Jul 1999 20:15:30 +0000 (EDT) -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id UAA44474 - for pgsql-hackers-outgoing; Thu, 1 Jul 1999 20:15:28 -0400 (EDT) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -X-Authentication-Warning: hub.org: majordom set sender to owner-pgsql-hackers@postgreSQL.org using -f -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by hub.org (8.9.3/8.9.3) with ESMTP id UAA44058 - for ; Thu, 1 Jul 1999 20:12:10 -0400 (EDT) - (envelope-from Inoue@tpf.co.jp) -Received: from cadzone ([126.0.1.40] (may be forged)) - by sd.tpf.co.jp (2.5 Build 2640 (Berkeley 8.8.6)/8.8.4) with SMTP - id JAA00279 for ; Fri, 02 Jul 1999 09:11:58 +0900 -From: "Hiroshi Inoue" -To: "pgsql-hackers" -Subject: [HACKERS] Optimization FAQ ? -Date: Fri, 2 Jul 1999 09:14:10 +0900 -Message-ID: <000401bec41f$ce81dcc0$2801007e@cadzone.tpf.co.jp> -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-2022-jp" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 -X-MimeOLE: Produced By Microsoft MimeOLE V4.72.2106.4 -Importance: Normal -Sender: owner-pgsql-hackers@postgreSQL.org -Precedence: bulk -Status: RO - -Hello all, - -I got the following result. -It's FAQ ? - -drop table int2t; -create table int2t (id int2 primary key); - -explain select * from int2t where id=1; - NOTICE: QUERY PLAN: - - Seq Scan on int2t (cost=43.00 rows=2 width=2) - -explain select * from int2t where id=1::int2; - NOTICE: QUERY PLAN: - - Index Scan using int2t_pkey on int2t (cost=2.05 rows=2 width=2) - -explain select * from int2t where id='1'; - NOTICE: QUERY PLAN: - - Index Scan using int2t_pkey on int2t (cost=2.05 rows=2 width=2) - -Right behavior ? - -Regards. - -Hiroshi Inoue -Inoue@tpf.co.jp - - -From owner-pgsql-hackers@hub.org Thu Jan 20 18:45:32 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id TAA00672 - for ; Thu, 20 Jan 2000 19:45:30 -0500 (EST) -Received: from hub.org (hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.19 $) with ESMTP id TAA01989 for ; Thu, 20 Jan 2000 19:39:15 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id TAA00957; - Thu, 20 Jan 2000 19:35:19 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Thu, 20 Jan 2000 19:33:34 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id TAA00581 - for pgsql-hackers-outgoing; Thu, 20 Jan 2000 19:32:37 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.9.3/8.9.3) with ESMTP id TAA98940 - for ; Thu, 20 Jan 2000 19:31:49 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id TAA25390 - for ; Thu, 20 Jan 2000 19:31:32 -0500 (EST) -To: pgsql-hackers@postgreSQL.org -Subject: [HACKERS] Some notes on optimizer cost estimates -Date: Thu, 20 Jan 2000 19:31:32 -0500 -Message-ID: <25387.948414692@sss.pgh.pa.us> -From: Tom Lane -Sender: owner-pgsql-hackers@postgreSQL.org -Status: OR - -I have been spending some time measuring actual runtimes for various -sequential-scan and index-scan query plans, and have learned that the -current Postgres optimizer's cost estimation equations are not very -close to reality at all. - -Presently we estimate the cost of a sequential scan as - - Nblocks + CPU_PAGE_WEIGHT * Ntuples - ---- that is, the unit of cost is the time to read one disk page, -and we have a "fudge factor" that relates CPU time per tuple to -disk time per page. (The default CPU_PAGE_WEIGHT is 0.033, which -is probably too high for modern hardware --- 0.01 seems like it -might be a better default, at least for simple queries.) OK, -it's a simplistic model, but not too unreasonable so far. - -The cost of an index scan is measured in these same terms as - - Nblocks + CPU_PAGE_WEIGHT * Ntuples + - CPU_INDEX_PAGE_WEIGHT * Nindextuples - -Here Ntuples is the number of tuples selected by the index qual -condition (typically, it's less than the total table size used in -sequential-scan estimation). CPU_INDEX_PAGE_WEIGHT essentially -estimates the cost of scanning an index tuple; by default it's 0.017 or -half CPU_PAGE_WEIGHT. Nblocks is estimated as the index size plus an -appropriate fraction of the main table size. - -There are two big problems with this: - -1. Since main-table tuples are visited in index order, we'll be hopping -around from page to page in the table. The current cost estimation -method essentially assumes that the buffer cache plus OS disk cache will -be 100% efficient --- we will never have to read the same page of the -main table twice in a scan, due to having discarded it between -references. This of course is unreasonably optimistic. Worst case -is that we'd fetch a main-table page for each selected tuple, but in -most cases that'd be unreasonably pessimistic. - -2. The cost of a disk page fetch is estimated at 1.0 unit for both -sequential and index scans. In reality, sequential access is *much* -cheaper than the quasi-random accesses performed by an index scan. -This is partly a matter of physical disk seeks, and partly a matter -of benefitting (or not) from any read-ahead logic the OS may employ. - -As best I can measure on my hardware, the cost of a nonsequential -disk read should be estimated at 4 to 5 times the cost of a sequential -one --- I'm getting numbers like 2.2 msec per disk page for sequential -scans, and as much as 11 msec per page for index scans. I don't -know, however, if this ratio is similar enough on other platforms -to be useful for cost estimating. We could make it a parameter like -we do for CPU_PAGE_WEIGHT ... but you know and I know that no one -ever bothers to adjust those numbers in the field ... - -The other effect that needs to be modeled, and currently is not, is the -"hit rate" of buffer cache. Presumably, this is 100% for tables smaller -than the cache and drops off as the table size increases --- but I have -no particular thoughts on the form of the dependency. Does anyone have -ideas here? The problem is complicated by the fact that we don't really -know how big the cache is; we know the number of buffers Postgres has, -but we have no idea how big a disk cache the kernel is keeping. As near -as I can tell, finding a hit in the kernel disk cache is not a lot more -expensive than having the page sitting in Postgres' own buffers --- -certainly it's much much cheaper than a disk read. - -BTW, if you want to do some measurements of your own, try turning on -PGOPTIONS="-d 2 -te". This will dump a lot of interesting numbers -into the postmaster log, if your platform supports getrusage(). - - regards, tom lane - -************ - -From owner-pgsql-hackers@hub.org Thu Jan 20 20:26:33 2000 -Received: from hub.org (hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id VAA06630 - for ; Thu, 20 Jan 2000 21:26:32 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id VAA35022; - Thu, 20 Jan 2000 21:22:08 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Thu, 20 Jan 2000 21:20:35 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id VAA34569 - for pgsql-hackers-outgoing; Thu, 20 Jan 2000 21:19:38 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from hercules.cs.ucsb.edu (hercules.cs.ucsb.edu [128.111.41.30]) - by hub.org (8.9.3/8.9.3) with ESMTP id VAA34534 - for ; Thu, 20 Jan 2000 21:19:26 -0500 (EST) - (envelope-from xun@cs.ucsb.edu) -Received: from xp10-06.dialup.commserv.ucsb.edu (root@xp10-06.dialup.commserv.ucsb.edu [128.111.253.249]) - by hercules.cs.ucsb.edu (8.8.6/8.8.6) with ESMTP id SAA04655 - for ; Thu, 20 Jan 2000 18:19:22 -0800 (PST) -Received: from xp10-06.dialup.commserv.ucsb.edu (xun@localhost) - by xp10-06.dialup.commserv.ucsb.edu (8.9.3/8.9.3) with ESMTP id SAA22377 - for ; Thu, 20 Jan 2000 18:19:40 -0800 -Message-Id: <200001210219.SAA22377@xp10-06.dialup.commserv.ucsb.edu> -To: pgsql-hackers@postgreSQL.org -Reply-to: xun@cs.ucsb.edu -Subject: Re. [HACKERS] Some notes on optimizer cost estimates -Date: Thu, 20 Jan 2000 18:19:40 -0800 -From: Xun Cheng -Sender: owner-pgsql-hackers@postgreSQL.org -Status: OR - -I'm very glad you bring up this cost estimate issue. -Recent work in database research have argued a more -detailed disk access cost model should be used for -large queries especially joins. -Traditional cost estimate only considers the number of -disk pages accessed. However a more detailed model -would consider three parameters: avg. seek, avg. latency -and avg. page transfer. For old disk, typical values are -SEEK=9.5 milliseconds, LATENCY=8.3 ms, TRANSFER=2.6ms. -A sequential continuous reading of a table (assuming -1000 continuous pages) would cost -(SEEK+LATENCY+1000*TRANFER=2617.8ms); while quasi-randomly -reading 200 times with 2 continuous pages/time would -cost (SEEK+200*LATENCY+400*TRANSFER=2700ms). -Someone from IBM lab re-studied the traditional -ad hoc join algorithms (nested, sort-merge, hash) using the detailed cost model -and found some interesting results. - ->I have been spending some time measuring actual runtimes for various ->sequential-scan and index-scan query plans, and have learned that the ->current Postgres optimizer's cost estimation equations are not very ->close to reality at all. - -One interesting question I'd like to ask is if this non-closeness -really affects the optimal choice of postgresql's query optimizer. -And to what degree the effects might be? My point is that -if the optimizer estimated the cost for sequential-scan is 10 and -the cost for index-scan is 20 while the actual costs are 10 vs. 40, -it should be ok because the optimizer would still choose sequential-scan -as it should. - ->1. Since main-table tuples are visited in index order, we'll be hopping ->around from page to page in the table. - -I'm not sure about the implementation in postgresql. One thing you might -be able to do is to first collect all must-read page addresses from -the index scan and then order them before the actual ordered page fetching. -It would at least avoid the same page being read twice (not entirely -true depending on the context (like in join) and algo.) - ->The current cost estimation ->method essentially assumes that the buffer cache plus OS disk cache will ->be 100% efficient --- we will never have to read the same page of the ->main table twice in a scan, due to having discarded it between ->references. This of course is unreasonably optimistic. Worst case ->is that we'd fetch a main-table page for each selected tuple, but in ->most cases that'd be unreasonably pessimistic. - -This is actually the motivation that I asked before if postgresql -has a raw disk facility. That way we have much control on this cache -issue. Of course only if we can provide some algo. better than OS -cache algo. (depending on the context, like large joins), a raw disk -facility will be worthwhile (besides the recoverability). - -Actually I have another question for you guys which is somehow related -to this cost estimation issue. You know the difference between OLTP -and OLAP. My question is how you target postgresql on both kinds -of applications or just OLTP. From what I know OLTP and OLAP would -have a big difference in query characteristics and thus -optimization difference. If postgresql is only targeted on -OLTP, the above cost estimation issue might not be that -important. However for OLAP, large tables and large queries are -common and optimization would be difficult. - -xun - - -************ - -From owner-pgsql-hackers@hub.org Thu Jan 20 20:41:44 2000 -Received: from hub.org (hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id VAA07020 - for ; Thu, 20 Jan 2000 21:41:43 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id VAA40222; - Thu, 20 Jan 2000 21:34:08 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Thu, 20 Jan 2000 21:32:35 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id VAA38388 - for pgsql-hackers-outgoing; Thu, 20 Jan 2000 21:31:38 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.9.3/8.9.3) with ESMTP id VAA37422 - for ; Thu, 20 Jan 2000 21:31:02 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id VAA26761; - Thu, 20 Jan 2000 21:30:41 -0500 (EST) -To: "Hiroshi Inoue" -cc: pgsql-hackers@postgreSQL.org -Subject: Re: [HACKERS] Some notes on optimizer cost estimates -In-reply-to: <000b01bf63b1$093cbd40$2801007e@tpf.co.jp> -References: <000b01bf63b1$093cbd40$2801007e@tpf.co.jp> -Comments: In-reply-to "Hiroshi Inoue" - message dated "Fri, 21 Jan 2000 10:44:20 +0900" -Date: Thu, 20 Jan 2000 21:30:41 -0500 -Message-ID: <26758.948421841@sss.pgh.pa.us> -From: Tom Lane -Sender: owner-pgsql-hackers@postgreSQL.org -Status: ORr - -"Hiroshi Inoue" writes: -> I've wondered why we cound't analyze database without vacuum. -> We couldn't run vacuum light-heartedly because it acquires an -> exclusive lock for the target table. - -There is probably no real good reason, except backwards compatibility, -why the ANALYZE function (obtaining pg_statistic data) is part of -VACUUM at all --- it could just as easily be a separate command that -would only use read access on the database. Bruce is thinking about -restructuring VACUUM, so maybe now is a good time to think about -splitting out the ANALYZE code too. - -> In addition,vacuum error occurs with analyze option in most -> cases AFAIK. - -Still, with current sources? What's the error message? I fixed -a problem with pg_statistic tuples getting too big... - - regards, tom lane - -************ - -From tgl@sss.pgh.pa.us Thu Jan 20 21:10:28 2000 -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id WAA08412 - for ; Thu, 20 Jan 2000 22:10:26 -0500 (EST) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id WAA27080; - Thu, 20 Jan 2000 22:10:28 -0500 (EST) -To: Bruce Momjian -cc: Hiroshi Inoue , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Some notes on optimizer cost estimates -In-reply-to: <200001210248.VAA07186@candle.pha.pa.us> -References: <200001210248.VAA07186@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Thu, 20 Jan 2000 21:48:57 -0500" -Date: Thu, 20 Jan 2000 22:10:28 -0500 -Message-ID: <27077.948424228@sss.pgh.pa.us> -From: Tom Lane -Status: OR - -Bruce Momjian writes: -> It is nice that ANALYZE is done during vacuum. I can't imagine why you -> would want to do an analyze without adding a vacuum to it. I guess -> that's why I made them the same command. - -Well, the main bad thing about ANALYZE being part of VACUUM is that -it adds to the length of time that VACUUM is holding an exclusive -lock on the table. I think it'd make more sense for it to be a -separate command. - -I have also been thinking about how to make ANALYZE produce a more -reliable estimate of the most common value. The three-element list -that it keeps now is a good low-cost hack, but it really doesn't -produce a trustworthy answer unless the MCV is pretty darn C (since -it will never pick up on the MCV at all until there are at least -two occurrences in three adjacent tuples). The only idea I've come -up with is to use a larger list, which would be slower and take -more memory. I think that'd be OK in a separate command, but I -hesitate to do it inside VACUUM --- VACUUM has its own considerable -memory requirements, and there's still the issue of not holding down -an exclusive lock longer than you have to. - - regards, tom lane - -From Inoue@tpf.co.jp Thu Jan 20 21:08:32 2000 -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id WAA08225 - for ; Thu, 20 Jan 2000 22:08:29 -0500 (EST) -Received: from cadzone ([126.0.1.40] (may be forged)) - by sd.tpf.co.jp (2.5 Build 2640 (Berkeley 8.8.6)/8.8.4) with SMTP - id MAA04148; Fri, 21 Jan 2000 12:08:30 +0900 -From: "Hiroshi Inoue" -To: "Bruce Momjian" , "Tom Lane" -Cc: -Subject: RE: [HACKERS] Some notes on optimizer cost estimates -Date: Fri, 21 Jan 2000 12:14:10 +0900 -Message-ID: <001301bf63bd$95cbe680$2801007e@tpf.co.jp> -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 -In-Reply-To: <200001210248.VAA07186@candle.pha.pa.us> -Importance: Normal -Status: OR - -> -----Original Message----- -> From: Bruce Momjian [mailto:pgman@candle.pha.pa.us] -> -> > "Hiroshi Inoue" writes: -> > > I've wondered why we cound't analyze database without vacuum. -> > > We couldn't run vacuum light-heartedly because it acquires an -> > > exclusive lock for the target table. -> > -> > There is probably no real good reason, except backwards compatibility, -> > why the ANALYZE function (obtaining pg_statistic data) is part of -> > VACUUM at all --- it could just as easily be a separate command that -> > would only use read access on the database. Bruce is thinking about -> > restructuring VACUUM, so maybe now is a good time to think about -> > splitting out the ANALYZE code too. -> -> I put it in vacuum because at the time I didn't know how to do such -> things and vacuum already scanned the table. I just linked on the the -> scan. Seemed like a good idea at the time. -> -> It is nice that ANALYZE is done during vacuum. I can't imagine why you -> would want to do an analyze without adding a vacuum to it. I guess -> that's why I made them the same command. -> -> If I made them separate commands, both would have to scan the table, -> though the analyze could do it without the exclusive lock, which would -> be good. -> - -The functionality of VACUUM and ANALYZE is quite different. -I don't prefer to charge VACUUM more than now about analyzing -database. Probably looong lock,more aborts .... -Various kind of analysis would be possible by splitting out ANALYZE. - -Regards. - -Hiroshi Inoue -Inoue@tpf.co.jp - -From owner-pgsql-hackers@hub.org Fri Jan 21 11:01:59 2000 -Received: from hub.org (hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id MAA07821 - for ; Fri, 21 Jan 2000 12:01:57 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id LAA77357; - Fri, 21 Jan 2000 11:52:25 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Fri, 21 Jan 2000 11:50:46 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id LAA76756 - for pgsql-hackers-outgoing; Fri, 21 Jan 2000 11:49:50 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from eclipse.pacifier.com (eclipse.pacifier.com [199.2.117.78]) - by hub.org (8.9.3/8.9.3) with ESMTP id LAA76594 - for ; Fri, 21 Jan 2000 11:49:01 -0500 (EST) - (envelope-from dhogaza@pacifier.com) -Received: from desktop (dsl-dhogaza.pacifier.net [216.65.147.68]) - by eclipse.pacifier.com (8.9.3/8.9.3pop) with SMTP id IAA00225; - Fri, 21 Jan 2000 08:47:26 -0800 (PST) -Message-Id: <3.0.1.32.20000121081044.01036290@mail.pacifier.com> -X-Sender: dhogaza@mail.pacifier.com -X-Mailer: Windows Eudora Pro Version 3.0.1 (32) -Date: Fri, 21 Jan 2000 08:10:44 -0800 -To: xun@cs.ucsb.edu, pgsql-hackers@postgreSQL.org -From: Don Baccus -Subject: Re: Re. [HACKERS] Some notes on optimizer cost estimates -In-Reply-To: <200001210219.SAA22377@xp10-06.dialup.commserv.ucsb.edu> -Mime-Version: 1.0 -Content-Type: text/plain; charset="us-ascii" -Sender: owner-pgsql-hackers@postgreSQL.org -Status: OR - -At 06:19 PM 1/20/00 -0800, Xun Cheng wrote: ->I'm very glad you bring up this cost estimate issue. ->Recent work in database research have argued a more ->detailed disk access cost model should be used for ->large queries especially joins. ->Traditional cost estimate only considers the number of ->disk pages accessed. However a more detailed model ->would consider three parameters: avg. seek, avg. latency ->and avg. page transfer. For old disk, typical values are ->SEEK=9.5 milliseconds, LATENCY=8.3 ms, TRANSFER=2.6ms. ->A sequential continuous reading of a table (assuming ->1000 continuous pages) would cost ->(SEEK+LATENCY+1000*TRANFER=2617.8ms); while quasi-randomly ->reading 200 times with 2 continuous pages/time would ->cost (SEEK+200*LATENCY+400*TRANSFER=2700ms). ->Someone from IBM lab re-studied the traditional ->ad hoc join algorithms (nested, sort-merge, hash) using the detailed cost -model ->and found some interesting results. - -One complication when doing an index scan is that you are -accessing two separate files (table and index), which can frequently -be expected to cause an considerable increase in average seek time. - -Oracle and other commercial databases recommend spreading indices and -tables over several spindles if at all possible in order to minimize -this effect. - -I suspect it also helps their optimizer make decisions that are -more consistently good for customers with the largest and most -complex databases and queries, by making cost estimates more predictably -reasonable. - -Still...this doesn't help with the question about the effect of the -filesystem system cache. I wandered around the web for a little bit -last night, and found one summary of a paper by Osterhout on the -effect of the Solaris cache on a fileserver serving diskless workstations. -There was reference to the hierarchy involved (i.e. the local workstation -cache is faster than the fileserver's cache which has to be read via -the network which in turn is faster than reading from the fileserver's -disk). It appears the rule-of-thumb for the cache-hit ratio on reads, -presumably based on measuring some internal Sun systems, used in their -calculations was 80%. - -Just a datapoint to think about. - -There's also considerable operating system theory on paging systems -that might be useful for thinking about trying to estimate the -Postgres cache/hit ratio. Then again, maybe Postgres could just -keep count of how many pages of a given table are in the cache at -any given time? Or simply keep track of the current ratio of hits -and misses? - ->>I have been spending some time measuring actual runtimes for various ->>sequential-scan and index-scan query plans, and have learned that the ->>current Postgres optimizer's cost estimation equations are not very ->>close to reality at all. - ->One interesting question I'd like to ask is if this non-closeness ->really affects the optimal choice of postgresql's query optimizer. ->And to what degree the effects might be? My point is that ->if the optimizer estimated the cost for sequential-scan is 10 and ->the cost for index-scan is 20 while the actual costs are 10 vs. 40, ->it should be ok because the optimizer would still choose sequential-scan ->as it should. - -This is crucial, of course - if there are only two types of scans -available, what ever heuristic is used only has to be accurate enough -to pick the right one. Once the choice is made, it doesn't really -matter (from the optimizer's POV) just how long it will actually take, -the time will be spent and presumably it will be shorter than the -alternative. - -How frequently will the optimizer choose wrongly if: - -1. All of the tables and indices were in PG buffer cache or filesystem - cache? (i.e. fixed access times for both types of scans) - -or - -2. The table's so big that only a small fraction can reside in RAM - during the scan and join, which means that the non-sequential - disk access pattern of the indexed scan is much more expensive. - -Also, if you pick sequential scans more frequently based on a presumption -that index scans are expensive due to increased average seek time, how -often will this penalize the heavy-duty user that invests in extra -drives and lots of RAM? - -... - ->>The current cost estimation ->>method essentially assumes that the buffer cache plus OS disk cache will ->>be 100% efficient --- we will never have to read the same page of the ->>main table twice in a scan, due to having discarded it between ->>references. This of course is unreasonably optimistic. Worst case ->>is that we'd fetch a main-table page for each selected tuple, but in ->>most cases that'd be unreasonably pessimistic. -> ->This is actually the motivation that I asked before if postgresql ->has a raw disk facility. That way we have much control on this cache ->issue. Of course only if we can provide some algo. better than OS ->cache algo. (depending on the context, like large joins), a raw disk ->facility will be worthwhile (besides the recoverability). - -Postgres does have control over its buffer cache. The one thing that -raw disk I/O would give you is control over where blocks are placed, -meaning you could more accurately model the cost of retrieving them. -So presumably the cache could be tuned to the allocation algorithm -used to place various structures on the disk. - -I still wonder just how much gain you get by this approach. Compared, -to, say simply spending $2,000 on a gigabyte of RAM. Heck, PCs even -support a couple gigs of RAM now. - ->Actually I have another question for you guys which is somehow related ->to this cost estimation issue. You know the difference between OLTP ->and OLAP. My question is how you target postgresql on both kinds ->of applications or just OLTP. From what I know OLTP and OLAP would ->have a big difference in query characteristics and thus ->optimization difference. If postgresql is only targeted on ->OLTP, the above cost estimation issue might not be that ->important. However for OLAP, large tables and large queries are ->common and optimization would be difficult. - - - -- Don Baccus, Portland OR - Nature photos, on-line guides, Pacific Northwest - Rare Bird Alert Service and other goodies at - http://donb.photo.net. - -************ - -From pgsql-hackers-owner+M6019@hub.org Mon Aug 21 11:47:56 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id LAA07289 - for ; Mon, 21 Aug 2000 11:47:55 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e7LFlpT03383; - Mon, 21 Aug 2000 11:47:51 -0400 (EDT) -Received: from mail.fct.unl.pt (fct1.si.fct.unl.pt [193.136.120.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e7LFlaT03243 - for ; Mon, 21 Aug 2000 11:47:37 -0400 (EDT) -Received: (qmail 7416 invoked by alias); 21 Aug 2000 15:54:33 -0000 -Received: (qmail 7410 invoked from network); 21 Aug 2000 15:54:32 -0000 -Received: from eros.si.fct.unl.pt (193.136.120.112) - by fct1.si.fct.unl.pt with SMTP; 21 Aug 2000 15:54:32 -0000 -Date: Mon, 21 Aug 2000 16:48:08 +0100 (WEST) -From: =?iso-8859-1?Q?Tiago_Ant=E3o?= -X-Sender: tiago@eros.si.fct.unl.pt -To: Tom Lane -cc: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Optimisation deficiency: currval('seq')-->seq scan, - constant-->index scan -In-Reply-To: <1731.966868649@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: ORr - -On Mon, 21 Aug 2000, Tom Lane wrote: - -> > One thing it might be interesting (please tell me if you think -> > otherwise) would be to improve pg with better statistical information, by -> > using, for example, histograms. -> -> Yes, that's been on the todo list for a while. - - If it's ok and nobody is working on that, I'll look on that subject. - I'll start by looking at the analize portion of vacuum. I'm thinking in -using arrays for the histogram (I've never used the array data type of -postgres). - Should I use 7.0.2 or the cvs version? - - -> Interesting article. We do most of what she talks about, but we don't -> have anything like the ClusterRatio statistic. We need it --- that was -> just being discussed a few days ago in another thread. Do you have any -> reference on exactly how DB2 defines that stat? - - - I don't remember seeing that information spefically. From what I've -read I can speculate: - - 1. They have clusterratios for both indexes and the relation itself. - 2. They might use an index even if there is no "order by" if the table -has a low clusterratio: just to get the RIDs, then sort the RIDs and -fetch. - 3. One possible way to calculate this ratio: - a) for tables - SeqScan - if tuple points to a next tuple on the same page then its -"good" - ratio = # good tuples / # all tuples - b) for indexes (high speculation ratio here) - foreach pointed RID in index - if RID is in same page of next RID in index than mark as -"good" - - I suspect that if a tuple size is big (relative to page size) than the -cluster ratio is always low. - - A tuple might also be "good" if it pointed to the next page. - -Tiago - - -From pgsql-hackers-owner+M6152@hub.org Wed Aug 23 13:00:33 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id NAA10259 - for ; Wed, 23 Aug 2000 13:00:33 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e7NGsPN83008; - Wed, 23 Aug 2000 12:54:25 -0400 (EDT) -Received: from mail.fct.unl.pt (fct1.si.fct.unl.pt [193.136.120.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e7NGniN81749 - for ; Wed, 23 Aug 2000 12:49:44 -0400 (EDT) -Received: (qmail 9869 invoked by alias); 23 Aug 2000 15:10:04 -0000 -Received: (qmail 9860 invoked from network); 23 Aug 2000 15:10:04 -0000 -Received: from eros.si.fct.unl.pt (193.136.120.112) - by fct1.si.fct.unl.pt with SMTP; 23 Aug 2000 15:10:04 -0000 -Date: Wed, 23 Aug 2000 16:03:42 +0100 (WEST) -From: =?iso-8859-1?Q?Tiago_Ant=E3o?= -X-Sender: tiago@eros.si.fct.unl.pt -To: Tom Lane -cc: Jules Bean , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Optimisation deficiency: currval('seq')-->seq scan, - constant-->index scan -In-Reply-To: <27971.967041030@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: ORr - -Hi! - -On Wed, 23 Aug 2000, Tom Lane wrote: - -> Yes, we know about that one. We have stats about the most common value -> in a column, but no information about how the less-common values are -> distributed. We definitely need stats about several top values not just -> one, because this phenomenon of a badly skewed distribution is pretty -> common. - - - An end-biased histogram has stats on top values and also on the least -frequent values. So if a there is a selection on a value that is well -bellow average, the selectivity estimation will be more acurate. On some -research papers I've read, it's refered that this is a better approach -than equi-width histograms (which are said to be the "industry" standard). - - I not sure whether to use a table or a array attribute on pg_stat for -the histogram, the problem is what could be expected from the size of the -attribute (being a text). I'm very affraid of the cost of going through -several tuples on a table (pg_histogram?) during the optimization phase. - - One other idea would be to only have better statistics for special -attributes requested by the user... something like "analyze special -table(column)". - -Best Regards, -Tiago - - - -From pgsql-hackers-owner+M6160@hub.org Thu Aug 24 00:21:39 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id AAA27662 - for ; Thu, 24 Aug 2000 00:21:38 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e7O46w585951; - Thu, 24 Aug 2000 00:06:58 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.10.1/8.10.1) with ESMTP id e7O3uv583775 - for ; Wed, 23 Aug 2000 23:56:57 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id XAA20973; - Wed, 23 Aug 2000 23:56:35 -0400 (EDT) -To: =?iso-8859-1?Q?Tiago_Ant=E3o?= -cc: Jules Bean , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Optimisation deficiency: currval('seq')-->seq scan, constant-->index scan -In-reply-to: -References: -Comments: In-reply-to =?iso-8859-1?Q?Tiago_Ant=E3o?= - message dated "Wed, 23 Aug 2000 16:03:42 +0100" -Date: Wed, 23 Aug 2000 23:56:35 -0400 -Message-ID: <20970.967089395@sss.pgh.pa.us> -From: Tom Lane -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: OR - -=?iso-8859-1?Q?Tiago_Ant=E3o?= writes: -> One other idea would be to only have better statistics for special -> attributes requested by the user... something like "analyze special -> table(column)". - -This might actually fall out "for free" from the cheapest way of -implementing the stats. We've talked before about scanning btree -indexes directly to obtain data values in sorted order, which makes -it very easy to find the most common values. If you do that, you -get good stats for exactly those columns that the user has created -indexes on. A tad indirect but I bet it'd be effective... - - regards, tom lane - -From pgsql-hackers-owner+M6165@hub.org Thu Aug 24 05:33:02 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id FAA14309 - for ; Thu, 24 Aug 2000 05:33:01 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e7O9X0584670; - Thu, 24 Aug 2000 05:33:00 -0400 (EDT) -Received: from athena.office.vi.net (office-gwb.fulham.vi.net [194.88.77.158]) - by hub.org (8.10.1/8.10.1) with ESMTP id e7O9Ix581216 - for ; Thu, 24 Aug 2000 05:19:03 -0400 (EDT) -Received: from grommit.office.vi.net [192.168.1.200] (mail) - by athena.office.vi.net with esmtp (Exim 3.12 #1 (Debian)) - id 13Rt2Y-00073I-00; Thu, 24 Aug 2000 10:11:14 +0100 -Received: from jules by grommit.office.vi.net with local (Exim 3.12 #1 (Debian)) - id 13Rt2Y-0005GV-00; Thu, 24 Aug 2000 10:11:14 +0100 -Date: Thu, 24 Aug 2000 10:11:14 +0100 -From: Jules Bean -To: Tom Lane -Cc: Tiago Ant?o , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Optimisation deficiency: currval('seq')-->seq scan, constant-->index scan -Message-ID: <20000824101113.N17510@grommit.office.vi.net> -References: <1731.966868649@sss.pgh.pa.us> <20000823133418.F17510@grommit.office.vi.net> <27971.967041030@sss.pgh.pa.us> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.2i -In-Reply-To: <27971.967041030@sss.pgh.pa.us>; from tgl@sss.pgh.pa.us on Wed, Aug 23, 2000 at 10:30:30AM -0400 -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: OR - -On Wed, Aug 23, 2000 at 10:30:30AM -0400, Tom Lane wrote: -> Jules Bean writes: -> > I have in a table a 'category' column which takes a small number of -> > (basically fixed) values. Here by 'small', I mean ~1000, while the -> > table itself has ~10 000 000 rows. Some categories have many, many -> > more rows than others. In particular, there's one category which hits -> > over half the rows. Because of this (AIUI) postgresql assumes -> > that the query -> > select ... from thistable where category='something' -> > is best served by a seqscan, even though there is an index on -> > category. -> -> Yes, we know about that one. We have stats about the most common value -> in a column, but no information about how the less-common values are -> distributed. We definitely need stats about several top values not just -> one, because this phenomenon of a badly skewed distribution is pretty -> common. - -ISTM that that might be enough, in fact. - -If you have stats telling you that the most popular value is 'xyz', -and that it constitutes 50% of the rows (i.e. 5 000 000) then you can -conclude that, on average, other entries constitute a mere 5 000 -000/999 ~~ 5000 entries, and it would be definitely be enough. -(That's assuming you store the number of distinct values somewhere). - - -> BTW, if your highly-popular value is actually a dummy value ('UNKNOWN' -> or something like that), a fairly effective workaround is to replace the -> dummy entries with NULL. The system does account for NULLs separately -> from real values, so you'd then get stats based on the most common -> non-dummy value. - -I can't really do that. Even if I could, the distribution is very -skewed -- so the next most common makes up a very high proportion of -what's left. I forget the figures exactly. - -Jules - -From pgsql-hackers-owner+M6154@hub.org Wed Aug 23 14:36:41 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id NAA11076 - for ; Wed, 23 Aug 2000 13:36:41 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e7NHTqN92431; - Wed, 23 Aug 2000 13:29:52 -0400 (EDT) -Received: from mail.fct.unl.pt (fct1.si.fct.unl.pt [193.136.120.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e7NHM1N90883 - for ; Wed, 23 Aug 2000 13:22:01 -0400 (EDT) -Received: (qmail 13816 invoked by alias); 23 Aug 2000 17:29:02 -0000 -Received: (qmail 13807 invoked from network); 23 Aug 2000 17:29:02 -0000 -Received: from eros.si.fct.unl.pt (193.136.120.112) - by fct1.si.fct.unl.pt with SMTP; 23 Aug 2000 17:29:02 -0000 -Date: Wed, 23 Aug 2000 18:22:40 +0100 (WEST) -From: =?iso-8859-1?Q?Tiago_Ant=E3o?= -X-Sender: tiago@eros.si.fct.unl.pt -To: Tom Lane -cc: =?iso-8859-1?Q?Tiago_Ant=E3o?= , - PostgreSQL Hackers list -Subject: Re: [HACKERS] analyze.c -In-Reply-To: <28154.967041988@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: ORr - - - -On Wed, 23 Aug 2000, Tom Lane wrote: - -> > What's the big reason not to do that? I know that -> > there is some code in analyze.c (like comparing) that uses other parts of -> > pg, but that seems to be easily fixed. -> -> Are you proposing not to do any comparisons? It will be interesting to -> see how you can compute a histogram without any idea of equality or -> ordering. But if you want that, then you still need the function-call -> manager as well as the type-specific comparison routines for every -> datatype that you might be asked to operate on (don't forget -> user-defined types here). - - I forgot user defined data types :-(, but regarding histograms I think -the code can be made external (at least for testing purposes): - 1. I was not suggesting not to do any comparisons, but I think the only -comparison I need is equality, I don't need order as I don't need to -calculate mins or maxs (I just need mins and maxes on frequencies, NOT on -dat itself) to make a histogram. - 2. The mapping to text guarantees that I have (PQgetvalue returns -always char* and pg_statistics keeps a "text" anyway) a way of knowing -about equality regardless of type. - - But at least anything relating to order has to be in. - -> > I'm leaning toward the implementation of end-biased histograms. There is -> > an introductory reference in the IEEE Data Engineering Bulletin, september -> > 1995 (available on microsoft research site). -> -> Sounds interesting. Can you give us an exact URL? - -http://www.research.microsoft.com/research/db/debull/default.htm - -BTW, you can get access to SIGMOD CDs with lots of goodies for a very low -price (at least in 1999 it was a bargain), check out ACM membership for -sigmod. - -I've been reading something about implementation of histograms, and, -AFAIK, in practice histograms is just a cool name for no more than: - 1. top ten with frequency for each - 2. the same for top ten worse - 3. average for the rest - -I'm writing code get this info (outside pg for now - for testing -purposes). - -Best Regards, -Tiago -PS - again: I'm starting, so, some of my comments can be completly dumb. - -From pgsql-hackers-owner+M7514@hub.org Sun Oct 15 20:38:12 2000 -Received: from hub.org (hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id TAA18459 - for ; Sun, 15 Oct 2000 19:38:12 -0400 (EDT) -Received: from hub.org.org (localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e9FNaUR59496; - Sun, 15 Oct 2000 19:36:30 -0400 (EDT) -Received: from sss.pgh.pa.us (sss.pgh.pa.us [209.114.132.154]) - by hub.org (8.10.1/8.10.1) with ESMTP id e9FNYuR58276 - for ; Sun, 15 Oct 2000 19:34:56 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.0/8.11.0) with ESMTP id e9FNXaB06046; - Sun, 15 Oct 2000 19:33:36 -0400 (EDT) -To: Bruce Momjian -cc: Jules Bean , - Alfred Perlstein , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Performance on inserts -In-reply-to: <200010152320.TAA17944@candle.pha.pa.us> -References: <200010152320.TAA17944@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Sun, 15 Oct 2000 19:20:35 -0400" -Date: Sun, 15 Oct 2000 19:33:36 -0400 -Message-ID: <6043.971652816@sss.pgh.pa.us> -From: Tom Lane -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: ORr - -Bruce Momjian writes: -> However, assume tab2.col2 equals 3. I assume this would cause an index -> scan because the executor doesn't know about the most common value, -> right? Is it worth trying to improve that? - -Oh, I see: you are assuming that a nestloop join is being done, and -wondering if it's worthwhile to switch dynamically between seqscan -and indexscan for each scan of the inner relation, depending on exactly -what value is being supplied from the outer relation for that scan. -Hmm. - -Not sure if it's worth the trouble or not. Nestloop is usually a -last-resort join strategy anyway, and is unlikely to be picked when the -tables are large enough to make performance be a big issue. - - regards, tom lane - -From tgl@sss.pgh.pa.us Mon Oct 16 01:48:27 2000 -Received: from sss.pgh.pa.us (sss.pgh.pa.us [209.114.132.154]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id AAA01602 - for ; Mon, 16 Oct 2000 00:48:26 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.1/8.11.1) with ESMTP id e9G4mu521809; - Mon, 16 Oct 2000 00:48:56 -0400 (EDT) -To: Bruce Momjian -cc: Jules Bean , - Alfred Perlstein , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Performance on inserts -In-reply-to: <200010160441.AAA01374@candle.pha.pa.us> -References: <200010160441.AAA01374@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Mon, 16 Oct 2000 00:41:49 -0400" -Date: Mon, 16 Oct 2000 00:48:56 -0400 -Message-ID: <21806.971671736@sss.pgh.pa.us> -From: Tom Lane -Status: OR - -Bruce Momjian writes: ->> So an inner indexscan for tab1 is definitely a possible plan. - -> Yes, that was my point, that a nested loop could easily be involved if -> the joined table has a restriction. Is there a TODO item here? - -More like a "to investigate" --- I'm not sold on the idea that a -dynamic switch in plan types would be a win. Maybe it would be, -but... - -One thing to think about is that it'd be critically dependent on having -accurate statistics. Currently, the planner only places bets on the -average behavior over a whole join. If you make a separate bet on each -scan, then you open up the risk of betting wrong every time, should -your stats be out-of-date or otherwise misleading. - - regards, tom lane - diff --git a/doc/TODO.detail/performance b/doc/TODO.detail/performance deleted file mode 100644 index 8d38aa5ddb..0000000000 --- a/doc/TODO.detail/performance +++ /dev/null @@ -1,1651 +0,0 @@ -From owner-pgsql-hackers@hub.org Sun Jun 14 18:45:04 1998 -Received: from hub.org (hub.org [209.47.148.200]) - by candle.pha.pa.us (8.8.5/8.8.5) with ESMTP id SAA03690 - for ; Sun, 14 Jun 1998 18:45:00 -0400 (EDT) -Received: from localhost (majordom@localhost) by hub.org (8.8.8/8.7.5) with SMTP id SAA28049; Sun, 14 Jun 1998 18:39:42 -0400 (EDT) -Received: by hub.org (TLB v0.10a (1.23 tibbs 1997/01/09 00:29:32)); Sun, 14 Jun 1998 18:36:06 +0000 (EDT) -Received: (from majordom@localhost) by hub.org (8.8.8/8.7.5) id SAA27943 for pgsql-hackers-outgoing; Sun, 14 Jun 1998 18:36:04 -0400 (EDT) -Received: from angular.illustra.com (ifmxoak.illustra.com [206.175.10.34]) by hub.org (8.8.8/8.7.5) with ESMTP id SAA27925 for ; Sun, 14 Jun 1998 18:35:47 -0400 (EDT) -Received: from hawk.illustra.com (hawk.illustra.com [158.58.61.70]) by angular.illustra.com (8.7.4/8.7.3) with SMTP id PAA21293 for ; Sun, 14 Jun 1998 15:35:12 -0700 (PDT) -Received: by hawk.illustra.com (5.x/smail2.5/06-10-94/S) - id AA07922; Sun, 14 Jun 1998 15:35:13 -0700 -From: dg@illustra.com (David Gould) -Message-Id: <9806142235.AA07922@hawk.illustra.com> -Subject: [HACKERS] performance tests, initial results -To: pgsql-hackers@postgreSQL.org -Date: Sun, 14 Jun 1998 15:35:13 -0700 (PDT) -Mime-Version: 1.0 -Content-Type: text/plain; charset=US-ASCII -Content-Transfer-Encoding: 7bit -Sender: owner-pgsql-hackers@hub.org -Precedence: bulk -Status: RO - - -I have been playing a little with the performance tests found in -pgsql/src/tests/performance and have a few observations that might be of -minor interest. - -The tests themselves are simple enough although the result parsing in the -driver did not work on Linux. I am enclosing a patch below to fix this. I -think it will also work better on the other systems. - -A summary of results from my testing are below. Details are at the bottom -of this message. - -My test system is 'leslie': - - linux 2.0.32, gcc version 2.7.2.3 - P133, HX chipset, 512K L2, 32MB mem - NCR810 fast scsi, Quantum Atlas 2GB drive (7200 rpm). - - - Results Summary (times in seconds) - - Single txn 8K txn Create 8K idx 8K random Simple -Case Description 8K insert 8K insert Index Insert Scans Orderby -=================== ========== ========= ====== ====== ========= ======= -1 From Distribution - P90 FreeBsd -B256 39.56 1190.98 3.69 46.65 65.49 2.27 - IDE - -2 Running on leslie - P133 Linux 2.0.32 15.48 326.75 2.99 20.69 35.81 1.68 - SCSI 32M - -3 leslie, -o -F - no forced writes 15.90 24.98 2.63 20.46 36.43 1.69 - -4 leslie, -o -F - no ASSERTS 14.92 23.23 1.38 18.67 33.79 1.58 - -5 leslie, -o -F -B2048 - more buffers 21.31 42.28 2.65 25.74 42.26 1.72 - -6 leslie, -o -F -B2048 - more bufs, no ASSERT 20.52 39.79 1.40 24.77 39.51 1.55 - - - - - Case to Case Difference Factors (+ is faster) - - Single txn 8K txn Create 8K idx 8K random Simple -Case Description 8K insert 8K insert Index Insert Scans Orderby -=================== ========== ========= ====== ====== ========= ======= - -leslie vs BSD P90. 2.56 3.65 1.23 2.25 1.83 1.35 - -(noflush -F) vs no -F -1.03 13.08 1.14 1.01 -1.02 1.00 - -No Assert vs Assert 1.05 1.07 1.90 1.06 1.07 1.09 - --B256 vs -B2048 1.34 1.69 1.01 1.26 1.16 1.02 - - -Observations: - - - leslie (P133 linux) appears to be about 1.8 times faster than the - P90 BSD system used for the test result distributed with the source, not - counting the 8K txn insert case which was completely disk bound. - - - SCSI disks make a big (factor of 3.6) difference. During this test the - disk was hammering and cpu utilization was < 10%. - - - Assertion checking seems to cost about 7% except for create index where - it costs 90% - - - the -F option to avoid flushing buffers has tremendous effect if there are - many very small transactions. Or, another way, flushing at the end of the - transaction is a major disaster for performance. - - - Something is very wrong with our buffer cache implementation. Going from - 256 buffers to 2048 buffers costs an average of 25%. In the 8K txn case - it costs about 70%. I see looking at the code and profiling that in the 8K - txn case this is in BufferSync() which examines all the buffers at commit - time. I don't quite understand why it is so costly for the single 8K row - txn (35%) though. - -It would be nice to have some more tests. Maybe the Wisconsin stuff will -be useful. - - - ------------------ patch to test harness. apply from pgsql ------------ -*** src/test/performance/runtests.pl.orig Sun Jun 14 11:34:04 1998 - -Differences % - - ------------------ patch to test harness. apply from pgsql ------------ -*** src/test/performance/runtests.pl.orig Sun Jun 14 11:34:04 1998 ---- src/test/performance/runtests.pl Sun Jun 14 12:07:30 1998 -*************** -*** 84,123 **** - open (STDERR, ">$TmpFile") or die; - select (STDERR); $| = 1; - -! for ($i = 0; $i <= $#perftests; $i++) -! { - $test = $perftests[$i]; - ($test, $XACTBLOCK) = split (/ /, $test); - $runtest = $test; -! if ( $test =~ /\.ntm/ ) -! { -! # - # No timing for this queries -- # - close (STDERR); # close $TmpFile - open (STDERR, ">/dev/null") or die; - $runtest =~ s/\.ntm//; - } -! else -! { - close (STDOUT); - open(STDOUT, ">&SAVEOUT"); - print STDOUT "\nRunning: $perftests[$i+1] ..."; - close (STDOUT); - open (STDOUT, ">/dev/null") or die; - select (STDERR); $| = 1; -! printf "$perftests[$i+1]: "; - } - - do "sqls/$runtest"; - - # Restore STDERR to $TmpFile -! if ( $test =~ /\.ntm/ ) -! { - close (STDERR); - open (STDERR, ">>$TmpFile") or die; - } -- - select (STDERR); $| = 1; - $i++; - } ---- 84,116 ---- - open (STDERR, ">$TmpFile") or die; - select (STDERR); $| = 1; - -! for ($i = 0; $i <= $#perftests; $i++) { - $test = $perftests[$i]; - ($test, $XACTBLOCK) = split (/ /, $test); - $runtest = $test; -! if ( $test =~ /\.ntm/ ) { - # No timing for this queries - close (STDERR); # close $TmpFile - open (STDERR, ">/dev/null") or die; - $runtest =~ s/\.ntm//; - } -! else { - close (STDOUT); - open(STDOUT, ">&SAVEOUT"); - print STDOUT "\nRunning: $perftests[$i+1] ..."; - close (STDOUT); - open (STDOUT, ">/dev/null") or die; - select (STDERR); $| = 1; -! print "$perftests[$i+1]: "; - } - - do "sqls/$runtest"; - - # Restore STDERR to $TmpFile -! if ( $test =~ /\.ntm/ ) { - close (STDERR); - open (STDERR, ">>$TmpFile") or die; - } - select (STDERR); $| = 1; - $i++; - } -*************** -*** 128,138 **** - open (TMPF, "<$TmpFile") or die; - open (RESF, ">$ResFile") or die; - -! while () -! { -! $str = $_; -! ($test, $rtime) = split (/:/, $str); -! ($tmp, $rtime, $rest) = split (/[ ]+/, $rtime); -! print RESF "$test: $rtime\n"; - } - ---- 121,130 ---- - open (TMPF, "<$TmpFile") or die; - open (RESF, ">$ResFile") or die; - -! while () { -! if (m/^(.*: ).* ([0-9:.]+) *elapsed/) { -! ($test, $rtime) = ($1, $2); -! print RESF $test, $rtime, "\n"; -! } - } - ------------------------------------------------------------------------- - - -------------------------- testcase detail -------------------------- - -1. from distribution - DBMS: PostgreSQL 6.2b10 - OS: FreeBSD 2.1.5-RELEASE - HardWare: i586/90, 24M RAM, IDE - StartUp: postmaster -B 256 '-o -S 2048' -S - Compiler: gcc 2.6.3 - Compiled: -O, without CASSERT checking, with - -DTBL_FREE_CMD_MEMORY (to free memory - if BEGIN/END after each query execution) - DB connection startup: 0.20 - 8192 INSERTs INTO SIMPLE (1 xact): 39.58 - 8192 INSERTs INTO SIMPLE (8192 xacts): 1190.98 - Create INDEX on SIMPLE: 3.69 - 8192 INSERTs INTO SIMPLE with INDEX (1 xact): 46.65 - 8192 random INDEX scans on SIMPLE (1 xact): 65.49 - ORDER BY SIMPLE: 2.27 - - -2. run on leslie with asserts - DBMS: PostgreSQL 6.3.2 (plus changes to 98/06/01) - OS: Linux 2.0.32 leslie - HardWare: i586/133 HX 512, 32M RAM, fast SCSI, 7200rpm - StartUp: postmaster -B 256 '-o -S 2048' -S - Compiler: gcc 2.7.2.3 - Compiled: -O, WITH CASSERT checking, with - -DTBL_FREE_CMD_MEMORY (to free memory - if BEGIN/END after each query execution) - DB connection startup: 0.10 - 8192 INSERTs INTO SIMPLE (1 xact): 15.48 - 8192 INSERTs INTO SIMPLE (8192 xacts): 326.75 - Create INDEX on SIMPLE: 2.99 - 8192 INSERTs INTO SIMPLE with INDEX (1 xact): 20.69 - 8192 random INDEX scans on SIMPLE (1 xact): 35.81 - ORDER BY SIMPLE: 1.68 - - -3. with -F to avoid forced i/o - DBMS: PostgreSQL 6.3.2 (plus changes to 98/06/01) - OS: Linux 2.0.32 leslie - HardWare: i586/133 HX 512, 32M RAM, fast SCSI, 7200rpm - StartUp: postmaster -B 256 '-o -S 2048 -F' -S - Compiler: gcc 2.7.2.3 - Compiled: -O, WITH CASSERT checking, with - -DTBL_FREE_CMD_MEMORY (to free memory - if BEGIN/END after each query execution) - DB connection startup: 0.10 - 8192 INSERTs INTO SIMPLE (1 xact): 15.90 - 8192 INSERTs INTO SIMPLE (8192 xacts): 24.98 - Create INDEX on SIMPLE: 2.63 - 8192 INSERTs INTO SIMPLE with INDEX (1 xact): 20.46 - 8192 random INDEX scans on SIMPLE (1 xact): 36.43 - ORDER BY SIMPLE: 1.69 - - -4. no asserts, -F to avoid forced I/O - DBMS: PostgreSQL 6.3.2 (plus changes to 98/06/01) - OS: Linux 2.0.32 leslie - HardWare: i586/133 HX 512, 32M RAM, fast SCSI, 7200rpm - StartUp: postmaster -B 256 '-o -S 2048' -S - Compiler: gcc 2.7.2.3 - Compiled: -O, No CASSERT checking, with - -DTBL_FREE_CMD_MEMORY (to free memory - if BEGIN/END after each query execution) - DB connection startup: 0.10 - 8192 INSERTs INTO SIMPLE (1 xact): 14.92 - 8192 INSERTs INTO SIMPLE (8192 xacts): 23.23 - Create INDEX on SIMPLE: 1.38 - 8192 INSERTs INTO SIMPLE with INDEX (1 xact): 18.67 - 8192 random INDEX scans on SIMPLE (1 xact): 33.79 - ORDER BY SIMPLE: 1.58 - - -5. with more buffers (2048 vs 256) and -F to avoid forced i/o - DBMS: PostgreSQL 6.3.2 (plus changes to 98/06/01) - OS: Linux 2.0.32 leslie - HardWare: i586/133 HX 512, 32M RAM, fast SCSI, 7200rpm - StartUp: postmaster -B 2048 '-o -S 2048 -F' -S - Compiler: gcc 2.7.2.3 - Compiled: -O, WITH CASSERT checking, with - -DTBL_FREE_CMD_MEMORY (to free memory - if BEGIN/END after each query execution) - DB connection startup: 0.11 - 8192 INSERTs INTO SIMPLE (1 xact): 21.31 - 8192 INSERTs INTO SIMPLE (8192 xacts): 42.28 - Create INDEX on SIMPLE: 2.65 - 8192 INSERTs INTO SIMPLE with INDEX (1 xact): 25.74 - 8192 random INDEX scans on SIMPLE (1 xact): 42.26 - ORDER BY SIMPLE: 1.72 - - -6. No Asserts, more buffers (2048 vs 256) and -F to avoid forced i/o - DBMS: PostgreSQL 6.3.2 (plus changes to 98/06/01) - OS: Linux 2.0.32 leslie - HardWare: i586/133 HX 512, 32M RAM, fast SCSI, 7200rpm - StartUp: postmaster -B 2048 '-o -S 2048 -F' -S - Compiler: gcc 2.7.2.3 - Compiled: -O, No CASSERT checking, with - -DTBL_FREE_CMD_MEMORY (to free memory - if BEGIN/END after each query execution) - DB connection startup: 0.11 - 8192 INSERTs INTO SIMPLE (1 xact): 20.52 - 8192 INSERTs INTO SIMPLE (8192 xacts): 39.79 - Create INDEX on SIMPLE: 1.40 - 8192 INSERTs INTO SIMPLE with INDEX (1 xact): 24.77 - 8192 random INDEX scans on SIMPLE (1 xact): 39.51 - ORDER BY SIMPLE: 1.55 ---------------------------------------------------------------------- - --dg - -David Gould dg@illustra.com 510.628.3783 or 510.305.9468 -Informix Software (No, really) 300 Lakeside Drive Oakland, CA 94612 -"Don't worry about people stealing your ideas. If your ideas are any - good, you'll have to ram them down people's throats." -- Howard Aiken - - -From owner-pgsql-hackers@hub.org Tue Oct 19 10:31:10 1999 -Received: from renoir.op.net (root@renoir.op.net [209.152.193.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id KAA29087 - for ; Tue, 19 Oct 1999 10:31:08 -0400 (EDT) -Received: from hub.org (hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.12 $) with ESMTP id KAA27535 for ; Tue, 19 Oct 1999 10:19:47 -0400 (EDT) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id KAA30328; - Tue, 19 Oct 1999 10:12:10 -0400 (EDT) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Tue, 19 Oct 1999 10:11:55 -0400 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id KAA30030 - for pgsql-hackers-outgoing; Tue, 19 Oct 1999 10:11:00 -0400 (EDT) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from sss.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.9.3/8.9.3) with ESMTP id KAA29914 - for ; Tue, 19 Oct 1999 10:10:33 -0400 (EDT) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss.sss.pgh.pa.us (localhost [127.0.0.1]) - by sss.sss.pgh.pa.us (8.9.1/8.9.1) with ESMTP id KAA09038; - Tue, 19 Oct 1999 10:09:15 -0400 (EDT) -To: "Hiroshi Inoue" -cc: "Vadim Mikheev" , pgsql-hackers@postgreSQL.org -Subject: Re: [HACKERS] mdnblocks is an amazing time sink in huge relations -In-reply-to: Your message of Tue, 19 Oct 1999 19:03:22 +0900 - <000801bf1a19$2d88ae20$2801007e@cadzone.tpf.co.jp> -Date: Tue, 19 Oct 1999 10:09:15 -0400 -Message-ID: <9036.940342155@sss.pgh.pa.us> -From: Tom Lane -Sender: owner-pgsql-hackers@postgreSQL.org -Status: RO - -"Hiroshi Inoue" writes: -> 1. shared cache holds committed system tuples. -> 2. private cache holds uncommitted system tuples. -> 3. relpages of shared cache are updated immediately by -> phisical change and corresponding buffer pages are -> marked dirty. -> 4. on commit, the contents of uncommitted tuples except -> relpages,reltuples,... are copied to correponding tuples -> in shared cache and the combined contents are -> committed. -> If so,catalog cache invalidation would be no longer needed. -> But synchronization of the step 4. may be difficult. - -I think the main problem is that relpages and reltuples shouldn't -be kept in pg_class columns at all, because they need to have -very different update behavior from the other pg_class columns. - -The rest of pg_class is update-on-commit, and we can lock down any one -row in the normal MVCC way (if transaction A has modified a row and -transaction B also wants to modify it, B waits for A to commit or abort, -so it can know which version of the row to start from). Furthermore, -there can legitimately be several different values of a row in use in -different places: the latest committed, an uncommitted modification, and -one or more old values that are still being used by active transactions -because they were current when those transactions started. (BTW, the -present relcache is pretty bad about maintaining pure MVCC transaction -semantics like this, but it seems clear to me that that's the direction -we want to go in.) - -relpages cannot operate this way. To be useful for avoiding lseeks, -relpages *must* change exactly when the physical file changes. It -matters not at all whether the particular transaction that extended the -file ultimately commits or not. Moreover there can be only one correct -value (per relation) across the whole system, because there is only one -length of the relation file. - -If we want to take reltuples seriously and try to maintain it -on-the-fly, then I think it needs still a third behavior. Clearly -it cannot be updated using MVCC rules, or we lose all writer -concurrency (if A has added tuples to a rel, B would have to wait -for A to commit before it could update reltuples...). Furthermore -"updating" isn't a simple matter of storing what you think the new -value is; otherwise two transactions adding tuples in parallel would -leave the wrong answer after B commits and overwrites A's value. -I think it would work for each transaction to keep track of a net delta -in reltuples for each table it's changed (total tuples added less total -tuples deleted), and then atomically add that value to the table's -shared reltuples counter during commit. But that still leaves the -problem of how you use the counter during a transaction to get an -accurate answer to the question "If I scan this table now, how many tuples -will I see?" At the time the question is asked, the current shared -counter value might include the effects of transactions that have -committed since your transaction started, and therefore are not visible -under MVCC rules. I think getting the correct answer would involve -making an instantaneous copy of the current counter at the start of -your xact, and then adding your own private net-uncommitted-delta to -the saved shared counter value when asked the question. This doesn't -look real practical --- you'd have to save the reltuples counts of -*all* tables in the database at the start of each xact, on the off -chance that you might need them. Ugh. Perhaps someone has a better -idea. In any case, reltuples clearly needs different mechanisms than -the ordinary fields in pg_class do, because updating it will be a -performance bottleneck otherwise. - -If we allow reltuples to be updated only by vacuum-like events, as -it is now, then I think keeping it in pg_class is still OK. - -In short, it seems clear to me that relpages should be removed from -pg_class and kept somewhere else if we want to make it more reliable -than it is now, and the same for reltuples (but reltuples doesn't -behave the same as relpages, and probably ought to be handled -differently). - - regards, tom lane - -************ - -From owner-pgsql-hackers@hub.org Tue Oct 19 21:25:30 1999 -Received: from renoir.op.net (root@renoir.op.net [209.152.193.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id VAA28130 - for ; Tue, 19 Oct 1999 21:25:26 -0400 (EDT) -Received: from hub.org (hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.12 $) with ESMTP id VAA10512 for ; Tue, 19 Oct 1999 21:15:28 -0400 (EDT) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id VAA50745; - Tue, 19 Oct 1999 21:07:23 -0400 (EDT) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Tue, 19 Oct 1999 21:07:01 -0400 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id VAA50644 - for pgsql-hackers-outgoing; Tue, 19 Oct 1999 21:06:06 -0400 (EDT) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by hub.org (8.9.3/8.9.3) with ESMTP id VAA50584 - for ; Tue, 19 Oct 1999 21:05:26 -0400 (EDT) - (envelope-from Inoue@tpf.co.jp) -Received: from cadzone ([126.0.1.40] (may be forged)) - by sd.tpf.co.jp (2.5 Build 2640 (Berkeley 8.8.6)/8.8.4) with SMTP - id KAA01715; Wed, 20 Oct 1999 10:05:14 +0900 -From: "Hiroshi Inoue" -To: "Tom Lane" -Cc: -Subject: RE: [HACKERS] mdnblocks is an amazing time sink in huge relations -Date: Wed, 20 Oct 1999 10:09:13 +0900 -Message-ID: <000501bf1a97$b925a860$2801007e@cadzone.tpf.co.jp> -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 -X-Mimeole: Produced By Microsoft MimeOLE V4.72.2106.4 -Importance: Normal -Sender: owner-pgsql-hackers@postgreSQL.org -Status: RO - -> -----Original Message----- -> From: Hiroshi Inoue [mailto:Inoue@tpf.co.jp] -> Sent: Tuesday, October 19, 1999 6:45 PM -> To: Tom Lane -> Cc: pgsql-hackers@postgreSQL.org -> Subject: RE: [HACKERS] mdnblocks is an amazing time sink in huge -> relations -> -> -> > -> > "Hiroshi Inoue" writes: -> -> [snip] -> -> > -> > > Deletion is necessary only not to consume disk space. -> > > -> > > For example vacuum could remove not deleted files. -> > -> > Hmm ... interesting idea ... but I can hear the complaints -> > from users already... -> > -> -> My idea is only an analogy of PostgreSQL's simple recovery -> mechanism of tuples. -> -> And my main point is -> "delete fails after commit" doesn't harm the database -> except that not deleted files consume disk space. -> -> Of cource,it's preferable to delete relation files immediately -> after(or just when) commit. -> Useless files are visible though useless tuples are invisible. -> - -Anyway I don't need "DROP TABLE inside transactions" now -and my idea is originally for that issue. - -After a thought,I propose the following solution. - -1. mdcreate() couldn't create existent relation files. - If the existent file is of length zero,we would overwrite - the file.(seems the comment in md.c says so but the - code doesn't do so). - If the file is an Index relation file,we would overwrite - the file. - -2. mdunlink() couldn't unlink non-existent relation files. - mdunlink() doesn't call elog(ERROR) even if the file - doesn't exist,though I couldn't find where to change - now. - mdopen() doesn't call elog(ERROR) even if the file - doesn't exist and leaves the relation as CLOSED. - -Comments ? - -Regards. - -Hiroshi Inoue -Inoue@tpf.co.jp - -************ - -From pgsql-hackers-owner+M6267@hub.org Sun Aug 27 21:46:37 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id UAA07972 - for ; Sun, 27 Aug 2000 20:46:36 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e7S0kaL27996; - Sun, 27 Aug 2000 20:46:36 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.10.1/8.10.1) with ESMTP id e7S05aL24107 - for ; Sun, 27 Aug 2000 20:05:36 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id UAA01604 - for ; Sun, 27 Aug 2000 20:05:29 -0400 (EDT) -To: pgsql-hackers@postgreSQL.org -Subject: [HACKERS] Possible performance improvement: buffer replacement policy -Date: Sun, 27 Aug 2000 20:05:29 -0400 -Message-ID: <1601.967421129@sss.pgh.pa.us> -From: Tom Lane -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -Those of you with long memories may recall a benchmark that Edmund Mergl -drew our attention to back in May '99. That test showed extremely slow -performance for updating a table with many indexes (about 20). At the -time, it seemed the problem was due to bad performance of btree with -many equal keys, so I thought I'd go back and retry the benchmark after -this latest round of btree hackery. - -The good news is that btree itself seems to be pretty well fixed; the -bad news is that the benchmark is still slow for large numbers of rows. -The problem is I/O: the CPU mostly sits idle waiting for the disk. -As best I can tell, the difficulty is that the working set of pages -needed to update this many indexes is too large compared to the number -of disk buffers Postgres is using. (I was running with -B 1000 and -looking at behavior for a 100000-row test table. This gave me a table -size of 3876 pages, plus 11526 pages in 20 indexes.) - -Of course, there's only so much we can do when the number of buffers -is too small, but I still started to wonder if we are using the buffers -as effectively as we can. Some tracing showed that most of the pages -of the indexes were being read and written multiple times within a -single UPDATE query, while most of the pages of the table proper were -fetched and written only once. That says we're not using the buffers -as well as we could; the index pages are not being kept in memory when -they should be. In a query like this, we should displace main-table -pages sooner to allow keeping more index pages in cache --- but with -the simple LRU replacement method we use, once a page has been loaded -it will stay in cache for at least the next NBuffers (-B) page -references, no matter what. With a large NBuffers that's a long time. - -I've come across an interesting article: - The LRU-K Page Replacement Algorithm For Database Disk Buffering - Elizabeth J. O'Neil, Patrick E. O'Neil, Gerhard Weikum - Proceedings of the 1993 ACM SIGMOD international conference - on Management of Data, May 1993 -(If you subscribe to the ACM digital library, you can get a PDF of this -from there.) This article argues that standard LRU buffer management is -inherently not great for database caches, and that it's much better to -replace pages on the basis of time since the K'th most recent reference, -not just time since the most recent one. K=2 is enough to get most of -the benefit. The big win is that you are measuring an actual page -interreference time (between the last two references) and not just -dealing with a lower-bound guess on the interreference time. Frequently -used pages are thus much more likely to stay in cache. - -It looks like it wouldn't take too much work to replace shared buffers -on the basis of LRU-2 instead of LRU, so I'm thinking about trying it. - -Has anyone looked into this area? Is there a better method to try? - - regards, tom lane - -From prlw1@newn.cam.ac.uk Fri Jan 19 12:54:45 2001 -Received: from henry.newn.cam.ac.uk (henry.newn.cam.ac.uk [131.111.204.130]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id MAA29822 - for ; Fri, 19 Jan 2001 12:54:44 -0500 (EST) -Received: from [131.111.204.180] (helo=quartz.newn.cam.ac.uk) - by henry.newn.cam.ac.uk with esmtp (Exim 3.13 #1) - id 14JfkU-0001WA-00; Fri, 19 Jan 2001 17:54:54 +0000 -Received: from prlw1 by quartz.newn.cam.ac.uk with local (Exim 3.13 #1) - id 14Jfj6-0001cq-00; Fri, 19 Jan 2001 17:53:28 +0000 -Date: Fri, 19 Jan 2001 17:53:28 +0000 -From: Patrick Welche -To: Bruce Momjian -Cc: Tom Lane , pgsql-hackers@postgreSQL.org -Subject: Re: [HACKERS] Possible performance improvement: buffer replacement policy -Message-ID: <20010119175328.A6223@quartz.newn.cam.ac.uk> -Reply-To: prlw1@cam.ac.uk -References: <1601.967421129@sss.pgh.pa.us> <200101191703.MAA25873@candle.pha.pa.us> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.2i -In-Reply-To: <200101191703.MAA25873@candle.pha.pa.us>; from pgman@candle.pha.pa.us on Fri, Jan 19, 2001 at 12:03:58PM -0500 -Status: RO - -On Fri, Jan 19, 2001 at 12:03:58PM -0500, Bruce Momjian wrote: -> -> Tom, did we ever test this? I think we did and found that it was the -> same or worse, right? - -(Funnily enough, I just read that message:) - -To: Bruce Momjian -cc: pgsql-hackers@postgreSQL.org -Subject: Re: [HACKERS] Possible performance improvement: buffer replacement policy -In-reply-to: <200010161541.LAA06653@candle.pha.pa.us> -References: <200010161541.LAA06653@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Mon, 16 Oct 2000 11:41:41 -0400" -Date: Mon, 16 Oct 2000 11:49:52 -0400 -Message-ID: <26100.971711392@sss.pgh.pa.us> -From: Tom Lane -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO -Content-Length: 947 -Lines: 19 - -Bruce Momjian writes: ->> It looks like it wouldn't take too much work to replace shared buffers ->> on the basis of LRU-2 instead of LRU, so I'm thinking about trying it. ->> ->> Has anyone looked into this area? Is there a better method to try? - -> Sounds like a perfect idea. Good luck. :-) - -Actually, the idea went down in flames :-(, but I neglected to report -back to pghackers about it. I did do some code to manage buffers as -LRU-2. I didn't have any good performance test cases to try it with, -but Richard Brosnahan was kind enough to re-run the TPC tests previously -published by Great Bridge with that code in place. Wasn't any faster, -in fact possibly a little slower, likely due to the extra CPU time spent -on buffer freelist management. It's possible that other scenarios might -show a better result, but right now I feel pretty discouraged about the -LRU-2 idea and am not pursuing it. - - regards, tom lane - - -From pgsql-hackers-owner+M3455@postgresql.org Fri Jan 19 13:18:12 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id NAA02092 - for ; Fri, 19 Jan 2001 13:18:12 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f0JIFJ037872; - Fri, 19 Jan 2001 13:15:19 -0500 (EST) - (envelope-from pgsql-hackers-owner+M3455@postgresql.org) -Received: from sectorbase2.sectorbase.com ([208.48.122.131]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id f0JI7V036780 - for ; Fri, 19 Jan 2001 13:07:31 -0500 (EST) - (envelope-from vmikheev@SECTORBASE.COM) -Received: by sectorbase2.sectorbase.com with Internet Mail Service (5.5.2653.19) - id ; Fri, 19 Jan 2001 09:46:14 -0800 -Message-ID: <8F4C99C66D04D4118F580090272A7A234D329F@sectorbase1.sectorbase.com> -From: "Mikheev, Vadim" -To: "'Tom Lane'" , Bruce Momjian -Cc: pgsql-hackers@postgresql.org -Subject: RE: [HACKERS] Possible performance improvement: buffer replacemen - t policy -Date: Fri, 19 Jan 2001 10:07:27 -0800 -MIME-Version: 1.0 -X-Mailer: Internet Mail Service (5.5.2653.19) -Content-Type: text/plain; - charset="iso-8859-1" -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: RO - -> > Tom, did we ever test this? I think we did and found that -> > it was the same or worse, right? -> -> I tried it and didn't see any noticeable improvement on the particular -> test case I was using, so I got discouraged and didn't pursue the idea -> further. I'd like to come back to it someday, though. - -I don't know how much useful could be LRU-2 but with WAL we should try -to reuse undirty free buffers first, not dirty ones, just to postpone -writes as long as we can. (BTW, this is what Oracle does.) -So, we probably should put new unfree dirty buffer just before first -dirty one in LRU. - -Vadim - -From markw@mohawksoft.com Thu Jun 7 14:40:02 2001 -Return-path: -Received: from gromit.dotclick.com (ipn9-f8366.net-resource.net [216.204.83.66]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f57Ie1c14004 - for ; Thu, 7 Jun 2001 14:40:02 -0400 (EDT) -Received: from mohawksoft.com (IDENT:markw@localhost.localdomain [127.0.0.1]) - by gromit.dotclick.com (8.9.3/8.9.3) with ESMTP id OAA04973; - Thu, 7 Jun 2001 14:37:00 -0400 -Sender: markw@gromit.dotclick.com -Message-ID: <3B1FC9CB.57C72AD6@mohawksoft.com> -Date: Thu, 07 Jun 2001 14:36:59 -0400 -From: mlw -X-Mailer: Mozilla 4.75 [en] (X11; U; Linux 2.4.2 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Bruce Momjian , - "pgsql-hackers@postgresql.org" -Subject: Re: 7.2 items -References: <200106071503.f57F32n03924@candle.pha.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Status: RO - -Bruce Momjian wrote: - -> > Bruce Momjian writes: -> > -> > > Here is a small list of big TODO items. I was wondering which ones -> > > people were thinking about for 7.2? -> > -> > A friend of mine wants to use PostgreSQL instead of Oracle for a large -> > application, but has run into a snag when speed comparisons looked -> > good until the Oracle folks added a couple of BITMAP indexes. I can't -> > recall seeing any discussion about that here -- are there any plans? -> -> It is not on our list and I am not sure what they do. - -Do you have access to any Oracle Documentation? There is a good explanation -of them. - -However, I will try to explain. - -If you have a table, locations. It has 1,000,000 records. - -In oracle you do this: - -create bitmap index bitmap_foo on locations (state) ; - -For each unique value of 'state' oracle will create a bitmap with 1,000,000 -bits in it. With a one representing a match and a zero representing no -match. Record '0' in the table is represented by bit '0' in the bitmap, -record '1' is represented by bit '1', record two by bit '2' and so on. - -In a table where comparatively few different values are to be indexed in a -large table, a bitmap index can be quite small and not suffer the N * log(N) -disk I/O most tree based indexes suffer. If the bitmap is fairly sparse or -dense (or have periods of denseness and sparseness), it can be compressed -very efficiently as well. - -When the statement: - -select * from locations where state = 'MA'; - -Is executed, the bitmap is read into memory in very few disk operations. -(Perhaps even as few as one or two). It is a simple operation of rifling -through the bitmap for '1's that indicate the record has the property, -'state' = 'MA'; - - -From mascarm@mascari.com Thu Jun 7 15:36:25 2001 -Return-path: -Received: from corvette.mascari.com (dhcp065-024-161-045.columbus.rr.com [65.24.161.45]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f57JaOc21943 - for ; Thu, 7 Jun 2001 15:36:24 -0400 (EDT) -Received: from ferrari (ferrari.mascari.com [192.168.2.1]) - by corvette.mascari.com (8.9.3/8.9.3) with SMTP id PAA25607; - Thu, 7 Jun 2001 15:29:31 -0400 -Received: by localhost with Microsoft MAPI; Thu, 7 Jun 2001 15:34:18 -0400 -Message-ID: <01C0EF67.5105D2E0.mascarm@mascari.com> -From: Mike Mascari -Reply-To: "mascarm@mascari.com" -To: "'mlw'" , Bruce Momjian , - "pgsql-hackers@postgresql.org" -Subject: RE: [HACKERS] Re: 7.2 items -Date: Thu, 7 Jun 2001 15:34:17 -0400 -Organization: Mascari Development Inc. -X-Mailer: Microsoft Internet E-mail/MAPI - 8.0.0.4211 -MIME-Version: 1.0 -Content-Type: text/plain; charset="us-ascii" -Content-Transfer-Encoding: 7bit -Status: RO - -And in addition, - -If you submitted the query: - -SELECT * FROM addresses WHERE state = 'OH' -AND areacode = '614' - -Then, with bitmap indexes, the bitmaps are just logically ANDed -together, and the final bitmap determines the matching rows. - -Mike Mascari -mascarm@mascari.com - ------Original Message----- -From: mlw [SMTP:markw@mohawksoft.com] - -Bruce Momjian wrote: - -> > Bruce Momjian writes: -> > -> > > Here is a small list of big TODO items. I was wondering which -ones -> > > people were thinking about for 7.2? -> > -> > A friend of mine wants to use PostgreSQL instead of Oracle for a -large -> > application, but has run into a snag when speed comparisons -looked -> > good until the Oracle folks added a couple of BITMAP indexes. I -can't -> > recall seeing any discussion about that here -- are there any -plans? -> -> It is not on our list and I am not sure what they do. - -Do you have access to any Oracle Documentation? There is a good -explanation -of them. - -However, I will try to explain. - -If you have a table, locations. It has 1,000,000 records. - -In oracle you do this: - -create bitmap index bitmap_foo on locations (state) ; - -For each unique value of 'state' oracle will create a bitmap with -1,000,000 -bits in it. With a one representing a match and a zero representing -no -match. Record '0' in the table is represented by bit '0' in the -bitmap, -record '1' is represented by bit '1', record two by bit '2' and so -on. - -In a table where comparatively few different values are to be indexed -in a -large table, a bitmap index can be quite small and not suffer the N * -log(N) -disk I/O most tree based indexes suffer. If the bitmap is fairly -sparse or -dense (or have periods of denseness and sparseness), it can be -compressed -very efficiently as well. - -When the statement: - -select * from locations where state = 'MA'; - -Is executed, the bitmap is read into memory in very few disk -operations. -(Perhaps even as few as one or two). It is a simple operation of -rifling -through the bitmap for '1's that indicate the record has the -property, -'state' = 'MA'; - - - -From oleg@sai.msu.su Thu Jun 7 15:39:15 2001 -Return-path: -Received: from ra.sai.msu.su (ra.sai.msu.su [158.250.29.2]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f57Jd7c22010 - for ; Thu, 7 Jun 2001 15:39:08 -0400 (EDT) -Received: from ra (ra [158.250.29.2]) - by ra.sai.msu.su (8.9.3/8.9.3) with ESMTP id WAA07783; - Thu, 7 Jun 2001 22:38:20 +0300 (GMT) -Date: Thu, 7 Jun 2001 22:38:20 +0300 (GMT) -From: Oleg Bartunov -X-X-Sender: -To: mlw -cc: Bruce Momjian , - "pgsql-hackers@postgresql.org" -Subject: Re: [HACKERS] Re: 7.2 items -In-Reply-To: <3B1FC9CB.57C72AD6@mohawksoft.com> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Status: RO - -I think it's possible to implement bitmap indexes with a little -effort using GiST. at least I know one implementation -http://www.it.iitb.ernet.in/~rvijay/dbms/proj/ -if you have interests you could implement bitmap indexes yourself -unfortunately, we're very busy - - Oleg -On Thu, 7 Jun 2001, mlw wrote: - -> Bruce Momjian wrote: -> -> > > Bruce Momjian writes: -> > > -> > > > Here is a small list of big TODO items. I was wondering which ones -> > > > people were thinking about for 7.2? -> > > -> > > A friend of mine wants to use PostgreSQL instead of Oracle for a large -> > > application, but has run into a snag when speed comparisons looked -> > > good until the Oracle folks added a couple of BITMAP indexes. I can't -> > > recall seeing any discussion about that here -- are there any plans? -> > -> > It is not on our list and I am not sure what they do. -> -> Do you have access to any Oracle Documentation? There is a good explanation -> of them. -> -> However, I will try to explain. -> -> If you have a table, locations. It has 1,000,000 records. -> -> In oracle you do this: -> -> create bitmap index bitmap_foo on locations (state) ; -> -> For each unique value of 'state' oracle will create a bitmap with 1,000,000 -> bits in it. With a one representing a match and a zero representing no -> match. Record '0' in the table is represented by bit '0' in the bitmap, -> record '1' is represented by bit '1', record two by bit '2' and so on. -> -> In a table where comparatively few different values are to be indexed in a -> large table, a bitmap index can be quite small and not suffer the N * log(N) -> disk I/O most tree based indexes suffer. If the bitmap is fairly sparse or -> dense (or have periods of denseness and sparseness), it can be compressed -> very efficiently as well. -> -> When the statement: -> -> select * from locations where state = 'MA'; -> -> Is executed, the bitmap is read into memory in very few disk operations. -> (Perhaps even as few as one or two). It is a simple operation of rifling -> through the bitmap for '1's that indicate the record has the property, -> 'state' = 'MA'; -> -> -> ---------------------------(end of broadcast)--------------------------- -> TIP 6: Have you searched our list archives? -> -> http://www.postgresql.org/search.mpl -> - - Regards, - Oleg -_____________________________________________________________ -Oleg Bartunov, sci.researcher, hostmaster of AstroNet, -Sternberg Astronomical Institute, Moscow University (Russia) -Internet: oleg@sai.msu.su, http://www.sai.msu.su/~megera/ -phone: +007(095)939-16-83, +007(095)939-23-83 - - -From pgsql-general-owner+M2497@hub.org Fri Jun 16 18:31:03 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id RAA04165 - for ; Fri, 16 Jun 2000 17:31:01 -0400 (EDT) -Received: from hub.org (root@hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.12 $) with ESMTP id RAA13110 for ; Fri, 16 Jun 2000 17:20:12 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5GLDaM14477; - Fri, 16 Jun 2000 17:13:36 -0400 (EDT) -Received: from home.dialix.com ([203.15.150.26]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5GLCQM14064 - for ; Fri, 16 Jun 2000 17:12:27 -0400 (EDT) -Received: from nemeton.com.au ([202.76.153.71]) - by home.dialix.com (8.9.3/8.9.3/JustNet) with SMTP id HAA95516 - for ; Sat, 17 Jun 2000 07:11:44 +1000 (EST) - (envelope-from giles@nemeton.com.au) -Received: (qmail 10213 invoked from network); 16 Jun 2000 09:52:29 -0000 -Received: from nemeton.com.au (203.8.3.17) - by nemeton.com.au with SMTP; 16 Jun 2000 09:52:29 -0000 -To: Jurgen Defurne -cc: Mark Stier , - postgreSQL general mailing list -Subject: Re: [GENERAL] optimization by removing the file system layer? -In-Reply-To: Message from Jurgen Defurne - of "Thu, 15 Jun 2000 20:26:57 +0200." <39491FF1.E1E583F8@glo.be> -Date: Fri, 16 Jun 2000 19:52:28 +1000 -Message-ID: <10210.961149148@nemeton.com.au> -From: Giles Lean -X-Mailing-List: pgsql-general@postgresql.org -Precedence: bulk -Sender: pgsql-general-owner@hub.org -Status: OR - - - -> I think that the Un*x filesystem is one of the reasons that large -> database vendors rather use raw devices, than filesystem storage -> files. - -This used to be the preference, back in the late 80s and possibly -early 90s. I'm seeing a preference toward using the filesystem now, -possibly with some sort of async I/O and co-operation from the OS -filesystem about interactions with the filesystem cache. - -Performance preferences don't stand still. The hardware changes, the -software changes, the volume of data changes, and different solutions -become preferable. - -> Using a raw device on the disk gives them the possibility to have -> complete control over their files, indices and objects without being -> bothered by the operating system. -> -> This speeds up things in several ways : -> - the least possible OS intervention - -Not that this is especially useful, necessarily. If the "raw" device -is in fact managed by a logical volume manager doing mirroring onto -some sort of storage array there is still plenty of OS code involved. - -The cost of using a filesystem in addition may not be much if anything -and of course a filesystem is considerably more flexible to -administer (backup, move, change size, check integrity, etc.) - -> - choose block sizes according to applications -> - reducing fragmentation -> - packing data in nearby cilinders - -... but when this storage area is spread over multiple mechanisms in a -smart storage array with write caching, you've no idea what is where -anyway. Better to let the hardware or at least the OS manage this; -there are so many levels of caching between a database and the -magnetic media that working hard to influence layout is almost -certainly a waste of time. - -Kirk McKusick tells a lovely story that once upon a time it used to be -sensible to check some registers on a particular disk controller to -find out where the heads were when scheduling I/O. Needless to say, -that is history now! - -There's a considerable cost in complexity and code in using "raw" -storage too, and it's not a one off cost: as the technologies change, -the "fast" way to do things will change and the code will have to be -updated to match. Better to leave this to the OS vendor where -possible, and take advantage of the tuning they do. - -> - Anyone other ideas -> the sky is the limit here - -> It also aids portability, at least on platforms that have an -> equivalent of a raw device. - -I don't understand that claim. Not much is portable about raw -devices, and they're typically not nearlly as well documented as the -filesystem interfaces. - -> It is also independent of the standard implemented Un*x filesystems, -> for which you will have to pay extra if you want to take extra -> measures against power loss. - -Rather, it is worse. With a Unix filesystem you get quite defined -semantics about what is written when. - -> The problem with e.g. e2fs, is that it is not robust enough if a CPU -> fails. - -ext2fs doesn't even claim to have Unix filesystem semantics. - -Regards, - -Giles - - - -From pgsql-hackers-owner+M1795@postgresql.org Thu Dec 7 18:47:52 2000 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id SAA09172 - for ; Thu, 7 Dec 2000 18:47:52 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id eB7NjFP10612; - Thu, 7 Dec 2000 18:45:15 -0500 (EST) - (envelope-from pgsql-hackers-owner+M1795@postgresql.org) -Received: from thor.tht.net (thor.tht.net [209.47.145.4]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id eB7N6BP08233 - for ; Thu, 7 Dec 2000 18:06:11 -0500 (EST) - (envelope-from bright@fw.wintelcom.net) -Received: from fw.wintelcom.net (bright@ns1.wintelcom.net [209.1.153.20]) - by thor.tht.net (8.9.3/8.9.3) with ESMTP id SAA97456 - for ; Thu, 7 Dec 2000 18:57:32 GMT - (envelope-from bright@fw.wintelcom.net) -Received: (from bright@localhost) - by fw.wintelcom.net (8.10.0/8.10.0) id eB7MvWE21269 - for pgsql-hackers@postgresql.org; Thu, 7 Dec 2000 14:57:32 -0800 (PST) -Date: Thu, 7 Dec 2000 14:57:32 -0800 -From: Alfred Perlstein -To: pgsql-hackers@postgresql.org -Subject: [HACKERS] Patches with vacuum fixes available for 7.0.x -Message-ID: <20001207145732.X16205@fw.wintelcom.net> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.2.5i -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: ORr - -We recently had a very satisfactory contract completed by -Vadim. - -Basically Vadim has been able to reduce the amount of time -taken by a vacuum from 10-15 minutes down to under 10 seconds. - -We've been running with these patches under heavy load for -about a week now without any problems except one: - don't 'lazy' (new option for vacuum) a table which has just - had an index created on it, or at least don't expect it to - take any less time than a normal vacuum would. - -There's three patchsets and they are available at: - -http://people.freebsd.org/~alfred/vacfix/ - -complete diff: -http://people.freebsd.org/~alfred/vacfix/v.diff - -only lazy vacuum option to speed up index vacuums: -http://people.freebsd.org/~alfred/vacfix/vlazy.tgz - -only lazy vacuum option to only scan from start of modified -data: -http://people.freebsd.org/~alfred/vacfix/mnmb.tgz - -Although the patches are for 7.0.x I'm hoping that they -can be forward ported (if Vadim hasn't done it already) -to 7.1. - -enjoy! - --- --Alfred Perlstein - [bright@wintelcom.net|alfred@freebsd.org] -"I have the heart of a child; I keep it in a jar on my desk." - -From pgsql-hackers-owner+M1809@postgresql.org Thu Dec 7 20:27:39 2000 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id UAA11827 - for ; Thu, 7 Dec 2000 20:27:38 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id eB81PsP22362; - Thu, 7 Dec 2000 20:25:54 -0500 (EST) - (envelope-from pgsql-hackers-owner+M1809@postgresql.org) -Received: from fw.wintelcom.net (ns1.wintelcom.net [209.1.153.20]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id eB81JkP21783 - for ; Thu, 7 Dec 2000 20:19:46 -0500 (EST) - (envelope-from bright@fw.wintelcom.net) -Received: (from bright@localhost) - by fw.wintelcom.net (8.10.0/8.10.0) id eB81JwU25447; - Thu, 7 Dec 2000 17:19:58 -0800 (PST) -Date: Thu, 7 Dec 2000 17:19:58 -0800 -From: Alfred Perlstein -To: Tom Lane -cc: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Patches with vacuum fixes available for 7.0.x -Message-ID: <20001207171958.B16205@fw.wintelcom.net> -References: <20001207145732.X16205@fw.wintelcom.net> <28791.976236143@sss.pgh.pa.us> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.2.5i -In-Reply-To: <28791.976236143@sss.pgh.pa.us>; from tgl@sss.pgh.pa.us on Thu, Dec 07, 2000 at 07:42:23PM -0500 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -* Tom Lane [001207 17:10] wrote: -> Alfred Perlstein writes: -> > Basically Vadim has been able to reduce the amount of time -> > taken by a vacuum from 10-15 minutes down to under 10 seconds. -> -> Cool. What's it do, exactly? - -================================================================ - -The first is a bonus that Vadim gave us to speed up index -vacuums, I'm not sure I understand it completely, but it -work really well. :) - -here's the README he gave us: - - Vacuum LAZY index cleanup option - -LAZY vacuum option introduces new way of indices cleanup. -Instead of reading entire index file to remove index tuples -pointing to deleted table records, with LAZY option vacuum -performes index scans using keys fetched from table record -to be deleted. Vacuum checks each result returned by index -scan if it points to target heap record and removes -corresponding index tuple. -This can greatly speed up indices cleaning if not so many -table records were deleted/modified between vacuum runs. -Vacuum uses new option on user' demand. - -New vacuum syntax is: - -vacuum [verbose] [analyze] [lazy] [table [(columns)]] - -================================================================ - -The second is one of the suggestions I gave on the lists a while -back, keeping track of the "last dirtied" block in the data files -to only scan the tail end of the file for deleted rows, I think -what he instead did was keep a table that holds all the modified -blocks and vacuum only scans those: - - Minimal Number Modified Block (MNMB) - -This feature is to track MNMB of required tables with triggers -to avoid reading unmodified table pages by vacuum. Triggers -store MNMB in per-table files in specified directory -($LIBDIR/contrib/mnmb by default) and create these files if not -existed. - -Vacuum first looks up functions - -mnmb_getblock(Oid databaseId, Oid tableId) -mnmb_setblock(Oid databaseId, Oid tableId, Oid block) - -in catalog. If *both* functions were found *and* there was no -ANALYZE option specified then vacuum calls mnmb_getblock to obtain -MNMB for table being vacuumed and starts reading this table from -block number returned. After table was processed vacuum calls -mnmb_setblock to update data in file to last table block number. -Neither mnmb_getblock nor mnmb_setblock try to create file. -If there was no file for table being vacuumed then mnmb_getblock -returns 0 and mnmb_setblock does nothing. -mnmb_setblock() may be used to set in file MNMB to 0 and force -vacuum to read entire table if required. - -To compile MNMB you have to add -DMNMB to CUSTOM_COPT -in src/Makefile.custom. - --- --Alfred Perlstein - [bright@wintelcom.net|alfred@freebsd.org] -"I have the heart of a child; I keep it in a jar on my desk." - -From pgsql-general-owner+M4010@postgresql.org Mon Feb 5 18:50:47 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id SAA02209 - for ; Mon, 5 Feb 2001 18:50:46 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f15Nn8x86486; - Mon, 5 Feb 2001 18:49:08 -0500 (EST) - (envelope-from pgsql-general-owner+M4010@postgresql.org) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f15N7Ux81124 - for ; Mon, 5 Feb 2001 18:07:30 -0500 (EST) - (envelope-from pgsql-general-owner@postgresql.org) -Received: from news.tht.net (news.hub.org [216.126.91.242]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id f0V0Twq69854 - for ; Tue, 30 Jan 2001 19:29:58 -0500 (EST) - (envelope-from news@news.tht.net) -Received: (from news@localhost) - by news.tht.net (8.11.1/8.11.1) id f0V0RAO01011 - for pgsql-general@postgresql.org; Tue, 30 Jan 2001 19:27:10 -0500 (EST) - (envelope-from news) -From: Mike Hoskins -X-Newsgroups: comp.databases.postgresql.general -Subject: Re: [GENERAL] MySQL file system -Date: Tue, 30 Jan 2001 18:30:36 -0600 -Organization: Hub.Org Networking Services (http://www.hub.org) -Lines: 120 -Message-ID: <3A775CAB.C416AA16@yahoo.com> -References: <016e01c080b7$ea554080$330a0a0a@6014cwpza006> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -X-Complaints-To: scrappy@hub.org -X-Mailer: Mozilla 4.76 [en] (Windows NT 5.0; U) -X-Accept-Language: en -To: pgsql-general@postgresql.org -Precedence: bulk -Sender: pgsql-general-owner@postgresql.org -Status: OR - -This idea is such a popular (even old) one that Oracle developed it for 8i -- -IFS. Yep, AS/400 has had it forever, and BeOS is another example. Informix has -had its DataBlades for years, as well. In fact, Reiser-FS is an FS implemented -on a DB, albeit probably not a SQL DB. AIX's LVM and JFS is extent/DB-based, as -well. Let's see now, why would all those guys do that? (Now, some of those that -aren't SQL-based probably won't allow SQL queries on files, so just think about -those that do, for a minute).... - -Rather than asking why, a far better question is why not? There is SO much -functionality to be gained here that it's silly to ask why. At a higher level, -treating BLOBs as files and as DB entries simultaneously has so many uses, that -one has trouble answering the question properly without the puzzled stare back -at the questioner. Again, look at the above list, particularly at AS/400 -- the -entire OS's FS sits on top of DB/2! - -For example, think how easy dynamically generated web sites could access online -catalog information, with all those JPEG's, GIFs, PNGs, HTML files, Text files, -.PDF's, etc., both in the DB and in the FS. This would be so much easier to -maintain, when you have webmasters, web designers, artists, programmers, -sysadmins, dba's, etc., all trying to manage a big, dynamic, graphics-rich web -site. Who cares if the FS is a bit slow, as long as it's not too slow? That's -not the point, anyway. - -The point is easy access to data: asset management, version control, the -ability to access the same data as a file and as a BLOB simultaneously, the -ability to replicate easier, the ability to use more tools on the same info, -etc. It's not for speed, per se; instead, it's for accessibility. - -Think about this issue. You have some already compiled text-based program that -works on binary files, but not on databases -- it was simply never designed into -the program. How are you going to get your graphics BLOBs into that program? -Oh yeah, let's write another program to transform our data into files, first, -then after processing delete them in some cleanup routine.... Why? If you have -a DB'ed FS, then file data can simultaneously have two views -- one for the DB -and one as an FS. (You can easily reverse the scenario.) Not only does this -save time and disk space; it saves you from having to pay for the most expensive -element of all -- programmer time. - -BTW, once this FS-on-a-DB concept really sinks in, imagine how tightly -integrated Linux/Unix apps could be written. Imagine if a bunch of GPL'ed -software started coding for this and used this as a means to exchange data, all -using a common set of libraries. You could get to the point of uniting files, -BLOBs, data of all sorts, IPC, version control, etc., all under one umbrella, -especially if XML was the means data was exchanged. Heck, distributed -authentication, file access, data access, etc., could be improved greatly. -Well, this paragraph sounds like flame bait, but really consider the -ramifications. Also, read the next paragraph.... - -Something like this *has* existed for Postgres for a long time -- PGFS, by Brian -Bartholomew. It's even supposedly matured with age. Unfortunately, I cannot -get to http://www.wv.com/ (Working Version's main site). Working Version is a -version control system that keeps old versions of files around in the FS. It -uses PG as the back-end DB and lets you mount it like another FS. It's -supposedly an awesome system, but where is it? It's not some clunky korbit -thingy, either. (If someone can find it, please let me know by email, if -possible.) - -The only thing I can find on this is from a Google search, which caches -everything but the actual software: - -http://www.google.com/search?q=pgfs+postgres&num=100&hl=en&lr=lang_en&newwindow=1&safe=active - -Also, there is the Perl-FS that can be transformed into something like PGFS: -http://www.assurdo.com/perlfs/ It allows you to write Perl code that can mount -various protocols or data types as an FS, in user space. (One example is the -ability to mount FTP sites, BTW.) - -Instead of ridiculing something you've never tried, consider that MySQL-FS, -Oracle (IFS), Informix (DataBlades), AS/400 (DB/2), BeOS, and Reiser-FS are -doing this today. Do you want to be left behind and let them tell us what it's -good for? Or, do we want this for PG? (Reiser-FS, BTW, is FASTER than ext2, -but has no SQL hooks). - -There were many posts on this on slashdot: - http://slashdot.org/article.pl?sid=01/01/16/1855253&mode=thread - (I wrote some comments here, as well, just look for mikehoskins) - -I, for one, want to see this succeed for MySQL, PostgreSQL, msql, etc. It's an -awesome feature that doesn't need to be speedy because it can save HUMANS time. - -The question really is, "When do we want to catch up to everyone else?" We are -always moving to higher levels of abstraction, anyway, so it's just a matter of -time. PG should participate. - - -Adam Lang wrote: - -> I wasn't following the thread too closely, but database for a filesystem has -> been done. BeOS uses a database for a filesystem as well as AS/400 and -> Mainframes. -> -> Adam Lang -> Systems Engineer -> Rutgers Casualty Insurance Company -> http://www.rutgersinsurance.com -> ----- Original Message ----- -> From: "Alfred Perlstein" -> To: "Robert D. Nelson" -> Cc: "Joseph Shraibman" ; "Karl DeBisschop" -> ; "Ned Lilly" ; "PostgreSQL -> General" -> Sent: Wednesday, January 17, 2001 12:23 PM -> Subject: Re: [GENERAL] MySQL file system -> -> > * Robert D. Nelson [010117 05:17] wrote: -> > > >Raw disk access allows: -> > > -> > > If I'm correct, mysql is providing a filesystem, not a way to access raw -> > > disk, like Oracle does. Huge difference there - with a filesystem, you -> have -> > > overhead of FS *and* SQL at the same time. -> > -> > Oh, so it's sort of like /proc for mysql? -> > -> > What a terrible waste of time and resources. :( -> > -> > -- -> > -Alfred Perlstein - [bright@wintelcom.net|alfred@freebsd.org] -> > "I have the heart of a child; I keep it in a jar on my desk." - - -From pgsql-general-owner+M4049@postgresql.org Tue Feb 6 01:26:19 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id BAA21425 - for ; Tue, 6 Feb 2001 01:26:18 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f166Nxx26400; - Tue, 6 Feb 2001 01:23:59 -0500 (EST) - (envelope-from pgsql-general-owner+M4049@postgresql.org) -Received: from simecity.com ([202.188.254.2]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id f166GUx25754 - for ; Tue, 6 Feb 2001 01:16:30 -0500 (EST) - (envelope-from lyeoh@pop.jaring.my) -Received: (from mail@localhost) - by simecity.com (8.9.3/8.8.7) id OAA23910; - Tue, 6 Feb 2001 14:28:48 +0800 -Received: from (ilab2.mecomb.po.my [192.168.3.22]) by cirrus.simecity.com via smap (V2.1) - id xma023908; Tue, 6 Feb 01 14:28:34 +0800 -Message-ID: <3.0.5.32.20010206141555.00a3d100@192.228.128.13> -X-Sender: lyeoh@192.228.128.13 -X-Mailer: QUALCOMM Windows Eudora Light Version 3.0.5 (32) -Date: Tue, 06 Feb 2001 14:15:55 +0800 -To: Mike Hoskins , pgsql-general@postgresql.org -From: Lincoln Yeoh -Subject: [GENERAL] Re: MySQL file system -In-Reply-To: <3A775CF7.3C5F1909@yahoo.com> -References: <016e01c080b7$ea554080$330a0a0a@6014cwpza006> -MIME-Version: 1.0 -Content-Type: text/plain; charset="us-ascii" -Precedence: bulk -Sender: pgsql-general-owner@postgresql.org -Status: OR - -What you're saying seems to be to have a data structure where the same data -can be accessed in both the filesystem style and the RDBMs style. How does -that work? How is the mapping done between both structures? Slapping a -filesystem on top of a RDBMs doesn't do that does it? - -Most filesystems are basically databases already, just differently -structured and featured databases. And so far most of them do their job -pretty well. You move a folder/directory somewhere, and everything inside -it moves. Tons of data are already arranged in that form. Though porting -over data from one filesystem to another is not always straightforward, -RDBMSes are far worse. - -Maybe what would be nice is not a filesystem based on a database, rather -one influenced by databases. One with a decent fulltextindex for data and -filenames, where you have the option to ignore or not ignore -nonalphanumerics and still get an indexed search. - -Then perhaps we could do something like the following: - -select file.name from path "/var/logs/" where file.name like "%.log%' and -file.lastmodified > '2000/1/1' and file.contents =~ 'te_st[0-9]+\.gif$' use -index - -Checkpoints would be nice too. Then I can rollback to a known point if I -screw up ;). - -In fact the SQL style interface doesn't have to be built in at all. Neither -does the index have to be realtime. I suppose there could be an option to -make it realtime if performance is not an issue. - -What could be done is to use some fast filesystem. Then we add tools to -maintain indexes, for SQL style interfaces and other style interfaces. -Checkpoints and rollbacks would be harder of course. - -Cheerio, -Link. - - -From pgsql-hackers-owner+M20329@postgresql.org Tue Mar 19 18:00:15 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g2K00EA02465 - for ; Tue, 19 Mar 2002 19:00:14 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 8C7164763EF; Tue, 19 Mar 2002 18:22:08 -0500 (EST) -Received: from CopelandConsulting.Net (dsl-24293-ld.customer.centurytel.net [209.142.135.135]) - by postgresql.org (Postfix) with ESMTP id E4DAD475F1F - for ; Tue, 19 Mar 2002 18:02:17 -0500 (EST) -Received: from mouse.copelandconsulting.net (mouse.copelandconsulting.net [192.168.1.2]) - by CopelandConsulting.Net (8.10.1/8.10.1) with ESMTP id g2JN0jh13185; - Tue, 19 Mar 2002 17:00:45 -0600 (CST) -X-Trade-Id: -To: Matthew Kirkwood -cc: Oleg Bartunov , - PostgresSQL Hackers Mailing List - - -Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; - boundary="=-Ivchb84S75fOMzJ9DxwK" -X-Mailer: Evolution/1.0.2 -Date: 19 Mar 2002 17:00:53 -0600 -Message-ID: <1016578854.14670.450.camel@mouse.copelandconsulting.net> -MIME-Version: 1.0 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - ---=-Ivchb84S75fOMzJ9DxwK -Content-Type: text/plain -Content-Transfer-Encoding: quoted-printable - -On Tue, 2002-03-19 at 15:30, Matthew Kirkwood wrote: -> On Tue, 19 Mar 2002, Oleg Bartunov wrote: ->=20 -> Sorry to reply over you, Oleg. ->=20 -> > On 13 Mar 2002, Greg Copeland wrote: -> > -> > > One of the reasons why I originally stated following the hackers list= - is -> > > because I wanted to implement bitmap indexes. I found in the archive= -s, -> > > the follow link, http://www.it.iitb.ernet.in/~rvijay/dbms/proj/, which -> > > was extracted from this, -> > > http://groups.google.com/groups?hl=3Den&threadm=3D01C0EF67.5105D2E0.m= -ascarm%40mascari.com&rnum=3D1&prev=3D/groups%3Fq%3Dbitmap%2Bindex%2Bgroup:c= -omp.databases.postgresql.hackers%26hl%3Den%26selm%3D01C0EF67.5105D2E0.masca= -rm%2540mascari.com%26rnum%3D1, archive thread. ->=20 -> For every case I have used a bitmap index on Oracle, a -> partial index[0] made more sense (especialy since it -> could usefully be compound). - -That's very true, however, often bitmap indexes are used where partial -indexes may not work well. It maybe you were trying to apply the cure -for the wrong disease. ;) - ->=20 -> Our troublesome case (on Oracle) is a table of "events" -> where maybe fifty to a couple of hundred are "published" -> (ie. web-visible) at any time. The events are categorised -> by sport (about a dozen) and by "event type" (about five). -> We never really query events except by PK or by sport/type/ -> published. - -The reason why bitmap indexes are primarily used for DSS and data -wherehousing applications is because they are best used on extremely -large to very large tables which have low cardinality (e.g, 10,000,000 -rows having 200 distinct values). On top of that, bitmap indexes also -tend to be much smaller than their "standard" cousins. On large and -very tables tables, this can sometimes save gigs in index space alone -(serious space benefit). Plus, their small index size tends to result -in much less I/O (serious speed benefit). This, of course, can result -in several orders of magnitude speed improvements when index scans are -required. As an added bonus, using AND, OR, XOR and NOT predicates are -exceptionally fast and if implemented properly, can even take advantage -of some 64-bit hardware for further speed improvements. This, of -course, further speeds look ups. The primary down side is that inserts -and updates to bitmap indexes are very costly (comparatively) which is, -yet again, why they excel in read-only environments (DSS & data -wherehousing). - -It should also be noted that RDMS's, such as Oracle, often use multiple -types of bitmap indexes. This further impedes insert/update -performance, however, the additional bitmap index types usually allow -for range predicates while still making use of the bitmap index. If I'm -not mistaken, several other types of bitmaps are available as well as -many ways to encode and compress (rle, quad compression, etc) bitmap -indexes which further save on an already compact indexing scheme. - -Given the proper problem domain, index bitmaps can be a big win. - ->=20 -> We make a bitmap index on "published", and trust Oracle to -> use it correctly, and hope that our other indexes are also -> useful. ->=20 -> On Postgres[1] we would make a partial compound index: ->=20 -> create index ... on events(sport_id,event_type_id) -> where published=3D'Y'; - - -Generally speaking, bitmap indexes will not serve you very will on -tables having a low row counts, high cardinality or where they are -attached to tables which are primarily used in an OLTP capacity.=20 -Situations where you have a low row count and low cardinality or high -row count and high cardinality tend to be better addressed by partial -indexes; which seem to make much more sense. In your example, it sounds -like you did "the right thing"(tm). ;) - - -Greg - - ---=-Ivchb84S75fOMzJ9DxwK -Content-Type: application/pgp-signature; name=signature.asc -Content-Description: This is a digitally signed message part - ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.0.6 (GNU/Linux) -Comment: For info see http://www.gnupg.org - -iD8DBQA8l8Ml4lr1bpbcL6kRAhldAJ9Aoi9dwm1OteZjySfsd1o42trWLACfegQj -OEV6eO8MnBSlbJMHiQ08gNE= -=PQvW ------END PGP SIGNATURE----- - ---=-Ivchb84S75fOMzJ9DxwK-- - - diff --git a/doc/TODO.detail/persistent b/doc/TODO.detail/persistent deleted file mode 100644 index f4edaad5ac..0000000000 --- a/doc/TODO.detail/persistent +++ /dev/null @@ -1,102 +0,0 @@ -From owner-pgsql-hackers@hub.org Mon May 11 11:31:09 1998 -Received: from renoir.op.net (root@renoir.op.net [209.152.193.4]) - by candle.pha.pa.us (8.8.5/8.8.5) with ESMTP id LAA03006 - for ; Mon, 11 May 1998 11:31:07 -0400 (EDT) -Received: from hub.org (hub.org [209.47.148.200]) by renoir.op.net (o1/$ Revision: 1.17 $) with ESMTP id LAA01663 for ; Mon, 11 May 1998 11:24:42 -0400 (EDT) -Received: from localhost (majordom@localhost) by hub.org (8.8.8/8.7.5) with SMTP id LAA21841; Mon, 11 May 1998 11:15:25 -0400 (EDT) -Received: by hub.org (TLB v0.10a (1.23 tibbs 1997/01/09 00:29:32)); Mon, 11 May 1998 11:15:12 +0000 (EDT) -Received: (from majordom@localhost) by hub.org (8.8.8/8.7.5) id LAA21683 for pgsql-hackers-outgoing; Mon, 11 May 1998 11:15:09 -0400 (EDT) -Received: from sss.sss.pgh.pa.us (sss.pgh.pa.us [206.210.65.6]) by hub.org (8.8.8/8.7.5) with ESMTP id LAA21451 for ; Mon, 11 May 1998 11:15:03 -0400 (EDT) -Received: from sss.sss.pgh.pa.us (localhost [127.0.0.1]) - by sss.sss.pgh.pa.us (8.8.5/8.8.5) with ESMTP id LAA24915; - Mon, 11 May 1998 11:14:43 -0400 (EDT) -To: Brett McCormick -cc: hackers@postgreSQL.org -Subject: Re: [HACKERS] Re: [PATCHES] Try again: S_LOCK reduced contentionh] -In-reply-to: Your message of Mon, 11 May 1998 07:57:23 -0700 (PDT) - <13655.4384.345723.466046@abraxas.scene.com> -Date: Mon, 11 May 1998 11:14:43 -0400 -Message-ID: <24913.894899683@sss.pgh.pa.us> -From: Tom Lane -Sender: owner-pgsql-hackers@hub.org -Precedence: bulk -Status: RO - -Brett McCormick writes: -> same way that the current network socket is passed -- through an execv -> argument. hopefully, however, the non-execv()ing fork will be in 6.4. - -Um, you missed the point, Brett. David was hoping to transfer a client -connection from the postmaster to an *already existing* backend process. -Fork, with or without exec, solves the problem for a backend that's -started after the postmaster has accepted the client socket. - -This does lead to a different line of thought, however. Pre-started -backends would have access to the "master" connection socket on which -the postmaster listens for client connections, right? Suppose that we -fire the postmaster as postmaster, and demote it to being simply a -manufacturer of new backend processes as old ones get used up. Have -one of the idle backend processes be the one doing the accept() on the -master socket. Once it has a client connection, it performs the -authentication handshake and then starts serving the client (or just -quits if authentication fails). Meanwhile the next idle backend process -has executed accept() on the master socket and is waiting for the next -client; and shortly the postmaster/factory/whateverwecallitnow notices -that it needs to start another backend to add to the idle-backend pool. - -This'd probably need some interlocking among the backends. I have no -idea whether it'd be safe to have all the idle backends trying to -do accept() on the master socket simultaneously, but it sounds risky. -Better to use a mutex so that only one gets to do it while the others -sleep. - - regards, tom lane - - -From owner-pgsql-hackers@hub.org Mon May 11 11:35:55 1998 -Received: from hub.org (hub.org [209.47.148.200]) - by candle.pha.pa.us (8.8.5/8.8.5) with ESMTP id LAA03043 - for ; Mon, 11 May 1998 11:35:53 -0400 (EDT) -Received: from localhost (majordom@localhost) by hub.org (8.8.8/8.7.5) with SMTP id LAA23494; Mon, 11 May 1998 11:27:10 -0400 (EDT) -Received: by hub.org (TLB v0.10a (1.23 tibbs 1997/01/09 00:29:32)); Mon, 11 May 1998 11:27:02 +0000 (EDT) -Received: (from majordom@localhost) by hub.org (8.8.8/8.7.5) id LAA23473 for pgsql-hackers-outgoing; Mon, 11 May 1998 11:27:01 -0400 (EDT) -Received: from sss.sss.pgh.pa.us (sss.pgh.pa.us [206.210.65.6]) by hub.org (8.8.8/8.7.5) with ESMTP id LAA23462 for ; Mon, 11 May 1998 11:26:56 -0400 (EDT) -Received: from sss.sss.pgh.pa.us (localhost [127.0.0.1]) - by sss.sss.pgh.pa.us (8.8.5/8.8.5) with ESMTP id LAA25006; - Mon, 11 May 1998 11:26:44 -0400 (EDT) -To: Brett McCormick -cc: hackers@postgreSQL.org -Subject: Re: [HACKERS] Re: [PATCHES] Try again: S_LOCK reduced contentionh] -In-reply-to: Your message of Mon, 11 May 1998 07:57:23 -0700 (PDT) - <13655.4384.345723.466046@abraxas.scene.com> -Date: Mon, 11 May 1998 11:26:44 -0400 -Message-ID: <25004.894900404@sss.pgh.pa.us> -From: Tom Lane -Sender: owner-pgsql-hackers@hub.org -Precedence: bulk -Status: RO - -Meanwhile, *I* missed the point about Brett's second comment :-( - -Brett McCormick writes: -> There will have to be some sort of arg parsing in any case, -> considering that you can pass configurable arguments to the backend.. - -If we do the sort of change David and I were just discussing, then the -pre-spawned backend would become responsible for parsing and dealing -with the PGOPTIONS portion of the client's connection request message. -That's just part of shifting the authentication handshake code from -postmaster to backend, so it shouldn't be too hard. - -BUT: the whole point is to be able to initialize the backend before it -is connected to a client. How much of the expensive backend startup -work depends on having the client connection options available? -Any work that needs to know the options will have to wait until after -the client connects. If that means most of the startup work can't -happen in advance anyway, then we're out of luck; a pre-started backend -won't save enough time to be worth the effort. (Unless we are willing -to eliminate or redefine the troublesome options...) - - regards, tom lane - - diff --git a/doc/TODO.detail/pool b/doc/TODO.detail/pool deleted file mode 100644 index 0a809e148f..0000000000 --- a/doc/TODO.detail/pool +++ /dev/null @@ -1,1321 +0,0 @@ -From pgsql-hackers-owner+M4897@hub.org Wed Jul 12 00:15:33 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id AAA06129 - for ; Wed, 12 Jul 2000 00:15:32 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e6C4FiW14410; - Wed, 12 Jul 2000 00:15:44 -0400 (EDT) -Received: from onyx-technologies.com (iron.onyx-technologies.com [216.205.44.194] (may be forged)) - by hub.org (8.10.1/8.10.1) with ESMTP id e6C4ECW07902 - for ; Wed, 12 Jul 2000 00:14:12 -0400 (EDT) -Received: from onyx-technologies.com (collins.onyx-technologies.com [192.168.188.10]) - by onyx-technologies.com (8.9.2/8.9.0) with ESMTP id AAA14868 - for ; Wed, 12 Jul 2000 00:11:43 -0400 (EDT) -Message-ID: <396BE1B6.F755C5CE@onyx-technologies.com> -Date: Tue, 11 Jul 2000 23:10:46 -0400 -From: Jeffery Collins -X-Mailer: Mozilla 4.7 [en] (X11; I; Linux 2.2.14-15mdk i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: pgsql-hackers@hub.org -Subject: Re: [HACKERS] Connection pooling. -References: <20000711185318.W25571@fw.wintelcom.net> <396BEA84.1A06F51F@nimrod.itg.telecom.com.au> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: ORr - -It seems like a first step would be to just have postmaster cache unused -connections. In other words if a client closes a connection, postmaster -keeps the connection and the child process around for the next connect -request. This has many of your advantages, but not all. However, it seems -like it would be simpler than attempting to multiplex a connection between -multiple clients. - -Jeff - -> -> Alfred Perlstein wrote: -> > -> > In an effort to complicate the postmaster beyond recognition I'm -> > proposing an idea that I hope can be useful to the developers. -> > -> > Connection pooling: -> > -> > The idea is to have the postmaster multiplex and do hand-offs of -> > database connections to other postgresql processes when the max -> > connections has been exceeded. -> > -> > This allows several gains: -> > -> > 1) Postgresql can support a large number of connections without -> > requiring a large amount of processes to do so. -> > -> > 2) Connection startup/finish will be cheaper because Postgresql -> > processes will not exit and need to reninit things such as shared -> > memory attachments and file opens. This will also reduce the load -> > on the supporting operating system and make postgresql much 'cheaper' -> > to run on systems that don't support the fork() model of execution -> > gracefully. -> > -> > 3) Long running connections can be preempted at transaction boundries -> > allowing other connections to gain process timeslices from the -> > connection pool. -> > -> > The idea is to make the postmaster that accepts connections a broker -> > for the connections. It will dole out descriptors using file -> > descriptor passing to children. If there's a demand for connections -> > meaning that all the postmasters are busy and there are pending -> > connections the postmaster can ask for a yeild on one of the -> > connections. -> > -> > A yeild involves the child postgresql process passing back the -> > client connection at a transaction boundry (between transactions) -> > so it can later be given to another (perhaps the same) child process. -> > -> > I spoke with Bruce briefly about this and he suggested that system -> > tables containing unique IDs could be used to identify passed -> > connections to the children and back to the postmaster. -> > -> > When a handoff occurs, the descriptor along with an ID referencing -> > things like temp tables and enviornment variables and authentication -> > information could be handed out as well allowing the child to resume -> > service to the interrupted connection. -> > -> > I really don't have the knowledge of Postgresql internals to -> > accomplish this, but the concepts are simple and the gains would -> > seem to be very high. -> > -> > Comments? -> > -> > -- -> > -Alfred Perlstein - [bright@wintelcom.net|alfred@freebsd.org] -> > "I have the heart of a child; I keep it in a jar on my desk." - - -From pgsql-hackers-owner+M4904@hub.org Wed Jul 12 01:24:09 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id BAA06757 - for ; Wed, 12 Jul 2000 01:24:08 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e6C5OLW65679; - Wed, 12 Jul 2000 01:24:21 -0400 (EDT) -Received: from fw.wintelcom.net (bright@ns1.wintelcom.net [209.1.153.20]) - by hub.org (8.10.1/8.10.1) with ESMTP id e6C5MkW61040 - for ; Wed, 12 Jul 2000 01:22:46 -0400 (EDT) -Received: (from bright@localhost) - by fw.wintelcom.net (8.10.0/8.10.0) id e6C5Md429901; - Tue, 11 Jul 2000 22:22:39 -0700 (PDT) -Date: Tue, 11 Jul 2000 22:22:39 -0700 -From: Alfred Perlstein -To: Chris Bitmead -Cc: pgsql-hackers@hub.org -Subject: Re: [HACKERS] Connection pooling. -Message-ID: <20000711222239.X25571@fw.wintelcom.net> -References: <20000711185318.W25571@fw.wintelcom.net> <396BEA84.1A06F51F@nimrod.itg.telecom.com.au> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.2i -In-Reply-To: <396BEA84.1A06F51F@nimrod.itg.telecom.com.au>; from chrisb@nimrod.itg.telstra.com.au on Wed, Jul 12, 2000 at 01:48:20PM +1000 -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: OR - -* Chris Bitmead [000711 20:53] wrote: -> -> Seems a lot trickier than you think. A backend can only be running -> one transaction at a time, so you'd have to keep track of which backends -> are in the middle of a transaction. I can imagine race conditions here. -> And backends can have contexts that are set by various clients using -> SET and friends. Then you'd have to worry about authentication each -> time. And you'd have to have algorithms for cleaning up old processes -> and/or dead processes. It all really sounds a bit hard. - -The backends can simply inform the postmaster when they are ready -either because they are done with a connection or because they -have just closed a transaction. - -All the state (auth/temp tables) can be held in the system tables. - -It's complicated, but no where on the order of something like -a new storage manager. - --Alfred - -From bright@fw.wintelcom.net Wed Jul 12 01:34:30 2000 -Received: from fw.wintelcom.net (bright@ns1.wintelcom.net [209.1.153.20]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id BAA06793 - for ; Wed, 12 Jul 2000 01:34:29 -0400 (EDT) -Received: (from bright@localhost) - by fw.wintelcom.net (8.10.0/8.10.0) id e6C5Z1f00384; - Tue, 11 Jul 2000 22:35:01 -0700 (PDT) -Date: Tue, 11 Jul 2000 22:35:00 -0700 -From: Alfred Perlstein -To: Bruce Momjian -Cc: Jeffery Collins , pgsql-hackers@hub.org -Subject: Re: [HACKERS] Connection pooling. -Message-ID: <20000711223500.Z25571@fw.wintelcom.net> -References: <396BE1B6.F755C5CE@onyx-technologies.com> <200007120428.AAA06357@candle.pha.pa.us> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.2i -In-Reply-To: <200007120428.AAA06357@candle.pha.pa.us>; from pgman@candle.pha.pa.us on Wed, Jul 12, 2000 at 12:28:46AM -0400 -Status: OR - -* Bruce Momjian [000711 21:31] wrote: -> > It seems like a first step would be to just have postmaster cache unused -> > connections. In other words if a client closes a connection, postmaster -> > keeps the connection and the child process around for the next connect -> > request. This has many of your advantages, but not all. However, it seems -> > like it would be simpler than attempting to multiplex a connection between -> > multiple clients. -> > -> -> This does seem like a good optimization. - -I'm not sure if the postmaster is needed besideds just to fork/exec -the backend, if so then when a backend finishes it can just call -accept() on the listening socket inherited from the postmaster to -get the next incomming connection. - --Alfred - -From pgsql-hackers-owner+M4906@hub.org Wed Jul 12 01:36:44 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id BAA06806 - for ; Wed, 12 Jul 2000 01:36:44 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e6C5akW94517; - Wed, 12 Jul 2000 01:36:46 -0400 (EDT) -Received: from fw.wintelcom.net (bright@ns1.wintelcom.net [209.1.153.20]) - by hub.org (8.10.1/8.10.1) with ESMTP id e6C5ZCW88503 - for ; Wed, 12 Jul 2000 01:35:12 -0400 (EDT) -Received: (from bright@localhost) - by fw.wintelcom.net (8.10.0/8.10.0) id e6C5Z1f00384; - Tue, 11 Jul 2000 22:35:01 -0700 (PDT) -Date: Tue, 11 Jul 2000 22:35:00 -0700 -From: Alfred Perlstein -To: Bruce Momjian -Cc: Jeffery Collins , pgsql-hackers@hub.org -Subject: Re: [HACKERS] Connection pooling. -Message-ID: <20000711223500.Z25571@fw.wintelcom.net> -References: <396BE1B6.F755C5CE@onyx-technologies.com> <200007120428.AAA06357@candle.pha.pa.us> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.2i -In-Reply-To: <200007120428.AAA06357@candle.pha.pa.us>; from pgman@candle.pha.pa.us on Wed, Jul 12, 2000 at 12:28:46AM -0400 -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: OR - -* Bruce Momjian [000711 21:31] wrote: -> > It seems like a first step would be to just have postmaster cache unused -> > connections. In other words if a client closes a connection, postmaster -> > keeps the connection and the child process around for the next connect -> > request. This has many of your advantages, but not all. However, it seems -> > like it would be simpler than attempting to multiplex a connection between -> > multiple clients. -> > -> -> This does seem like a good optimization. - -I'm not sure if the postmaster is needed besideds just to fork/exec -the backend, if so then when a backend finishes it can just call -accept() on the listening socket inherited from the postmaster to -get the next incomming connection. - --Alfred - -From pgsql-hackers-owner+M4907@hub.org Wed Jul 12 01:55:39 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id BAA06881 - for ; Wed, 12 Jul 2000 01:55:38 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e6C5tnW34576; - Wed, 12 Jul 2000 01:55:49 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.10.1/8.10.1) with ESMTP id e6C5rfW28119 - for ; Wed, 12 Jul 2000 01:53:42 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id BAA21895; - Wed, 12 Jul 2000 01:52:56 -0400 (EDT) -To: Chris Bitmead -cc: Alfred Perlstein , pgsql-hackers@hub.org -Subject: Re: [HACKERS] Connection pooling. -In-reply-to: <396BEA84.1A06F51F@nimrod.itg.telecom.com.au> -References: <20000711185318.W25571@fw.wintelcom.net> <396BEA84.1A06F51F@nimrod.itg.telecom.com.au> -Comments: In-reply-to Chris Bitmead - message dated "Wed, 12 Jul 2000 13:48:20 +1000" -Date: Wed, 12 Jul 2000 01:52:56 -0400 -Message-ID: <21892.963381176@sss.pgh.pa.us> -From: Tom Lane -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: OR - -Chris Bitmead writes: -> Seems a lot trickier than you think. A backend can only be running -> one transaction at a time, so you'd have to keep track of which backends -> are in the middle of a transaction. I can imagine race conditions here. - -Aborting out of a transaction is no problem; we have code for that -anyway. More serious problems: - -* We have no code for reassigning a backend to a different database, - so the pooling would have to be per-database. - -* AFAIK there is no portable way to pass a socket connection from the - postmaster to an already-existing backend process. If you do a - fork() then the connection is inherited ... otherwise you've got a - problem. (You could work around this if the postmaster relays - every single byte in both directions between client and backend, - but the performance problems with that should be obvious.) - -> And backends can have contexts that are set by various clients using -> SET and friends. - -Resetting SET variables would be a problem, and there's also the -assigned user name to be reset. This doesn't seem impossible, but -it does seem tedious and error-prone. (OTOH, Peter E's recent work -on guc.c might have unified option-handling enough to bring it -within reason.) - -The killer problem here is that you can't hand off a connection -accepted by the postmaster to a backend except by fork() --- at least -not with methods that work on a wide variety of Unixen. Unless someone -has a way around that, I think the idea is dead in the water; the lesser -issues don't matter. - - regards, tom lane - -From pgsql-hackers-owner+M4910@hub.org Wed Jul 12 02:24:16 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id CAA11184 - for ; Wed, 12 Jul 2000 02:24:15 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e6C6OAW98187; - Wed, 12 Jul 2000 02:24:10 -0400 (EDT) -Received: from acheron.rime.com.au (root@albatr.lnk.telstra.net [139.130.54.222]) - by hub.org (8.10.1/8.10.1) with ESMTP id e6C6MZW95741 - for ; Wed, 12 Jul 2000 02:22:36 -0400 (EDT) -Received: from oberon (Oberon.rime.com.au [203.8.195.100]) - by acheron.rime.com.au (8.9.3/8.9.3) with SMTP id QAA12845; - Wed, 12 Jul 2000 16:16:23 +1000 -Message-Id: <3.0.5.32.20000712162210.0098fb00@mail.rhyme.com.au> -X-Sender: pjw@mail.rhyme.com.au -X-Mailer: QUALCOMM Windows Eudora Pro Version 3.0.5 (32) -Date: Wed, 12 Jul 2000 16:22:10 +1000 -To: Tom Lane , - Chris Bitmead -From: Philip Warner -Subject: Re: [HACKERS] Connection pooling. -Cc: Alfred Perlstein , pgsql-hackers@hub.org -In-Reply-To: <21892.963381176@sss.pgh.pa.us> -References: <396BEA84.1A06F51F@nimrod.itg.telecom.com.au> - <20000711185318.W25571@fw.wintelcom.net> - <396BEA84.1A06F51F@nimrod.itg.telecom.com.au> -Mime-Version: 1.0 -Content-Type: text/plain; charset="us-ascii" -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: OR - -At 01:52 12/07/00 -0400, Tom Lane wrote: -> ->The killer problem here is that you can't hand off a connection ->accepted by the postmaster to a backend except by fork() --- at least ->not with methods that work on a wide variety of Unixen. Unless someone ->has a way around that, I think the idea is dead in the water; the lesser ->issues don't matter. -> - -My understanding of pg client interfaces is that the client uses ont of the -pg interface libraries to make a connection to the db; they specify host & -port and get back some kind of connection object. - -What stops the interface library from using the host & port to talk to the -postmaster, find the host & port the spare db server, then connect directly -to the server? This second connection is passed back in the connection object. - -When the client disconnects from the server, it tells the postmaster it's -available again etc. - -ie. in very rough terms: - - client calls interface to connect - - interface talks to postmaster on port 5432, says "I want a server for -xyz db" - - postmaster replies with "Try port ABCD" OR "no servers available" - postmaster marks the nominated server as 'used' - postmaster disconnects from client - - interface connects to port ABCD as per normal protocols - interface fills in connection object & returns - - ...client does some work... - - client disconnects - - db server tells postmaster it's available again. - - -There would also need to be timeout code to handle the case where the -interface did not do the second connect. - -You could also have the interface allocate a port send it's number to the -postmaster then listen on it, but I think that would represent a potential -security hole. - - ----------------------------------------------------------------- -Philip Warner | __---_____ -Albatross Consulting Pty. Ltd. |----/ - \ -(A.C.N. 008 659 498) | /(@) ______---_ -Tel: (+61) 0500 83 82 81 | _________ \ -Fax: (+61) 0500 83 82 82 | ___________ | -Http://www.rhyme.com.au | / \| - | --________-- -PGP key available upon request, | / -and from pgp5.ai.mit.edu:11371 |/ - -From pgsql-hackers-owner+M4912@hub.org Wed Jul 12 02:32:21 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id CAA11228 - for ; Wed, 12 Jul 2000 02:32:20 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e6C6WWW18412; - Wed, 12 Jul 2000 02:32:32 -0400 (EDT) -Received: from fw.wintelcom.net (bright@ns1.wintelcom.net [209.1.153.20]) - by hub.org (8.10.1/8.10.1) with ESMTP id e6C6UwW16062 - for ; Wed, 12 Jul 2000 02:30:58 -0400 (EDT) -Received: (from bright@localhost) - by fw.wintelcom.net (8.10.0/8.10.0) id e6C6Uov01852; - Tue, 11 Jul 2000 23:30:50 -0700 (PDT) -Date: Tue, 11 Jul 2000 23:30:49 -0700 -From: Alfred Perlstein -To: Tom Lane -Cc: Chris Bitmead , pgsql-hackers@hub.org -Subject: Re: [HACKERS] Connection pooling. -Message-ID: <20000711233049.A25571@fw.wintelcom.net> -References: <20000711185318.W25571@fw.wintelcom.net> <396BEA84.1A06F51F@nimrod.itg.telecom.com.au> <21892.963381176@sss.pgh.pa.us> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.2i -In-Reply-To: <21892.963381176@sss.pgh.pa.us>; from tgl@sss.pgh.pa.us on Wed, Jul 12, 2000 at 01:52:56AM -0400 -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: OR - -* Tom Lane [000711 22:53] wrote: -> Chris Bitmead writes: -> > Seems a lot trickier than you think. A backend can only be running -> > one transaction at a time, so you'd have to keep track of which backends -> > are in the middle of a transaction. I can imagine race conditions here. -> -> Aborting out of a transaction is no problem; we have code for that -> anyway. More serious problems: -> -> * We have no code for reassigning a backend to a different database, -> so the pooling would have to be per-database. - -That would need to be fixed. How difficult would that be? - -> * AFAIK there is no portable way to pass a socket connection from the -> postmaster to an already-existing backend process. If you do a -> fork() then the connection is inherited ... otherwise you've got a -> problem. (You could work around this if the postmaster relays -> every single byte in both directions between client and backend, -> but the performance problems with that should be obvious.) - -no, see below. - -> > And backends can have contexts that are set by various clients using -> > SET and friends. -> -> Resetting SET variables would be a problem, and there's also the -> assigned user name to be reset. This doesn't seem impossible, but -> it does seem tedious and error-prone. (OTOH, Peter E's recent work -> on guc.c might have unified option-handling enough to bring it -> within reason.) - -What can be done is that each incomming connection can be assigned an -ID into a system table. As options are added the system would assign -them to key-value pairs in this table. Once someone detects that the -remote side has closed the connection the data can be destroyed, but -until then along with the descriptor passing the ID of the client -as an index into the table can be passed for the backend to fetch. - -> The killer problem here is that you can't hand off a connection -> accepted by the postmaster to a backend except by fork() --- at least -> not with methods that work on a wide variety of Unixen. Unless someone -> has a way around that, I think the idea is dead in the water; the lesser -> issues don't matter. - -The code has been around since 4.2BSD, it takes a bit of #ifdef to -get it right on all systems but it's not impossible, have a look at -http://www.fhttpd.org/ for a web server that does this in a portable -fashion. - -I should have a library whipped up for you guys really soon now -to handle the descriptor and message passing. - --- --Alfred Perlstein - [bright@wintelcom.net|alfred@freebsd.org] -"I have the heart of a child; I keep it in a jar on my desk." - -From pgsql-hackers-owner+M4913@hub.org Wed Jul 12 03:06:54 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id DAA11529 - for ; Wed, 12 Jul 2000 03:06:53 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e6C76ZW95615; - Wed, 12 Jul 2000 03:06:35 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.10.1/8.10.1) with ESMTP id e6C74gW93358 - for ; Wed, 12 Jul 2000 03:04:42 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id DAA22136; - Wed, 12 Jul 2000 03:04:13 -0400 (EDT) -To: Alfred Perlstein -cc: Chris Bitmead , pgsql-hackers@hub.org -Subject: Re: [HACKERS] Connection pooling. -In-reply-to: <20000711233049.A25571@fw.wintelcom.net> -References: <20000711185318.W25571@fw.wintelcom.net> <396BEA84.1A06F51F@nimrod.itg.telecom.com.au> <21892.963381176@sss.pgh.pa.us> <20000711233049.A25571@fw.wintelcom.net> -Comments: In-reply-to Alfred Perlstein - message dated "Tue, 11 Jul 2000 23:30:49 -0700" -Date: Wed, 12 Jul 2000 03:04:13 -0400 -Message-ID: <22133.963385453@sss.pgh.pa.us> -From: Tom Lane -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: OR - -Alfred Perlstein writes: -> * Tom Lane [000711 22:53] wrote: ->> The killer problem here is that you can't hand off a connection ->> accepted by the postmaster to a backend except by fork() --- at least ->> not with methods that work on a wide variety of Unixen. - -> The code has been around since 4.2BSD, it takes a bit of #ifdef to -> get it right on all systems but it's not impossible, have a look at -> http://www.fhttpd.org/ for a web server that does this in a portable -> fashion. - -I looked at this to see if it would teach me something I didn't know. -It doesn't. It depends on sendmsg() which is a BSD-ism and not very -portable. - - regards, tom lane - -From pgsql-hackers-owner+M4914@hub.org Wed Jul 12 03:12:40 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id DAA11597 - for ; Wed, 12 Jul 2000 03:12:39 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e6C7CjW13459; - Wed, 12 Jul 2000 03:12:45 -0400 (EDT) -Received: from fw.wintelcom.net (bright@ns1.wintelcom.net [209.1.153.20]) - by hub.org (8.10.1/8.10.1) with ESMTP id e6C7B8W07036 - for ; Wed, 12 Jul 2000 03:11:08 -0400 (EDT) -Received: (from bright@localhost) - by fw.wintelcom.net (8.10.0/8.10.0) id e6C79lE02841; - Wed, 12 Jul 2000 00:09:47 -0700 (PDT) -Date: Wed, 12 Jul 2000 00:09:47 -0700 -From: Alfred Perlstein -To: Tom Lane -Cc: Chris Bitmead , pgsql-hackers@hub.org -Subject: Re: [HACKERS] Connection pooling. -Message-ID: <20000712000947.D25571@fw.wintelcom.net> -References: <20000711185318.W25571@fw.wintelcom.net> <396BEA84.1A06F51F@nimrod.itg.telecom.com.au> <21892.963381176@sss.pgh.pa.us> <20000711233049.A25571@fw.wintelcom.net> <22133.963385453@sss.pgh.pa.us> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.2i -In-Reply-To: <22133.963385453@sss.pgh.pa.us>; from tgl@sss.pgh.pa.us on Wed, Jul 12, 2000 at 03:04:13AM -0400 -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: OR - -* Tom Lane [000712 00:04] wrote: -> Alfred Perlstein writes: -> > * Tom Lane [000711 22:53] wrote: -> >> The killer problem here is that you can't hand off a connection -> >> accepted by the postmaster to a backend except by fork() --- at least -> >> not with methods that work on a wide variety of Unixen. -> -> > The code has been around since 4.2BSD, it takes a bit of #ifdef to -> > get it right on all systems but it's not impossible, have a look at -> > http://www.fhttpd.org/ for a web server that does this in a portable -> > fashion. -> -> I looked at this to see if it would teach me something I didn't know. -> It doesn't. It depends on sendmsg() which is a BSD-ism and not very -> portable. - -It's also specified by Posix.1g if that means anything. - --Alfred - -From pgsql-hackers-owner+M4916@hub.org Wed Jul 12 03:49:58 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id DAA11736 - for ; Wed, 12 Jul 2000 03:49:58 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e6C7oBW95547; - Wed, 12 Jul 2000 03:50:11 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.10.1/8.10.1) with ESMTP id e6C7mPW93141 - for ; Wed, 12 Jul 2000 03:48:25 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id DAA22297; - Wed, 12 Jul 2000 03:47:37 -0400 (EDT) -To: Philip Warner -cc: Chris Bitmead , - Alfred Perlstein , pgsql-hackers@hub.org -Subject: Re: [HACKERS] Connection pooling. -In-reply-to: <3.0.5.32.20000712162210.0098fb00@mail.rhyme.com.au> -References: <396BEA84.1A06F51F@nimrod.itg.telecom.com.au> <20000711185318.W25571@fw.wintelcom.net> <396BEA84.1A06F51F@nimrod.itg.telecom.com.au> <3.0.5.32.20000712162210.0098fb00@mail.rhyme.com.au> -Comments: In-reply-to Philip Warner - message dated "Wed, 12 Jul 2000 16:22:10 +1000" -Date: Wed, 12 Jul 2000 03:47:37 -0400 -Message-ID: <22294.963388057@sss.pgh.pa.us> -From: Tom Lane -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: OR - -Philip Warner writes: -> What stops the interface library from using the host & port to talk to -> the postmaster, find the host & port the spare db server, then connect -> directly to the server? - -You're assuming that we can change the on-the-wire protocol freely and -only the API presented by the client libraries matters. In a perfect -world that might be true, but reality is that we can't change the wire -protocol easily. If we do, it breaks all existing precompiled clients. -Updating clients can be an extremely painful experience in multiple- -machine installations. - -Also, we don't have just one set of client libraries to fix. There are -at least three client-side implementations that don't depend on libpq. - -We have done protocol updates in the past --- in fact I was responsible -for the last one. (And I'm still carrying the scars, which is why I'm -not too enthusiastic about another one.) It's not impossible, but it -needs more evidence than "this should speed up connections by -I-don't-know-how-much"... - -It might also be worth pointing out that the goal was to speed up the -end-to-end connection time. Redirecting as you suggest is not free -(at minimum it would appear to require two TCP connection setups and two -authentication cycles). What evidence have you got that it'd be faster -than spawning a new backend? - -I tend to agree with the opinion that connection-pooling on the client -side offers more bang for the buck than we could hope to get by doing -surgery on the postmaster/backend setup. - -Also, to return to the original point, AFAIK we have not tried hard -to cut the backend startup time, other than the work that was done -a year or so back to eliminate exec() of a separate executable. -It'd be worth looking to see what could be done there with zero -impact on existing clients. - - regards, tom lane - -From pgsql-hackers-owner+M16940@postgresql.org Sun Dec 23 23:06:28 2001 -Return-path: -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fBO46R429655 - for ; Sun, 23 Dec 2001 23:06:27 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fBO40oN57016; - Sun, 23 Dec 2001 22:00:50 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16940@postgresql.org) -Received: from relay.pair.com (relay1.pair.com [209.68.1.20]) - by postgresql.org (8.11.3/8.11.4) with SMTP id fBID0um78493 - for ; Tue, 18 Dec 2001 08:00:56 -0500 (EST) - (envelope-from ml@augustz.com) -Received: (qmail 79914 invoked from network); 18 Dec 2001 13:00:58 -0000 -Received: from acz01997-2.pomona.edu (HELO Microsoft) (134.173.91.3) - by relay1.pair.com with SMTP; 18 Dec 2001 13:00:58 -0000 -X-pair-Authenticated: 134.173.91.3 -From: "August Zajonc" -To: -Subject: [HACKERS] Connection Pooling, a year later -Date: Tue, 18 Dec 2001 05:00:57 -0800 -Message-ID: -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2911.0) -Importance: Normal -X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -I feel there was a reasonably nice client side attempt at this using a -worker pool model or something. Can't seem to track it down at this moment. -Also would spread queries in different ways to get a hot backup equivalent -etc. It was slick. - -The key is that pgsql be able to support a very significant number of -transactions. Be neat to see some numbers on your attempt. - -Site I used to run had 6 front end webservers running PHP apps. Each -persistent connection (a requirement to avoid overhead of set-up/teardowns) -lived as long as the httpd process lived, even if idle. That meant at 250 -processes per server we had a good 1500 connections clicking over. Our -feeling was that rather than growing to 3,000 connections as the frontend -grew, why not pool those connections off each machine down to perhaps -75/machine worker threads that actually did the work. - -Looks like that's not an issue if these backends suck up few resources. -Doing something similar with MySQL we'd experiance problems if we got into -the 2,000 connection range. (kernel/system limits bumped plenty high). - -While we are on TODO's I would like to point out that some way to fully -vacume (ie recover deleted and changed) while a db is in full swing is -critical to larger installtions. We did 2 billion queries between reboots on -a quad zeon MySQL box, and those are real user based queries not data loads -or anything like that. At 750-1000 queries/second bringing the database down -or seriously degrading its performance is not a good option. - -Enjoy playing with pgsql as always.... - -- AZ - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From dhogaza@pacifier.com Tue Dec 18 11:15:06 2001 -Return-path: -Received: from asteroid.pacifier.com ([199.2.117.154]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fBIGF5419342 - for ; Tue, 18 Dec 2001 11:15:05 -0500 (EST) -Received: from pacifier.com (dsl-dhogaza.pacifier.net [207.202.226.68]) - by asteroid.pacifier.com (8.11.2/8.11.1) with ESMTP id fBIGEGe29925; - Tue, 18 Dec 2001 08:14:17 -0800 (PST) -Message-ID: <3C1F6B81.10500@pacifier.com> -Date: Tue, 18 Dec 2001 08:14:57 -0800 -From: Don Baccus -User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.6) Gecko/20011120 -X-Accept-Language: en-us -MIME-Version: 1.0 -To: Bruce Momjian -cc: mlw , owensmk@earthlink.net, - pgsql-hackers@postgresql.org, Tom Lane -Subject: Re: [HACKERS] Connection Pooling, a year later -References: <200112180342.fBI3g4s23880@candle.pha.pa.us> -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Status: OR - -Bruce Momjian wrote: - - -> It would just be nice to have it done internally rather than have all -> the clients do it, iff it can be done cleanly. - -Serious client applications that need it already do it. Firing up an -Oracle or most other db's isn't that lightweight a deal, either, it's -not useful only for PG.. - -Personally I'd just view it as getting in the way, but then I use a -webserver that's provided connection pooling for client threads for the -last seven years ... - -I agree with Tom that the client seems to be the best place to do this. - -Among other things it isn't that difficult. If you know how to fire up -one connection, you know how to fire up N of them and adding logic to -pool them afterwards is easy enough. --- -Don Baccus -Portland, OR -http://donb.photo.net, http://birdnotes.net, http://openacs.org - - -From dhogaza@pacifier.com Tue Dec 18 11:24:33 2001 -Return-path: -Received: from asteroid.pacifier.com ([199.2.117.154]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fBIGOW421363 - for ; Tue, 18 Dec 2001 11:24:33 -0500 (EST) -Received: from pacifier.com (dsl-dhogaza.pacifier.net [207.202.226.68]) - by asteroid.pacifier.com (8.11.2/8.11.1) with ESMTP id fBIGNne00442; - Tue, 18 Dec 2001 08:23:49 -0800 (PST) -Message-ID: <3C1F6DBF.2040000@pacifier.com> -Date: Tue, 18 Dec 2001 08:24:31 -0800 -From: Don Baccus -User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.6) Gecko/20011120 -X-Accept-Language: en-us -MIME-Version: 1.0 -To: Bruce Momjian -cc: mlw , owensmk@earthlink.net, - pgsql-hackers@postgresql.org, Tom Lane -Subject: Re: [HACKERS] Connection Pooling, a year later -References: <200112180357.fBI3vBm24991@candle.pha.pa.us> -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Status: OR - -Bruce Momjian wrote: - - -> Yes, that is assuming you are using PHP. If you are using something -> else, you connection pooling in there too. All those client interfaces -> reimplementing connection pooling seems like a waste to me. - - -Effective pooling's pretty specific to your environment, though, so any -general mechanism would have to provide a wide-ranging suite of -parameters governing the number to pool, how long each handle should -live, what to do if a handle's released by a client while in the midst -of a transaction (AOLserver rolls back the transaction, other clients -might want to do something else, i.e. fire a callback or the like), etc etc. - -I think it would be fairly complex and for those high-throughput -applications already written with client-side pooling no improvement. - -And those are the only applications that need it. - --- -Don Baccus -Portland, OR -http://donb.photo.net, http://birdnotes.net, http://openacs.org - - -From pgsql-hackers-owner+M16726@postgresql.org Tue Dec 18 11:48:16 2001 -Return-path: -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fBIGmG422658 - for ; Tue, 18 Dec 2001 11:48:16 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fBIGkFN40986; - Tue, 18 Dec 2001 10:46:15 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16726@postgresql.org) -Received: from comet.pacifier.com ([199.2.117.155]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fBIGYZm93404 - for ; Tue, 18 Dec 2001 11:34:35 -0500 (EST) - (envelope-from dhogaza@pacifier.com) -Received: from pacifier.com (dsl-dhogaza.pacifier.net [207.202.226.68]) - by comet.pacifier.com (8.11.2/8.11.1) with ESMTP id fBIGXCX29823; - Tue, 18 Dec 2001 08:33:12 -0800 (PST) -Message-ID: <3C1F6FF1.9030606@pacifier.com> -Date: Tue, 18 Dec 2001 08:33:53 -0800 -From: Don Baccus -User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.6) Gecko/20011120 -X-Accept-Language: en-us -MIME-Version: 1.0 -To: Mark Pritchard -cc: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Connection Pooling, a year later -References: -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Mark Pritchard wrote: - ->>I think it is the startup cost that most people want to avoid, and our's ->>is higher than most db's that use threads; at least I think so. ->> ->>It would just be nice to have it done internally rather than have all ->>the clients do it, iff it can be done cleanly. ->> -> -> I'd add that client side connection pooling isn't effective in some cases -> anyway - one application we work with has 4 physical application servers -> running around 6 applications. Each of the applications was written by a -> different vendor, and thus a pool size of five gives you 120 open -> connections. - -Tuning a central pooling mechanism to run well in this kind of situation -isn't going to be a trivial task, either. The next thing you'll want is -some way to prioritize the various clients so your more serious -applications have a better chance of getting a pool. - -Or you'll want to set up subpools so they don't compete with each other, -in effect replicating what's done now, but adding more complexity to the -central service. - --- -Don Baccus -Portland, OR -http://donb.photo.net, http://birdnotes.net, http://openacs.org - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From oleg@sai.msu.su Tue Dec 18 12:05:51 2001 -Return-path: -Received: from ra.sai.msu.su (ra.sai.msu.su [158.250.29.2]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fBIH5h423591 - for ; Tue, 18 Dec 2001 12:05:43 -0500 (EST) -Received: from ra (ra [158.250.29.2]) - by ra.sai.msu.su (8.9.3/8.9.3) with ESMTP id UAA18592; - Tue, 18 Dec 2001 20:05:26 +0300 (GMT) -Date: Tue, 18 Dec 2001 20:05:26 +0300 (GMT) -From: Oleg Bartunov -X-X-Sender: -To: Don Baccus -cc: Bruce Momjian , mlw , - , , - Tom Lane -Subject: Re: [HACKERS] Connection Pooling, a year later -In-Reply-To: <3C1F6DBF.2040000@pacifier.com> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Status: OR - -Does schema support will resolve this discussion ? -If I understand correctly, initial arguments for connection pooling -was restriction in number of persistent connections. it's right in -current postgresql that if one wants keep connection for performance -reason to several databases the total number of connections will -doubled, trippled and so on. But if I understand schema support will -eventually put away these problem because we could keep only one -pool of connections to the *one* database. - - Oleg - -On Tue, 18 Dec 2001, Don Baccus wrote: - -> Bruce Momjian wrote: -> -> -> > Yes, that is assuming you are using PHP. If you are using something -> > else, you connection pooling in there too. All those client interfaces -> > reimplementing connection pooling seems like a waste to me. -> -> -> Effective pooling's pretty specific to your environment, though, so any -> general mechanism would have to provide a wide-ranging suite of -> parameters governing the number to pool, how long each handle should -> live, what to do if a handle's released by a client while in the midst -> of a transaction (AOLserver rolls back the transaction, other clients -> might want to do something else, i.e. fire a callback or the like), etc etc. -> -> I think it would be fairly complex and for those high-throughput -> applications already written with client-side pooling no improvement. -> -> And those are the only applications that need it. -> -> - - Regards, - Oleg -_____________________________________________________________ -Oleg Bartunov, sci.researcher, hostmaster of AstroNet, -Sternberg Astronomical Institute, Moscow University (Russia) -Internet: oleg@sai.msu.su, http://www.sai.msu.su/~megera/ -phone: +007(095)939-16-83, +007(095)939-23-83 - - -From pgsql-hackers-owner+M16748@postgresql.org Tue Dec 18 15:11:46 2001 -Return-path: -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fBIKBj405415 - for ; Tue, 18 Dec 2001 15:11:45 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fBIKB0N47430; - Tue, 18 Dec 2001 14:11:00 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16748@postgresql.org) -Received: from candle.pha.pa.us (216-55-132-35.dialup.tnt01.san-diego.abac.net [216.55.132.35]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fBIJulm05030 - for ; Tue, 18 Dec 2001 14:56:47 -0500 (EST) - (envelope-from pgman@candle.pha.pa.us) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.11.6/8.10.1) id fBIJuVB04553; - Tue, 18 Dec 2001 14:56:31 -0500 (EST) -From: Bruce Momjian -Message-ID: <200112181956.fBIJuVB04553@candle.pha.pa.us> -Subject: Re: [HACKERS] Connection Pooling, a year later -In-Reply-To: <3C1F6ED6.6080107@pacifier.com> "from Don Baccus at Dec 18, 2001 - 08:29:10 am" -To: Don Baccus -Date: Tue, 18 Dec 2001 14:56:31 -0500 (EST) -cc: Christopher Kings-Lynne , - mlw , owensmk@earthlink.net, - pgsql-hackers@postgresql.org, Tom Lane -X-Mailer: ELM [version 2.4ME+ PL90 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -> Bruce Momjian wrote: -> -> -> > -> > The trick for that is to call COMMIT before you pass the backend to a -> > new person. -> -> -> The failure to COMMIT is a programmer error - ROLLBACK's much safer. At -> least that's what we decided in the AOLserver community, and that's -> what the drivers for Oracle and PG (the two I maintain) implement. - - -Then you can issue a "BEGIN;ROLLBACK;" when you pass the session to the -next user, and "RESET ALL;" of course. - -> > Now, if you want to abort a left-over transaction, you can -> > do an ABORT but that is going to show up in the server logs because an -> > ABORT without a transaction causes an error message. -> -> -> The connection pooling mechanism needs to track the transaction state -> and only ROLLBACK a handle that's not in autocommit state or in the -> midst of a BEGIN/END transaction (again, Oracle vs. PG).. - -Seems like a lot of work to keep track of transaction state in the -client; seems easier to just unconditionally issue the begin;rollback. - --- - Bruce Momjian | http://candle.pha.pa.us - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M16793@postgresql.org Wed Dec 19 00:46:50 2001 -Return-path: -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fBJ5kn426988 - for ; Wed, 19 Dec 2001 00:46:49 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fBJ5gnN63439; - Tue, 18 Dec 2001 23:42:49 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16793@postgresql.org) -Received: from deborah.paradise.net.nz (deborah.paradise.net.nz [203.96.152.32]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fBJ5Uvm41224 - for ; Wed, 19 Dec 2001 00:30:58 -0500 (EST) - (envelope-from andrew@catalyst.net.nz) -Received: from heidegger.catalyst.net.nz (203-96-145-108.adsl.paradise.net.nz [203.96.145.108]) - by deborah.paradise.net.nz (Postfix) with ESMTP - id D1C7CD194D; Wed, 19 Dec 2001 18:31:01 +1300 (NZDT) -Received: from 127.0.0.1 (ident=unknown) by heidegger.catalyst.net.nz - with esmtp (MasqMail 0.1.15) id 16GZJK-5NU-00; Wed, 19 Dec 2001 - 18:30:34 +1300 -Subject: Re: [HACKERS] Connection Pooling, a year later -From: Andrew McMillan -To: owensmk@earthlink.net -cc: pgsql-hackers@postgresql.org -In-Reply-To: <200112180028.fBI0Sum06915@postgresql.org> -References: <200112180028.fBI0Sum06915@postgresql.org> -Content-Type: text/plain -Content-Transfer-Encoding: 7bit -X-Mailer: Evolution/1.0 (Preview Release) -Date: 19 Dec 2001 18:30:34 +1300 -Message-ID: <1008739834.25608.33.camel@kant.mcmillan.net.nz> -MIME-Version: 1.0 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Tue, 2001-12-18 at 13:46, Michael Owens wrote: -> -> By having the postmaster map multiple clients to a fixed number of backends, -> you achieve the happy medium: You never exceed the ideal number of active -> backends, and at the same time you are not limited to only accepting a fixed -> number of connections. Accepting connections can now be based on load -> (however you wish to define it), not number. You now make decisions based on -> utlization. -> -> If it were shown that even half of a backend's life consisted of idle time, -> leasing out that idle time to another active connection would potentially -> double the average number of simultaneous requests without (theoretically) -> incurring any significant degradation in performance. -> - -Have you looked at the client-side connection pooling solutions out -there? - -DBBalancer ( http://dbbalancer.sourceforge.net/ ) tries to sit very -transparently between your application and PostgreSQL, letting you -implement connection pooling with almost no application changes. - -There was another one I came across too, but that one requires you to -make more wide-reaching changes to the application. - -In my applications I have found DBBalancer to be roughly the same level -of performance as PHP persistent connections, but a lot fewer -connections are needed in the pool because they are only needed when -Apache is delivering dynamic content - not the associated static -stylesheets and images. - -Regards, - Andrew. --- --------------------------------------------------------------------- -Andrew @ Catalyst .Net.NZ Ltd, PO Box 11-053, Manners St, Wellington -WEB: http://catalyst.net.nz/ PHYS: Level 2, 150-154 Willis St -DDI: +64(4)916-7201 MOB: +64(21)635-694 OFFICE: +64(4)499-2267 - Are you enrolled at http://schoolreunions.co.nz/ yet? - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M16834@postgresql.org Wed Dec 19 14:17:47 2001 -Return-path: -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fBJJHk404096 - for ; Wed, 19 Dec 2001 14:17:46 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fBJJENN87550; - Wed, 19 Dec 2001 13:14:23 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16834@postgresql.org) -Received: from asteroid.pacifier.com ([199.2.117.154]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fBJJ55m16181 - for ; Wed, 19 Dec 2001 14:05:05 -0500 (EST) - (envelope-from dhogaza@pacifier.com) -Received: from pacifier.com (dsl-dhogaza.pacifier.net [207.202.226.68]) - by asteroid.pacifier.com (8.11.2/8.11.1) with ESMTP id fBJJ3fe20585; - Wed, 19 Dec 2001 11:03:41 -0800 (PST) -Message-ID: <3C20E4B9.8090200@pacifier.com> -Date: Wed, 19 Dec 2001 11:04:25 -0800 -From: Don Baccus -User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.6) Gecko/20011120 -X-Accept-Language: en-us -MIME-Version: 1.0 -To: owensmk@earthlink.net -cc: Andrew McMillan , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Connection Pooling, a year later -References: <200112180028.fBI0Sum06915@postgresql.org> <1008739834.25608.33.camel@kant.mcmillan.net.nz> -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Michael Owens wrote: - -> As long as each client's call is composed of a standalone transaction, there -> is no problem with external connection pools. But what about when a client's -> transactions spans two or more calls, such as SELECT FOR UPDATE? Then pooling -> is not safe: it offers no assurance of what may be interjected into an open -> transaction between calls. For example, each is a separate call to a shared -> connection: -> -> Client A: BEGIN WORK; SELECT last_name from customer for update where ; -> -> Client B: BEGIN WORK; SELECT street from customer for update where ; -> -> Client A: update customer set lastname= where ; COMMIT -> WORK; -> -> -> Now, isn't Client B's write lock gone with Client A's commit? Yet Client A's -> lock is still hanging around. While Client B's commit will close it, Client B -> has lost the assurance of its lock, defeating the purpose of SELECT FOR -> UPDATE. -> -> If this is corrent, then external connection pools limit what you can do with -> the database to a single call. Any transaction spanning more than one call is -> unsafe, because it is not isolated from other clients sharing the same -> connection. - - -The general idea is that you grab a handle and hold onto it until you're -done. This makes the above scenario impossible. - -Forgetting to commit or rollback before relenquishing the handle is -another scenario that can lead to problems but that's already been -discussed in detail. - --- -Don Baccus -Portland, OR -http://donb.photo.net, http://birdnotes.net, http://openacs.org - - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M16838@postgresql.org Wed Dec 19 15:17:32 2001 -Return-path: -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fBJKHV408663 - for ; Wed, 19 Dec 2001 15:17:32 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fBJKDNN89347; - Wed, 19 Dec 2001 14:13:23 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16838@postgresql.org) -Received: from gull.prod.itd.earthlink.net (gull.mail.pas.earthlink.net [207.217.120.84]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fBJKA2m62023 - for ; Wed, 19 Dec 2001 15:10:03 -0500 (EST) - (envelope-from owensmk@earthlink.net) -Received: from sdn-ar-004txfworp179.dialsprint.net ([158.252.142.219] helo=there) - by gull.prod.itd.earthlink.net with smtp (Exim 3.33 #1) - id 16Gn2K-0005YP-00; Wed, 19 Dec 2001 12:09:57 -0800 -Content-Type: text/plain; - charset="iso-8859-1" -From: Michael Owens -Reply-To: owensmk@earthlink.net -To: Don Baccus -Subject: Re: [HACKERS] Connection Pooling, a year later -Date: Wed, 19 Dec 2001 14:28:14 -0600 -X-Mailer: KMail [version 1.3.1] -cc: Andrew McMillan , pgsql-hackers@postgresql.org -References: <200112180028.fBI0Sum06915@postgresql.org> <3C20E4B9.8090200@pacifier.com> -In-Reply-To: <3C20E4B9.8090200@pacifier.com> -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -Message-ID: -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wednesday 19 December 2001 01:04 pm, Don Baccus wrote: - - -> The general idea is that you grab a handle and hold onto it until you're -> done. This makes the above scenario impossible. -> -> Forgetting to commit or rollback before relenquishing the handle is -> another scenario that can lead to problems but that's already been -> discussed in detail. - -But then the shared connection is unshared, sitting idle while the client -works in between calls, thus introducing idle time among a fixed number of -connections. The server is doing less than it could. - -I agree that this connection pool has improved things in eliminating backend -startup time. But idle time still exists for the clients performing multiple -calls, proportional to the product of the number of multiple call clients and -the number of calls they make, plus the idle time between them. - -However this probably only ever happens on update. Inserts and selects can be -done in one call. And, I suppose updates comprise only a small fraction of -the requests sent to the database. Even then, you can probably eliminate some -multiple calls by using things such as procedures. - -Factoring all that in, you can probably do as well by optimizing your -particular database/application than by writing code. - -I relent. Thanks for your thoughts. - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M16855@postgresql.org Thu Dec 20 01:02:51 2001 -Return-path: -Received: from rs.postgresql.org (server1.pgsql.org [64.39.15.238] (may be forged)) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id fBK62o404294 - for ; Thu, 20 Dec 2001 01:02:50 -0500 (EST) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by rs.postgresql.org (8.11.6/8.11.6) with ESMTP id fBK5xnN05417; - Wed, 19 Dec 2001 23:59:49 -0600 (CST) - (envelope-from pgsql-hackers-owner+M16855@postgresql.org) -Received: from deborah.paradise.net.nz (deborah.paradise.net.nz [203.96.152.32]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id fBK5mvm47263 - for ; Thu, 20 Dec 2001 00:48:57 -0500 (EST) - (envelope-from andrew@catalyst.net.nz) -Received: from heidegger.catalyst.net.nz (203-96-145-94.adsl.paradise.net.nz [203.96.145.94]) - by deborah.paradise.net.nz (Postfix) with ESMTP - id 7407FD2B76; Thu, 20 Dec 2001 18:49:01 +1300 (NZDT) -Received: from 127.0.0.1 (ident=unknown) by heidegger.catalyst.net.nz - with esmtp (MasqMail 0.1.15) id 16GrRk-2Ry-00; Thu, 20 Dec 2001 - 13:52:28 +1300 -Subject: Re: [HACKERS] Connection Pooling, a year later -From: Andrew McMillan -To: owensmk@earthlink.net -cc: pgsql-hackers@postgresql.org -In-Reply-To: -References: <200112180028.fBI0Sum06915@postgresql.org> - <1008739834.25608.33.camel@kant.mcmillan.net.nz> - -Content-Type: text/plain -Content-Transfer-Encoding: 7bit -X-Mailer: Evolution/1.0 (Preview Release) -Date: 20 Dec 2001 13:52:28 +1300 -Message-ID: <1008809548.24470.48.camel@kant.mcmillan.net.nz> -MIME-Version: 1.0 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Thu, 2001-12-20 at 07:22, Michael Owens wrote: -> As long as each client's call is composed of a standalone transaction, there -> is no problem with external connection pools. But what about when a client's -> transactions spans two or more calls, such as SELECT FOR UPDATE? Then pooling -> is not safe: it offers no assurance of what may be interjected into an open -> transaction between calls. For example, each is a separate call to a shared -> connection: -> -> Client A: BEGIN WORK; SELECT last_name from customer for update where ; -> -> Client B: BEGIN WORK; SELECT street from customer for update where ; -> -> Client A: update customer set lastname= where ; COMMIT -> WORK; -> -> -> Now, isn't Client B's write lock gone with Client A's commit? Yet Client A's -> lock is still hanging around. While Client B's commit will close it, Client B -> has lost the assurance of its lock, defeating the purpose of SELECT FOR -> UPDATE. -> -> If this is corrent, then external connection pools limit what you can do with -> the database to a single call. Any transaction spanning more than one call is -> unsafe, because it is not isolated from other clients sharing the same -> connection. - -Oh, I see. You are absolutely correct that client-side pooling wouldn't -work in that situation of course. - -As an application developer nobody has forced me into such a corner yet, -however. Long running transactions are something I avoid like the -plague. - -Cheers, - Andrew. --- --------------------------------------------------------------------- -Andrew @ Catalyst .Net.NZ Ltd, PO Box 11-053, Manners St, Wellington -WEB: http://catalyst.net.nz/ PHYS: Level 2, 150-154 Willis St -DDI: +64(4)916-7201 MOB: +64(21)635-694 OFFICE: +64(4)499-2267 - Are you enrolled at http://schoolreunions.co.nz/ yet? - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - diff --git a/doc/TODO.detail/prepare b/doc/TODO.detail/prepare deleted file mode 100644 index 5d66512690..0000000000 --- a/doc/TODO.detail/prepare +++ /dev/null @@ -1,1697 +0,0 @@ -From owner-pgsql-hackers@hub.org Wed Nov 18 14:40:49 1998 -Received: from hub.org (majordom@hub.org [209.47.148.200]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id OAA29743 - for ; Wed, 18 Nov 1998 14:40:36 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.1/8.9.1) with SMTP id OAA03716; - Wed, 18 Nov 1998 14:37:04 -0500 (EST) - (envelope-from owner-pgsql-hackers@hub.org) -Received: by hub.org (TLB v0.10a (1.23 tibbs 1997/01/09 00:29:32)); Wed, 18 Nov 1998 14:34:39 +0000 (EST) -Received: (from majordom@localhost) - by hub.org (8.9.1/8.9.1) id OAA03395 - for pgsql-hackers-outgoing; Wed, 18 Nov 1998 14:34:37 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from orion.SAPserv.Hamburg.dsh.de (Tpolaris2.sapham.debis.de [53.2.131.8]) - by hub.org (8.9.1/8.9.1) with SMTP id OAA03381 - for ; Wed, 18 Nov 1998 14:34:31 -0500 (EST) - (envelope-from wieck@sapserv.debis.de) -Received: by orion.SAPserv.Hamburg.dsh.de - for pgsql-hackers@hub.org - id m0zgDnj-000EBTC; Wed, 18 Nov 98 21:02 MET -Message-Id: -From: jwieck@debis.com (Jan Wieck) -Subject: Re: [HACKERS] PREPARE -To: meskes@usa.net (Michael Meskes) -Date: Wed, 18 Nov 1998 21:02:06 +0100 (MET) -Cc: pgsql-hackers@hub.org -Reply-To: jwieck@debis.com (Jan Wieck) -In-Reply-To: <19981118084843.B869@usa.net> from "Michael Meskes" at Nov 18, 98 08:48:43 am -X-Mailer: ELM [version 2.4 PL25] -Content-Type: text -Sender: owner-pgsql-hackers@postgreSQL.org -Precedence: bulk -Status: RO - -Michael Meskes wrote: - -> -> On Wed, Nov 18, 1998 at 03:23:30AM +0000, Thomas G. Lockhart wrote: -> > > I didn't get this one completly. What input do you mean? -> > -> > Just the original string/query to be prepared... -> -> I see. But wouldn't it be more useful to preprocess the query and store the -> resulting nodes instead? We don't want to parse the statement everytime a -> variable binding comes in. - - Right. A real improvement would only be to have the prepared - execution plan in the backend and just giving the parameter - values. - - I can think of the following construct: - - PREPARE optimizable-statement; - - That one will run parser/rewrite/planner, create a new memory - context with a unique identifier and saves the querytree's - and plan's in it. Parameter values are identified by the - usual $n notation. The command returns the identifier. - - EXECUTE QUERY identifier [value [, ...]]; - - then get's back the prepared plan and querytree by the id, - creates an executor context with the given values in the - parameter array and calls ExecutorRun() for them. - - The PREPARE needs to analyze the resulting parsetrees to get - the datatypes (and maybe atttypmod's) of the parameters, so - EXECUTE QUERY can convert the values into Datum's using the - types input functions. And the EXECUTE has to be handled - special in tcop (it's something between a regular query and - an utility statement). But it's not too hard to implement. - - Finally a - - FORGET QUERY identifier; - - (don't remember how the others named it) will remove the - prepared plan etc. simply by destroying the memory context - and dropping the identifier from the id->mcontext+prepareinfo - mapping. - - This all restricts the usage of PREPARE to optimizable - statements. Is it required to be able to prepare utility - statements (like CREATE TABLE or so) too? - - -Jan - --- - -#======================================================================# -# It's easier to get forgiveness for being wrong than for being right. # -# Let's break this rule - forgive me. # -#======================================== jwieck@debis.com (Jan Wieck) # - - - - -From pgsql-hackers-owner+M67@postgresql.org Tue Oct 31 19:18:16 2000 -Received: from mail.postgresql.org ([216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id TAA08916 - for ; Tue, 31 Oct 2000 19:18:15 -0500 (EST) -Received: from mail.postgresql.org ([216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id eA10IOl60635; - Tue, 31 Oct 2000 19:18:24 -0500 (EST) - (envelope-from pgsql-hackers-owner+M67@postgresql.org) -Received: from ara.zf.jcu.cz (ara.zf.jcu.cz [160.217.161.4]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id eA10H8l60400 - for ; Tue, 31 Oct 2000 19:17:08 -0500 (EST) - (envelope-from zakkr@zf.jcu.cz) -Received: from localhost (zakkr@localhost) - by ara.zf.jcu.cz (8.9.3/8.9.3/Debian 8.9.3-21) with SMTP id BAA32036; - Wed, 1 Nov 2000 01:16:42 +0100 -Date: Wed, 1 Nov 2000 01:16:42 +0100 (CET) -From: Karel Zak -To: Alfred Perlstein -cc: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Query cache import? -In-Reply-To: <20001031151144.F22110@fw.wintelcom.net> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -On Tue, 31 Oct 2000, Alfred Perlstein wrote: - -> I never saw much traffic regarding Karel's work on making stored -> proceedures: -> -> http://people.freebsd.org/~alfred/karel-pgsql.txt -> -> What happened with this? It looked pretty interesting. :( - - It's probably a little about me :-) ... well, - - My query cache is in usable state and it's efficient for all -things those motivate me to work on this. - - some basic features: - - - share parsed plans between backends in shared memory - - store plans to private backend hash table - - use parameters for stored queries - - better design for SPI - - memory usage for saved plans - - save plans "by key" - - - The current query cache code depend on 7.1 memory management. After -official 7.1 release I prepare patch with query cache+SPI (if not -hit me over head, please ..) - - All what will doing next time not depend on me, *it's on code developers*. - - For example Jan has interesting idea about caching all plans which -processing backend. But it's far future and IMHO we must go by small -steps to Oracle's funeral :-) - - If I need the query cache in the my work (typical for some web+pgsql) or -will some public interest I will continue on this, if not I freeze it. -(Exists more interesting work like http://mape.jcu.cz ... sorry of -advertising :-) - - Karel - - - - - - -From pgsql-hackers-owner+M312@postgresql.org Mon Nov 6 03:27:32 2000 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id DAA28404 - for ; Mon, 6 Nov 2000 03:27:32 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id eA68Pos51966; - Mon, 6 Nov 2000 03:25:50 -0500 (EST) - (envelope-from pgsql-hackers-owner+M312@postgresql.org) -Received: from ara.zf.jcu.cz (ara.zf.jcu.cz [160.217.161.4]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id eA68Fes50414 - for ; Mon, 6 Nov 2000 03:15:40 -0500 (EST) - (envelope-from zakkr@zf.jcu.cz) -Received: from localhost (zakkr@localhost) - by ara.zf.jcu.cz (8.9.3/8.9.3/Debian 8.9.3-21) with SMTP id JAA20862; - Mon, 6 Nov 2000 09:15:04 +0100 -Date: Mon, 6 Nov 2000 09:15:04 +0100 (CET) -From: Karel Zak -To: Christof Petig -cc: Zeugswetter Andreas SB , - The Hermit Hacker , pgsql-hackers@postgresql.org -Subject: Re: AW: [HACKERS] Re: [GENERAL] Query caching -In-Reply-To: <3A02DDFF.E8CBFCF3@wtal.de> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -On Fri, 3 Nov 2000, Christof Petig wrote: - -> Karel Zak wrote: -> -> > On Thu, 2 Nov 2000, Zeugswetter Andreas SB wrote: -> > -> > > -> > > > Well I can re-write and resubmit this patch. Add it as a -> > > > compile time option -> > > > is not bad idea. Second possibility is distribute it as patch -> > > > in the contrib -> > > > tree. And if it until not good tested not dirty with this main tree... -> > > > -> > > > Ok, I next week prepare it... -> > > -> > > One thing that worries me though is, that it extends the sql language, -> > > and there has been no discussion about the chosen syntax. -> > > -> > > Imho the standard embedded SQL syntax (prepare ...) could be a -> > > starting point. -> > -> > Yes, you are right... my PREPARE/EXECUTE is not too much ready to SQL92, -> > I some old letter I speculate about "SAVE/EXECUTE PLAN" instead -> > PREPARE/EXECUTE. But don't forget, it will *experimental* patch... we can -> > change it in future ..etc. -> > -> > Karel -> -> [Sorry, I didn't look into your patch, yet.] - - Please, read my old query cache and PREPARE/EXECUTE description... - -> What about parameters? Normally you can prepare a statement and execute it - - We have in PG parameters, see SPI, but now it's used inside backend only -and not exist statement that allows to use this feature in be<->fe. - -> using different parameters. AFAIK postgres' frontend-backend protocol is not -> designed to take parameters for statements (e.g. like result presents -> results). A very long road to go. -> By the way, I'm somewhat interested in getting this feature in. Perhaps it -> should be part of a protocol redesign (e.g. binary parameters/results). -> Handling endianness is one aspect, floats are harder (but float->ascii->float -> sometimes fails as well). - - PREPARE AS - [ USING type, ... typeN ] - [ NOSHARE | SHARE | GLOBAL ] - - EXECUTE - [ INTO [ TEMPORARY | TEMP ] [ TABLE ] new_table ] - [ USING val, ... valN ] - [ NOSHARE | SHARE | GLOBAL ] - - DEALLOCATE PREPARE - [ [ NOSHARE | SHARE | GLOBAL ]] - [ ALL | ALL INTERNAL ] - - -An example: - - -PREPARE chris_query AS SELECT * FROM pg_class WHERE relname = $1 USING text; - -EXECUTE chris_query USING 'pg_shadow'; - - - Or mean you something other? - Karel - - - - - - -From pgsql-hackers-owner+M444@postgresql.org Thu Nov 9 03:32:10 2000 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id DAA09953 - for ; Thu, 9 Nov 2000 03:32:09 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id eA98RSs11426; - Thu, 9 Nov 2000 03:27:28 -0500 (EST) - (envelope-from pgsql-hackers-owner+M444@postgresql.org) -Received: from ara.zf.jcu.cz (ara.zf.jcu.cz [160.217.161.4]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id eA98OPs11045; - Thu, 9 Nov 2000 03:24:25 -0500 (EST) - (envelope-from zakkr@zf.jcu.cz) -Received: from localhost (zakkr@localhost) - by ara.zf.jcu.cz (8.9.3/8.9.3/Debian 8.9.3-21) with SMTP id JAA08951; - Thu, 9 Nov 2000 09:23:41 +0100 -Date: Thu, 9 Nov 2000 09:23:41 +0100 (CET) -From: Karel Zak -To: Christof Petig -cc: PostgreSQL Hackers , - Michael Meskes , - Zeugswetter Andreas SB , - The Hermit Hacker -Subject: Re: AW: [HACKERS] Re: [GENERAL] Query caching -In-Reply-To: <3A096BCE.F9887955@wtal.de> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -On Wed, 8 Nov 2000, Christof Petig wrote: - -> Karel Zak wrote: -> -> > > What about parameters? Normally you can prepare a statement and execute it -> > -> > We have in PG parameters, see SPI, but now it's used inside backend only -> > and not exist statement that allows to use this feature in be<->fe. -> -> Sad. Since ecpg would certainly benefit from this. -> -> > > using different parameters. AFAIK postgres' frontend-backend protocol is not -> > > designed to take parameters for statements (e.g. like result presents -> > > results). A very long road to go. -> > > By the way, I'm somewhat interested in getting this feature in. Perhaps it -> > > should be part of a protocol redesign (e.g. binary parameters/results). -> > > Handling endianness is one aspect, floats are harder (but float->ascii->float -> > > sometimes fails as well). -> > -> > PREPARE AS -> > [ USING type, ... typeN ] -> > [ NOSHARE | SHARE | GLOBAL ] -> > -> > EXECUTE -> > [ INTO [ TEMPORARY | TEMP ] [ TABLE ] new_table ] -> > [ USING val, ... valN ] -> > [ NOSHARE | SHARE | GLOBAL ] -> > -> > DEALLOCATE PREPARE -> > [ [ NOSHARE | SHARE | GLOBAL ]] -> > [ ALL | ALL INTERNAL ] -> > -> > An example: -> > -> > PREPARE chris_query AS SELECT * FROM pg_class WHERE relname = $1 USING text; -> -> I would prefer '?' as a parameter name, since this is in the embedded sql standard -> (do you have a copy of the 94 draft? I can mail mine to you?) - - This not depend on query cache. The '$n' is PostgreSQL query parametr -keyword and is defined in standard parser. The PREPARE statement not parsing -query it's job for standard parser. - -> Also the standard says a whole lot about guessing the parameter's type. -> -> Also I vote for ?::type or type(?) or sql's cast(...) (don't know it's syntax) -> instead of abusing the using keyword. - -The postgresql executor expect types of parametrs in separate input (array). -I not sure how much expensive/executable is survey it from query. - -> > EXECUTE chris_query USING 'pg_shadow'; -> -> Great idea of yours to implement this! Since I was thinking about implementing a -> more decent schema for ecpg but had no mind to touch the backend and be-fe -> protocol (yet). -> It would be desirable to do an 'execute immediate using', since using input -> parameters would take a lot of code away from ecpg. - -By the way, PREPARE/EXECUTE is face only. More interesting in this period is -query-cache-kernel. SQL92 is really a little unlike my PREPARE/EXECUTE. - - Karel - - -From pgsql-hackers-owner+M9563@postgresql.org Thu May 31 16:31:59 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f4VKVxc26942 - for ; Thu, 31 May 2001 16:31:59 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f4VKVIE38645; - Thu, 31 May 2001 16:31:18 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9563@postgresql.org) -Received: from ara.zf.jcu.cz (ara.zf.jcu.cz [160.217.161.4]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f4VKNVE35356 - for ; Thu, 31 May 2001 16:23:31 -0400 (EDT) - (envelope-from zakkr@zf.jcu.cz) -Received: (from zakkr@localhost) - by ara.zf.jcu.cz (8.9.3/8.9.3/Debian 8.9.3-21) id WAA19957; - Thu, 31 May 2001 22:23:26 +0200 -Date: Thu, 31 May 2001 22:23:26 +0200 -From: Karel Zak -To: Roberto Abalde -cc: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Cache for query plans -Message-ID: <20010531222326.B16862@ara.zf.jcu.cz> -References: <000701c0e932$d17646c0$c6023dc8@ultra> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -User-Agent: Mutt/1.0.1i -In-Reply-To: <000701c0e932$d17646c0$c6023dc8@ultra>; from roberto.abalde@galego21.org on Wed, May 30, 2001 at 03:00:53PM -0300 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: ORr - -On Wed, May 30, 2001 at 03:00:53PM -0300, Roberto Abalde wrote: -> Hi, -> -> I need to implement a cache for query plans as part of my BSc thesis. Does -> anybody know what happened to Karel Zak's patch? -> - - - Hi, - - - my patch is on my ftp and nobody works on it, but I mean it's good -begin for some next work. I not sure with implement this experimental -patch (but usable) to official sources. For example Jan has more complex -idea about query plan cache ... but first time we must solve some -sub-problems like memory management in shared memory that is transparently -for starndard routines like copy query plan ... and Tom isn't sure with -query cache in shared memory...etc. Too much queries, but less answers :-) - - - Karel -> -> PS: Sorry for my english :( - - - Do you anytime read any my mail :-) - - - Karel - - --- - Karel Zak - http://home.zf.jcu.cz/~zakkr/ - - C, PostgreSQL, PHP, WWW, http://docs.linux.cz, http://mape.jcu.cz - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M21218@postgresql.org Fri Apr 12 04:52:19 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3C8qIS25666 - for ; Fri, 12 Apr 2002 04:52:18 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id AE2FA4769F1; Fri, 12 Apr 2002 03:54:34 -0400 (EDT) -Received: from ara.zf.jcu.cz (ara.zf.jcu.cz [160.217.161.4]) - by postgresql.org (Postfix) with ESMTP id A05A94769DC - for ; Fri, 12 Apr 2002 03:51:27 -0400 (EDT) -Received: from ara.zf.jcu.cz (LOCALHOST [127.0.0.1]) - by ara.zf.jcu.cz (8.12.1/8.12.1/Debian -5) with ESMTP id g3C7pHBK012031; - Fri, 12 Apr 2002 09:51:17 +0200 -Received: (from zakkr@localhost) - by ara.zf.jcu.cz (8.12.1/8.12.1/Debian -5) id g3C7pGum012030; - Fri, 12 Apr 2002 09:51:16 +0200 -Date: Fri, 12 Apr 2002 09:51:16 +0200 -From: Karel Zak -To: pgsql-hackers@postgresql.org -cc: Hiroshi Inoue -Subject: Re: [HACKERS] 7.3 schedule -Message-ID: <20020412095116.B6370@zf.jcu.cz> -References: <3CB52C54.4020507@freaky-namuh.com> <20020411115434.201ff92f.nconway@klamath.dyndns.org> <3CB61DAB.5010601@freaky-namuh.com> <24184.1018581907@sss.pgh.pa.us> <3CB65B49.93F2F790@tpf.co.jp> <20020412004134.5d35a2dd.nconway@klamath.dyndns.org> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.2.5i -In-Reply-To: <20020412004134.5d35a2dd.nconway@klamath.dyndns.org>; from nconway@klamath.dyndns.org on Fri, Apr 12, 2002 at 12:41:34AM -0400 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Fri, Apr 12, 2002 at 12:41:34AM -0400, Neil Conway wrote: -> On Fri, 12 Apr 2002 12:58:01 +0900 -> "Hiroshi Inoue" wrote: -> > -> > Just a confirmation. -> > Someone is working on PREPARE/EXECUTE ? -> > What about Karel's work ? - - Right question :-) - -> I am. My work is based on Karel's stuff -- at the moment I'm still -> basically working on getting Karel's patch to play nicely with -> current sources; once that's done I'll be addressing whatever -> issues are stopping the code from getting into CVS. - - My patch (qcache) for PostgreSQL 7.0 is available at - ftp://ftp2.zf.jcu.cz/users/zakkr/pg/. - - I very look forward to Neil's work on this. - - Notes: - - * It's experimental patch, but usable. All features below mentioned - works. - - * PREPARE/EXECUTE is not only SQL statements, I think good idea is - create something common and robus for query-plan caching, - beacuse there is for example SPI too. The RI triggers are based - on SPI_saveplan(). - - * My patch knows EXECUTE INTO feature: - - PREPARE foo AS SELECT * FROM pg_class WHERE relname ~~ $1 USING text; - - EXECUTE foo USING 'pg%'; <-- standard select - - EXECUTE foo INTO TEMP newtab USING 'pg%'; <-- select into - - - * The patch allows store query-planns to shared memory and is - possible EXECUTE it at more backends (over same DB) and planns - are persistent across connetions. For this feature I create special - memory context subsystem (like current aset.c, but it works with - IPC shared memory). - - This is maybe too complex solution and (maybe) sufficient is cache - query in one backend only. I know unbelief about this shared - memory solution (Tom?). - - - Karel - - - My experimental patch README (excuse my English): - - Implementation - ~~~~~~~~~~~~~~ - - The qCache allows save queryTree and queryPlan. There is available are - two space for data caching. - - LOCAL - data are cached in backend non-shared memory and data aren't - available in other backends. - - SHARE - data are cached in backend shared memory and data are - visible in all backends. - - Because size of share memory pool is limited and it is set during - postmaster start up, the qCache must remove all old planns if pool is - full. You can mark each entry as "REMOVEABLE" or "NOTREMOVEABLE". - - A removeable entry is removed if pool is full. - - A not-removeable entry must be removed via qCache_Remove() or - the other routines. The qCache not remove this entry itself. - - All records in qCache are cached (in the hash table) under some key. - The qCache knows two alternate of key --- "KEY_STRING" and "KEY_BINARY". - - The qCache API not allows access to shared memory, all cached planns that - API returns are copy to CurrentMemoryContext. All (qCache_ ) routines lock - shmem itself (exception is qCache_RemoveOldest_ShareRemoveAble()). - - - for locking is used spin lock. - - Memory management - ~~~~~~~~~~~~~~~~~ - The qCache use for qCache's shared pool its memory context independent on - standard aset/mcxt, but use compatible API --- it allows to use standard - palloc() (it is very needful for basic plan-tree operations, an example - for copyObject()). The qCache memory management is very simular to current - aset.c code. It is chunk-ed blocks too, but the block is smaller - 1024b. - - The number of blocks is available set in postmaster 'argv' via option - '-Z'. - - For plan storing is used separate MemoryContext for each plan, it - is good idea (Hiroshi's ?), bucause create new context is simple and - inexpensive and allows easy destroy (free) cached plan. This method is - used in my SPI overhaul instead TopMemoryContext feeding. - - Postmaster - ~~~~~~~~~~ - The query cache memory is init during potmaster startup. The size of - query cache pool is set via '-Z ' switch --- default - is 100 blocks where 1 block = 1024b, it is sufficient for 20-30 cached - planns. One query needs somewhere 3-10 blocks, for example query like - - PREPARE sel AS SELECT * FROM pg_class; - - needs 10Kb, because table pg_class has very much columns. - - Note: for development I add SQL function: "SELECT qcache_state();", - this routine show usage of qCache. - - SPI - ~~~ - I a little overwrite SPI save plan method and remove TopMemoryContext - "feeding". - - Standard SPI: - - SPI_saveplan() - save each plan to separate standard memory context. - - SPI_freeplan() - free plan. - - By key SPI: - - It is SPI interface for query cache and allows save planns to SHARED - or LOCAL cache 'by' arbitrary key (string or binary). Routines: - - SPI_saveplan_bykey() - save plan to query cache - - SPI_freeplan_bykey() - remove plan from query cache - - SPI_fetchplan_bykey() - fetch plan saved in query cache - - SPI_execp_bykey() - execute (via SPI) plan saved in query - cache - - - now, users can write functions that save planns to shared memory - and planns are visible in all backend and are persistent arcoss - connection. - - Example: - ~~~~~~~ - /* ---------- - * Save/exec query from shared cache via string key - * ---------- - */ - int keySize = 0; - flag = SPI_BYKEY_SHARE | SPI_BYKEY_STRING; - char *key = "my unique key"; - - res = SPI_execp_bykey(values, nulls, tcount, key, flag, keySize); - - if (res == SPI_ERROR_PLANNOTFOUND) - { - /* --- not plan in cache - must create it --- */ - - void *plan; - - plan = SPI_prepare(querystr, valnum, valtypes); - SPI_saveplan_bykey(plan, key, keySize, flag); - - res = SPI_execute(plan, values, Nulls, tcount); - } - - elog(NOTICE, "Processed: %d", SPI_processed); - - - PREPARE/EXECUTE - ~~~~~~~~~~~~~~~ - * Syntax: - - PREPARE AS - [ USING type, ... typeN ] - [ NOSHARE | SHARE | GLOBAL ] - - EXECUTE - [ INTO [ TEMPORARY | TEMP ] [ TABLE ] new_table ] - [ USING val, ... valN ] - [ NOSHARE | SHARE | GLOBAL ] - - DEALLOCATE PREPARE - [ [ NOSHARE | SHARE | GLOBAL ]] - [ ALL | ALL INTERNAL ] - - - I know that it is a little out of SQL92... (use CREATE/DROP PLAN instead - this?) --- what mean SQL standard guru? - - * Where: - - NOSHARE --- cached in local backend query cache - not accessable - from the others backends and not is persisten a across - conection. - - SHARE --- cached in shared query cache and accessable from - all backends which work over same database. - - GLOBAL --- cached in shared query cache and accessable from - all backends and all databases. - - - default is 'SHARE' - - Deallocate: - - ALL --- deallocate all users's plans - - ALL INTERNAL --- deallocate all internal plans, like planns - cached via SPI. It is needful if user - alter/drop table ...etc. - - * Parameters: - - "USING" part in the prepare statement is for datetype setting for - paremeters in the query. For example: - - PREPARE sel AS SELECT * FROM pg_class WHERE relname ~~ $1 USING text; - - EXECUTE sel USING 'pg%'; - - - * Limitation: - - - prepare/execute allow use full statement of SELECT/INSERT/DELETE/ - UPDATE. - - possible is use union, subselects, limit, ofset, select-into - - - Performance: - ~~~~~~~~~~~ - * the SPI - - - I for my tests a little change RI triggers to use SPI by_key API - and save planns to shared qCache instead to internal RI hash table. - - The RI use very simple (for parsing) queries and qCache interest is - not visible. It's better if backend very often startup and RI check - always same tables. In this situation speed go up --- 10-12%. - (This snapshot not include this RI change.) - - But all depend on how much complicate for parser is query in - trigger. - - * PREPARE/EXECUTE - - - For tests I use query that not use some table (the executor is - in boredom state), but is difficult for the parser. An example: - - SELECT 'a text ' || (10*10+(100^2))::text || ' next text ' || cast - (date_part('year', timestamp 'now') AS text ); - - - (10000 * this query): - - standard select: 54 sec - via prepare/execute: 4 sec (93% better) - - IMHO it is nod bad. - - - For standard query like: - - SELECT u.usename, r.relname FROM pg_class r, pg_user u WHERE - r.relowner = u.usesysid; - - it is with PREPARE/EXECUTE 10-20% faster. - --- - Karel Zak - http://home.zf.jcu.cz/~zakkr/ - - C, PostgreSQL, PHP, WWW, http://docs.linux.cz, http://mape.jcu.cz - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M21228@postgresql.org Fri Apr 12 10:15:34 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3CEFXS29835 - for ; Fri, 12 Apr 2002 10:15:33 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 7BFE1475A55; Fri, 12 Apr 2002 10:15:27 -0400 (EDT) -Received: from sss.pgh.pa.us (unknown [192.204.191.242]) - by postgresql.org (Postfix) with ESMTP id 5659B474E71 - for ; Fri, 12 Apr 2002 10:14:31 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g3CEEQF27238; - Fri, 12 Apr 2002 10:14:26 -0400 (EDT) -To: Karel Zak -cc: pgsql-hackers@postgresql.org, Neil Conway -Subject: Re: [HACKERS] 7.3 schedule -In-Reply-To: <20020412095116.B6370@zf.jcu.cz> -References: <3CB52C54.4020507@freaky-namuh.com> <20020411115434.201ff92f.nconway@klamath.dyndns.org> <3CB61DAB.5010601@freaky-namuh.com> <24184.1018581907@sss.pgh.pa.us> <3CB65B49.93F2F790@tpf.co.jp> <20020412004134.5d35a2dd.nconway@klamath.dyndns.org> <20020412095116.B6370@zf.jcu.cz> -Comments: In-reply-to Karel Zak - message dated "Fri, 12 Apr 2002 09:51:16 +0200" -Date: Fri, 12 Apr 2002 10:14:26 -0400 -Message-ID: <27235.1018620866@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: ORr - -Karel Zak writes: -> * The patch allows store query-planns to shared memory and is -> possible EXECUTE it at more backends (over same DB) and planns -> are persistent across connetions. For this feature I create special -> memory context subsystem (like current aset.c, but it works with -> IPC shared memory). -> This is maybe too complex solution and (maybe) sufficient is cache -> query in one backend only. I know unbelief about this shared -> memory solution (Tom?). - -Yes, that is the part that was my sticking point last time around. -(1) Because shared memory cannot be extended on-the-fly, I think it is -a very bad idea to put data structures in there without some well -thought out way of predicting/limiting their size. (2) How the heck do -you get rid of obsoleted cached plans, if the things stick around in -shared memory even after you start a new backend? (3) A shared cache -requires locking; contention among multiple backends to access that -shared resource could negate whatever performance benefit you might hope -to realize from it. - -A per-backend cache kept in local memory avoids all of these problems, -and I have seen no numbers to make me think that a shared plan cache -would achieve significantly more performance benefit than a local one. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M21233@postgresql.org Fri Apr 12 12:26:32 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3CGQVS11018 - for ; Fri, 12 Apr 2002 12:26:31 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 38DBB475B20; Fri, 12 Apr 2002 12:22:08 -0400 (EDT) -Received: from candle.pha.pa.us (216-55-132-35.dsl.san-diego.abac.net [216.55.132.35]) - by postgresql.org (Postfix) with ESMTP id 0DA70475B9E - for ; Fri, 12 Apr 2002 12:21:15 -0400 (EDT) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.11.6/8.10.1) id g3CGL4310492; - Fri, 12 Apr 2002 12:21:04 -0400 (EDT) -From: Bruce Momjian -Message-ID: <200204121621.g3CGL4310492@candle.pha.pa.us> -Subject: Re: [HACKERS] 7.3 schedule -In-Reply-To: <27235.1018620866@sss.pgh.pa.us> -To: Tom Lane -Date: Fri, 12 Apr 2002 12:21:04 -0400 (EDT) -cc: Karel Zak , pgsql-hackers@postgresql.org, - Neil Conway -X-Mailer: ELM [version 2.4ME+ PL97 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> Karel Zak writes: -> > * The patch allows store query-planns to shared memory and is -> > possible EXECUTE it at more backends (over same DB) and planns -> > are persistent across connetions. For this feature I create special -> > memory context subsystem (like current aset.c, but it works with -> > IPC shared memory). -> > This is maybe too complex solution and (maybe) sufficient is cache -> > query in one backend only. I know unbelief about this shared -> > memory solution (Tom?). -> -> Yes, that is the part that was my sticking point last time around. -> (1) Because shared memory cannot be extended on-the-fly, I think it is -> a very bad idea to put data structures in there without some well -> thought out way of predicting/limiting their size. (2) How the heck do -> you get rid of obsoleted cached plans, if the things stick around in -> shared memory even after you start a new backend? (3) A shared cache -> requires locking; contention among multiple backends to access that -> shared resource could negate whatever performance benefit you might hope -> to realize from it. -> -> A per-backend cache kept in local memory avoids all of these problems, -> and I have seen no numbers to make me think that a shared plan cache -> would achieve significantly more performance benefit than a local one. - -Certainly a shared cache would be good for apps that connect to issue a -single query frequently. In such cases, there would be no local cache -to use. - --- - Bruce Momjian | http://candle.pha.pa.us - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M21234@postgresql.org Fri Apr 12 12:44:12 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3CGiBS12385 - for ; Fri, 12 Apr 2002 12:44:12 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id AEAA7475C6C; Fri, 12 Apr 2002 12:43:17 -0400 (EDT) -Received: from barry.xythos.com (h-64-105-36-191.SNVACAID.covad.net [64.105.36.191]) - by postgresql.org (Postfix) with ESMTP id CE58C47598E - for ; Fri, 12 Apr 2002 12:42:48 -0400 (EDT) -Received: from xythos.com (localhost.localdomain [127.0.0.1]) - by barry.xythos.com (8.11.6/8.11.6) with ESMTP id g3CGgaI02920; - Fri, 12 Apr 2002 09:42:36 -0700 -Message-ID: <3CB70E7C.3090801@xythos.com> -Date: Fri, 12 Apr 2002 09:42:36 -0700 -From: Barry Lind -User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.9) Gecko/20020310 -X-Accept-Language: en-us, en -MIME-Version: 1.0 -To: Tom Lane -cc: Karel Zak , pgsql-hackers@postgresql.org, - Neil Conway -Subject: Re: [HACKERS] 7.3 schedule -References: <3CB52C54.4020507@freaky-namuh.com> <20020411115434.201ff92f.nconway@klamath.dyndns.org> <3CB61DAB.5010601@freaky-namuh.com> <24184.1018581907@sss.pgh.pa.us> <3CB65B49.93F2F790@tpf.co.jp> <20020412004134.5d35a2dd.nconway@klamath.dyndns.org> <20020412095116.B6370@zf.jcu.cz> <27235.1018620866@sss.pgh.pa.us> -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: ORr - - - -Tom Lane wrote: -> Yes, that is the part that was my sticking point last time around. -> (1) Because shared memory cannot be extended on-the-fly, I think it is -> a very bad idea to put data structures in there without some well -> thought out way of predicting/limiting their size. (2) How the heck do -> you get rid of obsoleted cached plans, if the things stick around in -> shared memory even after you start a new backend? (3) A shared cache -> requires locking; contention among multiple backends to access that -> shared resource could negate whatever performance benefit you might hope -> to realize from it. -> -> A per-backend cache kept in local memory avoids all of these problems, -> and I have seen no numbers to make me think that a shared plan cache -> would achieve significantly more performance benefit than a local one. -> - -Oracle's implementation is a shared cache for all plans. This was -introduced in Oracle 6 or 7 (I don't remember which anymore). The net -effect was that in general there was a significant performance -improvement with the shared cache. However poorly written apps can now -bring the Oracle database to its knees because of the locking issues -associated with the shared cache. For example if the most frequently -run sql statements are coded poorly (i.e. they don't use bind variables, -eg. 'select bar from foo where foobar = $1' vs. 'select bar from foo -where foobar = || somevalue' (where somevalue is likely to be -different on every call)) the shared cache doesn't help and its overhead -becomes significant. - -thanks, ---Barry - - - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M21237@postgresql.org Fri Apr 12 12:50:28 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3CGoRS13005 - for ; Fri, 12 Apr 2002 12:50:28 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 32A28475BA1; Fri, 12 Apr 2002 12:50:15 -0400 (EDT) -Received: from candle.pha.pa.us (216-55-132-35.dsl.san-diego.abac.net [216.55.132.35]) - by postgresql.org (Postfix) with ESMTP id 07F1E475892 - for ; Fri, 12 Apr 2002 12:49:43 -0400 (EDT) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.11.6/8.10.1) id g3CGnbw12950; - Fri, 12 Apr 2002 12:49:37 -0400 (EDT) -From: Bruce Momjian -Message-ID: <200204121649.g3CGnbw12950@candle.pha.pa.us> -Subject: Re: [HACKERS] 7.3 schedule -In-Reply-To: <3CB70E7C.3090801@xythos.com> -To: Barry Lind -Date: Fri, 12 Apr 2002 12:49:37 -0400 (EDT) -cc: Tom Lane , Karel Zak , - pgsql-hackers@postgresql.org, Neil Conway -X-Mailer: ELM [version 2.4ME+ PL97 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Barry Lind wrote: -> Oracle's implementation is a shared cache for all plans. This was -> introduced in Oracle 6 or 7 (I don't remember which anymore). The net -> effect was that in general there was a significant performance -> improvement with the shared cache. However poorly written apps can now -> bring the Oracle database to its knees because of the locking issues -> associated with the shared cache. For example if the most frequently -> run sql statements are coded poorly (i.e. they don't use bind variables, -> eg. 'select bar from foo where foobar = $1' vs. 'select bar from foo -> where foobar = || somevalue' (where somevalue is likely to be -> different on every call)) the shared cache doesn't help and its overhead -> becomes significant. - -This is very interesting. We have always been concerned that shared -cache invalidation could cause more of a performance problem that the -shared cache gives benefit, and it sounds like you are saying exactly -that. - --- - Bruce Momjian | http://candle.pha.pa.us - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M21238@postgresql.org Fri Apr 12 12:51:55 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3CGptS13119 - for ; Fri, 12 Apr 2002 12:51:55 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id C599D475BC6; Fri, 12 Apr 2002 12:51:47 -0400 (EDT) -Received: from sss.pgh.pa.us (unknown [192.204.191.242]) - by postgresql.org (Postfix) with ESMTP id C9F94475892 - for ; Fri, 12 Apr 2002 12:51:26 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g3CGpQF27967; - Fri, 12 Apr 2002 12:51:27 -0400 (EDT) -To: Bruce Momjian -cc: Karel Zak , pgsql-hackers@postgresql.org, - Neil Conway -Subject: Re: [HACKERS] 7.3 schedule -In-Reply-To: <200204121621.g3CGL4310492@candle.pha.pa.us> -References: <200204121621.g3CGL4310492@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Fri, 12 Apr 2002 12:21:04 -0400" -Date: Fri, 12 Apr 2002 12:51:26 -0400 -Message-ID: <27964.1018630286@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Bruce Momjian writes: -> Certainly a shared cache would be good for apps that connect to issue a -> single query frequently. In such cases, there would be no local cache -> to use. - -We have enough other problems with the single-query-per-connection -scenario that I see no reason to believe that a shared plan cache will -help materially. The correct answer for those folks will *always* be -to find a way to reuse the connection. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M21241@postgresql.org Fri Apr 12 16:25:46 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3CKPkS03078 - for ; Fri, 12 Apr 2002 16:25:46 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 9C3BD475CC6; Fri, 12 Apr 2002 16:25:42 -0400 (EDT) -Received: from klamath.dyndns.org (CPE002078144ae0.cpe.net.cable.rogers.com [24.102.202.35]) - by postgresql.org (Postfix) with ESMTP id B06D8475909 - for ; Fri, 12 Apr 2002 16:24:52 -0400 (EDT) -Received: from jiro (jiro [192.168.40.7]) - by klamath.dyndns.org (Postfix) with SMTP - id C05557013; Fri, 12 Apr 2002 16:24:53 -0400 (EDT) -Date: Fri, 12 Apr 2002 16:24:48 -0400 -From: Neil Conway -To: "Bruce Momjian" -cc: tgl@sss.pgh.pa.us, zakkr@zf.jcu.cz, pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] 7.3 schedule -Message-ID: <20020412162448.4d46d747.nconway@klamath.dyndns.org> -In-Reply-To: <200204121621.g3CGL4310492@candle.pha.pa.us> -References: <27235.1018620866@sss.pgh.pa.us> - <200204121621.g3CGL4310492@candle.pha.pa.us> -X-Mailer: Sylpheed version 0.7.4 (GTK+ 1.2.10; i386-debian-linux-gnu) -MIME-Version: 1.0 -Content-Type: text/plain; charset=US-ASCII -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: ORr - -On Fri, 12 Apr 2002 12:21:04 -0400 (EDT) -"Bruce Momjian" wrote: -> Tom Lane wrote: -> > A per-backend cache kept in local memory avoids all of these problems, -> > and I have seen no numbers to make me think that a shared plan cache -> > would achieve significantly more performance benefit than a local one. -> -> Certainly a shared cache would be good for apps that connect to issue a -> single query frequently. In such cases, there would be no local cache -> to use. - -One problem with this kind of scenario is: what to do if the plan no -longer exists for some reason? (e.g. the code that was supposed to be -PREPARE-ing your statements failed to execute properly, or the cached -plan has been evicted from shared memory, or the database was restarted, -etc.) -- EXECUTE in and of itself won't have enough information to do -anything useful. We could perhaps provide a means for an application -to test for the existence of a cached plan (in which case the -application developer will need to add logic to their application -to re-prepare the query if necessary, which could get complicated). - -Cheers, - -Neil - --- -Neil Conway -PGP Key ID: DB3C29FC - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M21242@postgresql.org Fri Apr 12 17:27:24 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3CLRNS14410 - for ; Fri, 12 Apr 2002 17:27:23 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id E05A1475D30; Fri, 12 Apr 2002 17:26:40 -0400 (EDT) -Received: from candle.pha.pa.us (216-55-132-35.dsl.san-diego.abac.net [216.55.132.35]) - by postgresql.org (Postfix) with ESMTP id 36BBB475858 - for ; Fri, 12 Apr 2002 17:25:44 -0400 (EDT) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.11.6/8.10.1) id g3CLPVa14231; - Fri, 12 Apr 2002 17:25:31 -0400 (EDT) -From: Bruce Momjian -Message-ID: <200204122125.g3CLPVa14231@candle.pha.pa.us> -Subject: Re: [HACKERS] 7.3 schedule -In-Reply-To: <20020412162448.4d46d747.nconway@klamath.dyndns.org> -To: Neil Conway -Date: Fri, 12 Apr 2002 17:25:31 -0400 (EDT) -cc: tgl@sss.pgh.pa.us, zakkr@zf.jcu.cz, pgsql-hackers@postgresql.org -X-Mailer: ELM [version 2.4ME+ PL97 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Neil Conway wrote: -> On Fri, 12 Apr 2002 12:21:04 -0400 (EDT) -> "Bruce Momjian" wrote: -> > Tom Lane wrote: -> > > A per-backend cache kept in local memory avoids all of these problems, -> > > and I have seen no numbers to make me think that a shared plan cache -> > > would achieve significantly more performance benefit than a local one. -> > -> > Certainly a shared cache would be good for apps that connect to issue a -> > single query frequently. In such cases, there would be no local cache -> > to use. -> -> One problem with this kind of scenario is: what to do if the plan no -> longer exists for some reason? (e.g. the code that was supposed to be -> PREPARE-ing your statements failed to execute properly, or the cached -> plan has been evicted from shared memory, or the database was restarted, -> etc.) -- EXECUTE in and of itself won't have enough information to do -> anything useful. We could perhaps provide a means for an application -> to test for the existence of a cached plan (in which case the -> application developer will need to add logic to their application -> to re-prepare the query if necessary, which could get complicated). - -Oh, are you thinking that one backend would do the PREPARE and another -one the EXECUTE? I can't see that working at all. I thought there -would some way to quickly test if the submitted query was in the cache, -but maybe that is too much of a performance penalty to be worth it. - --- - Bruce Momjian | http://candle.pha.pa.us - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From tgl@sss.pgh.pa.us Fri Apr 12 17:36:17 2002 -Return-path: -Received: from sss.pgh.pa.us (root@[192.204.191.242]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3CLaGS16061 - for ; Fri, 12 Apr 2002 17:36:17 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g3CLaGF10813; - Fri, 12 Apr 2002 17:36:16 -0400 (EDT) -To: Bruce Momjian -cc: Neil Conway , zakkr@zf.jcu.cz, - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] 7.3 schedule -In-Reply-To: <200204122125.g3CLPVa14231@candle.pha.pa.us> -References: <200204122125.g3CLPVa14231@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Fri, 12 Apr 2002 17:25:31 -0400" -Date: Fri, 12 Apr 2002 17:36:16 -0400 -Message-ID: <10810.1018647376@sss.pgh.pa.us> -From: Tom Lane -Status: ORr - -Bruce Momjian writes: -> Oh, are you thinking that one backend would do the PREPARE and another -> one the EXECUTE? I can't see that working at all. - -Uh, why exactly were you advocating a shared cache then? Wouldn't that -be exactly the *point* of a shared cache? - - regards, tom lane - -From pgsql-hackers-owner+M21245@postgresql.org Fri Apr 12 17:39:13 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3CLdCS16515 - for ; Fri, 12 Apr 2002 17:39:12 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id A904B475E15; Fri, 12 Apr 2002 17:39:09 -0400 (EDT) -Received: from candle.pha.pa.us (216-55-132-35.dsl.san-diego.abac.net [216.55.132.35]) - by postgresql.org (Postfix) with ESMTP id B1A3F4758DE - for ; Fri, 12 Apr 2002 17:38:25 -0400 (EDT) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.11.6/8.10.1) id g3CLcFX16347; - Fri, 12 Apr 2002 17:38:15 -0400 (EDT) -From: Bruce Momjian -Message-ID: <200204122138.g3CLcFX16347@candle.pha.pa.us> -Subject: Re: [HACKERS] 7.3 schedule -In-Reply-To: <10810.1018647376@sss.pgh.pa.us> -To: Tom Lane -Date: Fri, 12 Apr 2002 17:38:15 -0400 (EDT) -cc: Neil Conway , zakkr@zf.jcu.cz, - pgsql-hackers@postgresql.org -X-Mailer: ELM [version 2.4ME+ PL97 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> Bruce Momjian writes: -> > Oh, are you thinking that one backend would do the PREPARE and another -> > one the EXECUTE? I can't see that working at all. -> -> Uh, why exactly were you advocating a shared cache then? Wouldn't that -> be exactly the *point* of a shared cache? - -I thought it would somehow compare the SQL query string to the cached -plans and if it matched, it would use that plan rather than make a new -one. Any DDL statement would flush the cache. - --- - Bruce Momjian | http://candle.pha.pa.us - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M21246@postgresql.org Fri Apr 12 17:56:58 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3CLuvS19021 - for ; Fri, 12 Apr 2002 17:56:58 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 1B4D6475E2C; Fri, 12 Apr 2002 17:56:55 -0400 (EDT) -Received: from voyager.corporate.connx.com (unknown [209.20.248.131]) - by postgresql.org (Postfix) with ESMTP id 059F1475858 - for ; Fri, 12 Apr 2002 17:56:13 -0400 (EDT) -X-MimeOLE: Produced By Microsoft Exchange V6.0.4712.0 -content-class: urn:content-classes:message -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Subject: Re: [HACKERS] 7.3 schedule -Date: Fri, 12 Apr 2002 14:59:15 -0700 -Message-ID: -Thread-Topic: [HACKERS] 7.3 schedule -Thread-Index: AcHia2aODSpgXEd4Tluz/N0jN5fJOQAAC//w -From: "Dann Corbit" -To: "Bruce Momjian" , "Tom Lane" -cc: "Neil Conway" , , - -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Content-Transfer-Encoding: 8bit -X-MIME-Autoconverted: from quoted-printable to 8bit by candle.pha.pa.us id g3CLuvS19021 -Status: OR - ------Original Message----- -From: Bruce Momjian [mailto:pgman@candle.pha.pa.us] -Sent: Friday, April 12, 2002 2:38 PM -To: Tom Lane -Cc: Neil Conway; zakkr@zf.jcu.cz; pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] 7.3 schedule - - -Tom Lane wrote: -> Bruce Momjian writes: -> > Oh, are you thinking that one backend would do the PREPARE and -another -> > one the EXECUTE? I can't see that working at all. -> -> Uh, why exactly were you advocating a shared cache then? Wouldn't -that -> be exactly the *point* of a shared cache? - -I thought it would somehow compare the SQL query string to the cached -plans and if it matched, it would use that plan rather than make a new -one. Any DDL statement would flush the cache. ->>------------------------------------------------------------------- -Many applications will have similar queries coming from lots of -different end-users. Imagine an order-entry program where people are -ordering parts. Many of the queries might look like this: - -SELECT part_number FROM parts WHERE part_id = 12324 AND part_cost -< 12.95 - -In order to cache this query, we first parse it to replace the data -fields with paramter markers. -Then it looks like this: -SELECT part_number FROM parts WHERE part_id = ? AND part_cost < ? -{in the case of a 'LIKE' query or some other query where you can use -key information, you might have a symbolic replacement like this: -WHERE field LIKE '{D}%' to indicate that the key can be used} -Then, we make sure that the case is consistent by either capitalizing -the whole query or changing it all into lower case: -select part_number from parts where part_id = ? and part_cost < ? -Then, we run a checksum on the parameterized string. -The checksum might be used as a hash table key, where we keep some -additional information like how stale the entry is, and a pointer to -the actual parameterized SQL (in case the hash key has a collision -it would be simply wrong to run an incorrect query for obvious enough -reasons). -Now, if there are a huge number of users of the same application, it -makes sense that the probabilities of reusing queries goes up with -the number of users of the same application. Therefore, I would -advocate that the cache be kept in shared memory. - -Consider a single application with 100 different queries. Now, add -one user, ten users, 100 users, ... 10,000 users and you can see -that the benefit would be greater and greater as we add users. -<<------------------------------------------------------------------- - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M21270@postgresql.org Sat Apr 13 02:30:47 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3D6UkS07169 - for ; Sat, 13 Apr 2002 02:30:46 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 23FEC475D1E; Sat, 13 Apr 2002 02:30:38 -0400 (EDT) -Received: from mail.iinet.net.au (symphony-01.iinet.net.au [203.59.3.33]) - by postgresql.org (Postfix) with SMTP id A08A4475C6C - for ; Sat, 13 Apr 2002 02:29:37 -0400 (EDT) -Received: (qmail 11594 invoked by uid 666); 13 Apr 2002 06:29:36 -0000 -Received: from unknown (HELO SOL) (203.59.103.193) - by mail.iinet.net.au with SMTP; 13 Apr 2002 06:29:36 -0000 -Message-ID: <002301c1e2b3$804bd000$0200a8c0@SOL> -From: "Christopher Kings-Lynne" -To: "Barry Lind" , "Tom Lane" -cc: "Karel Zak" , , - "Neil Conway" -References: <3CB52C54.4020507@freaky-namuh.com> <20020411115434.201ff92f.nconway@klamath.dyndns.org> <3CB61DAB.5010601@freaky-namuh.com> <24184.1018581907@sss.pgh.pa.us> <3CB65B49.93F2F790@tpf.co.jp> <20020412004134.5d35a2dd.nconway@klamath.dyndns.org> <20020412095116.B6370@zf.jcu.cz> <27235.1018620866@sss.pgh.pa.us> <3CB70E7C.3090801@xythos.com> -Subject: Re: [HACKERS] 7.3 schedule -Date: Sat, 13 Apr 2002 14:21:50 +0800 -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook Express 5.50.4522.1200 -X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -> > thought out way of predicting/limiting their size. (2) How the heck do -> > you get rid of obsoleted cached plans, if the things stick around in -> > shared memory even after you start a new backend? (3) A shared cache -> > requires locking; contention among multiple backends to access that -> > shared resource could negate whatever performance benefit you might hope -> > to realize from it. - -I don't understand all these locking problems? Surely the only lock a -transaction would need on a stored query is one that prevents the cache -invalidation mechanism from deleting it out from under it? Surely this -means that there would be tonnes of readers on the cache - none of them -blocking each other, and the odd invalidation event that needs a complete -lock? - -Also, as for invalidation, there probably could be just two reasons to -invalidate a query in the cache. (1) The cache is running out of space and -you use LRU or something to remove old queries, or (2) someone runs ANALYZE, -in which case all cached queries should just be flushed? If they specify an -actual table to analyze, then just drop all queries on the table. - -Could this cache mechanism be used to make views fast as well? You could -cache the queries that back views on first use, and then they can follow the -above rules for flushing... - -Chris - - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M21276@postgresql.org Sat Apr 13 11:48:51 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3DFmoS27879 - for ; Sat, 13 Apr 2002 11:48:51 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 9EB81475C5C; Sat, 13 Apr 2002 11:46:52 -0400 (EDT) -Received: from sss.pgh.pa.us (unknown [192.204.191.242]) - by postgresql.org (Postfix) with ESMTP id 0FE0B474E78 - for ; Sat, 13 Apr 2002 11:46:09 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g3DFk2F15743; - Sat, 13 Apr 2002 11:46:02 -0400 (EDT) -To: "Christopher Kings-Lynne" -cc: "Barry Lind" , "Karel Zak" , - pgsql-hackers@postgresql.org, "Neil Conway" -Subject: Re: [HACKERS] 7.3 schedule -In-Reply-To: <002301c1e2b3$804bd000$0200a8c0@SOL> -References: <3CB52C54.4020507@freaky-namuh.com> <20020411115434.201ff92f.nconway@klamath.dyndns.org> <3CB61DAB.5010601@freaky-namuh.com> <24184.1018581907@sss.pgh.pa.us> <3CB65B49.93F2F790@tpf.co.jp> <20020412004134.5d35a2dd.nconway@klamath.dyndns.org> <20020412095116.B6370@zf.jcu.cz> <27235.1018620866@sss.pgh.pa.us> <3CB70E7C.3090801@xythos.com> <002301c1e2b3$804bd000$0200a8c0@SOL> -Comments: In-reply-to "Christopher Kings-Lynne" - message dated "Sat, 13 Apr 2002 14:21:50 +0800" -Date: Sat, 13 Apr 2002 11:46:01 -0400 -Message-ID: <15740.1018712761@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -"Christopher Kings-Lynne" writes: -> thought out way of predicting/limiting their size. (2) How the heck do -> you get rid of obsoleted cached plans, if the things stick around in -> shared memory even after you start a new backend? (3) A shared cache -> requires locking; contention among multiple backends to access that -> shared resource could negate whatever performance benefit you might hope -> to realize from it. - -> I don't understand all these locking problems? - -Searching the cache and inserting/deleting entries in the cache probably -have to be mutually exclusive; concurrent insertions probably won't work -either (at least not without a remarkably intelligent data structure). -Unless the cache hit rate is remarkably high, there are going to be lots -of insertions --- and, at steady state, an equal rate of deletions --- -leading to lots of contention. - -This could possibly be avoided if the cache is not used for all query -plans but only for explicitly PREPAREd plans, so that only explicit -EXECUTEs would need to search it. But that approach also makes a -sizable dent in the usefulness of the cache to begin with. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M21280@postgresql.org Sat Apr 13 14:36:34 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3DIaYS10293 - for ; Sat, 13 Apr 2002 14:36:34 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id AA151475BB1; Sat, 13 Apr 2002 14:36:17 -0400 (EDT) -Received: from klamath.dyndns.org (CPE002078144ae0.cpe.net.cable.rogers.com [24.102.202.35]) - by postgresql.org (Postfix) with ESMTP id 42993475BCB - for ; Sat, 13 Apr 2002 14:35:42 -0400 (EDT) -Received: from jiro (jiro [192.168.40.7]) - by klamath.dyndns.org (Postfix) with SMTP - id 82B84700C; Sat, 13 Apr 2002 14:35:42 -0400 (EDT) -Date: Sat, 13 Apr 2002 14:35:39 -0400 -From: Neil Conway -To: "Christopher Kings-Lynne" -cc: barry@xythos.com, tgl@sss.pgh.pa.us, zakkr@zf.jcu.cz, - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] 7.3 schedule -Message-ID: <20020413143539.7818bf7d.nconway@klamath.dyndns.org> -In-Reply-To: <002301c1e2b3$804bd000$0200a8c0@SOL> -References: - <3CB52C54.4020507@freaky-namuh.com> - <20020411115434.201ff92f.nconway@klamath.dyndns.org> - <3CB61DAB.5010601@freaky-namuh.com> - <24184.1018581907@sss.pgh.pa.us> - <3CB65B49.93F2F790@tpf.co.jp> - <20020412004134.5d35a2dd.nconway@klamath.dyndns.org> - <20020412095116.B6370@zf.jcu.cz> - <27235.1018620866@sss.pgh.pa.us> - <3CB70E7C.3090801@xythos.com> - <002301c1e2b3$804bd000$0200a8c0@SOL> -X-Mailer: Sylpheed version 0.7.4 (GTK+ 1.2.10; i386-debian-linux-gnu) -MIME-Version: 1.0 -Content-Type: text/plain; charset=US-ASCII -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Sat, 13 Apr 2002 14:21:50 +0800 -"Christopher Kings-Lynne" wrote: -> Could this cache mechanism be used to make views fast as well? - -The current PREPARE/EXECUTE code will speed up queries that use -rules of any kind, including views: the query plan is cached after -it has been rewritten as necessary, so (AFAIK) this should mean -that rules will be evaluated once when the query is PREPAREd, and -then cached for subsequent EXECUTE commands. - -Cheers, - -Neil - --- -Neil Conway -PGP Key ID: DB3C29FC - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M21309@postgresql.org Sun Apr 14 15:22:44 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3EJMiS24239 - for ; Sun, 14 Apr 2002 15:22:44 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 44BAC475E05; Sun, 14 Apr 2002 15:22:42 -0400 (EDT) -Received: from ara.zf.jcu.cz (ara.zf.jcu.cz [160.217.161.4]) - by postgresql.org (Postfix) with ESMTP id 3CD03475925 - for ; Sun, 14 Apr 2002 15:21:58 -0400 (EDT) -Received: from ara.zf.jcu.cz (LOCALHOST [127.0.0.1]) - by ara.zf.jcu.cz (8.12.1/8.12.1/Debian -5) with ESMTP id g3EJLiBK012612; - Sun, 14 Apr 2002 21:21:44 +0200 -Received: (from zakkr@localhost) - by ara.zf.jcu.cz (8.12.1/8.12.1/Debian -5) id g3EJLi3k012611; - Sun, 14 Apr 2002 21:21:44 +0200 -Date: Sun, 14 Apr 2002 21:21:44 +0200 -From: Karel Zak -To: Tom Lane -cc: Bruce Momjian , pgsql-hackers@postgresql.org, - Neil Conway -Subject: Re: [HACKERS] 7.3 schedule -Message-ID: <20020414212144.A12196@zf.jcu.cz> -References: <200204121621.g3CGL4310492@candle.pha.pa.us> <27964.1018630286@sss.pgh.pa.us> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.2.5i -In-Reply-To: <27964.1018630286@sss.pgh.pa.us>; from tgl@sss.pgh.pa.us on Fri, Apr 12, 2002 at 12:51:26PM -0400 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Fri, Apr 12, 2002 at 12:51:26PM -0400, Tom Lane wrote: -> Bruce Momjian writes: -> > Certainly a shared cache would be good for apps that connect to issue a -> > single query frequently. In such cases, there would be no local cache -> > to use. -> -> We have enough other problems with the single-query-per-connection -> scenario that I see no reason to believe that a shared plan cache will -> help materially. The correct answer for those folks will *always* be -> to find a way to reuse the connection. - - My query cache was write for 7.0. If some next release will use - pre-forked backend and after a client disconnection the backend will - still alives and waits for new client the shared cache is (maybe:-) not - needful. The current backend fork model is killer of all possible - caching. - - We have more caches. I hope persistent backend help will help to all - and I'm sure that speed will grow up with persistent backend and - persistent caches without shared memory usage. There I can agree with - Tom :-) - - Karel - --- - Karel Zak - http://home.zf.jcu.cz/~zakkr/ - - C, PostgreSQL, PHP, WWW, http://docs.linux.cz, http://mape.jcu.cz - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M21321@postgresql.org Sun Apr 14 20:40:08 2002 -Return-path: -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g3F0e7S29723 - for ; Sun, 14 Apr 2002 20:40:07 -0400 (EDT) -Received: from postgresql.org (postgresql.org [64.49.215.8]) - by postgresql.org (Postfix) with SMTP - id 3B5FB475DC5; Sun, 14 Apr 2002 20:40:03 -0400 (EDT) -Received: from localhost.localdomain (bgp01077650bgs.wanarb01.mi.comcast.net [68.40.135.112]) - by postgresql.org (Postfix) with ESMTP id 7B1D3474E71 - for ; Sun, 14 Apr 2002 20:39:18 -0400 (EDT) -Received: from localhost (camber@localhost) - by localhost.localdomain (8.11.6/8.11.6) with ESMTP id g3F0cmD10631; - Sun, 14 Apr 2002 20:38:48 -0400 -X-Authentication-Warning: localhost.localdomain: camber owned process doing -bs -Date: Sun, 14 Apr 2002 20:38:48 -0400 (EDT) -From: Brian Bruns -X-X-Sender: -To: Hannu Krosing -cc: -Subject: Re: [HACKERS] 7.3 schedule -In-Reply-To: <1018704763.1784.1.camel@taru.tm.ee> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On 13 Apr 2002, Hannu Krosing wrote: - -> On Fri, 2002-04-12 at 03:04, Brian Bruns wrote: -> > On 11 Apr 2002, Hannu Krosing wrote: -> > -> > > IIRC someone started work on modularising the network-related parts with -> > > a goal of supporting DRDA (DB2 protocol) and others in future. -> > -> > That was me, although I've been bogged down lately, and haven't been able -> > to get back to it. -> -> Has any of your modularisation work got into CVS yet ? - -No, Bruce didn't like the way I did certain things, and had some qualms -about the value of supporting multiple wire protocols IIRC. Plus the -patch was not really ready for primetime yet. - -I'm hoping to get back to it soon and sync it with the latest CVS, and -clean up the odds and ends. - -> > DRDA, btw, is not just a DB2 protocol but an opengroup -> > spec that hopefully will someday be *the* standard on the wire database -> > protocol. DRDA handles prepare/execute and is completely binary in -> > representation, among other advantages. -> -> What about extensibility - is there some predefined way of adding new -> types ? - -Not really, there is some ongoing standards activity adding some new -features. The list of supported types is pretty impressive, anything in -particular you are looking for? - -> Also, does it handle NOTIFY ? - -I don't know the answer to this. The spec is pretty huge, so it may, but -I haven't seen it. - -Even if it is supported as a secondary protocol, I believe there is alot -of value in having a single database protocol standard. (why else would I -be doing it!). I'm also looking into what it will take to do the same for -MySQL and Firebird. Hopefully they will be receptive to the idea as well. - -> ---------------- -> Hannu - -Cheers, - -Brian - - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - diff --git a/doc/TODO.detail/privileges b/doc/TODO.detail/privileges deleted file mode 100644 index 41f7f70aed..0000000000 --- a/doc/TODO.detail/privileges +++ /dev/null @@ -1,795 +0,0 @@ -From pgsql-hackers-owner@postgresql.org Thu Apr 19 15:15:30 2001 -Received: from mailout02.sul.t-online.com (mailout02.sul.t-online.com [194.25.134.17]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f3JId1301805 - for ; Thu, 19 Apr 2001 14:39:02 -0400 (EDT) - (envelope-from peter_e@gmx.net) -Received: from fwd03.sul.t-online.com - by mailout02.sul.t-online.com with smtp - id 14qGe9-0005Ng-05; Thu, 19 Apr 2001 17:47:05 +0200 -Received: from peter.localdomain (520083510237-0001@[217.80.146.53]) by fmrl03.sul.t-online.com - with esmtp id 14qGe4-2H8UKWC; Thu, 19 Apr 2001 17:47:00 +0200 -Date: Thu, 19 Apr 2001 17:58:12 +0200 (CEST) -From: Peter Eisentraut -To: PostgreSQL Development -Subject: System catalog representation of access privileges -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -X-Sender: 520083510237-0001@t-dialin.net -X-Archive-Number: 200104/704 -X-Sequence-Number: 7734 -Status: RO - -Oldtimers might recall the last thread about enhancements of the access -privilege system. See - -http://www.postgresql.org/mhonarc/pgsql-hackers/2000-05/msg01220.html - -to catch up. - -It was more or less agreed that privilege descriptors should be split out -into a separate table for better flexibility and ease of processing. The -dispute was that the old proposal wanted to store only one privilege per -row. I have devised something more efficient: - -pg_privilege ( - priobj oid, -- oid of table, column, function, etc. - prigrantor oid, -- user who granted the privilege - prigrantee oid, -- user who owns the privilege - - priselect char, -- specific privileges follow... - prihierarchy char, - priinsert char, - priupdate char, - pridelete char, - prireferences char, - priunder char, - pritrigger char, - prirule char - /* obvious extension mechanism... */ -) - -The various "char" fields would be NULL for not granted, some character -for granted, and some other character for granted with grant option (a -poor man's enum, if you will). Votes on the particular characters are -being taken. ;-) Since NULLs are stored specially, sparse pg_privilege -rows wouldn't take extra space. - -"Usage" privileges on types and other non-table objects could probably be -lumped under "priselect" (purely for internal purposes). - -For access we define system caches on these indexes: - -index ( priobj, prigrantee, priselect ) -index ( priobj, prigrantee, prihierarchy ) -index ( priobj, prigrantee, priinsert ) -index ( priobj, prigrantee, priupdate ) -index ( priobj, prigrantee, pridelete ) - -These are the privileges you usually need quickly during query processing, -the others are only needed during table creation. These indexes are not -unique (more than one grantor can grant the same privilege), but AFAICS -the syscache interface should work okay with this, since in normal -operation we don't care who granted the privilege, only whether you have -at least one. - -How does that look? - --- -Peter Eisentraut peter_e@gmx.net http://funkturm.homeip.net/~peter - - -From pgsql-hackers-owner+M7738@postgresql.org Thu Apr 19 16:28:19 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f3JKSJL13468 - for ; Thu, 19 Apr 2001 16:28:19 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f3JKRH336850; - Thu, 19 Apr 2001 16:27:17 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M7738@postgresql.org) -Received: from wallace.ece.rice.edu (wallace.ece.rice.edu [128.42.12.154]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f3JJbq325185 - for ; Thu, 19 Apr 2001 15:37:52 -0400 (EDT) - (envelope-from reedstrm@rice.edu) -Received: by rice.edu - via sendmail from stdin - id (Debian Smail3.2.0.102) - for pgsql-hackers@postgresql.org; Thu, 19 Apr 2001 14:37:48 -0500 (CDT) -Date: Thu, 19 Apr 2001 14:37:48 -0500 -From: "Ross J. Reedstrom" -To: Peter Eisentraut -cc: PostgreSQL Development -Subject: Re: [HACKERS] System catalog representation of access privileges -Message-ID: <20010419143748.A3815@rice.edu> -Mail-Followup-To: Peter Eisentraut , - PostgreSQL Development -References: -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -User-Agent: Mutt/1.0i -In-Reply-To: ; from peter_e@gmx.net on Thu, Apr 19, 2001 at 05:58:12PM +0200 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: RO - -So, this will remove the relacl field from pg_class, making pg_class -a fixed tuple-length table: that might actually speed access: there -are shortcircuits in place to speed pointer math when this is true. - -The implementation looks fine to me, as well. How are group privileges -going to be handled with this system? - -Ross - -On Thu, Apr 19, 2001 at 05:58:12PM +0200, Peter Eisentraut wrote: -> Oldtimers might recall the last thread about enhancements of the access -> privilege system. See -> -> http://www.postgresql.org/mhonarc/pgsql-hackers/2000-05/msg01220.html -> -> to catch up. -> -> It was more or less agreed that privilege descriptors should be split out -> into a separate table for better flexibility and ease of processing. The -> dispute was that the old proposal wanted to store only one privilege per -> row. I have devised something more efficient: -> -> pg_privilege ( - - - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://www.postgresql.org/search.mpl - -From pgsql-hackers-owner+M7737@postgresql.org Thu Apr 19 16:22:45 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f3JKMiL12982 - for ; Thu, 19 Apr 2001 16:22:45 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f3JKME335538; - Thu, 19 Apr 2001 16:22:14 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M7737@postgresql.org) -Received: from corvette.mascari.com (dhcp065-024-161-045.columbus.rr.com [65.24.161.45]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f3JKJK334679 - for ; Thu, 19 Apr 2001 16:19:20 -0400 (EDT) - (envelope-from mascarm@mascari.com) -Received: from mascari.com (ferrari.mascari.com [192.168.2.1]) - by corvette.mascari.com (8.9.3/8.9.3) with ESMTP id QAA25251; - Thu, 19 Apr 2001 16:12:11 -0400 -Message-ID: <3ADF47F0.82BD3A63@mascari.com> -Date: Thu, 19 Apr 2001 16:17:52 -0400 -From: Mike Mascari -Organization: Mascari Development Inc. -X-Mailer: Mozilla 4.72 [en] (X11; U; Linux 2.2.14-5.0 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Peter Eisentraut -cc: PostgreSQL Development -Subject: Re: [HACKERS] System catalog representation of access privileges -References: -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: RO - -Peter Eisentraut wrote: - -> I have devised something more efficient: -> -> pg_privilege ( -> priobj oid, -- oid of table, column, etc. -> prigrantor oid, -- user who granted the privilege -> prigrantee oid, -- user who owns the privilege -> -> priselect char, -- specific privileges follow... -> prihierarchy char, -> priinsert char, -> priupdate char, -> pridelete char, -> prireferences char, -> priunder char, -> pritrigger char, -> prirule char -> /* obvious extension mechanism... */ -> ) -> -> "Usage" privileges on types and other non-table objects could probably be -> lumped under "priselect" (purely for internal purposes). -> - -That looks quite nice. I do have 3 quick questions though. First, I -assume that the prigrantee could also be a group id? Or would this -system table represent the effective privileges granted to user via -groups? Second, one nice feature of Oracle is the ability to GRANT roles -(our groups) to other roles. So I could do: - -CREATE ROLE clerk; -GRANT SELECT on mascarm.deposits TO clerk; -GRANT UPDATE (mascarm.deposits.amount) ON mascarm.deposits TO clerk; - -CREATE ROLE banker; -GRANT clerk TO banker; - -Would any part of your design prohibit such functionality in the future? - -Finally, I'm wondering if "Usage" or "System" privileges should be -another system table. For example, one day I would like to (as in -Oracle): - -GRANT SELECT ANY TABLE TO foo WITH ADMIN; -GRANT CREATE PUBLIC SYNONYM TO foo; -GRANT DROP ANY TABLE TO foo; - -Presumably, in your design, the above would be represented by 3 records -with something like the following values: - -This would be a "SELECT ANY TABLE" privilege (w/Admin): - -NULL, grantor_oid, grantee_oid, 'S', NULL, NULL, NULL, NULL, ... - -This would be a "CREATE PUBLIC SYNONYM" privilege: - -NULL, grantor_oid, grantee_oid, 'c', NULL, NULL, NULL, NULL, ... - -That means that the system would need an index as: - -index ( prigrantee, priselect ) - -While I'm not arguing it won't work, it just doesn't "seem" clean to -shoe-horn the system privileges into the same table as the object -privileges. - -I've been wrong before though :-) - -Mike Mascari -mascarm@mascari.com - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://www.postgresql.org/search.mpl - -From pgsql-hackers-owner+M7740@postgresql.org Thu Apr 19 17:17:08 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f3JLH6L23163 - for ; Thu, 19 Apr 2001 17:17:07 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f3JLGL348132; - Thu, 19 Apr 2001 17:16:21 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M7740@postgresql.org) -Received: from mailout04.sul.t-online.com (mailout04.sul.t-online.com [194.25.134.18]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f3JLDx347396 - for ; Thu, 19 Apr 2001 17:13:59 -0400 (EDT) - (envelope-from peter_e@gmx.net) -Received: from fwd03.sul.t-online.com - by mailout04.sul.t-online.com with smtp - id 14qLkP-0001K0-04; Thu, 19 Apr 2001 23:13:53 +0200 -Received: from peter.localdomain (520083510237-0001@[217.80.146.53]) by fmrl03.sul.t-online.com - with esmtp id 14qLk8-0Y7RFAC; Thu, 19 Apr 2001 23:13:36 +0200 -Date: Thu, 19 Apr 2001 23:24:51 +0200 (CEST) -From: Peter Eisentraut -To: Mike Mascari -cc: PostgreSQL Development -Subject: Re: [HACKERS] System catalog representation of access privileges -In-Reply-To: <3ADF47F0.82BD3A63@mascari.com> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -X-Sender: 520083510237-0001@t-dialin.net -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: RO - -Mike Mascari writes: - -> That looks quite nice. I do have 3 quick questions though. First, I -> assume that the prigrantee could also be a group id? - -Yes. It was also suggested making two different grantee columns for users -and groups, but I'm not yet convinced of that. It's an option though. - -> Second, one nice feature of Oracle is the ability to GRANT roles -> (our groups) to other roles. - -Roles are not part of this deal, although I agree that they would be nice -to have eventually. I'm not sure yet whether role grants would get a -different system table, but I'm leaning there. - -> Would any part of your design prohibit such functionality in the future? - -Not that I can see. - -> Finally, I'm wondering if "Usage" or "System" privileges should be -> another system table. For example, one day I would like to (as in -> Oracle): -> -> GRANT SELECT ANY TABLE TO foo WITH ADMIN; - -ANY TABLE probably implies "any table in this schema/database", no? In -that case the grant record would refer to the oid of the schema/database. -Is there any use distinguishing between ANY TABLE and ANY VIEW? That -would make it a bit trickier. - -> GRANT CREATE PUBLIC SYNONYM TO foo; - -I'm not familiar with that above command. - -> GRANT DROP ANY TABLE TO foo; - -I'm not sold on a DROP privilege, but a CREATE privilege would be another -column. I didn't include it here because it's not in SQL. - -> While I'm not arguing it won't work, it just doesn't "seem" clean to -> shoe-horn the system privileges into the same table as the object -> privileges. - -It would make sense to split privileges on tables from privileges on -schemas/databases from privileges on, say, functions, etc. E.g., - -pg_privtable -- like proposed - -pg_privschema ( - priobj oid, prigrantor oid, prigrantee oid, - char pritarget, -- 't' = any table, 'v' = any view, ... - char priselect, - char priupdate, - /* etc */ -) - -But this would mean that a check like "can I select from this table" -would possibly require lookups in two tables. Not sure how much of a -tradeoff that is, but the "shoehorn factor" would be lower. - -Comments on this? - --- -Peter Eisentraut peter_e@gmx.net http://funkturm.homeip.net/~peter - - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M7741@postgresql.org Thu Apr 19 18:12:56 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f3JMCtL28468 - for ; Thu, 19 Apr 2001 18:12:55 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f3JMCF359250; - Thu, 19 Apr 2001 18:12:15 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M7741@postgresql.org) -Received: from sss.pgh.pa.us ([216.151.103.158]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f3JLrW355044 - for ; Thu, 19 Apr 2001 17:53:32 -0400 (EDT) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.3/8.11.3) with ESMTP id f3JLrQR22762; - Thu, 19 Apr 2001 17:53:26 -0400 (EDT) -To: Peter Eisentraut -cc: PostgreSQL Development -Subject: Re: [HACKERS] System catalog representation of access privileges -In-Reply-To: -References: -Comments: In-reply-to Peter Eisentraut - message dated "Thu, 19 Apr 2001 17:58:12 +0200" -Date: Thu, 19 Apr 2001 17:53:26 -0400 -Message-ID: <22759.987717206@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: RO - -Peter Eisentraut writes: -> pg_privilege ( -> priobj oid, -- oid of table, column, function, etc. -> prigrantor oid, -- user who granted the privilege -> prigrantee oid, -- user who owns the privilege - -What about groups? What about wildcards? We already allow -"grant to PUBLIC (all)", and it would be nice to be able to do -something like "grant to joeblow" - -> Since NULLs are stored specially, sparse pg_privilege -> rows wouldn't take extra space. - -Unless there get to be a very large number of privilege bits, it'd -probably be better to handle these columns as NOT NULL, so that a fixed -C struct record could be mapped onto the tuples. You'll notice that -most of the other system tables are done that way. - -Alternatively, since you really only need two bits per privilege, -perhaps a pair of BIT (VARYING?) fields would be a more effective -approach. BIT VARYING would have the nice property that adding a new -privilege type doesn't force initdb. - -> For access we define system caches on these indexes: - -> index ( priobj, prigrantee, priselect ) -> index ( priobj, prigrantee, prihierarchy ) -> index ( priobj, prigrantee, priinsert ) -> index ( priobj, prigrantee, priupdate ) -> index ( priobj, prigrantee, pridelete ) - -Using the privilege bits as part of the index won't work if you intend -to allow them to be null. Another objection is that this would end up -caching multiple copies of the same tuple. A third is that you can't -readily tell lack of an entry (implying you should use a default ACL -setting, which might allow the access) from presence of an entry denying -the access. A fourth is it doesn't work for groups or wildcards. - -> These indexes are not -> unique (more than one grantor can grant the same privilege), but AFAICS -> the syscache interface should work okay with this, - -Unfortunately not. The syscache stuff needs unique indexes, because it -can only return one tuple for any given request. - -I don't really believe this indexing scheme is workable. Need to think -some more. Possibly the syscache mechanism will not do, and we need a -specially indexed privilege cache instead. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M7743@postgresql.org Thu Apr 19 18:47:11 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f3JMlAL29690 - for ; Thu, 19 Apr 2001 18:47:10 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f3JMkg366031; - Thu, 19 Apr 2001 18:46:42 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M7743@postgresql.org) -Received: from corvette.mascari.com (dhcp065-024-161-045.columbus.rr.com [65.24.161.45]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f3JMZf364328 - for ; Thu, 19 Apr 2001 18:35:41 -0400 (EDT) - (envelope-from mascarm@mascari.com) -Received: from mascari.com (ferrari.mascari.com [192.168.2.1]) - by corvette.mascari.com (8.9.3/8.9.3) with ESMTP id SAA25665; - Thu, 19 Apr 2001 18:28:30 -0400 -Message-ID: <3ADF67E3.8367B467@mascari.com> -Date: Thu, 19 Apr 2001 18:34:11 -0400 -From: Mike Mascari -Organization: Mascari Development Inc. -X-Mailer: Mozilla 4.72 [en] (X11; U; Linux 2.2.14-5.0 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Peter Eisentraut -cc: PostgreSQL Development -Subject: Re: [HACKERS] System catalog representation of access privileges -References: -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: RO - -First, let me say that just because Oracle does it this way doesn't make -it better but... - -Oracle divides privileges into 2 categories: - -Object privileges -System privileges - -The Object privileges are the ones you describe. And I agree -fundamentally with your design. Although I would have (a) used a bitmask -for the privileges and (b) have an additional bitmask which determines -whether or not the Grantee could turn around and grant the same -permission to someone else: - -pg_objprivs { - priobj oid, - prigrantor oid, - prigrantee oid, - priprivileges int4, - priadmin int4 -}; - -Where priprivileges is a bitmask for: - -0 ALTER - tables, sequences -1 DELETE - tables, views -2 EXECUTE - procedures, functions -3 INDEX - tables -4 INSERT - tables, views -5 REFERENCES - tables -6 SELECT - tables, views, sequences -7 UPDATE - tables, views -8 HIERARCHY - tables -9 UNDER - tables - -And the priadmin is a bitmask to determine whether or not the Grantee -could grant the same privilege to another user. Since these are Object -privileges, 32 bits should be enough (and also 640K RAM ;-)). - -The System privileges are privileges granted to a user or role (a.k.a -group) which are not associated with any particular object. This is one -area where I think PostgreSQL needs a lot of work and thought, -particularly with schemas coming down the road. Some example Oracle -System privileges are: - -Typical User Privileges: ------------------------ - -CREATE SESSION - Allows the user to connect -CREATE SEQUENCE - Allows the user to create sequences in his schema -CREATE SYNONYM - Allows the user to create private synonyms -CREATE TABLE - Allows the user to create a table in his schema -CREATE TRIGGER - Allows the user to create triggers on tables in his -schema -CREATE VIEW - Allows the user to create views in his schema - -Typical Power-User Privileges: ------------------------------ - -ALTER ANY INDEX - Allows user to alter an index in *any* schema -ALTER ANY PROCEDURE - Allows user to alter a procedure in *any* schema -ALTER ANY TABLE - Allows user to alter a table in *any* schema -... -CREATE ANY TABLE - Allows user to create a table in *any* schema -COMMENT ANY TABLE - Allows user to document any table in *any* schema -... - -Typical DBA-Only Privileges: ---------------------------- - -ALTER USER - Allows user to change password, quotas, etc. for *any* user -CREATE USER - Allows user to create a new user -DROP USER - Allows user to drop a new user -GRANT ANY PRIVILEGE - Allows user to grant any privilege to any user -ANALYZE ANY - Allows user to analyze any table in *any* schema - -There are, in fact, many, many more System Privileges that Oracle -defines. You may want someone to connect to a database and query one -table and that's it. Or you may want someone to have no other abilities -except to document the database design via the great COMMENT ON command -;-), etc. - -So for System Privileges, I would have something like: - -pg_sysprivs { - prigrantee oid, - priprivilege oid, - prigroup bool, - priadmin bool -}; - -So each System privilege granted to a user (or group) would be its own -record. The priprivilege would be the OID of one of the many System -privileges defined in the same way types are defined, if prigroup is -false. If prigroup is true, however, then priprivilege is not a System -privilege, but a group id. And then PostgreSQL will have to examine the -privileges recursively for that group. Of course, you might not want to -allow for the GRANTing of group privileges to other groups initially, -which simplifies the implementation tremendously. But its a neat (if not -complicated) Oracle-ism. - -Unfortunately, this means that the permission might require > 2 lookups. -But these lookups are only if the previous lookup failed: - -SELECT * FROM employees.foo; - -1. Am I a member of the employees schema? Yes -> Done -2. Have I been GRANTed the Object Privilege of: - SELECT on employees.foo? Yes -> Done -3. Have I been GRANTed the System Privilege of: - SELECT ANY TABLE? Yes -> Done - -So the number of lookups does potentially increase, but only for those -users that have been granted access through greater and greater layers -of authority. - -I just think that each new feature added to PostgreSQL opens up a very -large can of worms. Schemas are such a feature and the security system -should be prepared for it. - -FWIW, - -Mike Mascari -mascarm@mascari.com - - -Peter Eisentraut wrote: -> -> -> It would make sense to split privileges on tables from privileges on -> schemas/databases from privileges on, say, functions, etc. E.g., -> -> pg_privtable -- like proposed -> -> pg_privschema ( -> priobj oid, prigrantor oid, prigrantee oid, -> char pritarget, -- 't' = any table, 'v' = any view, ... -> char priselect, -> char priupdate, -> /* etc */ -> ) -> -> But this would mean that a check like "can I select from this table" -> would possibly require lookups in two tables. Not sure how much of a -> tradeoff that is, but the "shoehorn factor" would be lower. -> -> Comments on this? -> -> -- -> Peter Eisentraut peter_e@gmx.net http://funkturm.homeip.net/~peter - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M7759@postgresql.org Fri Apr 20 11:25:24 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f3KFPNs14733 - for ; Fri, 20 Apr 2001 11:25:23 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f3KFNa389638; - Fri, 20 Apr 2001 11:23:36 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M7759@postgresql.org) -Received: from mailout00.sul.t-online.com (mailout00.sul.t-online.com [194.25.134.16]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f3KFLL388804 - for ; Fri, 20 Apr 2001 11:21:21 -0400 (EDT) - (envelope-from peter_e@gmx.net) -Received: from fwd04.sul.t-online.com - by mailout00.sul.t-online.com with smtp - id 14qchk-0001xH-01; Fri, 20 Apr 2001 17:20:16 +0200 -Received: from peter.localdomain (520083510237-0001@[212.185.245.11]) by fmrl04.sul.t-online.com - with esmtp id 14qchV-2L4flAC; Fri, 20 Apr 2001 17:20:01 +0200 -Date: Fri, 20 Apr 2001 17:31:16 +0200 (CEST) -From: Peter Eisentraut -To: Tom Lane -cc: PostgreSQL Development -Subject: Re: [HACKERS] System catalog representation of access privileges -In-Reply-To: <22759.987717206@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -X-Sender: 520083510237-0001@t-dialin.net -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: RO - -Tom Lane writes: - -> Peter Eisentraut writes: -> > pg_privilege ( -> > priobj oid, -- oid of table, column, function, etc. -> > prigrantor oid, -- user who granted the privilege -> > prigrantee oid, -- user who owns the privilege -> -> What about groups? - -Either integrated into prigrantee or another column prigroupgrantee. One -of these would always be zero or null, that's why I'm not sure if this -isn't a waste of space. - -> What about wildcards? We already allow -> "grant to PUBLIC (all)", and it would be nice to be able to do -> something like "grant to joeblow" - -Public would be prigrantee == 0. About , how is this -defined? If it is "everything I own and will ever own" then I suppose -priobj == 0. Although I admit I have never seen this kind of privilege -before. It's probably better to set up a group for that. - -> Alternatively, since you really only need two bits per privilege, -> perhaps a pair of BIT (VARYING?) fields would be a more effective -> approach. BIT VARYING would have the nice property that adding a new -> privilege type doesn't force initdb. - -This would be tricky to index, I think. - -> I don't really believe this indexing scheme is workable. Need to think -> some more. Possibly the syscache mechanism will not do, and we need a -> specially indexed privilege cache instead. - -Maybe just an index on (object, grantee) and walk through that with an -index scan. This is done in some other places as well (triggers, I -recall), but the performance is probably not too exciting. - -However, last I looked at the syscache I figured that it would be -perfectly capable of handling non-unique indexes if there only was an API -to retrieve those values. Storing and finding the entries didn't seem to -be the problem. Need to look there, probably. - --- -Peter Eisentraut peter_e@gmx.net http://funkturm.homeip.net/~peter - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M7763@postgresql.org Fri Apr 20 13:05:45 2001 -Return-path: -Received: from west.navpoint.com (root@west.navpoint.com [207.106.42.13]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f3KH5jE01810 - for ; Fri, 20 Apr 2001 13:05:45 -0400 (EDT) -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by west.navpoint.com (8.11.3/8.10.1) with ESMTP id f3KGc8129062 - for ; Fri, 20 Apr 2001 12:38:08 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f3KGbY311283; - Fri, 20 Apr 2001 12:37:34 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M7763@postgresql.org) -Received: from sss.pgh.pa.us ([216.151.103.158]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f3KGZp310688 - for ; Fri, 20 Apr 2001 12:35:51 -0400 (EDT) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.3/8.11.3) with ESMTP id f3KGZlR26837; - Fri, 20 Apr 2001 12:35:47 -0400 (EDT) -To: Peter Eisentraut -cc: PostgreSQL Development -Subject: Re: [HACKERS] System catalog representation of access privileges -In-Reply-To: -References: -Comments: In-reply-to Peter Eisentraut - message dated "Fri, 20 Apr 2001 17:31:16 +0200" -Date: Fri, 20 Apr 2001 12:35:46 -0400 -Message-ID: <26834.987784546@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: RO - -Peter Eisentraut writes: ->> Alternatively, since you really only need two bits per privilege, ->> perhaps a pair of BIT (VARYING?) fields would be a more effective ->> approach. BIT VARYING would have the nice property that adding a new ->> privilege type doesn't force initdb. - -> This would be tricky to index, I think. - -True, but I don't believe that making the privilege value part of the -index is useful. - -> Maybe just an index on (object, grantee) and walk through that with an -> index scan. This is done in some other places as well (triggers, I -> recall), but the performance is probably not too exciting. - -I agree, that'd be slower than we'd like. It needs to be cached somehow. - -The major problem is that you'd need multiple index scans: after failing -to find anything for (table, currentuser) you'd also need to try -(table, 0) for PUBLIC and (table, G) for every group G that contains the -current user. Not to mention the scan to find out which groups those are. - -It gets rapidly worse if you want to allow any wildcarding on the object ---- for example, if a privilege record attached to a schema can allow -access to the tables therein, which I think should be possible. You'd -have to repeat the above for each possible priobject that might relate -to the target object. - -I think this might be tolerable for getting the info in the first place, -but the final results really need to be cached. That's why I was -wondering about a special "privilege cache". - -> However, last I looked at the syscache I figured that it would be -> perfectly capable of handling non-unique indexes if there only was an API -> to retrieve those values. - -Yes, it's an API problem more than anything else. Invent away, if that -seems like a needed component. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - diff --git a/doc/TODO.detail/replication b/doc/TODO.detail/replication deleted file mode 100644 index d4bf4b1fe2..0000000000 --- a/doc/TODO.detail/replication +++ /dev/null @@ -1,6241 +0,0 @@ -From goran@kirra.net Mon Dec 20 14:30:54 1999 -Received: from villa.bildbasen.se (villa.bildbasen.se [193.45.225.97]) - by candle.pha.pa.us (8.9.0/8.9.0) with SMTP id PAA29058 - for ; Mon, 20 Dec 1999 15:30:17 -0500 (EST) -Received: (qmail 2485 invoked from network); 20 Dec 1999 20:29:53 -0000 -Received: from a112.dial.kiruna.se (HELO kirra.net) (193.45.238.12) - by villa.bildbasen.se with SMTP; 20 Dec 1999 20:29:53 -0000 -Sender: goran -Message-ID: <385E9192.226CC37D@kirra.net> -Date: Mon, 20 Dec 1999 21:29:06 +0100 -From: Goran Thyni -Organization: kirra.net -X-Mailer: Mozilla 4.6 [en] (X11; U; Linux 2.2.13 i586) -X-Accept-Language: sv, en -MIME-Version: 1.0 -To: Bruce Momjian -CC: "neil d. quiogue" , - PostgreSQL-development -Subject: Re: [HACKERS] Re: QUESTION: Replication -References: <199912201508.KAA20572@candle.pha.pa.us> -Content-Type: text/plain; charset=iso-8859-1 -Content-Transfer-Encoding: 8bit -Status: OR - -Bruce Momjian wrote: -> We need major work in this area, or at least a plan and an FAQ item. -> We are getting major questions on this, and I don't know enough even to -> make an FAQ item telling people their options. - -My 2 cents, or 2 ören since I'm a Swede, on this: - -It is pretty simple to build a replication with pg_dump, transfer, -empty replic and reload. -But if we want "live replicas" we better base our efforts on a -mechanism using WAL-logs to rollforward the replicas. - -regards, ------------------ -Göran Thyni -On quiet nights you can hear Windows NT reboot! - -From owner-pgsql-hackers@hub.org Fri Dec 24 10:01:18 1999 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id LAA11295 - for ; Fri, 24 Dec 1999 11:01:17 -0500 (EST) -Received: from hub.org (hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.10 $) with ESMTP id KAA20310 for ; Fri, 24 Dec 1999 10:39:18 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id KAA61760; - Fri, 24 Dec 1999 10:31:13 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Fri, 24 Dec 1999 10:30:48 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id KAA58879 - for pgsql-hackers-outgoing; Fri, 24 Dec 1999 10:29:51 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from bocs170n.black-oak.COM ([38.149.137.131]) - by hub.org (8.9.3/8.9.3) with ESMTP id KAA58795 - for ; Fri, 24 Dec 1999 10:29:00 -0500 (EST) - (envelope-from DWalker@black-oak.com) -From: DWalker@black-oak.com -To: pgsql-hackers@postgreSQL.org -Subject: [HACKERS] database replication -Date: Fri, 24 Dec 1999 10:27:59 -0500 -Message-ID: -X-Priority: 3 (Normal) -X-MIMETrack: Serialize by Router on notes01n/BOCS(Release 5.0.1|July 16, 1999) at 12/24/99 - 10:28:01 AM -MIME-Version: 1.0 -MIME-Version: 1.0 -Content-Type: text/html; charset=ISO-8859-1 -Content-Transfer-Encoding: quoted-printable -Sender: owner-pgsql-hackers@postgreSQL.org -Status: OR - -

I've been toying with the idea of implementing database replication for = -the last few days.  The system I'm proposing will be a seperate progra= -m which can be run on any machine and will most likely be implemented in Py= -thon.  What I'm looking for at this point are gaping holes in my think= -ing/logic/etc.  Here's what I'm thinking...

 

1) I wa= -nt to make this program an additional layer over PostgreSQL.  I really= - don't want to hack server code if I can get away with it.  At this po= -int I don't feel I need to.

2) The replication system will need to ad= -d at least one field to each table in each database that needs to be replic= -ated.  This field will be a date/time stamp which identifies the "= -;last update" of the record.  This field will be called PGR=5FTIM= -E for lack of a better name.  Because this field will be used from wit= -hin programs and triggers it can be longer so as to not mistake it for a us= -er field.

3) For each table to be replicated the replication system w= -ill programatically add one plpgsql function and trigger to modify the PGR= -=5FTIME field on both UPDATEs and INSERTs.  The name of this function = -and trigger will be along the lines of <table=5Fname>=5Freplication= -=5Fupdate=5Ftrigger and <table=5Fname>=5Freplication=5Fupdate=5Ffunct= -ion.  The function is a simple two-line chunk of code to set the field= - PGR=5FTIME equal to NOW.  The trigger is called before each insert/up= -date.  When looking at the Docs I see that times are stored in Zulu (G= -T) time.  Because of this I don't have to worry about time zones and t= -he like.  I need direction on this part (such as "hey dummy, look= - at page N of file X.").

4) At this point we have tables which c= -an, at a basic level, tell the replication system when they were last updat= -ed.

5) The replication system will have a database of its own to reco= -rd the last replication event, hold configuration, logs, etc.  I'd pre= -fer to store the configuration in a PostgreSQL table but it could just as e= -asily be stored in a text file on the filesystem somewhere.

6) To han= -dle replication I basically check the local "last replication time&quo= -t; and compare it against the remote PGR=5FTIME fields.  If the remote= - PGR=5FTIME is greater than the last replication time then change the local= - copy of the database, otherwise, change the remote end of the database. &n= -bsp;At this point I don't have a way to know WHICH field changed between th= -e two replicas so either I do ROW level replication or I check each field. = - I check PGR=5FTIME to determine which field is the most current. &nbs= -p;Some fine tuning of this process will have to occur no doubt.

7) Th= -e commandline utility, fired off by something like cron, could run several = -times during the day -- command line parameters can be implemented to say P= -USH ALL CHANGES TO SERVER A, or PULL ALL CHANGES FROM SERVER B.

 = -;

Questions/Concerns:

1) How far do I go with this?  Do I = -start manhandling the system catalogs (pg=5F* tables)?

2) As to #2 an= -d #3 above, I really don't like tools automagically changing my tables but = -at this point I don't see a way around it.  I guess this is where the = -testing comes into play.

3) Security: the replication app will have t= -o have pretty good rights to the database so it can add the nessecary funct= -ions and triggers, modify table schema, etc.  

 

&nbs= -p; So, any "you're insane and should run home to momma" comments?= -

 

              Damond= -

= - -************ - -From owner-pgsql-hackers@hub.org Fri Dec 24 18:31:03 1999 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id TAA26244 - for ; Fri, 24 Dec 1999 19:31:02 -0500 (EST) -Received: from hub.org (hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.10 $) with ESMTP id TAA12730 for ; Fri, 24 Dec 1999 19:30:05 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id TAA57851; - Fri, 24 Dec 1999 19:23:31 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Fri, 24 Dec 1999 19:22:54 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id TAA57710 - for pgsql-hackers-outgoing; Fri, 24 Dec 1999 19:21:56 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from Mail.austin.rr.com (sm2.texas.rr.com [24.93.35.55]) - by hub.org (8.9.3/8.9.3) with ESMTP id TAA57680 - for ; Fri, 24 Dec 1999 19:21:25 -0500 (EST) - (envelope-from ELOEHR@austin.rr.com) -Received: from austin.rr.com ([24.93.40.248]) by Mail.austin.rr.com with Microsoft SMTPSVC(5.5.1877.197.19); - Fri, 24 Dec 1999 18:12:50 -0600 -Message-ID: <38640E2D.75136600@austin.rr.com> -Date: Fri, 24 Dec 1999 18:22:05 -0600 -From: Ed Loehr -X-Mailer: Mozilla 4.7 [en] (X11; U; Linux 2.2.12-20smp i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: DWalker@black-oak.com -CC: pgsql-hackers@postgreSQL.org -Subject: Re: [HACKERS] database replication -References: -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Sender: owner-pgsql-hackers@postgreSQL.org -Status: OR - -DWalker@black-oak.com wrote: - -> 6) To handle replication I basically check the local "last -> replication time" and compare it against the remote PGR_TIME -> fields. If the remote PGR_TIME is greater than the last replication -> time then change the local copy of the database, otherwise, change -> the remote end of the database. At this point I don't have a way to -> know WHICH field changed between the two replicas so either I do ROW -> level replication or I check each field. I check PGR_TIME to -> determine which field is the most current. Some fine tuning of this -> process will have to occur no doubt. - -Interesting idea. I can see how this might sync up two databases -somehow. For true replication, however, I would always want every -replicated database to be, at the very least, internally consistent -(i.e., referential integrity), even if it was a little behind on -processing transactions. In this method, its not clear how -consistency is every achieved/guaranteed at any point in time if the -input stream of changes is continuous. If the input stream ceased, -then I can see how this approach might eventually catch up and totally -resync everything, but it looks *very* computationally expensive. - -But I might have missed something. How would internal consistency be -maintained? - - -> 7) The commandline utility, fired off by something like cron, could -> run several times during the day -- command line parameters can be -> implemented to say PUSH ALL CHANGES TO SERVER A, or PULL ALL CHANGES -> FROM SERVER B. - -My two cents is that, while I can see this kind of database syncing as -valuable, this is not the kind of "replication" I had in mind. This -may already possible by simply copying the database. What replication -means to me is a live, continuously streaming sequence of updates from -one database to another where the replicated database is always -internally consistent, available for read-only queries, and never "too -far" out of sync with the source/primary database. - -What does replication mean to others? - -Cheers, -Ed Loehr - - - -************ - -From owner-pgsql-hackers@hub.org Fri Dec 24 21:31:10 1999 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id WAA02578 - for ; Fri, 24 Dec 1999 22:31:09 -0500 (EST) -Received: from hub.org (hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.10 $) with ESMTP id WAA16641 for ; Fri, 24 Dec 1999 22:18:56 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id WAA89135; - Fri, 24 Dec 1999 22:11:12 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Fri, 24 Dec 1999 22:10:56 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id WAA89019 - for pgsql-hackers-outgoing; Fri, 24 Dec 1999 22:09:59 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from bocs170n.black-oak.COM ([38.149.137.131]) - by hub.org (8.9.3/8.9.3) with ESMTP id WAA88957; - Fri, 24 Dec 1999 22:09:11 -0500 (EST) - (envelope-from dwalker@black-oak.com) -Received: from gcx80 ([151.196.99.113]) - by bocs170n.black-oak.COM (Lotus Domino Release 5.0.1) - with SMTP id 1999122422080835:6 ; - Fri, 24 Dec 1999 22:08:08 -0500 -Message-ID: <001b01bf4e9e$647287d0$af63a8c0@walkers.org> -From: "Damond Walker" -To: -Cc: -References: <38640E2D.75136600@austin.rr.com> -Subject: Re: [HACKERS] database replication -Date: Fri, 24 Dec 1999 22:07:55 -0800 -MIME-Version: 1.0 -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook Express 5.00.2314.1300 -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 -X-MIMETrack: Itemize by SMTP Server on notes01n/BOCS(Release 5.0.1|July 16, 1999) at 12/24/99 - 10:08:09 PM, - Serialize by Router on notes01n/BOCS(Release 5.0.1|July 16, 1999) at 12/24/99 - 10:08:11 PM, - Serialize complete at 12/24/99 10:08:11 PM -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; - charset="iso-8859-1" -Sender: owner-pgsql-hackers@postgreSQL.org -Status: OR - -> -> Interesting idea. I can see how this might sync up two databases -> somehow. For true replication, however, I would always want every -> replicated database to be, at the very least, internally consistent -> (i.e., referential integrity), even if it was a little behind on -> processing transactions. In this method, its not clear how -> consistency is every achieved/guaranteed at any point in time if the -> input stream of changes is continuous. If the input stream ceased, -> then I can see how this approach might eventually catch up and totally -> resync everything, but it looks *very* computationally expensive. -> - - What's the typical unit of work for the database? Are we talking about -update transactions which span the entire DB? Or are we talking about -updating maybe 1% or less of the database everyday? I'd think it would be -more towards the latter than the former. So, yes, this process would be -computationally expensive but how many records would actually have to be -sent back and forth? - -> But I might have missed something. How would internal consistency be -> maintained? -> - - Updates that occur at site A will be moved to site B and vice versa. -Consistency would be maintained. The only problem that I can see right off -the bat would be what if site A and site B made changes to a row and then -site C was brought into the picture? Which one wins? - - Someone *has* to win when it comes to this type of thing. You really -DON'T want to start merging row changes... - -> -> My two cents is that, while I can see this kind of database syncing as -> valuable, this is not the kind of "replication" I had in mind. This -> may already possible by simply copying the database. What replication -> means to me is a live, continuously streaming sequence of updates from -> one database to another where the replicated database is always -> internally consistent, available for read-only queries, and never "too -> far" out of sync with the source/primary database. -> - - Sounds like you're talking about distributed transactions to me. That's -an entirely different subject all-together. What you describe can be done -by copying a database...but as you say, this would only work in a read-only -situation. - - - Damond - - -************ - -From owner-pgsql-hackers@hub.org Sat Dec 25 16:35:07 1999 -Received: from hub.org (hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id RAA28890 - for ; Sat, 25 Dec 1999 17:35:05 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id RAA86997; - Sat, 25 Dec 1999 17:29:10 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Sat, 25 Dec 1999 17:28:09 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id RAA86863 - for pgsql-hackers-outgoing; Sat, 25 Dec 1999 17:27:11 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from mtiwmhc08.worldnet.att.net (mtiwmhc08.worldnet.att.net [204.127.131.19]) - by hub.org (8.9.3/8.9.3) with ESMTP id RAA86798 - for ; Sat, 25 Dec 1999 17:26:34 -0500 (EST) - (envelope-from pgsql@rkirkpat.net) -Received: from [192.168.3.100] ([12.74.72.219]) - by mtiwmhc08.worldnet.att.net (InterMail v03.02.07.07 118-134) - with ESMTP id <19991225222554.VIOL28505@[12.74.72.219]>; - Sat, 25 Dec 1999 22:25:54 +0000 -Date: Sat, 25 Dec 1999 15:25:47 -0700 (MST) -From: Ryan Kirkpatrick -X-Sender: rkirkpat@excelsior.rkirkpat.net -To: DWalker@black-oak.com -cc: pgsql-hackers@postgreSQL.org -Subject: Re: [HACKERS] database replication -In-Reply-To: -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Sender: owner-pgsql-hackers@postgreSQL.org -Status: OR - -On Fri, 24 Dec 1999 DWalker@black-oak.com wrote: - -> I've been toying with the idea of implementing database replication -> for the last few days. - - I too have been thinking about this some over the last year or -two, just trying to find a quick and easy way to do it. I am not so -interested in replication, as in synchronization, as in between a desktop -machine and a laptop, so I can keep the databases on each in sync with -each other. For this sort of purpose, both the local and remote databases -would be "idle" at the time of syncing. - -> 2) The replication system will need to add at least one field to each -> table in each database that needs to be replicated. This field will be -> a date/time stamp which identifies the "last update" of the record. -> This field will be called PGR_TIME for lack of a better name. -> Because this field will be used from within programs and triggers it -> can be longer so as to not mistake it for a user field. - - How about a single, seperate table with the fields of 'database', -'tablename', 'oid', 'last_changed', that would store the same data as your -PGR_TIME field. It would be seperated from the actually data tables, and -therefore would be totally transparent to any database interface -applications. The 'oid' field would hold each row's OID, a nice, unique -identification number for the row, while the other fields would tell which -table and database the oid is in. Then this table can be compared with the -this table on a remote machine to quickly find updates and changes, then -each differences can be dealt with in turn. - -> 3) For each table to be replicated the replication system will -> programatically add one plpgsql function and trigger to modify the -> PGR_TIME field on both UPDATEs and INSERTs. The name of this function -> and trigger will be along the lines of -> _replication_update_trigger and -> _replication_update_function. The function is a simple -> two-line chunk of code to set the field PGR_TIME equal to NOW. The -> trigger is called before each insert/update. When looking at the Docs -> I see that times are stored in Zulu (GT) time. Because of this I -> don't have to worry about time zones and the like. I need direction -> on this part (such as "hey dummy, look at page N of file X."). - - I like this idea, better than any I have come up with yet. Though, -how are you going to handle DELETEs? - -> 6) To handle replication I basically check the local "last replication -> time" and compare it against the remote PGR_TIME fields. If the -> remote PGR_TIME is greater than the last replication time then change -> the local copy of the database, otherwise, change the remote end of -> the database. At this point I don't have a way to know WHICH field -> changed between the two replicas so either I do ROW level replication -> or I check each field. I check PGR_TIME to determine which field is -> the most current. Some fine tuning of this process will have to occur -> no doubt. - - Yea, this is indeed the sticky part, and would indeed require some -fine-tunning. Basically, the way I see it, is if the two timestamps for a -single row do not match (or even if the row and therefore timestamp is -missing on one side or the other altogether): - local ts > remote ts => Local row is exported to remote. - remote ts > local ts => Remote row is exported to local. - local ts > last sync time && no remote ts => - Local row is inserted on remote. - local ts < last sync time && no remote ts => - Local row is deleted. - remote ts > last sync time && no local ts => - Remote row is inserted on local. - remote ts < last sync time && no local ts => - Remote row is deleted. -where the synchronization process is running on the local machine. By -exported, I mean the local values are sent to the remote machine, and the -row on that remote machine is updated to the local values. How does this -sound? - -> 7) The commandline utility, fired off by something like cron, could -> run several times during the day -- command line parameters can be -> implemented to say PUSH ALL CHANGES TO SERVER A, or PULL ALL CHANGES -> FROM SERVER B. - - Or run manually for my purposes. Also, maybe follow it -with a vacuum run on both sides for all databases, as this is going to -potenitally cause lots of table changes that could stand with a cleanup. - -> 1) How far do I go with this? Do I start manhandling the system catalogs (pg_* tables)? - - Initially, I would just stick to user table data... If you have -changes in triggers and other meta-data/executable code, you are going to -want to make syncs of that stuff manually anyway. At least I would want -to. - -> 2) As to #2 and #3 above, I really don't like tools automagically -> changing my tables but at this point I don't see a way around it. I -> guess this is where the testing comes into play. - - Hence the reason for the seperate table with just a row's -identification and last update time. Only modifications to the synced -database is the update trigger, which should be pretty harmless. - -> 3) Security: the replication app will have to have pretty good rights -> to the database so it can add the nessecary functions and triggers, -> modify table schema, etc. - - Just run the sync program as the postgres super user, and there -are no problems. :) - -> So, any "you're insane and should run home to momma" comments? - - No, not at all. Though it probably should be remaned from -replication to synchronization. The former is usually associated with a -continuous stream of updates between the local and remote databases, so -they are almost always in sync, and have a queuing ability if their -connection is loss for span of time as well. Very complex and difficult to -implement, and would require hacking server code. :( Something only Sybase -and Oracle have (as far as I know), and from what I have seen of Sybase's -replication server support (dated by 5yrs) it was a pain to setup and get -running correctly. - The latter, synchronization, is much more managable, and can still -be useful, especially when you have a large database you want in two -places, mainly for read only purposes at one end or the other, but don't -want to waste the time/bandwidth to move and load the entire database each -time it changes on one end or the other. Same idea as mirroring software -for FTP sites, just transfers the changes, and nothing more. - I also like the idea of using Python. I have been using it -recently for some database interfaces (to PostgreSQL of course :), and it -is a very nice language to work with. Some worries about performance of -the program though, as python is only an interpreted lanuage, and I have -yet to really be impressed with the speed of execution of my database -interfaces yet. - Anyway, it sound like a good project, and finally one where I -actually have a clue of what is going on, and the skills to help. So, if -you are interested in pursing this project, I would be more than glad to -help. TTYL. - ---------------------------------------------------------------------------- -| "For to me to live is Christ, and to die is gain." | -| --- Philippians 1:21 (KJV) | ---------------------------------------------------------------------------- -| Ryan Kirkpatrick | Boulder, Colorado | http://www.rkirkpat.net/ | ---------------------------------------------------------------------------- - - - -************ - -From owner-pgsql-hackers@hub.org Sun Dec 26 08:31:09 1999 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id JAA17976 - for ; Sun, 26 Dec 1999 09:31:07 -0500 (EST) -Received: from hub.org (hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.10 $) with ESMTP id JAA23337 for ; Sun, 26 Dec 1999 09:28:36 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id JAA90738; - Sun, 26 Dec 1999 09:21:58 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Sun, 26 Dec 1999 09:19:19 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id JAA90498 - for pgsql-hackers-outgoing; Sun, 26 Dec 1999 09:18:21 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from bocs170n.black-oak.COM ([38.149.137.131]) - by hub.org (8.9.3/8.9.3) with ESMTP id JAA90452 - for ; Sun, 26 Dec 1999 09:17:54 -0500 (EST) - (envelope-from dwalker@black-oak.com) -Received: from vmware98 ([151.196.99.113]) - by bocs170n.black-oak.COM (Lotus Domino Release 5.0.1) - with SMTP id 1999122609164808:7 ; - Sun, 26 Dec 1999 09:16:48 -0500 -Message-ID: <002201bf4fb3$623f0220$b263a8c0@vmware98.walkers.org> -From: "Damond Walker" -To: "Ryan Kirkpatrick" -Cc: -Subject: Re: [HACKERS] database replication -Date: Sun, 26 Dec 1999 10:10:41 -0500 -MIME-Version: 1.0 -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook Express 4.72.3110.1 -X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3110.3 -X-MIMETrack: Itemize by SMTP Server on notes01n/BOCS(Release 5.0.1|July 16, 1999) at 12/26/99 - 09:16:51 AM, - Serialize by Router on notes01n/BOCS(Release 5.0.1|July 16, 1999) at 12/26/99 - 09:16:54 AM, - Serialize complete at 12/26/99 09:16:54 AM -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; - charset="iso-8859-1" -Sender: owner-pgsql-hackers@postgreSQL.org -Status: OR - -> -> I too have been thinking about this some over the last year or ->two, just trying to find a quick and easy way to do it. I am not so ->interested in replication, as in synchronization, as in between a desktop ->machine and a laptop, so I can keep the databases on each in sync with ->each other. For this sort of purpose, both the local and remote databases ->would be "idle" at the time of syncing. -> - - I don't think it would matter if the databases are idle or not to be -honest with you. At any single point in time when you replicate I'd figure -that the database would be in a consistent state. So, you should be able to -replicate (or sync) a remote database that is in use. After all, you're -getting a snapshot of the database as it stands at 8:45 PM. At 8:46 PM it -may be totally different...but the next time syncing takes place those -changes would appear in your local copy. - - The one problem you may run into is if the remote host is running a -large batch process. It's very likely that you will get 50% of their -changes when you replicate...but then again, that's why you can schedule the -event to work around such things. - -> How about a single, seperate table with the fields of 'database', ->'tablename', 'oid', 'last_changed', that would store the same data as your ->PGR_TIME field. It would be seperated from the actually data tables, and ->therefore would be totally transparent to any database interface ->applications. The 'oid' field would hold each row's OID, a nice, unique ->identification number for the row, while the other fields would tell which ->table and database the oid is in. Then this table can be compared with the ->this table on a remote machine to quickly find updates and changes, then ->each differences can be dealt with in turn. -> - - The problem with OID's is that they are unique at the local level but if -you try and use them between servers you can run into overlap. Also, if a -database is under heavy use this table could quickly become VERY large. Add -indexes to this table to help performance and you're taking up even more -disk space. - - Using the PGR_TIME field with an index will allow us to find rows which -have changed VERY quickly. All we need to do now is somehow programatically -find the primary key for a table so the person setting up replication (or -syncing) doesn't have to have an indepth knowledge of the schema in order to -setup a syncing schedule. - -> -> I like this idea, better than any I have come up with yet. Though, ->how are you going to handle DELETEs? -> - - Oops...how about defining a trigger for this? With deletion I guess we -would have to move a flag into another table saying we deleted record 'X' -with this primary key from this table. - -> -> Yea, this is indeed the sticky part, and would indeed require some ->fine-tunning. Basically, the way I see it, is if the two timestamps for a ->single row do not match (or even if the row and therefore timestamp is ->missing on one side or the other altogether): -> local ts > remote ts => Local row is exported to remote. -> remote ts > local ts => Remote row is exported to local. -> local ts > last sync time && no remote ts => -> Local row is inserted on remote. -> local ts < last sync time && no remote ts => -> Local row is deleted. -> remote ts > last sync time && no local ts => -> Remote row is inserted on local. -> remote ts < last sync time && no local ts => -> Remote row is deleted. ->where the synchronization process is running on the local machine. By ->exported, I mean the local values are sent to the remote machine, and the ->row on that remote machine is updated to the local values. How does this ->sound? -> - - The replication part will be the most complex...that much is for -certain... - - I've been writing systems in Lotus Notes/Domino for the last year or so -and I've grown quite spoiled with what it can do in regards to replication. -It's not real-time but you have to gear your applications to this type of -thing (it's possible to create documents, fire off email to notify people of -changes and have the email arrive before the replicated documents do). -Replicating large Notes/Domino databases takes quite a while....I don't see -any kind of replication or syncing running in a blink of an eye. - - Having said that, a good algo will have to be written to cut down on -network traffic and to keep database conversations down to a minimum. This -will be appreciated by people with low bandwidth connections I'm sure -(dial-ups, fractional T1's, etc). - -> Or run manually for my purposes. Also, maybe follow it ->with a vacuum run on both sides for all databases, as this is going to ->potenitally cause lots of table changes that could stand with a cleanup. -> - - What would a vacuum do to a system being used by many people? - -> No, not at all. Though it probably should be remaned from ->replication to synchronization. The former is usually associated with a ->continuous stream of updates between the local and remote databases, so ->they are almost always in sync, and have a queuing ability if their ->connection is loss for span of time as well. Very complex and difficult to ->implement, and would require hacking server code. :( Something only Sybase ->and Oracle have (as far as I know), and from what I have seen of Sybase's ->replication server support (dated by 5yrs) it was a pain to setup and get ->running correctly. - - It could probably be named either way...but the one thing I really don't -want to do is start hacking server code. The PostgreSQL people have enough -to do without worrying about trying to meld anything I've done to their -server. :) - - Besides, I like the idea of having it operate as a stand-alone product. -The only PostgreSQL feature we would require would be triggers and -plpgsql...what was the earliest version of PostgreSQL that supported -plpgsql? Even then I don't see the triggers being that complex to boot. - -> I also like the idea of using Python. I have been using it ->recently for some database interfaces (to PostgreSQL of course :), and it ->is a very nice language to work with. Some worries about performance of ->the program though, as python is only an interpreted lanuage, and I have ->yet to really be impressed with the speed of execution of my database ->interfaces yet. - - The only thing we'd need for Python is the Python extensions for -PostgreSQL...which in turn requires libpq and that's about it. So, it -should be able to run on any platform supported by Python and libpq. Using -TK for the interface components will require NT people to get additional -software from the 'net. At least it did with older version of Windows -Python. Unix folks should be happy....assuming they have X running on the -machine doing the replication or syncing. Even then I wrote a curses based -Python interface awhile back which allows buttons, progress bars, input -fields, etc (I called it tinter and it's available at -http://iximd.com/~dwalker). It's a simple interface and could probably be -cleaned up a bit but it works. :) - -> Anyway, it sound like a good project, and finally one where I ->actually have a clue of what is going on, and the skills to help. So, if ->you are interested in pursing this project, I would be more than glad to ->help. TTYL. -> - - - That would be a Good Thing. Have webspace somewhere? If I can get -permission from the "powers that be" at the office I could host a website on -our (Domino) webserver. - - Damond - - -************ - -From owner-pgsql-hackers@hub.org Sun Dec 26 19:11:48 1999 -Received: from hub.org (hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id UAA26661 - for ; Sun, 26 Dec 1999 20:11:46 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id UAA14959; - Sun, 26 Dec 1999 20:08:15 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Sun, 26 Dec 1999 20:07:27 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id UAA14820 - for pgsql-hackers-outgoing; Sun, 26 Dec 1999 20:06:28 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from mtiwmhc02.worldnet.att.net (mtiwmhc02.worldnet.att.net [204.127.131.37]) - by hub.org (8.9.3/8.9.3) with ESMTP id UAA14749 - for ; Sun, 26 Dec 1999 20:05:39 -0500 (EST) - (envelope-from rkirkpat@rkirkpat.net) -Received: from [192.168.3.100] ([12.74.72.56]) - by mtiwmhc02.worldnet.att.net (InterMail v03.02.07.07 118-134) - with ESMTP id <19991227010506.WJVW1914@[12.74.72.56]>; - Mon, 27 Dec 1999 01:05:06 +0000 -Date: Sun, 26 Dec 1999 18:05:02 -0700 (MST) -From: Ryan Kirkpatrick -X-Sender: rkirkpat@excelsior.rkirkpat.net -To: Damond Walker -cc: pgsql-hackers@postgreSQL.org -Subject: Re: [HACKERS] database replication -In-Reply-To: <002201bf4fb3$623f0220$b263a8c0@vmware98.walkers.org> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Sender: owner-pgsql-hackers@postgreSQL.org -Status: OR - -On Sun, 26 Dec 1999, Damond Walker wrote: - -> > How about a single, seperate table with the fields of 'database', -> >'tablename', 'oid', 'last_changed', that would store the same data as your -> >PGR_TIME field. It would be seperated from the actually data tables, and -... -> The problem with OID's is that they are unique at the local level but if -> you try and use them between servers you can run into overlap. - - Yea, forgot about that point, but became dead obvious once you -mentioned it. Boy, I feel stupid now. :) - -> Using the PGR_TIME field with an index will allow us to find rows which -> have changed VERY quickly. All we need to do now is somehow programatically -> find the primary key for a table so the person setting up replication (or -> syncing) doesn't have to have an indepth knowledge of the schema in order to -> setup a syncing schedule. - - Hmm... Yea, maybe look to see which field(s) has a primary, unique -index on it? Then use those field(s) as a primary key. Just require that -any table to be synchronized to have some set of fields that uniquely -identify each row. Either that, or add another field to each table with -our own, cross system consistent, identification system. Don't know which -would be more efficient and easier to work with. - The former could potentially get sticky if it takes a lots of -fields to generate a unique key value, but has the smallest effect on the -table to be synced. The latter could be difficult to keep straight between -systems (local vs. remote), and would require a trigger on inserts to -generate a new, unique id number, that does not exist locally or -remotely (nasty issue there), but would remove the uniqueness -requirement. - -> Oops...how about defining a trigger for this? With deletion I guess we -> would have to move a flag into another table saying we deleted record 'X' -> with this primary key from this table. - - Or, according to my logic below, if a row is missing on one side -or the other, then just compare the remaining row's timestamp to the last -synchronization time (stored in a seperate table/db elsewhere). The -results of the comparsion and the state of row existences tell one if the -row was inserted or deleted since the last sync, and what should be done -to perform the sync. - -> > Yea, this is indeed the sticky part, and would indeed require some -> >fine-tunning. Basically, the way I see it, is if the two timestamps for a -> >single row do not match (or even if the row and therefore timestamp is -> >missing on one side or the other altogether): -> > local ts > remote ts => Local row is exported to remote. -> > remote ts > local ts => Remote row is exported to local. -> > local ts > last sync time && no remote ts => -> > Local row is inserted on remote. -> > local ts < last sync time && no remote ts => -> > Local row is deleted. -> > remote ts > last sync time && no local ts => -> > Remote row is inserted on local. -> > remote ts < last sync time && no local ts => -> > Remote row is deleted. -> >where the synchronization process is running on the local machine. By -> >exported, I mean the local values are sent to the remote machine, and the -> >row on that remote machine is updated to the local values. How does this -> >sound? - -> Having said that, a good algo will have to be written to cut down on -> network traffic and to keep database conversations down to a minimum. This -> will be appreciated by people with low bandwidth connections I'm sure -> (dial-ups, fractional T1's, etc). - - Of course! In reflection, the assigned identification number I -mentioned above might be the best then, instead of having to transfer the -entire set of key fields back and forth. - -> What would a vacuum do to a system being used by many people? - - Probably lock them out of tables while they are vacuumed... Maybe -not really required in the end, possibly optional? - -> It could probably be named either way...but the one thing I really don't -> want to do is start hacking server code. The PostgreSQL people have enough -> to do without worrying about trying to meld anything I've done to their -> server. :) - - Yea, they probably would appreciate that. They already have enough -on thier plate for 7.x as it is! :) - -> Besides, I like the idea of having it operate as a stand-alone product. -> The only PostgreSQL feature we would require would be triggers and -> plpgsql...what was the earliest version of PostgreSQL that supported -> plpgsql? Even then I don't see the triggers being that complex to boot. - - No, provided that we don't do the identification number idea -(which the more I think about it, probably will not work). As for what -version support plpgsql, I don't know, one of the more hard-core pgsql -hackers can probably tell us that. - -> The only thing we'd need for Python is the Python extensions for -> PostgreSQL...which in turn requires libpq and that's about it. So, it -> should be able to run on any platform supported by Python and libpq. - - Of course. If it ran on NT as well as Linux/Unix, that would be -even better. :) - -> Unix folks should be happy....assuming they have X running on the -> machine doing the replication or syncing. Even then I wrote a curses -> based Python interface awhile back which allows buttons, progress -> bars, input fields, etc (I called it tinter and it's available at -> http://iximd.com/~dwalker). It's a simple interface and could -> probably be cleaned up a bit but it works. :) - - Why would we want any type of GUI (X11 or curses) for this sync -program. I imagine just a command line program with a few options (local -machine, remote machine, db name, etc...), and nothing else. - Though I will take a look at your curses interface, as I have been -wanting to make a curses interface to a few db interfaces I have, in a -simple as manner as possible. - -> That would be a Good Thing. Have webspace somewhere? If I can get -> permission from the "powers that be" at the office I could host a website on -> our (Domino) webserver. - - Yea, I got my own web server (www.rkirkpat.net) with 1GB+ of disk -space available, sitting on a decent speed DSL. Even can setup of a -virtual server if we want (i.e. pgsync.rkirkpat.net :). CVS repository, -email lists, etc... possible with some effort (and time). - So, where should we start? TTYL. - - PS. The current pages on my web site are very out of date at the -moment (save for the pgsql information). I hope to have updated ones up -within the week. - ---------------------------------------------------------------------------- -| "For to me to live is Christ, and to die is gain." | -| --- Philippians 1:21 (KJV) | ---------------------------------------------------------------------------- -| Ryan Kirkpatrick | Boulder, Colorado | http://www.rkirkpat.net/ | ---------------------------------------------------------------------------- - - -************ - -From owner-pgsql-hackers@hub.org Mon Dec 27 12:33:32 1999 -Received: from hub.org (hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id NAA24817 - for ; Mon, 27 Dec 1999 13:33:29 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id NAA53391; - Mon, 27 Dec 1999 13:29:02 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Mon, 27 Dec 1999 13:28:38 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id NAA53248 - for pgsql-hackers-outgoing; Mon, 27 Dec 1999 13:27:40 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from gtv.ca (h139-142-238-17.cg.fiberone.net [139.142.238.17]) - by hub.org (8.9.3/8.9.3) with ESMTP id NAA53170 - for ; Mon, 27 Dec 1999 13:26:40 -0500 (EST) - (envelope-from aaron@genisys.ca) -Received: from stilborne (24.67.90.252.ab.wave.home.com [24.67.90.252]) - by gtv.ca (8.9.3/8.8.7) with SMTP id MAA01200 - for ; Mon, 27 Dec 1999 12:36:39 -0700 -From: "Aaron J. Seigo" -To: pgsql-hackers@hub.org -Subject: Re: [HACKERS] database replication -Date: Mon, 27 Dec 1999 11:23:19 -0700 -X-Mailer: KMail [version 1.0.28] -Content-Type: text/plain -References: <199912271135.TAA10184@netrinsics.com> -In-Reply-To: <199912271135.TAA10184@netrinsics.com> -MIME-Version: 1.0 -Message-Id: <99122711245600.07929@stilborne> -Content-Transfer-Encoding: 8bit -Sender: owner-pgsql-hackers@postgreSQL.org -Status: OR - -hi.. - -> Before anyone starts implementing any database replication, I'd strongly -> suggest doing some research, first: -> -> http://sybooks.sybase.com:80/onlinebooks/group-rs/rsg1150e/rs_admin/@Generic__BookView;cs=default;ts=default - -good idea, but perhaps sybase isn't the best study case.. here's some extremely -detailed online coverage of Oracle 8i's replication, from the oracle online -library: - -http://bach.towson.edu/oracledocs/DOC/server803/A54651_01/toc.htm - --- -Aaron J. Seigo -Sys Admin - -************ - -From owner-pgsql-hackers@hub.org Thu Dec 30 08:01:09 1999 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id JAA10317 - for ; Thu, 30 Dec 1999 09:01:08 -0500 (EST) -Received: from hub.org (hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.10 $) with ESMTP id IAA02365 for ; Thu, 30 Dec 1999 08:37:10 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id IAA87902; - Thu, 30 Dec 1999 08:34:22 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Thu, 30 Dec 1999 08:32:24 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id IAA85771 - for pgsql-hackers-outgoing; Thu, 30 Dec 1999 08:31:27 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from sandman.acadiau.ca (dcurrie@sandman.acadiau.ca [131.162.129.111]) - by hub.org (8.9.3/8.9.3) with ESMTP id IAA85234 - for ; Thu, 30 Dec 1999 08:31:10 -0500 (EST) - (envelope-from dcurrie@sandman.acadiau.ca) -Received: (from dcurrie@localhost) - by sandman.acadiau.ca (8.8.8/8.8.8/Debian/GNU) id GAA18698; - Thu, 30 Dec 1999 06:30:58 -0400 -From: Duane Currie -Message-Id: <199912301030.GAA18698@sandman.acadiau.ca> -Subject: Re: [HACKERS] database replication -In-Reply-To: from "DWalker@black-oak.com" at "Dec 24, 99 10:27:59 am" -To: DWalker@black-oak.com -Date: Thu, 30 Dec 1999 10:30:58 +0000 (AST) -Cc: pgsql-hackers@postgresql.org -X-Mailer: ELM [version 2.4ME+ PL39 (25)] -MIME-Version: 1.0 -Content-Type: text/plain; charset=US-ASCII -Content-Transfer-Encoding: 7bit -Sender: owner-pgsql-hackers@postgresql.org -Status: OR - -Hi Guys, - -Now for one of my REALLY rare posts. -Having done a little bit of distributed data systems, I figured I'd -pitch in a couple cents worth. - -> 2) The replication system will need to add at least one field to each -> table in each database that needs to be re plicated.  This -> field will be a date/time stamp which identifies the " last -> update" of the record.  This field will be called PGR_TIME -> for la ck of a better name.  Because this field will be used -> from within programs and triggers it can be longer so as to not -> mistake it for a user field. - -I just started reading this thread, but I figured I'd throw in a couple -suggestions for distributed data control (a few idioms I've had to -deal with b4): - - Never use time (not reliable from system to system). Use - a version number of some sort that can stay consistent across - all replicas - - This way, if a system's time is or goes out of wack, it doesn't - cause your database to disintegrate, and it's easier to track - conflicts (see below. If using time, the algorithm gets - nightmarish) - - - On an insert, set to version 1 - - - On an update, version++ - - - On a delete, mark deleted, and add a delete stub somewhere for the - replicator process to deal with in sync'ing the databases. - - - If two records have the same version but different data, there's - a conflict. A few choices: - 1. Pick one as the correct one (yuck!! invisible data loss) - 2. Store both copies, pick one as current, and alert - database owner of the conflict, so they can deal with - it "manually." - 3. If possible, some conflicts can be merged. If a disjoint - set of fields were changed in each instance, these changes - may both be applied and the record merged. (Problem: - takes a lot more space. Requires a version number for - every field, or persistent storage of some old records. - However, this might help the "which fields changed" issue - you were talking about in #6) - - - A unique id across all systems should exist (or something that - effectively simulates a unique id. Maybe a composition of the - originating oid (from the insert) and the originating database - (oid of the database's record?) might do it. Store this as - an extra field in every record. - - (Two extra fieldss so far: 'unique id' and 'version') - -I do like your approach: triggers and a separate process. (Maintainable!! :) - -Anyway, just figured I'd throw in a few suggestions, -Duane - -************ - -From owner-pgsql-patches@hub.org Sun Jan 2 23:01:38 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id AAA16274 - for ; Mon, 3 Jan 2000 00:01:28 -0500 (EST) -Received: from hub.org (hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.10 $) with ESMTP id XAA02655 for ; Sun, 2 Jan 2000 23:45:55 -0500 (EST) -Received: from hub.org (hub.org [216.126.84.1]) - by hub.org (8.9.3/8.9.3) with ESMTP id XAA13828; - Sun, 2 Jan 2000 23:40:47 -0500 (EST) - (envelope-from owner-pgsql-patches@hub.org) -Received: by hub.org (TLB v0.10a (1.23 tibbs 1997/01/09 00:29:32)); Sun, 02 Jan 2000 23:38:34 +0000 (EST) -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id XAA13624 - for pgsql-patches-outgoing; Sun, 2 Jan 2000 23:37:36 -0500 (EST) - (envelope-from owner-pgsql-patches@postgreSQL.org) -Received: from falla.videotron.net (falla.videotron.net [205.151.222.106]) - by hub.org (8.9.3/8.9.3) with ESMTP id XAA13560 - for ; Sun, 2 Jan 2000 23:37:02 -0500 (EST) - (envelope-from P.Marchesso@Videotron.ca) -Received: from Videotron.ca ([207.253.210.234]) - by falla.videotron.net (Sun Internet Mail Server sims.3.5.1999.07.30.00.05.p8) - with ESMTP id <0FNQ000TEST8VI@falla.videotron.net> for pgsql-patches@postgresql.org; Sun, - 2 Jan 2000 23:37:01 -0500 (EST) -Date: Sun, 02 Jan 2000 23:39:23 -0500 -From: Philippe Marchesseault -Subject: [PATCHES] Distributed PostgreSQL! -To: pgsql-patches@postgreSQL.org -Message-id: <387027FB.EB88D757@Videotron.ca> -MIME-version: 1.0 -X-Mailer: Mozilla 4.51 [en] (X11; I; Linux 2.2.11 i586) -Content-type: MULTIPART/MIXED; BOUNDARY="Boundary_(ID_GeYGc69fE1/bkYLTPwOGFg)" -X-Accept-Language: en -Sender: owner-pgsql-patches@postgreSQL.org -Precedence: bulk -Status: ORr - -This is a multi-part message in MIME format. - ---Boundary_(ID_GeYGc69fE1/bkYLTPwOGFg) -Content-type: text/plain; charset=us-ascii -Content-transfer-encoding: 7bit - -Hi all! - -Here is a small patch to make postgres a distributed database. By -distributed I mean that you can have the same copy of the database on N -different machines and keep them all in sync. -It does not improve performances unless you distribute your clients in a -sensible manner. It does not allow you to do parallel selects. - -The support page is : pages.infinit.net/daemon and soon to be in -english. - -The patch was tested with RedHat Linux 6.0 on Intel with kernel 2.2.11. -Only two machines where used so i'm not competely sure that it works -with more than two. -But it should- - -I would like to know if somebody else is interested in this otherwise -i'm probably not gonna keep it growing. So please reply me to my e-mail -(P.Marchesso@videotron.ca) to give me an idea of the amount of people -interested in this. - -Thanks all. - -Philippe Marchesseault - --- -It's not the size of the dog in the fight, -but the size of the fight in the dog. - -Archie Griffen - - - ---Boundary_(ID_GeYGc69fE1/bkYLTPwOGFg) -Content-type: application/octet-stream; name=replicator-0.1.tgz -Content-disposition: attachment; filename=replicator-0.1.tgz -Content-transfer-encoding: base64 - -H4sIAOeZbzgAA+w8a3PayLL7Nara/9Dx3iRAME/brO11tjDGDjc2OIBvTm5OihLSAFoLiUgi -LGfX//12z0MaAX7UOU72nLpW7cagmenp6enp9xCwmetYZuQHxR++1QM7pVq5DD8AQG2vxv+W -d3b4X/mUsKVUrdbKO7XKLrZWdkqVH2D3m2GkPfMwMgOAH2Z+GI0DFt7ejwW3Nv7nPkGy/xfm -NRs5Lnv0Ocql0l6pdOv+l8u1XbH/e7W90m6NWsu7pR+g9OiYbHj+n+9/q904vzppwhFst6A4 -D4NiGFjF2Tj84vJPjme5c5vFra5vma5sl21FwzBdFw7AGwb+NQtgKv8mvAXYZWw6HnayXGZ6 -d3cVXQ7AeBZMYXukOquv0/TXZKhhGLJrjEvBAvlhYjwbW5b2/r8ycu1Z2B6P7SFs+8lMYRQ4 -s/irodA8UJOvwZ3eCXeahqu+GtqyD7SFrEFPNW2aQAO07c6+wPb52m65ztB49pNAQKfZzIys -CR7DA+OZ7YxGm5hgaFrXzLOLkeXPiuqgFHzXfnhnC96A+rJX2C3wWf9q5n96dPn/zbaH5L+U -95vkf6VUS/T/Xq2Crbt7ldqT/P8eD+6NWS6V8+VSzXgDxdzlBfTnDE6YBZWfcSMOqtWDnX0o -7+/v54rY4yelELaKE3/KYqYpaoykZNeW3v+XcBkWo+UMZcHkzVqDM7M2vZ6GY/G6mHuOmHEM -jL3arrn3cxU/PnO8SJmQan72fs6C5SH22sNeu/m9/T3qWcwBAuiZEfw36hYoQ7l6UKrg6pD9 -SiXqATlojSCaMECOiNiUeVFIHwP8s3CiCZjw6vWrPPXw0t3AQkqEMAr8qQREzZpIngW+xcKw -IFppEepxRpD5QggPSDB740+lz3B0RBNl/+C9Ya0VXsGrQ9GWXjM2ndbPe03eeEP/MDdkf9zS -td+90npy+iJme7V9a29/3/gFnskH4CVHIQoYG7hOGOXBZvSvabmdrywIHJtlD43t7W0x0V3P -gyDVSjsmegH5WnWfID7j/6wxZvWgXDso7SSMSX0APuC2oPKRG4DThRHR2IleheD5Ee5hyFxm -Rcnm8aEgQcTbQThuv8F9nZqe3UeuhedH0Lg4GfSa581GH16+XKGo2C5cf69/0R9c9M4AefdQ -viM2nhLvI93L6mU4wy2NRhnRyH5HQmy9fhFu5VNbnlXd5R+HDwg9m/6MWZRpd06ag3fNj3lo -XTYGjW6z3oc/obS3t5fNw0vslAfEZtBr/W8zD6Us/FKKUQWYIdX9ILN1EY57SLVTE81/+wC2 -4lk5cwgWURshGOWvlltPz+M8mtiOTdjHnuNu/69cre0I/69Sq5XLpSq1Vit7T/r/ezzFnP4Y -/YkTQivk8nOGhrw5ZvgZtSZ6eP4ijIWe43vKnO+9PwfbjMyhGTJAF880bIdk13AeMRuY99UJ -fI8kbcEwGv5sGTjjSQSZRpbLboDLieM6M5SNF2ZgTVBNMnPuRoZABTXnODCn4JB6ZSjc/VG0 -MAN2CEt/Dhaq8oAl06GcB5TXRXRrpj46M0t6Mfds9NxoQRELpiH4Qsmfta/gjHksMF24nA9x -VXDuWMwLmWHivPQmnOAChkve/ZRm78nZ4dRHqJwKh8DQNsAJUIGFRJWKISeQ0PKABkAGKYgI -B+DPaFAWsVyCi7ojHldYX7BORkeYHBN/JvcDF7Zw0OseMkDOHM3dvIE94UOr/7Zz1Yd6+yN8 -qHe79Xb/4yE3X3xsZV+l6eJMcRsRLC4mML1oiUQxLprdxlvsXz9unbf6Hwnt01a/3ez14LTT -hTpc1rv9VuPqvN6Fy6vuZafXLKC6Y4QQM24nJ4wQ0tRHqtksQgWDZpDxETcvRJTQg5yYX0lV -W8z5igiZaEvNlg/ZI9f3xsIuizS6HZK2R0Wfh0XgIENE/vruGcnuodL0rEIedvehz5AmDC5d -02KwDb05Da9WS3k4Rj6nrhd1gFKlXC5vl6ulWh6uevWCkTo+RcNAIyQJBRxAf0J8HdJGyxCC -Iw+XMAlxBeh8R7gJ4RS3lO+NhwSbiiNGJiXSxPNtZqBZqT8CXKhW6HMmpI6qpUCTI9Vxwvbr -8goWwdzz0LoA31uFS8Cmoi9KPOROvn9tDlrABIQmV4FNBI0vwrQsNkNb2fI9Dy0sRB93GnIE -/wOZzAsmrGkSJfTF9gnKwsRl0wwEThuKJ5060QmnSQiKJBla2pmLeq/f7MJxt/MO/1x2Ow1k -02Yva5Ahp7kQke345ECkXrnOcPUdWVrpd2gYeatD0SEJfeuaRen3Hosc/L/oeOv9aXn01rjF -D9roBW30gZK3W4l/ZRhffQeF7O9ONPDwZLjLDLlEhOWpjXYeWnjCyNxquH5IG56QmIw8AAvf -s4wcQC8IVqaEH2+ImXsT349WvB3JcZp/E02CuWAc3B9SGWjBzhluBceuPpu5y54anrEmZpBD -cFM8pN3mWavX79b7rU4bN3gQsDHHmhbxxbHzgIZul4WoDwi1tGmNL4q5fhoRjzGbH4lrz1+I -07NANzWF2wLFO/oIEaKXtsz59NtvWic0F/KENVvqxjlhzClEExdPjq/OFG0z8sRnIV7lAbxA -Nn1hZ//uoUGfghK4zEvgZhVIXC7iII16wd+3mPWHdyDw/qp1cnAEL2w+L8JU4BO/gdP1NsdA -dwq0ZZFLNeLOgeAaDpID5eeEXNZm5bh1lo35jX9VnVP96g08rFpH/r23setp/eq8r3Xl3zf2 -bJ10L7SO9HVzv3a/q/fDr7f0+5/6eaojft/Ys91BKmo9+XfVkx+mMv9yIw6UMLNQmnFtfzr3 -+FnkTqsQqa0TMmHAM6dMqUEu1ddOHXq05ERzkcfPWZeNHZLbbeyeuedkrR8nvqX6cUAIg/7H -yyY1Tdl05TRwiMjOzj+YP0rN9k9y9L/Ko2L1gdCbTwz7CAyLNOMsC2/JjOD6GY1G5B+p/Ikt -j4UqSpiwIfRL32/HrasqKeY7cjAYl+w6/yCLJzt5KFnWm0+PlxELlfzNdYXFmOrMJTquNaN6 -I/uhZflVqjfkKL33ZuYlNruTzxrcaqVYUrABhY0HH9JHM4WF4v0FekEMR4hp9RWmI5J8jXJP -b1+noGy8QkXx1dU9cIVqUSsLo+fGkCeLMG6gsYD2/oL8ExRXaOBJ+5zJrY6RD7HBmmTEWyFx -NJQs8iTPO413g8t6412zf4BWKzOvD1c7nMXtsgPi0PFc9Kz8cXrWZ3wEJ4MaYjyDVcskRodL -uNVtegYb0Wj+rZUA1Q0xZVMhUk18jQRFq95dHnC6MImjE/4aEwXQQRqR73uQkGKzpJPO0tC0 -5RIpQqnvEmzEJG6+0XYP/yczihzsWBkJz8xjX3lmNpoHdLQS9bX5KRp0UKem42X4Xl6z5QDP -PVp7zH7HlofSWsPXSpeJNlIufrBEFTieCrNMnXm2uERNBZufYu4qFO45+QeZrDj8ZJ6awwYe -Jjtg3qdy6fOhWp6UWqQzSbGSN27JfvFYLx6KR6q0OnUaEB6+IdIHQXEwtKfclw1n5sJjNoeJ -7DO3hPAzbTsYoBvPU7J1/KJEGzWOUCELg7aH5J6tOEO4yejaFnJFgYYUcmIc4il8kkz9dNBq -N/t56NHJQYHWrF/I8w7Jgb/ruFvI3hGT8BJ2Sh35G6VM43UU0K8YjMyp41JaQWJxuNZj5geU -qzmCCTrTYeYcRW6zPbjsdPvZ9c4m/8D/xCNa7frJSXdQb3/kZ+qcBqApwek8/AcL/MzLTBoK -vUSR93NiASDdhg7aF4J2ecisbFAuCy9jGLH4XOn0UP1AM+n6QD+OI1vqBoEUMSV6BQqtYxQn -A5Rv+tbdNZMY/pC5ijkZBzj3/VlIR4cOOadhWgNt4Fyh/RXrxme0x6VL8gop30O6EWNuJB+C -ynLvjbD5oNx/buNqnlzC/VI+cn2nZkPgItxw504mCKM0l2il1d9dRBUTrDnMd1CY20xSHxZz -ZzzdlAx/LheiVi6iJxTdYYs4HCS7o2CTMjIxstJ0uOTGtRB9Dz/h1P8hy9ARbY1ItJnKBOSy -TqKboKQwOtIQ4fLeU0uiBZHM1UJU4HsrsatCoRCrw02WZMwA2cM1raWrq8RM2kSNNbixxuM2 -DwF4/vxuMpGkNkcsWuK0UYK1IJxIuyoifCCdx2YU5LOuVzVPgqiuthI19Po1ZXylJkzvzQ0Z -FujmIMQPdHQ5pI1benNH/H9D2v7Rcwz31P9VK3s7qv6vWqtWeP3fTvUp//M9nqf8z1P+5yn/ -83j5H+MnZ4QMN5K5icHbH42f8KvjMe1N/Oqi/rdBo9NuNxsUfOhRLVLcplnIXEzu7lSrCSxp -ISrXpFJKA20fJ63VSnm/koBFt/ld86MaCLs/7yRDVTGJatwraQglITw5Eo9v0ijDdGpkuVRB -uCLWf3Lcrl80j/7Ymi7t4dbNITmSypMKtYyCTDvRN4asTSzOQwkUjyS9ibpcSB6HDKUppTMc -Mg+pA5GcoUsGf2iBg7wWJMjr7n9ed9vzcajzBujfQeeyKaJBiKmCLczLP7ingvPykAXPn+AK -gUcMPikSfBbRMxV0wW+x4xwHfvG/eZhIl8TK48HfdaLIxsiX0SYWGLLMjKxHbjrBBZ0xPXtI -4hHlA5rDOJOQNsrz5quZB4xH7mDDKosS0dYJODai44wcFgIzrQmX+3KrkjQintwpNhIrZBx+ -egOmEJiitPs1cdBFgoUTboKg2uaUfdpFR924ScUBkfh4dpiHchyxUYcnV/zxqfboER/N/vP+ -mvof2N2t7Kj6H5Rxu7z+p7z7ZP99j+fJ/nuy/57sv0et/7mj2sXxnMgxXQqP3RoA/5E0O1kB -vDRGi55oJpKQ1NQT1eG/Y71Lqre9Mn/kTNm3LIrR8hA/bg7CCzKqUKbsQMYIGV453Lcx43aJ -nibPqTz5vclKFZN0WfxKptyFYXVpBiFTMf6RM55Ls5YuX8a1UEJSiPiQIeNIVN4iA4ZyY2Tk -6RHyAd6/kg8oFvudkw78Znrz0BDRLEVCRAg/EW2HSypqyGzxXgpcshO35hHWOt2TSljrz9MI -1D+XUWFi+TaX1TDdfjPhLyUQlVNYAbaeVNictFH7It/cGahOprgr57CeCti0Z4m8EFBvyUhL -vCl+OA/Ws+hyy/iG6Y0FZbFz7halSDleFIiOgvI3vCWKZJTOc3QbuPAzw+vVkjFicx+dBREV -D1EL2f40Q5Ih0746PxdFJKmZcYIjkP14KxKXymZiyj4wu/9AQvJrJA9I7ce05NKeRtHSabVk -FKXlNl9rqizmjtsbh2s5mdWCnY2lFEmCQaVWzLj0TZaTKlP3C5oP4rJmEsEWNTiB9fWWGpx0 -Gc4mEqq6BVF+A4nc0LLnWoJBrwFAumhO+qFKRFHpUTo3n5TPpYt70vxwVxXEg4UggbxD9tH/ -SQ3lveH2f7tH8//0S8aPOsd9/l9V+n90/3Nnl+5/7JbK5Sf/73s838gES16i9Tn7sj1i/HUx -d+b6Q9Mls+byjHRVDsYDSn3hx08UM/x8aKRLF3mzXtynuol6DUrihTyiCOl0oFSEFGcjISys -JinuVOIxQMM7EtG3cK2A7Vj0lfXKswGOp8m40ODBKzlDT1zN3C1XPitrz7nXTDTimsoVrRXP -c0dtJVU5kd9IMTkqtUZVnJoAvFd073GGfqzNfjPR0QRunl3URbUEKoWMc1RCX+mXmILw+rUj -5WEx1/ahzUQOWoUbxbVXzxc2KDbI1cdqAzLrO+V8pnJqygqvaPKsFKcy26rp0nUgEkPKg6ar -WrOoVV3XtzK3EkqS+HaYDzIaOKjXr2NekwpH3d9MsUEetshCOnqBHilaqUe7O9UK2EOyo474 -3c5bjCkRIt9Q2v0i5JXcqUl4t+TYOESay/eyiz3MrHc2xA5dvqdCwnmY0QdnaX+SJMTguH4i -GUHEtsPxp3Ll589SGyeXVnGpf/cyidKIM+vEgcgg8vzAi/AAqSGLcR9CgFgf4yR31lHH0fT4 -0JszimuE6xcWeOBann4aFqLVazHun6hyLq3gWomJxcQXsfj5Csik3pWXEMbCIswk3uJsQPgT -JS/PAn6HIYeLD1My4iGH8dQJ8DBbE2Zdg7NyQR1N7qk063gUJEacAg7eqwgWplg/t2adSNWg -FIsOdzGs6Uz5Y2SBEjccHaFxhByEPv6cxeXDfDHbb6SVdrThmIqzvjpUzpbiaHE3QYcodzng -layX79nvzEqxqNY7sfmIoZ/TkD//xDGCwj3B3vglSxe2L8+6zd6g0bm4qLdPBp13scEXc3al -tKNY+x7mjstEgY6kNG7JvCYeBnFMdSzzt9BIsXxsUq4xO9BhdpkZ8HXoBrNeWLK5zw0SWxaF -IG4rNZv8qlcH3b3f/CFnexLvps1DVNoNmVAxVBxu4gqSx6QUK/EYFQ7z6W69cnKUCaXYMOR5 -IQk8uT8m7qT5VKiLHiBBcjzkaM+S50+Lgmr5pQQdylmlq01/TEdZ5DECPFXGP3ET4T6n6y/x -r1a48R4nS3xedbUc9WMD8hCrtKdWsfVBFrGmNT/uiG49pau/YN1kWnXPbimLEjPp8qwg5Knk -KV1oJ3VhqxL3ZXJyhEP2H+V//dWP5v/hOTi5aH6DOe75/Z+9cq0W+3/lCv3+G358uv//XZ5u -EpL7WiqUDcM4b120+tzy7cmUlMwD0sVJLrUj9C4oeUTJFxd1/e+Abp/HXKgUKoVymaR1l9lv -zUi27hVKBaPuhn4qrUjgdEgC9II8i+lsHtHdZin2PYavg+sC/T5P6E8ZaY0JjqYK3ZCrMZ5e -kvUHiDAqxlD+EAyaRzzxRj/lQvdnCpChlFX9qv+208Uu3G40hsz1F1nDaIEZhvMpaSuyRma+ -F5pDx3UiMiqTZJPKQhbgCueJc3sLDwInvMY5WrCgAJLhOtdSlgpx7Xi4skS9cp5aVXp5uvqs -sptkTZkWKjpmmOIermkHjJSx+MaErufjbd+aCyHa15EEDpptm+5sYj7nqTeOHIVqIz8ykeoX -9ROO5dwTkCiLS+jYc2FW60lcIABccg8Z8wycwWN2gX7/Rz2G8eEtatRWD1r9X9Ms5JAVQQUp -28JHSFLISLM4yUz1IiKlzHeRLqGHwEOlvayBo4gZcPR4wsgaoIEhMnEkbPTIxB0Ac8qrdAiQ -MF5wmDPFJSHeqFJ5jQwaHGEhjZ/tM/E7QUuGQOcznmmg2xeui+zNf5cHKM3KE3NEQwph2+YS -9TtZNgbn4YW5jPdvw5x5osJwmaR3ycARPMrr1YntDfolPjSUKMQh7Ka6NKPk7w9pP1FFW6yu -xseRDX6JQZ2IgsFvRdH7dqe9fSuImTk2tdLzpCybUrbG284HOOk0aVfhQ6f77leDJzrp1wm8 -NZi0RpXUzSeXWMmhinO9aY+KZ7P5kU3ngFNuHP8dJ7E2vY48idvym+ho1dG+slQfHr9Irtmu -XWfXTF2+l15ee21wSPEvS8WG8vpVeFXIv2K5huSnye0wMglgDWPQadx/2wTyW67arYaIINUv -Ou0zXqDXk+Tvo9xzPGeqsslobwUmUsfkXMCNJ48Hktbse9pvrcbMSGWV11eP7hJd7OPL5dfp -nWidFgU4UTxrqHKQUJ6SuUx3ciqIWfJJMQJ/q1yAAjQV4kAyPvKN2BDFI87cUXKpMLVlHQHM -JikcOrTsib+gKwF55TXrW2mjQBdLxAW5hB1tVhj5MzprkAkZo/pCd5mFse/bVANnamKTV2CM -jERLMJ3hN/pPYqkyPSQYk4nfjdM8mwIdNC491Ulrd+izsU1JYyGFxA+YhbLjqx78X3vX2tzG -dWQ/79T+iAlSFYlVEEyKlmRbqexCJCQhoUiZDzv6tBkSQ3BsAIOdAUhjf/32Od195w4ethMn -dtUuUXFsAjP32befp/ueDN5eppdn8th/yHOXEZAy+z4v71WDn43lt2+9dJ09IGP+Xo4d8CUL -2Rd5qNYFDKadHLeQqiAN9MGg00tznd5nfEoZrBH67WTVCw8Ko8dshd6XdbqcA3MxG+9ZQZOe -DTa7Lu+1WFsB2xECXv6vYpLepByPeYoc+omXPoihXzyTcwPblSJxHkBJpFFKJ7cvXazizeEm -N3Y2s6VaX/omv8mWTGjNZ2sPweAUTQFnqc1KMjtzsqBTUS3b9U1aT97K2a3vxJhNP+TZjEZn -d53v8qSOSiUZ7qIJ9xsnxbqc3CtKSWaNXU7Xp8OF2CiKF6UXyUHIyHbrnMvcFKdBdZiGkRj9 -Z7TQ1sw2DmqKsr3ZTMfvW+ioQll+1CCxc0BIAaZRyaFZgGaS5M3VuwsnUlPzfJE7VonvtS2O -/9lBa3Xuf+t6jblewjhSLBCcSYRQLR4KsJchZVPGCiEzEeZjTn74ZEq5/9+E/dTLClirB92m -H7CZohD04hMU0RxfUm6yAs6HYXifalH5ZHvpRankkKXXxUJdstATqijR2z0JHSQPutM0dIyn -R6CxDoBEo+sOv6HkbKz2abnWFouxQBdayrFe9Ri+gDNR8Qq2cJ1iflN31MeDrvB3Ne3YIa00 -AQzrIntPtYobUf8OUkuV6WQnlE9+6Pk35X/eCy8tF6JO9m6yRyjvb/2J7P/l/F/Uh9j/r37E -/k+fvzww+3//4OWrA9j/+4fPH+3/X+Pz+999Jqzms/ouSX5vduNNVcyDOrCcwxosq1FefSVP -HOzFCoar355bKQ881wdOt2nn8vPhnmkPQTzFbs2k50Uo/yD/OWv+s3nmD7/1gv0f+0TnH5rf -v6SPnzr/6SvD/7/Yf7XP+t+Hh4eP+P9f5dOcf1gC0Pv9cgL/e7b2d0Mxv/XYHz+//BOd/6Oz -j5+Gp+/++X3I+f989/n//HD/1cs0ffn54YsXL/afHwL/dfji5WP9/1/lo3XAmWgxOB2c90/S -j1dvToZHqfwzOL0YJP/mNd2/8QSXbvrnpZhmB19+eZAk6XpKzxdfdvnTzowZzblI0p2fl69e -oFppnfbvxSI+yoQhFaNxzgSM/ecHh18y9SJJB/d5tVIjERb9tFgsHJo0X9GSiTKD5Nlr6X6K -H4u8ToLXfGJZKu4979LBe3OXzeh5KGgush4IXBpwdSf/pmvyscplbJMctUwuWVmILdWW8FIv -Ghc8zfi8LsYzc69m38uX5iiuEqQ2jeAyKjUlhIPnEJDS1EvTNytGAqoM5fK3Z8Yknm5D//1C -7H3tarzMkOKTWxzkx7rCb4mP+dkzQsi/N2tYrfYmosBsLEa/malbayyjl1KHTHZkAgV4Tqnr -Y76XXdk5T6IghoEPguUZIAIPd7C0s+XirqyYFsw6umWyrHX7ZEhPL+BT0td2UWVrcjfwmtGr -kvhinxTXVVatduU4wX2ZZ6PeXsr4CFz/WRPJTrj0NmJ4CsqyB6oJmULzPGNpkFaOW9frrlT5 -LW5HoFPDN7ALmkzmFX0aBHVsH1m9QXvxnmroKgmB+Ig6orOjR2ZjfOlTo51qTFJINDaWV/fS -tTs3Hor6bq8bugrODgVgSdNiJ6DcjyzYOEdgJfEXgVwqFtGrjIcppbaoUV6Hl07GeKOjRCMz -IhY4Xl/31+bdsOZYItbbHZXmSaKTrebuXJZ4dYFsCu4fuVzNXXEQJNdShIaslJUtZvOyGNfF -KBFiBXvCYuYzjQlpJ9oSBg6Srr/Xn0rsSpWHdEV9ipGMer0XFIxG/iDZXV4tcLeWuaKLELDE -8UTLuqLJ1h2NV5Kpirb8IX+SS/FWfsh/yJAh1/UntjZXL1EJugllPtzlOHbJGO5bzlgRM7e5 -NMR+4CQdu/tLqKOYaxDMgxa2VlhXHCM6unp6yvjuGjnDCccD1g2kFpEXgh0R5Uk7fSGJMI6a -Pr+7fOrEwIRRjVuvlGDo0kt8axLeOLKFSixI8SB7usjn9Vfp04M9yiUVle1VF7JMnorhXCJ+ -YmQSSaaHO5TXxhrV/HGSj+WYU+LVtYEt0XQ33mFNg/VtjPvjqBGN73Iv6N5V9vmk9qkQS6m5 -QUrwjiPkahvBJVzw3KUw82wRxBnVYSuUnc7KJtFUXeEmQJImkB7u3onYMAdfqHfbHcIAEXFo -88zinRhfYtyijinIy0BzMA9OHOopNZlOd7tsSTHLJoi765QgZGQhRLRPKUsZCNdhqNdTXa5a -LeqW18l4JStrKzF59ATW0nKRWTV0nCT8PFl12UnMnhSHyow7MGoR91jLhYgQzt6E4xw/w5cM -ugNvJQchElVTjoQ7VjrjKDG6VJRBposeJCcmUcxGxX0xoms4La/JSLSToM904QHKhTZveNos -vSk0g8BxVeSiRa96xjQR2ltwm7uhLOI0GzE/m6jF1NfZJqTH7zroUIqsdNJ6YuoGuDxLxS2a -5zQ1vec62Bz7H04u5VMpM1Suecu6cvMVcdpN+F1pXTPG3aV/W0Lb6yX/nvykgiy/Xg7OP1yk -/dNj4KiPh1rLBUnTZlJ102PAyYdvrjSUKw9+ODsevrXYLga/bzGULaqSkSMXG/Ec6jHEQChn -IEZEFJAEsacFZO8cScwhdb1hO3flBMKlzlam2k5FA73O40zzZGu6vAxsu3rR02XvfNTxdUR7 -BpSmm1BnCcOnWIjmgNF71KnDqSBcHNAL3lqCiFLtGfbRL2iDIJG8Ku5lx+5zXRAdfDPhSfbw -lZ5phbvKzKVbfdaWzbP14paJ3QcZUJnoJk2Kv9oQmAH4e0wytbPcIJuRtc/5c8eSiZzNZTbG -kj1FRWVhBLcLhKf9BatsY5kzo5C1PylEpbWfZ4nvTNqJe+9A82Tk3E6GYm1Go0phIVmddkR2 -dOSg9IW936uCUNq6Emi041y0JkllEopnoyErdRg5vFYWS61suUAYnky5ltadVIBmKm8Tx0fE -S29M2TUdIEcsHoXWWsgpeyWJlHXGOXnXF8sokk8qGy0WlIjpBqEl3vNTYYP5HKrXjFaJxlKJ -cFLGJfPcMuK9HjAwvohKZNUS6vbc4c8ud8IkATEiuzpQKBWO4M8wWF1Xs2ae1LEeg+2NlWuo -zcBwyQmZihRYiiKGwHdBk9CVfizNvLhZlst6or0LzyEvF9qVb6wERsCS2CDjp5LmpBnnsUnc -TLJiqsVxXfK/1iqIheLZTLtL9LXaJdatlyiKOeEsIJIACLOYPeYWmk7wDJXIxj6MFIH20rXw -RU0/7YoS4WkrVsFdUkuHymsI6c/vVnUBPJLStR5mN9e0J1XwVtZKuxKI6XxBPYr0LwjdH9wy -d6WZlPO8oRzT7wziiFlV2wnGOaZxtkQ5W0pkBrAQOtydrLhrslTpNFY0ydrbjNAY/LbKKxc2 -uYOEsI8tdCmkIQr3NM8XjkLxEL/L8a+0eGy21xgBitNg0Nt1RhRTIM+/kbXlwsocFVBHkrPk -YkJSIhuT6608R1twDjSCtWWEp0/1dBzXG+MgbRKj6M1G6wWAiZ4sM22LGZtRHBIMMNZ7XgSx -zu9qFXUxtqi9sZZLXZnaXd7CCGppVADMWi8ZVsHpGSKKp7GoRqEVENAuTcBFv07/Zs9V97D0 -Lui14rmwEiB16gZrAPdUlUEMCZ+xyQujFQYb2YS6lKBR/shiKtK2c2GcCJCeJjY0DVJJtGo5 -6mOqRiJpK8IyuSZM8sGqyaaIogSCVnqazcqlcBeFL1II81C0OF66leNlbMC+2G37PIVOO0FJ -INPAAn3YKdBxhBf2GoeFIoVx4lv1jsiBbLW5XWxh/cCYGM0nE5dfaM4BLvdF/rDGE9lKo+E9 -HfyAUsjS1FeOpQsiWyF5RWtT4UFlEwFOGyhBF1+9BLPWkneVibU4kM9mU0MgWGzUbOdaY709 -0dzdb8JnDeiq2KWyTa/sszkeNEYTr3qXiRnoOHE7AzAn+YoqQzuPZpdyyapiyBmoy5m0Rlcu -VKOKGmKjd2jlP6CNF6rO1qbvTWWN7w2vOGudQd1ZQp9xRLsOP4rmWYpoC8N/CCiiFg1NU96J -FHcNp/NyEV5I1oiOmM3QLApmZQr3chajpgmRVs2WJutChYw1VjhNaGkbbhTaW86FkvYKqAO4 -cYeonadKgCvDNcCxeVAkEmxtZd24kql54uoOkS9ofOq0qnycVaMJEXG3xDA/QEyrc+xSXuxG -YQKMlP73RWCYdZMUS8Uo8v9RUa0XSew6coQ7KlhJO6kOVh0B8tzrVHbpjoZD0xXNmyT/Ia/U -/HXHmWVqL6pysnWxIwOqrESdm8Cb4eZUvVUVkDkPieEvNJozJTpsPMYqebMOAuQ8WAt/S0PJ -uq5FBmlXLe/URPa02OR9OVkyYTcBALOsAHRTnt7MT3XfhgtdV87/otEp2yRNw0rZKuUOf1xV -X5/C+uhhQqowdfXn+R5RNdffwafiPnBFKpLfQCPbIn+TCz9xBxzDcwPP7lCihBnAZWZnSl0a -sgKN/tS/Qa4N1BWWk7PdwHeTnLKuUp8yBaGh159BmGOQqkA1RkjXzryf2rh83W5NUGVNezpa -TVQ370ZaK6dZhapQS3cMNU5CCB3Vxl7LEnaDRrY5syycJ6rc3fQ+mxTaHBKVhDsv6H/Tea3y -rGKgpjErqCCRIay6ppCbBjWzBCQa0gzoUTGyCJdbCJB+ijsm1FwXLqbXLqWwrj1bWF/xVl5E -e3Na+0DFTwXwz9uD3euvM/kH9uBmF3XFBWojm5X6qSeeYINU9q/FoXZMGToKvWfZRMYyU35m -aoyFbdU9oDdNzJgMJpxSzLYNd4e7ESD08H4rXSX4an/y8HK+QUHNAtXBLJd1qSzp7WJ57dLh -WldfVBfmrsTm/W3DVNQjpmNhWFC3YxokJx5CMM48tW3LjCk0PY3nZLN40OqRC0dfe0/Yu3bp -8ZiNcQEyVI6WsJWKxmoRy26yrGmZZHVd3hTuEJMjgAqLLBtdhLJ3/rzyYQAQrUCySDWXXxhc -YX4yqj3wkE8mWaw4NDOSWb73BBDodkk9z7njuSuz3Y35xMeFIT5IDfPHJaGsmbt6glIbv/YU -Zru6C61lWaNrWiAJ9mkvTl/5jhrAVCia2ulTnSFGrAmVqprUYON7NsPEUiFwAFb1QlQ3Opl4 -i2xr/rCUZFWXM+otHHPoKjG1PbMT6iUzotUTIX+7oS1ErUPFik4AojXmJyOhIxOhSc8k37Lk -eA1Fkxropjat1t9Koa4La8Yo1xrYoD5Xt6mMsjHkRVDPr5NtamWLS1r+Ubkc30W8vbCIuTo5 -p/Oc6TFbhrDmLooWA1GDNP280Rm0Lh8cQequEfuPTvRQHna7LpEopYJ68x/mcOTSgDJR7+w8 -UlUQzYSDSahivkio4zxQGyx3dr+7d/BPxJWUBhkrypYQAwsTZpAiBTayFffcMqwknENfYKjQ -7bqv6rPiYniYndsLCeEaWuQTDPE3Ry4UVQO/CQPj0eE2wbwBL/YBiD2IQJf873Y5Uc4yKZh+ -Bun1QrfOzbvY2rRLgdoWSF3AKenBaZKOwS3IbMP0LYVHY5hjmPjqtm2Hcs2lJyx8x8aUzIRb -j30o9gYWb+ZWWcUg3V1xXSzUVT/JHkL0vowvOVojo0t4L3A3VBcQGB0Q07CqdtbqhuLrjq9t -TvY9de4g4HgTqEb7b9X+8D3WGwQRpobH0WFGf09gT0cchp+sLeKaiWNQh5eWgYhSlKag/Jiq -/xMzXsSghrUDZMQPE9lPo7O0xAPJ9osiRfQQt32JUYDfxyWn+zstAZosIhhDe80cQmHsqRDJ -YJ7L22XFeFULcBIKprlT/UkajE3PoFMGQLqWpbhjiKuXtE+SIVSszm0OXfBGr6X2E2ghpYgd -cx5rFtkrFANQwU53CrLaPDIAISBW+3fLEespp6qkRNapxpwT0UQhcXJ/6Nb20+MH8NekTzXa -PC0MW2jxas1L2+smERVSGeY6khBAO08N/4JJ6aiYSSEDF3PZO2449Z7LaUD95JgsTNMPXayd -kVbOGcQFnJ/oN4jG3e8q5MLwT3g99umXpo3XQO0IedXFdDmRY5prsEgDGCJDxqZXNlw/icM2 -EVovrxbqfo9eM9G/sYlQvZ0wd5w9C/tvIpMy392AngmVPBUjmlblSsyE1TNCCqLDHekJ3osw -P1V79VrTpo6DhVhGhWYvqts+/CVmJLUKmYdOkZynXRuAo/LlvZZFstr1bR4YFWpARL2C0Aru -IG7yjwxfdbgo6LPhkJL/vMsn0KTVGAaSbqaHMqeWp6KXTeAw3iwnqHtYVDfLqaZrK4e7ziZx -Lm3UfIRETdQp6fEUfygKS6whVw1AOVMSSuJuEUEdtlxu82VFDrbF5yY7szT5zL/01Efok7qB -VcDRL6S6Mu8Z3XUO1DNfnToOChbNZyP0ZuuTr9udM4GdKuOkNUKP8hmSBpMeV9biwmCYjYHd -2mJV+rvBv5qglD85iYr4ucIznPrndMljwdL0A/cxL1HmPkBykjFwHXKsletYN8EUf0AIv2IM -Eui+jSHlo8SpnazLbBKiEY2fay3OutDi6nHerDnTE33ptTlRUUnbwr0EUX02Kme6ASORPiMi -Swm1Sus70gyUQYr3lrMgjNXH1zAjG6TCTwJewtigSUJlxHdlQZ3wcu3UxGRKSBwGil7g3SfA -6cGMxGtZhvxeDwBqY69LK5Wq9WKDPdOI+KLnwbV1P8Vnhnpd41isQuDwCYQPHBxKw6jiHT6F -S6SI+q9XTWQrttOVRzfqyAaWCFyRplfdGsemGUCOno1G6ncAEch2j3M8Pr9jBL01xQj0InJN -Y3GJMuIwla5CM7NF+9VWOoC6c2ZUAlATJmkWQlnHsrYO8hFE4kyDU7jaudvmxaLkl3KCESKp -ydCjIco5F6p0B6OFH6/L0QbKgMrLlyyxsRuKjpVy9EWV3xeM3uqWA9RsN4bUftHIrms3qANA -i8VxwpULaXqBucVt8PCAMEXCF2DuMvZ6XlRRUT+hJxxce0PTIzBCLVGDF/ReD7J4BRz5laaK -oNQwhxAiIZBUrv2yFFkY+Ffhb8QWyh4vZdLgi/6E3rLc4EPdNqY3h3dSZWvPbhgSyiojQJ1J -2g6Yd+sSlk63seIosh2j0TjPIwdqW6F2kJhHCH1QZeWogVZX22+YSbaQw8bcm4CGLsJq2xKs -BclWAcNSup7vr/Da1B+/7ybKyVDo0n7PlUfHoEang7rCBv6EWDjlvzEKtbb4XesErynVoRjS -2q0uKh8Sw9BDfW8saVMNgxQI8ciYzf3Eyv/YJTKtK4CQwlFOcxyyOqE8CE7GOiCeLU0DQozr -7tf3CMmPmrEAMj4uswlPN89ede9kp2oBS5ySpuT9xglQ+9WybeUBtrNqHNMy2OzI/FFsA644 -MDESXhkrP2FRDkt1Oj0Ltwlx/w966ZvBUf/qYsBKRR/Pz96d9z+g5JehYo/Tt+eDQXr2Nj16 -3z9/N+jiufMBnojbAkY2aqCLMjb4e/DXy8HpZfpxcP5heHkprb35lPY/fpTG+29OBulJ/1tZ -zcFfjwYfL9Nv3w9OkzM0/+1QxnNx2ccLw9P02/Ph5fD0ndVS+vjpfPju/WX6/uzkeHBOtO5n -0jtf1KuNBheJjOOb4XF7Up3+hQy7E65W8sFjcrhm6S/D0+NuOhiyocFfP54PLmT+ibQ9/CAj -HsiPw9Ojk6tjAoHfXGlNH1bZk3FennFp/FlvXQYj7W/cyQTk8M+4lIlLKI3Igp8PL/6S9i8S -W9ivr/qhIVldaeND//SIG7W2kZhu+unsClJD5n1yjAcSfwALNUiPB29RNPob2V55Urq5uPow -sPW+uOQCnZykp4MjGW///FN6MTj/ZniEdUjOBx/7Q1l+YKTPz7X0tPKW5z1snlDJ4BvQwNXp -CWZ7Pvj6SuazhRLQRv+dUBsWM9r35NuhdI4dWt/8Ll+RH5rN/yRkhALpnxSY/cnIQ4YZkNtt -qhCiaKiz/+YMa/BGxjPksGQgWBBs0XH/Q//d4KKbBCJg1wYm76YXHwdHQ/yH/C6kJ3t9oqsi -p+jrK+yifGGNpH3ZTkwNdGhbhjMIWjt1GpG+18/l06bvNfoDXZycXYDYpJPLfsoRy7/fDPD0 -+eBU1ovHqX90dHUuRwtP4A0ZzcWVHLbhKTclwXx5mofnx36euM7p2/7w5Op8g8akZ71oc6C0 -FjbEiexir0saSIdvpauj97Z7aevUfkrfy1a8Gchj/eNvhuA82k8iZ+FiaGtyZi3YOpKxMddU -5sfntwD4gf3vzwHOKX74Ck5cyAEtT6t+1ktqAfLlJ7DdU1F5TNbVoGOTjyMRr5Ny3lzz3qAp -oyw3w+qZyBwzC6ReJGKJqLNsWQcppAae2d05K0yt1DN9B0NDVR9Fu1MSFYukLRFUEoa0nY07 -9KKE0BAydiei58W5Y3axyCzw1ChIAdLr+qM6I1KrvFRnt5gaRhzenjb3khqMiDAci7TwWixP -GdU8FEUOippwn68sciUqfG3KWgM5JpAHTbGN+MY5j/lTk+8EpaCDkqXmvErnJe0gLXuXWxIs -AwYG9UMaE9QAg0L+EevJ9x03EC3Ak1pLzGvT12KB3GpVOUKK9EY/YsP/xLbW06pXK2nfa9Sr -4vMn7fUX3ZNo/mNFUf4DdyWma3clBsTez78v0TuJ7ktkKz/rzsRtC/D33ptIyMgvuzsRTfyy -+xNDktHPvkMRb/zyexQVIvGP36WI9zfvU/x5KfxIRgFOCV6BGBYCz5myWy9/CyIWBZmVD6ty -JuPXFEDR91EDfqKuzhZCo4VI7Tov9ESSDMtWBRCv1umF+5qAR9S3XNCIYRZFC9sqByY3BNW7 -mSjV96rNOzm/lKltObvtk7vxthaC5A7031ycnYi2cfIp1pRfkwJs8/VG7L8xW/XhSa85BOun -v5EzZPz5BP1olbgWM2ALljsV/EVugr2Ou7t5Eg+kp1CVu9Uchh3jWg3K28fHMYS3jVo907aV -TdKyG3fmm53dMpRi0Y+mP4aKa3g1V3BoIMbGCLDYZfQoRMlOW4dmuUvqmedpv86TaSlNPruR -EXxPR8Y0ny1lwfJp/ewZuDaN5xr1/9I4x799xSnBeEg/5iO4Z7RcoS6WZ7oH+LG9PUVdWM3d -rpIaJvtEYxszRbAjuIzEucYZ16TcdJrMFNc1UKgUqfG1Zmi+N2R6BtzEfCIigqgpvgMy1fyK -T+WqHK1muZ9oyD8tWmw+8WwSewN5QqCNGMO1zqWhv0V0/gQBMWIE5TTWmsLLUtYOfKn3ghNN -OvszRpO+R6H/igzvjwodQbK3UMnlSk5aOftTNz0QvawqJqw+AgVFf+iiQkddeE7XN0JB5snd -wWSDX8UiRY1PI5RonkfejCTKfA1FBkJYrYpZUYagbFUiJg1mw1ISwSmTOB6cGZlg8iqZGG7U -kYhSQTRX3GOr6qnjUBJr3J1GyhQeHBbqadwjUd48Y2ZLdYtke3WLTWfmb1295vHzSz9R/afh -qZhzJyf//D5+4v6H588P9v3+h8NXuAvw4PDF4eP9f7/KZ+P+h6+vhkd/SY0WNi+AiG9siC6A -D+pP7wWFqvy7dwhFbiiCYWLXQSThOohu+8YIYe4He2l6NUNPUYG5ZzKi3mL8P+o8Vqba9Gnm -4aJiWuRzaeBDA4ahwed7itHMs8XNXagOrY9UdYB3qrEXCrpDqBmCGkH9EhyVuup0rYvm0kNZ -kygZn0/opWahloNDmsF5P51dnadeJ51yt5ce57eolwuO3ZmuRtedXnoUKvV+EJGJHnvJ4Z5d -gqOS1ufF5bHQZpSu3NEHnn3cT/+4uSCd5HNp7Tw3ARwe6KVPj3mBmGgTLJxSsjg664QTGbaX -vJAXj5pyPPPxf91dZz3caG0phaJVBS+Dgrn4p5WxfvpJhO3QK3QYWLteip6117NyWvLeUPP5 -6jUfgzT5FV/g5Vv+gUoizONLIamXXwjl7IO5vHjR83/2+dSikiOfvOS01d8Q7q1SRO+qQXU+ -KwDoBaY8X3gd5730dpKNheJeSRNUjTs0LqT3jtosupSRGlQnX+BZSw1O14C6pKNZKJbaVE7d -CwlJ/NIFuJORQjIKRHFd7fKbUpIvMb2lftlZzjsGqpZzts+rzDDrCZMQUXn70nZX94couspf -RlVQf113revbxvLwSxTJlzZ21H7eWfn5QlSSP4sunh6mz/f3fxVW//h5/Dx+Hj+Pn8fP4+fx -8/h5/Dx+Hj+Pn8fP/9fP/wKykq3cAMgAAA== - ---Boundary_(ID_GeYGc69fE1/bkYLTPwOGFg)-- - -************ - - -From owner-pgsql-hackers@hub.org Mon Jan 3 13:47:07 2000 -Received: from hub.org (hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id OAA23987 - for ; Mon, 3 Jan 2000 14:47:06 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id OAA03234; - Mon, 3 Jan 2000 14:39:56 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Mon, 3 Jan 2000 14:39:49 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id OAA03050 - for pgsql-hackers-outgoing; Mon, 3 Jan 2000 14:38:50 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from ara.zf.jcu.cz (zakkr@ara.zf.jcu.cz [160.217.161.4]) - by hub.org (8.9.3/8.9.3) with ESMTP id OAA02975 - for ; Mon, 3 Jan 2000 14:38:05 -0500 (EST) - (envelope-from zakkr@zf.jcu.cz) -Received: from localhost (zakkr@localhost) - by ara.zf.jcu.cz (8.9.3/8.9.3/Debian/GNU) with SMTP id UAA19297; - Mon, 3 Jan 2000 20:23:35 +0100 -Date: Mon, 3 Jan 2000 20:23:35 +0100 (CET) -From: Karel Zak - Zakkr -To: P.Marchesso@videotron.ca -cc: pgsql-hackers -Subject: [HACKERS] replicator -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Sender: owner-pgsql-hackers@postgresql.org -Status: OR - - -Hi, - -I look at your (Philippe's) replicator, but I don't good understand -your replication concept. - - - node1: SQL --IPC--> node-broker - | - TCP/IP - | - master-node --IPC--> replikator - | | | - libpq - | | | - node2 node..n - -(Is it right picture?) - -If I good understand, all nodes make connection to master node and data -replicate "replicator" on this master node. But it (master node) is very -critical space in this concept - If master node not work replication for -*all* nodes is lost. Hmm.. but I want use replication for high available -applications... - -IMHO is problem with node registration / authentification on master node. -Why concept is not more upright? As: - - SQL --IPC--> node-replicator - | | | - via libpq send data to all nodes with - current client/backend auth. - - (not exist any master node, all nodes have connection to all nodes) - - -Use replicator as external proces and copy data from SQL to this replicator -via IPC is (your) very good idea. - - Karel - - ----------------------------------------------------------------------- -Karel Zak http://home.zf.jcu.cz/~zakkr/ - -Docs: http://docs.linux.cz (big docs archive) -Kim Project: http://home.zf.jcu.cz/~zakkr/kim/ (process manager) -FTP: ftp://ftp2.zf.jcu.cz/users/zakkr/ (C/ncurses/PgSQL) ------------------------------------------------------------------------ - - -************ - -From owner-pgsql-hackers@hub.org Tue Jan 4 10:31:01 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id LAA17522 - for ; Tue, 4 Jan 2000 11:31:00 -0500 (EST) -Received: from hub.org (hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.10 $) with ESMTP id LAA01541 for ; Tue, 4 Jan 2000 11:27:30 -0500 (EST) -Received: from localhost (majordom@localhost) - by hub.org (8.9.3/8.9.3) with SMTP id LAA09992; - Tue, 4 Jan 2000 11:18:07 -0500 (EST) - (envelope-from owner-pgsql-hackers) -Received: by hub.org (bulk_mailer v1.5); Tue, 4 Jan 2000 11:17:58 -0500 -Received: (from majordom@localhost) - by hub.org (8.9.3/8.9.3) id LAA09856 - for pgsql-hackers-outgoing; Tue, 4 Jan 2000 11:17:17 -0500 (EST) - (envelope-from owner-pgsql-hackers@postgreSQL.org) -Received: from ara.zf.jcu.cz (zakkr@ara.zf.jcu.cz [160.217.161.4]) - by hub.org (8.9.3/8.9.3) with ESMTP id LAA09763 - for ; Tue, 4 Jan 2000 11:16:43 -0500 (EST) - (envelope-from zakkr@zf.jcu.cz) -Received: from localhost (zakkr@localhost) - by ara.zf.jcu.cz (8.9.3/8.9.3/Debian/GNU) with SMTP id RAA31673; - Tue, 4 Jan 2000 17:02:06 +0100 -Date: Tue, 4 Jan 2000 17:02:06 +0100 (CET) -From: Karel Zak - Zakkr -To: Philippe Marchesseault -cc: pgsql-hackers -Subject: Re: [HACKERS] replicator -In-Reply-To: <38714B6F.2DECAEC0@Videotron.ca> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Sender: owner-pgsql-hackers@postgreSQL.org -Status: OR - - -On Mon, 3 Jan 2000, Philippe Marchesseault wrote: - -> So it could become: -> -> SQL --IPC--> node-replicator -> | | | -> via TCP send statements to each node -> replicator (on local node) -> | -> via libpq send data to -> current (local) backend. -> -> > (not exist any master node, all nodes have connection to all nodes) -> -> Exactly, if the replicator dies only the node dies, everything else keeps -> working. - - - Hi, - - I a little explore replication conception on Oracle and Sybase (in manuals). -(Know anyone some interesting links or publication about it?) - - Firstly, I sure, untimely is write replication to PgSQL now, if we -haven't exactly conception for it. It need more suggestion from more -developers. We need firstly answers for next qestion: - - 1/ How replication concept choose for PG? - 2/ How manage transaction for nodes? (and we need define any - replication protocol for this) - 3/ How involve replication in current PG transaction code? - -My idea (dream:-) is replication that allow you use full read-write on all -nodes and replication which use current transaction method in PG - not is -difference between more backends on one host or more backend on more hosts -- it makes "global transaction consistency". - -Now is transaction manage via ICP (one host), my dream is alike manage -this transaction, but between more host via TCP. (And make optimalization -for this - transfer commited data/commands only.) - - -Any suggestion? - - -------------------- -Note: - -(transaction oriented replication) - - Sybase - I. model (only one node is read-write) - - primary SQL data (READ-WRITE) - | - replication agent (transaction log monitoring) - | - primary distribution server (one or more repl. servers) - | / | \ - | nodes (READ-ONLY) - | - secondary dist. server - / | \ - nodes (READ-ONLY) - - - If primary SQL is read-write and the other nodes *read-only* - => system good work if connection is disable (data are save to - replication-log and if connection is available log is write - to node). - - - Sybase - II. model (all nodes read-write) - - SQL data 1 --->--+ NODE I. - | | - ^ | - | replication agent 1 (transaction log monitoring) - V | - | V - | | - replication server 1 - | - ^ - V - | - replication server 2 NODE II. - | | - ^ +-<-->--- SQL data 2 - | | - replcation agent 2 -<-- - - - -Sorry, I not sure if I re-draw previous picture total good.. - - Karel - - - - - - -************ - -From pgsql-hackers-owner+M3133@hub.org Fri Jun 9 15:02:25 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id PAA22319 - for ; Fri, 9 Jun 2000 15:02:24 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e59IsET81137; - Fri, 9 Jun 2000 14:54:14 -0400 (EDT) -Received: from ultra2.quiknet.com (ultra2.quiknet.com [207.183.249.4]) - by hub.org (8.10.1/8.10.1) with SMTP id e59IrQT80458 - for ; Fri, 9 Jun 2000 14:53:26 -0400 (EDT) -Received: (qmail 13302 invoked from network); 9 Jun 2000 18:53:21 -0000 -Received: from 18.67.tc1.oro.pmpool.quiknet.com (HELO quiknet.com) (pecondon@207.231.67.18) - by ultra2.quiknet.com with SMTP; 9 Jun 2000 18:53:21 -0000 -Message-ID: <39413D08.A6BDC664@quiknet.com> -Date: Fri, 09 Jun 2000 11:52:57 -0700 -From: Paul Condon -X-Mailer: Mozilla 4.73 [en] (X11; U; Linux 2.2.14-5.0 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: ohp@pyrenet.fr, pgsql-hackers@postgresql.org -Subject: [HACKERS] Re: Big project, please help -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: OR - -Two way replication on a single "table" is availabe in Lotus Notes. In -Notes, every record has a time-stamp, which contains the time of the -last update. (It also has a creation timestamp.) During replication, -timestamps are compared at the row/record level, and compared with the -timestamp of the last replication. If, for corresponding rows in two -replicas, the timestamp of one row is newer than the last replication, -the contents of this newer row is copied to the other replica. But if -both of the corresponding rows have newer timestamps, there is a -problem. The Lotus Notes solution is to: - 1. send a replication conflict message to the Notes Administrator, -which message contains full copies of both rows. - 2. copy the newest row over the less new row in the replicas. - 3. there is a mechanism for the Administrator to reverse the default -decision in 2, if the semantics of the message history, or off-line -investigation indicates that the wrong decision was made. - -In practice, the Administrator is not overwhelmed with replication -conflict messages because updates usually only originate at the site -that originally created the row. Or updates fill only fields that were -originally 'TBD'. The full logic is perhaps more complicated than I have -described here, but it is already complicated enough to give you an idea -of what you're really being asked to do. I am not aware of a supplier of -relational database who really supports two way replication at the level -that Notes supports it, but Notes isn't a relational database. - -The difficulty of the position that you appear to be in is that -management might believe that the full problem is solved in brand X -RDBMS, and you will have trouble convincing management that this is not -really true. - - -From pgsql-hackers-owner+M2401@hub.org Tue May 23 12:19:54 2000 -Received: from news.tht.net (news.hub.org [216.126.91.242]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id MAA28410 - for ; Tue, 23 May 2000 12:19:53 -0400 (EDT) -Received: from hub.org (majordom@hub.org [216.126.84.1]) - by news.tht.net (8.9.3/8.9.3) with ESMTP id MAB53304; - Tue, 23 May 2000 12:00:08 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M2401@hub.org) -Received: from gwineta.repas.de (gwineta.repas.de [193.101.49.1]) - by hub.org (8.9.3/8.9.3) with ESMTP id LAA39896 - for ; Tue, 23 May 2000 11:57:31 -0400 (EDT) - (envelope-from kardos@repas-aeg.de) -Received: (from smap@localhost) - by gwineta.repas.de (8.8.8/8.8.8) id RAA27154 - for ; Tue, 23 May 2000 17:57:23 +0200 -Received: from dragon.dr.repas.de(172.30.48.206) by gwineta.repas.de via smap (V2.1) - id xma027101; Tue, 23 May 00 17:56:20 +0200 -Received: from kardos.dr.repas.de ([172.30.48.153]) - by dragon.dr.repas.de (UCX V4.2-21C, OpenVMS V6.2 Alpha); - Tue, 23 May 2000 17:57:24 +0200 -Message-ID: <010201bfc4cf$7334d5a0$99301eac@Dr.repas.de> -From: "Kardos, Dr. Andreas" -To: "Todd M. Shrider" , - -References: -Subject: Re: [HACKERS] failing over with postgresql -Date: Tue, 23 May 2000 17:56:20 +0200 -Organization: repas AEG Automation GmbH -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 8bit -X-Priority: 3 -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook Express 5.00.2314.1300 -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: OR - -For a SCADA system (Supervisory Control and Data Akquisition) which consists -of one master and one hot-standby server I have implemented such a -solution. To these UNIX servers client workstations are connected (NT and/or -UNIX). The database client programms run on client and server side. - -When developing this approach I had to goals in mind: -1) Not to get dependend on the PostgreSQL sources since they change very -dynamically. -2) Not to get dependend on the fe/be protocol since there are discussions -around to change it. - -So the approach is quite simple: Forward all database requests to the -standby server on TCP/IP level. - -On both servers the postmaster listens on port 5433 and not on 5432. On -standard port 5432 my program listens instead. This program forks twice for -every incomming connection. The first instance forwards all packets from the -frontend to both backends. The second instance receives the packets from all -backends and forwards the packets from the master backend to the frontend. -So a frontend running on a server machine connects to port 5432 of -localhost. - -On the client machine runs another program (on NT as a service). This -program forks for every incomming connections twice. The first instance -forwards all packets to port 5432 of the current master server and the -second instance forwards the packets from the master server to the frontend. - -During standby computer startup the database of the master computer is -dumped, zipped, copied to the standby computer, unzipped and loaded into -that database. -If a standby startup took place, all client connections are aborted to allow -a login into the standby database. The frontends need to reconnect in this -case. So the database of the standby computer is always in sync. - -The disadvantage of this method is that a query cannot be canceled in the -standby server since the request key of this connections gets lost. But we -can live with that. - -Both programms are able to run on Unix and on (native!) NT. On NT threads -are created instead of forked processes. - -This approach is simple, but it is effective and it works. - -We hope to survive this way until real replication will be implemented in -PostgreSQL. - -Andreas Kardos - ------Ursprüngliche Nachricht----- -Von: Todd M. Shrider -An: -Gesendet: Donnerstag, 18. Mai 2000 17:48 -Betreff: [HACKERS] failing over with postgresql - - -> -> is anyone working on or have working a fail-over implentation for the -> postgresql stuff. i'd be interested in seeing if and how any might be -> dealing with just general issues as well as the database syncing issues. -> -> we are looking to do this with heartbeat and lvs in mind. also if anyone -> is load ballancing their databases that would be cool to talk about to. -> -> --- -> Todd M. Shrider VA Linux Systems -> Systems Engineer -> tshrider@valinux.com www.valinux.com -> - - -From pgsql-hackers-owner+M3662@postgresql.org Tue Jan 23 16:23:34 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id QAA04456 - for ; Tue, 23 Jan 2001 16:23:34 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f0NLKf004705; - Tue, 23 Jan 2001 16:20:41 -0500 (EST) - (envelope-from pgsql-hackers-owner+M3662@postgresql.org) -Received: from sectorbase2.sectorbase.com ([208.48.122.131]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f0NLAe003753 - for ; Tue, 23 Jan 2001 16:10:40 -0500 (EST) - (envelope-from vmikheev@SECTORBASE.COM) -Received: by sectorbase2.sectorbase.com with Internet Mail Service (5.5.2653.19) - id ; Tue, 23 Jan 2001 12:49:07 -0800 -Message-ID: <8F4C99C66D04D4118F580090272A7A234D32AF@sectorbase1.sectorbase.com> -From: "Mikheev, Vadim" -To: "'dom@idealx.com'" , pgsql-hackers@postgresql.org -Subject: RE: [HACKERS] Re: AW: Re: MySQL and BerkleyDB (fwd) -Date: Tue, 23 Jan 2001 13:10:34 -0800 -MIME-Version: 1.0 -X-Mailer: Internet Mail Service (5.5.2653.19) -Content-Type: text/plain; - charset="iso-8859-1" -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: ORr - -> I had thought that the pre-commit information could be stored in an -> auxiliary table by the middleware program ; we would then have -> to re-implement some sort of higher-level WAL (I thought of the list -> of the commands performed in the current transaction, with a sequence -> number for each of them that would guarantee correct ordering between -> concurrent transactions in case of a REDO). But I fear I am missing - -This wouldn't work for READ COMMITTED isolation level. -But why do you want to log commands into WAL where each modification -is already logged in, hm, correct order? -Well, it has sense if you're looking for async replication but -you need not in two-phase commit for this and should aware about -problems with READ COMMITTED isolevel. - -Back to two-phase commit - it's easiest part of work required for -distributed transaction processing. -Currently we place single commit record to log and transaction is -committed when this record (and so all other transaction records) -is on disk. -Two-phase commit: - -1. For 1st phase we'll place into log "prepared-to-commit" record - and this phase will be accomplished after record is flushed on disk. - At this point transaction may be committed at any time because of - all its modifications are logged. But it still may be rolled back - if this phase failed on other sites of distributed system. - -2. When all sites are prepared to commit we'll place "committed" - record into log. No need to flush it because of in the event of - crash for all "prepared" transactions recoverer will have to - communicate other sites to know their statuses anyway. - -That's all! It is really hard to implement distributed lock- and -communication- managers but there is no problem with logging two -records instead of one. Period. - -Vadim - -From pgsql-hackers-owner+M3665@postgresql.org Tue Jan 23 17:05:26 2001 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id RAA05972 - for ; Tue, 23 Jan 2001 17:05:24 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id f0NM31008120; - Tue, 23 Jan 2001 17:03:01 -0500 (EST) - (envelope-from pgsql-hackers-owner+M3665@postgresql.org) -Received: from candle.pha.pa.us (candle.navpoint.com [162.33.245.46]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id f0NLsU007188 - for ; Tue, 23 Jan 2001 16:54:30 -0500 (EST) - (envelope-from pgman@candle.pha.pa.us) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.9.0/8.9.0) id QAA05300; - Tue, 23 Jan 2001 16:53:53 -0500 (EST) -From: Bruce Momjian -Message-Id: <200101232153.QAA05300@candle.pha.pa.us> -Subject: Re: [HACKERS] Re: AW: Re: MySQL and BerkleyDB (fwd) -In-Reply-To: <8F4C99C66D04D4118F580090272A7A234D32AF@sectorbase1.sectorbase.com> - "from Mikheev, Vadim at Jan 23, 2001 01:10:34 pm" -To: "Mikheev, Vadim" -Date: Tue, 23 Jan 2001 16:53:53 -0500 (EST) -CC: "'dom@idealx.com'" , pgsql-hackers@postgresql.org -X-Mailer: ELM [version 2.4ME+ PL77 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -[ Charset ISO-8859-1 unsupported, converting... ] -> > I had thought that the pre-commit information could be stored in an -> > auxiliary table by the middleware program ; we would then have -> > to re-implement some sort of higher-level WAL (I thought of the list -> > of the commands performed in the current transaction, with a sequence -> > number for each of them that would guarantee correct ordering between -> > concurrent transactions in case of a REDO). But I fear I am missing -> -> This wouldn't work for READ COMMITTED isolation level. -> But why do you want to log commands into WAL where each modification -> is already logged in, hm, correct order? -> Well, it has sense if you're looking for async replication but -> you need not in two-phase commit for this and should aware about -> problems with READ COMMITTED isolevel. -> - -I believe the issue here is that while SERIALIZABLE ISOLATION means all -queries can be run serially, our default is READ COMMITTED, meaning that -open transactions see committed transactions, even if the transaction -committed after our transaction started. (FYI, see my chapter on -transactions for help, http://www.postgresql.org/docs/awbook.html.) - -To do higher-level WAL, you would have to record not only the queries, -but the other queries that were committed at the start of each command -in your transaction. - -Ideally, you could number every commit by its XID your log, and then -when processing the query, pass the "committed" transaction ids that -were visible at the time each command began. - -In other words, you can replay the queries in transaction commit order, -except that you have to have some transactions committed at specific -points while other transactions are open, i.e.: - -XID Open XIDS Query -500 UPDATE t SET col = 3; -501 500 BEGIN; -501 500 UPDATE t SET col = 4; -501 UPDATE t SET col = 5; -501 COMMIT; - -This is a silly example, but it shows that 500 must commit after the -first command in transaction 501, but before the second command in the -transaction. This is because UPDATE t SET col = 5 actually sees the -changes made by transaction 500 in READ COMMITTED isolation level. - -I am not advocating this. I think WAL is a better choice. I just -wanted to outline how replaying the queries in commit order is -insufficient. - -> Back to two-phase commit - it's easiest part of work required for -> distributed transaction processing. -> Currently we place single commit record to log and transaction is -> committed when this record (and so all other transaction records) -> is on disk. -> Two-phase commit: -> -> 1. For 1st phase we'll place into log "prepared-to-commit" record -> and this phase will be accomplished after record is flushed on disk. -> At this point transaction may be committed at any time because of -> all its modifications are logged. But it still may be rolled back -> if this phase failed on other sites of distributed system. -> -> 2. When all sites are prepared to commit we'll place "committed" -> record into log. No need to flush it because of in the event of -> crash for all "prepared" transactions recoverer will have to -> communicate other sites to know their statuses anyway. -> -> That's all! It is really hard to implement distributed lock- and -> communication- managers but there is no problem with logging two -> records instead of one. Period. - -Great. - - --- - Bruce Momjian | http://candle.pha.pa.us - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - -From pgsql-general-owner+M805@postgresql.org Tue Nov 21 23:53:04 2000 -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id AAA19262 - for ; Wed, 22 Nov 2000 00:53:03 -0500 (EST) -Received: from mail.postgresql.org (webmail.postgresql.org [216.126.85.28]) - by mail.postgresql.org (8.11.1/8.11.1) with SMTP id eAM5qYs47249; - Wed, 22 Nov 2000 00:52:34 -0500 (EST) - (envelope-from pgsql-general-owner+M805@postgresql.org) -Received: from racerx.cabrion.com (racerx.cabrion.com [166.82.231.4]) - by mail.postgresql.org (8.11.1/8.11.1) with ESMTP id eAM5lJs46653 - for ; Wed, 22 Nov 2000 00:47:19 -0500 (EST) - (envelope-from rob@cabrion.com) -Received: from cabrionhome (gso163-25-211.triad.rr.com [24.163.25.211]) - by racerx.cabrion.com (8.8.7/8.8.7) with SMTP id AAA13731 - for ; Wed, 22 Nov 2000 00:45:20 -0500 -Message-ID: <006501c05447$fb9aa0c0$4100fd0a@cabrion.org> -From: "rob" -To: -Subject: [GENERAL] Synchronization Toolkit -Date: Wed, 22 Nov 2000 00:49:29 -0500 -MIME-Version: 1.0 -Content-Type: multipart/mixed; - boundary="----=_NextPart_000_0062_01C0541E.125CAF30" -X-Priority: 3 -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook Express 5.50.4133.2400 -X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 -Precedence: bulk -Sender: pgsql-general-owner@postgresql.org -Status: OR - -This is a multi-part message in MIME format. - -------=_NextPart_000_0062_01C0541E.125CAF30 -Content-Type: text/plain; charset="iso-8859-1" -Content-Transfer-Encoding: 7bit - -Not to be confused with replication, my concept of synchronization is to -manage changes between a server table (or tables) and one or more mobile, -disconnected databases (i.e. PalmPilot, laptop, etc.). - -I read through the notes in the TODO for this topic and devised a tool kit -for doing synchronization. I hope that the Postgresql development community -will find this useful and will help me refine this concept by offering -insight, experience and some good old fashion hacking if you are so -inclined. - -The bottom of this message describes how to use the attached files. - -I look forward to your feedback. - ---rob - - -Methodology: - -I devised a concept that I call "session versioning". This means that every -time a row changes it does NOT get a new version. Rather it gets stamped -with the current session version common to all published tables. Clients, -when they connect for synchronization, will immediately increment this -common version number reserve the result as a "post version" and then -increment the session version again. This version number, implemented as a -sequence, is common to all synchronized tables and rows. - -Any time the server makes changes to the row gets stamped with the current -session version, when the client posts its changes it uses the reserved -"post version". The client then makes all it's changes stamping the changed -rows with it's reserved "post version" rather than the current version. The -reason why is explained later. It is important that the client post all its -own changes first so that it does not end up receiving records which changed -since it's last session that it is about to update anyway. - -Reserving the post version is a two step process. First, the number is -simply stored in a variable for later use. Second, the value is added to a -lock table (last_stable) to indicate to any concurrent sessions that rows -with higher version numbers are to be considered "unstable" at the moment -and they should not attempt to retrieve them at this time. Each client, -upon connection, will use the lowest value in this lock table (max_version) -to determine the upper boundary for versions it should retrieve. The lower -boundary is simply the previous session's "max_version" plus one. Thus -when the client retrieves changes is uses the following SQL "where" -expression: - -WHERE row_version >= max_version and row_version <= last_stable_version and -version <> this_post_version - -The point of reserving and locking a post version is important in that it -allows concurrent synchronization by multiple clients. The first, of many, -clients to connect basically dictates to all future clients that they must -not take any rows equal to or greater than the one which it just reserved -and locked. The reason the session version is incremented a second time is -so that the server may continue to post changes concurrent with any client -changes and be certain that these concurrent server changes will not taint -rows the client is about to retrieve. Once the client is finished with it's -session it removes the lock on it's post version. - -Partitioning data for use by each node is the next challenge we face. How -can we control which "slice" of data each client receives? A slice can be -horizontal or vertical within a table. Horizontal slices are easy, it's -just the where clause of an SQL statement that says "give me the rows that -match X criteria". We handle this by storing and appending a where clause -to each client's retrieval statement in addition to where clause described -above. Actually, two where clauses are stored and appended. One is per -client and one is per publication (table). - -We defined horizontal slices by filtering rows. Vertical slices are limits -by column. The tool kit does provide a mechanism for pseudo vertical -partitioning. When a client is "subscribed" to a publication, the toolkit -stores what columns that node is to receive during a session. These are -stored in the subscribed_cols table. While this does limit the number -columns transmitted, the insert/update/delete triggers do not recognize -changes based on columns. The "pseudo" nature of our vertical partitioning -is evident by example: - -Say you have a table with name, address and phone number as columns. You -restrict a client to see only name and address. This means that phone -number information will not be sent to the client during synchronization, -and the client can't attempt to alter the phone number of a given entry. -Great, but . . . if, on the server, the phone number (but not the name or -address) is changed, the entire row gets marked with a new version. This -means that the name and address will get sent to the client even though they -didn't change. - -Well, there's the flaw in vertical partitioning. Other than wasting -bandwidth, the extra row does no harm to the process. The workaround for -this is to highly normalize your schema when possible. - -Collisions are the next crux one encounters with synchronization. When two -clients retrieve the same row and both make (different)changes, which one is -correct? So far the system operates totally independent of time. This is -good because it doesn't rely on the server or client to keep accurate time. -We can just ignore time all together, but then we force our clients to -synchronize on a strict schedule in order to avoid (or reduce) collisions. -If every node synchronized immediately after making changes we could just -stop here. Unfortunately this isn't reality. Reality dictates that of two -clients: Client A & B will each pick up the same record on Monday. A will -make changes on Monday, then leave for vacation. B will make changes on -Wednesday because new information was gathered in A's absence. Client B -posts those changes Wednesday. Meanwhile, client A returns from vacation on -Friday and synchronizes his changes. A over writes B's changes even though -A made changes before the most recent information was posted by B. - -It is clear that we need some form of time stamp to cope with the above -example. While clocks aren't the most reliable, they are the only common -version control available to solve this problem. The system is set up to -accept (but not require) timestamps from clients and changes on the server -are time stamped. The system, when presented a time stamp with a row, will -compare them to figure out who wins in a tie. The system makes certain -"sanity" checks with regard to these time stamps. A client may not attempt -to post a change with a timestamp that is more than one hour in the future -(according to what the server thinks "now" is) nor one hour before it's last -synchronization date/time. The client row will be immediately placed into -the collision table if the timestamp is that far out of whack. -Implementations of the tool kit should take care to ensure that client & -server agree on what "now" is before attempting to submit changes with -timestamps. - -Time stamps are not required. Should a client be incapable of tracking -timestamps, etc. The system will assume that any server row which has been -changed since the client's last session will win a tie. This is quite error -prone, so timestamps are encouraged where possible. - -Inserts pose an interesting challenge. Since multiple clients cannot share -a sequence (often used as a primary key) while disconnected. They will be -responsible for their own unique "row_id" when inserting records. Inserts -accept any arbitrary key, and write back to the client a special kind of -update that gives the server's row_id. The client is responsible for making -sure that this update takes place locally. - -Deletes are the last portion of the process. When deletes occur, the -row_id, version, etc. are stored in a "deleted" table. These entries are -retrieved by the client using the same version filter as described above. -The table is pruned at the end of each session by deleting all records with -versions that are less than the lowest 'last_version' stored for each -client. - -Having wrapped up the synchronization process, I'll move on to describe some -points about managing clients, publications and the like. - -The tool kit is split into two objects: SyncManagement and Synchronization. -The Synchronization object exposes an API that client implementations use to -communicate and receive changes. The management functions handle system -install and uninstall in addition to publication of tables and client -subscriptions. - -Installation and uninstallation are handled by their corresponding functions -in the API. All system tables are prefixed and suffixed with four -underscores, in hopes that this avoids conflict with an existing tables. -Calling the install function more than once will generate an error message. -Uninstall will remove all related tables, sequences, functions and triggers -from the system. - -The first step, after installing the system, is to publish a table. A table -can be published more than once under different names. Simply provide a -unique name as the second argument to the publish function. Since object -names are restricted to 32 characters in Postgres, each table is given a -unique id and this id is used to create the trigger and sequence names. -Since one table can be published multiple times, but only needs one set of -triggers and one sequence for change management a reference count is kept so -that we know when to add/drop triggers and functions. By default, all -columns are published, but the third argument to the publish function -accepts an array reference of column names that allows you to specify a -limited set. Information about the table is stored in the "tables" table, -info about the publication is in the "publications" table and column names -are stored in "subscribed_cols" table. - -The next step is to subscribe a client to a table. A client is identified -by a user name and a node name. The subscribe function takes three -arguments: user, node & publication. The subscription process writes an -entry into the "subscribed" table with default values. Of note, the -"RefreshOnce" attribute is set to true whenever a table is published. This -indicates to the system that a full table refresh should be sent the next -time the client connects even if the client requests synchronization rather -than refresh. - -The toolkit does not, yet, provide a way to manage the whereclause stored at -either the publication or client level. To use or test this feature, you -will need to set the whereclause attributes manually. - -Tables and users can be unpublished and unsubscribed using the corresponding -functions within the tool kit's management interface. Because postgres -lacks an "ALTER TABLE DROP COLUMN" function, the unpublish function only -removes default values and indexes for those columns. - -The API isn't the most robust thing in the world right now. All functions -return undef on success and an error string otherwise (like DBD). I hope to -clean up the API considerably over the next month. The code has not been -field tested at this time. - - -The files attached are: - -1) SynKit.pm (A perl module that contains install/uninstall functions and a -simple api for synchronization & management) - -2) sync_install.pl (Sample code to demonstrate the installation, publishing -and subscribe process) - -3) sync_uninstall.pl (Sample code to demonstrate the uninstallation, -unpublishing and unsubscribe process) - - -To use them on Linux (don't know about Win32 but should work fine): - - - set up a test database and make SURE plpgsql is installed - - - install perl 5.05 along with Date::Parse(TimeDate-1.1) , DBI and DBD::Pg -modules [www.cpan.org] - - - copy all three attached files to a test directory - - - cd to your test directory - - - edit all three files and change the three DBI variables to suit your -system (they are clearly marked) - - - % perl sync_install.pl - - - check out the tables, functions & triggers installed - - - % perl sync.pl - - - check out the 'sync_test' table, do some updates/inserts/deletes and run -sync.pl again - NOTE: Sanity checks default to allow no more than 50% of the table -to be changed by the client in a single session. - If you delete all (or most of) the rows you will get errors when -you run sync.pl again! (by design) - - - % perl sync_uninstall.pl (when you are done) - - - check out the sample scripts and the perl module code (commented, but -not documented) - - - - - - -------=_NextPart_000_0062_01C0541E.125CAF30 -Content-Type: application/octet-stream; name="sync.pl" -Content-Transfer-Encoding: quoted-printable -Content-Disposition: attachment; filename="sync.pl" - - - -# This script depicts the syncronization process for two users. - - -## CHANGE THESE THREE VARIABLE TO MATCH YOUR SYSTEM ########### -my $dbi_connect_string =3D 'dbi:Pg:dbname=3Dtest;host=3Dsnoopy'; # -my $db_user =3D 'test'; # -my $db_pass =3D 'test'; # -################################################################# - -my $ret; #holds return value - -use SynKit; - -#create a synchronization object (pass dbi connection info) -my $s =3D Synchronize->new($dbi_connect_string,$db_user,$db_pass); - -#start a session by passing a user name, "node" identifier and a collision = -queue name (client or server) -$ret =3D $s->start_session('JOE','REMOTE_NODE_NAME','server'); -print "Handle this error: $ret\n\n" if $ret; - -#call this once before attempting to apply individual changes -$ret =3D $s->start_changes('sync_test',['name']); -print "Handle this error: $ret\n\n" if $ret; - -#call this for each change the client wants to make to the database -$ret =3D $s->apply_change(CLIENTROWID,'insert',undef,['ted']); -print "Handle this error: $ret\n\n" if $ret; - -#call this for each change the client wants to make to the database -$ret =3D $s->apply_change(CLIENTROWID,'insert','1973-11-10 11:25:00 AM -05= -',['tim']); -print "Handle this error: $ret\n\n" if $ret; - -#call this for each change the client wants to make to the database -$ret =3D $s->apply_change(999,'update',undef,['tom']); -print "Handle this error: $ret\n\n" if $ret; - -#call this for each change the client wants to make to the database -$ret =3D $s->apply_change(1,'update',undef,['tom']); -print "Handle this error: $ret\n\n" if $ret; - -#call this once after all changes have been submitted -$ret =3D $s->end_changes(); -print "Handle this error: $ret\n\n" if $ret; - -#call this to get updates from all subscribed tables -$ret =3D $s->get_all_updates(); -print "Handle this error: $ret\n\n" if $ret; - -print "\n\nSyncronization session is complete. (JOE) \n\n"; - - -# make some changes to the database (server perspective) - -print "\n\nMaking changes to the the database. (server side) \n\n"; - -use DBI; -my $dbh =3D DBI->connect($dbi_connect_string,$db_user,$db_pass); - -$dbh->do("insert into sync_test values ('roger')"); -$dbh->do("insert into sync_test values ('john')"); -$dbh->do("insert into sync_test values ('harry')"); -$dbh->do("delete from sync_test where name =3D 'roger'"); -$dbh->do("update sync_test set name =3D 'tom' where name =3D 'harry'"); - -$dbh->disconnect; - - -#now do another session for a different user - -#start a session by passing a user name, "node" identifier and a collision = -queue name (client or server) -$ret =3D $s->start_session('KEN','ANOTHER_REMOTE_NODE_NAME','server'); -print "Handle this error: $ret\n\n" if $ret; - -#call this to get updates from all subscribed tables -$ret =3D $s->get_all_updates(); -print "Handle this error: $ret\n\n" if $ret; - -print "\n\nSynchronization session is complete. (KEN)\n\n"; - -print "Now look at your database and see what happend, make changes to the = -test table, etc. and run this again.\n\n"; - -------=_NextPart_000_0062_01C0541E.125CAF30 -Content-Type: application/octet-stream; name="sync_uninstall.pl" -Content-Transfer-Encoding: quoted-printable -Content-Disposition: attachment; filename="sync_uninstall.pl" - - -# this script uninstalls the synchronization system using the SyncManager o= -bject; - -use SynKit; - -### CHANGE THESE TO MATCH YOUR SYSTEM ######################## -my $dbi_connect_string =3D 'dbi:Pg:dbname=3Dtest;host=3Dsnoopy'; # -my $db_user =3D 'test'; # -my $db_pass =3D 'test'; # -################################################################# - - -my $ret; #holds return value - -#create an instance of the SyncManager object -my $m =3D SyncManager->new($dbi_connect_string,$db_user,$db_pass); - -# call this to unsubscribe a user/node (not necessary if you are uninstalli= -ng) -print $m->unsubscribe('KEN','ANOTHER_REMOTE_NODE_NAME','sync_test'); - -#call this to unpublish a table (not necessary if you are uninstalling) -print $m->unpublish('sync_test'); - -#call this to uninstall the syncronization system -# NOTE: this will automatically unpublish & unsubscribe all users -print $m->UNINSTALL; - -# now let's drop our little test table -use DBI; -my $dbh =3D DBI->connect($dbi_connect_string,$db_user,$db_pass); -$dbh->do("drop table sync_test"); -$dbh->disconnect; - -print "\n\nI hope you enjoyed this little demonstration\n\n"; - - - -------=_NextPart_000_0062_01C0541E.125CAF30 -Content-Type: application/octet-stream; name="sync_install.pl" -Content-Transfer-Encoding: quoted-printable -Content-Disposition: attachment; filename="sync_install.pl" - - -# This script shows how to install the synchronization system=20 -# using the SyncManager object - -use SynKit; - -### CHANGE THESE TO MATCH YOUR SYSTEM ########################## -my $dbi_connect_string =3D 'dbi:Pg:dbname=3Dtest;host=3Dsnoopy'; # -my $db_user =3D 'test'; # -my $db_pass =3D 'test'; # -################################################################# -my $ret; #holds return value - - -#create an instance of the sync manager object -my $m =3D SyncManager->new($dbi_connect_string,$db_user,$db_pass); - -#Call this to install the syncronization management tables, etc. -$ret =3D $m->INSTALL; -die "Handle this error: $ret\n\n" if $ret; - - - -#create a test table for us to demonstrate with -use DBI; -my $dbh =3D DBI->connect($dbi_connect_string,$db_user,$db_pass); -$dbh->do("create table sync_test (name text)"); -$dbh->do("insert into sync_test values ('rob')"); -$dbh->do("insert into sync_test values ('rob')"); -$dbh->do("insert into sync_test values ('rob')"); -$dbh->do("insert into sync_test values ('ted')"); -$dbh->do("insert into sync_test values ('ted')"); -$dbh->do("insert into sync_test values ('ted')"); -$dbh->disconnect; - - - - -#call this to "publish" a table -$ret =3D $m->publish('sync_test'); -print "Handle this error: $ret\n\n" if $ret; - -#call this to "subscribe" a user/node to a publication (table) -$ret =3D $m->subscribe('JOE','REMOTE_NODE_NAME','sync_test'); -print "Handle this error: $ret\n\n" if $ret; - -#call this to "subscribe" a user/node to a publication (table) -$ret =3D $m->subscribe('KEN','ANOTHER_REMOTE_NODE_NAME','sync_test'); -print "Handle this error: $ret\n\n" if $ret; - - -print "Now you can do: 'perl sync.pl' a few times to play\n\n"; -print "Do 'perl sync_uninstall.pl' to uninstall the system\n"; - - -------=_NextPart_000_0062_01C0541E.125CAF30 -Content-Type: application/octet-stream; name="SynKit.pm" -Content-Transfer-Encoding: quoted-printable -Content-Disposition: attachment; filename="SynKit.pm" - -# Perl DB synchronization toolkit - -#created for postgres 7.0.2 + -use strict; - -BEGIN { - use vars qw($VERSION); - # set the version for version checking - $VERSION =3D 1.00; -} - - -package Synchronize; - -use DBI; - -use Date::Parse; - -# new requires 3 arguments: dbi connection string, plus the corresponding u= -sername and password to get connected to the database -sub new { - my $proto =3D shift; - my $class =3D ref($proto) || $proto; - my $self =3D {}; - - my $dbi =3D shift; - my $user =3D shift; - my $pass =3D shift; - - $self->{DBH} =3D DBI->connect($dbi,$user,$pass) || die "Failed to connect = -to database: ".DBI->errstr(); - - $self->{user} =3D undef; - $self->{node} =3D undef; - $self->{status} =3D undef; # holds status of table update portion of sessi= -on - $self->{pubs} =3D {}; #holds hash of pubs available to sessiom with val = -=3D 1 if ok to request sync - $self->{orderpubs} =3D undef; #holds array ref of subscribed pubs ordered = -by sync_order - $self->{this_post_ver} =3D undef; #holds the version number under which th= -is session will post changes - $self->{max_ver} =3D undef; #holds the maximum safe version for getting up= -dates - $self->{current} =3D {}; #holds the current publication info to which chan= -ges are being applied - $self->{queue} =3D 'server'; # tells collide function what to do with coll= -isions. (default is to hold on server) - - $self->{DBLOG}=3D DBI->connect($dbi,$user,$pass) || die "cannot log to DB:= - ".DBI->errstr();=20 - - - return bless ($self, $class); -} - -sub dblog {=20 - my $self =3D shift; - my $msg =3D $self->{DBLOG}->quote($_[0]); - my $quser =3D $self->{DBH}->quote($self->{user}); - my $qnode =3D $self->{DBH}->quote($self->{node}); - $self->{DBLOG}->do("insert into ____sync_log____ (username, nodename,stamp= -, message) values($quser, $qnode, now(), $msg)"); -} - - -#start_session establishes session wide information and other housekeeping = -chores - # Accepts username, nodename and queue (client or server) as arguments; - -sub start_session { - my $self =3D shift; - $self->{user} =3D shift || die 'Username is required'; - $self->{node} =3D shift || die 'Nodename is required'; - $self->{queue} =3D shift; - - - if ($self->{queue} ne 'server' && $self->{queue} ne 'client') { - die "You must provide a queue argument of either 'server' or 'client'"; - } - - my $quser =3D $self->{DBH}->quote($self->{user}); - my $qnode =3D $self->{DBH}->quote($self->{node}); - - my $sql =3D "select pubname from ____subscribed____ where username =3D $qu= -ser and nodename =3D $qnode"; - my @pubs =3D $self->GetColList($sql); - - return 'User/Node has no subscriptions!' if !defined(@pubs); - - # go though the list and check permissions and rules for each - foreach my $pub (@pubs) { - my $qpub =3D $self->{DBH}->quote($pub); - my $sql =3D "select disabled, pubname, fullrefreshonly, refreshonce,post_= -ver from ____subscribed____ where username =3D $quser and pubname =3D $qpub= - and nodename =3D $qnode"; - my $sth =3D $self->{DBH}->prepare($sql) || die $self->{DBH}->errstr; - $sth->execute || die $self->{DBH}->errstr; - my @row; - while (@row =3D $sth->fetchrow_array) { - next if $row[0]; #publication is disabled - next if !defined($row[1]); #publication does not exist (should never occ= -ur) - if ($row[2] || $row[3]) { #refresh of refresh once flag is set - $self->{pubs}->{$pub} =3D 0; #refresh only - next; - } - if (!defined($row[4])) { #no previous session exists, must refresh - $self->{pubs}->{$pub} =3D 0; #refresh only - next; - } - $self->{pubs}->{$pub} =3D 1; #OK for sync - } - $sth->finish; - } - - - $sql =3D "select pubname from ____publications____ order by sync_order"; - my @op =3D $self->GetColList($sql); - my @orderpubs; - - #loop through ordered pubs and remove non subscribed publications - foreach my $pub (@op) { - push @orderpubs, $pub if defined($self->{pubs}->{$pub}); - } -=09 - $self->{orderpubs} =3D \@orderpubs; - -# Now we obtain a session version number, etc. - - $self->{DBH}->{AutoCommit} =3D 0; #allows "transactions" - $self->{DBH}->{RaiseError} =3D 1; #script [or eval] will automatically die= - on errors - - eval { #start DB transaction - - #lock the version sequence until we determin that we have gotten - #a good value. Lock will be released on commit. - $self->{DBH}->do('lock ____version_seq____ in access exclusive mode'); - - # remove stale locks if they exist - my $sql =3D "delete from ____last_stable____ where username =3D $quser an= -d nodename =3D $qnode"; - $self->{DBH}->do($sql); - - # increment version sequence & grab the next val as post_ver - my $sql =3D "select nextval('____version_seq____')"; - my $sth =3D $self->{DBH}->prepare($sql); - $sth->execute; - ($self->{this_post_ver}) =3D $sth->fetchrow_array(); - $sth->finish; - # grab max_ver from last_stable - - $sql =3D "select min(version) from ____last_stable____";=20 - $sth =3D $self->{DBH}->prepare($sql); - $sth->execute; - ($self->{max_ver}) =3D $sth->fetchrow_array(); - $sth->finish; - - # if there was no version in lock table, then take the ID that was in use - # when we started the session ($max_ver -1) - - $self->{max_ver} =3D $self->{this_post_ver} -1 if (!defined($self->{max_v= -er})); - - # lock post_ver by placing it in last_stable - $self->{DBH}->do("insert into ____last_stable____ (version, username, nod= -ename) values ($self->{this_post_ver}, $quser,$qnode)"); - - # increment version sequence again (discard result) - $sql =3D "select nextval('____version_seq____')"; - $sth =3D $self->{DBH}->prepare($sql); - $sth->execute; - $sth->fetchrow_array(); - $sth->finish; - - }; #end eval/transaction - - if ($@) { # part of transaction failed - return 'Start session failed'; - $self->{DBH}->rollback; - } else { # all's well commit block - $self->{DBH}->commit; - } - $self->{DBH}->{AutoCommit} =3D 1; - $self->{DBH}->{RaiseError} =3D 0; - - return undef; - -} - -#start changes should be called once before applying individual change requ= -ests - # Requires publication and ref to columns that will be updated as arguments -sub start_changes { - my $self =3D shift; - my $pub =3D shift || die 'Publication is required'; - my $colref =3D shift || die 'Reference to column array is required'; - - $self->{status} =3D 'starting'; - - my $qpub =3D $self->{DBH}->quote($pub); - my $quser =3D $self->{DBH}->quote($self->{user}); - my $qnode =3D $self->{DBH}->quote($self->{node}); - - my @cols =3D @{$colref}; - my @subcols =3D $self->GetColList("select col_name from ____subscribed_col= -s____ where username =3D $quser and nodename =3D $qnode and pubname =3D $qp= -ub"); - my %subcols; - foreach my $col (@subcols) { - $subcols{$col} =3D 1; - } - foreach my $col (@cols) {=09 - return "User/node is not subscribed to column '$col'" if !$subcols{$col}; - } - - my $sql =3D "select pubname, readonly, last_session, post_ver, last_ver, w= -hereclause, sanity_limit,=20 -sanity_delete, sanity_update, sanity_insert from ____subscribed____ where u= -sername =3D $quser and pubname =3D $qpub and nodename =3D $qnode"; - my ($junk, $readonly, $last_session, $post_ver, $last_ver, $whereclause, $= -sanity_limit,=20 -$sanity_delete, $sanity_update, $sanity_insert) =3D $self->GetOneRow($sql); -=09 - return 'Publication is read only' if $readonly; - - $sql =3D "select whereclause from ____publications____ where pubname =3D $= -qpub"; - my ($wc) =3D $self->GetOneRow($sql); - $whereclause =3D '('.$whereclause.')' if $whereclause; - $whereclause =3D $whereclause.' and ('.$wc.')' if $wc; - - my ($table) =3D $self->GetOneRow("select tablename from ____publications__= -__ where pubname =3D $qpub"); - - return 'Publication is not registered correctly' if !defined($table); - - my %info; - $info{pub} =3D $pub; - $info{whereclause} =3D $whereclause; - $info{post_ver} =3D $post_ver; - $last_session =3D~ s/([+|-]\d\d?)$/ $1/; #put a space before timezone=09 - $last_session =3D str2time ($last_session); #convert to perltime (seconds = -since 1970) - $info{last_session} =3D $last_session; - $info{last_ver} =3D $last_ver; - $info{table} =3D $table; - $info{cols} =3D \@cols; - - my $sql =3D "select count(oid) from $table"; - $sql =3D $sql .' '.$whereclause if $whereclause; - my ($rowcount) =3D $self->GetOneRow($sql); - - #calculate sanity levels (convert from % to number of rows) - # limits defined as less than 1 mean no limit - $info{sanitylimit} =3D $rowcount * ($sanity_limit / 100) if $sanity_limit = -> 0; - $info{insertlimit} =3D $rowcount * ($sanity_insert / 100) if $sanity_inser= -t > 0; - $info{updatelimit} =3D $rowcount * ($sanity_update / 100) if $sanity_updat= -e > 0; - $info{deletelimit} =3D $rowcount * ($sanity_delete / 100) if $sanity_delet= -e > 0; - - $self->{sanitycount} =3D 0; - $self->{updatecount} =3D 0; - $self->{insertcount} =3D 0; - $self->{deletecount} =3D 0; - - $self->{current} =3D \%info; - - $self->{DBH}->{AutoCommit} =3D 0; #turn on transaction behavior so we can = -roll back on sanity limits, etc. - - $self->{status} =3D 'ready'; - - return undef; -} - -#call this once all changes are submitted to commit them; -sub end_changes { - my $self =3D shift; - return undef if $self->{status} ne 'ready'; - $self->{DBH}->commit; - $self->{DBH}->{AutoCommit} =3D 1; - $self->{status} =3D 'success'; - return undef; -} - -#call apply_change once for each row level client update - # Accepts 4 params: rowid, action, timestamp and reference to data array - # Note: timestamp can be undef, data can be undef - # timestamp MUST be in perl time (secs since 1970) - -#this routine checks basic timestamp info and sanity limits, then passes th= -e info along to do_action() for processing -sub apply_change { - my $self =3D shift; - my $rowid =3D shift || return 'Row ID is required'; #don't die just for on= -e bad row - my $action =3D shift || return 'Action is required'; #don't die just for o= -ne bad row - my $timestamp =3D shift; - my $dataref =3D shift; - $action =3D lc($action); - - $timestamp =3D str2time($timestamp) if $timestamp; - - return 'Status failure, cannot accept changes: '.$self->{status} if $self-= ->{status} ne 'ready'; - - my %info =3D %{$self->{current}}; - - $self->{sanitycount}++; - if ($info{sanitylimit} && $self->{sanitycount} > $info{sanitylimit}) { - # too many changes from client - my $ret =3D $self->sanity('limit'); - return $ret if $ret; - } - -=09 - if ($timestamp && $timestamp > time() + 3600) { # current time + one hour - #client's clock is way off, cannot submit changes in future - my $ret =3D $self->collide('future', $info{table}, $rowid, $action, undef= -, $timestamp, $dataref, $self->{queue}); - return $ret if $ret; - } - - if ($timestamp && $timestamp < $info{last_session} - 3600) { # last sessio= -n time less one hour - #client's clock is way off, cannot submit changes that occured before las= -t sync date - my $ret =3D $self->collide('past', $info{table}, $rowid, $action, undef, = -$timestamp, $dataref , $self->{queue}); - return $ret if $ret; - } - - my ($crow, $cver, $ctime); #current row,ver,time - if ($action ne 'insert') { - my $sql =3D "select ____rowid____, ____rowver____, ____stamp____ from $in= -fo{table} where ____rowid____ =3D $rowid"; - ($crow, $cver, $ctime) =3D $self->GetOneRow($sql); - if (!defined($crow)) { - my $ret =3D $self->collide('norow', $info{table}, $rowid, $action, undef= -, $timestamp, $dataref , $self->{queue}); - return $ret if $ret;=09=09 - } - - $ctime =3D~ s/([+|-]\d\d?)$/ $1/; #put space between timezone - $ctime =3D str2time($ctime) if $ctime; #convert to perl time - - if ($timestamp) { - if ($ctime < $timestamp) { - my $ret =3D $self->collide('time', $info{table}, $rowid, $action, undef= -, $timestamp, $dataref, $self->{queue} );=09=09 - return $ret if $ret; - } - - } else { - if ($cver > $self->{this_post_ver}) { - my $ret =3D $self->collide('version', $info{table}, $rowid, $action, un= -def, $timestamp, $dataref, $self->{queue} ); - return $ret if $ret; - } - } -=09 - } - - if ($action eq 'insert') { - $self->{insertcount}++; - if ($info{insertlimit} && $self->{insertcount} > $info{insertlimit}) { - # too many changes from client - my $ret =3D $self->sanity('insert'); - return $ret if $ret; - } - - my $qtable =3D $self->{DBH}->quote($info{table}); - my ($rowidsequence) =3D '_'.$self->GetOneRow("select table_id from ____ta= -bles____ where tablename =3D $qtable").'__rowid_seq'; - return 'Table incorrectly registered, cannot get rowid sequence name: '.$= -self->{DBH}->errstr() if not defined $rowidsequence; - - my @data; - foreach my $val (@{$dataref}) { - push @data, $self->{DBH}->quote($val); - } - my $sql =3D "insert into $info{table} ("; - if ($timestamp) { - $sql =3D $sql . join(',',@{$info{cols}}) . ',____rowver____, ____stamp__= -__) values ('; - $sql =3D $sql . join (',',@data) .','.$self->{this_post_ver}.',\''.local= -time($timestamp).'\')'; - } else { - $sql =3D $sql . join(',',@{$info{cols}}) . ',____rowver____) values ('; - $sql =3D $sql . join (',',@data) .','.$self->{this_post_ver}.')'; - } - my $ret =3D $self->{DBH}->do($sql); - if (!$ret) { - my $ret =3D $self->collide($self->{DBH}->errstr(), $info{table}, $rowid,= - $action, undef, $timestamp, $dataref , $self->{queue}); - return $ret if $ret;=09=09 - } - my ($newrowid) =3D $self->GetOneRow("select currval('$rowidsequence')"); - return 'Failed to get current rowid on inserted row'.$self->{DBH}->errstr= - if not defined $newrowid; - $self->changerowid($rowid, $newrowid); - } - - if ($action eq 'update') { - $self->{updatecount}++; - if ($info{updatelimit} && $self->{updatecount} > $info{updatelimit}) { - # too many changes from client - my $ret =3D $self->sanity('update'); - return $ret if $ret; - } - my @data; - foreach my $val (@{$dataref}) { - push @data, $self->{DBH}->quote($val); - }=09 - - my $sql =3D "update $info{table} set "; - my @cols =3D @{$info{cols}}; - foreach my $col (@cols) { - my $val =3D shift @data; - $sql =3D $sql . "$col =3D $val,"; - } - $sql =3D $sql." ____rowver____ =3D $self->{this_post_ver}"; - $sql =3D $sql.", ____stamp____ =3D '".localtime($timestamp)."'" if $times= -tamp; - $sql =3D $sql." where ____rowid____ =3D $rowid"; - $sql =3D $sql." and $info{whereclause}" if $info{whereclause}; - my $ret =3D $self->{DBH}->do($sql); - if (!$ret) { - my $ret =3D $self->collide($self->{DBH}->errstr(), $info{table}, $rowid,= - $action, undef, $timestamp, $dataref , $self->{queue}); - return $ret if $ret;=09=09 - } - - } - - if ($action eq 'delete') { - $self->{deletecount}++; - if ($info{deletelimit} && $self->{deletecount} > $info{deletelimit}) { - # too many changes from client - my $ret =3D $self->sanity('delete'); - return $ret if $ret; - } - if ($timestamp) { - my $sql =3D "update $info{table} set ____rowver____ =3D $self->{this_pos= -t_ver}, ____stamp____ =3D '".localtime($timestamp)."' where ____rowid____ = -=3D $rowid"; - $sql =3D $sql . " where $info{whereclause}" if $info{whereclause}; - $self->{DBH}->do($sql) || return 'Predelete update failed: '.$self->{DBH= -}->errstr; - } else { - my $sql =3D "update $info{table} set ____rowver____ =3D $self->{this_pos= -t_ver} where ____rowid____ =3D $rowid"; - $sql =3D $sql . " where $info{whereclause}" if $info{whereclause}; - $self->{DBH}->do($sql) || return 'Predelete update failed: '.$self->{DBH= -}->errstr; - } - my $sql =3D "delete from $info{table} where ____rowid____ =3D $rowid"; - $sql =3D $sql . " where $info{whereclause}" if $info{whereclause}; - my $ret =3D $self->{DBH}->do($sql); - if (!$ret) { - my $ret =3D $self->collide($self->{DBH}->errstr(), $info{table}, $rowid,= - $action, undef, $timestamp, $dataref , $self->{queue}); - return $ret if $ret;=09=09 - } -} -=09 -=09 - return undef; -} - -sub changerowid { - my $self =3D shift; - my $oldid =3D shift; - my $newid =3D shift; - $self->writeclient('changeid',"$oldid\t$newid"); -} - -#writes info to client -sub writeclient { - my $self =3D shift; - my $type =3D shift; - my @info =3D @_; - print "$type: ",join("\t",@info),"\n"; - return undef; -} - -# Override this for custom behavior. Default is to echo back the sanity fa= -ilure reason.=20=20 -# If you want to override a collision, you can do so by returning undef. -sub sanity { - my $self =3D shift; - my $reason =3D shift; - $self->{status} =3D 'sanity exceeded'; - $self->{DBH}->rollback; - return $reason; -} - -# Override this for custom behavior. Default is to echo back the failure r= -eason.=20=20 -# If you want to override a collision, you can do so by returning undef. -sub collide { - my $self =3D shift; - my ($reason,$table,$rowid,$action,$rowver,$timestamp,$data, $queue) =3D @_; - - my @data; - foreach my $val (@{$data}) { - push @data, $self->{DBH}->quote($val); - }=09 - - if ($reason =3D~ /integrity/i || $reason =3D~ /constraint/i) { - $self->{status} =3D 'intergrity violation'; - $self->{DBH}->rollback; - } - - my $datastring; - my @cols =3D @{$self->{current}->{cols}}; - foreach my $col (@cols) { - my $val =3D shift @data; - $datastring =3D $datastring . "$col =3D $val,"; - } - chop $datastring; #remove trailing comma - - if ($queue eq 'server') { - $timestamp =3D localtime($timestamp) if defined($timestamp); - $rowid =3D $self->{DBH}->quote($rowid); - $rowid =3D 'null' if !defined($rowid); - $rowver =3D 'null' if !defined($rowver); - $timestamp =3D $self->{DBH}->quote($timestamp); - $data =3D $self->{DBH}->quote($data); - my $qtable =3D $self->{DBH}->quote($table); - my $qreason =3D $self->{DBH}->quote($reason); - my $qaction =3D $self->{DBH}->quote($action); - my $quser =3D $self->{DBH}->quote($self->{user}); - my $qnode =3D $self->{DBH}->quote($self->{node}); - $datastring =3D $self->{DBH}->quote($datastring); - - - my $sql =3D "insert into ____collision____ (rowid, -tablename, rowver, stamp, data, reason, action, username, -nodename, queue) values($rowid,$qtable, $rowver, $timestamp,$datastring, -$qreason, $qaction,$quser, $qnode)"; - $self->{DBH}->do($sql) || die 'Failed to write to collision table: '.$sel= -f->{DBH}->errstr; - - } else { - - $self->writeclient('collision',$rowid,$table, $rowver, $timestamp,$reason= -, $action,$self->{user}, $self->{node}, $data); - - } - return $reason; -} - -#calls get_updates once for each publication the user/node is subscribed to= - in correct sync_order -sub get_all_updates { - my $self =3D shift; - my $quser =3D $self->{DBH}->quote($self->{user}); - my $qnode =3D $self->{DBH}->quote($self->{node}); - - foreach my $pub (@{$self->{orderpubs}}) { - $self->get_updates($pub, 1); #request update as sync unless overrridden b= -y flags - } - -} - -# Call this once for each table the client needs refreshed or sync'ed AFTER= - all inbound client changes have been posted -# Accepts publication and sync flag as arguments -sub get_updates { - my $self =3D shift; - my $pub =3D shift || die 'Publication is required'; - my $sync =3D shift; - - my $qpub =3D $self->{DBH}->quote($pub); - my $quser =3D $self->{DBH}->quote($self->{user}); - my $qnode =3D $self->{DBH}->quote($self->{node}); - - #enforce refresh and refreshonce flags - undef $sync if !$self->{pubs}->{$pub};=20 - - - my %info =3D $self->{current}; - - my @cols =3D $self->GetColList("select col_name from ____subscribed_cols__= -__ where username =3D $quser and nodename =3D $qnode and pubname =3D $qpub"= -);; - - my ($table) =3D $self->GetOneRow("select tablename from ____publications__= -__ where pubname =3D $qpub"); - return 'Table incorrectly registered for read' if !defined($table); - my $qtable =3D $self->{DBH}->quote($table);=09 - - - my $sql =3D "select pubname, last_session, post_ver, last_ver, whereclause= - from ____subscribed____ where username =3D $quser and pubname =3D $qpub an= -d nodename =3D $qnode"; - my ($junk, $last_session, $post_ver, $last_ver, $whereclause) =3D $self->G= -etOneRow($sql); - - my ($wc) =3D $self->GetOneRow("select whereclause from ____publications___= -_ where pubname =3D $qpub"); - - $whereclause =3D '('.$whereclause.')' if $whereclause; - - $whereclause =3D $whereclause.' and ('.$wc.')' if $wc; - - - if ($sync) { - $self->writeclient('start synchronize', $pub); - } else { - $self->writeclient('start refresh', $pub); - $self->{DBH}->do("update ____subscribed____ set refreshonce =3D false whe= -re pubname =3D $qpub and username =3D $quser and nodename =3D $qnode") || r= -eturn 'Failed to clear RefreshOnce flag: '.$self->{DBH}->errstr; - } - - $self->writeclient('columns',@cols); - - - - my $sql =3D "select ____rowid____, ".join(',', @cols)." from $table"; - if ($sync) { - $sql =3D $sql." where (____rowver____ <=3D $self->{max_ver} and ____rowve= -r____ > $last_ver)"; - if (defined($self->{this_post_ver})) { - $sql =3D $sql . " and (____rowver____ <> $post_ver)"; - } - } else { - $sql =3D $sql." where (____rowver____ <=3D $self->{max_ver})"; - } - $sql =3D $sql." and $whereclause" if $whereclause; -=09 - my $sth =3D $self->{DBH}->prepare($sql) || return 'Failed to get prepare S= -QL for updates: '.$self->{DBH}->errstr; - $sth->execute || return 'Failed to execute SQL for updates: '.$self->{DBH}= -->errstr; - my @row; - while (@row =3D $sth->fetchrow_array) { - $self->writeclient('update/insert',@row); - } - - $sth->finish; - - # now get deleted rows - if ($sync) { - $sql =3D "select rowid from ____deleted____ where (tablename =3D $qtable)= -"; - $sql =3D $sql." and (rowver <=3D $self->{max_ver} and rowver > $last_ver)= -"; - if (defined($self->{this_post_ver})) { - $sql =3D $sql . " and (rowver <> $self->{this_post_ver})"; - } - $sql =3D $sql." and $whereclause" if $whereclause; - - $sth =3D $self->{DBH}->prepare($sql) || return 'Failed to get prepare SQL= - for deletes: '.$self->{DBH}->errstr; - $sth->execute || return 'Failed to execute SQL for deletes: '.$self->{DBH= -}->errstr; - my @row; - while (@row =3D $sth->fetchrow_array) { - $self->writeclient('delete',@row); - } - - $sth->finish; - } - - if ($sync) { - $self->writeclient('end synchronize', $pub); - } else { - $self->writeclient('end refresh', $pub); - } - - my $qpub =3D $self->{DBH}->quote($pub); - my $quser =3D $self->{DBH}->quote($self->{user}); - my $qnode =3D $self->{DBH}->quote($self->{node}); - - $self->{DBH}->do("update ____subscribed____ set last_ver =3D $self->{max_v= -er}, last_session =3D now(), post_ver =3D $self->{this_post_ver} where user= -name =3D $quser and nodename =3D $qnode and pubname =3D $qpub"); - return undef; -} - - -# Call this once when everything else is done. Does housekeeping.=20 -# (MAKE THIS AN OBJECT DESTRUCTOR?) -sub DESTROY { - my $self =3D shift; - -#release version from lock table (including old ones) - my $quser =3D $self->{DBH}->quote($self->{user}); - my $qnode =3D $self->{DBH}->quote($self->{node}); - my $sql =3D "delete from ____last_stable____ where username =3D $quser and= - nodename =3D $qnode"; - $self->{DBH}->do($sql); - -#clean up deleted table - my ($version) =3D $self->GetOneRow("select min(last_ver) from ____subscrib= -ed____"); - return undef if not defined $version; - $self->{DBH}->do("delete from ____deleted____ where rowver < $version") ||= - return 'Failed to prune deleted table'.$self->{DBH}->errstr;; - - -#disconnect from DBD sessions - $self->{DBH}->disconnect; - $self->{DBLOG}->disconnect; - return undef; -} - -############# Helper Subs ############ -sub GetColList { - my $self =3D shift; - my $sql =3D shift || die 'Must provide sql select statement'; - my $sth =3D $self->{DBH}->prepare($sql) || return undef; - $sth->execute || return undef; - my $val; - my @col; - while (($val) =3D $sth->fetchrow_array) { - push @col, $val; - } - $sth->finish; - return @col; -} - -sub GetOneRow { - my $self =3D shift; - my $sql =3D shift || die 'Must provide sql select statement'; - my $sth =3D $self->{DBH}->prepare($sql) || return undef; - $sth->execute || return undef; - my @row =3D $sth->fetchrow_array; - $sth->finish; - return @row; -} - -=20 - - - -package SyncManager; - -use DBI; -# new requires 3 arguments: dbi connection string, plus the corresponding u= -sername and password - -sub new { - my $proto =3D shift; - my $class =3D ref($proto) || $proto; - my $self =3D {}; - - my $dbi =3D shift; - my $user =3D shift; - my $pass =3D shift; - - $self->{DBH} =3D DBI->connect($dbi,$user,$pass) || die "Failed to connect = -to database: ".DBI->errstr(); - - $self->{DBLOG}=3D DBI->connect($dbi,$user,$pass) || die "cannot log to DB:= - ".DBI->errstr(); -=09 - return bless ($self, $class); -} - -sub dblog {=20 - my $self =3D shift; - my $msg =3D $self->{DBLOG}->quote($_[0]); - my $quser =3D $self->{DBH}->quote($self->{user}); - my $qnode =3D $self->{DBH}->quote($self->{node}); - $self->{DBLOG}->do("insert into ____sync_log____ (username, nodename,stamp= -, message) values($quser, $qnode, now(), $msg)"); -} - -#this should never need to be called, but it might if a node bails without = -releasing their locks -sub ReleaseAllLocks { - my $self =3D shift; - $self->{DBH}->do("delete from ____last_stable____)"); -} -# Adds a publication to the system. Also adds triggers, sequences, etc ass= -ociated with the table if approproate. - # accepts two argument: the name of a physical table and the name under wh= -ich to publish it=20 - # NOTE: the publication name is optional and will default to the table na= -me if not supplied - # returns undef if ok, else error string; -sub publish { - my $self =3D shift; - my $table =3D shift || die 'You must provide a table name (and optionally = -a unique publication name)'; - my $pub =3D shift; - $pub =3D $table if not defined($pub); - - my $qpub =3D $self->{DBH}->quote($pub); - my $sql =3D "select tablename from ____publications____ where pubname =3D = -$qpub"; - my ($junk) =3D $self->GetOneRow($sql); - return 'Publication already exists' if defined($junk); - - my $qtable =3D $self->{DBH}->quote($table); - - $sql =3D "select table_id, refcount from ____tables____ where tablename = -=3D $qtable"; - my ($id, $refcount) =3D $self->GetOneRow($sql); - - if(!defined($id)) { - $self->{DBH}->do("insert into ____tables____ (tablename, refcount) values= - ($qtable,1)") || return 'Failed to register table: ' . $self->{DBH}->errst= -r; - my $sql =3D "select table_id from ____tables____ where tablename =3D $qta= -ble"; - ($id) =3D $self->GetOneRow($sql); - } - - if (defined($refcount)) { - $self->{DBH}->do("update ____tables____ set refcount =3D refcount+1 where= - table_id =3D $id") || return 'Failed to update refrence count: ' . $self->= -{DBH}->errstr; - } else { -=09=09 - $id =3D '_'.$id.'_';=20 - - my @cols =3D $self->GetTableCols($table, 1); # 1 =3D get hidden cols too - my %skip; - foreach my $col (@cols) { - $skip{$col} =3D 1; - } -=09=09 - if (!$skip{____rowver____}) { - $self->{DBH}->do("alter table $table add column ____rowver____ int4"); #= -don't fail here in case table is being republished, just accept the error s= -ilently - } - $self->{DBH}->do("update $table set ____rowver____ =3D ____version_seq___= -_.last_value - 1") || return 'Failed to initialize rowver: ' . $self->{DBH}= -->errstr; - - if (!$skip{____rowid____}) { - $self->{DBH}->do("alter table $table add column ____rowid____ int4"); #d= -on't fail here in case table is being republished, just accept the error si= -lently - } - - my $index =3D $id.'____rowid____idx'; - $self->{DBH}->do("create index $index on $table(____rowid____)") || retur= -n 'Failed to create rowid index: ' . $self->{DBH}->errstr; - - my $sequence =3D $id.'_rowid_seq'; - $self->{DBH}->do("create sequence $sequence") || return 'Failed to create= - rowver sequence: ' . $self->{DBH}->errstr; - - $self->{DBH}->do("alter table $table alter column ____rowid____ set defau= -lt nextval('$sequence')"); #don't fail here in case table is being republis= -hed, just accept the error silently - - $self->{DBH}->do("update $table set ____rowid____ =3D nextval('$sequence= -')") || return 'Failed to initialize rowid: ' . $self->{DBH}->errstr; - - if (!$skip{____stamp____}) { - $self->{DBH}->do("alter table $table add column ____stamp____ timestamp"= -); #don't fail here in case table is being republished, just accept the err= -or silently - } - - $self->{DBH}->do("update $table set ____stamp____ =3D now()") || return = -'Failed to initialize stamp: ' . $self->{DBH}->errstr; - - my $trigger =3D $id.'_ver_ins'; - $self->{DBH}->do("create trigger $trigger before insert on $table for eac= -h row execute procedure sync_insert_ver()") || return 'Failed to create tri= -gger: ' . $self->{DBH}->errstr; - - my $trigger =3D $id.'_ver_upd'; - $self->{DBH}->do("create trigger $trigger before update on $table for eac= -h row execute procedure sync_update_ver()") || return 'Failed to create tri= -gger: ' . $self->{DBH}->errstr; - - my $trigger =3D $id.'_del_row'; - $self->{DBH}->do("create trigger $trigger after delete on $table for each= - row execute procedure sync_delete_row()") || return 'Failed to create trig= -ger: ' . $self->{DBH}->errstr; - } - - $self->{DBH}->do("insert into ____publications____ (pubname, tablename) va= -lues ('$pub','$table')") || return 'Failed to create publication entry: '.$= -self->{DBH}->errstr; - - return undef; -} - - -# Removes a publication from the system. Also drops triggers, sequences, e= -tc associated with the table if approproate. - # accepts one argument: the name of a publication - # returns undef if ok, else error string; -sub unpublish { - my $self =3D shift; - my $pub =3D shift || return 'You must provide a publication name'; - my $qpub =3D $self->{DBH}->quote($pub); - my $sql =3D "select tablename from ____publications____ where pubname =3D = -$qpub"; - my ($table) =3D $self->GetOneRow($sql); - return 'Publication does not exist' if !defined($table); - - my $qtable =3D $self->{DBH}->quote($table); - - $sql =3D "select table_id, refcount from ____tables____ where tablename = -=3D $qtable"; - my ($id, $refcount) =3D $self->GetOneRow($sql); - return 'Table: $table is not correctly registered!' if not defined($id); - - $self->{DBH}->do("update ____tables____ set refcount =3D refcount -1 where= - tablename =3D $qtable") || return 'Failed to decrement reference count: ' = -. $self->{DBH}->errstr; - - $self->{DBH}->do("delete from ____subscribed____ where pubname =3D $qpub")= - || return 'Failed to delete user subscriptions: ' . $self->{DBH}->errstr; - $self->{DBH}->do("delete from ____subscribed_cols____ where pubname =3D $q= -pub") || return 'Failed to delete subscribed columns: ' . $self->{DBH}->err= -str; - $self->{DBH}->do("delete from ____publications____ where tablename =3D $qt= -able and pubname =3D $qpub") || return 'Failed to delete from publications:= - ' . $self->{DBH}->errstr; - - #if this is the last reference, we want to drop triggers, etc; - if ($refcount <=3D 1) { - $id =3D "_".$id."_"; - - $self->{DBH}->do("alter table $table alter column ____rowver____ drop def= -ault") || return 'Failed to alter column default: ' . $self->{DBH}->errstr; - $self->{DBH}->do("alter table $table alter column ____rowid____ drop defa= -ult") || return 'Failed to alter column default: ' . $self->{DBH}->errstr; - $self->{DBH}->do("alter table $table alter column ____stamp____ drop defa= -ult") || return 'Failed to alter column default: ' . $self->{DBH}->errstr; - - my $trigger =3D $id.'_ver_upd'; - $self->{DBH}->do("drop trigger $trigger on $table") || return 'Failed to = -drop trigger: ' . $self->{DBH}->errstr; - - my $trigger =3D $id.'_ver_ins'; - $self->{DBH}->do("drop trigger $trigger on $table") || return 'Failed to = -drop trigger: ' . $self->{DBH}->errstr; - - my $trigger =3D $id.'_del_row'; - $self->{DBH}->do("drop trigger $trigger on $table") || return 'Failed to = -drop trigger: ' . $self->{DBH}->errstr; - - my $sequence =3D $id.'_rowid_seq'; - $self->{DBH}->do("drop sequence $sequence") || return 'Failed to drop seq= -uence: ' . $self->{DBH}->errstr; - - my $index =3D $id.'____rowid____idx'; - $self->{DBH}->do("drop index $index") || return 'Failed to drop index: ' = -. $self->{DBH}->errstr; - $self->{DBH}->do("delete from ____tables____ where tablename =3D $qtable"= -) || return 'remove entry from tables: ' . $self->{DBH}->errstr; - } -return undef; -} - - - - - -#Subscribe user/node to a publication - # Accepts 3 arguements: Username, Nodename, Publication - # NOTE: the remaining arguments can be supplied as column names to which = -the user/node should be subscribed - # Return undef if ok, else returns an error string - -sub subscribe { - my $self =3D shift; - my $user =3D shift || die 'You must provide user, node and publication as = -arguments'; - my $node =3D shift || die 'You must provide user, node and publication as = -arguments'; - my $pub =3D shift || die 'You must provide user, node and publication as a= -rguments'; - my @cols =3D @_; - - my $quser =3D $self->{DBH}->quote($user); - my $qnode =3D $self->{DBH}->quote($node); - my $qpub =3D $self->{DBH}->quote($pub); - - my $sql =3D "select tablename from ____publications____ where pubname =3D = -$qpub"; - my ($table) =3D $self->GetOneRow($sql); - return "Publication $pub does not exist." if not defined $table; - my $qtable =3D $self->{DBH}->quote($table); - - @cols =3D $self->GetTableCols($table) if !@cols; # get defaults if cols we= -re not spefified by caller - - $self->{DBH}->do("insert into ____subscribed____ (username, nodename,pubna= -me,last_ver,refreshonce) values('$user', '$node','$pub',0, true)") || retur= -n 'Failes to create subscription: ' . $self->{DBH}->errstr;=09 - - foreach my $col (@cols) { - $self->{DBH}->do("insert into ____subscribed_cols____ (username, nodename= -, pubname, col_name) values ('$user','$node','$pub','$col')") || return 'Fa= -iles to subscribe column: ' . $self->{DBH}->errstr;=09 - } - - return undef; -} - - -#Unsubscribe user/node to a publication - # Accepts 3 arguements: Username, Nodename, Publication - # Return undef if ok, else returns an error string - -sub unsubscribe { - my $self =3D shift; - my $user =3D shift || die 'You must provide user, node and publication as = -arguments'; - my $node =3D shift || die 'You must provide user, node and publication as = -arguments'; - my $pub =3D shift || die 'You must provide user, node and publication as a= -rguments'; - my @cols =3D @_; - - my $quser =3D $self->{DBH}->quote($user); - my $qnode =3D $self->{DBH}->quote($node); - my $qpub =3D $self->{DBH}->quote($pub); - - my $sql =3D "select tablename from ____publications____ where pubname =3D = -$qpub"; - my $table =3D $self->GetOneRow($sql); - return "Publication $pub does not exist." if not defined $table; - - $self->{DBH}->do("delete from ____subscribed_cols____ where pubname =3D $q= -pub and username =3D $quser and nodename =3D $qnode") || return 'Failed to = -remove column subscription: '. $self->{DBH}->errstr; - $self->{DBH}->do("delete from ____subscribed____ where pubname =3D $qpub a= -nd username =3D $quser and nodename =3D $qnode") || return 'Failed to remov= -e subscription: '. $self->{DBH}->errstr; - - - return undef; -} - - - -#INSTALL creates the necessary management tables.=20=20 - #returns undef if everything is ok, else returns a string describing the e= -rror; -sub INSTALL { -my $self =3D shift; - -#check to see if management tables are already installed - -my ($test) =3D $self->GetOneRow("select * from pg_class where relname =3D '= -____publications____'"); -if (defined($test)) { - return 'It appears that synchronization manangement tables are already ins= -talled here. Please uninstall before reinstalling.'; -}; - - - -#install the management tables, etc. - -$self->{DBH}->do("create table ____publications____ (pubname text primary k= -ey,description text, tablename text, sync_order int4, whereclause text)") |= -| return $self->{DBH}->errstr(); - -$self->{DBH}->do("create table ____subscribed_cols____ (nodename text, user= -name text, pubname text, col_name text, description text, primary key(noden= -ame, username, pubname,col_name))") || return $self->{DBH}->errstr(); - -$self->{DBH}->do("create table ____subscribed____ (nodename text, username = -text, pubname text, last_session timestamp, post_ver int4, last_ver int4, w= -hereclause text, sanity_limit int4 default 0, sanity_delete int4 default 0,= - sanity_update int4 default 0, sanity_insert int4 default 50, readonly bool= -ean, disabled boolean, fullrefreshonly boolean, refreshonce boolean, primar= -y key(nodename, username, pubname))") || return $self->{DBH}->errstr(); - -$self->{DBH}->do("create table ____last_stable____ (version int4, username = -text, nodename text, primary key(version, username, nodename))") || return = -$self->{DBH}->errstr(); - -$self->{DBH}->do("create table ____tables____ (tablename text, table_id int= -4, refcount int4, primary key(tablename, table_id))") || return $self->{DBH= -}->errstr(); - -$self->{DBH}->do("create sequence ____table_id_seq____") || return $self->{= -DBH}->errstr(); - -$self->{DBH}->do("alter table ____tables____ alter column table_id set defa= -ult nextval('____table_id_seq____')") || return $self->{DBH}->errstr(); - -$self->{DBH}->do("create table ____deleted____ (rowid int4, tablename text,= - rowver int4, stamp timestamp, primary key (rowid, tablename))") || return = -$self->{DBH}->errstr(); - -$self->{DBH}->do("create table ____collision____ (rowid text, tablename tex= -t, rowver int4, stamp timestamp, faildate timestamp default now(),data text= -,reason text, action text, username text, nodename text,queue text)") || re= -turn $self->{DBH}->errstr(); - -$self->{DBH}->do("create sequence ____version_seq____") || return $self->{D= -BH}->errstr(); - -$self->{DBH}->do("create table ____sync_log____ (username text, nodename te= -xt, stamp timestamp, message text)") || return $self->{DBH}->errstr(); - -$self->{DBH}->do("create function sync_insert_ver() returns opaque as -'begin -if new.____rowver____ isnull then -new.____rowver____ :=3D ____version_seq____.last_value; -end if; -if new.____stamp____ isnull then -new.____stamp____ :=3D now(); -end if; -return NEW; -end;' language 'plpgsql'") || return $self->{DBH}->errstr(); - -$self->{DBH}->do("create function sync_update_ver() returns opaque as -'begin -if new.____rowver____ =3D old.____rowver____ then -new.____rowver____ :=3D ____version_seq____.last_value; -end if; -if new.____stamp____ =3D old.____stamp____ then -new.____stamp____ :=3D now(); -end if; -return NEW; -end;' language 'plpgsql'") || return $self->{DBH}->errstr(); - - -$self->{DBH}->do("create function sync_delete_row() returns opaque as=20 -'begin=20 -insert into ____deleted____ (rowid,tablename,rowver,stamp) values -(old.____rowid____, TG_RELNAME, old.____rowver____,old.____stamp____);=20 -return old;=20 -end;' language 'plpgsql'") || return $self->{DBH}->errstr(); - -return undef; -} - -#removes all management tables & related stuff - #returns undef if ok, else returns an error message as a string -sub UNINSTALL { -my $self =3D shift; - -#Make sure all tables are unpublished first -my $sth =3D $self->{DBH}->prepare("select pubname from ____publications____= -"); -$sth->execute; -my $pub; -while (($pub) =3D $sth->fetchrow_array) { - $self->unpublish($pub);=09 -} -$sth->finish; - -$self->{DBH}->do("drop table ____publications____") || return $self->{DBH}-= ->errstr(); -$self->{DBH}->do("drop table ____subscribed_cols____") || return $self->{DB= -H}->errstr(); -$self->{DBH}->do("drop table ____subscribed____") || return $self->{DBH}->e= -rrstr(); -$self->{DBH}->do("drop table ____last_stable____") || return $self->{DBH}->= -errstr(); -$self->{DBH}->do("drop table ____deleted____") || return $self->{DBH}->errs= -tr(); -$self->{DBH}->do("drop table ____collision____") || return $self->{DBH}->er= -rstr(); -$self->{DBH}->do("drop table ____tables____") || return $self->{DBH}->errst= -r(); -$self->{DBH}->do("drop table ____sync_log____") || return $self->{DBH}->err= -str(); - -$self->{DBH}->do("drop sequence ____table_id_seq____") || return $self->{DB= -H}->errstr(); -$self->{DBH}->do("drop sequence ____version_seq____") || return $self->{DBH= -}->errstr(); - -$self->{DBH}->do("drop function sync_insert_ver()") || return $self->{DBH}-= ->errstr(); -$self->{DBH}->do("drop function sync_update_ver()") || return $self->{DBH}-= ->errstr(); -$self->{DBH}->do("drop function sync_delete_row()") || return $self->{DBH}-= ->errstr(); - -return undef; - -} - -sub DESTROY { - my $self =3D shift; - - $self->{DBH}->disconnect; - $self->{DBLOG}->disconnect; - return undef; -} - -############# Helper Subs ############ - -sub GetOneRow { - my $self =3D shift; - my $sql =3D shift || die 'Must provide sql select statement'; - my $sth =3D $self->{DBH}->prepare($sql) || return undef; - $sth->execute || return undef; - my @row =3D $sth->fetchrow_array; - $sth->finish; - return @row; -} - -#call this with second non-zero value to get hidden columns -sub GetTableCols { - my $self =3D shift; - my $table =3D shift || die 'Must provide table name'; - my $wanthidden =3D shift; - my $sql =3D "select * from $table where 0 =3D 1"; - my $sth =3D $self->{DBH}->prepare($sql) || return undef; - $sth->execute || return undef; - my @row =3D @{$sth->{NAME}}; - $sth->finish; - return @row if $wanthidden; - my @cols; - foreach my $col (@row) { - next if $col eq '____rowver____'; - next if $col eq '____stamp____'; - next if $col eq '____rowid____'; - push @cols, $col;=09 - } - return @cols; -} - - -1; #happy require - -------=_NextPart_000_0062_01C0541E.125CAF30-- - - -From pgsql-hackers-owner+M9917@postgresql.org Mon Jun 11 15:53:25 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f5BJrPL01206 - for ; Mon, 11 Jun 2001 15:53:25 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5BJrPE67753; - Mon, 11 Jun 2001 15:53:25 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9917@postgresql.org) -Received: from mail.greatbridge.com (mail.greatbridge.com [65.196.68.36]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f5BJmLE65620 - for ; Mon, 11 Jun 2001 15:48:21 -0400 (EDT) - (envelope-from djohnson@greatbridge.com) -Received: from j2.us.greatbridge.com (djohnsonpc.us.greatbridge.com [65.196.69.70]) - by mail.greatbridge.com (8.11.2/8.11.2) with SMTP id f5BJm2Q28847 - for ; Mon, 11 Jun 2001 15:48:02 -0400 -From: Darren Johnson -Date: Mon, 11 Jun 2001 19:46:44 GMT -Message-ID: <20010611.19464400@j2.us.greatbridge.com> -Subject: [HACKERS] Postgres Replication -To: pgsql-hackers@postgresql.org -Reply-To: Darren Johnson -X-Mailer: Mozilla/3.0 (compatible; StarOffice/5.2;Linux) -X-Priority: 3 (Normal) -MIME-Version: 1.0 -Content-Type: text/plain; charset=ISO-8859-1 -Content-Transfer-Encoding: 8bit -X-MIME-Autoconverted: from quoted-printable to 8bit by postgresql.org id f5BJmLE65621 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -We have been researching replication for several months now, and -I have some opinions to share to the community for feedback, -discussion, and/or participation. Our goal is to get a replication -solution for PostgreSQL that will meet most needs of users -and applications alike (mission impossible theme here :). - -My research work along with others contributors has been collected -and presented here http://www.greatbridge.org/genpage?replication_top -If there is something missing, especially PostgreSQL related -work, I would like to know about it, and my apologies to any -one who got left off the list. This work is ongoing and doesn't -draw a conclusion, which IMHO should be left up to the user, -but I'm offering my opinions to spur discussion and/or feed back -from this list, and try not to offend any one. - -Here's my opinion: of the approaches we've surveyed, the most -promising one is the Postgres-R project from the Information and -Communication Systems Group, ETH in Zurich, Switzerland, originally -produced by Bettina Kemme, Gustavo Alonso, and others. Although -Postgres-R is a synchronous approach, I believe it is the closest to -the goal mentioned above. Here is an abstract of the advantages. - -1) Postgres-R is built on the PostgreSQL-6.4.2 code base. The -replication -functionality is an optional parameter, so there will be insignificant -overhead for non replication situations. The replication and -communication -managers are the two new modules added to the PostgreSQL code base. - -2) The replication manager's main function is controlling the -replication protocol via a message handling process. It receives -messages from the local and remote backends and forwards write -sets and decision messages via the communication manager to the -other servers. The replication manager controls all the transactions -running on the local server by keeping track of the states, including -which protocol phase (read, send, lock, or write) the transaction is -in. The replication manager maintains a two way channel -implemented as buffered sockets to each backend. - -3) The main task of the communication manager is to provide simple -socket based interface between the replication manager and the -group communication system (currently Ensemble). The -communication system is a cluster of servers connected via -the communication manager. The replication manager also maintains -three one-way channels to the communication system: a broadcast -channel to send messages, a total-order channel to receive -totally orders write sets, and a no-order channel to listen for -decision messages from the communication system. Decision -messages can be received at any time where the reception of -totally ordered write sets can be blocked in certain phases. - -4) Based on a two phase locking approach, all dead lock situations -are local and detectable by Postgres-R code base, and aborted. - -5) The write set messages used to send database changes to other -servers, can use either the SQL statements or the actual tuples -changed. This is a parameter based on number of tuples changed -by a transaction. While sending the tuple changes reduces -overhead in query parse, plan and execution, there is a negative -effect in sending a large write set across the network. - -6) Postgres-R uses a synchronous approach that keeps the data on -all sites consistent and provides serializability. The user does not -have to bother with conflict resolution, and receives the same -correctness and consistency of a centralized system. - -7) Postgres-R could be part of a good fault-resilient and load -distribution -solution. It is peer-to-peer based and incurs low overhead propagating -updates to the other cluster members. All replicated databases locally -process queries. - -8) Compared to other synchronous replication strategies (e.g., standard -distributed 2-phase-locking + 2-phase-commit), Postgres-R has much -better performance using 2-phase-locking. - - -There are some issues that are not currently addressed by -Postgres-R, but some enhancements made to PostgreSQL since the -6.4.2 tree are very favorable to addressing these short comings. - -1) The addition of WAL in 7.1 has the information for recovering -failed/off-line servers, currently all the servers would have to be -stopped, and a copy would be used to get all the servers synchronized -before starting again. - -2)Being synchronous, Postgres-R would not be a good solution -for off line/WAN scenarios where asynchronous replication is -required. There are some theories on this issue which involve servers -connecting and disconnecting from the cluster. - -3)As in any serialized synchronous approach there is change in the -flow of execution of a transaction; while most of these changes can -be solved by calling newly developed functions at certain time points, -synchronous replica control is tightly coupled with the concurrency -control. -Hence, especially in PostgreSQL 7.2 some parts of the concurrency control -(MVCC) might have to be adjusted. This can lead to a slightly more -complicated maintenance than a system that does not change the backend. - -4)Partial replication is not addressed. - - -Any feedback on this post will be appreciated. - -Thanks, - -Darren - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M9923@postgresql.org Mon Jun 11 18:14:23 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f5BMENL18644 - for ; Mon, 11 Jun 2001 18:14:23 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5BMEQE14877; - Mon, 11 Jun 2001 18:14:26 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9923@postgresql.org) -Received: from spoetnik.xs4all.nl (spoetnik.xs4all.nl [194.109.249.226]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f5BM6ME12270 - for ; Mon, 11 Jun 2001 18:06:23 -0400 (EDT) - (envelope-from reinoud@xs4all.nl) -Received: from KAYAK (kayak [192.168.1.20]) - by spoetnik.xs4all.nl (Postfix) with SMTP id 865A33E1B - for ; Tue, 12 Jun 2001 00:06:16 +0200 (CEST) -From: reinoud@xs4all.nl (Reinoud van Leeuwen) -To: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Postgres Replication -Date: Mon, 11 Jun 2001 22:06:07 GMT -Organization: Not organized in any way -Reply-To: reinoud@xs4all.nl -Message-ID: <3b403d96.562404297@192.168.1.10> -References: <20010611.19464400@j2.us.greatbridge.com> -In-Reply-To: <20010611.19464400@j2.us.greatbridge.com> -X-Mailer: Forte Agent 1.5/32.451 -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 8bit -X-MIME-Autoconverted: from quoted-printable to 8bit by postgresql.org id f5BM6PE12276 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Mon, 11 Jun 2001 19:46:44 GMT, you wrote: - ->We have been researching replication for several months now, and ->I have some opinions to share to the community for feedback, ->discussion, and/or participation. Our goal is to get a replication ->solution for PostgreSQL that will meet most needs of users ->and applications alike (mission impossible theme here :). -> ->My research work along with others contributors has been collected ->and presented here http://www.greatbridge.org/genpage?replication_top ->If there is something missing, especially PostgreSQL related ->work, I would like to know about it, and my apologies to any ->one who got left off the list. This work is ongoing and doesn't ->draw a conclusion, which IMHO should be left up to the user, ->but I'm offering my opinions to spur discussion and/or feed back ->from this list, and try not to offend any one. -> ->Here's my opinion: of the approaches we've surveyed, the most ->promising one is the Postgres-R project from the Information and ->Communication Systems Group, ETH in Zurich, Switzerland, originally ->produced by Bettina Kemme, Gustavo Alonso, and others. Although ->Postgres-R is a synchronous approach, I believe it is the closest to ->the goal mentioned above. Here is an abstract of the advantages. -> ->1) Postgres-R is built on the PostgreSQL-6.4.2 code base. The ->replication ->functionality is an optional parameter, so there will be insignificant ->overhead for non replication situations. The replication and ->communication ->managers are the two new modules added to the PostgreSQL code base. -> ->2) The replication manager's main function is controlling the ->replication protocol via a message handling process. It receives ->messages from the local and remote backends and forwards write ->sets and decision messages via the communication manager to the ->other servers. The replication manager controls all the transactions ->running on the local server by keeping track of the states, including ->which protocol phase (read, send, lock, or write) the transaction is ->in. The replication manager maintains a two way channel ->implemented as buffered sockets to each backend. - -what does "manager controls all the transactions" mean? I hope it does -*not* mean that a bug in the manager would cause transactions not to -commit... - -> ->3) The main task of the communication manager is to provide simple ->socket based interface between the replication manager and the ->group communication system (currently Ensemble). The ->communication system is a cluster of servers connected via ->the communication manager. The replication manager also maintains ->three one-way channels to the communication system: a broadcast ->channel to send messages, a total-order channel to receive ->totally orders write sets, and a no-order channel to listen for ->decision messages from the communication system. Decision ->messages can be received at any time where the reception of ->totally ordered write sets can be blocked in certain phases. -> ->4) Based on a two phase locking approach, all dead lock situations ->are local and detectable by Postgres-R code base, and aborted. - -Does this imply locking over different servers? That would mean a -grinding halt when a network outage occurs... - ->5) The write set messages used to send database changes to other ->servers, can use either the SQL statements or the actual tuples ->changed. This is a parameter based on number of tuples changed ->by a transaction. While sending the tuple changes reduces ->overhead in query parse, plan and execution, there is a negative ->effect in sending a large write set across the network. -> ->6) Postgres-R uses a synchronous approach that keeps the data on ->all sites consistent and provides serializability. The user does not ->have to bother with conflict resolution, and receives the same ->correctness and consistency of a centralized system. -> ->7) Postgres-R could be part of a good fault-resilient and load ->distribution ->solution. It is peer-to-peer based and incurs low overhead propagating ->updates to the other cluster members. All replicated databases locally ->process queries. -> ->8) Compared to other synchronous replication strategies (e.g., standard ->distributed 2-phase-locking + 2-phase-commit), Postgres-R has much ->better performance using 2-phase-locking. - -Coming from a Sybase background I have some experience with -replication. The way it works in Sybase Replication server is as -follows: -- for each replicated database, there is a "log reader" process that -reads the WAL and captures only *committed transactions* to the -replication server. (it does not make much sense to replicate other -things IMHO :-). -- the replication server stores incoming data in a que ("stable -device"), until it is sure it has reached its final destination - -- a replication server can send data to another replication server in -a compact (read: WAN friendly) way. A chain of replication servers can -be made, depending on network architecture) - -- the final replication server makes a almost standard client -connection to the target database and translates the compact -transactions back to SQL statements. By using masks, extra -functionality can be built in. - -This kind of architecture has several advantages: -- only committed transactions are replicated which saves overhead -- it does not have very much impact on performance of the source -server (apart from reading the WAL) -- since every replication server has a stable device, data is stored -when the network is down and nothing gets lost (nor stops performing) -- because only the log reader and the connection from the final -replication server are RDBMS specific, it is possible to replicate -from MS to Oracle using a Sybase replication server (or different -versions etc). - -I do not know how much of this is patented or copyrighted, but the -architecture seems elegant and robust to me. I have done -implementations of bi-directional replication too. It *is* possible -but does require some funky setup and maintenance. (but it is better -that letting offices on different continents working on the same -database :-) - -just my 2 EURO cts :-) - - --- -__________________________________________________ -"Nothing is as subjective as reality" -Reinoud van Leeuwen reinoud@xs4all.nl -http://www.xs4all.nl/~reinoud -__________________________________________________ - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M9924@postgresql.org Mon Jun 11 18:41:51 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f5BMfpL28917 - for ; Mon, 11 Jun 2001 18:41:51 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5BMfsE25092; - Mon, 11 Jun 2001 18:41:54 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9924@postgresql.org) -Received: from spider.pilosoft.com (p55-222.acedsl.com [160.79.55.222]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f5BMalE23024 - for ; Mon, 11 Jun 2001 18:36:47 -0400 (EDT) - (envelope-from alex@pilosoft.com) -Received: from localhost (alexmail@localhost) - by spider.pilosoft.com (8.9.3/8.9.3) with ESMTP id SAA06092; - Mon, 11 Jun 2001 18:46:05 -0400 (EDT) -Date: Mon, 11 Jun 2001 18:46:05 -0400 (EDT) -From: Alex Pilosov -To: Reinoud van Leeuwen -cc: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Postgres Replication -In-Reply-To: <3b403d96.562404297@192.168.1.10> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Mon, 11 Jun 2001, Reinoud van Leeuwen wrote: - -> On Mon, 11 Jun 2001 19:46:44 GMT, you wrote: - -> what does "manager controls all the transactions" mean? I hope it does -> *not* mean that a bug in the manager would cause transactions not to -> commit... -Well yeah it does. Bugs are a fact of life. :) - -> >4) Based on a two phase locking approach, all dead lock situations -> >are local and detectable by Postgres-R code base, and aborted. -> -> Does this imply locking over different servers? That would mean a -> grinding halt when a network outage occurs... -Don't know, but see below. - -> Coming from a Sybase background I have some experience with -> replication. The way it works in Sybase Replication server is as -> follows: -> - for each replicated database, there is a "log reader" process that -> reads the WAL and captures only *committed transactions* to the -> replication server. (it does not make much sense to replicate other -> things IMHO :-). -> - the replication server stores incoming data in a que ("stable -> device"), until it is sure it has reached its final destination -> -> - a replication server can send data to another replication server in -> a compact (read: WAN friendly) way. A chain of replication servers can -> be made, depending on network architecture) -> -> - the final replication server makes a almost standard client -> connection to the target database and translates the compact -> transactions back to SQL statements. By using masks, extra -> functionality can be built in. -> -> This kind of architecture has several advantages: -> - only committed transactions are replicated which saves overhead -> - it does not have very much impact on performance of the source -> server (apart from reading the WAL) -> - since every replication server has a stable device, data is stored -> when the network is down and nothing gets lost (nor stops performing) -> - because only the log reader and the connection from the final -> replication server are RDBMS specific, it is possible to replicate -> from MS to Oracle using a Sybase replication server (or different -> versions etc). -> -> I do not know how much of this is patented or copyrighted, but the -> architecture seems elegant and robust to me. I have done -> implementations of bi-directional replication too. It *is* possible -> but does require some funky setup and maintenance. (but it is better -> that letting offices on different continents working on the same -> database :-) -Yes, the above architecture is what almost every vendor of replication -software uses. And I'm sure if you worked much with Sybase, you hate the -garbage that their repserver is :). - -The architecture of postgres-r and repserver are fundamentally different -for a good reason: repserver only wants to replicate committed -transactions, while postgres-r is more of a 'clustering' solution (albeit -they don't say this word), and is capable to do much more than simple rep -server. - -I.E. you can safely put half of your clients to second server in a -replicated postgres-r cluster without being worried that a conflict (or a -wierd locking situation) may occur. - -Try that with sybase, it is fundamentally designed for one-way -replication, and the fact that you can do one-way replication in both -directions doesn't mean its safe to do that! - -I'm not sure how postgres-r handles network problems. To be useful, a good -replication solution must have an option of "no network->no updates" as -well as "no network->queue updates and send them later". However, it is -far easier to add queuing to a correct 'eager locking' database than it is -to add proper locking to a queue-based replicator. - --alex - - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M9932@postgresql.org Mon Jun 11 22:17:54 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f5C2HsL15803 - for ; Mon, 11 Jun 2001 22:17:54 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5C2HtE86836; - Mon, 11 Jun 2001 22:17:55 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9932@postgresql.org) -Received: from femail15.sdc1.sfba.home.com (femail15.sdc1.sfba.home.com [24.0.95.142]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f5C2BXE85020 - for ; Mon, 11 Jun 2001 22:11:33 -0400 (EDT) - (envelope-from djohnson@greatbridge.com) -Received: from greatbridge.com ([65.2.95.27]) - by femail15.sdc1.sfba.home.com - (InterMail vM.4.01.03.20 201-229-121-120-20010223) with ESMTP - id <20010612021124.OZRG17243.femail15.sdc1.sfba.home.com@greatbridge.com>; - Mon, 11 Jun 2001 19:11:24 -0700 -Message-ID: <3B257969.6050405@greatbridge.com> -Date: Mon, 11 Jun 2001 22:07:37 -0400 -From: Darren Johnson -User-Agent: Mozilla/5.0 (Windows; U; WinNT4.0; en-US; m18) Gecko/20001108 Netscape6/6.0 -X-Accept-Language: en -MIME-Version: 1.0 -To: Alex Pilosov , Reinoud van Leeuwen -cc: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Postgres Replication -References: -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -Thanks for the feedback. I'll try to address both your issues here. - ->> what does "manager controls all the transactions" mean? -> -The replication manager controls the transactions by serializing the -write set messages. -This ensures all transactions are committed in the same order on each -server, so bugs -here are not allowed ;-) - ->> I hope it does ->> *not* mean that a bug in the manager would cause transactions not to ->> commit... -> -> Well yeah it does. Bugs are a fact of life. : - -> ->>> 4) Based on a two phase locking approach, all dead lock situations ->>> are local and detectable by Postgres-R code base, and aborted. ->> ->> Does this imply locking over different servers? That would mean a ->> grinding halt when a network outage occurs... -> -> Don't know, but see below. - -There is a branch of the Postgres-R code that has some failure detection -implemented, -so we will have to merge this functionality with the version of -Postgres-R we have, and -test this issue. I'll let you the results. - ->> ->> - the replication server stores incoming data in a que ("stable ->> device"), until it is sure it has reached its final destination -> -I like this idea for recovering servers that have been down a short -period of time, using WAL -to recover transactions missed during the outage. - ->> ->> This kind of architecture has several advantages: ->> - only committed transactions are replicated which saves overhead ->> - it does not have very much impact on performance of the source ->> server (apart from reading the WAL) ->> - since every replication server has a stable device, data is stored ->> when the network is down and nothing gets lost (nor stops performing) ->> - because only the log reader and the connection from the final ->> replication server are RDBMS specific, it is possible to replicate ->> from MS to Oracle using a Sybase replication server (or different ->> versions etc). -> -There are some issues with the "log reader" approach: -1) The databases are not synchronized until the log reader completes its -processing. -2) I'm not sure about Sybase, but the log reader sends SQL statements to -the other servers -which are then parsed, planned and executed. This over head could be -avoided if only -the tuple changes are replicated. -3) Works fine for read only situations, but peer-to-peer applications -using this approach -must be designed with a conflict resolution scheme. - -Don't get me wrong, I believe we can learn from the replication -techniques used by commercial -databases like Sybase, and try to implement the good ones into -PostgreSQL. Postgres-R is -a synchronous approach which out performs the traditional approaches to -synchronous replication. -Being based on PostgreSQL-6.4.2, getting this approach in the 7.2 tree -might be better than -reinventing the wheel. - -Thanks again, - -Darren - - -Thanks again, - -Darren - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://www.postgresql.org/search.mpl - -From pgsql-hackers-owner+M9936@postgresql.org Tue Jun 12 03:22:51 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f5C7MoL11061 - for ; Tue, 12 Jun 2001 03:22:50 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5C7MPE35441; - Tue, 12 Jun 2001 03:22:25 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9936@postgresql.org) -Received: from reorxrsm.server.lan.at (zep3.it-austria.net [213.150.1.73]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f5C72ZE25009 - for ; Tue, 12 Jun 2001 03:02:36 -0400 (EDT) - (envelope-from ZeugswetterA@wien.spardat.at) -Received: from gz0153.gc.spardat.at (gz0153.gc.spardat.at [172.20.10.149]) - by reorxrsm.server.lan.at (8.11.2/8.11.2) with ESMTP id f5C72Qu27966 - for ; Tue, 12 Jun 2001 09:02:26 +0200 -Received: by sdexcgtw01.f000.d0188.sd.spardat.at with Internet Mail Service (5.5.2650.21) - id ; Tue, 12 Jun 2001 09:02:21 +0200 -Message-ID: <11C1E6749A55D411A9670001FA68796336831B@sdexcsrv1.f000.d0188.sd.spardat.at> -From: Zeugswetter Andreas SB -To: "'Darren Johnson'" , - pgsql-hackers@postgresql.org -Subject: AW: [HACKERS] Postgres Replication -Date: Tue, 12 Jun 2001 09:02:20 +0200 -MIME-Version: 1.0 -X-Mailer: Internet Mail Service (5.5.2650.21) -Content-Type: text/plain; - charset="iso-8859-1" -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -> Although -> Postgres-R is a synchronous approach, I believe it is the closest to -> the goal mentioned above. Here is an abstract of the advantages. - -If you only want synchronous replication, why not simply use triggers ? -All you would then need is remote query access and two phase commit, -and maybe a little script that helps create the appropriate triggers. - -Doing a replicate all or nothing approach that only works synchronous -is imho not flexible enough. - -Andreas - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://www.postgresql.org/search.mpl - -From pgsql-hackers-owner+M9945@postgresql.org Tue Jun 12 10:18:29 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f5CEISL06372 - for ; Tue, 12 Jun 2001 10:18:28 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5CEIQE77517; - Tue, 12 Jun 2001 10:18:26 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9945@postgresql.org) -Received: from krypton.netropolis.org ([208.222.215.99]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f5CEDuE75514 - for ; Tue, 12 Jun 2001 10:13:56 -0400 (EDT) - (envelope-from root@generalogic.com) -Received: from [132.216.183.103] (helo=localhost) - by krypton.netropolis.org with esmtp (Exim 3.12 #1 (Debian)) - id 159ouq-0003MU-00 - for ; Tue, 12 Jun 2001 10:13:08 -0400 -To: pgsql-hackers@postgresql.org -Subject: Re: AW: [HACKERS] Postgres Replication -In-Reply-To: <20010612.13321600@j2.us.greatbridge.com> -References: - <20010612.13321600@j2.us.greatbridge.com> -X-Mailer: Mew version 1.94.2 on Emacs 20.7 / Mule 4.0 (HANANOEN) -MIME-Version: 1.0 -Content-Type: Text/Plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Message-ID: <20010612123623O.root@generalogic.com> -Date: Tue, 12 Jun 2001 12:36:23 +0530 -From: root -X-Dispatcher: imput version 20000414(IM141) -Lines: 47 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -Hello - -I have hacked up a replication layer for Perl code accessing a -database throught the DBI interface. It works pretty well with MySQL -(I can run pre-bender slashcode replicated, haven't tried the more -recent releases). - -Potentially this hack should also work with Pg but I haven't tried -yet. If someone would like to test it out with a complex Pg app and -let me know how it went that would be cool. - -The replication layer is based on Eric Newton's Recall replication -library (www.fault-tolerant.org/recall), and requires that all -database accesses be through the DBI interface. - -The replicas are live, in that every operation affects all the -replicas in real time. Replica outages are invisible to the user, so -long as a majority of the replicas are functioning. Disconnected -replicas can be used for read-only access. - -The only code modification that should be required to use the -replication layer is to change the DSN in connect(): - - my $replicas = '192.168.1.1:7000,192.168.1.2:7000,192.168.1.3:7000'; - my $dbh = DBI->connect("DBI:Recall:database=$replicas"); - -You should be able to install the replication modules with: - -perl -MCPAN -eshell -cpan> install Replication::Recall::DBServer - -and then install DBD::Recall (which doesn't seem to be accessible from -the CPAN shell yet, for some reason), by: - -wget http://www.cpan.org/authors/id/AGUL/DBD-Recall-1.10.tar.gz -tar xzvf DBD-Recall-1.10.tar.gz -cd DBD-Recall-1.10 -perl Makefile.PL -make install - -I would be very interested in hearing about your experiences with -this... - -Thanks - -#! - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M9938@postgresql.org Tue Jun 12 05:12:54 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f5C9CrL15228 - for ; Tue, 12 Jun 2001 05:12:53 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5C9CnE91297; - Tue, 12 Jun 2001 05:12:49 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9938@postgresql.org) -Received: from mobile.hub.org (SHW39-29.accesscable.net [24.138.39.29]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f5C98DE89175 - for ; Tue, 12 Jun 2001 05:08:13 -0400 (EDT) - (envelope-from scrappy@hub.org) -Received: from localhost (scrappy@localhost) - by mobile.hub.org (8.11.3/8.11.1) with ESMTP id f5C97f361630; - Tue, 12 Jun 2001 06:07:46 -0300 (ADT) - (envelope-from scrappy@hub.org) -X-Authentication-Warning: mobile.hub.org: scrappy owned process doing -bs -Date: Tue, 12 Jun 2001 06:07:41 -0300 (ADT) -From: The Hermit Hacker -To: Zeugswetter Andreas SB -cc: "'Darren Johnson'" , - -Subject: Re: AW: [HACKERS] Postgres Replication -In-Reply-To: <11C1E6749A55D411A9670001FA68796336831B@sdexcsrv1.f000.d0188.sd.spardat.at> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -which I believe is what the rserv implementation in contrib currently does -... no? - -its funny ... what is in contrib right now was developed in a weekend by -Vadim, put in contrib, yet nobody has either used it *or* seen fit to -submit patches to improve it ... ? - -On Tue, 12 Jun 2001, Zeugswetter Andreas SB wrote: - -> -> > Although -> > Postgres-R is a synchronous approach, I believe it is the closest to -> > the goal mentioned above. Here is an abstract of the advantages. -> -> If you only want synchronous replication, why not simply use triggers ? -> All you would then need is remote query access and two phase commit, -> and maybe a little script that helps create the appropriate triggers. -> -> Doing a replicate all or nothing approach that only works synchronous -> is imho not flexible enough. -> -> Andreas -> -> ---------------------------(end of broadcast)--------------------------- -> TIP 6: Have you searched our list archives? -> -> http://www.postgresql.org/search.mpl -> - -Marc G. Fournier ICQ#7615664 IRC Nick: Scrappy -Systems Administrator @ hub.org -primary: scrappy@hub.org secondary: scrappy@{freebsd|postgresql}.org - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M9940@postgresql.org Tue Jun 12 09:39:08 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f5CDd8L03200 - for ; Tue, 12 Jun 2001 09:39:08 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5CDcmE58175; - Tue, 12 Jun 2001 09:38:48 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9940@postgresql.org) -Received: from mail.greatbridge.com (mail.greatbridge.com [65.196.68.36]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f5CDYAE56164 - for ; Tue, 12 Jun 2001 09:34:10 -0400 (EDT) - (envelope-from djohnson@greatbridge.com) -Received: from j2.us.greatbridge.com (djohnsonpc.us.greatbridge.com [65.196.69.70]) - by mail.greatbridge.com (8.11.2/8.11.2) with SMTP id f5CDXeQ03585; - Tue, 12 Jun 2001 09:33:40 -0400 -From: Darren Johnson -Date: Tue, 12 Jun 2001 13:32:16 GMT -Message-ID: <20010612.13321600@j2.us.greatbridge.com> -Subject: Re: AW: [HACKERS] Postgres Replication -To: The Hermit Hacker -cc: Zeugswetter Andreas SB , - -Reply-To: Darren Johnson -In-Reply-To: -References: -X-Mailer: Mozilla/3.0 (compatible; StarOffice/5.2;Linux) -X-Priority: 3 (Normal) -MIME-Version: 1.0 -Content-Type: text/plain; charset=ISO-8859-1 -Content-Transfer-Encoding: 8bit -X-MIME-Autoconverted: from quoted-printable to 8bit by postgresql.org id f5CDYAE56166 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -> which I believe is what the rserv implementation in contrib currently -does -> ... no? - -We tried rserv, PG Link (Joseph Conway), and PosrgreSQL Replicator. All -these projects are trigger based asynchronous replication. They all have -some advantages over the current functionality of Postgres-R some of -which I believe can be addressed: - -1) Partial replication - being able to replicate just one or part of a -table(s) -2) They make no changes to the PostgreSQL code base. (Postgres-R can't -address this one ;) -3) PostgreSQL Replicator has some very nice conflict resolution schemes. - - -Here are some disadvantages to using a "trigger based" approach: - -1) Triggers simply transfer individual data items when they are modified, -they do not keep track of transactions. -2) The execution of triggers within a database imposes a performance -overhead to that database. -3) Triggers require careful management by database administrators. -Someone needs to keep track of all the "alarms" going off. -4) The activation of triggers in a database cannot be easily -rolled back or undone. - - - -> On Tue, 12 Jun 2001, Zeugswetter Andreas SB wrote: - -> > Doing a replicate all or nothing approach that only works synchronous -> > is imho not flexible enough. -> > - - -I agree. Partial and asynchronous replication need to be addressed, -and some of the common functionality of Postgres-R could possibly -be used to meet those needs. - - -Thanks for your feedback, - -Darren - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M9969@postgresql.org Tue Jun 12 16:53:45 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f5CKriL23104 - for ; Tue, 12 Jun 2001 16:53:44 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5CKrlE87423; - Tue, 12 Jun 2001 16:53:47 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9969@postgresql.org) -Received: from sectorbase2.sectorbase.com (sectorbase2.sectorbase.com [63.88.121.62] (may be forged)) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5CHWkE69562 - for ; Tue, 12 Jun 2001 13:32:46 -0400 (EDT) - (envelope-from vmikheev@SECTORBASE.COM) -Received: by sectorbase2.sectorbase.com with Internet Mail Service (5.5.2653.19) - id ; Tue, 12 Jun 2001 10:30:29 -0700 -Message-ID: <3705826352029646A3E91C53F7189E32016670@sectorbase2.sectorbase.com> -From: "Mikheev, Vadim" -To: "'Darren Johnson'" , - The Hermit Hacker - -cc: Zeugswetter Andreas SB , - pgsql-hackers@postgresql.org -Subject: RE: AW: [HACKERS] Postgres Replication -Date: Tue, 12 Jun 2001 10:30:27 -0700 -MIME-Version: 1.0 -X-Mailer: Internet Mail Service (5.5.2653.19) -Content-Type: text/plain; - charset="iso-8859-1" -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -> Here are some disadvantages to using a "trigger based" approach: -> -> 1) Triggers simply transfer individual data items when they -> are modified, they do not keep track of transactions. - -I don't know about other *async* replication engines but Rserv -keeps track of transactions (if I understood you corectly). -Rserv transfers not individual modified data items but -*consistent* snapshot of changes to move slave database from -one *consistent* state (when all RI constraints satisfied) -to another *consistent* state. - -> 4) The activation of triggers in a database cannot be easily -> rolled back or undone. - -What do you mean? - -Vadim - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M9967@postgresql.org Tue Jun 12 16:42:11 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f5CKgBL17982 - for ; Tue, 12 Jun 2001 16:42:11 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5CKgDE80566; - Tue, 12 Jun 2001 16:42:13 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9967@postgresql.org) -Received: from mail.greatbridge.com (mail.greatbridge.com [65.196.68.36]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f5CIVdE07561 - for ; Tue, 12 Jun 2001 14:31:39 -0400 (EDT) - (envelope-from djohnson@greatbridge.com) -Received: from j2.us.greatbridge.com (djohnsonpc.us.greatbridge.com [65.196.69.70]) - by mail.greatbridge.com (8.11.2/8.11.2) with SMTP id f5CIUfQ10080; - Tue, 12 Jun 2001 14:30:41 -0400 -From: Darren Johnson -Date: Tue, 12 Jun 2001 18:29:20 GMT -Message-ID: <20010612.18292000@j2.us.greatbridge.com> -Subject: RE: AW: [HACKERS] Postgres Replication -To: "Mikheev, Vadim" -cc: The Hermit Hacker , - Zeugswetter Andreas SB - , - pgsql-hackers@postgresql.org -Reply-To: Darren Johnson - <3705826352029646A3E91C53F7189E32016670@sectorbase2.sectorbase.com> -References: <3705826352029646A3E91C53F7189E32016670@sectorbase2.sectorbase.com> -X-Mailer: Mozilla/3.0 (compatible; StarOffice/5.2;Linux) -X-Priority: 3 (Normal) -MIME-Version: 1.0 -Content-Type: text/plain; charset=ISO-8859-1 -Content-Transfer-Encoding: 8bit -X-MIME-Autoconverted: from quoted-printable to 8bit by postgresql.org id f5CIVdE07562 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - - -> > Here are some disadvantages to using a "trigger based" approach: -> > -> > 1) Triggers simply transfer individual data items when they -> > are modified, they do not keep track of transactions. - -> I don't know about other *async* replication engines but Rserv -> keeps track of transactions (if I understood you corectly). -> Rserv transfers not individual modified data items but -> *consistent* snapshot of changes to move slave database from -> one *consistent* state (when all RI constraints satisfied) -> to another *consistent* state. - -I thought Andreas did a good job of correcting me here. Transaction- -based replication with triggers do not apply to points 1 and 4. I -should have made a distinction between non-transaction and -transaction based replication with triggers. I was not trying to -single out rserv or any other project, and I can see how my wording -implies this misinterpretation (my apologies). - - -> > 4) The activation of triggers in a database cannot be easily -> > rolled back or undone. - -> What do you mean? - -Once the trigger fires, it is not an easy task to abort that -execution via rollback or undo. Again this is not an issue -with a transaction-based trigger approach. - - -Sincerely, - -Darren - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M9943@postgresql.org Tue Jun 12 10:03:02 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f5CE32L04619 - for ; Tue, 12 Jun 2001 10:03:02 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5CE31E70430; - Tue, 12 Jun 2001 10:03:01 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9943@postgresql.org) -Received: from fizbanrsm.server.lan.at (zep4.it-austria.net [213.150.1.74]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f5CDoQE64062 - for ; Tue, 12 Jun 2001 09:50:26 -0400 (EDT) - (envelope-from ZeugswetterA@wien.spardat.at) -Received: from gz0153.gc.spardat.at (gz0153.gc.spardat.at [172.20.10.149]) - by fizbanrsm.server.lan.at (8.11.2/8.11.2) with ESMTP id f5CDoJe11224 - for ; Tue, 12 Jun 2001 15:50:19 +0200 -Received: by sdexcgtw01.f000.d0188.sd.spardat.at with Internet Mail Service (5.5.2650.21) - id ; Tue, 12 Jun 2001 15:50:15 +0200 -Message-ID: <11C1E6749A55D411A9670001FA68796336831F@sdexcsrv1.f000.d0188.sd.spardat.at> -From: Zeugswetter Andreas SB -To: "'Darren Johnson'" , - The Hermit Hacker - -cc: pgsql-hackers@postgresql.org -Subject: AW: AW: [HACKERS] Postgres Replication -Date: Tue, 12 Jun 2001 15:50:09 +0200 -MIME-Version: 1.0 -X-Mailer: Internet Mail Service (5.5.2650.21) -Content-Type: text/plain; - charset="iso-8859-1" -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -> Here are some disadvantages to using a "trigger based" approach: -> -> 1) Triggers simply transfer individual data items when they -> are modified, they do not keep track of transactions. -> 2) The execution of triggers within a database imposes a performance -> overhead to that database. -> 3) Triggers require careful management by database administrators. -> Someone needs to keep track of all the "alarms" going off. -> 4) The activation of triggers in a database cannot be easily -> rolled back or undone. - -Yes, points 2 and 3 are a given, although point 2 buys you the functionality -of transparent locking across all involved db servers. -Points 1 and 4 are only the case for a trigger mechanism that does -not use remote connection and 2-phase commit. - -Imho an implementation that opens a separate client connection to the -replication target is only suited for async replication, and for that a WAL -based solution would probably impose less overhead. - -Andreas - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M9946@postgresql.org Tue Jun 12 10:47:09 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f5CEl9L08144 - for ; Tue, 12 Jun 2001 10:47:09 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5CEihE88714; - Tue, 12 Jun 2001 10:44:43 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9946@postgresql.org) -Received: from mail.greatbridge.com (mail.greatbridge.com [65.196.68.36]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f5CEd6E85859 - for ; Tue, 12 Jun 2001 10:39:06 -0400 (EDT) - (envelope-from djohnson@greatbridge.com) -Received: from j2.us.greatbridge.com (djohnsonpc.us.greatbridge.com [65.196.69.70]) - by mail.greatbridge.com (8.11.2/8.11.2) with SMTP id f5CEcgQ04905; - Tue, 12 Jun 2001 10:38:42 -0400 -From: Darren Johnson -Date: Tue, 12 Jun 2001 14:37:18 GMT -Message-ID: <20010612.14371800@j2.us.greatbridge.com> -Subject: Re: AW: AW: [HACKERS] Postgres Replication -To: Zeugswetter Andreas SB -cc: pgsql-hackers@postgresql.org -Reply-To: Darren Johnson - <11C1E6749A55D411A9670001FA68796336831F@sdexcsrv1.f000.d0188.sd.spardat.at> -References: <11C1E6749A55D411A9670001FA68796336831F@sdexcsrv1.f000.d0188.sd.spardat.at> -X-Mailer: Mozilla/3.0 (compatible; StarOffice/5.2;Linux) -X-Priority: 3 (Normal) -MIME-Version: 1.0 -Content-Type: text/plain; charset=ISO-8859-1 -Content-Transfer-Encoding: 8bit -X-MIME-Autoconverted: from quoted-printable to 8bit by postgresql.org id f5CEd6E85860 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - - -> Imho an implementation that opens a separate client connection to the -> replication target is only suited for async replication, and for that a -WAL -> based solution would probably impose less overhead. - - -Yes there is significant overhead with opening a connection to a -client, so Postgres-R creates a pool of backends at start up, -coupled with the group communication system (Ensemble) that -significantly reduces this issue. - - -Very good points, - -Darren - - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://www.postgresql.org/search.mpl - -From pgsql-hackers-owner+M9982@postgresql.org Tue Jun 12 19:04:06 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f5CN46E10043 - for ; Tue, 12 Jun 2001 19:04:06 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5CN4AE62160; - Tue, 12 Jun 2001 19:04:10 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9982@postgresql.org) -Received: from spoetnik.xs4all.nl (spoetnik.xs4all.nl [194.109.249.226]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f5CMxaE60194 - for ; Tue, 12 Jun 2001 18:59:36 -0400 (EDT) - (envelope-from reinoud@xs4all.nl) -Received: from KAYAK (kayak [192.168.1.20]) - by spoetnik.xs4all.nl (Postfix) with SMTP id 435353E1B - for ; Wed, 13 Jun 2001 00:59:28 +0200 (CEST) -From: reinoud@xs4all.nl (Reinoud van Leeuwen) -To: pgsql-hackers@postgresql.org -Subject: Re: AW: AW: [HACKERS] Postgres Replication -Date: Tue, 12 Jun 2001 22:59:23 GMT -Organization: Not organized in any way -Reply-To: reinoud@xs4all.nl -Message-ID: <3b499c5b.652202125@192.168.1.10> -References: <11C1E6749A55D411A9670001FA68796336831F@sdexcsrv1.f000.d0188.sd.spardat.at> -In-Reply-To: <11C1E6749A55D411A9670001FA68796336831F@sdexcsrv1.f000.d0188.sd.spardat.at> -X-Mailer: Forte Agent 1.5/32.451 -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 8bit -X-MIME-Autoconverted: from quoted-printable to 8bit by postgresql.org id f5CMxcE60196 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Tue, 12 Jun 2001 15:50:09 +0200, you wrote: - -> ->> Here are some disadvantages to using a "trigger based" approach: ->> ->> 1) Triggers simply transfer individual data items when they ->> are modified, they do not keep track of transactions. ->> 2) The execution of triggers within a database imposes a performance ->> overhead to that database. ->> 3) Triggers require careful management by database administrators. ->> Someone needs to keep track of all the "alarms" going off. ->> 4) The activation of triggers in a database cannot be easily ->> rolled back or undone. -> ->Yes, points 2 and 3 are a given, although point 2 buys you the functionality ->of transparent locking across all involved db servers. ->Points 1 and 4 are only the case for a trigger mechanism that does ->not use remote connection and 2-phase commit. -> ->Imho an implementation that opens a separate client connection to the ->replication target is only suited for async replication, and for that a WAL ->based solution would probably impose less overhead. - -Well as I read back the thread I see 2 different approaches to -replication: - -1: tight integrated replication. -pro: -- bi-directional (or multidirectional): updates are possible -everywhere -- A cluster of servers allways has the same state. -- it does not matter to which server you connect -con: -- network between servers will be a bottleneck, especially if it is a -WAN connection -- only full replication possible -- what happens if one server is down? (or the network between) are -commits still possible - -2: async replication -pro: -- long distance possible -- no problems with network outages -- only changes are replicated, selects do not have impact -- no locking issues accross servers -- partial replication possible (many->one (datawarehouse), or one-many -(queries possible everywhere, updates only central) -- goof for failover situations (backup server is standing by) -con: -- bidirectional replication hard to set up (you'll have to implement -conflict resolution according to your business rules) -- different servers are not guaranteed to be in the same state. - -I can think of some scenarios where I would definitely want to -*choose* one of the options. A load-balanced web environment would -likely want the first option, but synchronizing offices in different -continents might not work with 2-phase commit over the network.... - -And we have not even started talking about *managing* replicated -environments. A lot of fail-over scenarios stop planning after the -backup host has take control. But how to get back? --- -__________________________________________________ -"Nothing is as subjective as reality" -Reinoud van Leeuwen reinoud@xs4all.nl -http://www.xs4all.nl/~reinoud -__________________________________________________ - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M9986@postgresql.org Tue Jun 12 19:48:48 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f5CNmmE13125 - for ; Tue, 12 Jun 2001 19:48:48 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5CNmqE76673; - Tue, 12 Jun 2001 19:48:52 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9986@postgresql.org) -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f5CNdQE73923 - for ; Tue, 12 Jun 2001 19:39:26 -0400 (EDT) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.3/8.11.3) with ESMTP id f5CNdI016442; - Tue, 12 Jun 2001 19:39:18 -0400 (EDT) -To: reinoud@xs4all.nl -cc: pgsql-hackers@postgresql.org -Subject: Re: AW: AW: [HACKERS] Postgres Replication -In-Reply-To: <3b499c5b.652202125@192.168.1.10> -References: <11C1E6749A55D411A9670001FA68796336831F@sdexcsrv1.f000.d0188.sd.spardat.at> <3b499c5b.652202125@192.168.1.10> -Comments: In-reply-to reinoud@xs4all.nl (Reinoud van Leeuwen) - message dated "Tue, 12 Jun 2001 22:59:23 +0000" -Date: Tue, 12 Jun 2001 19:39:18 -0400 -Message-ID: <16439.992389158@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -reinoud@xs4all.nl (Reinoud van Leeuwen) writes: -> Well as I read back the thread I see 2 different approaches to -> replication: -> ... -> I can think of some scenarios where I would definitely want to -> *choose* one of the options. - -Yes. IIRC, it looks to be possible to support a form of async -replication using the Postgres-R approach: you allow the cluster -to break apart when communications fail, and then rejoin when -your link comes back to life. (This can work in principle, how -close it is to reality is another question; but the rejoin operation -is the same as crash recovery, so you have to have it anyway.) - -So this seems to me to allow getting most of the benefits of the async -approach. OTOH it is difficult to see how to go the other way: getting -the benefits of a synchronous solution atop a basically-async -implementation doesn't seem like it can work. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://www.postgresql.org/search.mpl - -From pgsql-hackers-owner+M9997@postgresql.org Wed Jun 13 09:05:56 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f5DD5tE28260 - for ; Wed, 13 Jun 2001 09:05:55 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5DD5xE12437; - Wed, 13 Jun 2001 09:05:59 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M9997@postgresql.org) -Received: from fizbanrsm.server.lan.at (zep4.it-austria.net [213.150.1.74]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f5DD19E00635 - for ; Wed, 13 Jun 2001 09:01:10 -0400 (EDT) - (envelope-from ZeugswetterA@wien.spardat.at) -Received: from gz0153.gc.spardat.at (gz0153.gc.spardat.at [172.20.10.149]) - by fizbanrsm.server.lan.at (8.11.2/8.11.2) with ESMTP id f5DD13m08153 - for ; Wed, 13 Jun 2001 15:01:03 +0200 -Received: by sdexcgtw01.f000.d0188.sd.spardat.at with Internet Mail Service (5.5.2650.21) - id ; Wed, 13 Jun 2001 15:00:02 +0200 -Message-ID: <11C1E6749A55D411A9670001FA687963368322@sdexcsrv1.f000.d0188.sd.spardat.at> -From: Zeugswetter Andreas SB -To: "'reinoud@xs4all.nl'" , pgsql-hackers@postgresql.org -Subject: AW: AW: AW: [HACKERS] Postgres Replication -Date: Wed, 13 Jun 2001 11:55:48 +0200 -MIME-Version: 1.0 -X-Mailer: Internet Mail Service (5.5.2650.21) -Content-Type: text/plain; - charset="iso-8859-1" -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -> Well as I read back the thread I see 2 different approaches to -> replication: -> -> 1: tight integrated replication. -> pro: -> - bi-directional (or multidirectional): updates are possible everywhere -> - A cluster of servers allways has the same state. -> - it does not matter to which server you connect -> con: -> - network between servers will be a bottleneck, especially if it is a -> WAN connection -> - only full replication possible - -I do not understand that point, if it is trigger based, you -have all the flexibility you need. (only some tables, only some rows, -different rows to different targets ....), -(or do you mean not all targets, that could also be achieved with triggers) - -> - what happens if one server is down? (or the network between) are -> commits still possible - -No, updates are not possible if one target is not reachable, -that would not be synchronous and would again need business rules -to resolve conflicts. - -Allowing updates when a target is not reachable would require admin -intervention. - -Andreas - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M10005@postgresql.org Wed Jun 13 11:15:48 2001 -Return-path: -Received: from postgresql.org (webmail.postgresql.org [216.126.85.28]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f5DFFmE08382 - for ; Wed, 13 Jun 2001 11:15:48 -0400 (EDT) -Received: from postgresql.org.org (webmail.postgresql.org [216.126.85.28]) - by postgresql.org (8.11.3/8.11.1) with SMTP id f5DFFoE53621; - Wed, 13 Jun 2001 11:15:50 -0400 (EDT) - (envelope-from pgsql-hackers-owner+M10005@postgresql.org) -Received: from mail.greatbridge.com (mail.greatbridge.com [65.196.68.36]) - by postgresql.org (8.11.3/8.11.1) with ESMTP id f5DEk7E38930 - for ; Wed, 13 Jun 2001 10:46:07 -0400 (EDT) - (envelope-from djohnson@greatbridge.com) -Received: from j2.us.greatbridge.com (djohnsonpc.us.greatbridge.com [65.196.69.70]) - by mail.greatbridge.com (8.11.2/8.11.2) with SMTP id f5DEhfQ22566; - Wed, 13 Jun 2001 10:43:41 -0400 -From: Darren Johnson -Date: Wed, 13 Jun 2001 14:44:11 GMT -Message-ID: <20010613.14441100@j2.us.greatbridge.com> -Subject: Re: AW: AW: AW: [HACKERS] Postgres Replication -To: Zeugswetter Andreas SB -cc: "'reinoud@xs4all.nl'" , pgsql-hackers@postgresql.org -Reply-To: Darren Johnson - <11C1E6749A55D411A9670001FA687963368322@sdexcsrv1.f000.d0188.sd.spardat.at> -References: <11C1E6749A55D411A9670001FA687963368322@sdexcsrv1.f000.d0188.sd.spardat.at> -X-Mailer: Mozilla/3.0 (compatible; StarOffice/5.2;Linux) -X-Priority: 3 (Normal) -MIME-Version: 1.0 -Content-Type: text/plain; charset=ISO-8859-1 -Content-Transfer-Encoding: 8bit -X-MIME-Autoconverted: from quoted-printable to 8bit by postgresql.org id f5DEk8E38931 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -> > - only full replication possible - -> I do not understand that point, if it is trigger based, you -> have all the flexibility you need. (only some tables, only some rows, -> different rows to different targets ....), -> (or do you mean not all targets, that could also be achieved with -triggers) - -Currently with Postgres-R, it is one database replicating all tables to -all servers in the group communication system. There are some ways -around -this by invoking the -r option when a SQL statement should be replicated, -and leaving the -r option off for non-replicated scenarios. IMHO this is -not a good solution. - -A better solution will need to be implemented, which involves a -subscription table(s) with relation/server information. There are two -ideas for subscribing and receiving replicated data. - -1) Receiver driven propagation - A simple solution where all -transactions are propagated and the receiving servers will reference -the subscription information before applying updates. - -2) Sender driven propagation - A more optimal and complex solution -where servers do not receive any messages regarding data items for -which they have not subscribed - - -> > - what happens if one server is down? (or the network between) are -> > commits still possible - -> No, updates are not possible if one target is not reachable, - -AFAIK, Postgres-R can still replicate if one target is not reachable, -but only to the remaining servers ;). - -There is a scenario that could arise if a server issues a lock -request then fails or goes off line. There is code that checks -for this condition, which needs to be merged with the branch we have. - -> that would not be synchronous and would again need business rules -> to resolve conflicts. - -Yes the failed server would not be synchronized, and getting this -failed server back in sync needs to be addressed. - -> Allowing updates when a target is not reachable would require admin -> intervention. - -In its current state yes, but our goal would be to eliminate this -requirement as well. - - - -Darren - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M18443=candle.pha.pa.us=pgman@postgresql.org Mon Feb 4 19:16:17 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g150GGP03822 - for ; Mon, 4 Feb 2002 19:16:16 -0500 (EST) -Received: (qmail 77444 invoked by alias); 5 Feb 2002 00:16:11 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 5 Feb 2002 00:16:11 -0000 -Received: from snoopy.mohawksoft.com (h0050bf7a618d.ne.mediaone.net [24.147.138.78]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g150Esl77040 - for ; Mon, 4 Feb 2002 19:14:54 -0500 (EST) - (envelope-from markw@mohawksoft.com) -Received: from mohawksoft.com (localhost [127.0.0.1]) - by snoopy.mohawksoft.com (8.11.6/8.11.6) with ESMTP id g150AWh08676 - for ; Mon, 4 Feb 2002 19:10:33 -0500 -Message-ID: <3C5F22F8.C9B958F0@mohawksoft.com> -Date: Mon, 04 Feb 2002 19:10:32 -0500 -From: mlw -X-Mailer: Mozilla 4.78 [en] (X11; U; Linux 2.4.17 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: PostgreSQL-development -Subject: [HACKERS] Replication -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -I re-wrote RServ.pm to C, and wrote a replication daemon. It works, but it -works like the whole rserv project. I don't like it. - -OK, what the hell do we need to do to get PostgreSQL replicating? - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18445=candle.pha.pa.us=pgman@postgresql.org Mon Feb 4 19:57:01 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g150v0P06518 - for ; Mon, 4 Feb 2002 19:57:00 -0500 (EST) -Received: (qmail 90440 invoked by alias); 5 Feb 2002 00:56:59 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 5 Feb 2002 00:56:59 -0000 -Received: from www1.navtechinc.com ([192.234.226.140]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g150rMl89885 - for ; Mon, 4 Feb 2002 19:53:22 -0500 (EST) - (envelope-from ssinger@navtechinc.com) -Received: from pcNavYkfAdm1.ykf.navtechinc.com (wall [192.234.226.190]) - by www1.navtechinc.com (8.9.3/8.9.3) with ESMTP id AAA06047; - Tue, 5 Feb 2002 00:53:22 GMT -Received: from localhost (ssinger@localhost) - by pcNavYkfAdm1.ykf.navtechinc.com (8.9.3/8.9.3) with ESMTP id AAA10675; - Tue, 5 Feb 2002 00:52:43 GMT -Date: Tue, 5 Feb 2002 00:52:43 +0000 (GMT) -From: Steven -X-X-Sender: -To: mlw -cc: PostgreSQL-development -Subject: Re: [HACKERS] Replication -In-Reply-To: <3C5F22F8.C9B958F0@mohawksoft.com> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Mon, 4 Feb 2002, mlw wrote: - -I've developed a replacement for Rserv and we are planning on releasing -it as open source(ie as a contrib module). - -Like Rserv its trigger based but its much more flexible. -The key adventages it has over Rserv is that it has --Support for multiple slaves --It Perserves transactions while doing the mirroring. Ie If rows A,B are -originally added in the same transaction they will be mirrored in the same -transaction. - -We have plans on adding filtering based on data/selective mirroring as -well. (Ie only rows with COUNTRY='Canada' go to -slave A, and rows with COUNTRY='China' go to slave B). -But I'm not sure when I'll get to that. - -Support for conflict resolution(If allow edits to be made on the slaves) -would be nice. - -I hope to be able to send a tarball with the source to the pgpatches list -within the next few days. - -We've been using the system operationally for a number of months and have -been happy with it. - -> I re-wrote RServ.pm to C, and wrote a replication daemon. It works, but it -> works like the whole rserv project. I don't like it. -> OK, what the hell do we need to do to get PostgreSQL replicating? -> -> ---------------------------(end of broadcast)--------------------------- -> TIP 4: Don't 'kill -9' the postmaster -> - --- -Steven Singer ssinger@navtechinc.com -Aircraft Performance Systems Phone: 519-747-1170 ext 282 -Navtech Systems Support Inc. AFTN: CYYZXNSX SITA: YYZNSCR -Waterloo, Ontario ARINC: YKFNSCR - - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M18447=candle.pha.pa.us=pgman@postgresql.org Mon Feb 4 20:06:57 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g1516vP07508 - for ; Mon, 4 Feb 2002 20:06:57 -0500 (EST) -Received: (qmail 92753 invoked by alias); 5 Feb 2002 01:06:55 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 5 Feb 2002 01:06:55 -0000 -Received: from inflicted.crimelabs.net (crimelabs.net [66.92.101.112]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g150vhl91978 - for ; Mon, 4 Feb 2002 19:57:44 -0500 (EST) - (envelope-from bpalmer@crimelabs.net) -Received: from mizer.crimelabs.net (mizer.crimelabs.net [192.168.88.10]) - by inflicted.crimelabs.net (Postfix) with ESMTP - id 9D6EE8779; Mon, 4 Feb 2002 19:57:46 -0500 (EST) -Date: Mon, 4 Feb 2002 19:57:34 -0500 (EST) -From: bpalmer -To: mlw -cc: PostgreSQL-development -Subject: Re: [HACKERS] Replication -In-Reply-To: <3C5F22F8.C9B958F0@mohawksoft.com> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -> -> OK, what the hell do we need to do to get PostgreSQL replicating? - -I hope you understand that replication, done right, is a massive -project. I know that Darren any myself (and the rest of the pg-repl -folks) have been waiting till 7.2 went gold till we did anymore work. I -think we hope to have master / slave replicatin working for 7.3 and then -target multimaster for 7.4. At least that's the hope. - -- Brandon - ----------------------------------------------------------------------------- - c: 646-456-5455 h: 201-798-4983 - b. palmer, bpalmer@crimelabs.net pgp:crimelabs.net/bpalmer.pgp5 - - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M18449=candle.pha.pa.us=pgman@postgresql.org Mon Feb 4 21:16:56 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g152GtP10503 - for ; Mon, 4 Feb 2002 21:16:55 -0500 (EST) -Received: (qmail 6711 invoked by alias); 5 Feb 2002 02:16:53 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 5 Feb 2002 02:16:53 -0000 -Received: from snoopy.mohawksoft.com (h0050bf7a618d.ne.mediaone.net [24.147.138.78]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g151qSl99469 - for ; Mon, 4 Feb 2002 20:52:28 -0500 (EST) - (envelope-from markw@mohawksoft.com) -Received: from mohawksoft.com (localhost [127.0.0.1]) - by snoopy.mohawksoft.com (8.11.6/8.11.6) with ESMTP id g151lph09147; - Mon, 4 Feb 2002 20:47:51 -0500 -Message-ID: <3C5F39C7.970F4549@mohawksoft.com> -Date: Mon, 04 Feb 2002 20:47:51 -0500 -From: mlw -X-Mailer: Mozilla 4.78 [en] (X11; U; Linux 2.4.17 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Steven -cc: PostgreSQL-development -Subject: Re: [HACKERS] Replication -References: -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Steven wrote: -> -> On Mon, 4 Feb 2002, mlw wrote: -> -> I've developed a replacement for Rserv and we are planning on releasing -> it as open source(ie as a contrib module). -> -> Like Rserv its trigger based but its much more flexible. -> The key adventages it has over Rserv is that it has -> -Support for multiple slaves -> -It Perserves transactions while doing the mirroring. Ie If rows A,B are -> originally added in the same transaction they will be mirrored in the same -> transaction. - -I did a similar thing. I took the rserv trigger "as is," but rewrote the -replication support code. What I eventually did was write a "snapshot daemon" -which created snapshot files. Then a "slave daemon" which would check the last -snapshot applied and apply all the snapshots, in order, as needed. One would -run one of these daemons per slave server. - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M18448=candle.pha.pa.us=pgman@postgresql.org Mon Feb 4 20:57:25 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g151vOP09239 - for ; Mon, 4 Feb 2002 20:57:24 -0500 (EST) -Received: (qmail 99828 invoked by alias); 5 Feb 2002 01:57:19 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 5 Feb 2002 01:57:19 -0000 -Received: from snoopy.mohawksoft.com (h0050bf7a618d.ne.mediaone.net [24.147.138.78]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g151s0l99529 - for ; Mon, 4 Feb 2002 20:54:00 -0500 (EST) - (envelope-from markw@mohawksoft.com) -Received: from mohawksoft.com (localhost [127.0.0.1]) - by snoopy.mohawksoft.com (8.11.6/8.11.6) with ESMTP id g151nah09156; - Mon, 4 Feb 2002 20:49:37 -0500 -Message-ID: <3C5F3A30.A4C46FB8@mohawksoft.com> -Date: Mon, 04 Feb 2002 20:49:36 -0500 -From: mlw -X-Mailer: Mozilla 4.78 [en] (X11; U; Linux 2.4.17 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: bpalmer -cc: PostgreSQL-development -Subject: Re: [HACKERS] Replication -References: -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -bpalmer wrote: -> -> > -> > OK, what the hell do we need to do to get PostgreSQL replicating? -> -> I hope you understand that replication, done right, is a massive -> project. I know that Darren any myself (and the rest of the pg-repl -> folks) have been waiting till 7.2 went gold till we did anymore work. I -> think we hope to have master / slave replicatin working for 7.3 and then -> target multimaster for 7.4. At least that's the hope. - -I do know how hard replication is. I also understand how important it is. - -If you guys have a project going, and need developers, I am more than willing. - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M18450=candle.pha.pa.us=pgman@postgresql.org Mon Feb 4 21:42:13 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g152gCP11957 - for ; Mon, 4 Feb 2002 21:42:13 -0500 (EST) -Received: (qmail 14229 invoked by alias); 5 Feb 2002 02:42:09 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 5 Feb 2002 02:42:09 -0000 -Received: from www1.navtechinc.com ([192.234.226.140]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g152SBl10682 - for ; Mon, 4 Feb 2002 21:28:11 -0500 (EST) - (envelope-from ssinger@navtechinc.com) -Received: from pcNavYkfAdm1.ykf.navtechinc.com (wall [192.234.226.190]) - by www1.navtechinc.com (8.9.3/8.9.3) with ESMTP id CAA06384; - Tue, 5 Feb 2002 02:28:13 GMT -Received: from localhost (ssinger@localhost) - by pcNavYkfAdm1.ykf.navtechinc.com (8.9.3/8.9.3) with ESMTP id CAA10682; - Tue, 5 Feb 2002 02:27:35 GMT -Date: Tue, 5 Feb 2002 02:27:35 +0000 (GMT) -From: Steven -X-X-Sender: -To: mlw -cc: PostgreSQL-development -Subject: Re: [HACKERS] Replication -In-Reply-To: <3C5F39C7.970F4549@mohawksoft.com> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -DBMirror doesn't use snapshot's instead it records a log of transactions -that are committed to the database in a pair of tables. -In the case of an INSERT this is the row that is being added. -In the case of a delete the primary key of the row being deleted. - -And in the case of an UPDATE, the primary key before the update along with -all of the data the row should have after an update. - -Then for each slave database a perl script walks though the transactions -that are pending for that host and reconstructs SQL to send the row edits -to that host. A record of the fact that transaction Y has been sent to -host X is also kept. - -When transaction X has been sent to all of the hosts that are in the -system it is then deleted from the Pending tables. - -I suspect that all of the information I'm storing in the Pending tables is -also being stored by Postgres in its log but I haven't investigated how -the information could be extracted(or how long it is kept for). That -would reduce the extra storage overhead that the replication system -imposes. - -As I remember(Its been a while since I've looked at it) RServ uses OID's -in its tables to point to the data that needs to be replicated. We tried -a similar approach but found difficulties with doing partial updates. - - - - - - -On Mon, 4 Feb 2002, mlw wrote: - -> I did a similar thing. I took the rserv trigger "as is," but rewrote the -> replication support code. What I eventually did was write a "snapshot daemon" -> which created snapshot files. Then a "slave daemon" which would check the last -> snapshot applied and apply all the snapshots, in order, as needed. One would -> run one of these daemons per slave server. - - - - - - --- -Steven Singer ssinger@navtechinc.com -Aircraft Performance Systems Phone: 519-747-1170 ext 282 -Navtech Systems Support Inc. AFTN: CYYZXNSX SITA: YYZNSCR -Waterloo, Ontario ARINC: YKFNSCR - - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M18554=candle.pha.pa.us=pgman@postgresql.org Thu Feb 7 02:49:48 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g177nlP04347 - for ; Thu, 7 Feb 2002 02:49:47 -0500 (EST) -Received: (qmail 22556 invoked by alias); 7 Feb 2002 07:49:49 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 7 Feb 2002 07:49:49 -0000 -Received: from linuxworld.com.au (www.linuxworld.com.au [203.34.46.50]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g177QfE19572 - for ; Thu, 7 Feb 2002 02:26:42 -0500 (EST) - (envelope-from swm@linuxworld.com.au) -Received: from localhost (swm@localhost) - by linuxworld.com.au (8.11.4/8.11.4) with ESMTP id g177RiU06086; - Thu, 7 Feb 2002 18:27:45 +1100 -Date: Thu, 7 Feb 2002 18:27:44 +1100 (EST) -From: Gavin Sherry -To: mlw -cc: PostgreSQL-development -Subject: Re: [HACKERS] Replication -In-Reply-To: <3C5F22F8.C9B958F0@mohawksoft.com> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Mon, 4 Feb 2002, mlw wrote: - -> I re-wrote RServ.pm to C, and wrote a replication daemon. It works, but it -> works like the whole rserv project. I don't like it. -> -> OK, what the hell do we need to do to get PostgreSQL replicating? - -The trigger model is not a very sophisticated one. I think I have a better --- though more complicated -- one. This model would be able to handle -multiple masters and master->slave. - -First of all, all machines in the cluster would have to be aware all the -machines in the cluster. This would have to be stored in a new system -table. - -The FE/BE protocol would need to be modified to accepted parsed node trees -generated by pg_analyze_and_rewrite(). These could then be dispatched by -the executing server, inside of pg_exec_query_string, to all other servers -in the cluster (excluding itself). Naturally, this dispatch would need to -be non-blocking. - -pg_exec_query_string() would need to check that nodetags to make sure -selects and perhaps some commands are not dispatched. - -Before the executing server runs finish_xact_command(), it would check -that the query was successfully executed on all machines otherwise -abort. Such a system would need a few configuration options: whether or -not you abort on failed replication to slaves, the ability to replicate -only certain tables, etc. - -Naturally, this would slow down writes to the system (possibly a lot -depending on the performance difference between the executing machine and -the least powerful machine in the cluster), but most usages of postgresql -are read intensive, not write. - -Any reason this model would not work? - -Gavin - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18558=candle.pha.pa.us=pgman@postgresql.org Thu Feb 7 08:31:00 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g17DUxP13923 - for ; Thu, 7 Feb 2002 08:30:59 -0500 (EST) -Received: (qmail 91796 invoked by alias); 7 Feb 2002 13:30:55 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 7 Feb 2002 13:30:55 -0000 -Received: from snoopy.mohawksoft.com (h0050bf7a618d.ne.mediaone.net [24.147.138.78]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g17Cw0E87782 - for ; Thu, 7 Feb 2002 07:58:01 -0500 (EST) - (envelope-from markw@mohawksoft.com) -Received: from mohawksoft.com (localhost [127.0.0.1]) - by snoopy.mohawksoft.com (8.11.6/8.11.6) with ESMTP id g17CqNt16887; - Thu, 7 Feb 2002 07:52:24 -0500 -Message-ID: <3C627887.CC9FF837@mohawksoft.com> -Date: Thu, 07 Feb 2002 07:52:23 -0500 -From: mlw -X-Mailer: Mozilla 4.78 [en] (X11; U; Linux 2.4.17 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Gavin Sherry -cc: PostgreSQL-development -Subject: Re: [HACKERS] Replication -References: -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Gavin Sherry wrote: -> Naturally, this would slow down writes to the system (possibly a lot -> depending on the performance difference between the executing machine and -> the least powerful machine in the cluster), but most usages of postgresql -> are read intensive, not write. -> -> Any reason this model would not work? - -What, then is the purpose of replication to multiple masters? - -I can think of only two reasons why you want replication. (1) Redundancy, make -sure that if one server dies, then another server has the same data and is used -seamlessly. (2) Increase performance over one system. - -In reason (1) I submit that a server load balance which sits on top of -PostgreSQL, and executes writes on both servers while distributing reads would -be best. This is a HUGE project. The load balancer must know EXACTLY how the -system is configured, which includes all functions and everything. - -In reason (2) your system would fail to provide the scalability that would be -needed. If writes take a long time, but reads are fine, what is the difference -between the trigger based replicator? - -I have in the back of my mind, an idea of patching into the WAL stuff, and -using that mechanism to push changes out to the slaves. - -Where one machine is still the master, but no trigger stuff, just a WAL patch. -Perhaps some shared memory paradigm to manage WAL visibility? I'm not sure -exactly, the idea hasn't completely formed yet. - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M18574=candle.pha.pa.us=pgman@postgresql.org Thu Feb 7 12:51:42 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g17HpfP16661 - for ; Thu, 7 Feb 2002 12:51:41 -0500 (EST) -Received: (qmail 62955 invoked by alias); 7 Feb 2002 17:50:42 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 7 Feb 2002 17:50:42 -0000 -Received: from www1.navtechinc.com ([192.234.226.140]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g17HnTE62256 - for ; Thu, 7 Feb 2002 12:49:29 -0500 (EST) - (envelope-from ssinger@navtechinc.com) -Received: from pcNavYkfAdm1.ykf.navtechinc.com (wall [192.234.226.190]) - by www1.navtechinc.com (8.9.3/8.9.3) with ESMTP id RAA07908; - Thu, 7 Feb 2002 17:49:31 GMT -Received: from localhost (ssinger@localhost) - by pcNavYkfAdm1.ykf.navtechinc.com (8.9.3/8.9.3) with ESMTP id RAA05687; - Thu, 7 Feb 2002 17:48:52 GMT -Date: Thu, 7 Feb 2002 17:48:51 +0000 (GMT) -From: Steven Singer -X-X-Sender: -To: Gavin Sherry -cc: mlw , - PostgreSQL-development -Subject: Re: [HACKERS] Replication -In-Reply-To: -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - - -What you describe sounds like a form of a two-stage commit protocol. - -If the command worked on two of the replicated databases but failed on a -third then the executing server would have to be able to undo the command -on the replicated databases as well as itself. - -The problems with two stage commit type approches to replication are -1) Speed as you mentioned. Write speed isn't a concern for some -applications but it is very important in others. - -and -2) All of the databases must be able to communicate with each other at -all times in order for any edits to work. If the servers are -connected over some sort of WAN that periodically has short outages this -is a problem. Also if your using replication because you want to be able -to take down one of the databases for short periods of time without -bringing down the others your in trouble. - - -btw: I posted the alternative to Rserv that I mentioned the other day to -the pg-patches mailing list. If anyone is intreasted you should be able -to grab it off the archives. - -On Thu, 7 Feb 2002, Gavin Sherry wrote: - -> -> First of all, all machines in the cluster would have to be aware all the -> machines in the cluster. This would have to be stored in a new system -> table. -> -> The FE/BE protocol would need to be modified to accepted parsed node trees -> generated by pg_analyze_and_rewrite(). These could then be dispatched by -> the executing server, inside of pg_exec_query_string, to all other servers -> in the cluster (excluding itself). Naturally, this dispatch would need to -> be non-blocking. -> -> pg_exec_query_string() would need to check that nodetags to make sure -> selects and perhaps some commands are not dispatched. -> -> Before the executing server runs finish_xact_command(), it would check -> that the query was successfully executed on all machines otherwise -> abort. Such a system would need a few configuration options: whether or -> not you abort on failed replication to slaves, the ability to replicate -> only certain tables, etc. -> -> Naturally, this would slow down writes to the system (possibly a lot -> depending on the performance difference between the executing machine and -> the least powerful machine in the cluster), but most usages of postgresql -> are read intensive, not write. -> -> Any reason this model would not work? -> -> Gavin -> -> -> ---------------------------(end of broadcast)--------------------------- -> TIP 4: Don't 'kill -9' the postmaster -> - --- -Steven Singer ssinger@navtechinc.com -Aircraft Performance Systems Phone: 519-747-1170 ext 282 -Navtech Systems Support Inc. AFTN: CYYZXNSX SITA: YYZNSCR -Waterloo, Ontario ARINC: YKFNSCR - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M18590=candle.pha.pa.us=pgman@postgresql.org Thu Feb 7 17:50:42 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g17MoeP27121 - for ; Thu, 7 Feb 2002 17:50:40 -0500 (EST) -Received: (qmail 39930 invoked by alias); 7 Feb 2002 22:50:17 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 7 Feb 2002 22:50:17 -0000 -Received: from odin.fts.net (wall.icgate.net [209.26.177.2]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g17Ma4E38041 - for ; Thu, 7 Feb 2002 17:36:04 -0500 (EST) - (envelope-from fharvell@odin.fts.net) -Received: from odin.fts.net (fharvell@localhost) - by odin.fts.net (8.11.6/8.11.6) with ESMTP id g17MZhR17707; - Thu, 7 Feb 2002 17:35:43 -0500 -Message-ID: <200202072235.g17MZhR17707@odin.fts.net> -X-Mailer: exmh version 2.2 06/23/2000 with nmh-1.0.4 -From: F Harvell -To: mlw -cc: Gavin Sherry , - PostgreSQL-development -Subject: Re: [HACKERS] Replication -In-Reply-To: Message from mlw - of "Thu, 07 Feb 2002 07:52:23 EST." - <3C627887.CC9FF837@mohawksoft.com> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Date: Thu, 07 Feb 2002 17:35:43 -0500 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -I'm not that familiar with the whole replication issues in PostgreSQL, -however, I would be partial to replication that was based upon the -playback of the (a?) journal file. (I believe that the WAL is a -journal file.) - -By being based upon a journal file, it would be possible to accomplish -two significant items. First, it would be possible to "restore" a -database to an exact state just before a failure. Most commercial -databases provide the ability to do this. Banks, etc. log the journal -files directly to tape to provide a complete transaction history such -that they can rebuild their database from any given snapshot. (Note -that the journal file needs to be "editable" as a failure may be -"delete from x" with a missing where clause.) - -This leads directly into the second advantage, the ability to have a -replicated database operating anywhere, over any connection on any -server. Speed of writes would not be a factor. In essence, as long -as the replicated database had a snapshot of the database and then was -provided with all journal files since the snapshot, it would be -possible to build a current database. If the replicant got behind in -the processing, it would catch up when things slowed down. - -In my opionion, the first advantage is in many ways most important. -Replication becomes simply the restoration of the database in realtime -on a second server. The "replication" task becomes the definition of -a protocol for distributing the journal file. At least one major -database vendor does replication (shadowing) in exactly this mannor. - -Maybe I'm all wet and the journal file and journal playback already -exists. If so, IMHO, basing replication off of this would be the -right direction. - - -On Thu, 07 Feb 2002 07:52:23 EST, mlw wrote: -> -> I have in the back of my mind, an idea of patching into the WAL stuff, and -> using that mechanism to push changes out to the slaves. -> -> Where one machine is still the master, but no trigger stuff, just a WAL patch. -> Perhaps some shared memory paradigm to manage WAL visibility? I'm not sure -> exactly, the idea hasn't completely formed yet. -> - - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18605=candle.pha.pa.us=pgman@postgresql.org Fri Feb 8 00:50:08 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g185o7P27878 - for ; Fri, 8 Feb 2002 00:50:07 -0500 (EST) -Received: (qmail 17348 invoked by alias); 8 Feb 2002 05:50:03 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 8 Feb 2002 05:50:03 -0000 -Received: from lakemtao03.mgt.cox.net (mtao3.east.cox.net [68.1.17.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g185cTE15241 - for ; Fri, 8 Feb 2002 00:38:29 -0500 (EST) - (envelope-from darren.johnson@cox.net) -Received: from cox.net ([68.10.181.230]) by lakemtao03.mgt.cox.net - (InterMail vM.5.01.04.05 201-253-122-122-105-20011231) with ESMTP - id <20020208053833.YKTV6710.lakemtao03.mgt.cox.net@cox.net> - for ; - Fri, 8 Feb 2002 00:38:33 -0500 -Message-ID: <3C636232.6060206@cox.net> -Date: Fri, 08 Feb 2002 00:29:22 -0500 -From: Darren Johnson -User-Agent: Mozilla/5.0 (Windows; U; WinNT4.0; en-US; m18) Gecko/20001108 Netscape6/6.0 -X-Accept-Language: en -MIME-Version: 1.0 -To: PostgreSQL-development -Subject: Re: [HACKERS] Replication -References: -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - - > - > The problems with two stage commit type approches to replication are - -IMHO the biggest problem with two phased commit is it doesn't scale. -The more servers -you add to the replica the slower it goes. Also there's the potential -for dead locks across -server boundaries. - - > - > 2) All of the databases must be able to communicate with each other at - > all times in order for any edits to work. If the servers are - > connected over some sort of WAN that periodically has short outages this - > is a problem. Also if your using replication because you want to be -able - > to take down one of the databases for short periods of time without - > bringing down the others your in trouble. - -All true for two phased commit protocol. To have multi master -replication, you must have all -systems communicating, but you can use a multicast group communication -system instead of -2PC. Using total order messaging, you can ensure all changes are -delivered to all servers in the -replica in the same order. This group communication system also allows -failures to be detected -while other servers in the replica continue processing. - -A few of us are working with this theory, and trying to integrate with -7.2. There is a working -model for 6.4, but its very limited. (insert, update, and deletes) We -are currently hosted at - -http://gborg.postgresql.org/project/pgreplication/projdisplay.php -But the site has been down the last 2 days. I've contacted the web -master, but haven't seen -any results yet. If any one knows what going on with gborg, I'd -appreciate a status. - -Darren - - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M18617=candle.pha.pa.us=pgman@postgresql.org Fri Feb 8 06:20:44 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g18BKhP06132 - for ; Fri, 8 Feb 2002 06:20:43 -0500 (EST) -Received: (qmail 90815 invoked by alias); 8 Feb 2002 11:20:40 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 8 Feb 2002 11:20:40 -0000 -Received: from laptop.kieser.demon.co.uk (kieser.demon.co.uk [62.49.6.72]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g18B9ZE89589 - for ; Fri, 8 Feb 2002 06:09:36 -0500 (EST) - (envelope-from brad@kieser.net) -Received: from laptop.kieser.demon.co.uk (localhost.localdomain [127.0.0.1]) - by laptop.kieser.demon.co.uk (Postfix) with SMTP - id 598393A132; Fri, 8 Feb 2002 11:09:36 +0000 (GMT) -From: Bradley Kieser -Date: Fri, 08 Feb 2002 11:09:36 GMT -Message-ID: <20020208.11093600@laptop.kieser.demon.co.uk> -Subject: Re: [HACKERS] Replication -To: Darren Johnson -cc: PostgreSQL-development -In-Reply-To: <3C636232.6060206@cox.net> -References: <3C636232.6060206@cox.net> -X-Mailer: Mozilla/3.0 (compatible; StarOffice/5.2;Linux) -X-Priority: 3 (Normal) -MIME-Version: 1.0 -Content-Type: text/plain; charset=ISO-8859-1 -Content-Transfer-Encoding: 8bit -X-MIME-Autoconverted: from quoted-printable to 8bit by postgresql.org id g18BJoF90352 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Darren, -Given that different replication strategies will probably be developed -for PG, do you envisage DBAs to be able to select the type of replication -for their installation? I.e. Replication being selectable rther like -storage structures? - -Would be a killer bit of flexibility, given how enormous the impact of -replication will be to corporate adoption of PG. - -Brad - - ->>>>>>>>>>>>>>>>>> Original Message <<<<<<<<<<<<<<<<<< - -On 2/8/02, 5:29:22 AM, Darren Johnson wrote -regarding Re: [HACKERS] Replication: - - -> > -> > The problems with two stage commit type approches to replication are - -> IMHO the biggest problem with two phased commit is it doesn't scale. -> The more servers -> you add to the replica the slower it goes. Also there's the potential -> for dead locks across -> server boundaries. - -> > -> > 2) All of the databases must be able to communicate with each other at -> > all times in order for any edits to work. If the servers are -> > connected over some sort of WAN that periodically has short outages this -> > is a problem. Also if your using replication because you want to be -> able -> > to take down one of the databases for short periods of time without -> > bringing down the others your in trouble. - -> All true for two phased commit protocol. To have multi master -> replication, you must have all -> systems communicating, but you can use a multicast group communication -> system instead of -> 2PC. Using total order messaging, you can ensure all changes are -> delivered to all servers in the -> replica in the same order. This group communication system also allows -> failures to be detected -> while other servers in the replica continue processing. - -> A few of us are working with this theory, and trying to integrate with -> 7.2. There is a working -> model for 6.4, but its very limited. (insert, update, and deletes) We -> are currently hosted at - -> http://gborg.postgresql.org/project/pgreplication/projdisplay.php -> But the site has been down the last 2 days. I've contacted the web -> master, but haven't seen -> any results yet. If any one knows what going on with gborg, I'd -> appreciate a status. - -> Darren - - -> ---------------------------(end of broadcast)--------------------------- -> TIP 2: you can get off all lists at once with the unregister command -> (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M18642=candle.pha.pa.us=pgman@postgresql.org Fri Feb 8 12:40:36 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g18HeZP08450 - for ; Fri, 8 Feb 2002 12:40:35 -0500 (EST) -Received: (qmail 74089 invoked by alias); 8 Feb 2002 17:40:30 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 8 Feb 2002 17:40:30 -0000 -Received: from lakemtao03.mgt.cox.net (mtao3.east.cox.net [68.1.17.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g18HbwE73437 - for ; Fri, 8 Feb 2002 12:37:58 -0500 (EST) - (envelope-from darren.johnson@cox.net) -Received: from cox.net ([68.10.181.230]) by lakemtao03.mgt.cox.net - (InterMail vM.5.01.04.05 201-253-122-122-105-20011231) with ESMTP - id <20020208173804.DKQS6710.lakemtao03.mgt.cox.net@cox.net>; - Fri, 8 Feb 2002 12:38:04 -0500 -Message-ID: <3C63FB71.206@cox.net> -Date: Fri, 08 Feb 2002 11:23:13 -0500 -From: Darren Johnson -User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; m18) Gecko/20010131 Netscape6/6.01 -X-Accept-Language: en -MIME-Version: 1.0 -To: Bradley Kieser -cc: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Replication -References: <3C636232.6060206@cox.net> <20020208.11093600@laptop.kieser.demon.co.uk> -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -> -> Given that different replication strategies will probably be developed -> for PG, do you envisage DBAs to be able to select the type of replication -> for their installation? I.e. Replication being selectable rther like -> storage structures? - -I can't speak for other replication solutions, but we are using the ---with-replication or --r parameter when starting postmaster. Some day I hope there will be -parameters for -master/slave partial/full and sync/async, but it will be some time -before we cross those -bridges. - -Darren - - - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18658=candle.pha.pa.us=pgman@postgresql.org Fri Feb 8 14:42:40 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g18JgdP28166 - for ; Fri, 8 Feb 2002 14:42:39 -0500 (EST) -Received: (qmail 18650 invoked by alias); 8 Feb 2002 19:42:39 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 8 Feb 2002 19:42:39 -0000 -Received: from enigma.trueimpact.net (enigma.trueimpact.net [209.82.45.201]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g18JYBE17341 - for ; Fri, 8 Feb 2002 14:34:11 -0500 (EST) - (envelope-from rjonasz@trueimpact.com) -Received: from nietzsche.trueimpact.net (unknown [209.82.45.200]) - by enigma.trueimpact.net (Postfix) with ESMTP id A785066B04 - for ; Fri, 8 Feb 2002 14:33:28 -0500 (EST) -Date: Fri, 8 Feb 2002 14:34:34 -0500 (EST) -From: Randall Jonasz -X-X-Sender: -To: PostgreSQL-development -Subject: Re: [HACKERS] Replication -In-Reply-To: <3C627887.CC9FF837@mohawksoft.com> -Message-ID: <20020208142932.H6545-100000@nietzsche.trueimpact.net> -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -I've been looking into database replication theory lately and have found -some interesting papers discussing various approaches. (Here's -one paper that struck me as being very helpful, -http://citeseer.nj.nec.com/460405.html ) So far I favour an -eager replication system which is predicated on a read local/write all -available. The system should not depend on two phase commit or primary -copy algorithms. The former leads to the whole system being as quick as -the slowest machine. In addition, 2 phase commit involves 2n messages for -each transaction which does not scale well at all. This idea will also -have to take into account a crashed node which did not ack a transaction. -The primary copy algorithms I've seen suffer from a single point of -failure and potential bottlenecks at the primary node. - -Instead I like the master to master or peer to peer algorithm as discussed -in the above paper. This approach accounts for network partitions, nodes -leaving and joining a cluster and the ability to commit a transaction once -the communication module has determined the total order of the said -transaction, i.e. no need for waiting for acks. This scales well and -research has shown it to increase the number of transactions/second a -database cluster can handle over a single node. - -Postgres-R is another interesting approach which I think should be taken -seriously. Anyone interested can read a paper on this at -http://citeseer.nj.nec.com/330257.html - -Anyways, my two cents - -Randall Jonasz -Software Engineer -Click2net Inc. - - -On Thu, 7 Feb 2002, mlw wrote: - -> Gavin Sherry wrote: -> > Naturally, this would slow down writes to the system (possibly a lot -> > depending on the performance difference between the executing machine and -> > the least powerful machine in the cluster), but most usages of postgresql -> > are read intensive, not write. -> > -> > Any reason this model would not work? -> -> What, then is the purpose of replication to multiple masters? -> -> I can think of only two reasons why you want replication. (1) Redundancy, make -> sure that if one server dies, then another server has the same data and is used -> seamlessly. (2) Increase performance over one system. -> -> In reason (1) I submit that a server load balance which sits on top of -> PostgreSQL, and executes writes on both servers while distributing reads would -> be best. This is a HUGE project. The load balancer must know EXACTLY how the -> system is configured, which includes all functions and everything. -> -> In reason (2) your system would fail to provide the scalability that would be -> needed. If writes take a long time, but reads are fine, what is the difference -> between the trigger based replicator? -> -> I have in the back of my mind, an idea of patching into the WAL stuff, and -> using that mechanism to push changes out to the slaves. -> -> Where one machine is still the master, but no trigger stuff, just a WAL patch. -> Perhaps some shared memory paradigm to manage WAL visibility? I'm not sure -> exactly, the idea hasn't completely formed yet. -> -> ---------------------------(end of broadcast)--------------------------- -> TIP 5: Have you checked our extensive FAQ? -> -> http://www.postgresql.org/users-lounge/docs/faq.html -> -> - - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M18660=candle.pha.pa.us=pgman@postgresql.org Fri Feb 8 15:20:32 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g18KKSP03731 - for ; Fri, 8 Feb 2002 15:20:29 -0500 (EST) -Received: (qmail 28961 invoked by alias); 8 Feb 2002 20:20:27 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 8 Feb 2002 20:20:27 -0000 -Received: from inflicted.crimelabs.net (crimelabs.net [66.92.101.112]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g18KC7E27667 - for ; Fri, 8 Feb 2002 15:12:07 -0500 (EST) - (envelope-from bpalmer@crimelabs.net) -Received: from mizer.crimelabs.net (mizer.crimelabs.net [192.168.88.10]) - by inflicted.crimelabs.net (Postfix) with ESMTP - id 1066F8787; Fri, 8 Feb 2002 15:12:08 -0500 (EST) -Date: Fri, 8 Feb 2002 15:12:00 -0500 (EST) -From: bpalmer -To: Randall Jonasz -cc: PostgreSQL-development -Subject: Re: [HACKERS] Replication -In-Reply-To: <20020208142932.H6545-100000@nietzsche.trueimpact.net> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -I've not looked at the first paper, but I wil. - -> Postgres-R is another interesting approach which I think should be taken -> seriously. Anyone interested can read a paper on this at -> http://citeseer.nj.nec.com/330257.html - -I would point you to the info on gborg, but it seems to be down at the -moment. - -- Brandon - ----------------------------------------------------------------------------- - c: 646-456-5455 h: 201-798-4983 - b. palmer, bpalmer@crimelabs.net pgp:crimelabs.net/bpalmer.pgp5 - - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M18666=candle.pha.pa.us=pgman@postgresql.org Fri Feb 8 17:41:03 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g18Mf2P18046 - for ; Fri, 8 Feb 2002 17:41:03 -0500 (EST) -Received: (qmail 63057 invoked by alias); 8 Feb 2002 22:41:02 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 8 Feb 2002 22:41:02 -0000 -Received: from lakemtao03.mgt.cox.net (mtao3.east.cox.net [68.1.17.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g18MR9E60361 - for ; Fri, 8 Feb 2002 17:27:11 -0500 (EST) - (envelope-from darren.johnson@cox.net) -Received: from cox.net ([68.10.181.230]) by lakemtao03.mgt.cox.net - (InterMail vM.5.01.04.05 201-253-122-122-105-20011231) with ESMTP - id <20020208222634.GTRG6710.lakemtao03.mgt.cox.net@cox.net>; - Fri, 8 Feb 2002 17:26:34 -0500 -Message-ID: <3C643F0F.70303@cox.net> -Date: Fri, 08 Feb 2002 16:11:43 -0500 -From: Darren Johnson -User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; m18) Gecko/20010131 Netscape6/6.01 -X-Accept-Language: en -MIME-Version: 1.0 -To: Randall Jonasz -cc: PostgreSQL-development -Subject: Re: [HACKERS] Replication -References: <20020208142932.H6545-100000@nietzsche.trueimpact.net> -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -> I've been looking into database replication theory lately and have found -> some interesting papers discussing various approaches. (Here's -> one paper that struck me as being very helpful, -> http://citeseer.nj.nec.com/460405.html ) - - -Here is another one from that same group, that addresses the WAN issues. - -> http://www.cnds.jhu.edu/pub/papers/cnds-2002-1.pdf - - -enjoy, - -Darren - - - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M18674=candle.pha.pa.us=pgman@postgresql.org Fri Feb 8 19:20:30 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g190KTP26980 - for ; Fri, 8 Feb 2002 19:20:29 -0500 (EST) -Received: (qmail 88124 invoked by alias); 9 Feb 2002 00:20:27 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 9 Feb 2002 00:20:27 -0000 -Received: from localhost.localdomain (bgp01077650bgs.wanarb01.mi.comcast.net [68.40.135.112]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g190H3E87489 - for ; Fri, 8 Feb 2002 19:17:03 -0500 (EST) - (envelope-from camber@ais.org) -Received: from localhost (camber@localhost) - by localhost.localdomain (8.11.6/8.11.6) with ESMTP id g190H0P18427; - Fri, 8 Feb 2002 19:17:00 -0500 -X-Authentication-Warning: localhost.localdomain: camber owned process doing -bs -Date: Fri, 8 Feb 2002 19:17:00 -0500 (EST) -From: Brian Bruns -X-X-Sender: -To: Randall Jonasz -cc: PostgreSQL-development -Subject: Re: [HACKERS] Replication -In-Reply-To: <20020208142932.H6545-100000@nietzsche.trueimpact.net> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -> > I have in the back of my mind, an idea of patching into the WAL stuff, and -> > using that mechanism to push changes out to the slaves. -> > -> > Where one machine is still the master, but no trigger stuff, just a WAL patch. -> > Perhaps some shared memory paradigm to manage WAL visibility? I'm not sure -> > exactly, the idea hasn't completely formed yet. -> > - -FWIW, Sybase Replication Server does just such a thing. - -They have a secondary log marker (prevents the log from truncating past -the oldest unreplicated transaction). A thread within the system called -the "rep agent" (but it use to be a separate process call the LTM), reads -the log and forwards it to the rep server, once the rep server has the -whole transaction and it is written to a stable device (aka synced to -disk) the rep server responds to the LTM telling him it's OK to move the -log marker forward. - -Anyway, once the replication server proper has the transaction it uses a -publish/subscribe methodology to see who wants get the update. - -Bidirectional replication is done by making two oneway replications. The -whole thing is table based, it marks the tables as replicated or not in -the database to save the trip to the repserver on un replicated tables. - -Plus you can take parts of a database (replicate all rows where the -country is "us" to this server and all the rows with "uk" to that server). -Or opposite you can roll up smaller regional databases to bigger ones, -it's very flexible. - - -Cheers, - -Brian - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - diff --git a/doc/TODO.detail/schema b/doc/TODO.detail/schema deleted file mode 100644 index b7c8464578..0000000000 --- a/doc/TODO.detail/schema +++ /dev/null @@ -1,7817 +0,0 @@ -From ronz@ravensfield.com Tue May 22 17:35:37 2001 -Return-path: -Received: from carp.ravensfield.com ([209.41.227.126]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f4MLZaQ17913 - for ; Tue, 22 May 2001 17:35:37 -0400 (EDT) -Received: from coho.ravensfield.com (coho [209.41.227.117]) - by carp.ravensfield.com (Postfix) with SMTP - id 5C2A9800D; Tue, 22 May 2001 16:46:38 -0500 (EST) -Content-Type: text/plain; - charset="iso-8859-1" -From: Andrew Rawnsley -Organization: Ravensfield Geographic -To: Bruce Momjian -Subject: Re: [GENERAL] Queries across multiple databases (was: SELECT from a table in another database). -Date: Tue, 22 May 2001 17:37:25 -0400 -X-Mailer: KMail [version 1.2] -cc: Tom Lane -References: <200105220437.f4M4bUA00539@candle.pha.pa.us> -In-Reply-To: <200105220437.f4M4bUA00539@candle.pha.pa.us> -MIME-Version: 1.0 -Message-ID: <01052217372504.01367@coho.ravensfield.com> -Content-Transfer-Encoding: 8bit -Status: ORr - -On Tuesday 22 May 2001 12:37am, Bruce Momjian wrote: -> Can you send me a little sample of SCHEMA use? - -Pardon if this is more long-winded or tangental than you are looking for... - -What may beconfusing many people (not excluding myself from time to time) is -that cross-schema queries may have nothing to do with cross-database queries, -which is an entirely different kettle of trout.... SCHEMAs as used by at -least by Oracle and Sybase are nothing more than users/object owners (I have -no experience with DB2 or Informix, or anything more exotic than that). - -Just off the top of my head, what would satisfy most people would be to be -able to refer to objects as OWNER.OBJECT, with owner being 'within' the -database (i.e. DATABASE.OWNER.OBJECT, which is how Sybase does it. Oracle has -no 'database' parallel like that). Whether you do it Oracle-fashion and use -the term SCHEMA for owner pretty universally or Sybase fashion and just pay -lip service to the word doesn't really matter (unless there is a standards -compliance issue). - -As to creating schemas...In Oracle you have to execute the CREATE SCHEMA -AUTHORIZATION while logged in as that user before you can add objects -under that user's ownership. While it seems trivial, if you have a situation -where you do not want to grant a user session rights, you have to grant them -session rights, log in as them, execute CREATE SCHEMA..., then revoke the -session rights. Bah. A table created by user X in schema Y is also owned by -user Y, and its user Y that has to have many of the object rights to create -that table. - -In Sybase, its essentially the same except the only real use for the CREATE -SCHEMA command is for compliance and to group some DDL commands together. -Other than that, Sybase always refers to schemas as owners. You don't have to -execute CREATE SCHEMA... to create objects - you just need the rights. I've -never used it at least - the only thing I see in it is eliminating the need -to type 'go' after every DDL command. - -As for examples from Oracle space - - -Here is a foreign key reference with delete triggers from a table in -schema/user PROJECT to tables in schemas/users SERVICES and WEBCAL: - -CREATE TABLE PROJECT.tasks_users ( -   event_id INTEGER REFERENCES WEBCAL.tasks(event_id) ON DELETE CASCADE, -   user_id VARCHAR2(25) REFERENCES SERVICES.users(user_id) ON DELETE CASCADE, -   confirmed CHAR(1), -   PRIMARY KEY (event_id,user_id) -); - -A join between tables in would be -SELECT   A.SAMPLE_ID, -                 A.CONCENTRATION, -                 A.CASNO, -                 B.PARAMETER, -                 C.DESCRIPTION AS STYPE -         FROM HAI.RESULTS A, SAMPLETRACK.PARAMETERS B, -SAMPLETRACK.SAMPLE_TYPE C -                 WHERE A.CASNO = B.CASNO AND A.SAMPLE_TYPE = B.SAMPLE_TYPE - -In both Oracle and Sybase, all the objects are in the same 'database' -(instance in Oracle), as I assume they would be in Postgres. There is I -assume a name space issue - one should be able to create a FOO.BAR and a -BAR.BAR in the same database. - -> I may be adding it to -> 7.2 inside the same code that maps temp table names to real tables. -> - -Excellent! I see light at the end of the tunnel (I will say the Postgres -maintainers are among the most solidly competent around - one never has any -real doubts about the system's progress). - --- -Regards, - -Andrew Rawnsley -Ravensfield Digital Resource Group, Ltd. -(740) 587-0114 -www.ravensfield.com - -From reedstrm@rice.edu Wed May 23 10:59:42 2001 -Return-path: -Received: from ece.rice.edu (ece.rice.edu [128.42.4.34]) - by candle.pha.pa.us (8.10.1/8.10.1) with ESMTP id f4NExgQ05774 - for ; Wed, 23 May 2001 10:59:42 -0400 (EDT) -Received: from wallace.ece.rice.edu (wallace.ece.rice.edu [128.42.12.154]) - by ece.rice.edu (Postfix) with ESMTP id A419F68A0E - for ; Wed, 23 May 2001 09:59:36 -0500 (CDT) -Received: from reedstrm by wallace.ece.rice.edu with local (Exim 3.22 #1 (Debian)) - id 152a41-0006E5-00 - for ; Wed, 23 May 2001 09:56:41 -0500 -Date: Wed, 23 May 2001 09:56:41 -0500 -From: "Ross J. Reedstrom" -To: Bruce Momjian -Subject: Re: [HACKERS] Re: [GENERAL] Re: [GENERAL] Queries across multiple databases ?(was: SELECT from a table in another database). -Message-ID: <20010523095641.D23741@rice.edu> -References: <004c01c0e214$ce6c4800$1001a8c0@archonet.com> <200105221131.f4MBVIc28574@candle.pha.pa.us> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -User-Agent: Mutt/1.3.17i -In-Reply-To: <200105221131.f4MBVIc28574@candle.pha.pa.us>; from pgman@candle.pha.pa.us on Tue, May 22, 2001 at 07:31:18AM -0400 -Status: ORr - -Bruce - -Around the first of the year, I started playing around with a schema -implementation. As you may recall, my first crack at changing file storage -names about a year ago was motivated by the need to avoid collisions -once schema were available. - -Anyway, now that Vadim has removed a lot of the internal dependence -on relname for keeping track of relations, using the new relfinenode -many places relname used to be used, it seems to me that adding a -parallel schemaname to all the data structures that use relname isn't -as cumbersome as Peter might think. I hadn't tackled the relcache yet: -perhaps concatenating the schemaname and relname to use as the hash key -is the way to go for that. - -Unfortunately, all that code is now 4 months old, and on my machine -at home. I has started with the rangetable entries, because hacked the -parser to allow 'SELECT * FROM schemaname.tablename' was easier than -'select schemaname.tablename.fieldname FROM', since the dot function -calling convention isn't allowed in the range list, while it is in the -target list. - -I seem to recall tripping up on the query plan printer, of all things, -before other, paying work pushed it aside. I'll see if I can update that -code to the current tree, and send you something, if you'd like. - -Ross - - - -On Tue, May 22, 2001 at 07:31:18AM -0400, Bruce Momjian wrote: -> > > I'm not sure whether it is quite the way to do it, but I'd have a better -> > > time with things if I could span databases in a single request. Are -> > > there theoretical problems with spanning databases in a single query? Is -> > > it a feature of bad database design & implementation? -> > -> > I think the developers are planning full schema support for the relatively -> > near future (possibly even 7.2, but check the archives and see what's been -> > said). Although it looks easy to access a table from another database, -> > things can rapidly become more complicated as you start having to deal with -> > transactions, triggers, rules, constraints... -> -> Schema is on my radar screen for 7.2. I am waiting to do some research -> in what needs to be done, but my initial idea is to use the system cache -> to do namespace mapping, just like is done now for temp tables. -> -> -- -> Bruce Momjian | http://candle.pha.pa.us -> pgman@candle.pha.pa.us | (610) 853-3000 -> + If your life is a hard drive, | 830 Blythe Avenue -> + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 -> -> ---------------------------(end of broadcast)--------------------------- -> TIP 2: you can get off all lists at once with the unregister command -> (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M17793=candle.pha.pa.us=pgman@postgresql.org Fri Jan 18 19:40:47 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0J0elU09208 - for ; Fri, 18 Jan 2002 19:40:47 -0500 (EST) -Received: (qmail 94886 invoked by alias); 19 Jan 2002 00:40:45 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 19 Jan 2002 00:40:45 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0J0TfV92793 - for ; Fri, 18 Jan 2002 19:29:41 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0J0Th311096 - for ; Fri, 18 Jan 2002 19:29:44 -0500 (EST) -To: pgsql-hackers@postgresql.org -Subject: [HACKERS] Schemas vs. PostQUEL: resolving qualified identifiers -Date: Fri, 18 Jan 2002 19:29:43 -0500 -Message-ID: <11093.1011400183@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -I'm starting to think about how to do SQL-compatible schemas in Postgres. - -One of the first issues that comes up is that Postgres has interpretations -of qualified (dotted) names that conflict with what the standard says to -do. This stuff is a hangover from Berkeley days and PostQUEL. Briefly, -since there are no schemas in PG, anytime we have a dotted name we know -that the first component *must* be a table name. Successive components are -then resolved as either column or function names applied to whatever we -have so far. For example, - - a.b.c is equivalent to c(a.b) if c is a function - -The equivalence works the other way too: you can write colname(tabname) -and it will be taken as tabname.colname (though this seems to work only -if tabname already has a rangetable entry). - -This is not going to fly together with SQL92, which wants a.b.c to mean -schema a, table b, column c. - -I believe we can resolve the conflict without breaking any cases that -are likely to be used much in practice. Here's my proposal: - -First, I'd like to allow the notation "table.*" to be used as a function -argument, representing passing a whole-row value to a function (the -function's argument would be declared as the table rowtype). Presently -this is done by writing just the undecorated table name, but that is -ambiguous if the same name is also used as a column name in the query. -Also, we need this notation for use with qualified table names. - -Having done that, we can resolve names appearing in expressions thus: - -foo First try to resolve as unqualified column name; - if not found, try to resolve as unqualified table name - (in which case this is a whole-row value, equivalent - to foo.*). - -foo.bar foo is an unqualified table name. Try first to resolve - bar as a column name of foo; if not found, try to resolve - bar as a function taking the rowtype of foo. - -foo.bar.baz This refers to table bar in schema foo. baz is either - a column or function name, as above. - -foo.bar.baz.quux Refers to table baz in schema bar in catalog foo. - quux is either a column or function name, as above. - -foo.* foo is an unqualified table name; means whole-row value. - -foo.bar.* Whole row of table bar in schema foo. - -foo.bar.baz.* Whole row of table baz in schema bar in catalog foo. - -The first two of these rules are the same as current behavior; the next -two are additions mandated by SQL92; the last three are a proposed -extension to allow unambiguous reference to whole-row values. - -With these rules, we do not lose any functionality that we have now, -but some PostQUEL-ish constructs will need to be rewritten into an -equivalent form. - -PostQUEL-isms that still work: - -table.func equivalent to func(table.*) - -func(table) equivalent to func(table.*), as long as table name - doesn't match any column name of the query - -PostQUEL-isms that no longer work: - -table.col.func Must rewrite as func(table.col) - -table.func1.func2 Must rewrite as, eg, func2(func1(table.*)) - -While there are a couple of examples of the above two constructs in the -regression tests, I doubt they are used much in the real world. - -Another PostQUEL-ism that I would like to remove is col(tab) to mean -tab.col; I'd prefer to restrict the function syntax to functions only. -We could continue to support this for unqualified table names, but -given the above rules it could not work for a qualified table name, -eg, col(schema.tab) would be misinterpreted. Again, it seems unlikely -that many people are using this, so we may as well try to regularize -the syntax as much as we can. - -You may wonder why I'm still allowing the construction tab.func --- -why not get rid of that too? Well, mainly because I'd like to support -the Oracle-ish syntax for nextval: seqname.nextval. Together with the -desire not to break existing code unnecessarily, that seems a good enough -reason to leave it in. - -Comments? - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M18054=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 14:15:06 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NJF5U00389 - for ; Wed, 23 Jan 2002 14:15:05 -0500 (EST) -Received: (qmail 74462 invoked by alias); 23 Jan 2002 19:13:45 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 19:13:45 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0NJ0Fl67761 - for ; Wed, 23 Jan 2002 14:00:15 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0NJ00f04506; - Wed, 23 Jan 2002 14:00:01 -0500 (EST) -To: Fernando Nasser -cc: Zeugswetter Andreas SB SD , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Schemas vs. PostQUEL: resolving qualified identifiers -In-Reply-To: <3C4EFD15.882B0785@redhat.com> -References: <46C15C39FEB2C44BA555E356FBCD6FA42128D9@m0114.s-mxs.net> <2521.1011798379@sss.pgh.pa.us> <3C4EFD15.882B0785@redhat.com> -Comments: In-reply-to Fernando Nasser - message dated "Wed, 23 Jan 2002 13:12:37 -0500" -Date: Wed, 23 Jan 2002 14:00:00 -0500 -Message-ID: <4503.1011812400@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Fernando Nasser writes: -> Tom Lane wrote: ->> Okay, but then how will you refer unambiguously to the rowtype object? - -> What about casting with the keyord ROW? -> func(ROW table) -> always refers to the row-type of table "table" even if there is -> a column called "table". - -Strikes me as gratuituously different from the way everything else is -done. We have .* and %ROWTYPE and so forth, and they're all suffixes. -The closest analogy to your ROW syntax is CAST, but it doesn't alter the -initial interpretation of its argument. - -I was toying with the notion of inventing some new notation like - table.** -I don't like double-asterisk much, but maybe there's some other symbol -we could use here? - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18069=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 17:13:24 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NMDOU16966 - for ; Wed, 23 Jan 2002 17:13:24 -0500 (EST) -Received: (qmail 49292 invoked by alias); 23 Jan 2002 22:13:23 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 22:13:23 -0000 -Received: from cygnus.com (runyon.sfbay.redhat.com [205.180.230.5] (may be forged)) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0NLvFl45904 - for ; Wed, 23 Jan 2002 16:57:15 -0500 (EST) - (envelope-from fnasser@redhat.com) -Received: from redhat.com (totem.toronto.redhat.com [172.16.14.242]) - by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id NAA18180; - Wed, 23 Jan 2002 13:57:09 -0800 (PST) -Message-ID: <3C4F31B4.C7C9B2D6@redhat.com> -Date: Wed, 23 Jan 2002 16:57:08 -0500 -From: Fernando Nasser -Organization: Red Hat , Inc. - Toronto -X-Mailer: Mozilla 4.78 [en] (X11; U; Linux 2.4.7-10smp i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Tom Lane -cc: Zeugswetter Andreas SB SD , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Schemas vs. PostQUEL: resolving qualified identifiers -References: <46C15C39FEB2C44BA555E356FBCD6FA42128D9@m0114.s-mxs.net> <2521.1011798379@sss.pgh.pa.us> <3C4EFD15.882B0785@redhat.com> <4503.1011812400@sss.pgh.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> -> Fernando Nasser writes: -> > Tom Lane wrote: -> >> Okay, but then how will you refer unambiguously to the rowtype object? -> -> > What about casting with the keyord ROW? -> > func(ROW table) -> > always refers to the row-type of table "table" even if there is -> > a column called "table". -> -> Strikes me as gratuituously different from the way everything else is -> done. We have .* and %ROWTYPE and so forth, and they're all suffixes. -> The closest analogy to your ROW syntax is CAST, but it doesn't alter the -> initial interpretation of its argument. -> - -I didn't mean literally that way, I just wanted to add a keyword for -solving ambiguity (when there is one). - -You are right, it should be: - -func(table%ROWTYPE) - - - - --- -Fernando Nasser -Red Hat - Toronto E-Mail: fnasser@redhat.com -2323 Yonge Street, Suite #300 -Toronto, Ontario M4P 2C9 - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M17920=candle.pha.pa.us=pgman@postgresql.org Mon Jan 21 16:45:17 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0LLjHU16235 - for ; Mon, 21 Jan 2002 16:45:17 -0500 (EST) -Received: (qmail 38745 invoked by alias); 21 Jan 2002 21:43:19 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 21 Jan 2002 21:43:19 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0LLTql30573 - for ; Mon, 21 Jan 2002 16:29:53 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0LLTrf11384 - for ; Mon, 21 Jan 2002 16:29:53 -0500 (EST) -To: pgsql-hackers@postgresql.org -Subject: [HACKERS] RFD: schemas and different kinds of Postgres objects -Date: Mon, 21 Jan 2002 16:29:52 -0500 -Message-ID: <11381.1011648592@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Continuing to think about implementing SQL schemas for 7.3 ... - -Today's topic for discussion: which types of Postgres objects should -belong to schemas, and which ones should have other name scopes? - -Relations (tables, indexes, views, sequences) clearly belong to schemas. -Since each relation has an associated datatype with the same name, it -seems that datatypes must belong to schemas as well. (Even if that -argument doesn't convince you, SQL99 says that user-defined datatypes -belong to schemas.) However the situation is murkier for other kinds of -objects. - -Here are all the kinds of named objects that exist in Postgres today, -with some comments on whether they should belong to schemas or not: - -relations Must be in schemas -types Must be in schemas -databases Databases contain schemas, not vice versa -users Users are cross-database, so not in schemas -groups User groups are cross-database, so not in schemas -languages Probably should not be in schemas -access methods Probably should not be in schemas -opclasses See below -operators See below -functions/procedures See below -aggregates Should treat same as regular functions -constraints See below -rules See below -triggers See below -NOTIFY conditions See below - -Languages and access methods are not trivial to add to the system, so -there's not much risk of name conflicts, and no reason to make their name -scope less than global. - -The situation is a lot murkier for operators and functions. These should -probably be treated alike, since operators are just syntactic sugar for -functions. I think the basic argument for making them schema-local is -that different users might conceivably want to define conflicting -functions or operators of the same name. Against that, however, there -are a number of reasons for wanting to keep these objects database-wide. -First off there are syntactic problems. Do you really want to write - A schemaname.+ B -to qualify an ambiguous "+" operator? Looks way too much like a syntax -error to me. Allowing this would probably turn a lot of simple syntax -errors into things that get past the grammar and end up producing truly -confusing error messages. Qualified function names also pose some -problems, not so much with - schemaname.function(args) -which seems reasonable, but with the Berkeley-derived syntax that allows -"foo.function" to mean "function(foo)" --- there's no way to squeeze a -schema-name for the function into that. (And you'll recall from my note -of the other day that we don't want to abandon this syntax entirely, -because people would like us to support "sequencename.nextval" for Oracle -compatibility.) Notice that we are not forced to make functions/operators -schema-local just because datatypes are, because overloading will save the -day. func(schema1.type1) and func(schema2.type1) are distinct functions -because the types are different, even if they live in the same function -namespace. Finally, SQL99 doesn't appear to think that operator and -function names are schema-local; though that may just be because it hasn't -got user-defined operators AFAICT. - -I am leaning towards keeping functions/operators database-wide, but would -like to hear comments. Is there any real value in, eg, allowing different -users to define different "+" operators *on the same datatypes*? - -Not sure about index opclasses. Given that datatype names are -schema-local, one can think of scenarios where two users define similar -datatypes and then try to use the same index opclass name for both. -But it seems pretty unlikely. I'd prefer to leave opclass names -database-wide for simplicity. Comments? - -As for constraints, currently we only support table-level constraints, -and we do not enforce any uniqueness at all on their names; multiple -constraints for the same table can have the same name (and if so, ALTER -TABLE DROP CONSTRAINT drops all matching names). SQL92 requires named -constraints to have names that are unique within their schema, which is -okay for standalone assertions (which we haven't got) but seems quite -unnecessary for constraints attached to tables. And what's really odd, -it appears to allow a table constraint to belong to a different schema -than the table it is on! This is pretty bogus. I'd prefer to ignore the -part of the spec that says that table constraint names can be qualified -names, and either keep our existing behavior or require constraint names -to be unique per-table. Thoughts? - -Rewrite rules are currently required to have a name unique within their -database. We clearly don't want that to still be true in the schema -environment. Personally I would like to make rules' names unique only -among rules on the same table (like we handle triggers). That would -mean an incompatible change in the syntax of DROP RULE: it'd have to -become DROP RULE rule ON table, much like DROP TRIGGER. Is that okay? -If not, probably we must make rulenames local to schemas and say they -implicitly belong to the schema of the associated table. - -Triggers are already handled as being named uniquely among the triggers -of the same table. This behavior is fine with me, and doesn't need to -be changed for schema support. - -I can see some advantage to considering NOTIFY condition names to be local -to a schema, but I can also see risks of breaking existing applications. -Currently, "NOTIFY foo" will signal to "LISTEN foo" even if the two -processes belong to different users. With an implicit schema qualifier -attached to foo, very likely this would fail to work. Since NOTIFY names -aren't officially registered anywhere, the implicit qualifier would have -to correspond to the front schema of one's schema search path, and there'd -be no way for such processes to communicate if their search paths didn't -match. I think people would end up always qualifying NOTIFY names with -a single schema name, which means we might as well continue to consider -them global. On the other hand, if you assume that NOTIFY names are often -the names of tables, it'd make sense to allow them to be qualified. Any -thoughts on this? - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M17929=candle.pha.pa.us=pgman@postgresql.org Mon Jan 21 19:13:39 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0M0DcU03335 - for ; Mon, 21 Jan 2002 19:13:38 -0500 (EST) -Received: (qmail 78739 invoked by alias); 22 Jan 2002 00:12:48 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 00:12:48 -0000 -Received: from corvette.mascari.com (dhcp065-024-158-068.columbus.rr.com [65.24.158.68]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0LNo9l76502 - for ; Mon, 21 Jan 2002 18:50:09 -0500 (EST) - (envelope-from mascarm@mascari.com) -Received: from mascari.com (ferrari.mascari.com [192.168.2.1]) - by corvette.mascari.com (8.9.3/8.9.3) with ESMTP id SAA26029 - for ; Mon, 21 Jan 2002 18:45:34 -0500 -Message-ID: <3C4CA81E.4D1D7BD9@mascari.com> -Date: Mon, 21 Jan 2002 18:45:34 -0500 -From: Mike Mascari -X-Mailer: Mozilla 4.7 [en] (WinNT; I) -X-Accept-Language: en -MIME-Version: 1.0 -To: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: <11381.1011648592@sss.pgh.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> -> Continuing to think about implementing SQL schemas for 7.3 ... -> -> Today's topic for discussion: which types of Postgres objects should -> belong to schemas, and which ones should have other name scopes? -... -> -> I am leaning towards keeping functions/operators database-wide, but would -> like to hear comments. Is there any real value in, eg, allowing different -> users to define different "+" operators *on the same datatypes*? - -With regard to functions, I believe they should be schema specific. -Oracle allows the creation of procedures/functions in specific schema. -User2 may then execute user1's function as: - -EXECUTE user1.myfunction(); - -However, as you suggest, the fully qualified naming of functions gets -messy. So Oracle allows (and I think we would need) PUBLIC SYNONYMs. -This allows user1 to do: - -CREATE TABLE employees(key integer, name VARCHAR(20)); - -CREATE SEQUENCE s; - -CREATE PROCEDURE newemployee(n IN VARCHAR) -AS -BEGIN -INSERT INTO employees -SELECT s.nextval, n -FROM DUAL; -END; -/ - -GRANT INSERT ON employees TO user2; -GRANT EXECUTE ON newemployee TO user2; -CREATE PUBLIC SYNONYM newemployee FOR user1.newemployee; - -Now, user2 just does: - -EXECUTE newemployee(10); - - -In fact, with regard to the package discussion a while back, Oracle -allows this: - -Database->Schema->Package->Procedure - -and this: - -Database->Schema->Procedure - -and effectively this: - -Database->Procedure via Database->PUBLIC Schema->Procedure - -I really think that the main purpose of schemas is to prevent an -ill-informed or malicious user from engaging in unacceptable behavior. -By placing everything in schemas, it allows the Oracle DBA to have a -very fine-grained control over the ability of user1 to interfere with -user2. Before user1 above could pollute the global namespace, the dba -must have: - -GRANT user1 CREATE PUBLIC SYNONYM - -privilege, or created the synonym himself. This allows things like -pg_class to reside within their own schema, as well as all built-in -PostgreSQL functions. After the bootstrapping, PUBLIC SYNONYMs are -created for all of the system objects which should have global scope: - -CREATE PUBLIC SYNONYM pg_class FOR system.pg_class; -CREATE PUBLIC SYNONYM abs(int) FOR system.abs(int); - -One major benefit of Oracle is that the DBA, through the use of -STATEMENT privileges (i.e. GRANT CREATE TABLE to user1), resource -PROFILEs, and TABLESPACES can easily admin a database used by 20 -different deparments and 1000 different users without the fear that one -might step on the other's toes. If the accounting department wants to -create an addtax() function, it shouldn't have to ask the receiving -deptartment to do so. - -Just my thoughts, - -Mike Mascari -mascarm@mascari.com - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M17928=candle.pha.pa.us=pgman@postgresql.org Mon Jan 21 19:13:39 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0M0DcU03336 - for ; Mon, 21 Jan 2002 19:13:38 -0500 (EST) -Received: (qmail 78777 invoked by alias); 22 Jan 2002 00:12:50 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 00:12:50 -0000 -Received: from student.gvsu.edu ([148.61.7.124]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0LNxBl77018 - for ; Mon, 21 Jan 2002 18:59:12 -0500 (EST) - (envelope-from peter_e@gmx.net) -Received: from [148.61.250.18] [148.61.250.18] by student.gvsu.edu - with Novonyx SMTP Server $Revision: 1.3 $; Mon, 21 Jan 2002 18:59:14 -0500 (EDT) -Date: Mon, 21 Jan 2002 19:01:13 -0500 (EST) -From: Peter Eisentraut -X-Sender: -To: Tom Lane -cc: -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <11381.1011648592@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane writes: - -> languages Probably should not be in schemas -> access methods Probably should not be in schemas -> opclasses See below -> operators See below -> functions/procedures See below -> aggregates Should treat same as regular functions -> constraints See below -> rules See below -> triggers See below -> NOTIFY conditions See below - -Remember that a schema is a named representation of ownership, so anything -that can be owned must be in a schema. (Unless you want to invent a -parallel universe for a different kind of ownership, which would be -incredibly confusing.) Also remember that we wanted to use schemas as a -way to prevent unprivileged users from creating anything by default. So -it would be much simpler if "everything" were in a schema. - -I wouldn't worry so much about the invocation syntax -- if you don't like -ugly don't make ugly. For instance, if you add a user-defined operator -you would probably either put it in the same schema with the rest of your -project or put it in some sort of a global or default schema (to be -determined) to make it available to the whole system, my assumption being -that either way you don't need to qualify the operator. But the important -thing is that you *could* make cross-schema operator calls, say during -development or testing. - -Consequentially, I opine that all of the things listed above should be in -a schema. (Although I don't have a strong opinion about notifications, -yet.) - -> namespace. Finally, SQL99 doesn't appear to think that operator and -> function names are schema-local; though that may just be because it hasn't -> got user-defined operators AFAICT. - -Check clause 10.4 : routine names are (optionally) -schema qualified like everything else. - -> Rewrite rules are currently required to have a name unique within their -> database. We clearly don't want that to still be true in the schema -> environment. Personally I would like to make rules' names unique only -> among rules on the same table (like we handle triggers). That would -> mean an incompatible change in the syntax of DROP RULE: it'd have to -> become DROP RULE rule ON table, much like DROP TRIGGER. Is that okay? -> If not, probably we must make rulenames local to schemas and say they -> implicitly belong to the schema of the associated table. - -I'd rather make the opposite change (make trigger names schema-global) -because that aligns with SQL99 and it would make more sense for overall -consistency (e.g., you can't have indexes with the same names on different -tables). The syntax change would also be backward compatible. I think -either way, schema-global or table-global namespace, can be argued to be -more useful or more confusion-prone, so I side with the standard on this -one. - --- -Peter Eisentraut peter_e@gmx.net - - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M17932=candle.pha.pa.us=pgman@postgresql.org Mon Jan 21 20:14:13 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0M1ECU11565 - for ; Mon, 21 Jan 2002 20:14:12 -0500 (EST) -Received: (qmail 88800 invoked by alias); 22 Jan 2002 01:14:11 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 01:14:11 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0M16kl87933 - for ; Mon, 21 Jan 2002 20:06:47 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0M16Uf12242; - Mon, 21 Jan 2002 20:06:30 -0500 (EST) -To: Peter Eisentraut -cc: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -References: -Comments: In-reply-to Peter Eisentraut - message dated "Mon, 21 Jan 2002 19:01:13 -0500" -Date: Mon, 21 Jan 2002 20:06:30 -0500 -Message-ID: <12239.1011661590@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Peter Eisentraut writes: -> Remember that a schema is a named representation of ownership, so anything -> that can be owned must be in a schema. (Unless you want to invent a -> parallel universe for a different kind of ownership, which would be -> incredibly confusing.) - -I don't buy that premise. It's true that SQL92 equates ownership of a -schema with ownership of the objects therein, but AFAICS we have no hope -of being forward-compatible with existing database setups (wherein there -can be multiple tables of different ownership all in a single namespace) -if we don't allow varying ownership within a schema. I think we can -arrange things so that we are upward compatible with both SQL92 and -the old way. Haven't worked out details yet though. - -Have to run, more later. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M17933=candle.pha.pa.us=pgman@postgresql.org Mon Jan 21 20:42:40 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0M1geU12708 - for ; Mon, 21 Jan 2002 20:42:40 -0500 (EST) -Received: (qmail 92393 invoked by alias); 22 Jan 2002 01:42:38 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 01:42:38 -0000 -Received: from p566.codebydesign.com (cx950878-a.fed1.sdca.home.com [24.11.158.40]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0M1cZl91431 - for ; Mon, 21 Jan 2002 20:38:35 -0500 (EST) - (envelope-from pharvey@codebydesign.com) -Received: from p12.codebydesign.com (p12.codebydesign.com [192.168.1.27]) - by p566.codebydesign.com (8.11.1/8.11.1) with SMTP id g0M2mmt12179; - Mon, 21 Jan 2002 18:48:53 -0800 -Content-Type: text/plain; - charset="iso-8859-1" -From: Peter Harvey -Organization: CodeByDesign -To: Tom Lane , Peter Eisentraut -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -Date: Mon, 21 Jan 2002 17:39:05 -0800 -X-Mailer: KMail [version 1.2] -cc: pgsql-hackers@postgresql.org -References: <12239.1011661590@sss.pgh.pa.us> -In-Reply-To: <12239.1011661590@sss.pgh.pa.us> -MIME-Version: 1.0 -Message-ID: <02012117390500.02279@p12.codebydesign.com> -Content-Transfer-Encoding: 8bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -FYI: Applications like Data Architect would benefit from a consistent and -complete interface to the schema. For example; I found that we had to bypass -the DD views which exist (as I recall) because they did not give us all -information we needed. So we selected stuff from the system tables directly. -Yucky. Sorry I can not recall details but thought that I would mention this -here. The MySQL 'SHOW' statements seem to work pretty well and shields us -from changes to the system tables. - -Peter - -> I don't buy that premise. It's true that SQL92 equates ownership of a -> schema with ownership of the objects therein, but AFAICS we have no hope -> of being forward-compatible with existing database setups (wherein there -> can be multiple tables of different ownership all in a single namespace) -> if we don't allow varying ownership within a schema. I think we can -> arrange things so that we are upward compatible with both SQL92 and -> the old way. Haven't worked out details yet though. -> -> Have to run, more later. - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M17966=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 10:53:20 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0MFrJU05739 - for ; Tue, 22 Jan 2002 10:53:20 -0500 (EST) -Received: (qmail 83537 invoked by alias); 22 Jan 2002 15:53:00 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 15:53:00 -0000 -Received: from cygnus.com (runyon.sfbay.redhat.com [205.180.230.5] (may be forged)) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0MFoql80523 - for ; Tue, 22 Jan 2002 10:50:52 -0500 (EST) - (envelope-from fnasser@redhat.com) -Received: from redhat.com (rtl.sfbay.redhat.com [205.180.230.21]) - by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id HAA09903; - Tue, 22 Jan 2002 07:50:43 -0800 (PST) -Message-ID: <3C4D8A39.FF79CDC4@redhat.com> -Date: Tue, 22 Jan 2002 10:50:17 -0500 -From: Fernando Nasser -Organization: Red Hat Canada -X-Mailer: Mozilla 4.78 [en] (X11; U; Linux 2.4.9-13 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Tom Lane -cc: Peter Eisentraut , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: <12239.1011661590@sss.pgh.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> -> Peter Eisentraut writes: -> > Remember that a schema is a named representation of ownership, so anything -> > that can be owned must be in a schema. (Unless you want to invent a -> > parallel universe for a different kind of ownership, which would be -> > incredibly confusing.) -> -> I don't buy that premise. It's true that SQL92 equates ownership of a -> schema with ownership of the objects therein, but AFAICS we have no hope -> of being forward-compatible with existing database setups (wherein there -> can be multiple tables of different ownership all in a single namespace) -> if we don't allow varying ownership within a schema. I think we can -> arrange things so that we are upward compatible with both SQL92 and -> the old way. Haven't worked out details yet though. -> - -Peter is right. Schemas is just a practical way of creating things -under -the same authorization-id + crating a namespace so that different -authorization-ids can have objects with the same (unqualified name). - -Quoting Date (pg. 221): "The schema authID for a given schema identifies -the owner of that schema (and hence the owner of everything described by -that schema also)." - -It is very important that we reach a conclusion on this as it simplifies -things a lot. - -Regards, -Fernando - - -P.S.: That is why I was telling you that, except for the namespace part, -we already have the groundwork for Entry-level SQL-Schemas (where the -schema is always the authorization-id of the creator) -- it is just -a question of handling the "owner" appropriately. - - --- -Fernando Nasser -Red Hat Canada Ltd. E-Mail: fnasser@redhat.com -2323 Yonge Street, Suite #300 -Toronto, Ontario M4P 2C9 - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M17973=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 11:26:13 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0MGQCU09218 - for ; Tue, 22 Jan 2002 11:26:12 -0500 (EST) -Received: (qmail 4629 invoked by alias); 22 Jan 2002 16:25:41 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 16:25:41 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0MGGTl95123 - for ; Tue, 22 Jan 2002 11:16:29 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0MGGBf15342; - Tue, 22 Jan 2002 11:16:11 -0500 (EST) -To: Fernando Nasser -cc: Peter Eisentraut , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <3C4D8A39.FF79CDC4@redhat.com> -References: <12239.1011661590@sss.pgh.pa.us> <3C4D8A39.FF79CDC4@redhat.com> -Comments: In-reply-to Fernando Nasser - message dated "Tue, 22 Jan 2002 10:50:17 -0500" -Date: Tue, 22 Jan 2002 11:16:11 -0500 -Message-ID: <15339.1011716171@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Fernando Nasser writes: -> Tom Lane wrote: ->> I don't buy that premise. It's true that SQL92 equates ownership of a ->> schema with ownership of the objects therein, but AFAICS we have no hope ->> of being forward-compatible with existing database setups (wherein there ->> can be multiple tables of different ownership all in a single namespace) ->> if we don't allow varying ownership within a schema. - -> Quoting Date (pg. 221): "The schema authID for a given schema identifies -> the owner of that schema (and hence the owner of everything described by -> that schema also)." - -Yes, I know what the spec says. I also think we'll have a revolt on our -hands if we don't make it possible for existing Postgres applications to -continue working as they have in the past --- and that means allowing -tables of different ownerships to be accessible in a single namespace. - -Although I haven't thought through the details yet, it seems to me that -a solution exists along these lines: - -1. The creator of an object owns it. (With some special cases, eg the - superuser should be able to create a schema owned by someone else.) - -2. Whether you can create an object in a schema that is owned by someone - else depends on permissions attached to the schema. By default only - the owner of a schema can create anything in it. - -3. SQL92-compatible behavior is achieved when everyone has their own - schema and they don't grant each other create-in-schema rights. - Backwards-compatible behavior is achieved when everyone uses a - shared "public" schema. - -We'd probably need GUC variable(s) to make it possible to choose which -behavior is the default. I haven't thought much about exactly what -knobs should be provided. I do think we will want at least these two -knobs: - -1. A "search path" that is an ordered list of schemas to look in - when trying to resolve an unqualified name. - -2. A "default schema" variable that identifies the schema to create - objects in, if a fully qualified name is not given. - -The default creation location shouldn't be hardwired to equal the -front of the search path, because the front item of the search path -is probably always going to be a backend-local temporary schema -(this is where we'll create temporary tables). - -The most dumbed-down version of this that would work is to reduce the -search path to just a fixed list of three locations: temp schema, a -selectable default schema (which is also the default creation location), -and a system schema (where pg_class and friends live). But a -user-settable path wouldn't be any more effort to support, and might -offer some useful capability. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M17976=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 12:04:19 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0MH4IU12377 - for ; Tue, 22 Jan 2002 12:04:18 -0500 (EST) -Received: (qmail 20616 invoked by alias); 22 Jan 2002 17:04:13 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 17:04:13 -0000 -Received: from cygnus.com (runyon.sfbay.redhat.com [205.180.230.5] (may be forged)) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0MGiKl15781 - for ; Tue, 22 Jan 2002 11:44:20 -0500 (EST) - (envelope-from fnasser@redhat.com) -Received: from redhat.com (rtl.sfbay.redhat.com [205.180.230.21]) - by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id IAA14751; - Tue, 22 Jan 2002 08:44:15 -0800 (PST) -Message-ID: <3C4D96C5.80BBF764@redhat.com> -Date: Tue, 22 Jan 2002 11:43:49 -0500 -From: Fernando Nasser -Organization: Red Hat Canada -X-Mailer: Mozilla 4.78 [en] (X11; U; Linux 2.4.9-13 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Tom Lane -cc: Peter Eisentraut , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: <12239.1011661590@sss.pgh.pa.us> <3C4D8A39.FF79CDC4@redhat.com> <15339.1011716171@sss.pgh.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> -> > Quoting Date (pg. 221): "The schema authID for a given schema identifies -> > the owner of that schema (and hence the owner of everything described by -> > that schema also)." -> -> Yes, I know what the spec says. I also think we'll have a revolt on our -> hands if we don't make it possible for existing Postgres applications to -> continue working as they have in the past --- and that means allowing -> tables of different ownerships to be accessible in a single namespace. -> - -But them it is not SQL-Schemas. Call it something else, "packages" -for instance. The standard has lots of rules and other considerations -all around the document that depend on schemas have the meaning they -assigned to it. - -If someone wants to really make use of SQL-Schemas, he/she will need to -reorg the database anyway, which will probably mean dumping the data, -massaging the DLL and recreating it. I guess most users of SQL-Schemas -will be people creating new databases. - -For the current users, (based on your idea below) a default behavior of -searching the current-AuthID schema, them the "default" schema them -"any" -schema will probably make things work. - -Fernando - -P.S.: Note that the standard has no GRANTs for SCHEMAs themselves; all -GRANTS go to the specific objects as before. - - -> Although I haven't thought through the details yet, it seems to me that -> a solution exists along these lines: -> -> 1. The creator of an object owns it. (With some special cases, eg the -> superuser should be able to create a schema owned by someone else.) -> -> 2. Whether you can create an object in a schema that is owned by someone -> else depends on permissions attached to the schema. By default only -> the owner of a schema can create anything in it. -> -> 3. SQL92-compatible behavior is achieved when everyone has their own -> schema and they don't grant each other create-in-schema rights. -> Backwards-compatible behavior is achieved when everyone uses a -> shared "public" schema. -> -> We'd probably need GUC variable(s) to make it possible to choose which -> behavior is the default. I haven't thought much about exactly what -> knobs should be provided. I do think we will want at least these two -> knobs: -> -> 1. A "search path" that is an ordered list of schemas to look in -> when trying to resolve an unqualified name. -> -> 2. A "default schema" variable that identifies the schema to create -> objects in, if a fully qualified name is not given. -> -> The default creation location shouldn't be hardwired to equal the -> front of the search path, because the front item of the search path -> is probably always going to be a backend-local temporary schema -> (this is where we'll create temporary tables). -> -> The most dumbed-down version of this that would work is to reduce the -> search path to just a fixed list of three locations: temp schema, a -> selectable default schema (which is also the default creation location), -> and a system schema (where pg_class and friends live). But a -> user-settable path wouldn't be any more effort to support, and might -> offer some useful capability. -> -> regards, tom lane -> -> ---------------------------(end of broadcast)--------------------------- -> TIP 3: if posting/reading through Usenet, please send an appropriate -> subscribe-nomail command to majordomo@postgresql.org so that your -> message can get through to the mailing list cleanly - --- -Fernando Nasser -Red Hat Canada Ltd. E-Mail: fnasser@redhat.com -2323 Yonge Street, Suite #300 -Toronto, Ontario M4P 2C9 - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M17976=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 12:04:19 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0MH4IU12378 - for ; Tue, 22 Jan 2002 12:04:18 -0500 (EST) -Received: (qmail 20627 invoked by alias); 22 Jan 2002 17:04:13 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 17:04:13 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0MGpjl18339 - for ; Tue, 22 Jan 2002 11:51:45 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0MGpUf15641; - Tue, 22 Jan 2002 11:51:30 -0500 (EST) -To: Fernando Nasser -cc: Peter Eisentraut , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <3C4D96C5.80BBF764@redhat.com> -References: <12239.1011661590@sss.pgh.pa.us> <3C4D8A39.FF79CDC4@redhat.com> <15339.1011716171@sss.pgh.pa.us> <3C4D96C5.80BBF764@redhat.com> -Comments: In-reply-to Fernando Nasser - message dated "Tue, 22 Jan 2002 11:43:49 -0500" -Date: Tue, 22 Jan 2002 11:51:30 -0500 -Message-ID: <15638.1011718290@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Fernando Nasser writes: -> But them it is not SQL-Schemas. Call it something else, "packages" -> for instance. The standard has lots of rules and other considerations -> all around the document that depend on schemas have the meaning they -> assigned to it. - -Where? And are there any cases where it really matters? - -> If someone wants to really make use of SQL-Schemas, he/she will need to -> reorg the database anyway, which will probably mean dumping the data, -> massaging the DLL and recreating it. I guess most users of SQL-Schemas -> will be people creating new databases. - -No doubt. That still leaves us with the problem of providing -backward-compatible behavior in an engine that is going to be designed -to support schemas. I'm not sure what you think the implementation of -schemas is going to look like --- but I think it's not going to be -something that can be turned off or ignored. Every table is going to -belong to some schema, and the old behavior has to be available within -that framework. - -We are not working in a vacuum here, and that means that "implement -the specification and nothing but" is not a workable design approach. -We are going to end up with something that does the things SQL92 asks -for, but does other things too. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M17980=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 15:34:09 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0MKY7U05934 - for ; Tue, 22 Jan 2002 15:34:07 -0500 (EST) -Received: (qmail 77926 invoked by alias); 22 Jan 2002 20:33:26 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 20:33:26 -0000 -Received: from cygnus.com (runyon.sfbay.redhat.com [205.180.230.5] (may be forged)) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0MKUrl76871 - for ; Tue, 22 Jan 2002 15:30:54 -0500 (EST) - (envelope-from fnasser@redhat.com) -Received: from redhat.com (rtl.sfbay.redhat.com [205.180.230.21]) - by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id MAA09466; - Tue, 22 Jan 2002 12:30:46 -0800 (PST) -Message-ID: <3C4DCBDB.689D7201@redhat.com> -Date: Tue, 22 Jan 2002 15:30:20 -0500 -From: Fernando Nasser -Organization: Red Hat Canada -X-Mailer: Mozilla 4.78 [en] (X11; U; Linux 2.4.9-13 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Tom Lane -cc: Peter Eisentraut , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: <12239.1011661590@sss.pgh.pa.us> <3C4D8A39.FF79CDC4@redhat.com> <15339.1011716171@sss.pgh.pa.us> <3C4D96C5.80BBF764@redhat.com> <15638.1011718290@sss.pgh.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -OK, so the proposal is that we dissociate the ownership from the -namespace when we implement our version of SQL-Schemas, right? -This way an object will have both an owner and a schema (while in -the standard they are the same thing). - -The important is not much to accommodate someone who is creating -schemas (a new thing, so objects can be created the "right" way) -but rather to accommodate current code that does not use schemas -and have several owners for the objects (which would all fall -into a "default" schema). Can you agree with that? - -I was looking to see if we choose the proper defaults and search paths -and the "default" schema we could make it look for SQL-compliant code -as if it was a vanilla SQL-Schemas implementation. - -To support the current database schema definitions (without SQL-Schemas -and with different owners), things would be created with the current -user authorization id and will have its name defined in the "default" -SQL-Schema -namespace. Also, when referring to an object if the name is not -qualified -with the schema name, the search would go through the schema with the -current authorization id (as required by the std) and proceed to check -the "default" schema. - -The only problem in the scenario above is that the standard says that -when creating objects and not specifying the schema the schema name -should be assumed to be the current user authorization id (or whatever -authorization id the code is running as). In our case it would go to -the default schema. If someone wants the SQL std behavior then, he/she -must create things inside a CREATE SCHEMA statement or explicitly -qualify -with the schema name the objects being created. Can we live with that? -Will we pass the conformance tests? (I saw tests that test the schema -name -that is assumed when referencing but I do not recall seeing one that -tests -what is assumed on creation -- things I saw were all created inside -CREATE SCHEMA statements. Note, also, that passing the NIST tests -doesn't -make us compliant if we know that we are doing something different than -what is specified -- it just means that we got away with it :-) - - --- -Fernando Nasser -Red Hat Canada Ltd. E-Mail: fnasser@redhat.com -2323 Yonge Street, Suite #300 -Toronto, Ontario M4P 2C9 - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M17982=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 15:46:46 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0MKkhU07389 - for ; Tue, 22 Jan 2002 15:46:44 -0500 (EST) -Received: (qmail 82732 invoked by alias); 22 Jan 2002 20:43:40 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 20:43:40 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0MKg8l81714 - for ; Tue, 22 Jan 2002 15:42:08 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0MKfnf28202; - Tue, 22 Jan 2002 15:41:49 -0500 (EST) -To: Fernando Nasser -cc: Peter Eisentraut , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <3C4DCBDB.689D7201@redhat.com> -References: <12239.1011661590@sss.pgh.pa.us> <3C4D8A39.FF79CDC4@redhat.com> <15339.1011716171@sss.pgh.pa.us> <3C4D96C5.80BBF764@redhat.com> <15638.1011718290@sss.pgh.pa.us> <3C4DCBDB.689D7201@redhat.com> -Comments: In-reply-to Fernando Nasser - message dated "Tue, 22 Jan 2002 15:30:20 -0500" -Date: Tue, 22 Jan 2002 15:41:49 -0500 -Message-ID: <28199.1011732109@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Fernando Nasser writes: -> The only problem in the scenario above is that the standard says that -> when creating objects and not specifying the schema the schema name -> should be assumed to be the current user authorization id (or whatever -> authorization id the code is running as). In our case it would go to -> the default schema. If someone wants the SQL std behavior then, he/she -> must create things inside a CREATE SCHEMA statement or explicitly -> qualify -> with the schema name the objects being created. Can we live with -> that? - -Huh? You seem to be assuming that we need to support both the -historical Postgres behavior and the SQL-standard behavior with exactly -the same configuration switches. That's not how I'm seeing it at all. -The way I'm envisioning it, you could get either the historical -behavior, or the standard's behavior, depending on how you set up the -configuration variables. I don't see any particular reason to limit the -system to just those two cases, either, if the underlying implementation -has enough flexibility to support custom namespace configurations. - -I believe that we could get the historical behavior with something like - - schema search path = ("public" schema, system schema); - - default creation schema = "public" schema - -and the standard's behavior with something like - - schema search path = (user's own schema, system schema); - - default creation schema = user's own schema - -(ignoring the issue of a schema for temp tables for the moment). - -If you prefer to think of these things as "namespaces" rather than -"schemas", that's fine with me ... what we're talking about here -is an implementation that can support SQL-style schemas, but isn't -narrowly able to do only that. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M17985=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 16:15:56 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0MLFrU10671 - for ; Tue, 22 Jan 2002 16:15:53 -0500 (EST) -Received: (qmail 94223 invoked by alias); 22 Jan 2002 21:14:17 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 21:14:17 -0000 -Received: from cygnus.com (runyon.sfbay.redhat.com [205.180.230.5] (may be forged)) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0ML2fl90295 - for ; Tue, 22 Jan 2002 16:02:41 -0500 (EST) - (envelope-from fnasser@redhat.com) -Received: from redhat.com (rtl.sfbay.redhat.com [205.180.230.21]) - by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id NAA12269; - Tue, 22 Jan 2002 13:02:34 -0800 (PST) -Message-ID: <3C4DD34F.CC4D8B6@redhat.com> -Date: Tue, 22 Jan 2002 16:02:07 -0500 -From: Fernando Nasser -Organization: Red Hat Canada -X-Mailer: Mozilla 4.78 [en] (X11; U; Linux 2.4.9-13 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Tom Lane -cc: Peter Eisentraut , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: <12239.1011661590@sss.pgh.pa.us> <3C4D8A39.FF79CDC4@redhat.com> <15339.1011716171@sss.pgh.pa.us> <3C4D96C5.80BBF764@redhat.com> <15638.1011718290@sss.pgh.pa.us> <3C4DCBDB.689D7201@redhat.com> <28199.1011732109@sss.pgh.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> -> Huh? You seem to be assuming that we need to support both the -> historical Postgres behavior and the SQL-standard behavior with exactly -> the same configuration switches. That's not how I'm seeing it at all. -> The way I'm envisioning it, you could get either the historical -> behavior, or the standard's behavior, depending on how you set up the -> configuration variables. - -Then we can live just with the schema being the ownership. - -Switches set to standard: - - schema search path = ("user's own schema", postgres) - - [ default creation schema = user's own schema ] same as below, - we don't need this -switch - -Switches set to historical: - - schema search path = (user's own schema, "any" schema, postgres) - - [ default creation schema = user's own schema ] - -The searching in "any" schema (i.e., any owner) will let will find -things that where defined the way they are today, i.e., possibly -by several different users. - - -P.S.: You can even add the "default" schema in the standard case and -I believe you are still compliant and can handle things easier: - schema search path = ("user's own schema", postgres) - - -Maybe you could give an example of a case where the schema meaning -ownership breaks things. Or what kind of additional things you have -in mind that would require orthogonal schema and ownership spaces. - - -Regards, -Fernando - - - - --- -Fernando Nasser -Red Hat Canada Ltd. E-Mail: fnasser@redhat.com -2323 Yonge Street, Suite #300 -Toronto, Ontario M4P 2C9 - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M17986=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 16:23:41 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0MLNbU11596 - for ; Tue, 22 Jan 2002 16:23:38 -0500 (EST) -Received: (qmail 703 invoked by alias); 22 Jan 2002 21:23:31 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 21:23:31 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0MLEYl94662 - for ; Tue, 22 Jan 2002 16:14:34 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0MLEGf28560; - Tue, 22 Jan 2002 16:14:17 -0500 (EST) -To: Fernando Nasser -cc: Peter Eisentraut , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <3C4DD34F.CC4D8B6@redhat.com> -References: <12239.1011661590@sss.pgh.pa.us> <3C4D8A39.FF79CDC4@redhat.com> <15339.1011716171@sss.pgh.pa.us> <3C4D96C5.80BBF764@redhat.com> <15638.1011718290@sss.pgh.pa.us> <3C4DCBDB.689D7201@redhat.com> <28199.1011732109@sss.pgh.pa.us> <3C4DD34F.CC4D8B6@redhat.com> -Comments: In-reply-to Fernando Nasser - message dated "Tue, 22 Jan 2002 16:02:07 -0500" -Date: Tue, 22 Jan 2002 16:14:16 -0500 -Message-ID: <28557.1011734056@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Fernando Nasser writes: -> Switches set to historical: - -> schema search path = (user's own schema, "any" schema, postgres) - -> [ default creation schema = user's own schema ] - -> The searching in "any" schema (i.e., any owner) will let will find -> things that where defined the way they are today, i.e., possibly -> by several different users. - -No, it won't, because nothing will ever get put into that schema. -(At least not by existing pg_dump scripts, which are the things that -really need to see the historical behavior.) The -default-creation-schema variable has got to point at any/public/ -whatever-we-call it, or you do not have the historical behavior. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M17988=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 16:44:43 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0MLifU13572 - for ; Tue, 22 Jan 2002 16:44:41 -0500 (EST) -Received: (qmail 8653 invoked by alias); 22 Jan 2002 21:43:27 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 21:43:27 -0000 -Received: from cygnus.com (runyon.sfbay.redhat.com [205.180.230.5] (may be forged)) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0MLR6l02610 - for ; Tue, 22 Jan 2002 16:27:06 -0500 (EST) - (envelope-from fnasser@redhat.com) -Received: from redhat.com (rtl.sfbay.redhat.com [205.180.230.21]) - by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id NAA14337; - Tue, 22 Jan 2002 13:27:00 -0800 (PST) -Message-ID: <3C4DD909.F26FD0D1@redhat.com> -Date: Tue, 22 Jan 2002 16:26:33 -0500 -From: Fernando Nasser -Organization: Red Hat Canada -X-Mailer: Mozilla 4.78 [en] (X11; U; Linux 2.4.9-13 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Tom Lane -cc: Peter Eisentraut , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: <12239.1011661590@sss.pgh.pa.us> <3C4D8A39.FF79CDC4@redhat.com> <15339.1011716171@sss.pgh.pa.us> <3C4D96C5.80BBF764@redhat.com> <15638.1011718290@sss.pgh.pa.us> <3C4DCBDB.689D7201@redhat.com> <28199.1011732109@sss.pgh.pa.us> <3C4DD34F.CC4D8B6@redhat.com> <28557.1011734056@sss.pgh.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> -> Fernando Nasser writes: -> > Switches set to historical: -> -> > schema search path = (user's own schema, "any" schema, postgres) -> -> > [ default creation schema = user's own schema ] -> -> > The searching in "any" schema (i.e., any owner) will let will find -> > things that where defined the way they are today, i.e., possibly -> > by several different users. -> -> No, it won't, because nothing will ever get put into that schema. -> (At least not by existing pg_dump scripts, which are the things that -> really need to see the historical behavior.) The -> default-creation-schema variable has got to point at any/public/ -> whatever-we-call it, or you do not have the historical behavior. -> - -You did not understand what I meant by "any". It is not a schema -called "any". It is _any_ schema. - -Example: - -A creates a table (do not specify the schema) so it gets into -the schema named A (as per standard). - -B refers to the table without qualifying it... - -In the standard case: look into schema B (=> not found), not in -postgres either. -ERROR: Inv. relation As the standard requires. - -In the historical mode: look into schema B (=> not found), look into -ANY -schema (finds it in A). Works as it is today. - - -Note that I only suggest looking in B first (in the historical case) -because -this will allow for the coexistence of the current mode with a -quasi-compliant -use of SQL-Schemas. You only need to change the switch if you want -strict -compliance. - - - --- -Fernando Nasser -Red Hat Canada Ltd. E-Mail: fnasser@redhat.com -2323 Yonge Street, Suite #300 -Toronto, Ontario M4P 2C9 - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M17987=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 16:45:30 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0MLjSU13642 - for ; Tue, 22 Jan 2002 16:45:29 -0500 (EST) -Received: (qmail 8533 invoked by alias); 22 Jan 2002 21:43:23 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 21:43:23 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0MLZ5l06911 - for ; Tue, 22 Jan 2002 16:35:05 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0MLYlf28790; - Tue, 22 Jan 2002 16:34:47 -0500 (EST) -To: Fernando Nasser -cc: Peter Eisentraut , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <3C4DD909.F26FD0D1@redhat.com> -References: <12239.1011661590@sss.pgh.pa.us> <3C4D8A39.FF79CDC4@redhat.com> <15339.1011716171@sss.pgh.pa.us> <3C4D96C5.80BBF764@redhat.com> <15638.1011718290@sss.pgh.pa.us> <3C4DCBDB.689D7201@redhat.com> <28199.1011732109@sss.pgh.pa.us> <3C4DD34F.CC4D8B6@redhat.com> <28557.1011734056@sss.pgh.pa.us> <3C4DD909.F26FD0D1@redhat.com> -Comments: In-reply-to Fernando Nasser - message dated "Tue, 22 Jan 2002 16:26:33 -0500" -Date: Tue, 22 Jan 2002 16:34:47 -0500 -Message-ID: <28787.1011735287@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Fernando Nasser writes: -> In the historical mode: look into schema B (=> not found), look into -> ANY schema (finds it in A). Works as it is today. - -No, it doesn't work the same as today, because in that implementation -both A and B can create the same tablename without complaint. It then -becomes very unclear which instance other people will get (unless your -"any" placeholder somehow implies a search order). - -The idea of being able to put an "any" placeholder into the search list -is an interesting one, though. If we can resolve the ambiguity problem -it might be a useful feature. - -I am a little troubled by the idea of placing "any" before the system -schema (what if JRandomLuser creates a table named "pg_class"?) but it -might be workable at the tail end of the path. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M17991=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 17:13:49 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0MMDmU19678 - for ; Tue, 22 Jan 2002 17:13:49 -0500 (EST) -Received: (qmail 19170 invoked by alias); 22 Jan 2002 22:13:14 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 22:13:14 -0000 -Received: from cygnus.com (runyon.sfbay.redhat.com [205.180.230.5] (may be forged)) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0MM3ql17554 - for ; Tue, 22 Jan 2002 17:03:53 -0500 (EST) - (envelope-from fnasser@redhat.com) -Received: from redhat.com (rtl.sfbay.redhat.com [205.180.230.21]) - by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id OAA18084; - Tue, 22 Jan 2002 14:03:46 -0800 (PST) -Message-ID: <3C4DE1A7.98860E96@redhat.com> -Date: Tue, 22 Jan 2002 17:03:19 -0500 -From: Fernando Nasser -Organization: Red Hat Canada -X-Mailer: Mozilla 4.78 [en] (X11; U; Linux 2.4.9-13 i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Tom Lane -cc: Peter Eisentraut , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: <12239.1011661590@sss.pgh.pa.us> <3C4D8A39.FF79CDC4@redhat.com> <15339.1011716171@sss.pgh.pa.us> <3C4D96C5.80BBF764@redhat.com> <15638.1011718290@sss.pgh.pa.us> <3C4DCBDB.689D7201@redhat.com> <28199.1011732109@sss.pgh.pa.us> <3C4DD34F.CC4D8B6@redhat.com> <28557.1011734056@sss.pgh.pa.us> <3C4DD909.F26FD0D1@redhat.com> <28787.1011735287@sss.pgh.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> -> Fernando Nasser writes: -> > In the historical mode: look into schema B (=> not found), look into -> > ANY schema (finds it in A). Works as it is today. -> -> No, it doesn't work the same as today, because in that implementation -> both A and B can create the same tablename without complaint. - -I agree that we won't be able to catch this as an error unless we turn -another switch that requires unique names (there goes one of the -advantages -of having schemas, but there is always the option of leaving it on). - -In this case it would be more close to the current behavior but what is -left of the SQL-Schemas will be more of a syntactic sugar (although it -can -be still used by the DBA to better organize the grant of privileges). - -Anyway, it would be a DBA option to live with not detecting duplicate -names. And, I hope all our tools, graphical or not, will make it clear -what -is the schema things are defined into, so it would not be difficult to -figure out what is going wrong if something goes wrong (and we can also -print the relation oid on messages). - -> It then -> becomes very unclear which instance other people will get (unless your -> "any" placeholder somehow implies a search order). -> - -If someone is just using the current mode, there shouldn't be (all names -are -database-unique). - -The only case where this situation can happen is if someone is trying -to use schemas and the historical non-schema organization in the same -database, right? Can we make the search order per database?) - -One possibility is to state that this is not recommended (one should -organize things as schemas or not at all in a database) and say that -the search order, besides the current AuthId, is unspecified (random). - -Another possibility is to allow only one object with that name in the -"any" space. If someone means an object that was defined on a schema, -he/she can qualify the name with the schema (good practice). The only -case where this is not possible is the legacy case, where there is -exactly one object with that name anyway. - -I prefer this second solution. - -> The idea of being able to put an "any" placeholder into the search list -> is an interesting one, though. If we can resolve the ambiguity problem -> it might be a useful feature. -> - -See above. - -> I am a little troubled by the idea of placing "any" before the system -> schema (what if JRandomLuser creates a table named "pg_class"?) but it -> might be workable at the tail end of the path. -> - -Yes, I thought of that as I was typing, but it was not the important -point at that time. You're right, should go at the end. - --- -Fernando Nasser -Red Hat Canada Ltd. E-Mail: fnasser@redhat.com -2323 Yonge Street, Suite #300 -Toronto, Ontario M4P 2C9 - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M17993=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 18:44:53 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0MNiqU29215 - for ; Tue, 22 Jan 2002 18:44:53 -0500 (EST) -Received: (qmail 36986 invoked by alias); 22 Jan 2002 23:43:31 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 23:43:31 -0000 -Received: from student.gvsu.edu ([148.61.7.124]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0MNGYl30543 - for ; Tue, 22 Jan 2002 18:16:34 -0500 (EST) - (envelope-from peter_e@gmx.net) -Received: from [148.61.250.147] [148.61.250.147] by student.gvsu.edu - with Novonyx SMTP Server $Revision: 1.3 $; Tue, 22 Jan 2002 18:16:37 -0500 (EDT) -Date: Tue, 22 Jan 2002 18:18:38 -0500 (EST) -From: Peter Eisentraut -X-Sender: -To: Tom Lane -cc: -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <12239.1011661590@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane writes: - -> I don't buy that premise. It's true that SQL92 equates ownership of a -> schema with ownership of the objects therein, but AFAICS we have no hope -> of being forward-compatible with existing database setups (wherein there -> can be multiple tables of different ownership all in a single namespace) -> if we don't allow varying ownership within a schema. - -We could have a Boolean knob that says "if you don't find the object in -the default schema, search all other schemas". That should provide all -the backward compatibility we need. Moreover, I figure if we do it that -way, the whole schema implementation reduces itself mostly to parser work, -no complicated system catalog changes, no complex overhaul of the -privilege system -- at least initially. - --- -Peter Eisentraut peter_e@gmx.net - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M17992=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 18:34:48 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0MNYmU28419 - for ; Tue, 22 Jan 2002 18:34:48 -0500 (EST) -Received: (qmail 32848 invoked by alias); 22 Jan 2002 23:34:10 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 23:34:10 -0000 -Received: from student.gvsu.edu ([148.61.7.124]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0MNPUl31485 - for ; Tue, 22 Jan 2002 18:25:30 -0500 (EST) - (envelope-from peter_e@gmx.net) -Received: from [148.61.250.147] [148.61.250.147] by student.gvsu.edu - with Novonyx SMTP Server $Revision: 1.3 $; Tue, 22 Jan 2002 18:25:33 -0500 (EDT) -Date: Tue, 22 Jan 2002 18:27:35 -0500 (EST) -From: Peter Eisentraut -X-Sender: -To: Tom Lane -cc: Fernando Nasser , -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <28787.1011735287@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane writes: - -> No, it doesn't work the same as today, because in that implementation -> both A and B can create the same tablename without complaint. It then -> becomes very unclear which instance other people will get (unless your -> "any" placeholder somehow implies a search order). - -The "search any schema" switch is only intended for use with legacy -databases, where duplicate names don't occur anyway. If someone uses it -with a new schema-using database design, then he kind of ought to know -that the switch probably doesn't make a whole lot of sense. However, to -get reproduceable behaviour anyway we can just define a search order, such -as by schema name. - --- -Peter Eisentraut peter_e@gmx.net - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M17994=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 18:45:53 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0MNjqU29324 - for ; Tue, 22 Jan 2002 18:45:52 -0500 (EST) -Received: (qmail 37021 invoked by alias); 22 Jan 2002 23:43:34 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 22 Jan 2002 23:43:34 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0MNVOl31958 - for ; Tue, 22 Jan 2002 18:31:24 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0MNV8f29291; - Tue, 22 Jan 2002 18:31:08 -0500 (EST) -To: Peter Eisentraut -cc: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -References: -Comments: In-reply-to Peter Eisentraut - message dated "Tue, 22 Jan 2002 18:18:38 -0500" -Date: Tue, 22 Jan 2002 18:31:08 -0500 -Message-ID: <29288.1011742268@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Peter Eisentraut writes: -> Moreover, I figure if we do it that -> way, the whole schema implementation reduces itself mostly to parser work, -> no complicated system catalog changes, no complex overhaul of the -> privilege system -- at least initially. - -Why are you guys so eager to save me work? I'm not in the least -interested in implementing a "schema" feature that can only handle -the entry-level user == schema case. Therefore, just relabeling the -owner column as schema isn't an interesting option. - -I really don't see what's wrong with building a namespace mechanism -that is orthogonal to ownership and then using that to implement what -SQL92 wants. I think this will be cleaner, simpler, and more flexible -than trying to equate ownership with namespace. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M17997=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 19:13:42 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0N0DgU01512 - for ; Tue, 22 Jan 2002 19:13:42 -0500 (EST) -Received: (qmail 46269 invoked by alias); 23 Jan 2002 00:13:11 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 00:13:11 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0N02bl42634 - for ; Tue, 22 Jan 2002 19:02:37 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0N02Kf29439; - Tue, 22 Jan 2002 19:02:21 -0500 (EST) -To: Peter Eisentraut -cc: Fernando Nasser , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -References: -Comments: In-reply-to Peter Eisentraut - message dated "Tue, 22 Jan 2002 18:27:35 -0500" -Date: Tue, 22 Jan 2002 19:02:20 -0500 -Message-ID: <29436.1011744140@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Peter Eisentraut writes: -> Tom Lane writes: ->> No, it doesn't work the same as today, because in that implementation ->> both A and B can create the same tablename without complaint. It then ->> becomes very unclear which instance other people will get (unless your ->> "any" placeholder somehow implies a search order). - -> The "search any schema" switch is only intended for use with legacy -> databases, where duplicate names don't occur anyway. - -That's a mighty narrow view of the world. Do you think that people had -better convert to SQL schemas before they ever again create a table? -The fact is that ordinary non-schema-aware usage will certainly lead to -the above scenario. - -> that the switch probably doesn't make a whole lot of sense. However, to -> get reproduceable behaviour anyway we can just define a search order, such -> as by schema name. - -Or say that you get an "ambiguous reference" error if there is more than -one possible candidate in the "any" namespace. (Although that opens the -door for innocent creation of a table foo by one user to break other -people's formerly-working queries that reference some other foo.) -Bottom line for me is that this is an untried concept. I think the -concept of an "any" searchlist entry is risky enough that I don't much -want to hang the entire usability of the implementation on the -assumption that we won't find any fatal problems with "any". - - -However, the argument over whether SQL92's concept of ownership should -be taken as gospel is not really the argument I wanted to have in this -thread. Is it possible to go back to the original point concerning -whether there should be different namespace boundaries for different -types of objects? You aren't going to avoid those issues by saying that -namespace == ownership is good enough. - -I'm particularly troubled by the idea of trying to apply this "any" -lookup concept to resolution of overloaded operators and functions. -Suppose I have a reference func(type1,type2) that I'm trying to resolve, -and I have an inexact match (one requiring coercion) in my own schema. -Do I look to the "any" schema to see if there are better matches? -If so, what happens if the "any" schema contains multiple possibilities -with identical signatures (presumably created by different users)? ISTM -this will positively guarantee a resolution failure, since there's no -way for the resolver to prefer one over another. Thus, by creating -a "func(foo,bar)" function --- quite legally --- JRandomLuser might -break other people's formerly working queries that use other functions -named func. Although it's possible for this to happen now, it'll be -a lot more surprising if JRandomLuser thinks that his functions live -in his own private schema namespace. - -I'm thinking that the overloading concept is not going to play well -at all with multiple namespaces for functions or operators, and that -we'd be best off to say that there is only one namespace (per database) -for these things. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M17998=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 19:33:10 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0N0X9U02302 - for ; Tue, 22 Jan 2002 19:33:09 -0500 (EST) -Received: (qmail 52787 invoked by alias); 23 Jan 2002 00:33:08 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 00:33:08 -0000 -Received: from ece.rice.edu (ece.rice.edu [128.42.4.34]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0N0IEl49263 - for ; Tue, 22 Jan 2002 19:18:14 -0500 (EST) - (envelope-from reedstrm@rice.edu) -Received: from localhost (localhost [127.0.0.1]) - by ece.rice.edu (Postfix) with ESMTP - id A57FF68A57; Tue, 22 Jan 2002 18:18:14 -0600 (CST) -Received: from wallace.ece.rice.edu (wallace.ece.rice.edu [128.42.12.154]) - by ece.rice.edu (Postfix) with ESMTP - id 393F168A1D; Tue, 22 Jan 2002 18:18:13 -0600 (CST) -Received: from reedstrm by wallace.ece.rice.edu with local (Exim 3.22 #1 (Debian)) - id 16TB7F-000292-00; Tue, 22 Jan 2002 18:18:13 -0600 -Date: Tue, 22 Jan 2002 18:18:13 -0600 -From: "Ross J. Reedstrom" -To: Tom Lane -cc: Peter Eisentraut , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -Message-ID: <20020123001812.GB7932@rice.edu> -Mail-Followup-To: "Ross J. Reedstrom" , - Tom Lane , Peter Eisentraut , - pgsql-hackers@postgresql.org -References: <29288.1011742268@sss.pgh.pa.us> -MIME-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -Content-Disposition: inline -In-Reply-To: <29288.1011742268@sss.pgh.pa.us> -User-Agent: Mutt/1.3.25i -X-Virus-Scanned: by AMaViS snapshot-20010714 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Tue, Jan 22, 2002 at 06:31:08PM -0500, Tom Lane wrote: -> Peter Eisentraut writes: -> > Moreover, I figure if we do it that -> > way, the whole schema implementation reduces itself mostly to parser work, -> > no complicated system catalog changes, no complex overhaul of the -> > privilege system -- at least initially. -> -> Why are you guys so eager to save me work? I'm not in the least -> interested in implementing a "schema" feature that can only handle -> the entry-level user == schema case. Therefore, just relabeling the -> owner column as schema isn't an interesting option. -> -> I really don't see what's wrong with building a namespace mechanism -> that is orthogonal to ownership and then using that to implement what -> SQL92 wants. I think this will be cleaner, simpler, and more flexible -> than trying to equate ownership with namespace. -> - -I'm with Tom on this: the extended Schema capability he's described -combines the best of both authentication mechanisms, IMHO. It give -us namespace separation ala the SQL standard, and individual object -ownership, like unix FS semantics. Only having ownership on the -'containers' strikes me as limiting, even if that is how the standard -describes it. - -Ross - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18002=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 20:33:04 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0N1X3U05117 - for ; Tue, 22 Jan 2002 20:33:03 -0500 (EST) -Received: (qmail 73320 invoked by alias); 23 Jan 2002 01:32:55 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 01:32:55 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0N1FDl69103 - for ; Tue, 22 Jan 2002 20:15:14 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 12961 invoked by uid 1130); 23 Jan 2002 01:15:07 -0000 -Date: Tue, 22 Jan 2002 17:10:24 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Tom Lane -cc: -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <11381.1011648592@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Mon, 21 Jan 2002, Tom Lane wrote: - -> Continuing to think about implementing SQL schemas for 7.3 ... -> -> Today's topic for discussion: which types of Postgres objects should -> belong to schemas, and which ones should have other name scopes? -> -> Relations (tables, indexes, views, sequences) clearly belong to schemas. -> Since each relation has an associated datatype with the same name, it -> seems that datatypes must belong to schemas as well. (Even if that -> argument doesn't convince you, SQL99 says that user-defined datatypes -> belong to schemas.) However the situation is murkier for other kinds of -> objects. -> -> Here are all the kinds of named objects that exist in Postgres today, -> with some comments on whether they should belong to schemas or not: -> -> relations Must be in schemas -> types Must be in schemas -> databases Databases contain schemas, not vice versa -> users Users are cross-database, so not in schemas -> groups User groups are cross-database, so not in schemas -> languages Probably should not be in schemas -> access methods Probably should not be in schemas -> opclasses See below -> operators See below -> functions/procedures See below -> aggregates Should treat same as regular functions -> constraints See below -> rules See below -> triggers See below -> NOTIFY conditions See below -> -> Languages and access methods are not trivial to add to the system, so -> there's not much risk of name conflicts, and no reason to make their name -> scope less than global. -> -> The situation is a lot murkier for operators and functions. These should -> probably be treated alike, since operators are just syntactic sugar for -> functions. I think the basic argument for making them schema-local is -> that different users might conceivably want to define conflicting -> functions or operators of the same name. Against that, however, there -> are a number of reasons for wanting to keep these objects database-wide. -> First off there are syntactic problems. Do you really want to write -> A schemaname.+ B -> to qualify an ambiguous "+" operator? Looks way too much like a syntax -> error to me. Allowing this would probably turn a lot of simple syntax -> errors into things that get past the grammar and end up producing truly -> confusing error messages. Qualified function names also pose some -> problems, not so much with -> schemaname.function(args) -> which seems reasonable, but with the Berkeley-derived syntax that allows -> "foo.function" to mean "function(foo)" --- there's no way to squeeze a -> schema-name for the function into that. (And you'll recall from my note - -Why not? What's wrong with either schema.foo.function (==> -function(schema.foo)) or foo.schema.function (==> schema.function(foo))? -Tables and functions can't have the same names as schemas, so we will be -able to notice the schema names in there. Oh, and I worked out how to get -parse.y to be happy with x.y & x.y.z (schema.package.function) names. :-) - -> of the other day that we don't want to abandon this syntax entirely, -> because people would like us to support "sequencename.nextval" for Oracle -> compatibility.) Notice that we are not forced to make functions/operators -> schema-local just because datatypes are, because overloading will save the -> day. func(schema1.type1) and func(schema2.type1) are distinct functions -> because the types are different, even if they live in the same function -> namespace. Finally, SQL99 doesn't appear to think that operator and -> function names are schema-local; though that may just be because it hasn't -> got user-defined operators AFAICT. - -Actually functions do have to be schema local. It's in the spec (don't -have exactly where with me). - -> I am leaning towards keeping functions/operators database-wide, but would -> like to hear comments. Is there any real value in, eg, allowing different -> users to define different "+" operators *on the same datatypes*? - -Yes. It means that third-party developers can develop routines and then -operators based on them without having to worry about conflicts. Obviously -these two different operators would have to be in different schemas. Also, -it would mean that someone could ship replacement operators for built-in -operators. Say adding a + operator which throws exceptions on overflow. -:-) - -> Not sure about index opclasses. Given that datatype names are -> schema-local, one can think of scenarios where two users define similar -> datatypes and then try to use the same index opclass name for both. -> But it seems pretty unlikely. I'd prefer to leave opclass names -> database-wide for simplicity. Comments? - -My vote would be to make them schema-specific. As Peter pointed out, -schemas are how you own things, so put them in a schema so we can keep -track of ownership. - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M18001=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 20:23:11 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0N1NAU04735 - for ; Tue, 22 Jan 2002 20:23:10 -0500 (EST) -Received: (qmail 70414 invoked by alias); 23 Jan 2002 01:23:01 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 01:23:01 -0000 -Received: from corvette.mascari.com (dhcp065-024-158-068.columbus.rr.com [65.24.158.68]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0N1KBl69469 - for ; Tue, 22 Jan 2002 20:20:11 -0500 (EST) - (envelope-from mascarm@mascari.com) -Received: from mascari.com (ferrari.mascari.com [192.168.2.1]) - by corvette.mascari.com (8.9.3/8.9.3) with ESMTP id UAA30752 - for ; Tue, 22 Jan 2002 20:15:29 -0500 -Message-ID: <3C4E0EB1.1E3687FD@mascari.com> -Date: Tue, 22 Jan 2002 20:15:29 -0500 -From: Mike Mascari -X-Mailer: Mozilla 4.7 [en] (WinNT; I) -X-Accept-Language: en -MIME-Version: 1.0 -To: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: <29436.1011744140@sss.pgh.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> -> I'm particularly troubled by the idea of trying to apply this "any" -> lookup concept to resolution of overloaded operators and functions. -> Suppose I have a reference func(type1,type2) that I'm trying to resolve, -> and I have an inexact match (one requiring coercion) in my own schema. -> Do I look to the "any" schema to see if there are better matches? -> If so, what happens if the "any" schema contains multiple possibilities -> with identical signatures (presumably created by different users)? ISTM -> this will positively guarantee a resolution failure, since there's no -> way for the resolver to prefer one over another. Thus, by creating -> a "func(foo,bar)" function --- quite legally --- JRandomLuser might -> break other people's formerly working queries that use other functions -> named func. Although it's possible for this to happen now, it'll be -> a lot more surprising if JRandomLuser thinks that his functions live -> in his own private schema namespace. -> - -So, in a nutshell, the price we pay for function overloading is the -inability to have schema-specific functions. Right? Possibly why Oracle -doesn't allow function overloading? As a user, I'd much rather have -schema-specific functions than only global. I'm not downplaying the -value of function overloading, but if I had the choice (which I guess I -can't/won't), I'd choose schema-specific functions over function -overloading... - -Mike Mascari -mascarm@mascari.com - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18003=candle.pha.pa.us=pgman@postgresql.org Tue Jan 22 20:52:52 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0N1qqU05847 - for ; Tue, 22 Jan 2002 20:52:52 -0500 (EST) -Received: (qmail 76088 invoked by alias); 23 Jan 2002 01:52:50 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 01:52:50 -0000 -Received: from student.gvsu.edu ([148.61.7.124]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0N1o8l75594 - for ; Tue, 22 Jan 2002 20:50:08 -0500 (EST) - (envelope-from peter_e@gmx.net) -Received: from [148.61.250.147] [148.61.250.147] by student.gvsu.edu - with Novonyx SMTP Server $Revision: 1.3 $; Tue, 22 Jan 2002 20:50:13 -0500 (EDT) -Date: Tue, 22 Jan 2002 20:52:14 -0500 (EST) -From: Peter Eisentraut -X-Sender: -To: Tom Lane -cc: -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <29288.1011742268@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane writes: - -> I really don't see what's wrong with building a namespace mechanism -> that is orthogonal to ownership and then using that to implement what -> SQL92 wants. I think this will be cleaner, simpler, and more flexible -> than trying to equate ownership with namespace. - -OK, I can accept that. But then I want to get back at my original point, -namely that all database objects (except users and groups) should be in -schemas. This is also cleaner, simpler, and more flexible. There is -clearly demand for schema-local functions. So I think that designing this -system from the premise that a schema-qualified operator call will look -strange is the wrong end to start at. - --- -Peter Eisentraut peter_e@gmx.net - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18006=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 00:13:21 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0N5DLU26660 - for ; Wed, 23 Jan 2002 00:13:21 -0500 (EST) -Received: (qmail 12536 invoked by alias); 23 Jan 2002 05:13:01 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 05:13:01 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0N58Cl11241 - for ; Wed, 23 Jan 2002 00:08:12 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0N57vf00651; - Wed, 23 Jan 2002 00:07:58 -0500 (EST) -To: Bill Studenmund -cc: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -References: -Comments: In-reply-to Bill Studenmund - message dated "Tue, 22 Jan 2002 17:10:24 -0800" -Date: Wed, 23 Jan 2002 00:07:57 -0500 -Message-ID: <648.1011762477@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Bill Studenmund writes: -> Why not? What's wrong with either schema.foo.function (==> -> function(schema.foo)) or foo.schema.function (==> schema.function(foo))? - -Neither is wrong in isolation, but how do you tell the difference? -More to the point, given input x.y.z, how do you tell which component -is what? - -> Tables and functions can't have the same names as schemas, - -News to me. Where is that written on stone tablets? Even if that's -considered an acceptable limitation from a purely functional point of -view, I don't like using it to disambiguate input. The error messages -you'll get from incorrect input to an implementation that depends on -that to disambiguate cases will not be very helpful. - -> Actually functions do have to be schema local. It's in the spec (don't -> have exactly where with me). - -(A) I don't believe that; please cite chapter and verse; (B) even if -SQL92 thinks that's okay, we can't do it that way because of -backwards-compatibility issues. - -> My vote would be to make them schema-specific. As Peter pointed out, -> schemas are how you own things, - -Sorry, but this line of argument is trying to assume the very point in -dispute. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M18007=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 01:12:58 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0N6CvU01868 - for ; Wed, 23 Jan 2002 01:12:57 -0500 (EST) -Received: (qmail 21084 invoked by alias); 23 Jan 2002 06:13:00 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 06:13:00 -0000 -Received: from student.gvsu.edu ([148.61.7.124]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0N69Kl20384 - for ; Wed, 23 Jan 2002 01:09:20 -0500 (EST) - (envelope-from peter_e@gmx.net) -Received: from [148.61.250.147] [148.61.250.147] by student.gvsu.edu - with Novonyx SMTP Server $Revision: 1.3 $; Wed, 23 Jan 2002 01:09:18 -0500 (EDT) -Date: Wed, 23 Jan 2002 01:11:21 -0500 (EST) -From: Peter Eisentraut -X-Sender: -To: Tom Lane -cc: Bill Studenmund , -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <648.1011762477@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane writes: - -> > Actually functions do have to be schema local. It's in the spec (don't -> > have exactly where with me). -> -> (A) I don't believe that; please cite chapter and verse; - -In SQL99, chapter 4 verse 23 it says - -"An SQL-invoked routine is an element of an SQL-schema and is called a -schema-level routine." - -> (B) even if -> SQL92 thinks that's okay, we can't do it that way because of -> backwards-compatibility issues. - -I don't buy that. If all you're looking for is preserving - -foo.bar <==> bar(foo) - -for compatibility, then you can simply say that "bar" cannot be -schema-qualified in the left form (so it needs to live in the current or -the default schema). We currently only have one default schema, so that's -backward compatible. I think this syntax is a mistake, so I don't feel -compelled to provide more than backwards compatibility. - --- -Peter Eisentraut peter_e@gmx.net - - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M18008=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 04:13:30 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0N9DTU17316 - for ; Wed, 23 Jan 2002 04:13:29 -0500 (EST) -Received: (qmail 56495 invoked by alias); 23 Jan 2002 09:13:26 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 09:13:26 -0000 -Received: from smxsat1.smxs.net (smxsat1.smxs.net [213.150.10.1]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0N9BKl55718 - for ; Wed, 23 Jan 2002 04:11:21 -0500 (EST) - (envelope-from ZeugswetterA@spardat.at) -Received: from m01x1.s-mxs.net [10.3.55.201] - by smxsat1.smxs.net - with XWall v3.18f ; - Wed, 23 Jan 2002 10:12:42 +0100 -Received: from m0102.s-mxs.net [10.3.55.2] - by m01x1.s-mxs.net - with XWall v3.18a ; - Wed, 23 Jan 2002 10:11:14 +0100 -Received: from m0114.s-mxs.net ([10.3.55.14]) by m0102.s-mxs.net with Microsoft SMTPSVC(5.0.2195.2966); - Wed, 23 Jan 2002 10:11:13 +0100 -X-MimeOLE: Produced By Microsoft Exchange V6.0.5762.3 -content-class: urn:content-classes:message -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -Date: Wed, 23 Jan 2002 10:11:13 +0100 -Message-ID: <46C15C39FEB2C44BA555E356FBCD6FA41EB4C2@m0114.s-mxs.net> -Thread-Topic: [HACKERS] RFD: schemas and different kinds of Postgres objects -Thread-Index: AcGjixqphLJq/YpTSK6U7FZuNf4j3AAWxJvQ -From: "Zeugswetter Andreas SB SD" -To: "Tom Lane" , "Fernando Nasser" -cc: "Peter Eisentraut" , -X-OriginalArrivalTime: 23 Jan 2002 09:11:13.0579 (UTC) FILETIME=[E7DEA7B0:01C1A3ED] -Content-Transfer-Encoding: 8bit -X-MIME-Autoconverted: from quoted-printable to 8bit by postgresql.org id g0N9CTm55809 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -> > Switches set to historical: -> -> > schema search path = (user's own schema, "any" schema, postgres) -> -> > [ default creation schema = user's own schema ] -> -> > The searching in "any" schema (i.e., any owner) will let will find -> > things that where defined the way they are today, i.e., possibly -> > by several different users. -> -> No, it won't, because nothing will ever get put into that schema. -> (At least not by existing pg_dump scripts, which are the things that -> really need to see the historical behavior.) The -> default-creation-schema variable has got to point at any/public/ -> whatever-we-call it, or you do not have the historical behavior. - -When configured for historical behavior would need to: -1. have search path: temp, any, system -2. guard against duplicate table names across all schemas (except temp schema) - -Or are you thinking about a per session behavior ? -I would rather envision a per database behavior. - -Maybe the easy way out would be a "default creation schema" property for -each user, that would default to the username. If you want everything in one -schema simply alter the users. - -Andreas - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M18010=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 05:03:10 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NA39U22271 - for ; Wed, 23 Jan 2002 05:03:09 -0500 (EST) -Received: (qmail 70600 invoked by alias); 23 Jan 2002 10:03:04 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 10:03:04 -0000 -Received: from smxsat1.smxs.net (smxsat1.smxs.net [213.150.10.1]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0N9xNl69597 - for ; Wed, 23 Jan 2002 04:59:24 -0500 (EST) - (envelope-from ZeugswetterA@spardat.at) -Received: from m01x1.s-mxs.net [10.3.55.201] - by smxsat1.smxs.net - with XWall v3.18f ; - Wed, 23 Jan 2002 11:00:47 +0100 -Received: from m0103.s-mxs.net [10.3.55.3] - by m01x1.s-mxs.net - with XWall v3.18a ; - Wed, 23 Jan 2002 10:59:19 +0100 -Received: from m0114.s-mxs.net ([10.3.55.14]) by m0103.s-mxs.net with Microsoft SMTPSVC(5.0.2195.2966); - Wed, 23 Jan 2002 10:59:18 +0100 -X-MimeOLE: Produced By Microsoft Exchange V6.0.5762.3 -content-class: urn:content-classes:message -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -Date: Wed, 23 Jan 2002 10:59:18 +0100 -Message-ID: <46C15C39FEB2C44BA555E356FBCD6FA42128DA@m0114.s-mxs.net> -Thread-Topic: [HACKERS] RFD: schemas and different kinds of Postgres objects -Thread-Index: AcGj1QtRzBpAfJVfQjCydtlooB5fgwAHyaDQ -From: "Zeugswetter Andreas SB SD" -To: "Peter Eisentraut" , "Tom Lane" -cc: "Bill Studenmund" , -X-OriginalArrivalTime: 23 Jan 2002 09:59:18.0969 (UTC) FILETIME=[9FB23A90:01C1A3F4] -Content-Transfer-Encoding: 8bit -X-MIME-Autoconverted: from quoted-printable to 8bit by postgresql.org id g0NA2d170062 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -> I don't buy that. If all you're looking for is preserving -> -> foo.bar <==> bar(foo) -> -> for compatibility, then you can simply say that "bar" cannot be -> schema-qualified in the left form (so it needs to live in the current or -> the default schema). We currently only have one default schema, so that's -> backward compatible. I think this syntax is a mistake, so I don't feel -> compelled to provide more than backwards compatibility. - -This syntax is actually my favorite :-) I use it heavily for calculated -columns. I don't feel it is a mistake. - -Andreas - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18012=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 06:13:40 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NBDdU21327 - for ; Wed, 23 Jan 2002 06:13:39 -0500 (EST) -Received: (qmail 81930 invoked by alias); 23 Jan 2002 11:13:12 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 11:13:12 -0000 -Received: from mail_exchange.westcountrypublications.co.uk ([195.171.163.135]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0NB70l80597 - for ; Wed, 23 Jan 2002 06:07:02 -0500 (EST) - (envelope-from SHenshall@westcountrypublications.co.uk) -Received: by MAIL_EXCHANGE with Internet Mail Service (5.5.2650.21) - id ; Wed, 23 Jan 2002 11:03:18 -0000 -Message-ID: -From: "Henshall, Stuart - WCP" -To: "'Tom Lane'" , Peter Eisentraut -cc: Fernando Nasser , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -Date: Wed, 23 Jan 2002 11:03:16 -0000 -MIME-Version: 1.0 -X-Mailer: Internet Mail Service (5.5.2650.21) -Content-Type: text/plain; - charset="iso-8859-1" -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - - -> -----Original Message----- -> From: Tom Lane [mailto:tgl@sss.pgh.pa.us] -> Sent: 23 January 2002 00:02 -> To: Peter Eisentraut -> Cc: Fernando Nasser; pgsql-hackers@postgresql.org -> Subject: Re: RFD: schemas and different kinds of Postgres objects -> -> -> Peter Eisentraut writes: -> > Tom Lane writes: -> >> No, it doesn't work the same as today, because in that -> implementation -> >> both A and B can create the same tablename without -> complaint. It then -> >> becomes very unclear which instance other people will get -> (unless your -> >> "any" placeholder somehow implies a search order). -> -> > The "search any schema" switch is only intended for use with legacy -> > databases, where duplicate names don't occur anyway. -> -> That's a mighty narrow view of the world. Do you think that -> people had -> better convert to SQL schemas before they ever again create a table? -> The fact is that ordinary non-schema-aware usage will -> certainly lead to -> the above scenario. -> -> > that the switch probably doesn't make a whole lot of sense. -> However, to -> > get reproduceable behaviour anyway we can just define a -> search order, such -> > as by schema name. -> -> Or say that you get an "ambiguous reference" error if there -> is more than -> one possible candidate in the "any" namespace. (Although -> that opens the -> door for innocent creation of a table foo by one user to break other -> people's formerly-working queries that reference some other foo.) -> Bottom line for me is that this is an untried concept. I think the -> concept of an "any" searchlist entry is risky enough that I don't much -> want to hang the entire usability of the implementation on the -> assumption that we won't find any fatal problems with "any". -> -> -> However, the argument over whether SQL92's concept of ownership should -> be taken as gospel is not really the argument I wanted to have in this -> thread. Is it possible to go back to the original point concerning -> whether there should be different namespace boundaries for different -> types of objects? You aren't going to avoid those issues by -> saying that -> namespace == ownership is good enough. -> -> I'm particularly troubled by the idea of trying to apply this "any" -> lookup concept to resolution of overloaded operators and functions. -> Suppose I have a reference func(type1,type2) that I'm trying -> to resolve, -> and I have an inexact match (one requiring coercion) in my own schema. -> Do I look to the "any" schema to see if there are better matches? -> If so, what happens if the "any" schema contains multiple -> possibilities -> with identical signatures (presumably created by different -> users)? ISTM -> this will positively guarantee a resolution failure, since there's no -> way for the resolver to prefer one over another. Thus, by creating -> a "func(foo,bar)" function --- quite legally --- JRandomLuser might -> break other people's formerly working queries that use other functions -> named func. Although it's possible for this to happen now, it'll be -> a lot more surprising if JRandomLuser thinks that his functions live -> in his own private schema namespace. -> -> I'm thinking that the overloading concept is not going to play well -> at all with multiple namespaces for functions or operators, and that -> we'd be best off to say that there is only one namespace (per -> database) -> for these things. -> -> regards, tom lane -> -Could you just have a general rule of search in order of age (by OID)? This -should prevent changes to existing operation when new definitions come along -(unless new definition is in new own schema or default). -Cheers, -- Stuart - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18024=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 10:13:55 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NFDsU06028 - for ; Wed, 23 Jan 2002 10:13:54 -0500 (EST) -Received: (qmail 39657 invoked by alias); 23 Jan 2002 15:13:28 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 15:13:28 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0NF1dl35283 - for ; Wed, 23 Jan 2002 10:01:40 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0NExef02480; - Wed, 23 Jan 2002 09:59:40 -0500 (EST) -To: "Henshall, Stuart - WCP" -cc: Peter Eisentraut , Fernando Nasser , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -References: -Comments: In-reply-to "Henshall, Stuart - WCP" - message dated "Wed, 23 Jan 2002 11:03:16 +0000" -Date: Wed, 23 Jan 2002 09:59:39 -0500 -Message-ID: <2477.1011797979@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -"Henshall, Stuart - WCP" writes: -> Could you just have a general rule of search in order of age (by OID)? - -No, unless you plan to abandon the whole notion of resolving ambiguous -operator/function calls. (Which'd cut down our TODO list a good bit ;-) -but I don't think users would be happy...) OID/age ordering generally -has little to do with reasonable resolution behavior. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M18026=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 10:33:35 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NFXYU07736 - for ; Wed, 23 Jan 2002 10:33:34 -0500 (EST) -Received: (qmail 44416 invoked by alias); 23 Jan 2002 15:33:29 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 15:33:29 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0NFVfl43926 - for ; Wed, 23 Jan 2002 10:31:41 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0NFVQf02603; - Wed, 23 Jan 2002 10:31:26 -0500 (EST) -To: Peter Eisentraut -cc: pgsql-hackers@postgresql.org, Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -References: -Comments: In-reply-to Peter Eisentraut - message dated "Tue, 22 Jan 2002 20:52:14 -0500" -Date: Wed, 23 Jan 2002 10:31:25 -0500 -Message-ID: <2600.1011799885@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Peter Eisentraut writes: -> OK, I can accept that. But then I want to get back at my original point, -> namely that all database objects (except users and groups) should be in -> schemas. This is also cleaner, simpler, and more flexible. There is -> clearly demand for schema-local functions. So I think that designing this -> system from the premise that a schema-qualified operator call will look -> strange is the wrong end to start at. - -Okay, a fair point --- or you could have used my own argument against -me: there's nothing wrong with designing a general mechanism and then -choosing not to expose all of the functionality. So let's assume that -functions and operators live in namespaces, and that we have some kind -of search path across multiple namespaces for use when an unqualified -name is given. - -Now, how is that going to play with resolution of ambiguous calls? - -The most reasonable semantics I can think of are to collect all the -potential matches (matching op/func name) across all the searchable -namespaces, discarding only those that have exactly the same signature -as one in a prior namespace. Thus, eg, plus(int4,int4) in an earlier -namespace would hide plus(int4,int4) in a later namespace in the search -path, but it wouldn't hide plus(int8,int8). After we've collected all -the visible alternatives, do resolution based on argument types the same -way as we do now. - -The only alternative semantics that seem defensible at all are to stop -at the first namespace that contains any matching-by-name op or func, -and do resolution using only the candidates available in that namespace. -That strikes me as not a good idea; for example, a user who defines a -"+" operator in his own schema for his own datatype would be quite -unhappy to find it masking all the "+" operators in the system schema. - -I believe that this behavior would be fairly reasonable if our -backward-compatibility feature consists of a "public" namespace -that all users can write in. OTOH I think it would not play at all -well if we use Fernando's idea of an "any" wildcard in the search -path. (1) Imagine the case where we have some users who are using -the backward-compatible behavior while others have set up private -namespaces. If Joe SmartGuy creates a "+" operator in his private -namespace, it'll be visible to people using the "any" wildcard and -possibly cause resolution-ambiguity failures for them, even though -Joe deliberately did what he should do to avoid that. (2) "any" -creates the problem of resolving multiple functions with identical -signatures in different namespaces, with no reasonable rule for -making the choice. - -So I'm still of the opinion that an "any" wildcard is too risky a -solution for our backwards-compatibility problem. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18030=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 11:35:41 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NGZeU13512 - for ; Wed, 23 Jan 2002 11:35:40 -0500 (EST) -Received: (qmail 91981 invoked by alias); 23 Jan 2002 16:34:06 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 16:34:06 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0NFjNl67457 - for ; Wed, 23 Jan 2002 10:45:58 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0NFiYf02680; - Wed, 23 Jan 2002 10:44:34 -0500 (EST) -To: "Zeugswetter Andreas SB SD" -cc: "Fernando Nasser" , - "Peter Eisentraut" , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <46C15C39FEB2C44BA555E356FBCD6FA41EB4C2@m0114.s-mxs.net> -References: <46C15C39FEB2C44BA555E356FBCD6FA41EB4C2@m0114.s-mxs.net> -Comments: In-reply-to "Zeugswetter Andreas SB SD" - message dated "Wed, 23 Jan 2002 10:11:13 +0100" -Date: Wed, 23 Jan 2002 10:44:34 -0500 -Message-ID: <2677.1011800674@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: ORr - -"Zeugswetter Andreas SB SD" writes: -> When configured for historical behavior would need to: -> 1. have search path: temp, any, system -> 2. guard against duplicate table names across all schemas (except temp schema) - -This would be a *whole* lot simpler if we forgot the notion of "any" -and made the search order look like - - (temp, private, public, system) - -where the public namespace is world-writable but the private per-user -ones are (typically at least) not. - -It occurs to me that we can get both backward-compatible and SQL92 -semantics with this same search path; the only thing that needs to -be different in the two cases is whether the default place to create -objects is your private schema or the public one. If you don't ever -use your private schema then it doesn't matter if it's on the search -path or not. I would still prefer that the search path be a settable -option, since a paranoid person might well wish to not have public in -his path at all ... but the default could be as-above. - -> Or are you thinking about a per session behavior ? -> I would rather envision a per database behavior. -> Maybe the easy way out would be a "default creation schema" property for -> each user, that would default to the username. If you want everything in one -> schema simply alter the users. - -I hadn't really gotten to the point of thinking about exactly what and -where the control knobs should be. I suspect you are right that we will -want the default behavior to be selectable on a per-user or per-database -basis, which seems to eliminate the option of using GUC (at least in its -current form). We could easily add a field to pg_shadow or pg_database -respectively to determine the default behavior. It'd be nice though if -the behavior could be changed after connection by a SET statement, which -would be lots easier if the setting were GUC-controlled. Peter, you see -any way to resolve that? - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M18034=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 11:50:22 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NGoLU15032 - for ; Wed, 23 Jan 2002 11:50:21 -0500 (EST) -Received: (qmail 1716 invoked by alias); 23 Jan 2002 16:50:05 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 16:50:05 -0000 -Received: from megazone.bigpanda.com (megazone.bigpanda.com [63.150.15.178]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0NGZgl93351 - for ; Wed, 23 Jan 2002 11:35:42 -0500 (EST) - (envelope-from sszabo@megazone23.bigpanda.com) -Received: by megazone.bigpanda.com (Postfix, from userid 1001) - id ABA27D5E5; Wed, 23 Jan 2002 08:35:47 -0800 (PST) -Received: from localhost (localhost [127.0.0.1]) - by megazone.bigpanda.com (Postfix) with ESMTP - id 9D3E55BF5; Wed, 23 Jan 2002 08:35:47 -0800 (PST) -Date: Wed, 23 Jan 2002 08:35:47 -0800 (PST) -From: Stephan Szabo -To: Tom Lane -cc: Peter Eisentraut , , - Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <2600.1011799885@sss.pgh.pa.us> -Message-ID: <20020123083152.W18169-100000@megazone23.bigpanda.com> -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -On Wed, 23 Jan 2002, Tom Lane wrote: - -> The only alternative semantics that seem defensible at all are to stop -> at the first namespace that contains any matching-by-name op or func, -> and do resolution using only the candidates available in that namespace. -> That strikes me as not a good idea; for example, a user who defines a -> "+" operator in his own schema for his own datatype would be quite -> unhappy to find it masking all the "+" operators in the system schema. -> -> I believe that this behavior would be fairly reasonable if our -> backward-compatibility feature consists of a "public" namespace -> that all users can write in. OTOH I think it would not play at all -> well if we use Fernando's idea of an "any" wildcard in the search -> path. (1) Imagine the case where we have some users who are using -> the backward-compatible behavior while others have set up private -> namespaces. If Joe SmartGuy creates a "+" operator in his private -> namespace, it'll be visible to people using the "any" wildcard and -> possibly cause resolution-ambiguity failures for them, even though -> Joe deliberately did what he should do to avoid that. (2) "any" -> creates the problem of resolving multiple functions with identical -> signatures in different namespaces, with no reasonable rule for -> making the choice. - -Wouldn't it make sense to prefer operators/functions earlier in the search -path for resolving ambiguity. So if you had plus(int4, int4) in my -schema and plus(int8, int8) in system, and they'd otherwise cause an -ambiguity failure for the query, use the plus(int4, int4) on mine. It -seems not too far from having the search path shadow later exact matches. - - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18041=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 12:18:50 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NHInU20563 - for ; Wed, 23 Jan 2002 12:18:49 -0500 (EST) -Received: (qmail 17817 invoked by alias); 23 Jan 2002 17:14:34 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 17:14:34 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0NHC6l15615 - for ; Wed, 23 Jan 2002 12:12:06 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0NGkwf03162; - Wed, 23 Jan 2002 11:46:58 -0500 (EST) -To: Stephan Szabo -cc: Peter Eisentraut , pgsql-hackers@postgresql.org, - Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <20020123083152.W18169-100000@megazone23.bigpanda.com> -References: <20020123083152.W18169-100000@megazone23.bigpanda.com> -Comments: In-reply-to Stephan Szabo - message dated "Wed, 23 Jan 2002 08:35:47 -0800" -Date: Wed, 23 Jan 2002 11:46:58 -0500 -Message-ID: <3159.1011804418@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Stephan Szabo writes: -> Wouldn't it make sense to prefer operators/functions earlier in the search -> path for resolving ambiguity. So if you had plus(int4, int4) in my -> schema and plus(int8, int8) in system, and they'd otherwise cause an -> ambiguity failure for the query, use the plus(int4, int4) on mine. It -> seems not too far from having the search path shadow later exact matches. - -Given the complexity of the resolution rules (cf. -http://developer.postgresql.org/docs/postgres/typeconv.html), -it's not clear that we can determine exactly which "later" entry ought -to be blamed for causing a resolution failure. I'd be interested to -hear Lockhart's opinion on this --- but my gut feeling is we don't -want to go there. The resolution rules are already complicated enough, -and I think layering an additional mechanism like that onto them might -make the behavior totally unpredictable. - -Another problem is that this would probably cause earlier namespace -entries to be over-preferred. For example, suppose that the system -namespace has plus(int4,int4) and plus(int8,int8) and you choose to -define plus(int4,int8) locally. I believe you'd suddenly find yours -being used for *any* cross-datatype addition, including cases that -had nothing obvious to do with either int4 or int8 ... - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M18040=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 12:18:51 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NHIoU20594 - for ; Wed, 23 Jan 2002 12:18:51 -0500 (EST) -Received: (qmail 17832 invoked by alias); 23 Jan 2002 17:14:34 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 17:14:34 -0000 -Received: from mx1.relaypoint.net (ns2.generalbroadband.com [64.32.62.5]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0NGu6l05540 - for ; Wed, 23 Jan 2002 11:56:06 -0500 (EST) - (envelope-from jconway@cox.net) -Received: from [206.19.64.3] (account jconway@wwc.com HELO cox.net) - by mx1.relaypoint.net (CommuniGate Pro SMTP 3.4.8) - with ESMTP id 2510369; Wed, 23 Jan 2002 08:56:10 -0800 -Message-ID: <3C4EEB2F.8040803@cox.net> -Date: Wed, 23 Jan 2002 08:56:15 -0800 -From: "Joe Conway (wwc)" -User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:0.9.6+) Gecko/20011219 -X-Accept-Language: en-us -MIME-Version: 1.0 -To: Tom Lane -cc: Zeugswetter Andreas SB SD , - Fernando Nasser , Peter Eisentraut , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: <46C15C39FEB2C44BA555E356FBCD6FA41EB4C2@m0114.s-mxs.net> <2677.1011800674@sss.pgh.pa.us> -Content-Type: text/plain; charset=us-ascii; format=flowed -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane wrote: - -> -> This would be a *whole* lot simpler if we forgot the notion of "any" -> and made the search order look like -> -> (temp, private, public, system) -> -> where the public namespace is world-writable but the private per-user -> ones are (typically at least) not. -> -> It occurs to me that we can get both backward-compatible and SQL92 -> semantics with this same search path; the only thing that needs to -> be different in the two cases is whether the default place to create -> objects is your private schema or the public one. If you don't ever -> use your private schema then it doesn't matter if it's on the search -> path or not. I would still prefer that the search path be a settable -> option, since a paranoid person might well wish to not have public in -> his path at all ... but the default could be as-above. -> - - -I think it would be desirable to be able to restrict users from -"publishing" objects into the public schema. As an admin, I'd like some -control over the objects in this namespace. Hand-in-hand with this would -be the ability for the superuser to move (or "promote") an object from a -private schema to the public one. This would allow a user to develop -their own objects without interfering with others, but then make it -public with the superuser's assistance. - -The search path you suggest above would then lead to the behavior that -unqualified references to objects will see my own objects before the -public ones, and other people's private objects must be explicitly -qualified. - -Joe - - - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18042=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 12:18:45 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NHIiU20532 - for ; Wed, 23 Jan 2002 12:18:45 -0500 (EST) -Received: (qmail 17765 invoked by alias); 23 Jan 2002 17:14:31 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 17:14:31 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0NH1Tl11512 - for ; Wed, 23 Jan 2002 12:01:29 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0NH0vf03329; - Wed, 23 Jan 2002 12:00:57 -0500 (EST) -To: "Joe Conway (wwc)" -cc: Zeugswetter Andreas SB SD , - Fernando Nasser , Peter Eisentraut , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <3C4EEB2F.8040803@cox.net> -References: <46C15C39FEB2C44BA555E356FBCD6FA41EB4C2@m0114.s-mxs.net> <2677.1011800674@sss.pgh.pa.us> <3C4EEB2F.8040803@cox.net> -Comments: In-reply-to "Joe Conway (wwc)" - message dated "Wed, 23 Jan 2002 08:56:15 -0800" -Date: Wed, 23 Jan 2002 12:00:56 -0500 -Message-ID: <3326.1011805256@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -"Joe Conway (wwc)" writes: -> I think it would be desirable to be able to restrict users from -> "publishing" objects into the public schema. - -Sure. I'm envisioning that namespaces will have ACLs --- that's what -will keep private namespaces private. So, while public would by default -be world-writable (at least in the backwards-compatibility case), -there'd be nothing stopping you from marking it as read-only to some -users. - -Come to think of it, that's still another reason not to have an "any" -wildcard: there's no way to put any restrictions on what appears in -such a namespace. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18043=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 12:22:29 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NHMSU21118 - for ; Wed, 23 Jan 2002 12:22:28 -0500 (EST) -Received: (qmail 17648 invoked by alias); 23 Jan 2002 17:14:27 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 17:14:27 -0000 -Received: from megazone.bigpanda.com (megazone.bigpanda.com [63.150.15.178]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0NH9Ul15308 - for ; Wed, 23 Jan 2002 12:09:30 -0500 (EST) - (envelope-from sszabo@megazone23.bigpanda.com) -Received: by megazone.bigpanda.com (Postfix, from userid 1001) - id E7DB9D5E5; Wed, 23 Jan 2002 09:09:35 -0800 (PST) -Received: from localhost (localhost [127.0.0.1]) - by megazone.bigpanda.com (Postfix) with ESMTP - id DD82F5BF5; Wed, 23 Jan 2002 09:09:35 -0800 (PST) -Date: Wed, 23 Jan 2002 09:09:35 -0800 (PST) -From: Stephan Szabo -To: Tom Lane -cc: Peter Eisentraut , , - Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <3159.1011804418@sss.pgh.pa.us> -Message-ID: <20020123085959.U18688-100000@megazone23.bigpanda.com> -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - -On Wed, 23 Jan 2002, Tom Lane wrote: - -> Stephan Szabo writes: -> > Wouldn't it make sense to prefer operators/functions earlier in the search -> > path for resolving ambiguity. So if you had plus(int4, int4) in my -> > schema and plus(int8, int8) in system, and they'd otherwise cause an -> > ambiguity failure for the query, use the plus(int4, int4) on mine. It -> > seems not too far from having the search path shadow later exact matches. -> -> Given the complexity of the resolution rules (cf. -> http://developer.postgresql.org/docs/postgres/typeconv.html), -> it's not clear that we can determine exactly which "later" entry ought -> to be blamed for causing a resolution failure. I'd be interested to -> hear Lockhart's opinion on this --- but my gut feeling is we don't -> want to go there. The resolution rules are already complicated enough, -> and I think layering an additional mechanism like that onto them might -> make the behavior totally unpredictable. - -> Another problem is that this would probably cause earlier namespace -> entries to be over-preferred. For example, suppose that the system -> namespace has plus(int4,int4) and plus(int8,int8) and you choose to -> define plus(int4,int8) locally. I believe you'd suddenly find yours -> being used for *any* cross-datatype addition, including cases that -> had nothing obvious to do with either int4 or int8 ... - -Well, what I'd been thinking of would have been similar to anywhere it -says "If only one candidate matches", becoming "If the earliest search -path entry with at least one candidate matching has only one -matching candidate ..." But that would cause the plus(int4, int8) to get -used in any cross-datatype case that could coerce and didn't have a -stronger match (ie, one of the arguments exactly matching a plus argument -per b or c) so that's probably not good enough. - - - - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M18058=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 14:45:20 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NJjJU03694 - for ; Wed, 23 Jan 2002 14:45:19 -0500 (EST) -Received: (qmail 89208 invoked by alias); 23 Jan 2002 19:43:44 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 19:43:44 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0NJd7l87615 - for ; Wed, 23 Jan 2002 14:39:07 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 11757 invoked by uid 1130); 23 Jan 2002 19:39:07 -0000 -Date: Wed, 23 Jan 2002 11:34:23 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Tom Lane -cc: Peter Eisentraut , -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <12239.1011661590@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Mon, 21 Jan 2002, Tom Lane wrote: - -> Peter Eisentraut writes: -> > Remember that a schema is a named representation of ownership, so anything -> > that can be owned must be in a schema. (Unless you want to invent a -> > parallel universe for a different kind of ownership, which would be -> > incredibly confusing.) -> -> I don't buy that premise. It's true that SQL92 equates ownership of a -> schema with ownership of the objects therein, but AFAICS we have no hope -> of being forward-compatible with existing database setups (wherein there -> can be multiple tables of different ownership all in a single namespace) -> if we don't allow varying ownership within a schema. I think we can -> arrange things so that we are upward compatible with both SQL92 and -> the old way. Haven't worked out details yet though. - -Yes we most certianly can! :-) - -One of the things schemas have to support is essentially a PATH specifier. -So all we need to do is have all of the schemas created in a new DB have -path specifiers pulling in all of the other schemas. Thus we can make a -schema-savy system act as if it has only one namespace. - -Back when Zembu was paying me to work on this, I envisioned a script or -tool you'd feed a DB dump, and it would do the schema fixup, including -adding PATH directives to all schemas, so they all see everything. - -Since you have to pg_dump when updating, all this adds is running one tool -during an upgrade. And then existing apps would work. :-) - -Take care, - -Bill - - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M18059=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 15:15:34 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NKFXU06599 - for ; Wed, 23 Jan 2002 15:15:34 -0500 (EST) -Received: (qmail 357 invoked by alias); 23 Jan 2002 20:13:55 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 20:13:55 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0NJvXl94681 - for ; Wed, 23 Jan 2002 14:57:33 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0NJvEf05081; - Wed, 23 Jan 2002 14:57:14 -0500 (EST) -To: Bill Studenmund -cc: Peter Eisentraut , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -References: -Comments: In-reply-to Bill Studenmund - message dated "Wed, 23 Jan 2002 11:34:23 -0800" -Date: Wed, 23 Jan 2002 14:57:14 -0500 -Message-ID: <5078.1011815834@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Bill Studenmund writes: -> One of the things schemas have to support is essentially a PATH specifier. - -Yes, but... - -> So all we need to do is have all of the schemas created in a new DB have -> path specifiers pulling in all of the other schemas. Thus we can make a -> schema-savy system act as if it has only one namespace. - -When you create a new user, do all those path specifiers for the -existing users magically update themselves? Seems like maintenance -would be a pain. - -Fernando's "any" idea is probably a cleaner way to handle it if we -wanted to do things like that. But I still think it'll be safer and -more controllable if we provide a "public" namespace instead; see -followup discussions. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M18061=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 16:04:22 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NL4LU11265 - for ; Wed, 23 Jan 2002 16:04:21 -0500 (EST) -Received: (qmail 21187 invoked by alias); 23 Jan 2002 21:03:47 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 21:03:47 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0NKkVl14074 - for ; Wed, 23 Jan 2002 15:46:32 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 21707 invoked by uid 1130); 23 Jan 2002 20:46:32 -0000 -Date: Wed, 23 Jan 2002 12:41:48 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Tom Lane -cc: -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <648.1011762477@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 23 Jan 2002, Tom Lane wrote: - -> Bill Studenmund writes: -> > Why not? What's wrong with either schema.foo.function (==> -> > function(schema.foo)) or foo.schema.function (==> schema.function(foo))? -> -> Neither is wrong in isolation, but how do you tell the difference? -> More to the point, given input x.y.z, how do you tell which component -> is what? - -See below. - -> > Tables and functions can't have the same names as schemas, -> -> News to me. Where is that written on stone tablets? Even if that's - -I'm still trying to find the quote, but I found it a few months ago. I'm -looking in SQL99, which is 1100+ pages for section 2. :-) - -> considered an acceptable limitation from a purely functional point of -> view, I don't like using it to disambiguate input. The error messages -> you'll get from incorrect input to an implementation that depends on -> that to disambiguate cases will not be very helpful. - -?? Depends on how we do it. As I see it, we have four cases. In the -x.y.z.p.q, we have: - -1) No table name, but a function name. It's a function call. - -2) A table name, but no function name. It's a table reference. - -3) Both a table name & function name, and the function is first. I think -this case is an error (I don't think we support function.foo == -function(foo)) - -4) Both a table name & function name, and the table is first. This is -foo.function. - -Ok, there is a fifth case, no function nor table names, which is an error. - -> > Actually functions do have to be schema local. It's in the spec (don't -> > have exactly where with me). -> -> (A) I don't believe that; please cite chapter and verse; (B) even if - -Peter got to that one first. - -> SQL92 thinks that's okay, we can't do it that way because of -> backwards-compatibility issues. - -Why do backwards-compatability issues keep us from doing it? - -Yes, I understand we have apps now with different users owning things -(tables, functions) which they all can access, just like they were in one -unified name space. With real schemas, they are in differen namespaces. -But as long as the routines, tables, triggers & such in each schema can -find things in the other schemas as if they were in one namespace, where -is the problem? We just have the app gain PATH directives to path in all -the other schemas. - -The app runs, even though there are different schemas involved. Where is -the problem? - -> > My vote would be to make them schema-specific. As Peter pointed out, -> > schemas are how you own things, -> -> Sorry, but this line of argument is trying to assume the very point in -> dispute. - -When you started this thread, you said you were thinking about -"implementing SQL schemas." Are these "SQL schemas" going to follow the -spec or not? SQL'99 is rather clear that ownership happens at the schema -level. Peter spent quite a lot of time last October pounding that into my -head, and after I looked at the spec, I found he was 100% correct. - -If these schemas are to follow the standards, ownership happens at the -schema level. If ownership happens elsewhere, whatever we're doing is not -following the standard. Unfortunatly it's that cut & dried. So why should -we call them "SQL schemas" if we aren't following the SQL spec? - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M18061=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 16:04:22 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NL4LU11264 - for ; Wed, 23 Jan 2002 16:04:21 -0500 (EST) -Received: (qmail 21192 invoked by alias); 23 Jan 2002 21:03:48 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 21:03:48 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0NKvHl19546 - for ; Wed, 23 Jan 2002 15:57:17 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0NKvGf08536; - Wed, 23 Jan 2002 15:57:16 -0500 (EST) -To: Bill Studenmund -cc: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -References: -Comments: In-reply-to Bill Studenmund - message dated "Wed, 23 Jan 2002 12:41:48 -0800" -Date: Wed, 23 Jan 2002 15:57:16 -0500 -Message-ID: <8533.1011819436@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Bill Studenmund writes: -> On Wed, 23 Jan 2002, Tom Lane wrote: ->> Bill Studenmund writes: -> Why not? What's wrong with either schema.foo.function (==> -> function(schema.foo)) or foo.schema.function (==> schema.function(foo))? ->> ->> Neither is wrong in isolation, but how do you tell the difference? ->> More to the point, given input x.y.z, how do you tell which component ->> is what? - -> ?? Depends on how we do it. As I see it, we have four cases. In the -> x.y.z.p.q, we have: - -> 1) No table name, but a function name. It's a function call. - -> 2) A table name, but no function name. It's a table reference. - -No, you're missing the point. Which of x,y,z,p,q is the name we -are going to test to see if it is a table or function? And which -of these names is a schema name --- if you don't even know that, -it's hard to argue that checking to see if some name is known is -a well-defined operation. - -> When you started this thread, you said you were thinking about -> "implementing SQL schemas." Are these "SQL schemas" going to follow the -> spec or not? - -If you use only the SQL-defined operations, after setting up any -configuration variables we may invent in the way we will document as -necessary for SQL-compatible behavior, then you will get SQL-compatible -behavior. I do not think that precludes having an underlying -implementation that sees the world differently than SQL does and -supports non-SQL behaviors too. (For that matter, I'm sure there is -text somewhere in the spec that points out that the spec intends to -define user-visible behavior, not implementation.) - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M18062=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 16:14:05 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NLE4U12279 - for ; Wed, 23 Jan 2002 16:14:04 -0500 (EST) -Received: (qmail 25791 invoked by alias); 23 Jan 2002 21:13:41 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 21:13:41 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0NL3Jl20482 - for ; Wed, 23 Jan 2002 16:03:19 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 27532 invoked by uid 1130); 23 Jan 2002 21:03:16 -0000 -Date: Wed, 23 Jan 2002 12:58:33 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Tom Lane -cc: Peter Eisentraut , -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <5078.1011815834@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 23 Jan 2002, Tom Lane wrote: - -> Bill Studenmund writes: -> > One of the things schemas have to support is essentially a PATH specifier. -> -> Yes, but... -> -> > So all we need to do is have all of the schemas created in a new DB have -> > path specifiers pulling in all of the other schemas. Thus we can make a -> > schema-savy system act as if it has only one namespace. -> -> When you create a new user, do all those path specifiers for the -> existing users magically update themselves? Seems like maintenance -> would be a pain. - -No, they don't. But why should they? Why should they need to? - -Either we're migrating an existing app, for which adding PATH directives -with a helper program before restore works, or we're making a new app. If -you're designing an app for a schema-savy system, you need to think about -schemas. - -> Fernando's "any" idea is probably a cleaner way to handle it if we -> wanted to do things like that. But I still think it'll be safer and -> more controllable if we provide a "public" namespace instead; see -> followup discussions. - -Why? Why is it needed? What would public let you do that PATH and ACLs -wouldn't? - -The only reason I can see it's needed is so that people can make new apps -for a schema-savy PostgreSQL while ignoring the schemas. That strikes me -as bad. I agree that schemas shouldn't interfeer with things, but to let -folks just blow them off seems equally bad. - -Also, it wouldn't be SQL'99 schemas. It can still be done, but it's -solving a problem that the other SQL'99 databases don't seem to have. - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18065=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 16:33:45 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NLXiU14151 - for ; Wed, 23 Jan 2002 16:33:44 -0500 (EST) -Received: (qmail 32278 invoked by alias); 23 Jan 2002 21:33:41 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 21:33:41 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0NLKGl28778 - for ; Wed, 23 Jan 2002 16:20:16 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 665 invoked by uid 1130); 23 Jan 2002 21:20:17 -0000 -Date: Wed, 23 Jan 2002 13:15:33 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Tom Lane -cc: -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <8533.1011819436@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 23 Jan 2002, Tom Lane wrote: - -> Bill Studenmund writes: -> > On Wed, 23 Jan 2002, Tom Lane wrote: -> >> Bill Studenmund writes: -> > Why not? What's wrong with either schema.foo.function (==> -> > function(schema.foo)) or foo.schema.function (==> schema.function(foo))? -> >> -> >> Neither is wrong in isolation, but how do you tell the difference? -> >> More to the point, given input x.y.z, how do you tell which component -> >> is what? -> -> > ?? Depends on how we do it. As I see it, we have four cases. In the -> > x.y.z.p.q, we have: -> -> > 1) No table name, but a function name. It's a function call. -> -> > 2) A table name, but no function name. It's a table reference. -> -> No, you're missing the point. Which of x,y,z,p,q is the name we -> are going to test to see if it is a table or function? And which -> of these names is a schema name --- if you don't even know that, -> it's hard to argue that checking to see if some name is known is -> a well-defined operation. - -No, I'm not. :-) You test enough of them to figure out what case you have. -Yes, it might be a bit of work, but it's doable. - -Actually, it's not that hard. In foo.funcname, do we support anything -AFTER the funcname? I don't think so. If there were a parenthesis, then we -have a function call. If it's an operator or something else, we have -either a table reference, or a foo.funcname function call. So all we have -to do is see if p.q (last two elements) is a schema.function, or of q is a -function pathed into our current schema. If yes, we have foo.function. If -not, then we have some table reference. - -> > When you started this thread, you said you were thinking about -> > "implementing SQL schemas." Are these "SQL schemas" going to follow the -> > spec or not? -> -> If you use only the SQL-defined operations, after setting up any -> configuration variables we may invent in the way we will document as -> necessary for SQL-compatible behavior, then you will get SQL-compatible -> behavior. I do not think that precludes having an underlying -> implementation that sees the world differently than SQL does and -> supports non-SQL behaviors too. (For that matter, I'm sure there is -> text somewhere in the spec that points out that the spec intends to -> define user-visible behavior, not implementation.) - -While I agree in principle, that quote is from talking about ownership. I -don't see how we can gloss over ownership. :-) - -Also, why support two different behaviors? That means 1) there's code -bloat since the backend has to support both. 2) Support is harder as major -DB behaviors will change depending on these settings. 3) I still haven't -seen anything this variant behavior would do that can't be done with -schema paths and access control lists, other than it would let people keep -thinking about things as they do now. - -That latter reason doesn't strike me as a good one. Yes, it will take some -getting used to to wrap minds around schemas, but once done, I don't think -it will be that hard. Yes, the documentation will need work, and the -tutorial will need changing (And Bruce will need to release a new edition -of his book :-) , but once that's done, I don't think working with real -schemas will be that hard. So why not just do things right from the -begining? - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M18064=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 16:23:32 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NLNVU13386 - for ; Wed, 23 Jan 2002 16:23:31 -0500 (EST) -Received: (qmail 29442 invoked by alias); 23 Jan 2002 21:23:26 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 21:23:26 -0000 -Received: from stubee.d2hosting.net (d2hosting.net [66.70.41.160]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0NLGVl28360 - for ; Wed, 23 Jan 2002 16:16:31 -0500 (EST) - (envelope-from tswan-lst@ics.olemiss.edu) -Received: from ics.olemiss.edu (adsl-81-102-77.jan.bellsouth.net [65.81.102.77]) - by stubee.d2hosting.net (8.11.6/linuxconf) with ESMTP id g0NLGLT00962; - Wed, 23 Jan 2002 15:16:22 -0600 -Message-ID: <3C4F2824.90709@ics.olemiss.edu> -Date: Wed, 23 Jan 2002 15:16:20 -0600 -From: Thomas Swan -User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:0.9.7+) Gecko/20020123 -X-Accept-Language: en-us -MIME-Version: 1.0 -To: Tom Lane -cc: Stephan Szabo , - Peter Eisentraut , pgsql-hackers@postgresql.org, - Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: <20020123083152.W18169-100000@megazone23.bigpanda.com> <3159.1011804418@sss.pgh.pa.us> -Content-Type: text/html; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - - - - - - - -Tom Lane wrote:
-
-
Stephan Szabo <sszabo@megazone23.bigpanda.com> writes:
-
-
Wouldn't it make sense to prefer operators/functions earlier in the search
path for resolving ambiguity. So if you had plus(int4, int4) in my
schema and plus(int8, int8) in system, and they'd otherwise cause an
ambiguity failure for the query, use the plus(int4, int4) on mine. It
seems not too far from having the search path shadow later exact matches.
-
-

Given the complexity of the resolution rules (cf.
http://developer.postgresql.org/docs/postgres/typeconv.html),
it's not clear that we can determine exactly which "later" entry ought
to be blamed for causing a resolution failure. I'd be interested to
hear Lockhart's opinion on this --- but my gut feeling is we don't
want to go there. The resolution rules are already complicated enough,
and I think layering an additional mechanism like that onto them might
make the behavior totally unpredictable.

Another problem is that this would probably cause earlier namespace
entries to be over-preferred. For example, suppose that the system
namespace has plus(int4,int4) and plus(int8,int8) and you choose to
define plus(int4,int8) locally. I believe you'd suddenly find yours
being used for *any* cross-datatype addit -ion, including cases that
had nothing obvious to do with either int4 or int8 ...
-
-This is a good example.  The other option is to use  name, arg1, arg2... -as a hunt path for function call resolution.  This would depend on when datatype -promotion is occuring (i.e. int4 to int8, int8 to int4, etc... )
-
-Then you could just be really hard and say that only exact and trivial conversion -matches in user space will be used .  
-
-There is no easy answer for this, but whatever rules are initiated need to -be something that someone can step through to solve w/o a machine.
-
-I do think you will ultimately need a search utility that provides 'which' -functionality.   (Given my namespace, which function in what namespace is -going to be called.)
-
-


regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org
-
-
-
- - - - -From pgsql-hackers-owner+M18066=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 16:45:11 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NLjAU15010 - for ; Wed, 23 Jan 2002 16:45:11 -0500 (EST) -Received: (qmail 39170 invoked by alias); 23 Jan 2002 21:43:48 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 21:43:48 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0NLQpl30489 - for ; Wed, 23 Jan 2002 16:26:51 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0NLQXf08750; - Wed, 23 Jan 2002 16:26:33 -0500 (EST) -To: Bill Studenmund -cc: Peter Eisentraut , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -References: -Comments: In-reply-to Bill Studenmund - message dated "Wed, 23 Jan 2002 12:58:33 -0800" -Date: Wed, 23 Jan 2002 16:26:33 -0500 -Message-ID: <8747.1011821193@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Bill Studenmund writes: -> Either we're migrating an existing app, for which adding PATH directives -> with a helper program before restore works, or we're making a new app. - -Sorry, I don't accept that either-or proposition. People will expect to -be able to continue to use 7.3 as they have used Postgres in the past. -Among other things that will mean being able to add new users to an -existing installation. If we say "you can't do much of anything in 7.3 -until you upgrade all your applications to schema-awareness", then we're -going to have lots of unhappy users. - ->> Fernando's "any" idea is probably a cleaner way to handle it if we ->> wanted to do things like that. But I still think it'll be safer and ->> more controllable if we provide a "public" namespace instead; see ->> followup discussions. - -> Why? Why is it needed? What would public let you do that PATH and ACLs -> wouldn't? - -Public gives you a place to put the ACL determining what people can do -with publicly-visible names. See, eg, comments from Joe Conway. -Without a specific public namespace to put ACLs on, a dbadmin has very -little control over interuser interactions. Please note that the -facility we are talking about offering here is not available in existing -Postgres nor in SQL92, but that doesn't make it evil or unreasonable. - -Basically my point here is that the SQL spec is not the be-all and -end-all of database development. (Have you read C. J. Date's commentary -on it, for example?) We have a proven useful concept of object ownership -in existing Postgres, and I see no need to remove that facility in -pursuit of slavish adherence to a specification. If it were a project -goal to rip out everything in Postgres that is not mentioned in the -SQL spec, we could have a much smaller distribution ... with lots fewer -users. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18067=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 17:04:34 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NM4XU16392 - for ; Wed, 23 Jan 2002 17:04:33 -0500 (EST) -Received: (qmail 47125 invoked by alias); 23 Jan 2002 22:04:32 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 22:04:32 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0NLk1l42602 - for ; Wed, 23 Jan 2002 16:46:01 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0NLk1f08845; - Wed, 23 Jan 2002 16:46:01 -0500 (EST) -To: Bill Studenmund -cc: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -References: -Comments: In-reply-to Bill Studenmund - message dated "Wed, 23 Jan 2002 13:15:33 -0800" -Date: Wed, 23 Jan 2002 16:46:01 -0500 -Message-ID: <8842.1011822361@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Bill Studenmund writes: ->> No, you're missing the point. Which of x,y,z,p,q is the name we ->> are going to test to see if it is a table or function? - -> No, I'm not. :-) You test enough of them to figure out what case you have. - -There could be multiple valid interpretations. When you can't even -figure out where to start, it's too squishy for me. Code complexity -isn't really the issue here, it's whether a user can understand what's -going on. - -> Actually, it's not that hard. In foo.funcname, do we support anything -> AFTER the funcname? I don't think so. If there were a parenthesis, then we -> have a function call. If it's an operator or something else, we have -> either a table reference, or a foo.funcname function call. So all we have -> to do is see if p.q (last two elements) is a schema.function, or of q is a -> function pathed into our current schema. If yes, we have foo.function. If -> not, then we have some table reference. - -Now wait a sec. What you started out with was the claim - -> Why not? What's wrong with either schema.foo.function (==> -> function(schema.foo)) or foo.schema.function (==> schema.function(foo))? - -The issue was not figuring out whether the last component was a function -name or not, it was to determine what the other components were, and in -particular whether the function name should be presumed to be qualified -(by the next-to-last component taken as a schema name) or unqualified. -That in turns changes your assumptions about which of the components -further left are table names, schema names, or catalog names. - -> ... I don't think working with real -> schemas will be that hard. So why not just do things right from the -> begining? - -If I thought that SQL's model of ownership == namespace was "right", -then we probably wouldn't be having this argument. I think the spec -pretty much sucks in this particular department, and I don't see why -we should restrict our implementation to support only the spec's -braindead world view. Especially not when it makes the implementation -harder, not easier, because we end up needing to add in weird frammishes -to have some semblance of backwards-compatibility too. - -Please give me some good reasons (not "the spec says so") why it's -a good idea to treat ownership of a namespace as equivalent to ownership -of the objects in it, and why decoupling the concepts at the -implementation level isn't a reasonable thing to do. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M18070=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 17:43:52 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NMhpU18760 - for ; Wed, 23 Jan 2002 17:43:51 -0500 (EST) -Received: (qmail 53592 invoked by alias); 23 Jan 2002 22:43:08 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 22:43:08 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0NMP4l51662 - for ; Wed, 23 Jan 2002 17:25:04 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 9718 invoked by uid 1130); 23 Jan 2002 22:25:06 -0000 -Date: Wed, 23 Jan 2002 14:20:22 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Tom Lane -cc: -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <8842.1011822361@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 23 Jan 2002, Tom Lane wrote: - -> Bill Studenmund writes: -> >> No, you're missing the point. Which of x,y,z,p,q is the name we -> >> are going to test to see if it is a table or function? -> -> > No, I'm not. :-) You test enough of them to figure out what case you have. -> -> There could be multiple valid interpretations. When you can't even -> figure out where to start, it's too squishy for me. Code complexity -> isn't really the issue here, it's whether a user can understand what's -> going on. -> -> > Actually, it's not that hard. In foo.funcname, do we support anything -> > AFTER the funcname? I don't think so. If there were a parenthesis, then we -> > have a function call. If it's an operator or something else, we have -> > either a table reference, or a foo.funcname function call. So all we have -> > to do is see if p.q (last two elements) is a schema.function, or of q is a -> > function pathed into our current schema. If yes, we have foo.function. If -> > not, then we have some table reference. -> -> Now wait a sec. What you started out with was the claim -> -> > Why not? What's wrong with either schema.foo.function (==> -> > function(schema.foo)) or foo.schema.function (==> schema.function(foo))? -> -> The issue was not figuring out whether the last component was a function -> name or not, it was to determine what the other components were, and in -> particular whether the function name should be presumed to be qualified -> (by the next-to-last component taken as a schema name) or unqualified. -> That in turns changes your assumptions about which of the components -> further left are table names, schema names, or catalog names. - -Then you choose. Choose a search order, and document it. If you are going -to go back into a corner full of so much ambiguity, then document your way -out. - -You can make it easier restricting say catalogs and schemas to have -different names, or schemas, tables, and functions can't have the same -name. For this, I'd suggest following Oracle's example. I don't think you -can go too wrong using Oracle's behavior to break ties & ambiguities. - -> > ... I don't think working with real -> > schemas will be that hard. So why not just do things right from the -> > begining? -> -> If I thought that SQL's model of ownership == namespace was "right", -> then we probably wouldn't be having this argument. I think the spec -> pretty much sucks in this particular department, and I don't see why -> we should restrict our implementation to support only the spec's -> braindead world view. Especially not when it makes the implementation -> harder, not easier, because we end up needing to add in weird frammishes -> to have some semblance of backwards-compatibility too. - -?? What weird fammishes from ownership? - -It actually makes things (slightly) simpler. All of the owner fields -disapear from most system tables, because the owner is implied by the -containing schema. - -Also, what is braindead about the spec? Yes, it's not what I would choose, -and it's different from what PG does now. But it's just that, different. -Given all of the ACL abilities (if the superuser wants user X to be able -to create objects in table Y of schema Z, s/he makes it so), why does it -matter who owns the object? - -> Please give me some good reasons (not "the spec says so") why it's -> a good idea to treat ownership of a namespace as equivalent to ownership -> of the objects in it, and why decoupling the concepts at the -> implementation level isn't a reasonable thing to do. - -Can you really give a good reason other than, "I don't like it?" - -Absent the existance of specs, it's a matter of choice. Having all of the -ownership happen at the schema level or at the individual item level, it's -six of one, half-dozen of the other. - -But there is a spec. A spec that, as far as I can tell, all other -schema-claming DBs follow. So why shouldn't we follow it? Yes, you don't -like it. But is this really supposed to be about personal desires, or -about the resulting DB? - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M18072=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 18:14:00 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NNDxU20711 - for ; Wed, 23 Jan 2002 18:14:00 -0500 (EST) -Received: (qmail 61874 invoked by alias); 23 Jan 2002 23:13:20 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 23:13:20 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0NMitl56697 - for ; Wed, 23 Jan 2002 17:44:55 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 10914 invoked by uid 1130); 23 Jan 2002 22:44:56 -0000 -Date: Wed, 23 Jan 2002 14:40:12 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Tom Lane -cc: Peter Eisentraut , , - Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <2600.1011799885@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 23 Jan 2002, Tom Lane wrote: - -> Peter Eisentraut writes: -> > OK, I can accept that. But then I want to get back at my original point, -> > namely that all database objects (except users and groups) should be in -> > schemas. This is also cleaner, simpler, and more flexible. There is -> > clearly demand for schema-local functions. So I think that designing this -> > system from the premise that a schema-qualified operator call will look -> > strange is the wrong end to start at. -> -> Okay, a fair point --- or you could have used my own argument against -> me: there's nothing wrong with designing a general mechanism and then -> choosing not to expose all of the functionality. So let's assume that -> functions and operators live in namespaces, and that we have some kind -> of search path across multiple namespaces for use when an unqualified -> name is given. -> -> Now, how is that going to play with resolution of ambiguous calls? -> -> The most reasonable semantics I can think of are to collect all the -> potential matches (matching op/func name) across all the searchable -> namespaces, discarding only those that have exactly the same signature -> as one in a prior namespace. Thus, eg, plus(int4,int4) in an earlier -> namespace would hide plus(int4,int4) in a later namespace in the search -> path, but it wouldn't hide plus(int8,int8). After we've collected all -> the visible alternatives, do resolution based on argument types the same -> way as we do now. -> -> The only alternative semantics that seem defensible at all are to stop -> at the first namespace that contains any matching-by-name op or func, -> and do resolution using only the candidates available in that namespace. -> That strikes me as not a good idea; for example, a user who defines a -> "+" operator in his own schema for his own datatype would be quite -> unhappy to find it masking all the "+" operators in the system schema. - -There is a third behavior which is almost the first one. And it's the one -I use for function matching in the package diffs I made oh so long ago. -:-) - -You look in the first namespace for all candidates. If one matches, you -use it. If two or more match, you throw the error we throw now. If none -match, you move on to the next namespace and repeat the search there. - -It's what the code does now. It's not that hard. It's just essentially -turning part of the function lookup into a for loop over the namespaces. -:-) - -It's easier than gathering everything as you only gather one namespace's -worth of matches at once. - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M18071=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 18:14:06 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NNE5U20779 - for ; Wed, 23 Jan 2002 18:14:06 -0500 (EST) -Received: (qmail 62072 invoked by alias); 23 Jan 2002 23:13:28 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 23:13:28 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0NMsEl57927 - for ; Wed, 23 Jan 2002 17:54:14 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 13221 invoked by uid 1130); 23 Jan 2002 22:54:16 -0000 -Date: Wed, 23 Jan 2002 14:49:32 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Tom Lane -cc: Zeugswetter Andreas SB SD , - Fernando Nasser , Peter Eisentraut , - -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <2677.1011800674@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 23 Jan 2002, Tom Lane wrote: - -> "Zeugswetter Andreas SB SD" writes: -> > When configured for historical behavior would need to: -> > 1. have search path: temp, any, system -> > 2. guard against duplicate table names across all schemas (except temp schema) -> -> This would be a *whole* lot simpler if we forgot the notion of "any" -> and made the search order look like -> -> (temp, private, public, system) -> -> where the public namespace is world-writable but the private per-user -> ones are (typically at least) not. -> -> It occurs to me that we can get both backward-compatible and SQL92 -> semantics with this same search path; the only thing that needs to -> be different in the two cases is whether the default place to create -> objects is your private schema or the public one. If you don't ever -> use your private schema then it doesn't matter if it's on the search -> path or not. I would still prefer that the search path be a settable -> option, since a paranoid person might well wish to not have public in -> his path at all ... but the default could be as-above. - -s/public/DEFAULT/ and add a way (createdb option) to make the default ACL -on DEFAULT such that anyone can create things and we are in agreement. - -One of the parts of the schema system I'd envisioned (and tried to make) -was that there would be an IMPLIMENTATION_SCHEMA which owned all -built-ins, and a DEFAULT schema which was owned by the superuser. Making -the default schema path for a schema -IMPLIMENTATION_SCHEMA::DEFAULT is fine. - -Making the default schema for creation settable to DEFAULT would be fine, -and I think would remove objection. :-) - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M18073=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 18:14:19 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NNEIU20817 - for ; Wed, 23 Jan 2002 18:14:18 -0500 (EST) -Received: (qmail 61956 invoked by alias); 23 Jan 2002 23:13:23 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 23:13:23 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0NN0Cl58411 - for ; Wed, 23 Jan 2002 18:00:12 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 14480 invoked by uid 1130); 23 Jan 2002 23:00:14 -0000 -Date: Wed, 23 Jan 2002 14:55:29 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Tom Lane -cc: Peter Eisentraut , -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <8747.1011821193@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 23 Jan 2002, Tom Lane wrote: - -> Bill Studenmund writes: -> > Either we're migrating an existing app, for which adding PATH directives -> > with a helper program before restore works, or we're making a new app. -> -> Sorry, I don't accept that either-or proposition. People will expect to -> be able to continue to use 7.3 as they have used Postgres in the past. -> Among other things that will mean being able to add new users to an -> existing installation. If we say "you can't do much of anything in 7.3 -> until you upgrade all your applications to schema-awareness", then we're -> going to have lots of unhappy users. - -"upgrad[ing] .. to schema-awareness" is adding the PATHs to the schema -creates. You then have a unified namespace (to the apps perspective). The -migration tool I mentioned should be able to do this (and will need to be -present). - -As PostgreSQL changes, people are going to have to learn to deal with new -features. I really don't think that dealing with schemas is going to be -that hard. Also, at Zembu, all of the apps we looked at had maybe two or -three schemas. These are big apps. If they can live with just a few -schemas, why do we need so many that maintainance is a pain? - -Also, what is this new user going to do *IN THE EXISTING APP*? Either the -user is going to change existing tables, for which adding the user to the -ACLs (or better yet to a group) will work, or the new user is going to own -new tables. If the new user is owning new tables, then you have to change -the app to refer to them. If the upgrade to 7.3 included a, "quick -tutorial about the new schema support," the author should be able to adapt -easily. - -> >> Fernando's "any" idea is probably a cleaner way to handle it if we -> >> wanted to do things like that. But I still think it'll be safer and -> >> more controllable if we provide a "public" namespace instead; see -> >> followup discussions. -> -> > Why? Why is it needed? What would public let you do that PATH and ACLs -> > wouldn't? -> -> Public gives you a place to put the ACL determining what people can do -> with publicly-visible names. See, eg, comments from Joe Conway. -> Without a specific public namespace to put ACLs on, a dbadmin has very -> little control over interuser interactions. Please note that the -> facility we are talking about offering here is not available in existing -> Postgres nor in SQL92, but that doesn't make it evil or unreasonable. - -I think the existance of a DEFAULT schema (which is a real schema, not a -special namespace) would also aleviate the above concerns. - -> Basically my point here is that the SQL spec is not the be-all and -> end-all of database development. (Have you read C. J. Date's commentary -> on it, for example?) We have a proven useful concept of object ownership -> in existing Postgres, and I see no need to remove that facility in -> pursuit of slavish adherence to a specification. If it were a project -> goal to rip out everything in Postgres that is not mentioned in the -> SQL spec, we could have a much smaller distribution ... with lots fewer -> users. - -I haven't read the comentary, do you have a URL? - -I agree that we should not limit ourselves to SQL'99. But doing more than -SQL'99 is different from wanting to support SQL schemas while using a -different ownership model, when one of the main things of SQL schemas as I -understand it is the ownership model. - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M18075=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 18:33:16 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0NNXGU21830 - for ; Wed, 23 Jan 2002 18:33:16 -0500 (EST) -Received: (qmail 68962 invoked by alias); 23 Jan 2002 23:33:14 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 23 Jan 2002 23:33:14 -0000 -Received: from megazone.bigpanda.com (megazone.bigpanda.com [63.150.15.178]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0NNUFl68439 - for ; Wed, 23 Jan 2002 18:30:15 -0500 (EST) - (envelope-from sszabo@megazone23.bigpanda.com) -Received: by megazone.bigpanda.com (Postfix, from userid 1001) - id 4D769D5F7; Wed, 23 Jan 2002 15:30:07 -0800 (PST) -Received: from localhost (localhost [127.0.0.1]) - by megazone.bigpanda.com (Postfix) with ESMTP - id 412425BF5; Wed, 23 Jan 2002 15:30:07 -0800 (PST) -Date: Wed, 23 Jan 2002 15:30:07 -0800 (PST) -From: Stephan Szabo -To: Bill Studenmund -cc: Tom Lane , Peter Eisentraut , - , Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -Message-ID: <20020123152711.I22382-100000@megazone23.bigpanda.com> -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 23 Jan 2002, Bill Studenmund wrote: - -> On Wed, 23 Jan 2002, Tom Lane wrote: -> -> There is a third behavior which is almost the first one. And it's the one -> I use for function matching in the package diffs I made oh so long ago. -> :-) -> -> You look in the first namespace for all candidates. If one matches, you -> use it. If two or more match, you throw the error we throw now. If none -> match, you move on to the next namespace and repeat the search there. - -That's even more strongly towards earlier namespaces than my suggestion. -How do you define match? If you allow coercions, then the -plus(int8, int8) in my schema would be prefered over better (possibly -exact) matches in the system schema which may not be what you want. - - - - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M18078=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 19:04:16 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0O04GU23131 - for ; Wed, 23 Jan 2002 19:04:16 -0500 (EST) -Received: (qmail 74730 invoked by alias); 24 Jan 2002 00:03:43 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 24 Jan 2002 00:03:43 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0NNqbl73179 - for ; Wed, 23 Jan 2002 18:52:37 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 20343 invoked by uid 1130); 23 Jan 2002 23:52:39 -0000 -Date: Wed, 23 Jan 2002 15:47:55 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Stephan Szabo -cc: Tom Lane , Peter Eisentraut , - , Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <20020123152711.I22382-100000@megazone23.bigpanda.com> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 23 Jan 2002, Stephan Szabo wrote: - -> On Wed, 23 Jan 2002, Bill Studenmund wrote: -> -> > On Wed, 23 Jan 2002, Tom Lane wrote: -> > -> > There is a third behavior which is almost the first one. And it's the one -> > I use for function matching in the package diffs I made oh so long ago. -> > :-) -> > -> > You look in the first namespace for all candidates. If one matches, you -> > use it. If two or more match, you throw the error we throw now. If none -> > match, you move on to the next namespace and repeat the search there. -> -> That's even more strongly towards earlier namespaces than my suggestion. -> How do you define match? If you allow coercions, then the -> plus(int8, int8) in my schema would be prefered over better (possibly -> exact) matches in the system schema which may not be what you want. - -True. But: - -1) How often are you going to make routines with names that duplicate -those in the system schema, when you don't want them to be used? - -2) you can always explicitly refer to the system schema, so you can get -the routine you want if it's not the one you'll get by coercion. - -3) We tested other (commercial) databases, and they have this behavior, so -it seems a reasonable thing to do. - -4) It's simple and easy to understand. - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18079=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 19:13:55 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0O0DsU23615 - for ; Wed, 23 Jan 2002 19:13:55 -0500 (EST) -Received: (qmail 79143 invoked by alias); 24 Jan 2002 00:13:37 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 24 Jan 2002 00:13:37 -0000 -Received: from megazone.bigpanda.com (megazone.bigpanda.com [63.150.15.178]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0O074l78013 - for ; Wed, 23 Jan 2002 19:07:04 -0500 (EST) - (envelope-from sszabo@megazone23.bigpanda.com) -Received: by megazone.bigpanda.com (Postfix, from userid 1001) - id 7D1CFD5F7; Wed, 23 Jan 2002 16:07:07 -0800 (PST) -Received: from localhost (localhost [127.0.0.1]) - by megazone.bigpanda.com (Postfix) with ESMTP - id 6EC505BF5; Wed, 23 Jan 2002 16:07:07 -0800 (PST) -Date: Wed, 23 Jan 2002 16:07:07 -0800 (PST) -From: Stephan Szabo -To: Bill Studenmund -cc: Tom Lane , Peter Eisentraut , - , Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -Message-ID: <20020123155603.Y22713-100000@megazone23.bigpanda.com> -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 23 Jan 2002, Bill Studenmund wrote: - -> On Wed, 23 Jan 2002, Stephan Szabo wrote: -> -> > On Wed, 23 Jan 2002, Bill Studenmund wrote: -> > -> > > On Wed, 23 Jan 2002, Tom Lane wrote: -> > > -> > > There is a third behavior which is almost the first one. And it's the one -> > > I use for function matching in the package diffs I made oh so long ago. -> > > :-) -> > > -> > > You look in the first namespace for all candidates. If one matches, you -> > > use it. If two or more match, you throw the error we throw now. If none -> > > match, you move on to the next namespace and repeat the search there. -> > -> > That's even more strongly towards earlier namespaces than my suggestion. -> > How do you define match? If you allow coercions, then the -> > plus(int8, int8) in my schema would be prefered over better (possibly -> > exact) matches in the system schema which may not be what you want. -> -> True. But: -> -> 1) How often are you going to make routines with names that duplicate -> those in the system schema, when you don't want them to be used? - -Sure, you want them used when the arguments match, but what about when -they don't exactly? -If the system schema has foo(integer) and in my schema I make a new type -and then make a type(integer) and foo(type), when I call foo(1), do I -really mean do a coersion to my type and call foo(type)? - - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M18082=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 19:33:21 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0O0XKU24428 - for ; Wed, 23 Jan 2002 19:33:21 -0500 (EST) -Received: (qmail 85643 invoked by alias); 24 Jan 2002 00:33:19 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 24 Jan 2002 00:33:19 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0O0N0l83366 - for ; Wed, 23 Jan 2002 19:23:00 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 24329 invoked by uid 1130); 24 Jan 2002 00:23:02 -0000 -Date: Wed, 23 Jan 2002 16:18:18 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Stephan Szabo -cc: Tom Lane , Peter Eisentraut , - , Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <20020123155603.Y22713-100000@megazone23.bigpanda.com> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 23 Jan 2002, Stephan Szabo wrote: - -> On Wed, 23 Jan 2002, Bill Studenmund wrote: -> -> > True. But: -> > -> > 1) How often are you going to make routines with names that duplicate -> > those in the system schema, when you don't want them to be used? -> -> Sure, you want them used when the arguments match, but what about when -> they don't exactly? -> If the system schema has foo(integer) and in my schema I make a new type -> and then make a type(integer) and foo(type), when I call foo(1), do I -> really mean do a coersion to my type and call foo(type)? - -Yes, you did. The documentation said that that would happen, so since you -made the call ambiguous, you wanted the coercion to happen. Or at least -you weren't concerned that it might. - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M18083=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 19:43:17 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0O0hGU24835 - for ; Wed, 23 Jan 2002 19:43:16 -0500 (EST) -Received: (qmail 88309 invoked by alias); 24 Jan 2002 00:43:14 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 24 Jan 2002 00:43:14 -0000 -Received: from megazone.bigpanda.com (megazone.bigpanda.com [63.150.15.178]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0O0YUl87134 - for ; Wed, 23 Jan 2002 19:34:30 -0500 (EST) - (envelope-from sszabo@megazone23.bigpanda.com) -Received: by megazone.bigpanda.com (Postfix, from userid 1001) - id 11552D5F8; Wed, 23 Jan 2002 16:34:33 -0800 (PST) -Received: from localhost (localhost [127.0.0.1]) - by megazone.bigpanda.com (Postfix) with ESMTP - id 050095BF5; Wed, 23 Jan 2002 16:34:33 -0800 (PST) -Date: Wed, 23 Jan 2002 16:34:32 -0800 (PST) -From: Stephan Szabo -To: Bill Studenmund -cc: Tom Lane , Peter Eisentraut , - , Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -Message-ID: <20020123162426.K22713-100000@megazone23.bigpanda.com> -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 23 Jan 2002, Bill Studenmund wrote: - -> On Wed, 23 Jan 2002, Stephan Szabo wrote: -> -> > On Wed, 23 Jan 2002, Bill Studenmund wrote: -> > -> > > True. But: -> > > -> > > 1) How often are you going to make routines with names that duplicate -> > > those in the system schema, when you don't want them to be used? -> > -> > Sure, you want them used when the arguments match, but what about when -> > they don't exactly? -> > If the system schema has foo(integer) and in my schema I make a new type -> > and then make a type(integer) and foo(type), when I call foo(1), do I -> > really mean do a coersion to my type and call foo(type)? -> -> Yes, you did. The documentation said that that would happen, so since you - -It doesn't currently say anything of the sort. If we made the above -behavior the standard, it would, but that's sort of circular. ;) Unless -I'm misreading the page Tom sent me to earlier, it seems to say it -prefers matches with exact types over coercions which would no longer be -true. - -> made the call ambiguous, you wanted the coercion to happen. Or at least -> you weren't concerned that it might. - -I still disagree. If I make a complex number type in my schema, -I don't really intend integer+integer to convert to complex and give me a -complex answer even if I want to be able to cast integers into complex. -AFAIK there's no way to specify that I want to make the function -complex(integer) such that I can do CAST(1 as complex) but not as an -implicit cast. - - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M18084=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 20:06:02 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0O161U25898 - for ; Wed, 23 Jan 2002 20:06:01 -0500 (EST) -Received: (qmail 91014 invoked by alias); 24 Jan 2002 01:05:59 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 24 Jan 2002 01:05:59 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0O0qTl89749 - for ; Wed, 23 Jan 2002 19:52:29 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 1144 invoked by uid 1130); 24 Jan 2002 00:52:32 -0000 -Date: Wed, 23 Jan 2002 16:47:48 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Stephan Szabo -cc: Tom Lane , Peter Eisentraut , - , Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <20020123162426.K22713-100000@megazone23.bigpanda.com> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 23 Jan 2002, Stephan Szabo wrote: - -> On Wed, 23 Jan 2002, Bill Studenmund wrote: -> -> > On Wed, 23 Jan 2002, Stephan Szabo wrote: -> > -> > Yes, you did. The documentation said that that would happen, so since you -> -> It doesn't currently say anything of the sort. If we made the above -> behavior the standard, it would, but that's sort of circular. ;) Unless -> I'm misreading the page Tom sent me to earlier, it seems to say it -> prefers matches with exact types over coercions which would no longer be -> true. - -The documentation says nothing about schemas at all now, so obviously it -has to change. :-) - -> > made the call ambiguous, you wanted the coercion to happen. Or at least -> > you weren't concerned that it might. -> -> I still disagree. If I make a complex number type in my schema, -> I don't really intend integer+integer to convert to complex and give me a -> complex answer even if I want to be able to cast integers into complex. -> AFAIK there's no way to specify that I want to make the function -> complex(integer) such that I can do CAST(1 as complex) but not as an -> implicit cast. - -Note: I've been talking about functions, and you're talking about -operators. While operators are syntactic sugar for functions, one big -difference is that you can't specify explicit schemas for operators (nor -do I think you should be able to). I think exact matches for operators -anywhere in the path would be better than local coercable ones. - -Does SQL'99 say anything about this? - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18086=candle.pha.pa.us=pgman@postgresql.org Wed Jan 23 20:25:47 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0O1PkU26965 - for ; Wed, 23 Jan 2002 20:25:47 -0500 (EST) -Received: (qmail 94892 invoked by alias); 24 Jan 2002 01:25:45 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 24 Jan 2002 01:25:45 -0000 -Received: from megazone.bigpanda.com (megazone.bigpanda.com [63.150.15.178]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0O1MNl94162 - for ; Wed, 23 Jan 2002 20:22:24 -0500 (EST) - (envelope-from sszabo@megazone23.bigpanda.com) -Received: by megazone.bigpanda.com (Postfix, from userid 1001) - id 5B37BD5F7; Wed, 23 Jan 2002 17:22:26 -0800 (PST) -Received: from localhost (localhost [127.0.0.1]) - by megazone.bigpanda.com (Postfix) with ESMTP - id 50EA45BF5; Wed, 23 Jan 2002 17:22:26 -0800 (PST) -Date: Wed, 23 Jan 2002 17:22:26 -0800 (PST) -From: Stephan Szabo -To: Bill Studenmund -cc: Tom Lane , Peter Eisentraut , - , Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -Message-ID: <20020123165321.K23306-100000@megazone23.bigpanda.com> -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 23 Jan 2002, Bill Studenmund wrote: - -What I was getting at was that Tom's behavior (or even mine) is more -similar to the currently described behavior than the suggested one. - -> > > made the call ambiguous, you wanted the coercion to happen. Or at least -> > > you weren't concerned that it might. -> > -> > I still disagree. If I make a complex number type in my schema, -> > I don't really intend integer+integer to convert to complex and give me a -> > complex answer even if I want to be able to cast integers into complex. -> > AFAIK there's no way to specify that I want to make the function -> > complex(integer) such that I can do CAST(1 as complex) but not as an -> > implicit cast. -> -> Note: I've been talking about functions, and you're talking about -> operators. While operators are syntactic sugar for functions, one big -> difference is that you can't specify explicit schemas for operators (nor -> do I think you should be able to). I think exact matches for operators -> anywhere in the path would be better than local coercable ones. - -I'd say the same thing for a random math function as well. For example -if there was a square(int) that returned $1*$1 and I made a square for my -complex type, I'd still expect that square(5) is an integer rather than a -complex using the square(complex). For example, I'd expect square(5) to -be a valid length argument to substr. - -> Does SQL'99 say anything about this? -That I don't know about (don't have a draft around to look at). I'm not -sure that it'd have these problems though unless it's got the same sort of -coercion system. - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18095=candle.pha.pa.us=pgman@postgresql.org Thu Jan 24 00:43:04 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0O5h4U15469 - for ; Thu, 24 Jan 2002 00:43:04 -0500 (EST) -Received: (qmail 28221 invoked by alias); 24 Jan 2002 05:43:00 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 24 Jan 2002 05:43:00 -0000 -Received: from student.gvsu.edu ([148.61.7.124]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0O5QCl26727 - for ; Thu, 24 Jan 2002 00:26:13 -0500 (EST) - (envelope-from peter_e@gmx.net) -Received: from [148.61.250.90] [148.61.250.90] by student.gvsu.edu - with Novonyx SMTP Server $Revision: 1.3 $; Thu, 24 Jan 2002 00:26:11 -0500 (EDT) -Date: Thu, 24 Jan 2002 00:28:16 -0500 (EST) -From: Peter Eisentraut -X-Sender: -To: Bill Studenmund -cc: Stephan Szabo , - Tom Lane , - PostgreSQL Development , - Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Bill Studenmund writes: - -> Does SQL'99 say anything about this? - -Yes, though, as usual, you have to twist your brain a little to understand -it. My understanding is that for a function call of the form "foo(a, b)" -it goes like this: - -1. Find all functions named "foo" in the current database. This is the -set of "possibly candidate routines". - -2. Drop all routines that you do not have EXECUTE privilege for. This is -the set of "executable routines". - -3. Drop all routines that do not have compatible parameter lists. This is -the set of "invocable routines". - -4. Drop all routines whose schema is not in the path. This is the set of -"candidate routines". - -5. If you have more than one routine left, eliminate some routines -according to type precedence rules. (We do some form of this, SQL99 -specifies something different.) This yields the set of "candidate subject -routines". - -6. Choose the routine whose schema is earliest in the path as the "subject -routine". - -Execute the subject routine. Phew! - - -This doesn't look glaringly wrong to me, so maybe you want to consider it. -Please note step 2. - --- -Peter Eisentraut peter_e@gmx.net - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18127=candle.pha.pa.us=pgman@postgresql.org Thu Jan 24 14:53:53 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0OJrqU16554 - for ; Thu, 24 Jan 2002 14:53:52 -0500 (EST) -Received: (qmail 59340 invoked by alias); 24 Jan 2002 19:53:33 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 24 Jan 2002 19:53:33 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0OJprl58616 - for ; Thu, 24 Jan 2002 14:51:53 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 22083 invoked by uid 1130); 24 Jan 2002 19:51:54 -0000 -Date: Thu, 24 Jan 2002 11:47:07 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Stephan Szabo -cc: Tom Lane , Peter Eisentraut , - , Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <20020123165321.K23306-100000@megazone23.bigpanda.com> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 23 Jan 2002, Stephan Szabo wrote: - -> On Wed, 23 Jan 2002, Bill Studenmund wrote: -> -> What I was getting at was that Tom's behavior (or even mine) is more -> similar to the currently described behavior than the suggested one. - -I understand. As part of developing the package changes, though, I found -that Oracle used the method I described for finding routines in packages. - ->From Peter's description, it sounds like Oracle's not following the spec. - -> I'd say the same thing for a random math function as well. For example -> if there was a square(int) that returned $1*$1 and I made a square for my -> complex type, I'd still expect that square(5) is an integer rather than a -> complex using the square(complex). For example, I'd expect square(5) to -> be a valid length argument to substr. - -Yeah, that makes sense. - -> > Does SQL'99 say anything about this? -> That I don't know about (don't have a draft around to look at). I'm not - -Do you want pdfs? - -> sure that it'd have these problems though unless it's got the same sort of -> coercion system. - -I don't think it has the same sort of coercion, but it has some, I'd -expect (as all of the DBs I know of have some sort of coercion :-) - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M18128=candle.pha.pa.us=pgman@postgresql.org Thu Jan 24 15:04:41 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0OK4eU18207 - for ; Thu, 24 Jan 2002 15:04:40 -0500 (EST) -Received: (qmail 65543 invoked by alias); 24 Jan 2002 20:03:53 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 24 Jan 2002 20:03:53 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0OJsul61073 - for ; Thu, 24 Jan 2002 14:54:57 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 23026 invoked by uid 1130); 24 Jan 2002 19:54:57 -0000 -Date: Thu, 24 Jan 2002 11:50:12 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Peter Eisentraut -cc: Stephan Szabo , - Tom Lane , - PostgreSQL Development , - Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Thu, 24 Jan 2002, Peter Eisentraut wrote: - -> Bill Studenmund writes: -> -> > Does SQL'99 say anything about this? -> -> Yes, though, as usual, you have to twist your brain a little to understand -> it. - -Indeed. I find the spec makes the most sense after you understand it. ;-) - -> My understanding is that for a function call of the form "foo(a, b)" -> it goes like this: -> -> 1. Find all functions named "foo" in the current database. This is the -> set of "possibly candidate routines". -> -> 2. Drop all routines that you do not have EXECUTE privilege for. This is -> the set of "executable routines". -> -> 3. Drop all routines that do not have compatible parameter lists. This is -> the set of "invocable routines". -> -> 4. Drop all routines whose schema is not in the path. This is the set of -> "candidate routines". -> -> 5. If you have more than one routine left, eliminate some routines -> according to type precedence rules. (We do some form of this, SQL99 -> specifies something different.) This yields the set of "candidate subject -> routines". -> -> 6. Choose the routine whose schema is earliest in the path as the "subject -> routine". -> -> Execute the subject routine. Phew! - -Wow. Thanks for diging this out. - -> This doesn't look glaringly wrong to me, so maybe you want to consider it. -> Please note step 2. - -It looks fine, and is probably what we should do. Well, I'd do things in a -different order (look only in in-path schemas first for instance), but -that's just trying to optimize the query. :-) - -How different are the type coercion rules? - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18156=candle.pha.pa.us=pgman@postgresql.org Thu Jan 24 22:45:56 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0P3jte02265 - for ; Thu, 24 Jan 2002 22:45:55 -0500 (EST) -Received: (qmail 95096 invoked by alias); 25 Jan 2002 03:45:50 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 03:45:50 -0000 -Received: from candle.pha.pa.us (216-55-132-35.dsl.san-diego.abac.net [216.55.132.35]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0P3NWl91448 - for ; Thu, 24 Jan 2002 22:23:33 -0500 (EST) - (envelope-from pgman@candle.pha.pa.us) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.11.6/8.10.1) id g0P3NMY22893; - Thu, 24 Jan 2002 22:23:22 -0500 (EST) -From: Bruce Momjian -Message-ID: <200201250323.g0P3NMY22893@candle.pha.pa.us> -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <2677.1011800674@sss.pgh.pa.us> -To: Tom Lane -Date: Thu, 24 Jan 2002 22:23:22 -0500 (EST) -cc: Zeugswetter Andreas SB SD , - Fernando Nasser , Peter Eisentraut , - pgsql-hackers@postgresql.org -X-Mailer: ELM [version 2.4ME+ PL96 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> "Zeugswetter Andreas SB SD" writes: -> > When configured for historical behavior would need to: -> > 1. have search path: temp, any, system -> > 2. guard against duplicate table names across all schemas (except temp schema) -> -> This would be a *whole* lot simpler if we forgot the notion of "any" -> and made the search order look like -> -> (temp, private, public, system) -> -> where the public namespace is world-writable but the private per-user -> ones are (typically at least) not. - -[ I am just reading this schema thread now.] - -The above private/public idea seems like a much better than 'any'. That -'any' thing had me quite confused and the idea thought you would have -duplicates that would only be found at runtime seems destined to random -falures. - -I assume 'private' above means search in my personal schema/namespace. - --- - Bruce Momjian | http://candle.pha.pa.us - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18157=candle.pha.pa.us=pgman@postgresql.org Thu Jan 24 22:45:56 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0P3jte02266 - for ; Thu, 24 Jan 2002 22:45:55 -0500 (EST) -Received: (qmail 95098 invoked by alias); 25 Jan 2002 03:45:50 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 03:45:50 -0000 -Received: from candle.pha.pa.us (216-55-132-35.dsl.san-diego.abac.net [216.55.132.35]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0P3Qql91635 - for ; Thu, 24 Jan 2002 22:26:52 -0500 (EST) - (envelope-from pgman@candle.pha.pa.us) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.11.6/8.10.1) id g0P3Qhw23061; - Thu, 24 Jan 2002 22:26:43 -0500 (EST) -From: Bruce Momjian -Message-ID: <200201250326.g0P3Qhw23061@candle.pha.pa.us> -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <2677.1011800674@sss.pgh.pa.us> -To: Tom Lane -Date: Thu, 24 Jan 2002 22:26:43 -0500 (EST) -cc: Zeugswetter Andreas SB SD , - Fernando Nasser , Peter Eisentraut , - pgsql-hackers@postgresql.org -X-Mailer: ELM [version 2.4ME+ PL96 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -> > Or are you thinking about a per session behavior ? -> > I would rather envision a per database behavior. -> > Maybe the easy way out would be a "default creation schema" property for -> > each user, that would default to the username. If you want everything in one -> > schema simply alter the users. -> -> I hadn't really gotten to the point of thinking about exactly what and -> where the control knobs should be. I suspect you are right that we will -> want the default behavior to be selectable on a per-user or per-database -> basis, which seems to eliminate the option of using GUC (at least in its -> current form). We could easily add a field to pg_shadow or pg_database -> respectively to determine the default behavior. It'd be nice though if -> the behavior could be changed after connection by a SET statement, which -> would be lots easier if the setting were GUC-controlled. Peter, you see -> any way to resolve that? - -I think we could set the database default at db creation time, then -allow SET to modify that default per session; seems flexible enough. -It is basically a GUC value who's default is stored in pg_database -rather than postgresql.conf. You could use postgresql.conf to set the -default schema type at db creation time. - --- - Bruce Momjian | http://candle.pha.pa.us - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18158=candle.pha.pa.us=pgman@postgresql.org Thu Jan 24 23:03:48 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0P43le13410 - for ; Thu, 24 Jan 2002 23:03:47 -0500 (EST) -Received: (qmail 97941 invoked by alias); 25 Jan 2002 04:03:42 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 04:03:42 -0000 -Received: from student.gvsu.edu ([148.61.7.124]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0P3wjl97273 - for ; Thu, 24 Jan 2002 22:58:46 -0500 (EST) - (envelope-from peter_e@gmx.net) -Received: from [148.61.250.128] [148.61.250.128] by student.gvsu.edu - with Novonyx SMTP Server $Revision: 1.3 $; Thu, 24 Jan 2002 22:58:51 -0500 (EDT) -Date: Thu, 24 Jan 2002 23:00:57 -0500 (EST) -From: Peter Eisentraut -X-Sender: -To: Tom Lane -cc: Zeugswetter Andreas SB SD , - Fernando Nasser , -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <2677.1011800674@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: ORr - -Tom Lane writes: - -> It'd be nice though if -> the behavior could be changed after connection by a SET statement, which -> would be lots easier if the setting were GUC-controlled. Peter, you see -> any way to resolve that? - -We had a text[] field to pg_shadow and/or pg_database containing -name=value assignments which are executed just before the session starts. -Doesn't look terribly difficult, and it's something I've always wanted to -do anyway. - --- -Peter Eisentraut peter_e@gmx.net - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18160=candle.pha.pa.us=pgman@postgresql.org Thu Jan 24 23:45:22 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0P4jLe11106 - for ; Thu, 24 Jan 2002 23:45:21 -0500 (EST) -Received: (qmail 3520 invoked by alias); 25 Jan 2002 04:43:35 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 04:43:35 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0P4OAl00294 - for ; Thu, 24 Jan 2002 23:24:11 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0P4Nef23267; - Thu, 24 Jan 2002 23:23:40 -0500 (EST) -To: Peter Eisentraut -cc: Zeugswetter Andreas SB SD , - Fernando Nasser , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -References: -Comments: In-reply-to Peter Eisentraut - message dated "Thu, 24 Jan 2002 23:00:57 -0500" -Date: Thu, 24 Jan 2002 23:23:39 -0500 -Message-ID: <23264.1011932619@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Peter Eisentraut writes: -> We [add] a text[] field to pg_shadow and/or pg_database containing -> name=value assignments which are executed just before the session starts. -> Doesn't look terribly difficult, and it's something I've always wanted to -> do anyway. - -Seems like a fine idea, with many uses besides this one. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M18159=candle.pha.pa.us=pgman@postgresql.org Thu Jan 24 23:33:32 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0P4XVe10435 - for ; Thu, 24 Jan 2002 23:33:31 -0500 (EST) -Received: (qmail 1069 invoked by alias); 25 Jan 2002 04:33:26 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 04:33:26 -0000 -Received: from linuxworld.com.au (www.linuxworld.com.au [203.34.46.50]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0P4Pal00372 - for ; Thu, 24 Jan 2002 23:25:36 -0500 (EST) - (envelope-from swm@linuxworld.com.au) -Received: from localhost (swm@localhost) - by linuxworld.com.au (8.11.4/8.11.4) with ESMTP id g0P4P5Z12976; - Fri, 25 Jan 2002 15:25:05 +1100 -Date: Fri, 25 Jan 2002 15:25:05 +1100 (EST) -From: Gavin Sherry -To: Tom Lane -cc: Bill Studenmund , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <8533.1011819436@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 23 Jan 2002, Tom Lane wrote: - -> If you use only the SQL-defined operations, after setting up any -> configuration variables we may invent in the way we will document as -> necessary for SQL-compatible behavior, then you will get SQL-compatible -> behavior. I do not think that precludes having an underlying -> implementation that sees the world differently than SQL does and -> supports non-SQL behaviors too. (For that matter, I'm sure there is -> text somewhere in the spec that points out that the spec intends to -> define user-visible behavior, not implementation.) - -This makes a lot of sense and suggests the possibility of 'schema enabled' -databases. That is, a switch 'bool withschemas' (which defaults to -false) could be added to pg_database. If true, the parser and ownership -model reflects that of SQL'99 and/or the Postgres schema model. If false, -the existing 'schema' model is assumed. - -This should allow existing users to migrate their data and applications to -7.3 without having to modify either. - -Its not an ideal solution but backward compatibility is generally results -in compromise ;). - -Gavin - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18164=candle.pha.pa.us=pgman@postgresql.org Thu Jan 24 23:45:36 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0P4jae11220 - for ; Thu, 24 Jan 2002 23:45:36 -0500 (EST) -Received: (qmail 4119 invoked by alias); 25 Jan 2002 04:43:57 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 04:43:57 -0000 -Received: from candle.pha.pa.us (216-55-132-35.dsl.san-diego.abac.net [216.55.132.35]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0P4Y0l01902 - for ; Thu, 24 Jan 2002 23:34:00 -0500 (EST) - (envelope-from pgman@candle.pha.pa.us) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.11.6/8.10.1) id g0P4XqD10470; - Thu, 24 Jan 2002 23:33:52 -0500 (EST) -From: Bruce Momjian -Message-ID: <200201250433.g0P4XqD10470@candle.pha.pa.us> -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -To: Peter Eisentraut -Date: Thu, 24 Jan 2002 23:33:52 -0500 (EST) -cc: Tom Lane , - Zeugswetter Andreas SB SD , - Fernando Nasser , pgsql-hackers@postgresql.org -X-Mailer: ELM [version 2.4ME+ PL96 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Peter Eisentraut wrote: -> Tom Lane writes: -> -> > It'd be nice though if -> > the behavior could be changed after connection by a SET statement, which -> > would be lots easier if the setting were GUC-controlled. Peter, you see -> > any way to resolve that? -> -> We had a text[] field to pg_shadow and/or pg_database containing -> name=value assignments which are executed just before the session starts. -> Doesn't look terribly difficult, and it's something I've always wanted to -> do anyway. - -So are thinking of "dbname=schema_type"? Seems this is really something -that should be in pg_database. If you create a database, who wants to -edit postgresql.conf to set its default schema type? Why not set the -GUC value from pg_database? - --- - Bruce Momjian | http://candle.pha.pa.us - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M18165=candle.pha.pa.us=pgman@postgresql.org Fri Jan 25 00:33:36 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0P5XZe14335 - for ; Fri, 25 Jan 2002 00:33:36 -0500 (EST) -Received: (qmail 15579 invoked by alias); 25 Jan 2002 05:33:30 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 05:33:30 -0000 -Received: from student.gvsu.edu ([148.61.7.124]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0P5Oul14811 - for ; Fri, 25 Jan 2002 00:24:56 -0500 (EST) - (envelope-from peter_e@gmx.net) -Received: from [148.61.250.128] [148.61.250.128] by student.gvsu.edu - with Novonyx SMTP Server $Revision: 1.3 $; Fri, 25 Jan 2002 00:25:01 -0500 (EDT) -Date: Fri, 25 Jan 2002 00:27:07 -0500 (EST) -From: Peter Eisentraut -X-Sender: -To: Tom Lane -cc: Bill Studenmund , -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <8842.1011822361@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane writes: - -> There could be multiple valid interpretations. When you can't even -> figure out where to start, it's too squishy for me. Code complexity -> isn't really the issue here, it's whether a user can understand what's -> going on. - -Here's a tricky question: In what situations is a.b valid to mean b(a)? -Because in a general object-like system you could write a.b.c.d to mean -d(c(b(a))). There you've got a system where it's really impossible to -tell anything. Maybe b() returns a table, so a.b.c.d could mean -subattribute d in column c in the table returned by b(a). - -Somehow we need to do at least one of three things: -1. Require parentheses after function calls. -2. Use a different operator to invoke function calls (SQL uses ->). -3. Require users to register functions as "methods" with the data type -before being able to say a.b for b(a). This also takes care of having to -specify the schema of b because that's declared when you define the -method. - -SQL99 does 2 and 3 (but not 1). - -I say, forget Oracle. Oracle doesn't have all the extensibility -functionality that PostgreSQL has. Let's build a system that is -consistent, orthogonal, and easy to use for *our* users, and those that -want to convert will quickly see the value. - --- -Peter Eisentraut peter_e@gmx.net - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18166=candle.pha.pa.us=pgman@postgresql.org Fri Jan 25 00:43:38 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0P5hce15000 - for ; Fri, 25 Jan 2002 00:43:38 -0500 (EST) -Received: (qmail 18028 invoked by alias); 25 Jan 2002 05:43:28 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 05:43:28 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0P5eol16732 - for ; Fri, 25 Jan 2002 00:40:50 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0P5eIf23724; - Fri, 25 Jan 2002 00:40:18 -0500 (EST) -To: Peter Eisentraut -cc: Bill Studenmund , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -References: -Comments: In-reply-to Peter Eisentraut - message dated "Fri, 25 Jan 2002 00:27:07 -0500" -Date: Fri, 25 Jan 2002 00:40:18 -0500 -Message-ID: <23721.1011937218@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Peter Eisentraut writes: -> Here's a tricky question: In what situations is a.b valid to mean b(a)? - -I defined that in my first message on these issues: the last element -of a dotted-name string can be either a field name or a function -(which is applied to a table that's the next-to-last item). The -next-to-last element is always a table name. - -> Because in a general object-like system you could write a.b.c.d to mean -> d(c(b(a))). - -Indeed, that can happen now in Postgres, and as I pointed out we have -to get rid of it. That doesn't mean we need to eliminate the base case, -however. - -> Somehow we need to do at least one of three things: -> 1. Require parentheses after function calls. - -Breaks existing code unnecessarily. - -> 2. Use a different operator to invoke function calls (SQL uses ->). - -Breaks existing code unnecessarily. - -> 3. Require users to register functions as "methods" with the data type -> before being able to say a.b for b(a). This also takes care of having to -> specify the schema of b because that's declared when you define the -> method. - -Doesn't buy you anything unless you intend to reject function -overloading too. With overloading you may have multiple functions -b(something), so you still have to be able to determine what a is -without any context. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M18168=candle.pha.pa.us=pgman@postgresql.org Fri Jan 25 01:13:24 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0P6DNe17080 - for ; Fri, 25 Jan 2002 01:13:23 -0500 (EST) -Received: (qmail 22750 invoked by alias); 25 Jan 2002 06:13:23 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 06:13:23 -0000 -Received: from candle.pha.pa.us (216-55-132-35.dsl.san-diego.abac.net [216.55.132.35]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0P5tdl21299 - for ; Fri, 25 Jan 2002 00:55:39 -0500 (EST) - (envelope-from pgman@candle.pha.pa.us) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.11.6/8.10.1) id g0P5tWY15824; - Fri, 25 Jan 2002 00:55:32 -0500 (EST) -From: Bruce Momjian -Message-ID: <200201250555.g0P5tWY15824@candle.pha.pa.us> -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -To: Peter Eisentraut -Date: Fri, 25 Jan 2002 00:55:32 -0500 (EST) -cc: Tom Lane , - Zeugswetter Andreas SB SD , - Fernando Nasser , pgsql-hackers@postgresql.org -X-Mailer: ELM [version 2.4ME+ PL96 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Peter Eisentraut wrote: -> Tom Lane writes: -> -> > It'd be nice though if -> > the behavior could be changed after connection by a SET statement, which -> > would be lots easier if the setting were GUC-controlled. Peter, you see -> > any way to resolve that? -> -> We had a text[] field to pg_shadow and/or pg_database containing -> name=value assignments which are executed just before the session starts. -> Doesn't look terribly difficult, and it's something I've always wanted to -> do anyway. - -Sorry, I see what you are saying now, that the name=value pairs would -set in pg_database and pg_shadow and get executed on session startup. -Very good. - --- - Bruce Momjian | http://candle.pha.pa.us - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18174=candle.pha.pa.us=pgman@postgresql.org Fri Jan 25 06:44:17 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0PBiGe20620 - for ; Fri, 25 Jan 2002 06:44:16 -0500 (EST) -Received: (qmail 92210 invoked by alias); 25 Jan 2002 11:43:41 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 11:43:41 -0000 -Received: from smxsat1.smxs.net (smxsat1.smxs.net [213.150.10.1]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0PBYsl90858 - for ; Fri, 25 Jan 2002 06:34:54 -0500 (EST) - (envelope-from ZeugswetterA@spardat.at) -Received: from m01x1.s-mxs.net [10.3.55.201] - by smxsat1.smxs.net - with XWall v3.18f ; - Fri, 25 Jan 2002 12:36:18 +0100 -Received: from m0102.s-mxs.net [10.3.55.2] - by m01x1.s-mxs.net - with XWall v3.18a ; - Fri, 25 Jan 2002 12:34:49 +0100 -Received: from m0114.s-mxs.net ([10.3.55.14]) by m0102.s-mxs.net with Microsoft SMTPSVC(5.0.2195.2966); - Fri, 25 Jan 2002 12:34:49 +0100 -X-MimeOLE: Produced By Microsoft Exchange V6.0.5762.3 -content-class: urn:content-classes:message -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -Date: Fri, 25 Jan 2002 12:34:48 +0100 -Message-ID: <46C15C39FEB2C44BA555E356FBCD6FA42128DD@m0114.s-mxs.net> -Thread-Topic: [HACKERS] RFD: schemas and different kinds of Postgres objects -Thread-Index: AcGkLuTMcnCfXPmkTji5zHYd6Vhu3QBZTo9w -From: "Zeugswetter Andreas SB SD" -To: "Joe Conway (wwc)" , "Tom Lane" -cc: "Fernando Nasser" , - "Peter Eisentraut" , -X-OriginalArrivalTime: 25 Jan 2002 11:34:49.0376 (UTC) FILETIME=[4C1C7200:01C1A594] -Content-Transfer-Encoding: 8bit -X-MIME-Autoconverted: from quoted-printable to 8bit by postgresql.org id g0PBh2m91415 -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: ORr - - -> Tom Lane wrote: -> -> > -> > This would be a *whole* lot simpler if we forgot the notion of "any" -> > and made the search order look like -> > -> > (temp, private, public, system) - -I am starting to see the advantages and like it. I also like the exact -name "public" for the public schema. - -Andreas - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M18195=candle.pha.pa.us=pgman@postgresql.org Fri Jan 25 12:18:20 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0PHIJe26232 - for ; Fri, 25 Jan 2002 12:18:19 -0500 (EST) -Received: (qmail 96791 invoked by alias); 25 Jan 2002 17:14:40 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 17:14:40 -0000 -Received: from candle.pha.pa.us (216-55-132-35.dsl.san-diego.abac.net [216.55.132.35]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0PGrXl88459 - for ; Fri, 25 Jan 2002 11:53:34 -0500 (EST) - (envelope-from pgman@candle.pha.pa.us) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.11.6/8.10.1) id g0PGq4L23522; - Fri, 25 Jan 2002 11:52:04 -0500 (EST) -From: Bruce Momjian -Message-ID: <200201251652.g0PGq4L23522@candle.pha.pa.us> -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <46C15C39FEB2C44BA555E356FBCD6FA42128DD@m0114.s-mxs.net> -To: Zeugswetter Andreas SB SD -Date: Fri, 25 Jan 2002 11:52:04 -0500 (EST) -cc: "Joe Conway (wwc)" , Tom Lane , - Fernando Nasser , Peter Eisentraut , - pgsql-hackers@postgresql.org -X-Mailer: ELM [version 2.4ME+ PL96 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Zeugswetter Andreas SB SD wrote: -> -> > Tom Lane wrote: -> > -> > > -> > > This would be a *whole* lot simpler if we forgot the notion of "any" -> > > and made the search order look like -> > > -> > > (temp, private, public, system) -> -> I am starting to see the advantages and like it. I also like the exact -> name "public" for the public schema. - -I wonder if we should think about a 'group' area so people in a group -can create things that others in the group can see, but not people -outside the group. - --- - Bruce Momjian | http://candle.pha.pa.us - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From tgl@sss.pgh.pa.us Fri Jan 25 12:04:14 2002 -Return-path: -Received: from sss.pgh.pa.us (root@[192.204.191.242]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g0PH4De25154 - for ; Fri, 25 Jan 2002 12:04:13 -0500 (EST) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0PH4Cf26410; - Fri, 25 Jan 2002 12:04:12 -0500 (EST) -To: Bruce Momjian -cc: Zeugswetter Andreas SB SD , - "Joe Conway (wwc)" , Fernando Nasser , - Peter Eisentraut , pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <200201251652.g0PGq4L23522@candle.pha.pa.us> -References: <200201251652.g0PGq4L23522@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Fri, 25 Jan 2002 11:52:04 -0500" -Date: Fri, 25 Jan 2002 12:04:12 -0500 -Message-ID: <26407.1011978252@sss.pgh.pa.us> -From: Tom Lane -Status: OR - -Bruce Momjian writes: ->> I am starting to see the advantages and like it. I also like the exact ->> name "public" for the public schema. - -> I wonder if we should think about a 'group' area so people in a group -> can create things that others in the group can see, but not people -> outside the group. - -I see no reason to hard-wire such a concept. Given createable -namespaces, ACLs for namespaces, and a settable namespace search path, -people can set up group namespaces or anything else they want. - -The (temp, private, public, system) path is suggested as default because -it's the minimum we need to support both SQL92 and backwards-compatible -behaviors. I don't think we should put in special-purpose features -beyond that, when we can instead offer a general mechanism with which -people can build the special-purpose features they want. - - regards, tom lane - -From pgsql-hackers-owner+M18209=candle.pha.pa.us=pgman@postgresql.org Fri Jan 25 16:14:02 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0PLE1e19183 - for ; Fri, 25 Jan 2002 16:14:01 -0500 (EST) -Received: (qmail 85059 invoked by alias); 25 Jan 2002 21:13:58 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 21:13:58 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0PKtNl77878 - for ; Fri, 25 Jan 2002 15:55:23 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 10628 invoked by uid 1130); 25 Jan 2002 20:55:14 -0000 -Date: Fri, 25 Jan 2002 12:50:26 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Gavin Sherry -cc: Tom Lane , -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Fri, 25 Jan 2002, Gavin Sherry wrote: - -> This makes a lot of sense and suggests the possibility of 'schema enabled' -> databases. That is, a switch 'bool withschemas' (which defaults to -> false) could be added to pg_database. If true, the parser and ownership -> model reflects that of SQL'99 and/or the Postgres schema model. If false, -> the existing 'schema' model is assumed. -> -> This should allow existing users to migrate their data and applications to -> 7.3 without having to modify either. -> -> Its not an ideal solution but backward compatibility is generally results -> in compromise ;). - -I guess my frustration with this idea is that we don't really need it. We -can achieve the same global namespace for an old app without it. All we -need is a tool which turns old dumps into new ones (which we probably need -anyway) that merges all of the schemas together w/ PATH statements. Or -maybe (new idea) a tool which looks at the schemas in a DB and updates -their PATHs so they act unified. - -We can achieve the old behavior w/o having to build it into the backend. -So why add code to the backend when we don't have to? Among other things, -it would complicate the system schema as we'd have to keep track of -ownership values we wouldn't otherwise need to. - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From ZeugswetterA@spardat.at Fri Jan 25 16:36:49 2002 -Return-path: -Received: from smxsat1.smxs.net (smxsat1.smxs.net [213.150.10.1]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g0PLame20819 - for ; Fri, 25 Jan 2002 16:36:48 -0500 (EST) -Received: from m01x1.s-mxs.net [10.3.55.201] - by smxsat1.smxs.net - with XWall v3.18f ; - Fri, 25 Jan 2002 22:38:07 +0100 -Received: from m0102.s-mxs.net [10.3.55.2] - by m01x1.s-mxs.net - with XWall v3.18a ; - Fri, 25 Jan 2002 22:36:38 +0100 -Received: from m0114.s-mxs.net ([10.3.55.14]) by m0102.s-mxs.net with Microsoft SMTPSVC(5.0.2195.2966); - Fri, 25 Jan 2002 22:36:38 +0100 -X-MimeOLE: Produced By Microsoft Exchange V6.0.5762.3 -content-class: urn:content-classes:message -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Subject: RE: [HACKERS] RFD: schemas and different kinds of Postgres objects -Date: Fri, 25 Jan 2002 22:36:37 +0100 -Message-ID: <46C15C39FEB2C44BA555E356FBCD6FA42128E0@m0114.s-mxs.net> -Thread-Topic: [HACKERS] RFD: schemas and different kinds of Postgres objects -Thread-Index: AcGlwKXMNIw3BiZ7R4G6MaOhn/ahAgAJ0maA -From: "Zeugswetter Andreas SB SD" -To: "Bruce Momjian" -cc: "Joe Conway (wwc)" , "Tom Lane" , - "Fernando Nasser" , - "Peter Eisentraut" , -X-OriginalArrivalTime: 25 Jan 2002 21:36:38.0285 (UTC) FILETIME=[5EB2B3D0:01C1A5E8] -Content-Transfer-Encoding: 8bit -X-MIME-Autoconverted: from quoted-printable to 8bit by candle.pha.pa.us id g0PLame20819 -Status: OR - - -> > I am starting to see the advantages and like it. I also like the exact -> > name "public" for the public schema. -> -> I wonder if we should think about a 'group' area so people in a group -> can create things that others in the group can see, but not people -> outside the group. - -A group simply chooses a special schema name for their group. - -Maybe an extra in the ACL area so you can grant privs for a whole -schema. - -grant select on schema blabla to "JoeLuser" - -Andreas - -From wrstuden@netbsd.org Fri Jan 25 17:12:51 2002 -Return-path: -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0PMCoe23588 - for ; Fri, 25 Jan 2002 17:12:51 -0500 (EST) -Received: (qmail 20909 invoked by uid 1130); 25 Jan 2002 22:12:46 -0000 -Date: Fri, 25 Jan 2002 14:07:58 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Bruce Momjian -cc: Tom Lane , - Zeugswetter Andreas SB SD , - Fernando Nasser , Peter Eisentraut , - -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <200201250326.g0P3Qhw23061@candle.pha.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Status: OR - -On Thu, 24 Jan 2002, Bruce Momjian wrote: - -> I think we could set the database default at db creation time, then -> allow SET to modify that default per session; seems flexible enough. -> It is basically a GUC value who's default is stored in pg_database -> rather than postgresql.conf. You could use postgresql.conf to set the -> default schema type at db creation time. - -Specifically to the question of schema pathing, why would you want it to -be session-settable? Either your DB app is designed to work w/ schemas, or -it isn't. That's a pretty fundamental design concept. Given that, I don't -see how it can make sense to try to operate in the opposite mode as the -app was designed for - that'll only lead to chaos. - -Take care, - -Bill - - -From tgl@sss.pgh.pa.us Fri Jan 25 17:26:17 2002 -Return-path: -Received: from sss.pgh.pa.us (root@[192.204.191.242]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g0PMQGe24836 - for ; Fri, 25 Jan 2002 17:26:16 -0500 (EST) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0PMQEf07711; - Fri, 25 Jan 2002 17:26:14 -0500 (EST) -To: Bill Studenmund -cc: Bruce Momjian , - Zeugswetter Andreas SB SD , - Fernando Nasser , Peter Eisentraut , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -References: -Comments: In-reply-to Bill Studenmund - message dated "Fri, 25 Jan 2002 14:07:58 -0800" -Date: Fri, 25 Jan 2002 17:26:14 -0500 -Message-ID: <7708.1011997574@sss.pgh.pa.us> -From: Tom Lane -Status: OR - -Bill Studenmund writes: -> Specifically to the question of schema pathing, why would you want it to -> be session-settable? Either your DB app is designed to work w/ schemas, or -> it isn't. - -So that you can set the correct mode for your client application. It is -silly to suppose that an installation-wide or even database-wide setting -is sufficient. Consider for example a database shared by multiple -pieces of client software; wouldn't you like to be able to upgrade them -to schema-awareness one at a time? - -You could possibly make a case for a single setting per user, but even -that makes an assumption (user == client software) that I think is not -reasonable for us to force on all Postgres installations. - -Basically I haven't got a lot of patience for arguments that say we do -not need flexibility. There are more people out there, using Postgres -in more different ways, than either you or I know about. - - regards, tom lane - -From pgsql-hackers-owner+M18216=candle.pha.pa.us=pgman@postgresql.org Fri Jan 25 18:54:34 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0PNsXe02286 - for ; Fri, 25 Jan 2002 18:54:34 -0500 (EST) -Received: (qmail 18323 invoked by alias); 25 Jan 2002 23:53:56 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 25 Jan 2002 23:53:56 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0PNk1l17143 - for ; Fri, 25 Jan 2002 18:46:02 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 23281 invoked by uid 1130); 25 Jan 2002 23:46:04 -0000 -Date: Fri, 25 Jan 2002 15:41:16 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Tom Lane -cc: Bruce Momjian , - Zeugswetter Andreas SB SD , - Fernando Nasser , Peter Eisentraut , - -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <7708.1011997574@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Fri, 25 Jan 2002, Tom Lane wrote: - -> Bill Studenmund writes: -> > Specifically to the question of schema pathing, why would you want it to -> > be session-settable? Either your DB app is designed to work w/ schemas, or -> > it isn't. -> -> So that you can set the correct mode for your client application. It is -> silly to suppose that an installation-wide or even database-wide setting -> is sufficient. Consider for example a database shared by multiple -> pieces of client software; wouldn't you like to be able to upgrade them -> to schema-awareness one at a time? - -What exactly does it mean to upgrade to schema-awareness? I know the jist -of what you mean, but what does it entail? What steps? I ask as, when I -think of what it means in practical steps, an upgraded app won't have -problems with extra stuff pathed in. So the upgraded app will be fine with -the pathing set up to include all (not-upgraded) schemas. Also, if it does -have a problem with stuff pathed in, since you can easily set the new apps -up to live in different schemas than the old ones, you can have upgraded & -from-before schemas. - -> You could possibly make a case for a single setting per user, but even -> that makes an assumption (user == client software) that I think is not -> reasonable for us to force on all Postgres installations. - -But we will have the ability to set the path per schema. Since -schema-aware apps should be able to choose which schema they connect to (I -envision it being a connect parameter), the different apps can implicitly -get different behaviors by connecting to schemas that are designed to be -schema-savy, or connecting to ones which aren't (i.e. have all of the -schema-unaware stuff pathed in). - -> Basically I haven't got a lot of patience for arguments that say we do -> not need flexibility. There are more people out there, using Postgres -> in more different ways, than either you or I know about. - -Tom, please listen to what I'm saying. I'm trying to be as clear as I can -& making sure I'm not working from details in my head and not my posts. -I'm sorry if it isn't clear but I'm _not_ saying that we don't need the -flexability you describe. We do. - -I'm saying that IT IS ALREADY THERE! The pathing built into schemas can be -very powerful. Powerful enough that I haven't heard of an example yet that -can't be taken care of with judicious use of pathing. And I don't think -the pathing needed is beyond mid-level admins (I don't see it as something -which only say 5 people on the lists can get right). Yes, people will have -to learn it, but it doesn't strike me as that hard a thing. - -What I am saying is that we don't need the solution you & Bruce mentioned -to get the flexability you mentioned as the reason for adding it. So why -add the feature which isn't needed? - -One of my objections to a "mode" supporting the old behavior is that, as I -understand it, there would be a schema ("public") where different users -could own objects in the same schema. That goes against one of the -advantages I see for schemas: we can consolidate ownership info in the -system tables. If you know what schema something is in, you know its -owner. That means that adding schema support doesn't mean growing system -tables, just renaming a column (the user id gets turned into the schema -id). - -Maybe that's not such a big deal. But it seems when we're doing things -right, things should get cleaner. Having to keep ownership info at both -the schema level and at the object level strikes me as not making things -cleaner. That just seems to be going in the wrong direction. - -Especially as, AFAICT, it wouldn't be hard to let the sysadmins have all -the flexability you want them to have (and also that I agree they should -have) in a system which is, at its core, very schema-savy (everything in -one schema is owned by the same user or group). - -I also agree that migration is important. Apps from 7.2 (and 7.1 and -earlier as possible) should run on the schema-savy backend I describe. A -migration tool to take the dump from before and add update schema commands -to path everything in (so it looks like one namespace) should make the old -apps keep working. - -The one thing I'll concede could be useful would be for createuser to be -told to automatically set the new user's schema to include all the other -schemas, and to update all the other user schemas to add this user. That -way you can add new users to your DB when you're acting as if it didn't -have schemas. - -Hmmm. If we made the above behavior a per-db-configurable default, the -pg_dump file wouldn't need to be changed. That would be good. It would -make the path updates O(nusers^2) rather than O(nusers), but that probably -won't be bad. And offering both options would probably be good. - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From tgl@sss.pgh.pa.us Fri Jan 25 19:04:17 2002 -Return-path: -Received: from sss.pgh.pa.us (root@[192.204.191.242]) - by candle.pha.pa.us (8.11.6/8.10.1) with ESMTP id g0Q04Ge02926 - for ; Fri, 25 Jan 2002 19:04:17 -0500 (EST) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0Q04Ff08236; - Fri, 25 Jan 2002 19:04:16 -0500 (EST) -To: Bill Studenmund -cc: Bruce Momjian , - Zeugswetter Andreas SB SD , - Fernando Nasser , Peter Eisentraut , - pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: -References: -Comments: In-reply-to Bill Studenmund - message dated "Fri, 25 Jan 2002 15:41:16 -0800" -Date: Fri, 25 Jan 2002 19:04:15 -0500 -Message-ID: <8233.1012003455@sss.pgh.pa.us> -From: Tom Lane -Status: OR - -Bill Studenmund writes: -> But we will have the ability to set the path per schema. - -?? I don't follow that at all. A namespace is something that's referred -to by a search path, not vice versa. Or are you defining "schema" to -mean some higher-level concept that incorporates a search path of -multiple primitive namespaces? Maybe that could work, but I'm not sure -I see the point yet. - - regards, tom lane - -From wrstuden@netbsd.org Fri Jan 25 20:39:59 2002 -Return-path: -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0Q1dve10731 - for ; Fri, 25 Jan 2002 20:39:58 -0500 (EST) -Received: (qmail 27927 invoked by uid 1130); 26 Jan 2002 01:39:59 -0000 -Date: Fri, 25 Jan 2002 17:35:11 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Tom Lane -cc: Bruce Momjian , - Zeugswetter Andreas SB SD , - Fernando Nasser , Peter Eisentraut , - -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <8233.1012003455@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Status: OR - -On Fri, 25 Jan 2002, Tom Lane wrote: - -> Bill Studenmund writes: -> > But we will have the ability to set the path per schema. -> -> ?? I don't follow that at all. A namespace is something that's referred -> to by a search path, not vice versa. Or are you defining "schema" to -> mean some higher-level concept that incorporates a search path of -> multiple primitive namespaces? Maybe that could work, but I'm not sure -> I see the point yet. - -Oh. That would make a difference. We've been talking past each other. - -SQL schemas, as I understand the spec, are both. A shema is a container -that holds things like tables and views and functions (and for PostgreSQL -operators and aggregates and I'd suggest index operators, etc.). It also -can include a schema path specification, which defines the search path -used by routines (stored procedures & functions) contained in that schema. - -So say I have schemas foo, bar, and baz. I can set the schema path for -schema bar to be foo:bar:baz:IMPLIMENTATION_SCHEMA, and all routines in -bar will look in those four schemas for types, functions and tables (and -everything else we use the search path for). - -(*) IMPLIMENTATION_SCHEMA is required by the spec, and contains all the -built-ins. It's be implimentation_schema for pg. Also, if you have a path -that doesn't list it, the db is supposed to prepend it to the list. - -So when migrating an app from a schema-unaware PostgreSQL to a -schema-aware one, if we create a schema for each user, and make each -such schema path in all the other such schemas, we make it such that all -of the procedures in those schemas act like they have a unified namespace. - -There also is also the concept of the CURRENT_PATH which is the schema -path used for parsed queries (like ones typed into psql). I got lost in -the spec trying to find what this is supposed to default to, but what I -understand other DBs to do is your CURRENT_PATH is set to the path of the -schema you log into. - -Add to this mix the default schema for user X is schema X (which I thought -was in the spec but I can't find now), and let's look at that example -again. - -Say we had users foo, bar and baz before. We made schemas foo, bar, and -baz. We set the default paths for each of these schemas to -foo:bar:baz:IMPLIMENTATION_SCHEMA. Now the routines in each of these -schemas will see a unified namespace. Next, when we log in as users foo, -bar, or baz, and our CURRENT_PATH ends up including the namespaces of the -three original users. So now all of our submitted queries also see a -unified namespace. - -So with a schema-savy backend, by adding PATH statements to the schemas -that pull in all of the previous schemas, we can make the old app behave -as if it had a unified namespace. - -Does that make sense? - -Take care, - -Bill - -P.S. does anyone need copies of the spec? I found pdf's on the web a while -back.. - - -From pgsql-hackers-owner+M18221=candle.pha.pa.us=pgman@postgresql.org Fri Jan 25 22:13:58 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0Q3Dwe17302 - for ; Fri, 25 Jan 2002 22:13:58 -0500 (EST) -Received: (qmail 42344 invoked by alias); 26 Jan 2002 03:13:55 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 26 Jan 2002 03:13:55 -0000 -Received: from golem.fourpalms.org (golem.fourpalms.org [64.3.68.148]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0Q35hl41629 - for ; Fri, 25 Jan 2002 22:05:43 -0500 (EST) - (envelope-from lockhart@fourpalms.org) -Received: from fourpalms.org (localhost.localdomain [127.0.0.1]) - by golem.fourpalms.org (Postfix) with ESMTP - id 0336CFEC5; Sat, 26 Jan 2002 03:05:45 +0000 (UTC) -Message-ID: <3C521D08.9138E2EA@fourpalms.org> -Date: Sat, 26 Jan 2002 03:05:44 +0000 -From: Thomas Lockhart -Reply-To: lockhart@fourpalms.org -Organization: Yes -X-Mailer: Mozilla 4.75 [en] (X11; U; Linux 2.2.17-21mdksmp i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Tom Lane -cc: Stephan Szabo , - Peter Eisentraut , pgsql-hackers@postgresql.org, - Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: <20020123083152.W18169-100000@megazone23.bigpanda.com> <3159.1011804418@sss.pgh.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -... -> > Wouldn't it make sense to prefer operators/functions earlier in the search -> > path for resolving ambiguity. So if you had plus(int4, int4) in my -> > schema and plus(int8, int8) in system, and they'd otherwise cause an -> > ambiguity failure for the query, use the plus(int4, int4) on mine. It -> > seems not too far from having the search path shadow later exact matches. -> Given the complexity of the resolution rules (cf. -> http://developer.postgresql.org/docs/postgres/typeconv.html), -> it's not clear that we can determine exactly which "later" entry ought -> to be blamed for causing a resolution failure. I'd be interested to -> hear Lockhart's opinion on this --- but my gut feeling is we don't -> want to go there. The resolution rules are already complicated enough, -> and I think layering an additional mechanism like that onto them might -> make the behavior totally unpredictable. - -(I've been following the discussion; I suspect that this part may -already have an obvious answer since "any" scoping -- equivalent to -flattening the namespace? -- may now be out of favor; I'm assuming that -we have a clearly scoped lookup scheme available). - -imho there is nothing fundamentally difficult or "unpredictable" about -layering schema lookup on to the existing function resolution rules. One -might want a bit better diagnostics about *which* function was actually -chosen, but reasonable scoping and lookup rules could be constructed -which give reasonable behavior with the addition of schemas. - -For example, the current function resolution rules prefer an exact -match, then start looking for approximate matches, and narrow that down -to preferring the one with the best explicit match on data types. If -more than one matches, then it rejects the query. (I've left out one or -two steps, but on the whole this is the behavior that matters.) - -With schemas, one could choose to use "closest schema" as the tiebreaker -for multiple matches, but istm that an exact match should always win. - -We might want to include a mechanism that *blocks* schema lookups deeper -into the search path, to allow reliable *complete replacement* of a -function. This would be a property of the function, to be set when it is -defined in the schema. So an implementer could choose to restrict -lookups explicitly if that is deemed necessary. Again, this is not a -huge complication. - -It is an interesting discussion, and the fine points will not be brought -out without having lots of back-and-forth, which seems to be happening -already ;) - - - Thomas - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18236=candle.pha.pa.us=pgman@postgresql.org Sun Jan 27 20:44:07 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0S1i6e21103 - for ; Sun, 27 Jan 2002 20:44:06 -0500 (EST) -Received: (qmail 86523 invoked by alias); 28 Jan 2002 01:44:01 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 28 Jan 2002 01:44:01 -0000 -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0S1X4l84668 - for ; Sun, 27 Jan 2002 20:33:04 -0500 (EST) - (envelope-from Inoue@tpf.co.jp) -Received: (qmail 4010 invoked from network); 28 Jan 2002 01:33:07 -0000 -Received: from unknown (HELO viscomail.tpf.co.jp) (100.0.0.108) - by sd2.tpf-fw-c.co.jp with SMTP; 28 Jan 2002 01:33:07 -0000 -Received: from tpf.co.jp (3dgateway1 [126.0.1.60]) - by viscomail.tpf.co.jp (8.8.8+Sun/8.8.8) with ESMTP id KAA05318; - Mon, 28 Jan 2002 10:33:04 +0900 (JST) -Message-ID: <3C54AA51.64CE68AD@tpf.co.jp> -Date: Mon, 28 Jan 2002 10:33:05 +0900 -From: Hiroshi Inoue -X-Mailer: Mozilla 4.73 [ja] (Windows NT 5.0; U) -X-Accept-Language: ja -MIME-Version: 1.0 -To: Peter Eisentraut , Tom Lane -cc: Bill Studenmund , - Stephan Szabo , - PostgreSQL Development , - Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: -Content-Type: text/plain; charset=iso-2022-jp -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Is *the path* below the same as "search path* in other -postings about this thread ? - -Maybe Peter's posting isn't the one exactly what I have to -ask but there are too many postings for me to follow. - -regards, -Hiroshi Inoue - -Peter Eisentraut wrote: -> -> Bill Studenmund writes: -> -> > Does SQL'99 say anything about this? -> -> Yes, though, as usual, you have to twist your brain a little to understand -> it. My understanding is that for a function call of the form "foo(a, b)" -> it goes like this: -> -> 1. Find all functions named "foo" in the current database. This is the -> set of "possibly candidate routines". -> -> 2. Drop all routines that you do not have EXECUTE privilege for. This is -> the set of "executable routines". -> -> 3. Drop all routines that do not have compatible parameter lists. This is -> the set of "invocable routines". -> -> 4. Drop all routines whose schema is not in the path. This is the set of -> "candidate routines". -> -> 5. If you have more than one routine left, eliminate some routines -> according to type precedence rules. (We do some form of this, SQL99 -> specifies something different.) This yields the set of "candidate subject -> routines". -> -> 6. Choose the routine whose schema is earliest in the path as the "subject -> routine". -> -> Execute the subject routine. Phew! -> -> This doesn't look glaringly wrong to me, so maybe you want to consider it. -> Please note step 2. -> -> -- -> Peter Eisentraut peter_e@gmx.net - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M18249=candle.pha.pa.us=pgman@postgresql.org Mon Jan 28 19:34:59 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0T0Ywe04781 - for ; Mon, 28 Jan 2002 19:34:58 -0500 (EST) -Received: (qmail 99270 invoked by alias); 29 Jan 2002 00:34:49 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 29 Jan 2002 00:34:49 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0T0WDl98697 - for ; Mon, 28 Jan 2002 19:32:13 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 26513 invoked by uid 1130); 29 Jan 2002 00:31:57 -0000 -Date: Mon, 28 Jan 2002 16:27:04 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Hiroshi Inoue -cc: Peter Eisentraut , Tom Lane , - Stephan Szabo , - PostgreSQL Development , - Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <3C54AA51.64CE68AD@tpf.co.jp> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Mon, 28 Jan 2002, Hiroshi Inoue wrote: - -> Is *the path* below the same as "search path* in other -> postings about this thread ? - -I think so. I believe the path I've been talking about is the one in step -6 below. - -Take care, - -Bill - -> Maybe Peter's posting isn't the one exactly what I have to -> ask but there are too many postings for me to follow. -> -> regards, -> Hiroshi Inoue -> -> Peter Eisentraut wrote: -> > -> > Bill Studenmund writes: -> > -> > > Does SQL'99 say anything about this? -> > -> > Yes, though, as usual, you have to twist your brain a little to understand -> > it. My understanding is that for a function call of the form "foo(a, b)" -> > it goes like this: -> > -> > 1. Find all functions named "foo" in the current database. This is the -> > set of "possibly candidate routines". -> > -> > 2. Drop all routines that you do not have EXECUTE privilege for. This is -> > the set of "executable routines". -> > -> > 3. Drop all routines that do not have compatible parameter lists. This is -> > the set of "invocable routines". -> > -> > 4. Drop all routines whose schema is not in the path. This is the set of -> > "candidate routines". -> > -> > 5. If you have more than one routine left, eliminate some routines -> > according to type precedence rules. (We do some form of this, SQL99 -> > specifies something different.) This yields the set of "candidate subject -> > routines". -> > -> > 6. Choose the routine whose schema is earliest in the path as the "subject -> > routine". -> > -> > Execute the subject routine. Phew! -> > -> > This doesn't look glaringly wrong to me, so maybe you want to consider it. -> > Please note step 2. -> > -> > -- -> > Peter Eisentraut peter_e@gmx.net -> - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18257=candle.pha.pa.us=pgman@postgresql.org Tue Jan 29 01:14:41 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0T6Eee16404 - for ; Tue, 29 Jan 2002 01:14:40 -0500 (EST) -Received: (qmail 64203 invoked by alias); 29 Jan 2002 06:14:43 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 29 Jan 2002 06:14:43 -0000 -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0T5lJl60013 - for ; Tue, 29 Jan 2002 00:47:20 -0500 (EST) - (envelope-from Inoue@tpf.co.jp) -Received: (qmail 19665 invoked from network); 29 Jan 2002 05:47:24 -0000 -Received: from unknown (HELO viscomail.tpf.co.jp) (100.0.0.108) - by sd2.tpf-fw-c.co.jp with SMTP; 29 Jan 2002 05:47:24 -0000 -Received: from tpf.co.jp (3dgateway1 [126.0.1.60]) - by viscomail.tpf.co.jp (8.8.8+Sun/8.8.8) with ESMTP id OAA07250; - Tue, 29 Jan 2002 14:47:22 +0900 (JST) -Message-ID: <3C56376C.BCA5B3A5@tpf.co.jp> -Date: Tue, 29 Jan 2002 14:47:24 +0900 -From: Hiroshi Inoue -X-Mailer: Mozilla 4.73 [ja] (Windows NT 5.0; U) -X-Accept-Language: ja -MIME-Version: 1.0 -To: Bill Studenmund -cc: Peter Eisentraut , Tom Lane , - Stephan Szabo , - PostgreSQL Development , - Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: -Content-Type: text/plain; charset=iso-2022-jp -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Bill Studenmund wrote: -> -> On Mon, 28 Jan 2002, Hiroshi Inoue wrote: -> -> > Is *the path* below the same as "search path* in other -> > postings about this thread ? -> -> I think so. I believe the path I've been talking about is the one in step -> 6 below. - -What I can find in SQL99 is SQL-path. -Does *the path*(i.e search path) mean SQL-path ? -They don't seem the same to me. - -regards, -Hiroshi Inoue - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M18271=candle.pha.pa.us=pgman@postgresql.org Tue Jan 29 12:55:04 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0THt2P00626 - for ; Tue, 29 Jan 2002 12:55:02 -0500 (EST) -Received: (qmail 77793 invoked by alias); 29 Jan 2002 17:54:57 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 29 Jan 2002 17:54:57 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0THmBl76965 - for ; Tue, 29 Jan 2002 12:48:11 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 23554 invoked by uid 1130); 29 Jan 2002 17:48:16 -0000 -Date: Tue, 29 Jan 2002 09:43:22 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Hiroshi Inoue -cc: Peter Eisentraut , Tom Lane , - Stephan Szabo , - PostgreSQL Development , - Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <3C56376C.BCA5B3A5@tpf.co.jp> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Tue, 29 Jan 2002, Hiroshi Inoue wrote: - -> Bill Studenmund wrote: -> > -> > On Mon, 28 Jan 2002, Hiroshi Inoue wrote: -> > -> > > Is *the path* below the same as "search path* in other -> > > postings about this thread ? -> > -> > I think so. I believe the path I've been talking about is the one in step -> > 6 below. -> -> What I can find in SQL99 is SQL-path. -> Does *the path*(i.e search path) mean SQL-path ? -> They don't seem the same to me. - -While we may have not been using the terminology of the spec, I think we -have been talking about schema paths from SQL99. - -One difference between our discussions and SQL99 I've noticed is that -we've spoken of having the path find functions (and operators and -aggregates), types, _and_tables_. SQL99 doesn't have tables in there -AFAICT, but I think it makes sense. - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M18273=candle.pha.pa.us=pgman@postgresql.org Tue Jan 29 19:25:30 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0U0PUP06467 - for ; Tue, 29 Jan 2002 19:25:30 -0500 (EST) -Received: (qmail 92158 invoked by alias); 30 Jan 2002 00:25:29 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 30 Jan 2002 00:25:29 -0000 -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0U0Kil91336 - for ; Tue, 29 Jan 2002 19:20:45 -0500 (EST) - (envelope-from Inoue@tpf.co.jp) -Received: (qmail 18978 invoked from network); 30 Jan 2002 00:20:46 -0000 -Received: from unknown (HELO viscomail.tpf.co.jp) (100.0.0.108) - by sd2.tpf-fw-c.co.jp with SMTP; 30 Jan 2002 00:20:46 -0000 -Received: from tpf.co.jp (3dgateway1 [126.0.1.60]) - by viscomail.tpf.co.jp (8.8.8+Sun/8.8.8) with ESMTP id JAA08622; - Wed, 30 Jan 2002 09:20:44 +0900 (JST) -Message-ID: <3C573C5E.F01B48C2@tpf.co.jp> -Date: Wed, 30 Jan 2002 09:20:46 +0900 -From: Hiroshi Inoue -X-Mailer: Mozilla 4.73 [ja] (Windows NT 5.0; U) -X-Accept-Language: ja -MIME-Version: 1.0 -To: Bill Studenmund , Peter Eisentraut , - Tom Lane -cc: PostgreSQL Development -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: -Content-Type: text/plain; charset=iso-2022-jp -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Bill Studenmund wrote: -> -> On Tue, 29 Jan 2002, Hiroshi Inoue wrote: -> -> > What I can find in SQL99 is SQL-path. -> > Does *the path*(i.e search path) mean SQL-path ? -> > They don't seem the same to me. -> -> While we may have not been using the terminology of the spec, I think we -> have been talking about schema paths from SQL99. -> -> One difference between our discussions and SQL99 I've noticed is that -> we've spoken of having the path find functions (and operators and -> aggregates), types, _and_tables_. - -My understanding is the same. -Tom, Peter is it right ? - -> SQL99 doesn't have tables in there -> AFAICT, but I think it makes sense. - -It seems to make sense but they are different and -our *path* is never an extension of SQL-path. -Where are the difference or the relevance referred -to in this thread ? - -regards, -Hiroshi Inoue - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18305=candle.pha.pa.us=pgman@postgresql.org Wed Jan 30 15:15:26 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0UKFOP11825 - for ; Wed, 30 Jan 2002 15:15:25 -0500 (EST) -Received: (qmail 72977 invoked by alias); 30 Jan 2002 20:15:22 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 30 Jan 2002 20:15:22 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0UKEKl72120 - for ; Wed, 30 Jan 2002 15:14:20 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 23890 invoked by uid 1130); 30 Jan 2002 20:13:52 -0000 -Date: Wed, 30 Jan 2002 12:08:54 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Hiroshi Inoue -cc: Peter Eisentraut , Tom Lane , - PostgreSQL Development -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <3C573C5E.F01B48C2@tpf.co.jp> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 30 Jan 2002, Hiroshi Inoue wrote: - -> Bill Studenmund wrote: -> > -> > On Tue, 29 Jan 2002, Hiroshi Inoue wrote: -> > SQL99 doesn't have tables in there -> > AFAICT, but I think it makes sense. -> -> It seems to make sense but they are different and -> our *path* is never an extension of SQL-path. -> Where are the difference or the relevance referred -> to in this thread ? - -How is our path not an extention of SQL-path? Or at least how is the path -I've been pushing not an SQL-path? - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M18307=candle.pha.pa.us=pgman@postgresql.org Wed Jan 30 16:15:23 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0ULFMP19850 - for ; Wed, 30 Jan 2002 16:15:22 -0500 (EST) -Received: (qmail 96622 invoked by alias); 30 Jan 2002 21:15:08 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 30 Jan 2002 21:15:08 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0ULD4l95438 - for ; Wed, 30 Jan 2002 16:13:04 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0ULCPf26128; - Wed, 30 Jan 2002 16:12:25 -0500 (EST) -To: Stephan Szabo -cc: Bill Studenmund , Peter Eisentraut , - pgsql-hackers@postgresql.org, Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <20020123162426.K22713-100000@megazone23.bigpanda.com> -References: <20020123162426.K22713-100000@megazone23.bigpanda.com> -Comments: In-reply-to Stephan Szabo - message dated "Wed, 23 Jan 2002 16:34:32 -0800" -Date: Wed, 30 Jan 2002 16:12:24 -0500 -Message-ID: <26125.1012425144@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -[ just catching up on this thread after a couple days thinking about -other things ] - -Stephan Szabo writes: -> AFAIK there's no way to specify that I want to make the function -> complex(integer) such that I can do CAST(1 as complex) but not as an -> implicit cast. - -You may have forgotten that I recently suggested adding just such a -feature, ie a boolean flag on pg_proc rows to indicate whether they can -be considered for implicit casts. I think we'd agreed that it would be -a good thing to do in 7.3. - -However, that doesn't bear very much on the general argument of the -thread. The bottom line is that we've put a whole lot of sweat into -developing rules for resolving ambiguous operator and function calls, -and I don't think we're going to be willing to toss all that effort into -the scrap heap. But making namespace search order the dominant factor -in choosing a function/operator (as Bill seems to want) would certainly -break all that carefully-crafted effort. If we put the system namespace -at the front of the search list then users would be unable to override -standard operators with schema-local substitutes; clearly that's no -good. But if we put it at the back, then a schema-local user operator -would dominate all system entries of the same operator name, even for -quite different types, and thereby it would break the resolution -behavior. - -So I'm still of the opinion that my original suggestion is the only -workable one: collect candidates across all available namespaces, -discarding only those that are exact matches to candidates in earlier -namespaces, and then apply the existing resolution rules to the -collection. AFAICS this need not be any slower than what we do now, -if the catalog is set up so that we can collect candidates in one -indexscan without regard to namespace. The case where there actually -are any exact matches to discard should be uncommon, so we can deal with -it later on in the resolution process. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - -From pgsql-hackers-owner+M18308=candle.pha.pa.us=pgman@postgresql.org Wed Jan 30 16:25:39 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0ULPcP20879 - for ; Wed, 30 Jan 2002 16:25:38 -0500 (EST) -Received: (qmail 3172 invoked by alias); 30 Jan 2002 21:25:37 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 30 Jan 2002 21:25:37 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0ULM4l01963 - for ; Wed, 30 Jan 2002 16:22:04 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 21064 invoked by uid 1130); 30 Jan 2002 21:22:04 -0000 -Date: Wed, 30 Jan 2002 13:17:07 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Tom Lane -cc: Stephan Szabo , - Peter Eisentraut , , - Fernando Nasser -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <26125.1012425144@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 30 Jan 2002, Tom Lane wrote: - -> [ just catching up on this thread after a couple days thinking about -> other things ] -> -> However, that doesn't bear very much on the general argument of the -> thread. The bottom line is that we've put a whole lot of sweat into -> developing rules for resolving ambiguous operator and function calls, -> and I don't think we're going to be willing to toss all that effort into -> the scrap heap. But making namespace search order the dominant factor -> in choosing a function/operator (as Bill seems to want) would certainly -> break all that carefully-crafted effort. If we put the system namespace -> at the front of the search list then users would be unable to override -> standard operators with schema-local substitutes; clearly that's no -> good. But if we put it at the back, then a schema-local user operator -> would dominate all system entries of the same operator name, even for -> quite different types, and thereby it would break the resolution -> behavior. - -I've changed my mind. :-) - -> So I'm still of the opinion that my original suggestion is the only -> workable one: collect candidates across all available namespaces, -> discarding only those that are exact matches to candidates in earlier -> namespaces, and then apply the existing resolution rules to the -> collection. AFAICS this need not be any slower than what we do now, -> if the catalog is set up so that we can collect candidates in one -> indexscan without regard to namespace. The case where there actually -> are any exact matches to discard should be uncommon, so we can deal with -> it later on in the resolution process. - -Sounds like the thing to do, and it matches the spec. :-) - -Oh, you can make a path with your namespace before the built-in one. It's -just that if you don't include the built-in one (IMPLIMENTATION_SCHEMA) in -a path, you're supposed to prepend it to the specified list. - -Take care, - -Bill - - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18311=candle.pha.pa.us=pgman@postgresql.org Wed Jan 30 18:15:49 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0UNFmP04299 - for ; Wed, 30 Jan 2002 18:15:48 -0500 (EST) -Received: (qmail 40895 invoked by alias); 30 Jan 2002 23:15:47 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 30 Jan 2002 23:15:47 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0UNDrl39795 - for ; Wed, 30 Jan 2002 18:13:53 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0UND7f27530; - Wed, 30 Jan 2002 18:13:07 -0500 (EST) -To: Hiroshi Inoue -cc: Bill Studenmund , Peter Eisentraut , - PostgreSQL Development -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <3C573C5E.F01B48C2@tpf.co.jp> -References: <3C573C5E.F01B48C2@tpf.co.jp> -Comments: In-reply-to Hiroshi Inoue - message dated "Wed, 30 Jan 2002 09:20:46 +0900" -Date: Wed, 30 Jan 2002 18:13:06 -0500 -Message-ID: <27527.1012432386@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Hiroshi Inoue writes: -> Bill Studenmund wrote: ->> While we may have not been using the terminology of the spec, I think we ->> have been talking about schema paths from SQL99. ->> ->> One difference between our discussions and SQL99 I've noticed is that ->> we've spoken of having the path find functions (and operators and ->> aggregates), types, _and_tables_. - -> My understanding is the same. -> Tom, Peter is it right ? - -SQL99's SQL-path is very clearly stated to be used only for looking up -routines and user-defined type names. Extending it to cover tables, -operators, and so forth makes sense to me, but we have to recognize -that it is a spec extension and therefore not all the answers we need -can be found in the spec. - -I also find it curious that they exclude standard type names from the -search path. It would seem obvious to treat the standard type names -as included in a schema that is part of the search path, but AFAICT -this is not done in the spec. Postgres *has to* do it that way, -however, or give up our whole approach to datatypes; surely we don't -want to hardwire the SQL-standard datatypes into the parser to the -exclusion of the not-so-standard ones. - -IMHO, the spec's artificial distinction between system and user types -limits its usefulness as a guide to the questions we're debating here. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 5: Have you checked our extensive FAQ? - -http://www.postgresql.org/users-lounge/docs/faq.html - -From pgsql-hackers-owner+M18312=candle.pha.pa.us=pgman@postgresql.org Wed Jan 30 18:55:30 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0UNtSP08482 - for ; Wed, 30 Jan 2002 18:55:29 -0500 (EST) -Received: (qmail 58399 invoked by alias); 30 Jan 2002 23:55:26 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 30 Jan 2002 23:55:26 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0UNqhl56957 - for ; Wed, 30 Jan 2002 18:52:43 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 17164 invoked by uid 1130); 30 Jan 2002 23:46:06 -0000 -Date: Wed, 30 Jan 2002 15:41:09 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Tom Lane -cc: Hiroshi Inoue , Peter Eisentraut , - PostgreSQL Development -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <27527.1012432386@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 30 Jan 2002, Tom Lane wrote: - -> Hiroshi Inoue writes: -> > Bill Studenmund wrote: -> >> While we may have not been using the terminology of the spec, I think we -> >> have been talking about schema paths from SQL99. -> >> -> >> One difference between our discussions and SQL99 I've noticed is that -> >> we've spoken of having the path find functions (and operators and -> >> aggregates), types, _and_tables_. -> -> > My understanding is the same. -> > Tom, Peter is it right ? -> -> SQL99's SQL-path is very clearly stated to be used only for looking up -> routines and user-defined type names. Extending it to cover tables, -> operators, and so forth makes sense to me, but we have to recognize -> that it is a spec extension and therefore not all the answers we need -> can be found in the spec. - -True. I think that extending the path to be used for operators and -aggregates makes sense as they are special types of function calls. The -searching for tables might need to be a configurable parameter (defaulting -to yes), though. I think it makes sense to do, but I can imagine cases -where apps need to not. - -> I also find it curious that they exclude standard type names from the -> search path. It would seem obvious to treat the standard type names -> as included in a schema that is part of the search path, but AFAICT -> this is not done in the spec. Postgres *has to* do it that way, -> however, or give up our whole approach to datatypes; surely we don't -> want to hardwire the SQL-standard datatypes into the parser to the -> exclusion of the not-so-standard ones. -> -> IMHO, the spec's artificial distinction between system and user types -> limits its usefulness as a guide to the questions we're debating here. - -True. - -Does SQL99 support types as flexable as the ones we do? I know types in -Oracle are basically special cases of already built-in ones... - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M18314=candle.pha.pa.us=pgman@postgresql.org Wed Jan 30 19:15:14 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0V0FDP11130 - for ; Wed, 30 Jan 2002 19:15:14 -0500 (EST) -Received: (qmail 70218 invoked by alias); 31 Jan 2002 00:15:12 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 31 Jan 2002 00:15:12 -0000 -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0UNtQl58401 - for ; Wed, 30 Jan 2002 18:55:28 -0500 (EST) - (envelope-from Inoue@tpf.co.jp) -Received: (qmail 11171 invoked from network); 30 Jan 2002 23:55:24 -0000 -Received: from unknown (HELO viscomail.tpf.co.jp) (100.0.0.108) - by sd2.tpf-fw-c.co.jp with SMTP; 30 Jan 2002 23:55:24 -0000 -Received: from tpf.co.jp (3dgateway1 [126.0.1.60]) - by viscomail.tpf.co.jp (8.8.8+Sun/8.8.8) with ESMTP id IAA10232; - Thu, 31 Jan 2002 08:55:17 +0900 (JST) -Message-ID: <3C5887E8.CE7E569F@tpf.co.jp> -Date: Thu, 31 Jan 2002 08:55:20 +0900 -From: Hiroshi Inoue -X-Mailer: Mozilla 4.73 [ja] (Windows NT 5.0; U) -X-Accept-Language: ja -MIME-Version: 1.0 -To: Bill Studenmund -cc: Peter Eisentraut , Tom Lane , - PostgreSQL Development -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: -Content-Type: text/plain; charset=iso-2022-jp -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Bill Studenmund wrote: -> -> On Wed, 30 Jan 2002, Hiroshi Inoue wrote: -> -> > Bill Studenmund wrote: -> > > -> > > On Tue, 29 Jan 2002, Hiroshi Inoue wrote: -> > > SQL99 doesn't have tables in there -> > > AFAICT, but I think it makes sense. -> > -> > It seems to make sense but they are different and -> > our *path* is never an extension of SQL-path. -> > Where are the difference or the relevance referred -> > to in this thread ? -> -> How is our path not an extention of SQL-path? Or at least how is the path -> I've been pushing not an SQL-path? - -IMHO _tables_like objects must be guarded from such -a search mechanism fundamentally. I don't object to -the use of our *path* but it should be distinguished -from SQL-path. - -For example the PATH environment variable is used -only to search executables not files. Is it -preferable for *rm a_file* to search all the directory -in the PATH ? If the purpose is different the different -*path* is needed of cource. - -regards, -Hiroshi Inoue - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M18317=candle.pha.pa.us=pgman@postgresql.org Wed Jan 30 21:15:26 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0V2FPP23342 - for ; Wed, 30 Jan 2002 21:15:25 -0500 (EST) -Received: (qmail 15445 invoked by alias); 31 Jan 2002 02:15:12 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 31 Jan 2002 02:15:12 -0000 -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0V1v1l07129 - for ; Wed, 30 Jan 2002 20:57:01 -0500 (EST) - (envelope-from Inoue@tpf.co.jp) -Received: (qmail 21526 invoked from network); 31 Jan 2002 01:57:03 -0000 -Received: from unknown (HELO viscomail.tpf.co.jp) (100.0.0.108) - by sd2.tpf-fw-c.co.jp with SMTP; 31 Jan 2002 01:57:03 -0000 -Received: from tpf.co.jp (3dgateway1 [126.0.1.60]) - by viscomail.tpf.co.jp (8.8.8+Sun/8.8.8) with ESMTP id KAA10366; - Thu, 31 Jan 2002 10:57:02 +0900 (JST) -Message-ID: <3C58A472.2E90C21C@tpf.co.jp> -Date: Thu, 31 Jan 2002 10:57:06 +0900 -From: Hiroshi Inoue -X-Mailer: Mozilla 4.73 [ja] (Windows NT 5.0; U) -X-Accept-Language: ja -MIME-Version: 1.0 -To: Tom Lane -cc: Bill Studenmund , Peter Eisentraut , - PostgreSQL Development -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: <3C573C5E.F01B48C2@tpf.co.jp> <27527.1012432386@sss.pgh.pa.us> -Content-Type: text/plain; charset=iso-2022-jp -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> -> Hiroshi Inoue writes: -> > Bill Studenmund wrote: -> >> While we may have not been using the terminology of the spec, I think we -> >> have been talking about schema paths from SQL99. -> >> -> >> One difference between our discussions and SQL99 I've noticed is that -> >> we've spoken of having the path find functions (and operators and -> >> aggregates), types, _and_tables_. -> -> > My understanding is the same. -> > Tom, Peter is it right ? -> -> SQL99's SQL-path is very clearly stated to be used only for looking up -> routines and user-defined type names. Extending it to cover tables, -> operators, and so forth makes sense to me, - -I have no objection to the point it makes sense to use -such *path*s internally but I think it also has a siginificance -for SQL-path to not look up _tables_like objects. -I think they are different from the first and we should(need) -not manage the system with one *path*. - -BTW I see few references to *catalog*. Would the concept -of catalog be introduced together. If so what would be -contained in the current database. - -regards, -Hiroshi Inoue - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M18319=candle.pha.pa.us=pgman@postgresql.org Wed Jan 30 21:45:37 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0V2jZP27049 - for ; Wed, 30 Jan 2002 21:45:36 -0500 (EST) -Received: (qmail 27626 invoked by alias); 31 Jan 2002 02:45:32 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 31 Jan 2002 02:45:32 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0V2Wfl22316 - for ; Wed, 30 Jan 2002 21:32:41 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0V2WAf29271; - Wed, 30 Jan 2002 21:32:10 -0500 (EST) -To: Hiroshi Inoue -cc: Bill Studenmund , Peter Eisentraut , - PostgreSQL Development -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <3C58A472.2E90C21C@tpf.co.jp> -References: <3C573C5E.F01B48C2@tpf.co.jp> <27527.1012432386@sss.pgh.pa.us> <3C58A472.2E90C21C@tpf.co.jp> -Comments: In-reply-to Hiroshi Inoue - message dated "Thu, 31 Jan 2002 10:57:06 +0900" -Date: Wed, 30 Jan 2002 21:32:10 -0500 -Message-ID: <29268.1012444330@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Hiroshi Inoue writes: -> I have no objection to the point it makes sense to use -> such *path*s internally but I think it also has a siginificance -> for SQL-path to not look up _tables_like objects. -> I think they are different from the first and we should(need) -> not manage the system with one *path*. - -I'm unconvinced. We must search for datatypes and tables on the same -path because tables have associated datatypes; it will definitely not -do to look for a table's datatype and get the wrong type. And I think -that functions and operators should be looked for on the same path -as datatypes, because a type should be pretty closely associated with -the functions/operators for it. So it seems to me that the apparent -flexibility of having more than one path is just a way to shoot yourself -in the foot. Why are you concerned that we keep them separate? - -> BTW I see few references to *catalog*. Would the concept -> of catalog be introduced together. If so what would be -> contained in the current database. - -My thought is that we will consider catalog == database. As far as -I can tell, that is a legitimate implementation-defined way of -interpreting the spec. (It's not clear to me what the value is of -having more than one level of schema hierarchy; or at least, if you want -hierarchical namespaces, there's no argument for stopping at depth two. -But I digress.) To satisfy the spec we must allow a (purely decorative) -specification of the current database name as the catalog level of a -qualified name, but that's as far as I want to go. In this round, -anyway. Cross-database access is not something to tackle for 7.3. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M18323=candle.pha.pa.us=pgman@postgresql.org Wed Jan 30 22:45:10 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0V3j9P04896 - for ; Wed, 30 Jan 2002 22:45:09 -0500 (EST) -Received: (qmail 48073 invoked by alias); 31 Jan 2002 03:45:06 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 31 Jan 2002 03:45:06 -0000 -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0V3aPl45009 - for ; Wed, 30 Jan 2002 22:36:27 -0500 (EST) - (envelope-from Inoue@tpf.co.jp) -Received: (qmail 31045 invoked from network); 31 Jan 2002 03:36:21 -0000 -Received: from unknown (HELO viscomail.tpf.co.jp) (100.0.0.108) - by sd2.tpf-fw-c.co.jp with SMTP; 31 Jan 2002 03:36:21 -0000 -Received: from tpf.co.jp (3dgateway1 [126.0.1.60]) - by viscomail.tpf.co.jp (8.8.8+Sun/8.8.8) with ESMTP id MAA10485; - Thu, 31 Jan 2002 12:36:15 +0900 (JST) -Message-ID: <3C58BBB3.58D5F964@tpf.co.jp> -Date: Thu, 31 Jan 2002 12:36:19 +0900 -From: Hiroshi Inoue -X-Mailer: Mozilla 4.73 [ja] (Windows NT 5.0; U) -X-Accept-Language: ja -MIME-Version: 1.0 -To: Tom Lane -cc: Bill Studenmund , Peter Eisentraut , - PostgreSQL Development -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: <3C573C5E.F01B48C2@tpf.co.jp> <27527.1012432386@sss.pgh.pa.us> <3C58A472.2E90C21C@tpf.co.jp> <29268.1012444330@sss.pgh.pa.us> -Content-Type: text/plain; charset=iso-2022-jp -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> -> Hiroshi Inoue writes: -> > I have no objection to the point it makes sense to use -> > such *path*s internally but I think it also has a siginificance -> > for SQL-path to not look up _tables_like objects. -> > I think they are different from the first and we should(need) -> > not manage the system with one *path*. -> -> I'm unconvinced. We must search for datatypes and tables on the same -> path because tables have associated datatypes; - -Isn't the table definition a part of the datatype in -such a case ? - -> it will definitely not -> do to look for a table's datatype and get the wrong type. And I think -> that functions and operators should be looked for on the same path -> as datatypes, because a type should be pretty closely associated with -> the functions/operators for it. So it seems to me that the apparent -> flexibility of having more than one path is just a way to shoot yourself -> in the foot. Why are you concerned that we keep them separate? - -For example, doesn't 'DROP table a_table' drop the -a_table table in a schema in the *path* if there's -no a_table table in the current schema ? - -If we would never introduce SQL-paths (in the future) -there would be problem. - -regards, -Hiroshi Inoue - ----------------------------(end of broadcast)--------------------------- -TIP 2: you can get off all lists at once with the unregister command - (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) - -From pgsql-hackers-owner+M18325=candle.pha.pa.us=pgman@postgresql.org Wed Jan 30 22:55:24 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0V3tOP06352 - for ; Wed, 30 Jan 2002 22:55:24 -0500 (EST) -Received: (qmail 52777 invoked by alias); 31 Jan 2002 03:55:21 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 31 Jan 2002 03:55:21 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0V3iml47386 - for ; Wed, 30 Jan 2002 22:44:48 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0V3hff29736; - Wed, 30 Jan 2002 22:43:42 -0500 (EST) -To: Hiroshi Inoue -cc: Bill Studenmund , Peter Eisentraut , - PostgreSQL Development -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <3C58BBB3.58D5F964@tpf.co.jp> -References: <3C573C5E.F01B48C2@tpf.co.jp> <27527.1012432386@sss.pgh.pa.us> <3C58A472.2E90C21C@tpf.co.jp> <29268.1012444330@sss.pgh.pa.us> <3C58BBB3.58D5F964@tpf.co.jp> -Comments: In-reply-to Hiroshi Inoue - message dated "Thu, 31 Jan 2002 12:36:19 +0900" -Date: Wed, 30 Jan 2002 22:43:41 -0500 -Message-ID: <29733.1012448621@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Hiroshi Inoue writes: -> For example, doesn't 'DROP table a_table' drop the -> a_table table in a schema in the *path* if there's -> no a_table table in the current schema ? - -Sure. And that's exactly what it should do, IMHO. -Otherwise the notion that you can ignore your private -schema (at the front of the path) if you're not using -it falls down. Also, we wouldn't be able to implement -temp tables via a backend-local schema at the front of -the path. - -Any security concerns here should be addressed by putting -ACLs on the schemas you don't want altered; not by contorting -the notion of a search path to work for some operations and -not others. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18326=candle.pha.pa.us=pgman@postgresql.org Wed Jan 30 23:15:07 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0V4F6P09920 - for ; Wed, 30 Jan 2002 23:15:06 -0500 (EST) -Received: (qmail 57935 invoked by alias); 31 Jan 2002 04:15:03 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 31 Jan 2002 04:15:03 -0000 -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0V3lIl50338 - for ; Wed, 30 Jan 2002 22:47:20 -0500 (EST) - (envelope-from Inoue@tpf.co.jp) -Received: (qmail 31967 invoked from network); 31 Jan 2002 03:47:17 -0000 -Received: from unknown (HELO viscomail.tpf.co.jp) (100.0.0.108) - by sd2.tpf-fw-c.co.jp with SMTP; 31 Jan 2002 03:47:17 -0000 -Received: from tpf.co.jp (3dgateway1 [126.0.1.60]) - by viscomail.tpf.co.jp (8.8.8+Sun/8.8.8) with ESMTP id MAA10500; - Thu, 31 Jan 2002 12:47:17 +0900 (JST) -Message-ID: <3C58BE48.AD4EE527@tpf.co.jp> -Date: Thu, 31 Jan 2002 12:47:20 +0900 -From: Hiroshi Inoue -X-Mailer: Mozilla 4.73 [ja] (Windows NT 5.0; U) -X-Accept-Language: ja -MIME-Version: 1.0 -To: Tom Lane -cc: Bill Studenmund , Peter Eisentraut , - PostgreSQL Development -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: <3C573C5E.F01B48C2@tpf.co.jp> <27527.1012432386@sss.pgh.pa.us> <3C58A472.2E90C21C@tpf.co.jp> <29268.1012444330@sss.pgh.pa.us> -Content-Type: text/plain; charset=iso-2022-jp -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> -> Hiroshi Inoue writes: -> -> > BTW I see few references to *catalog*. Would the concept -> > of catalog be introduced together. If so what would be -> > contained in the current database. -> -> My thought is that we will consider catalog == database. As far as -> I can tell, that is a legitimate implementation-defined way of -> interpreting the spec. (It's not clear to me what the value is of -> having more than one level of schema hierarchy; or at least, if you want -> hierarchical namespaces, there's no argument for stopping at depth two. -> But I digress.) To satisfy the spec we must allow a (purely decorative) -> specification of the current database name as the catalog level of a -> qualified name, but that's as far as I want to go. In this round, -> anyway. Cross-database access is not something to tackle for 7.3. - -Just a confirmation. -We can't see any catalog.schema.object notation in 7.3, -can we ? - -regards, -Hiroshi Inoue - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18324=candle.pha.pa.us=pgman@postgresql.org Wed Jan 30 22:55:24 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0V3tOP06351 - for ; Wed, 30 Jan 2002 22:55:24 -0500 (EST) -Received: (qmail 52747 invoked by alias); 31 Jan 2002 03:55:20 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 31 Jan 2002 03:55:20 -0000 -Received: from sss.pgh.pa.us ([192.204.191.242]) - by postgresql.org (8.11.3/8.11.4) with ESMTP id g0V3pTl51655 - for ; Wed, 30 Jan 2002 22:51:29 -0500 (EST) - (envelope-from tgl@sss.pgh.pa.us) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss.pgh.pa.us (8.11.4/8.11.4) with ESMTP id g0V3p0f29810; - Wed, 30 Jan 2002 22:51:00 -0500 (EST) -To: Hiroshi Inoue -cc: Bill Studenmund , Peter Eisentraut , - PostgreSQL Development -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <3C58BE48.AD4EE527@tpf.co.jp> -References: <3C573C5E.F01B48C2@tpf.co.jp> <27527.1012432386@sss.pgh.pa.us> <3C58A472.2E90C21C@tpf.co.jp> <29268.1012444330@sss.pgh.pa.us> <3C58BE48.AD4EE527@tpf.co.jp> -Comments: In-reply-to Hiroshi Inoue - message dated "Thu, 31 Jan 2002 12:47:20 +0900" -Date: Wed, 30 Jan 2002 22:51:00 -0500 -Message-ID: <29807.1012449060@sss.pgh.pa.us> -From: Tom Lane -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Hiroshi Inoue writes: -> Just a confirmation. -> We can't see any catalog.schema.object notation in 7.3, -> can we ? - -No, what I meant was you could write catalog.schema.object --- but for -7.3, the system will only accept it if the catalog name is the same as -the current database. This satisfies the minimum requirements of the -spec, and it leaves notational room to use the catalog name as the cue -for cross-database access, if we ever decide we want to try to do that. - - regards, tom lane - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18334=candle.pha.pa.us=pgman@postgresql.org Thu Jan 31 05:45:28 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0VAjRP11000 - for ; Thu, 31 Jan 2002 05:45:27 -0500 (EST) -Received: (qmail 4065 invoked by alias); 31 Jan 2002 10:45:25 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 31 Jan 2002 10:45:25 -0000 -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0VAbGl02141 - for ; Thu, 31 Jan 2002 05:37:17 -0500 (EST) - (envelope-from Inoue@tpf.co.jp) -Received: (qmail 30401 invoked from network); 31 Jan 2002 10:37:17 -0000 -Received: from unknown (HELO viscomail.tpf.co.jp) (100.0.0.108) - by sd2.tpf-fw-c.co.jp with SMTP; 31 Jan 2002 10:37:17 -0000 -Received: from tpf.co.jp (3dgateway1 [126.0.1.60]) - by viscomail.tpf.co.jp (8.8.8+Sun/8.8.8) with ESMTP id TAA10891; - Thu, 31 Jan 2002 19:37:15 +0900 (JST) -Message-ID: <3C591E5E.14549DF@tpf.co.jp> -Date: Thu, 31 Jan 2002 19:37:18 +0900 -From: Hiroshi Inoue -X-Mailer: Mozilla 4.73 [ja] (Windows NT 5.0; U) -X-Accept-Language: ja -MIME-Version: 1.0 -To: Tom Lane -cc: Bill Studenmund , Peter Eisentraut , - PostgreSQL Development -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: <3C573C5E.F01B48C2@tpf.co.jp> <27527.1012432386@sss.pgh.pa.us> <3C58A472.2E90C21C@tpf.co.jp> <29268.1012444330@sss.pgh.pa.us> <3C58BBB3.58D5F964@tpf.co.jp> <29733.1012448621@sss.pgh.pa.us> -Content-Type: text/plain; charset=iso-2022-jp -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Tom Lane wrote: -> -> Hiroshi Inoue writes: -> > For example, doesn't 'DROP table a_table' drop the -> > a_table table in a schema in the *path* if there's -> > no a_table table in the current schema ? -> -> Sure. And that's exactly what it should do, IMHO. -> Otherwise the notion that you can ignore your private -> schema (at the front of the path) if you're not using -> it falls down. Also, we wouldn't be able to implement -> temp tables via a backend-local schema at the front of -> the path. - -I don't think it's useful for tables other than temp -ones and I wouldn't use it other than for temp ones. - -When we type 'rm a_file' in a shell environment -does the *rm* command search the PATH in finding -the a_file file ? Even though we need to implement -such a search mechanism we would use another path -different from the executable search PATH. I don't -think our *path* is an extension of SQL-path. - -I wouldn't complain unless we call the *path* -as SQL-path or an extension of SQL-path. - -regards, -Hiroshi Inoue - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18340=candle.pha.pa.us=pgman@postgresql.org Thu Jan 31 11:55:49 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0VGtmP13664 - for ; Thu, 31 Jan 2002 11:55:48 -0500 (EST) -Received: (qmail 32205 invoked by alias); 31 Jan 2002 16:53:46 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 31 Jan 2002 16:53:46 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0VGVXl24649 - for ; Thu, 31 Jan 2002 11:31:37 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 29829 invoked by uid 1130); 31 Jan 2002 16:31:38 -0000 -Date: Thu, 31 Jan 2002 08:26:40 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Hiroshi Inoue -cc: Tom Lane , Peter Eisentraut , - PostgreSQL Development -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <3C58A472.2E90C21C@tpf.co.jp> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Thu, 31 Jan 2002, Hiroshi Inoue wrote: - -> Tom Lane wrote: -> > -> > Hiroshi Inoue writes: -> > SQL99's SQL-path is very clearly stated to be used only for looking up -> > routines and user-defined type names. Extending it to cover tables, -> > operators, and so forth makes sense to me, -> -> I have no objection to the point it makes sense to use -> such *path*s internally but I think it also has a siginificance -> for SQL-path to not look up _tables_like objects. -> I think they are different from the first and we should(need) -> not manage the system with one *path*. - -I'm confused. Are you suggesting multiple paths? i.e. a function/type path -and a table one? - -I think calling our path an SQL path is fine. Yes, we extend it by using -it for tables too, but it strikes me as still fundamentally an SQL path. -So I don't see why we should not call it that. - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 6: Have you searched our list archives? - -http://archives.postgresql.org - -From pgsql-hackers-owner+M18342=candle.pha.pa.us=pgman@postgresql.org Thu Jan 31 11:56:06 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0VGu5P13918 - for ; Thu, 31 Jan 2002 11:56:05 -0500 (EST) -Received: (qmail 32437 invoked by alias); 31 Jan 2002 16:53:56 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 31 Jan 2002 16:53:56 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0VGdAl25623 - for ; Thu, 31 Jan 2002 11:39:11 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 29902 invoked by uid 1130); 31 Jan 2002 16:33:09 -0000 -Date: Thu, 31 Jan 2002 08:28:10 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Hiroshi Inoue -cc: Tom Lane , Peter Eisentraut , - PostgreSQL Development -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <3C58BBB3.58D5F964@tpf.co.jp> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Thu, 31 Jan 2002, Hiroshi Inoue wrote: - -> > it will definitely not -> > do to look for a table's datatype and get the wrong type. And I think -> > that functions and operators should be looked for on the same path -> > as datatypes, because a type should be pretty closely associated with -> > the functions/operators for it. So it seems to me that the apparent -> > flexibility of having more than one path is just a way to shoot yourself -> > in the foot. Why are you concerned that we keep them separate? -> -> For example, doesn't 'DROP table a_table' drop the -> a_table table in a schema in the *path* if there's -> no a_table table in the current schema ? -> -> If we would never introduce SQL-paths (in the future) -> there would be problem. - -?? - -We're talking about adding them now. Why would we add them twice? - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18341=candle.pha.pa.us=pgman@postgresql.org Thu Jan 31 11:59:16 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0VGxFP14456 - for ; Thu, 31 Jan 2002 11:59:15 -0500 (EST) -Received: (qmail 32440 invoked by alias); 31 Jan 2002 16:53:56 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 31 Jan 2002 16:53:56 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0VGdAl25618 - for ; Thu, 31 Jan 2002 11:39:11 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 223 invoked by uid 1130); 31 Jan 2002 16:36:01 -0000 -Date: Thu, 31 Jan 2002 08:31:03 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Tom Lane -cc: Hiroshi Inoue , Peter Eisentraut , - PostgreSQL Development -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <29733.1012448621@sss.pgh.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Wed, 30 Jan 2002, Tom Lane wrote: - -> Hiroshi Inoue writes: -> > For example, doesn't 'DROP table a_table' drop the -> > a_table table in a schema in the *path* if there's -> > no a_table table in the current schema ? -> -> Sure. And that's exactly what it should do, IMHO. -> Otherwise the notion that you can ignore your private -> schema (at the front of the path) if you're not using -> it falls down. Also, we wouldn't be able to implement -> temp tables via a backend-local schema at the front of -> the path. - -Well, I disagree on this one. :-) I'd vote drop should need a specific -schema if it's not the current one. But I won't push the point. :-) - -> Any security concerns here should be addressed by putting -> ACLs on the schemas you don't want altered; not by contorting -> the notion of a search path to work for some operations and -> not others. - -I'm not so concerned about security as being sure of operator intent. ACLs -address security (and should be used), but they don't address making sure -you delete exactly what you wanted. - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org - -From pgsql-hackers-owner+M18341=candle.pha.pa.us=pgman@postgresql.org Thu Jan 31 12:00:40 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g0VH0dP14749 - for ; Thu, 31 Jan 2002 12:00:39 -0500 (EST) -Received: (qmail 32325 invoked by alias); 31 Jan 2002 16:53:51 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 31 Jan 2002 16:53:51 -0000 -Received: from mail.netbsd.org (mail.netbsd.org [155.53.1.253]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g0VGdAl25625 - for ; Thu, 31 Jan 2002 11:39:12 -0500 (EST) - (envelope-from wrstuden@netbsd.org) -Received: (qmail 284 invoked by uid 1130); 31 Jan 2002 16:38:48 -0000 -Date: Thu, 31 Jan 2002 08:33:50 -0800 (PST) -From: Bill Studenmund -X-X-Sender: -To: Hiroshi Inoue -cc: Tom Lane , Peter Eisentraut , - PostgreSQL Development -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -In-Reply-To: <3C591E5E.14549DF@tpf.co.jp> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -On Thu, 31 Jan 2002, Hiroshi Inoue wrote: - -> Tom Lane wrote: -> > -> > Hiroshi Inoue writes: -> > > For example, doesn't 'DROP table a_table' drop the -> > > a_table table in a schema in the *path* if there's -> > > no a_table table in the current schema ? -> > -> > Sure. And that's exactly what it should do, IMHO. -> > Otherwise the notion that you can ignore your private -> > schema (at the front of the path) if you're not using -> > it falls down. Also, we wouldn't be able to implement -> > temp tables via a backend-local schema at the front of -> > the path. -> -> I don't think it's useful for tables other than temp -> ones and I wouldn't use it other than for temp ones. - -I agree. - -> When we type 'rm a_file' in a shell environment -> does the *rm* command search the PATH in finding -> the a_file file ? Even though we need to implement -> such a search mechanism we would use another path -> different from the executable search PATH. I don't -> think our *path* is an extension of SQL-path. -> -> I wouldn't complain unless we call the *path* -> as SQL-path or an extension of SQL-path. - -I still don't get this. The path we're talking about is the same thing -(with the same envirnment name and operational syntax) as SQL-paths, -except that we use it to find tables too. Why does that make it not an SQL -path? - -Take care, - -Bill - - ----------------------------(end of broadcast)--------------------------- -TIP 4: Don't 'kill -9' the postmaster - -From pgsql-hackers-owner+M18346=candle.pha.pa.us=pgman@postgresql.org Thu Jan 31 20:15:10 2002 -Return-path: -Received: from server1.pgsql.org (www.postgresql.org [64.49.215.9]) - by candle.pha.pa.us (8.11.6/8.10.1) with SMTP id g111FAP04980 - for ; Thu, 31 Jan 2002 20:15:10 -0500 (EST) -Received: (qmail 48143 invoked by alias); 1 Feb 2002 01:15:08 -0000 -Received: from unknown (HELO postgresql.org) (64.49.215.8) - by www.postgresql.org with SMTP; 1 Feb 2002 01:15:08 -0000 -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by postgresql.org (8.11.3/8.11.4) with SMTP id g11181l47339 - for ; Thu, 31 Jan 2002 20:08:01 -0500 (EST) - (envelope-from Inoue@tpf.co.jp) -Received: (qmail 14937 invoked from network); 1 Feb 2002 01:08:03 -0000 -Received: from unknown (HELO viscomail.tpf.co.jp) (100.0.0.108) - by sd2.tpf-fw-c.co.jp with SMTP; 1 Feb 2002 01:08:03 -0000 -Received: from tpf.co.jp (3dgateway1 [126.0.1.60]) - by viscomail.tpf.co.jp (8.8.8+Sun/8.8.8) with ESMTP id KAA11846; - Fri, 1 Feb 2002 10:08:01 +0900 (JST) -Message-ID: <3C59EA75.E117B2FA@tpf.co.jp> -Date: Fri, 01 Feb 2002 10:08:05 +0900 -From: Hiroshi Inoue -X-Mailer: Mozilla 4.73 [ja] (Windows NT 5.0; U) -X-Accept-Language: ja -MIME-Version: 1.0 -To: Bill Studenmund -cc: Tom Lane , Peter Eisentraut , - PostgreSQL Development -Subject: Re: [HACKERS] RFD: schemas and different kinds of Postgres objects -References: -Content-Type: text/plain; charset=iso-2022-jp -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@postgresql.org -Status: OR - -Bill Studenmund wrote: -> -> On Thu, 31 Jan 2002, Hiroshi Inoue wrote: -> > -> > I wouldn't complain unless we call the *path* -> > as SQL-path or an extension of SQL-path. -> -> I still don't get this. The path we're talking about is the same thing -> (with the same envirnment name and operational syntax) as SQL-paths, -> except that we use it to find tables too. Why does that make it not an SQL -> path? - -I don't think It's always good to follow the standard. -However it's very wrong to change the meaning of words -in the standard. It seems impossible to introduce SQL-path -using our *path*. The *path* is PostgreSQL specific and -it would be configurable for us to be SQL99-compatible -(without SQL-path) or SQL99-imcompatible using the *path*. - -regards, -Hiroshi Inoue - ----------------------------(end of broadcast)--------------------------- -TIP 3: if posting/reading through Usenet, please send an appropriate -subscribe-nomail command to majordomo@postgresql.org so that your -message can get through to the mailing list cleanly - diff --git a/doc/TODO.detail/tablespaces b/doc/TODO.detail/tablespaces deleted file mode 100644 index d978540375..0000000000 --- a/doc/TODO.detail/tablespaces +++ /dev/null @@ -1,10906 +0,0 @@ -From pgsql-hackers-owner+M174@hub.org Sun Mar 12 22:31:11 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id XAA25886 - for ; Sun, 12 Mar 2000 23:31:10 -0500 (EST) -Received: from news.tht.net (news.hub.org [216.126.91.242]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id XAA04589 for ; Sun, 12 Mar 2000 23:19:33 -0500 (EST) -Received: from hub.org (hub.org [216.126.84.1]) - by news.tht.net (8.9.3/8.9.3) with SMTP id XAA42854; - Sun, 12 Mar 2000 23:05:05 -0500 (EST) - (envelope-from pgsql-hackers-owner+M174@hub.org) -Received: from candle.pha.pa.us (root@s5-03.ppp.op.net [209.152.195.67]) - by hub.org (8.9.3/8.9.3) with ESMTP id XAA95917 - for ; Sun, 12 Mar 2000 23:00:56 -0500 (EST) - (envelope-from pgman@candle.pha.pa.us) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.9.0/8.9.0) id WAA25403 - for pgsql-hackers@postgreSQL.org; Sun, 12 Mar 2000 22:59:56 -0500 (EST) -From: Bruce Momjian -Message-Id: <200003130359.WAA25403@candle.pha.pa.us> -Subject: [HACKERS] Fix for RENAME -To: PostgreSQL-development -Date: Sun, 12 Mar 2000 22:59:56 -0500 (EST) -X-Mailer: ELM [version 2.4ME+ PL72 (25)] -MIME-Version: 1.0 -Content-Type: text/plain; charset=US-ASCII -Content-Transfer-Encoding: 7bit -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -I have thought about the issue with ALTER TABLE RENAME and keeping the -file system in sync with the database. - -It seems there are three commands that can cause these to get out of -sync: - - CREATE TABLE/INDEX - DROP TABLE/INDEX - ALTER TABLE RENAME - -Now, if we had file names based only on the oid, we can eliminate file -renaming for RENAME, but the others are still a problem. - -Seems there are three ways to get out of sync: - - ABORT transaction - backend crash - OS crash - -The last two are the same, except the backend crash restarts the -postmaster, while the OS crash has the postmaster starting up normally. - -Here is my idea. Create a C List of file names to unlink on transaction -commit or abort. For CREATE, unlink created files on transaction ABORT. -For DROP, unlink dropped files on COMMIT. For RENAME, create a hard -link for the new table linked to old table, and unlink the old file name -on COMMIT or the new file on ABORT. - -That takes care of COMMIT and ABORT. For backend crash or OS crash, add -a postgres command-line flag for recovery. Have the postmaster on -startup or shared memory refresh start up a postgres backend on every -database with the recovery flag set. Have the postgres backend find all -the oids in the pg_class table, and have it go through every file in the -database directory and remove all files that don't match the oids/names -in pg_class. Also, remove all old sort, noname, and temp files at the -same time. Seems we should be doing this anyway. - -Care would have to be taken that a corrupted database that caused a -postgres crash on connection would not get the postmaster startup into -an infinite loop. - -Comments? - --- - Bruce Momjian | http://www.op.net/~candle - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - -From reedstrm@wallace.ece.rice.edu Tue Mar 14 12:33:31 2000 -Received: from wallace.ece.rice.edu (root@wallace.ece.rice.edu [128.42.12.154]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id NAA23826 - for ; Tue, 14 Mar 2000 13:33:29 -0500 (EST) -Received: by wallace.ece.rice.edu - via sendmail from stdin - id (Debian Smail3.2.0.102) - for pgman@candle.pha.pa.us; Tue, 14 Mar 2000 12:33:32 -0600 (CST) -Date: Tue, 14 Mar 2000 12:33:32 -0600 -From: "Ross J. Reedstrom" -To: Hiroshi Inoue -Cc: Bruce Momjian , - PostgreSQL-development -Subject: Re: [HACKERS] Fix for RENAME -Message-ID: <20000314123331.A6094@rice.edu> -References: <200003140317.WAA27733@candle.pha.pa.us> <000c01bf8d75$a0016800$2801007e@tpf.co.jp> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -User-Agent: Mutt/1.0i -In-Reply-To: <000c01bf8d75$a0016800$2801007e@tpf.co.jp>; from Inoue@tpf.co.jp on Tue, Mar 14, 2000 at 02:24:52PM +0900 -Status: RO - -Hiroshi - -I've just about finished working up a patch to store the physical -file name in the pg_class table. There are only two places that -require a Rule for generating the filename, and one of them is -only used for bootstrapping. For the initial cut, I used the rule: - -The filename consists of the TABLENAME, and underscore, and the OID. -If this is longer than NAMEDATALEN, shorten the TABLENAME. - -I implemented this rule by exporting Tom's makeObjectName function -from analyze.c, which is used to make other system generated names -that are have a requirement to be human readable. Replacing this -rule with any other in the future would be straightforward, except -for bootstrap. There are a number of places in bootstrap that need to -know the filename. I've factored them out into yet another set of -#defines (in catname.h) to make that easier. - - -I'm working through the regression tests right now: this is a relatively -extensive change, since it modifies the low level access routines, and the -buffer cache (which I indexed on physical filename, rather than relname, -as it is now) Hopefully, I caught all the places that assume relname == -filename == unique name within a single database (see, I want schemas...) - -Ross --- -Ross J. Reedstrom, Ph.D., -NSBRI Research Scientist/Programmer -Computer and Information Technology Institute -Rice University, 6100 S. Main St., Houston, TX 77005 - - - - - -On Tue, Mar 14, 2000 at 02:24:52PM +0900, Hiroshi Inoue wrote: -> > -----Original Message----- -> > From: Bruce Momjian [mailto:pgman@candle.pha.pa.us] -> > -> > > > They use the existing table file. It is only when -> > > > adding/removing/renaming file system files that this -> > out-of-sync problem -> > > > happens. -> > > > -> > -> > Not sure. I was going to get the CREATE/DROP/RENAME working as it -> > should then as we add more features, we can implement this solution for -> > them too. -> > -> -> Hmm,is general solution difficult ? -> Is more flexible naming rule bad ? -> -> This the 3rd or 4th time that I mention the following. -> -> PostgreSQL doesn't keep the information in itself where tables are -> allocated. So we need a naming rule to find where existent tables -> are allocated. Don't you wonder the spec ? -> -> Regards. -> -> Hiroshi Inoue -> Inoue@tpf.co.jp -> -> - -From pgsql-hackers-owner+M74@hub.org Tue Mar 14 18:14:15 2000 -Received: from hub.org (hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id TAA06093 - for ; Tue, 14 Mar 2000 19:14:13 -0500 (EST) -Received: from hub.org (hub.org [216.126.84.1]) - by hub.org (8.9.3/8.9.3) with SMTP id SAA95465; - Tue, 14 Mar 2000 18:45:35 -0500 (EST) - (envelope-from pgsql-hackers-owner+M74@hub.org) -Received: from wallace.ece.rice.edu (root@wallace.ece.rice.edu [128.42.12.154]) - by hub.org (8.9.3/8.9.3) with ESMTP id NAA31276 - for ; Tue, 14 Mar 2000 13:33:52 -0500 (EST) - (envelope-from reedstrm@wallace.ece.rice.edu) -Received: by wallace.ece.rice.edu - via sendmail from stdin - id (Debian Smail3.2.0.102) - for pgsql-hackers@postgresql.org; Tue, 14 Mar 2000 12:33:32 -0600 (CST) -Date: Tue, 14 Mar 2000 12:33:32 -0600 -From: "Ross J. Reedstrom" -To: Hiroshi Inoue -Cc: Bruce Momjian , - PostgreSQL-development -Subject: Re: [HACKERS] Fix for RENAME -Message-ID: <20000314123331.A6094@rice.edu> -References: <200003140317.WAA27733@candle.pha.pa.us> <000c01bf8d75$a0016800$2801007e@tpf.co.jp> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -User-Agent: Mutt/1.0i -In-Reply-To: <000c01bf8d75$a0016800$2801007e@tpf.co.jp>; from Inoue@tpf.co.jp on Tue, Mar 14, 2000 at 02:24:52PM +0900 -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -Hiroshi - -I've just about finished working up a patch to store the physical -file name in the pg_class table. There are only two places that -require a Rule for generating the filename, and one of them is -only used for bootstrapping. For the initial cut, I used the rule: - -The filename consists of the TABLENAME, and underscore, and the OID. -If this is longer than NAMEDATALEN, shorten the TABLENAME. - -I implemented this rule by exporting Tom's makeObjectName function -from analyze.c, which is used to make other system generated names -that are have a requirement to be human readable. Replacing this -rule with any other in the future would be straightforward, except -for bootstrap. There are a number of places in bootstrap that need to -know the filename. I've factored them out into yet another set of -#defines (in catname.h) to make that easier. - - -I'm working through the regression tests right now: this is a relatively -extensive change, since it modifies the low level access routines, and the -buffer cache (which I indexed on physical filename, rather than relname, -as it is now) Hopefully, I caught all the places that assume relname == -filename == unique name within a single database (see, I want schemas...) - -Ross --- -Ross J. Reedstrom, Ph.D., -NSBRI Research Scientist/Programmer -Computer and Information Technology Institute -Rice University, 6100 S. Main St., Houston, TX 77005 - - - - - -On Tue, Mar 14, 2000 at 02:24:52PM +0900, Hiroshi Inoue wrote: -> > -----Original Message----- -> > From: Bruce Momjian [mailto:pgman@candle.pha.pa.us] -> > -> > > > They use the existing table file. It is only when -> > > > adding/removing/renaming file system files that this -> > out-of-sync problem -> > > > happens. -> > > > -> > -> > Not sure. I was going to get the CREATE/DROP/RENAME working as it -> > should then as we add more features, we can implement this solution for -> > them too. -> > -> -> Hmm,is general solution difficult ? -> Is more flexible naming rule bad ? -> -> This the 3rd or 4th time that I mention the following. -> -> PostgreSQL doesn't keep the information in itself where tables are -> allocated. So we need a naming rule to find where existent tables -> are allocated. Don't you wonder the spec ? -> -> Regards. -> -> Hiroshi Inoue -> Inoue@tpf.co.jp -> -> - -From mascarm@mascari.com Tue Mar 14 16:34:04 2000 -Received: from corvette.mascari.com (dhcp26136016.columbus.rr.com [24.26.136.16]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id RAA04395 - for ; Tue, 14 Mar 2000 17:32:14 -0500 (EST) -Received: from mascari.com (ferrari.mascari.com [192.168.2.1]) - by corvette.mascari.com (8.9.3/8.9.3) with ESMTP id RAA09562; - Tue, 14 Mar 2000 17:27:22 -0500 -Message-ID: <38CEBD0A.52ADB37E@mascari.com> -Date: Tue, 14 Mar 2000 17:28:26 -0500 -From: Mike Mascari -X-Mailer: Mozilla 4.7 [en] (Win95; I) -X-Accept-Language: en -MIME-Version: 1.0 -To: Bruce Momjian -CC: Hiroshi Inoue , - PostgreSQL-development -Subject: Re: [HACKERS] Fix for RENAME -References: <200003141545.KAA17518@candle.pha.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Status: RO - -Bruce Momjian wrote: -> -> > Hmm,is general solution difficult ? -> > Is more flexible naming rule bad ? -> > -> > This the 3rd or 4th time that I mention the following. -> -> That's because I didn't understand. -> -> > -> > PostgreSQL doesn't keep the information in itself where tables are -> > allocated. So we need a naming rule to find where existent tables -> > are allocated. Don't you wonder the spec ? -> -> How does naming the files in the database help our DROP/CREATE problem? -> It would help RENAME a little bit. Not sure about the others because -> currently they don't have a problem. - -I've been thinking about this somewhat, and I think the first -step necessary in correctly supporting ROLLBACK-able DDL -statements in transactions is the change to _. -Imagine the scenario: - -CREATE TABLE test (key int4); - -a) Session #1: - -BEGIN; - -b) Session #2: - -BEGIN; -DROP TABLE test; -CREATE TABLE test (value varchar(32)); - -c) Session #1: - -DROP TABLE test; -COMMIT; - -d) Session #2: - -COMMIT; - -What's clear to me is that, if DDL statements are to be -ROLLBACK-able, either (1) an AccessExclusive lock is held on the -relation until transaction commit (like Phillip Warner stated was -Dec/Rdb's behavior) or (2) PostgreSQL must be capable of -supporting "multi-versioned schema" as well as tuples. Before -step 'c' is executed, both tables must simultaneously exist in -the database with the same name, which works fine in the cataloge -thanks to MVCC, but requires that, on disk, there exists: - -test_01231 - Session #1's table, available for ROLLBACK -test_13421 - Session #2's table, available for COMMIT - -Now, I believe it was Andreas who suggested that VACUUM be -modified to perform cleanup. I agree with this. VACUUM will need -to check for aborted relation tuples in pg_class and remove the -associated file from the filesystem in the event, for example, -that Session #2 aborted -or- Session #1 aborted leaving the -original pg_class tuple the "active" one and Session #2 attempted -to COMMIT, which violates the UNIQUE constraint on the relname of -pg_class. In addition, for "active" relation entries, VACUUM -should verify the filename is -_ for the given oid. If it is not, it should rename -the filename on the filesystem. Again, this is purely cosmetic -for administrative purposes only, but would allow -for lack of atomicity only with respect to the label of the -relation file, until the next -VACUUM is run. - -For the case of ALTER TABLE RENAME, ALTER TABLE DROP COLUMN, -etc., the same functionality would apply. But, as in previous -discussions regarding ALTER TABLE DROP COLUMN, PostgreSQL MUST be -capable of allowing multiple tuples with different attribute -counts and types within the same relation: - -CREATE TABLE test (key int4); - -a) Session #1: - -BEGIN; - -b) Session #2: - -BEGIN; -ALTER TABLE test ADD COLUMN value int4; -INSERT INTO test values (1, 1); - -c) Session #1: - -INSERT INTO test values (0); -COMMIT; - -d) Session #2: - -COMMIT; - -This also means that Hiroshi's plan to suppress the visibility of -attributes for ALTER TABLE DROP COLUMN would be required anyway, -to allow for "multi-versioning" of attributes within a single -tuple (i.e., like multi-versioning of tuples within relations), -an attribute is either visible or not, but the tuple should -always grow, until, of course, the next VACUUM. - -So, to support rollback-able DDL statements ("multi-versioning -schema", if you will), PostgreSQL needs: - -1) relation names of the form _ -2) support "multi-versioning" of attributes within a single tuple -3) modify VACUUM to: - - A) Remove filesystem files whose pg_class tuples are no longer -valid - B) Rename filesystem files to relname of pg_class when the -_ doesn't match - C) Reconstruct relations after attributes have been -added/dropped. - -4) All DDL statements should perform their non-create filesystem -functions in the now infamous "post-transaction-commit" trigger. -If the backend should crash between the time the transaction -committed and the rename() or unlink(), no adverse affects would -be encountered with the database WRT data, VACUUM would clean up -the rename() problem, and, worst-case scenario, an old -_ file would lie around unused. But at least it -would no longer prohibit the creation of a table by the same -name.... - -Just my humble opinion, - -Mike Mascari - -From Inoue@tpf.co.jp Tue Mar 14 20:31:35 2000 -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id VAA08792 - for ; Tue, 14 Mar 2000 21:30:35 -0500 (EST) -Received: from cadzone ([126.0.1.40] (may be forged)) - by sd.tpf.co.jp (2.5 Build 2640 (Berkeley 8.8.6)/8.8.4) with SMTP - id LAA00515; Wed, 15 Mar 2000 11:29:09 +0900 -From: "Hiroshi Inoue" -To: "Ross J. Reedstrom" , - "Bruce Momjian" -Cc: "PostgreSQL-development" -Subject: RE: [HACKERS] Fix for RENAME -Date: Wed, 15 Mar 2000 11:35:46 +0900 -Message-ID: <000c01bf8e27$2b3c3ce0$2801007e@tpf.co.jp> -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 -In-Reply-To: <20000314123331.A6094@rice.edu> -Importance: Normal -Status: ROr - -> -----Original Message----- -> From: Ross J. Reedstrom [mailto:reedstrm@wallace.ece.rice.edu] -> -> Hiroshi - -> I've just about finished working up a patch to store the physical -> file name in the pg_class table. There are only two places that -> require a Rule for generating the filename, and one of them is -> only used for bootstrapping. - -Thanks for your trial. -It's nice that only two places require naming rule. - -I don't stick to one naming rule. -The only limitation is the uniqueness and the rule -could be changed according to situations. -For example,we could change the naming rule according to -the kind of relation such as system/user relations. - -I'm now inclined to introduce a new system relation to store -the physical path name. It could also have table(data)space -information in the (near ?) future. -It seems better to separate it from pg_class because table(data?) -space may change the concept of table allocation. - -Comments ? - -Regards. - -Hiroshi Inoue -Inoue@tpf.co.jp - - -From Inoue@tpf.co.jp Wed Mar 15 02:00:58 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id DAA17887 - for ; Wed, 15 Mar 2000 03:00:57 -0500 (EST) -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id CAA02974 for ; Wed, 15 Mar 2000 02:54:44 -0500 (EST) -Received: from cadzone ([126.0.1.40] (may be forged)) - by sd.tpf.co.jp (2.5 Build 2640 (Berkeley 8.8.6)/8.8.4) with SMTP - id QAA00734; Wed, 15 Mar 2000 16:53:56 +0900 -From: "Hiroshi Inoue" -To: "Bruce Momjian" -Cc: "Ross J. Reedstrom" , - "PostgreSQL-development" -Subject: RE: [HACKERS] Fix for RENAME -Date: Wed, 15 Mar 2000 17:00:35 +0900 -Message-ID: <001101bf8e54$8b941cc0$2801007e@tpf.co.jp> -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 -In-Reply-To: <200003150433.XAA13256@candle.pha.pa.us> -Importance: Normal -Status: ROr - -> -----Original Message----- -> From: Bruce Momjian [mailto:pgman@candle.pha.pa.us] -> -> > I'm now inclined to introduce a new system relation to store -> > the physical path name. It could also have table(data)space -> > information in the (near ?) future. -> > It seems better to separate it from pg_class because table(data?) -> > space may change the concept of table allocation. -> -> Why not just put it in pg_class? -> - -Not sure,it's only my feeling. -Comments please,everyone. - -We have taken a practical way which doesn't break file per table -assumption in this thread and it wouldn't so difficult to implement. -In fact Ross has already tried it. - -However there was a discussion about data(table)space for -months ago and currently a new discussion is there. -Judging from the previous discussion,I can't expect so much -that it could get a practical consensus(How many opinions there -were). We can make a practical step toward future by encapsulating -the information of table allocation. Separating table alloc info from -pg_class seems one of the way. -There may be more essential things for encapsulation. - -Comments ? - -Regards. - -Hiroshi Inoue -Inoue@tpf.co.jp - - -From pgsql-hackers-owner+M196@hub.org Thu Mar 16 03:02:35 2000 -Received: from hub.org (hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id EAA05789 - for ; Thu, 16 Mar 2000 04:02:29 -0500 (EST) -Received: from hub.org (hub.org [216.126.84.1]) - by hub.org (8.9.3/8.9.3) with SMTP id CAA27302; - Thu, 16 Mar 2000 02:58:55 -0500 (EST) - (envelope-from pgsql-hackers-owner+M196@hub.org) -Received: from downtown.oche.de (root@downtown.oche.de [194.94.253.3]) - by hub.org (8.9.3/8.9.3) with ESMTP id CAA23907 - for ; Thu, 16 Mar 2000 02:37:54 -0500 (EST) - (envelope-from mne@darwin.oche.de) -Received: from darwin.oche.de (uucp@localhost) - by downtown.oche.de (8.9.3/8.9.3/Debian/GNU) with SMTP id IAA30654 - for ; Thu, 16 Mar 2000 08:40:04 +0100 -Received: from mne by darwin.oche.de with local (Exim 3.12 #1 (Debian)) - id 12VUhX-0003Vz-00 - for ; Thu, 16 Mar 2000 08:28:11 +0100 -Date: Thu, 16 Mar 2000 08:28:11 +0100 (CET) -From: Martin Neumann -Subject: [HACKERS] RfD: Design of tablespaces -To: pgsql-hackers@postgresql.org -MIME-Version: 1.0 -Content-Type: TEXT/plain; CHARSET=US-ASCII -Message-Id: -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - - -I have written some thoughts on the concept of tablespace -down. I would be happy to get some comments on it. - ------------------------------------------------------------------ - Implementation of tablespaces within PostgreSQL -- a brainstorming paper designed for general discussion - - -by Martin Neumann, 2000/3/15 - - -1. What are tablespaces? -------------------------- - -Tablespaces make it possible to distribute storage objects -over multiple points of storage (POS). Therefor one could -say a tablespace can be a POS. - -Example: - -tablespace_a -----> /mnt/raid/arena0/ -tablespace_b -----> /mnt/raid/emc0/ - -Tablespaces can also store their data on other tablespaces: - -tablespace_c -----> tablespace_b - -This is quite interessting for administration purposes. - - -2. What are its advantages? ----------------------------- - -As you can choose a different tablespace for every storage -object (table, index etc.) it is easy to improve the following -aspects of your system: - - - Reliability - - You can put storage objects (mostly tables) you strongly depend - on onto a more reliable tablespace (mirrored RAID or perhaps - simply a directory which gets backuped more often than others). - - - Speed - - You can put storage objects you rarely need onto a rather slow - tablespace and keep your quick tablespaces clean from this. - - A fast, but more expensive RAID-Stripeset can be used more - efficiently as it doesn't get filled with non-performance - sensitive data. - - But also distributing storage objects which have equal needs - in sense of speed onto different tablespaces makes sense as - you gain more speed by distributing data over more than one - harddisk spindle. - - - Manageability - - You can grant and revoke rights on base of a tablespace. - - As every storage object belongs to exactly one tablespace, - you can easily group storage objects using a tablespace. - - -3. What about disk I/O? ------------------------- - -Tablespaces tell the storage manager only where to store -the data, not how. This is the reasonable way. - - -4. Usage ---------- - -CREATE TABLESPACE tsname TYPE storage_type storage_options - -Examples: - -CREATE TABLESPACE tsemc0 - TYPE classic DIRECTORY /mnt/raid/emc0 NOFSYNC - -CREATE TABLESPACE tsarena0 TYPE raw DEVICE /dev/araid/0 - MINSIZE 128 MAXSIZE 4096 GROW 4 32 SHRINK 2 32 - BLOCKSIZE 16384 - -CREATE TABLESPACE quick0 TYPE link TABLESPACE tsarena0; - --- - -CREATE TABLE tbname ( ... ) TABLESPACE tsname; - -Examples: - -CREATE TABLE foo ( - id int4 NOT NULL UNIQUE, - name text NOT NULL -) TABLESPACE tsemc0; - -CREATE TABLE bar ( - id int4 NOT NULL UNIQUE, - name text NOT NULL -) TABLESPACE default; - -If the tablespace isn't given, the storage objects gets created -in the "default" tablespace. - -"default" is the PostgreSQL's default tablespace and the only one -which has to exist on each system. - --- - -ALTER TABLESPACE tsname tssettings - -Examples: - -ALTER TABLESPACE tsemc0 DIRECTORY /mnt/raid/emc1 - - -NOTE: altering tablespaces without recreating the contained -storage objects introduces many problems. -Realisation is difficult and won't be my first goal. - --- - -DROP TABLESPACE tsname [FORCE] - -Examples: - -DROP TABLESPACE tsarena0 - -This will immediately remove the tablespace tsarena0 -if it contains no storage objects. - -If it still contains some the tablespace is marked for -deletion. - -This means: -1. you can't create new storage objects in the tablespace -2. if the last storage object inside gets dropped, the - tablespace will be removed. - - -DROP TABLESPACE tsarena0 FORCE - -This will remove the tablespace including all contained -storage objects immediately. - --- - -VACUUM tsname - -Example: - -VACUUM tsemc1 - -This will vacuum a single tablespace with all contained -storage objects. ------------------------------------------------------------------ - --- -Martin Neumann, Welkenrather Str. 118c, 52074 Aachen, Germany -mne@mne.de - http://www.mne.de/mne/ - sms@mne.de [eMail2SMS] -Tel. 0241 / 8876-080 - Mobil: 0173 / 27 69 632 -..------.--------------------------------------------------------- -| at | Inform GmbH - Abteilung Airport Logistics -| work | Pascalstr. 23 - 52076 Aachen - Tel. 02408 / 9456-0 -|______| martin.neumann@inform-ac.com - http://www.inform-ac.com - - - -From JanWieck@t-online.de Wed Jun 14 19:01:01 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id TAA21372 - for ; Wed, 14 Jun 2000 19:00:59 -0400 (EDT) -Received: from mailout02.sul.t-online.com (mailout02.sul.t-online.com [194.25.134.17]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id SAA01930 for ; Wed, 14 Jun 2000 18:51:11 -0400 (EDT) -Received: from fwd01.sul.t-online.de - by mailout02.sul.t-online.com with smtp - id 132Lz6-0004ec-01; Thu, 15 Jun 2000 00:50:08 +0200 -Received: from hot.jw.home (340000654369-0001@[62.224.107.172]) by fwd01.sul.t-online.de - with esmtp id 132Lyy-0tYyi9C; Thu, 15 Jun 2000 00:50:00 +0200 -Received: (from wieck@localhost) - by hot.jw.home (8.8.5/8.8.5) id WAA07887; - Wed, 14 Jun 2000 22:43:39 +0200 -From: JanWieck@t-online.de (Jan Wieck) -Message-Id: <200006142043.WAA07887@hot.jw.home> -Subject: Re: [HACKERS] Big 7.1 open items -In-Reply-To: <14752.960996980@sss.pgh.pa.us> from Tom Lane at "Jun 14, 2000 11:36:20 - am" -To: Tom Lane -Date: Wed, 14 Jun 2000 22:43:39 +0200 (MEST) -CC: Oliver Elphick , Bruce Momjian , - PostgreSQL-development -Reply-To: Jan Wieck -X-Mailer: ELM [version 2.4ME+ PL68 (25)] -MIME-Version: 1.0 -Content-Type: text/plain; charset=US-ASCII -Content-Transfer-Encoding: 7bit -X-Sender: 340000654369-0001@t-dialin.net -Status: ROr - -Tom Lane wrote: -> "Oliver Elphick" writes: -> > I suggest that DROP TABLE in a transaction should not be allowed. -> -> I had actually made it do that for a short time early this year, -> and was shouted down. On reflection I have to agree; it's too useful -> to be able to do -> -> begin; -> drop table foo; -> create table foo(new schema); -> ... -> end; -> -> You do indeed lose big if you suffer an error partway through, but -> the answer to that is to fix our file naming conventions so that we -> can support rollback of drop table. - - Belongs IMHO to the discussion to keep separate what is - separate (having indices/toast-relations/etc. in separate - directories and whatnot). - - I've never been really happy with the file naming - conventions. The need of a filesystem entry to have the same - name of the DB object that is associated with it isn't right. - I know, some people love to be able to easily identify the - files with ls(1). OTOH what is that good for? - - Well, someone can easily see how big the disk footprint of - his data is. Whow - what an info. Anything else? - - Why not changing the naming to be something like this: - - /catalog_tables/pg_... - /catalog_index/pg_... - /user_tables/oid_... - /user_index/oid_... - /temp_tables/oid_... - /temp_index/oid_... - /toast_tables/oid_... - /toast_index/oid_... - /whatnot_???/... - - This way, it would be much easier to separate all the - different object types to different physical media. We would - loose some transparency, but I've allways wondered what - people USE that for (except for just wanna know). For - convinience we could implement another little utility that - tells the object size like - - DESCRIBE TABLE/VIEW/whatnot - - that returns the physical location and storage details of the - object. And psql could use it to print this info additional - on the \d commands. Would give unprivileged users access to - this info, so be it, it's not a security issue IMHO. - - The subdirectory an object goes into has to be controlled by - the relkind. So we need to tidy up that a little too. I think - it's worth it. - - The objects storage location (the bare file) now would - contain the OID. So we avoid naming conflicts for temp - tables, naming conflicts during DROP/CREATE in a transaction - and all the like. - - Comments? - - -Jan - --- - -#======================================================================# -# It's easier to get forgiveness for being wrong than for being right. # -# Let's break this rule - forgive me. # -#================================================== JanWieck@Yahoo.com # - - - -From tgl@sss.pgh.pa.us Wed Jun 14 22:06:54 2000 -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id WAA02821 - for ; Wed, 14 Jun 2000 22:06:52 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id WAA16609; - Wed, 14 Jun 2000 22:07:16 -0400 (EDT) -To: Jan Wieck -cc: Oliver Elphick , Bruce Momjian , - PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <200006142043.WAA07887@hot.jw.home> -References: <200006142043.WAA07887@hot.jw.home> -Comments: In-reply-to JanWieck@t-online.de (Jan Wieck) - message dated "Wed, 14 Jun 2000 22:43:39 +0200" -Date: Wed, 14 Jun 2000 22:07:15 -0400 -Message-ID: <16606.961034835@sss.pgh.pa.us> -From: Tom Lane -Status: RO - -JanWieck@t-online.de (Jan Wieck) writes: -> I've never been really happy with the file naming -> conventions. The need of a filesystem entry to have the same -> name of the DB object that is associated with it isn't right. -> I know, some people love to be able to easily identify the -> files with ls(1). OTOH what is that good for? - -I agree with Jan on this: let's just change the file names over to -be OIDs. Then we can have rollbackable DROP and RENAME TABLE easily. -Naming the files after the logical names of the tables is nice if it -doesn't cost anything, but it is *not* worth the trouble to preserve -a relationship between filename and tablename when it is costing us. -And it's costing us big time. That single feature is hurting us on -functionality, robustness, and portability, and for what benefit? -Not nearly enough. It's time to just let go of it. - -> Why not changing the naming to be something like this: - -> /catalog_tables/pg_... -> /catalog_index/pg_... -> /user_tables/oid_... -> /user_index/oid_... -> /temp_tables/oid_... -> /temp_index/oid_... -> /toast_tables/oid_... -> /toast_index/oid_... -> /whatnot_???/... - -I don't see a lot of value in that. Better to do something like -tablespaces: - - // - - regards, tom lane - -From tgl@sss.pgh.pa.us Wed Jun 14 22:20:59 2000 -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id WAA25561 - for ; Wed, 14 Jun 2000 22:20:56 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id WAA16708; - Wed, 14 Jun 2000 22:21:30 -0400 (EDT) -To: Bruce Momjian -cc: Jan Wieck , Oliver Elphick , - PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <200006142313.TAA22904@candle.pha.pa.us> -References: <200006142313.TAA22904@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Wed, 14 Jun 2000 19:13:47 -0400" -Date: Wed, 14 Jun 2000 22:21:30 -0400 -Message-ID: <16705.961035690@sss.pgh.pa.us> -From: Tom Lane -Status: ROr - -Bruce Momjian writes: -> You need something that works from the command line, and something that -> works if PostgreSQL is not running. How would you restore one file from -> a tape. - -"Restore one file from a tape"? How are you going to do that anyway? -You can't save and restore portions of a database like that, because -of transaction commit status problems. To restore table X correctly, -you'd have to restore pg_log as well, and then your other tables are -hosed --- unless you also restore all of them from the backup. Only -a complete database restore from tape would work, and for that you -don't need to tell which file is which. So the above argument is a -red herring. - -I realize it's nice to be able to tell which table file is which by -eyeball, but the price we are paying for that small convenience is -just too high. Give that up, and we can have rollbackable DROP and -RENAME now (I'll personally commit to making it happen for 7.1). -Continue to insist on it, and I don't think we'll *ever* have those -features in a really robust form. It's just not possible to do -multiple file renames atomically. - - regards, tom lane - -From pgsql-hackers-owner+M3381@hub.org Wed Jun 14 22:23:25 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id WAA05943 - for ; Wed, 14 Jun 2000 22:23:24 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5F2ME840721; - Wed, 14 Jun 2000 22:22:14 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5F2Le840155 - for ; Wed, 14 Jun 2000 22:21:41 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id WAA16708; - Wed, 14 Jun 2000 22:21:30 -0400 (EDT) -To: Bruce Momjian -cc: Jan Wieck , Oliver Elphick , - PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <200006142313.TAA22904@candle.pha.pa.us> -References: <200006142313.TAA22904@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Wed, 14 Jun 2000 19:13:47 -0400" -Date: Wed, 14 Jun 2000 22:21:30 -0400 -Message-ID: <16705.961035690@sss.pgh.pa.us> -From: Tom Lane -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: ROr - -Bruce Momjian writes: -> You need something that works from the command line, and something that -> works if PostgreSQL is not running. How would you restore one file from -> a tape. - -"Restore one file from a tape"? How are you going to do that anyway? -You can't save and restore portions of a database like that, because -of transaction commit status problems. To restore table X correctly, -you'd have to restore pg_log as well, and then your other tables are -hosed --- unless you also restore all of them from the backup. Only -a complete database restore from tape would work, and for that you -don't need to tell which file is which. So the above argument is a -red herring. - -I realize it's nice to be able to tell which table file is which by -eyeball, but the price we are paying for that small convenience is -just too high. Give that up, and we can have rollbackable DROP and -RENAME now (I'll personally commit to making it happen for 7.1). -Continue to insist on it, and I don't think we'll *ever* have those -features in a really robust form. It's just not possible to do -multiple file renames atomically. - - regards, tom lane - -From pgsql-hackers-owner+M3382@hub.org Wed Jun 14 22:31:42 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id WAA10091 - for ; Wed, 14 Jun 2000 22:31:41 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5F2UI853244; - Wed, 14 Jun 2000 22:30:18 -0400 (EDT) -Received: from candle.pha.pa.us (pgman@s5-03.ppp.op.net [209.152.195.67]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5F2Th852641 - for ; Wed, 14 Jun 2000 22:29:43 -0400 (EDT) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.9.0/8.9.0) id WAA06576; - Wed, 14 Jun 2000 22:28:53 -0400 (EDT) -From: Bruce Momjian -Message-Id: <200006150228.WAA06576@candle.pha.pa.us> -Subject: Re: [HACKERS] Big 7.1 open items -In-Reply-To: <16705.961035690@sss.pgh.pa.us> "from Tom Lane at Jun 14, 2000 10:21:30 - pm" -To: Tom Lane -Date: Wed, 14 Jun 2000 22:28:53 -0400 (EDT) -CC: Jan Wieck , Oliver Elphick , - PostgreSQL-development -X-Mailer: ELM [version 2.4ME+ PL77 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -> Bruce Momjian writes: -> > You need something that works from the command line, and something that -> > works if PostgreSQL is not running. How would you restore one file from -> > a tape. -> -> "Restore one file from a tape"? How are you going to do that anyway? -> You can't save and restore portions of a database like that, because -> of transaction commit status problems. To restore table X correctly, -> you'd have to restore pg_log as well, and then your other tables are -> hosed --- unless you also restore all of them from the backup. Only -> a complete database restore from tape would work, and for that you -> don't need to tell which file is which. So the above argument is a -> red herring. -> -> I realize it's nice to be able to tell which table file is which by -> eyeball, but the price we are paying for that small convenience is -> just too high. Give that up, and we can have rollbackable DROP and -> RENAME now (I'll personally commit to making it happen for 7.1). -> Continue to insist on it, and I don't think we'll *ever* have those -> features in a really robust form. It's just not possible to do -> multiple file renames atomically. -> - -OK, I am flexible. (Yea, right.) :-) - -But seriously, let me give some background. I used Ingres, that used -the VMS file system, but used strange sequential AAAF324 numbers for -tables. When someone deleted a table, or we were looking at what tables -were using disk space, it was impossible to find the Ingres table names -that went with the file. There was a system table that showed it, but -it was poorly documented, and if you deleted the table, there was no way -to look on the tape to find out which file to restore. - -As far as pg_log, you certainly would not expect to get any information -back from the time of the backup table to current, so the current pg_log -would be just fine. - -Basically, I guess we have to do it, but we have to print the proper -error messages for cases in the backend we just print the file name. -Also, we have to now replace the 'ls -l' command with something that -will be meaningful. - -Right now, we use 'ps' with args to display backend information, and ls --l to show disk information. We are going to lose that here. - - - --- - Bruce Momjian | http://www.op.net/~candle - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - -From tgl@sss.pgh.pa.us Wed Jun 14 22:31:01 2000 -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id WAA09340 - for ; Wed, 14 Jun 2000 22:31:00 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id WAA16783 - for ; Wed, 14 Jun 2000 22:31:34 -0400 (EDT) -To: Bruce Momjian -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <200006150223.WAA06516@candle.pha.pa.us> -References: <200006150223.WAA06516@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Wed, 14 Jun 2000 22:23:58 -0400" -Date: Wed, 14 Jun 2000 22:31:33 -0400 -Message-ID: <16780.961036293@sss.pgh.pa.us> -From: Tom Lane -Status: RO - -> Can I phone you? - -Sure, I'm here. - - regards, tom lane - -From pgsql-hackers-owner+M3383@hub.org Wed Jun 14 22:38:29 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id WAA27501 - for ; Wed, 14 Jun 2000 22:38:28 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5F2bD870244; - Wed, 14 Jun 2000 22:37:13 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5F2af869743 - for ; Wed, 14 Jun 2000 22:36:41 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id WAA16814; - Wed, 14 Jun 2000 22:36:19 -0400 (EDT) -To: Bruce Momjian -cc: Jan Wieck , Oliver Elphick , - PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <200006150228.WAA06576@candle.pha.pa.us> -References: <200006150228.WAA06576@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Wed, 14 Jun 2000 22:28:53 -0400" -Date: Wed, 14 Jun 2000 22:36:19 -0400 -Message-ID: <16810.961036579@sss.pgh.pa.us> -From: Tom Lane -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: ROr - -Bruce Momjian writes: -> But seriously, let me give some background. I used Ingres, that used -> the VMS file system, but used strange sequential AAAF324 numbers for -> tables. When someone deleted a table, or we were looking at what tables -> were using disk space, it was impossible to find the Ingres table names -> that went with the file. There was a system table that showed it, but -> it was poorly documented, and if you deleted the table, there was no way -> to look on the tape to find out which file to restore. - -Fair enough, but it seems to me that the answer is to expend some effort -on system admin support tools. We could do a lot in that line with less -effort than trying to make a fundamentally mismatched filesystem -representation do what we need. - - regards, tom lane - -From tgl@sss.pgh.pa.us Wed Jun 14 23:13:35 2000 -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id XAA06306 - for ; Wed, 14 Jun 2000 23:13:26 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id XAA16988; - Wed, 14 Jun 2000 23:13:53 -0400 (EDT) -To: Bruce Momjian -cc: Jan Wieck , Oliver Elphick , - PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <200006150244.WAA27741@candle.pha.pa.us> -References: <200006150244.WAA27741@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Wed, 14 Jun 2000 22:44:16 -0400" -Date: Wed, 14 Jun 2000 23:13:52 -0400 -Message-ID: <16985.961038832@sss.pgh.pa.us> -From: Tom Lane -Status: ROr - -Bruce Momjian writes: -> That was my point --- that in doing this change, we are taking on more -> TODO items, that may detract from our main TODO items. - -True, but they are also TODO items that could be handled by people other -than the inner circle of key developers. The actual rejiggering of -table-to-filename mapping is going to have to be done by one of the -small number of people who are fully up to speed on backend internals. -But we've got a lot more folks who would be able (and, hopefully, -willing) to design and code whatever tools are needed to make the -dbadmin's job easier in the face of the new filesystem layout. I'd -rather not expend a lot of core time to avoid needing those tools, -especially when I feel the old approach is fatally flawed anyway. - -> Even gdb shows us the filename/tablename in backtraces. We are never -> going to be able to reproduce that. - -Backtraces from *what*, exactly? 99% of the backend is still going -to be dealing with the same data as ever. It might be that poking -around in fd.c will be a little harder, but considering that fd.c -doesn't really know or care what the files it's manipulating are -anyway, I'm not convinced that this is a real issue. - -> I guess I don't consider table schema commands inside transactions and -> such to be as big an items as the utility features we will need to -> build. - -You've *got* to be kidding. We're constantly seeing complaints about -the fact that rolling back DROP or RENAME TABLE fails --- and worse, -leaves the table in a corrupted/inconsistent state. As far as I can -tell, that's one of the worst robustness problems we've got left to -fix. This is a big deal IMHO, and I want it to be fixed and fixed -right. I don't see how to fix it right if we try to keep physical -filenames tied to logical tablenames. - -Moreover, that restriction will continue to hurt us if we try to -preserve it while implementing tablespaces, ANSI schemas, etc. - - regards, tom lane - -From pgsql-hackers-owner+M3387@hub.org Wed Jun 14 23:16:56 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id XAA07268 - for ; Wed, 14 Jun 2000 23:16:54 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5F3Em841832; - Wed, 14 Jun 2000 23:14:48 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5F3EG841655 - for ; Wed, 14 Jun 2000 23:14:16 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id XAA16988; - Wed, 14 Jun 2000 23:13:53 -0400 (EDT) -To: Bruce Momjian -cc: Jan Wieck , Oliver Elphick , - PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <200006150244.WAA27741@candle.pha.pa.us> -References: <200006150244.WAA27741@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Wed, 14 Jun 2000 22:44:16 -0400" -Date: Wed, 14 Jun 2000 23:13:52 -0400 -Message-ID: <16985.961038832@sss.pgh.pa.us> -From: Tom Lane -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: ROr - -Bruce Momjian writes: -> That was my point --- that in doing this change, we are taking on more -> TODO items, that may detract from our main TODO items. - -True, but they are also TODO items that could be handled by people other -than the inner circle of key developers. The actual rejiggering of -table-to-filename mapping is going to have to be done by one of the -small number of people who are fully up to speed on backend internals. -But we've got a lot more folks who would be able (and, hopefully, -willing) to design and code whatever tools are needed to make the -dbadmin's job easier in the face of the new filesystem layout. I'd -rather not expend a lot of core time to avoid needing those tools, -especially when I feel the old approach is fatally flawed anyway. - -> Even gdb shows us the filename/tablename in backtraces. We are never -> going to be able to reproduce that. - -Backtraces from *what*, exactly? 99% of the backend is still going -to be dealing with the same data as ever. It might be that poking -around in fd.c will be a little harder, but considering that fd.c -doesn't really know or care what the files it's manipulating are -anyway, I'm not convinced that this is a real issue. - -> I guess I don't consider table schema commands inside transactions and -> such to be as big an items as the utility features we will need to -> build. - -You've *got* to be kidding. We're constantly seeing complaints about -the fact that rolling back DROP or RENAME TABLE fails --- and worse, -leaves the table in a corrupted/inconsistent state. As far as I can -tell, that's one of the worst robustness problems we've got left to -fix. This is a big deal IMHO, and I want it to be fixed and fixed -right. I don't see how to fix it right if we try to keep physical -filenames tied to logical tablenames. - -Moreover, that restriction will continue to hurt us if we try to -preserve it while implementing tablespaces, ANSI schemas, etc. - - regards, tom lane - -From pgsql-hackers-owner+M3397@hub.org Thu Jun 15 03:03:33 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id DAA24286 - for ; Thu, 15 Jun 2000 03:03:32 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5F72T815284; - Thu, 15 Jun 2000 03:02:29 -0400 (EDT) -Received: from mailo.vtcif.telstra.com.au (mailo.vtcif.telstra.com.au [202.12.144.17]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5F721814963 - for ; Thu, 15 Jun 2000 03:02:01 -0400 (EDT) -Received: (from uucp@localhost) by mailo.vtcif.telstra.com.au (8.8.2/8.6.9) id RAA01186; Thu, 15 Jun 2000 17:01:48 +1000 (EST) -Received: from maili.vtcif.telstra.com.au(202.12.142.17) - via SMTP by mailo.vtcif.telstra.com.au, id smtpd0SbI.z; Thu Jun 15 17:00:39 2000 -Received: (from uucp@localhost) by maili.vtcif.telstra.com.au (8.8.2/8.6.9) id RAA21419; Thu, 15 Jun 2000 17:00:37 +1000 (EST) -Received: from localhost(127.0.0.1), claiming to be "mail.cdn.telstra.com.au" - via SMTP by localhost, id smtpdWTHrU_; Thu Jun 15 16:59:34 2000 -Received: from lunitari.nimrod.itg.telecom.com.au (lunitari.nimrod.itg.telecom.com.au [192.53.254.48]) by mail.cdn.telstra.com.au (8.8.2/8.6.9) with ESMTP id QAA04796; Thu, 15 Jun 2000 16:59:33 +1000 (EST) -Received: from nimrod.itg.telecom.com.au (majere [192.53.254.45]) - by lunitari.nimrod.itg.telecom.com.au (8.9.1/8.9.3) with ESMTP id QAA18056; - Thu, 15 Jun 2000 16:58:17 +1000 (EST) -Message-ID: <39487E0C.970680AB@nimrod.itg.telecom.com.au> -Date: Thu, 15 Jun 2000 16:56:12 +1000 -From: Chris Bitmead -Organization: IBM Global Services -X-Mailer: Mozilla 4.6 [en] (X11; I; SunOS 5.6 sun4u) -X-Accept-Language: en -MIME-Version: 1.0 -To: "Ross J. Reedstrom" -CC: PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -References: <16985.961038832@sss.pgh.pa.us> <200006150321.XAA09510@candle.pha.pa.us> <20000615010312.A995@rice.edu> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -"Ross J. Reedstrom" wrote: - -> Any strong objections to the mixed relname_oid solution? It gets us -> everything oids does, and still lets Bruce use 'ls -l' to find the big -> tables, putting off writing any admin tools that'll need to be rewritten, -> anyway. - -Doesn't relname_oid defeat the purpose of oid file names, which is that -they don't change when the table is renamed? Wasn't it going to be oids -with a tool to create a symlink of relname -> oid ? - -From pgsql-hackers-owner+M3400@hub.org Thu Jun 15 03:31:16 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id DAA24604 - for ; Thu, 15 Jun 2000 03:31:15 -0400 (EDT) -Received: from hub.org (root@hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id DAA01191 for ; Thu, 15 Jun 2000 03:15:28 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5F7CP835301; - Thu, 15 Jun 2000 03:12:25 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5F7Bt833744 - for ; Thu, 15 Jun 2000 03:11:55 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id DAA18801; - Thu, 15 Jun 2000 03:11:53 -0400 (EDT) -To: "Ross J. Reedstrom" -cc: PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <20000615010312.A995@rice.edu> -References: <16985.961038832@sss.pgh.pa.us> <200006150321.XAA09510@candle.pha.pa.us> <20000615010312.A995@rice.edu> -Comments: In-reply-to "Ross J. Reedstrom" - message dated "Thu, 15 Jun 2000 01:03:12 -0500" -Date: Thu, 15 Jun 2000 03:11:52 -0400 -Message-ID: <18798.961053112@sss.pgh.pa.us> -From: Tom Lane -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -"Ross J. Reedstrom" writes: -> Any strong objections to the mixed relname_oid solution? - -Yes! - -You cannot make it work reliably unless the relname part is the original -relname and does not track ALTER TABLE RENAME. IMHO having an obsolete -relname in the filename is worse than not having the relname at all; -it's a recipe for confusion, it means you still need admin tools to tell -which end is really up, and what's worst is you might think you don't. - -Furthermore it requires an additional column in pg_class to keep track -of the original relname, which is a waste of space and effort. - -It also creates a portability risk, or at least fails to remove one, -since you are critically dependent on the assumption that the OS -supports long filenames --- on a filesystem that truncates names to less -than about 45 characters you're in very deep trouble. An OID-only -approach still works on traditional 14-char-filename Unix filesystems -(it'd mostly even work on DOS 8+3, though I doubt we care about that). - -Finally, one of the reasons I want to go to filenames based only on OID -is that that'll make life easier for mdblindwrt. Original relname + OID -doesn't help, in fact it makes life harder (more shmem space needed to -keep track of the filename for each buffer). - -Can we *PLEASE JUST LET GO* of this bad idea? No relname in the -filename. Period. - - regards, tom lane - -From tgl@sss.pgh.pa.us Thu Jun 15 03:31:11 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id DAA24592 - for ; Thu, 15 Jun 2000 03:31:10 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id DAA01213 for ; Thu, 15 Jun 2000 03:15:46 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id DAA18833; - Thu, 15 Jun 2000 03:14:30 -0400 (EDT) -To: Bruce Momjian -cc: Jan Wieck , Oliver Elphick , - PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <200006150321.XAA09510@candle.pha.pa.us> -References: <200006150321.XAA09510@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Wed, 14 Jun 2000 23:21:15 -0400" -Date: Thu, 15 Jun 2000 03:14:30 -0400 -Message-ID: <18830.961053270@sss.pgh.pa.us> -From: Tom Lane -Status: RO - -Bruce Momjian writes: -> Well, we did have someone do a test implementation of oid file names, -> and their report was that is looked pretty ugly. However, if people are -> convinced it has to be done, we can get started. I guess I was waiting -> for Vadim's storage manager, where the whole idea of separate files is -> going to go away anyway, I suspect. We would then have to re-write all -> our admin tools for the new format. - -I seem to recall him saying that he wanted to go to filename == OID -just like I'm suggesting. But I agree we probably ought to hold off -doing anything until he gets back from Russia and can let us know -whether that's still his plan. If he is planning one-huge-file or -something like that, we might as well let these issues go unfixed -for one more release cycle. - - regards, tom lane - -From pgsql-hackers-owner+M3401@hub.org Thu Jun 15 03:31:15 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id DAA24601 - for ; Thu, 15 Jun 2000 03:31:14 -0400 (EDT) -Received: from hub.org (root@hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id DAA01428 for ; Thu, 15 Jun 2000 03:19:39 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5F7GP843802; - Thu, 15 Jun 2000 03:16:25 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5F7Fr842651 - for ; Thu, 15 Jun 2000 03:15:53 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id DAA18833; - Thu, 15 Jun 2000 03:14:30 -0400 (EDT) -To: Bruce Momjian -cc: Jan Wieck , Oliver Elphick , - PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <200006150321.XAA09510@candle.pha.pa.us> -References: <200006150321.XAA09510@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Wed, 14 Jun 2000 23:21:15 -0400" -Date: Thu, 15 Jun 2000 03:14:30 -0400 -Message-ID: <18830.961053270@sss.pgh.pa.us> -From: Tom Lane -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -Bruce Momjian writes: -> Well, we did have someone do a test implementation of oid file names, -> and their report was that is looked pretty ugly. However, if people are -> convinced it has to be done, we can get started. I guess I was waiting -> for Vadim's storage manager, where the whole idea of separate files is -> going to go away anyway, I suspect. We would then have to re-write all -> our admin tools for the new format. - -I seem to recall him saying that he wanted to go to filename == OID -just like I'm suggesting. But I agree we probably ought to hold off -doing anything until he gets back from Russia and can let us know -whether that's still his plan. If he is planning one-huge-file or -something like that, we might as well let these issues go unfixed -for one more release cycle. - - regards, tom lane - -From ZeugswetterA@wien.spardat.at Thu Jun 15 03:30:59 2000 -Received: from gandalf.it-austria.net (gandalf.it-austria.net [213.150.1.65]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id DAA24584 - for ; Thu, 15 Jun 2000 03:30:56 -0400 (EDT) -Received: from sdexcgtw01.f000.d0188.sd.spardat.at (sdgtw.sd.spardat.at [172.18.1.16]) - by gandalf.it-austria.net (xxx/xxx) with ESMTP id JAA29140; - Thu, 15 Jun 2000 09:31:12 +0200 -Received: by sdexcgtw01.f000.d0188.sd.spardat.at with Internet Mail Service (5.5.2448.0) - id ; Thu, 15 Jun 2000 09:31:12 +0200 -Message-ID: <219F68D65015D011A8E000006F8590C604AF7DE4@sdexcsrv1.f000.d0188.sd.spardat.at> -From: Zeugswetter Andreas SB -To: "'Tom Lane'" , Bruce Momjian -Cc: Jan Wieck , Oliver Elphick , - PostgreSQL-development -Subject: AW: [HACKERS] Big 7.1 open items -Date: Thu, 15 Jun 2000 09:31:11 +0200 -MIME-Version: 1.0 -X-Mailer: Internet Mail Service (5.5.2448.0) -Content-Type: text/plain; - charset="iso-8859-1" -Status: RO - - -> Bruce Momjian writes: -> > You need something that works from the command line, and -> something that -> > works if PostgreSQL is not running. How would you restore -> one file from -> > a tape. -> -> "Restore one file from a tape"? How are you going to do that anyway? -> You can't save and restore portions of a database like that, because -> of transaction commit status problems. To restore table X correctly, -> you'd have to restore pg_log as well, and then your other tables are -> hosed --- unless you also restore all of them from the backup. Only -> a complete database restore from tape would work, and for that you -> don't need to tell which file is which. So the above argument is a -> red herring. - ->From what I know it is possible to simply restore one table file -since pg_log keeps all tid's. Of course it cannot guarantee integrity -and does not work if the table was altered. - -> I realize it's nice to be able to tell which table file is which by -> eyeball, but the price we are paying for that small convenience is -> just too high. Give that up, and we can have rollbackable DROP and -> RENAME now (I'll personally commit to making it happen for 7.1). -> Continue to insist on it, and I don't think we'll *ever* have those -> features in a really robust form. It's just not possible to do -> multiple file renames atomically. - -In the last proposal Bruce and I had it all layed out for tabname + oid -with no overhead in the normal situation, and little overhead if a rename -table crashed or was not rolled back or committed properly -which imho had all advantages combined. - -Andreas - -From ZeugswetterA@wien.spardat.at Thu Jun 15 04:31:04 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id EAA25144 - for ; Thu, 15 Jun 2000 04:31:03 -0400 (EDT) -Received: from gandalf.it-austria.net (gandalf.it-austria.net [213.150.1.65]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id EAA03225 for ; Thu, 15 Jun 2000 04:05:41 -0400 (EDT) -Received: from sdexcgtw01.f000.d0188.sd.spardat.at (sdgtw.sd.spardat.at [172.18.1.16]) - by gandalf.it-austria.net (xxx/xxx) with ESMTP id KAA100894; - Thu, 15 Jun 2000 10:04:52 +0200 -Received: by sdexcgtw01.f000.d0188.sd.spardat.at with Internet Mail Service (5.5.2448.0) - id ; Thu, 15 Jun 2000 10:04:52 +0200 -Message-ID: <219F68D65015D011A8E000006F8590C604AF7DE7@sdexcsrv1.f000.d0188.sd.spardat.at> -From: Zeugswetter Andreas SB -To: "'Don Baccus'" , - Bruce Momjian - , Tom Lane -Cc: Jan Wieck , Oliver Elphick , - PostgreSQL-development -Subject: AW: [HACKERS] Big 7.1 open items -Date: Thu, 15 Jun 2000 10:04:51 +0200 -MIME-Version: 1.0 -X-Mailer: Internet Mail Service (5.5.2448.0) -Content-Type: text/plain; - charset="windows-1252" -Status: RO - - -> In reality, very few people are going to be interested in restoring -> a table in a way that breaks referential integrity and other -> normal assumptions about what exists in the database. - -This is not true. In my DBA history it would have saved me manweeks -of work if an easy and efficient restore of one single table from backup -would have been available in Informix and Oracle. -We allways had to restore most of the whole system to another machine only -to get back at some table info that would then be manually re-added -to the production system. -A restore of one table to a different/new tablename would have been -very convenient, and this is currently possible in PostgreSQL. -(create new table with same schema, then replace new table data file -with file from backup) - -> The reality -> is that most people are going to engage in a little time travel -> to a past, consistent backup rather than do as you suggest. - -No, this is what is done most of the time, but it is very inconvenient -to tell people that they loose all work from past days, so it is usually -done as I noted above if possible. We once had a situation where all data -was deleted from a table, but the problem was only noticed 3 weeks later. - -> This is going to be more and more true as Postgres gains more and -> more acceptance in (no offense intended) the real world. -> -> >Right now, we use 'ps' with args to display backend -> information, and ls -> >-l to show disk information. We are going to lose that here. -> -> Dependence on "ls -l" is, IMO, a very weak argument. - -In normal situations where everything works I agree, it is the -error situations where it really helps if you see what data is where. -debugging, lsof, Bruce already named them. - -Andreas - -From pgsql-hackers-owner+M3405@hub.org Thu Jun 15 04:31:09 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id EAA25151 - for ; Thu, 15 Jun 2000 04:31:07 -0400 (EDT) -Received: from hub.org (root@hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id EAA04151 for ; Thu, 15 Jun 2000 04:30:23 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5F8RI883087; - Thu, 15 Jun 2000 04:27:18 -0400 (EDT) -Received: from gandalf.it-austria.net (gandalf.it-austria.net [213.150.1.65]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5F8Qx881928 - for ; Thu, 15 Jun 2000 04:27:00 -0400 (EDT) -Received: from sdexcgtw01.f000.d0188.sd.spardat.at (sdgtw.sd.spardat.at [172.18.1.16]) - by gandalf.it-austria.net (xxx/xxx) with ESMTP id KAA79848; - Thu, 15 Jun 2000 10:26:13 +0200 -Received: by sdexcgtw01.f000.d0188.sd.spardat.at with Internet Mail Service (5.5.2448.0) - id ; Thu, 15 Jun 2000 10:26:14 +0200 -Message-ID: <219F68D65015D011A8E000006F8590C604AF7DE8@sdexcsrv1.f000.d0188.sd.spardat.at> -From: Zeugswetter Andreas SB -To: "'Tom Lane'" , - "Ross J. Reedstrom" - -Cc: PostgreSQL-development -Subject: AW: [HACKERS] Big 7.1 open items -Date: Thu, 15 Jun 2000 10:26:12 +0200 -MIME-Version: 1.0 -X-Mailer: Internet Mail Service (5.5.2448.0) -Content-Type: text/plain; - charset="iso-8859-1" -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: ROr - - -> "Ross J. Reedstrom" writes: -> > Any strong objections to the mixed relname_oid solution? -> -> Yes! -> -> You cannot make it work reliably unless the relname part is -> the original -> relname and does not track ALTER TABLE RENAME. - -It does, or should at least. Only problem case is where db crashes during -alter or commit/rollback. This could be fixed by first open that fails to -find the file -or vacuum, or some other utility. - -> IMHO having -> an obsolete -> relname in the filename is worse than not having the relname at all; -> it's a recipe for confusion, it means you still need admin -> tools to tell -> which end is really up, and what's worst is you might think you don't. -> -> Furthermore it requires an additional column in pg_class to keep track -> of the original relname, which is a waste of space and effort. - -it does not. - -> Finally, one of the reasons I want to go to filenames based -> only on OID -> is that that'll make life easier for mdblindwrt. Original -> relname + OID -> doesn't help, in fact it makes life harder (more shmem space needed to -> keep track of the filename for each buffer). - -I do not see this. filename is constructed from relname+oid. -if not found, do directory scan for *_.dat, if found --> rename. - -Andreas - -From pgsql-hackers-owner+M3407@hub.org Thu Jun 15 05:01:03 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id FAA25462 - for ; Thu, 15 Jun 2000 05:01:02 -0400 (EDT) -Received: from hub.org (root@hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id EAA04667 for ; Thu, 15 Jun 2000 04:45:51 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5F8gr817124; - Thu, 15 Jun 2000 04:42:53 -0400 (EDT) -Received: from gandalf.it-austria.net (gandalf.it-austria.net [213.150.1.65]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5F8gX815763 - for ; Thu, 15 Jun 2000 04:42:34 -0400 (EDT) -Received: from sdexcgtw01.f000.d0188.sd.spardat.at (sdgtw.sd.spardat.at [172.18.1.16]) - by gandalf.it-austria.net (xxx/xxx) with ESMTP id KAA29072; - Thu, 15 Jun 2000 10:41:51 +0200 -Received: by sdexcgtw01.f000.d0188.sd.spardat.at with Internet Mail Service (5.5.2448.0) - id ; Thu, 15 Jun 2000 10:41:51 +0200 -Message-ID: <219F68D65015D011A8E000006F8590C604AF7DE9@sdexcsrv1.f000.d0188.sd.spardat.at> -From: Zeugswetter Andreas SB -To: "'Tom Lane'" -Cc: PostgreSQL-development -Subject: AW: [HACKERS] Big 7.1 open items -Date: Thu, 15 Jun 2000 10:41:50 +0200 -MIME-Version: 1.0 -X-Mailer: Internet Mail Service (5.5.2448.0) -Content-Type: text/plain; - charset="iso-8859-1" -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -> It's just not possible to do -> multiple file renames atomically. - -This is not necessary, since *_ is unique regardless of relname prefix. - -Andreas - -From scrappy@hub.org Thu Jun 15 08:30:59 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id IAA03846 - for ; Thu, 15 Jun 2000 08:30:58 -0400 (EDT) -Received: from thelab.hub.org (nat193.152.mpoweredpc.net [142.177.193.152]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id IAA14167 for ; Thu, 15 Jun 2000 08:16:58 -0400 (EDT) -Received: from localhost (scrappy@localhost) - by thelab.hub.org (8.9.3/8.9.3) with ESMTP id JAA74856; - Thu, 15 Jun 2000 09:14:29 -0300 (ADT) - (envelope-from scrappy@hub.org) -X-Authentication-Warning: thelab.hub.org: scrappy owned process doing -bs -Date: Thu, 15 Jun 2000 09:14:29 -0300 (ADT) -From: The Hermit Hacker -To: Bruce Momjian -cc: Tom Lane , Jan Wieck , - Oliver Elphick , - PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -In-Reply-To: <200006150321.XAA09510@candle.pha.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Status: RO - -On Wed, 14 Jun 2000, Bruce Momjian wrote: - -> > Backtraces from *what*, exactly? 99% of the backend is still going -> > to be dealing with the same data as ever. It might be that poking -> > around in fd.c will be a little harder, but considering that fd.c -> > doesn't really know or care what the files it's manipulating are -> > anyway, I'm not convinced that this is a real issue. -> -> I was just throwing gdb out as an example. The bigger ones are ls, -> lsof/fstat, and tar. - -You've lost me on this one ... if someone does an lsof of the process, it -will still provide them a list of open files ... are you complaining about -the extra step required to translate the file name to a "valid table"? - -Oh, one point here ... this whole 'filenaming issue' ... as far as ls is -concerned, at least, only affects the superuser, since he's the only one -that can go 'ls'ng around i nthe directories ... - -And, ummm, how hard would it be to have \d in psql display the "physical -table name" as part of its output? - -Slight tangent here: - -One thing that I think would be great if we could add is some sort of: - -SELECT db_name, disk_space; - -query wher a database owner, not the superuser, could see how much disk -space their tables are using up ... possible? - - -From pgsql-hackers-owner+M3412@hub.org Thu Jun 15 08:30:55 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id IAA03842 - for ; Thu, 15 Jun 2000 08:30:54 -0400 (EDT) -Received: from hub.org (root@hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id IAA15241 for ; Thu, 15 Jun 2000 08:31:29 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5FCSM877572; - Thu, 15 Jun 2000 08:28:22 -0400 (EDT) -Received: from zrtps06s.us.nortel.com ([47.140.48.50]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5FCRS877255 - for ; Thu, 15 Jun 2000 08:27:28 -0400 (EDT) -Received: from ertpg15e1.nortelnetworks.com (actually zrtph06n.us.nortel.com) - by zrtps06s.us.nortel.com; Thu, 15 Jun 2000 08:26:34 -0400 -Received: from zrtpd004.us.nortel.com (actually zrtpd004) - by ertpg15e1.nortelnetworks.com; Thu, 15 Jun 2000 08:26:11 -0400 -Received: from zrtpd003.us.nortel.com ([47.140.224.137]) - by zrtpd004.us.nortel.com - with SMTP (Microsoft Exchange Internet Mail Service Version 5.5.2650.21) - id MPQCZWMM; Thu, 15 Jun 2000 08:26:10 -0400 -Received: from americasm01.nt.com (hrtpp28d.us.nortel.com [47.190.110.250]) - by zrtpd003.us.nortel.com - with SMTP (Microsoft Exchange Internet Mail Service Version 5.5.2650.21) - id L1N0XG78; Thu, 15 Jun 2000 08:26:12 -0400 -Message-ID: <3948CBDC.5A4F5705@americasm01.nt.com> -Date: Thu, 15 Jun 2000 08:28:12 -0400 -X-Sybari-Space: 00000000 00000000 00000000 -From: "Mark Hollomon" -Reply-To: "Mark Hollomon" -Organization: Nortel Networks -X-Mailer: Mozilla 4.04 [en] (Win95; U) -MIME-Version: 1.0 -To: "Ross J. Reedstrom" -CC: PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -References: <16985.961038832@sss.pgh.pa.us> <200006150321.XAA09510@candle.pha.pa.us> <20000615010312.A995@rice.edu> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -X-Orig: -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -Ross J. Reedstrom wrote: -> -> Any strong objections to the mixed relname_oid solution? It gets us -> everything oids does, and still lets Bruce use 'ls -l' to find the big -> tables, putting off writing any admin tools that'll need to be rewritten, -> anyway. - -I would object to the mixed name. - -Consider: - -CREATE TABLE FOO .... -ALTER TABLE FOO RENAME FOO_OLD; -CREATE TABLE FOO .... - -For the same atomicity reason, rename can't change the -name of the files. So, which foo_ is the FOO_OLD -and which is FOO? - -In other words, in the presence of rename, putting -relname in the filename is misleading at best. - --- - -Mark Hollomon -mhh@nortelnetworks.com -ESN 451-9008 (302)454-9008 - -From pgsql-hackers-owner+M3413@hub.org Thu Jun 15 08:30:47 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id IAA03837 - for ; Thu, 15 Jun 2000 08:30:45 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5FCTb883200; - Thu, 15 Jun 2000 08:29:37 -0400 (EDT) -Received: from smtp1.andrew.cmu.edu (SMTP1.ANDREW.CMU.EDU [128.2.10.81]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5FCT7881265 - for ; Thu, 15 Jun 2000 08:29:07 -0400 (EDT) -Received: from export.andrew.cmu.edu (EXPORT.ANDREW.CMU.EDU [128.2.23.2]) - by smtp1.andrew.cmu.edu (8.9.3/8.9.3) with ESMTP id IAA02782 - for ; Thu, 15 Jun 2000 08:29:02 -0400 (EDT) -Date: Thu, 15 Jun 2000 08:29:02 -0400 (EDT) -Message-Id: <200006151229.IAA02782@smtp1.andrew.cmu.edu> -From: Brian E Gallew -X-Mailer: BatIMail version 3.2 -To: "PostgreSQL-development" -In-reply-to: <16810.961036579@sss.pgh.pa.us> -Subject: Re: [HACKERS] Big 7.1 open items -References: <200006150228.WAA06576@candle.pha.pa.us> <16810.961036579@sss.pgh.pa.us> -Mime-Version: 1.0 (generated by tm-edit 7.106) -Content-Type: multipart/signed; protocol="application/pgp-signature"; - boundary="pgp-sign-Multipart_Thu_Jun_15_08:29:00_2000-1"; micalg=pgp-md5 -Content-Transfer-Encoding: 7bit -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - - ---pgp-sign-Multipart_Thu_Jun_15_08:29:00_2000-1 -Content-Type: text/plain; charset=US-ASCII - -Then spoke up and said: -> Precedence: bulk -> -> Bruce Momjian writes: -> > But seriously, let me give some background. I used Ingres, that used -> > the VMS file system, but used strange sequential AAAF324 numbers for -> > tables. When someone deleted a table, or we were looking at what tables -> > were using disk space, it was impossible to find the Ingres table names -> > that went with the file. There was a system table that showed it, but -> > it was poorly documented, and if you deleted the table, there was no way -> > to look on the tape to find out which file to restore. -> -> Fair enough, but it seems to me that the answer is to expend some effort -> on system admin support tools. We could do a lot in that line with less -> effort than trying to make a fundamentally mismatched filesystem -> representation do what we need. - -We've been an Ingres shop as long as there's been an Ingres. While -we've also had the problem Bruce noticed with table names, we've -*also* used the trivial fix of running a (simple) Report Writer job -each night, immediately before the backup, that lists all of the -database tables/indicies and the underlying files. - -True, if someone drops/recreates a table twice between backups we -can't find the intermediate file name, but since we also haven't -backed up that filename, this isn't an issue. - -Also, the consistency issue is really not as important as you would -think. If you are restoring a table, you want the information in it, -whether or not it's consistent with anything else. I've done hundreds -of table restores (can you say "modify table to heap"?) and never once -has inconsistency been an issue. Oh, yeah, and we don't shut the -database down for this, either. (That last isn't my choice, BTW.) - --- -===================================================================== -| JAVA must have been developed in the wilds of West Virginia. | -| After all, why else would it support only single inheritance?? | -===================================================================== -| Finger geek@cmu.edu for my public key. | -===================================================================== - ---pgp-sign-Multipart_Thu_Jun_15_08:29:00_2000-1 -Content-Type: application/pgp-signature -Content-Transfer-Encoding: 7bit - ------BEGIN PGP MESSAGE----- -Version: 2.6.2 -Comment: Processed by Mailcrypt 3.3, an Emacs/PGP interface - -iQBVAwUBOUjMDYdzVnzma+gdAQHUowH+JglNasUWT5RKSnF3pzNdy5nyrGmLhbWa -Oom1oUqToxcyfjVFL34dXpnIlvNHO0K2Di4NKZ9HykwOHzrnExf15w== -=yXoe ------END PGP MESSAGE----- - ---pgp-sign-Multipart_Thu_Jun_15_08:29:00_2000-1-- - - -From dhogaza@pacifier.com Thu Jun 15 09:31:05 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id JAA04418 - for ; Thu, 15 Jun 2000 09:31:04 -0400 (EDT) -Received: from smtp.pacifier.com (comet.pacifier.com [199.2.117.155]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id JAA20080 for ; Thu, 15 Jun 2000 09:22:36 -0400 (EDT) -Received: from desktop (dsl-dhogaza.pacifier.net [207.202.226.68]) - by smtp.pacifier.com (8.9.3/8.9.3pop) with SMTP id GAA05755; - Thu, 15 Jun 2000 06:21:54 -0700 (PDT) -Message-Id: <3.0.1.32.20000615054049.011bcec0@mail.pacifier.com> -X-Sender: dhogaza@mail.pacifier.com -X-Mailer: Windows Eudora Pro Version 3.0.1 (32) -Date: Thu, 15 Jun 2000 05:40:49 -0700 -To: Zeugswetter Andreas SB , - Bruce Momjian , Tom Lane -From: Don Baccus -Subject: Re: AW: [HACKERS] Big 7.1 open items -Cc: Jan Wieck , Oliver Elphick , - PostgreSQL-development -In-Reply-To: <219F68D65015D011A8E000006F8590C604AF7DE7@sdexcsrv1.f000.d0 - 188.sd.spardat.at> -Mime-Version: 1.0 -Content-Type: text/plain; charset="us-ascii" -Status: RO - -At 10:04 AM 6/15/00 +0200, Zeugswetter Andreas SB wrote: -> ->> In reality, very few people are going to be interested in restoring ->> a table in a way that breaks referential integrity and other ->> normal assumptions about what exists in the database. -> ->This is not true. In my DBA history it would have saved me manweeks ->of work if an easy and efficient restore of one single table from backup ->would have been available in Informix and Oracle. ->We allways had to restore most of the whole system to another machine only ->to get back at some table info that would then be manually re-added ->to the production system. - -I'm missing something, I guess. You would do a createdb, do a filesystem -copy of pg_log and one file into it, and then read data from the table - without having to restore the other tables in the database? - -I'm just curious - when was the last time you restored a Postgres -database in this piecemeal manner, and how often do you do it? - - - -- Don Baccus, Portland OR - Nature photos, on-line guides, Pacific Northwest - Rare Bird Alert Service and other goodies at - http://donb.photo.net. - -From pgsql-hackers-owner+M3440@hub.org Thu Jun 15 14:46:22 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id OAA04607 - for ; Thu, 15 Jun 2000 14:46:21 -0400 (EDT) -Received: from hub.org (root@hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id MAA12695 for ; Thu, 15 Jun 2000 12:48:58 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5FGjXI40370; - Thu, 15 Jun 2000 12:45:33 -0400 (EDT) -Received: from wallace.ece.rice.edu (wallace.ece.rice.edu [128.42.12.154]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5FGjJI39359 - for ; Thu, 15 Jun 2000 12:45:20 -0400 (EDT) -Received: by rice.edu - via sendmail from stdin - id (Debian Smail3.2.0.102) - for pgsql-hackers@postgresql.org; Thu, 15 Jun 2000 11:45:19 -0500 (CDT) -Date: Thu, 15 Jun 2000 11:45:19 -0500 -From: "Ross J. Reedstrom" -To: Tom Lane -Cc: PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -Message-ID: <20000615114519.B3939@rice.edu> -Mail-Followup-To: Tom Lane , - PostgreSQL-development -References: <16985.961038832@sss.pgh.pa.us> <200006150321.XAA09510@candle.pha.pa.us> <20000615010312.A995@rice.edu> <18798.961053112@sss.pgh.pa.us> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -User-Agent: Mutt/1.0i -In-Reply-To: <18798.961053112@sss.pgh.pa.us>; from tgl@sss.pgh.pa.us on Thu, Jun 15, 2000 at 03:11:52AM -0400 -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: ROr - -On Thu, Jun 15, 2000 at 03:11:52AM -0400, Tom Lane wrote: -> "Ross J. Reedstrom" writes: -> > Any strong objections to the mixed relname_oid solution? -> -> Yes! -> -> You cannot make it work reliably unless the relname part is the original -> relname and does not track ALTER TABLE RENAME. IMHO having an obsolete -> relname in the filename is worse than not having the relname at all; -> it's a recipe for confusion, it means you still need admin tools to tell -> which end is really up, and what's worst is you might think you don't. - -The plan here was to let VACUUM handle renaming the file, since it -will already have all the necessary locks. This shortens the window -of confusion. ALTER TABLE RENAME doesn't happen that often, really - -the relname is there just for human consumption, then. - -> -> Furthermore it requires an additional column in pg_class to keep track -> of the original relname, which is a waste of space and effort. -> - -I actually started down this path thinking about implementing SCHEMA, -since tables in the same DB but in different schema can have the same -relname, I figured I needed to change that. We'll need something in -pg_class to keep track of what schema a relation is in, instead. - -> It also creates a portability risk, or at least fails to remove one, -> since you are critically dependent on the assumption that the OS -> supports long filenames --- on a filesystem that truncates names to less -> than about 45 characters you're in very deep trouble. An OID-only -> approach still works on traditional 14-char-filename Unix filesystems -> (it'd mostly even work on DOS 8+3, though I doubt we care about that). - -Actually, no. Since I store the filename in a name attribute, I used this -nifty function somebody wrote, makeObjectName, to trim the relname part, -but leave the oid. (Yes, I know it's yours ;-) - -> -> Finally, one of the reasons I want to go to filenames based only on OID -> is that that'll make life easier for mdblindwrt. Original relname + OID -> doesn't help, in fact it makes life harder (more shmem space needed to -> keep track of the filename for each buffer). - -Can you explain in more detail how this helps? Not by letting the bufmgr -know that oid == filename, I hope. We need to improving the abstraction -of the smgr, not add another violation. Ah, sorry, mdblindwrt _is_ -in the smgr. - -Hmm, grovelling through that code, I see how it could be simpler if reloid -== filename. Heck, we even get to save shmem in the buffdesc.blind part, -since we only need the dbname in there, now. - -Hmm, I see I missed the relpath_blind() in my patch - oops. (relpath() -is always called with RelationGetPhysicalRelationName(), and that's -where I was putting in the relphysname) - -Hmm, what's all this with functions in catalog.c that are only called by -smgr/md.c? seems to me that anything having to do with physical storage -(like the path!) belongs in the smgr abstraction. - -> -> Can we *PLEASE JUST LET GO* of this bad idea? No relname in the -> filename. Period. -> - -Gee, so dogmatic. No one besides Bruce and Hiroshi discussed this _at -all_ when I first put up patches two month ago. O.K., I'll do the oids -only version (and fix up relpath_blind) - -Ross - --- -Ross J. Reedstrom, Ph.D., -NSBRI Research Scientist/Programmer -Computer and Information Technology Institute -Rice University, 6100 S. Main St., Houston, TX 77005 - -From Inoue@tpf.co.jp Thu Jun 15 17:45:40 2000 -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id RAA27548 - for ; Thu, 15 Jun 2000 17:45:37 -0400 (EDT) -Received: from mcadnote1 (ppm122.noc.fukui.nsk.ne.jp [210.161.188.41]) - by sd.tpf.co.jp (2.5 Build 2640 (Berkeley 8.8.6)/8.8.4) with SMTP - id GAA07248; Fri, 16 Jun 2000 06:45:30 +0900 -From: "Hiroshi Inoue" -To: "Bruce Momjian" , - "Ross J. Reedstrom" -Cc: "Tom Lane" , - "PostgreSQL-development" -Subject: RE: [HACKERS] Big 7.1 open items -Date: Fri, 16 Jun 2000 06:48:21 +0900 -Message-ID: -MIME-Version: 1.0 -Content-Type: text/plain; - charset="us-ascii" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2910.0) -In-Reply-To: <200006151935.PAA17512@candle.pha.pa.us> -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2919.6700 -Importance: Normal -Status: ROr - -> -----Original Message----- -> From: pgsql-hackers-owner@hub.org -> [mailto:pgsql-hackers-owner@hub.org]On Behalf Of Bruce Momjian -> -> > > Can we *PLEASE JUST LET GO* of this bad idea? No relname in the -> > > filename. Period. -> > > -> > -> > Gee, so dogmatic. No one besides Bruce and Hiroshi discussed this _at -> > all_ when I first put up patches two month ago. O.K., I'll do the oids -> > only version (and fix up relpath_blind) -> -> Hold on. I don't think we want that work done yet. Seems even Tom is -> thinking that if Vadim is going to re-do everything later anyway, we may -> be better with a relname/oid solution that does require additional -> administration apps. -> - -Hmm,why is naming rule first ? - -I've never enphasized naming rule except that it should be unique. -It has been my main point to reduce the necessity of naming rule -as possible. IIRC,by keeping the stored place in pg_class,Ross's -trial patch remains only 2 places where naming rule is required. -So wouldn't we be free from naming rule(it would not be so difficult -to change naming rule if the rule is found to be bad) ? - -I've also mentioned many times neither relname nor oid is sufficient -for the uniqueness. In addiiton neither relname nor oid would be -necessary for the uniqueness. -IMHO,it's bad to rely on the item which is neither necessary nor -sufficient. -I proposed relname+unique_id naming once. The unique_id is -independent from oid. The relname is only for convinience for -DBA and so we don't have to change it due to RENAME. -Db's consistency is much more important than dba's satis- -faction. - -Comments ? - -Regards. - -Hiroshi Inoue -Inoue@tpf.co.jp - - -From pgsql-hackers-owner+M3448@hub.org Thu Jun 15 19:01:03 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id TAA00764 - for ; Thu, 15 Jun 2000 19:01:02 -0400 (EDT) -Received: from hub.org (root@hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id SAA17328 for ; Thu, 15 Jun 2000 18:57:32 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5FMsMI97744; - Thu, 15 Jun 2000 18:54:22 -0400 (EDT) -Received: from wallace.ece.rice.edu (wallace.ece.rice.edu [128.42.12.154]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5FMs0I94252 - for ; Thu, 15 Jun 2000 18:54:00 -0400 (EDT) -Received: by rice.edu - via sendmail from stdin - id (Debian Smail3.2.0.102) - for pgsql-hackers@postgresql.org; Thu, 15 Jun 2000 17:53:59 -0500 (CDT) -Date: Thu, 15 Jun 2000 17:53:59 -0500 -From: "Ross J. Reedstrom" -To: PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -Message-ID: <20000615175359.A12194@rice.edu> -Mail-Followup-To: PostgreSQL-development -References: <200006152148.RAA27790@candle.pha.pa.us> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -User-Agent: Mutt/1.0i -In-Reply-To: <200006152148.RAA27790@candle.pha.pa.us>; from pgman@candle.pha.pa.us on Thu, Jun 15, 2000 at 05:48:59PM -0400 -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -On Thu, Jun 15, 2000 at 05:48:59PM -0400, Bruce Momjian wrote: -> > I've also mentioned many times neither relname nor oid is sufficient -> > for the uniqueness. In addiiton neither relname nor oid would be -> > necessary for the uniqueness. -> > IMHO,it's bad to rely on the item which is neither necessary nor -> > sufficient. -> > I proposed relname+unique_id naming once. The unique_id is -> > independent from oid. The relname is only for convinience for -> > DBA and so we don't have to change it due to RENAME. -> > Db's consistency is much more important than dba's satis- -> > faction. -> > -> > Comments ? -> -> I am happy not to rename the file on 'RENAME', but seems no one likes -> that. - -Good, 'cause that's how I've implemented it so far. Actually, all -I've done is port my previous patch to current, with one little -change: I added a macro RelationGetRealRelationName which does what -RelationGetPhysicalRelationName used to do: i.e. return the relname with -no temptable funny business, and used that for the relcache macros. It -passes all the serial regression tests: I haven't run the parallel tests -yet. ALTER TABLE RENAME rollsback nicely. I'll need to learn some omre -about xacts to get DROP TABLE rolling back. - -I'll drop it on PATCHES right now, for comment. - -Ross --- -Ross J. Reedstrom, Ph.D., -NSBRI Research Scientist/Programmer -Computer and Information Technology Institute -Rice University, 6100 S. Main St., Houston, TX 77005 - -From pgsql-hackers-owner+M3451@hub.org Thu Jun 15 20:01:00 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id UAA01651 - for ; Thu, 15 Jun 2000 20:00:59 -0400 (EDT) -Received: from hub.org (root@hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id TAA20985 for ; Thu, 15 Jun 2000 19:57:49 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5FNsgI25402; - Thu, 15 Jun 2000 19:54:42 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5FNsCI22412 - for ; Thu, 15 Jun 2000 19:54:12 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id TAA02263; - Thu, 15 Jun 2000 19:53:52 -0400 (EDT) -To: "Ross J. Reedstrom" -cc: PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <20000615114519.B3939@rice.edu> -References: <16985.961038832@sss.pgh.pa.us> <200006150321.XAA09510@candle.pha.pa.us> <20000615010312.A995@rice.edu> <18798.961053112@sss.pgh.pa.us> <20000615114519.B3939@rice.edu> -Comments: In-reply-to "Ross J. Reedstrom" - message dated "Thu, 15 Jun 2000 11:45:19 -0500" -Date: Thu, 15 Jun 2000 19:53:52 -0400 -Message-ID: <2260.961113232@sss.pgh.pa.us> -From: Tom Lane -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -"Ross J. Reedstrom" writes: -> On Thu, Jun 15, 2000 at 03:11:52AM -0400, Tom Lane wrote: ->> "Ross J. Reedstrom" writes: ->>>> Any strong objections to the mixed relname_oid solution? ->> ->> Yes! - -> The plan here was to let VACUUM handle renaming the file, since it -> will already have all the necessary locks. This shortens the window -> of confusion. ALTER TABLE RENAME doesn't happen that often, really - -> the relname is there just for human consumption, then. - -Yeah, I've seen tons of discussion of how if we do this, that, and -the other thing, and be prepared to fix up some other things in case -of crash recovery, we can make it work with filename == relname + OID -(where relname tracks logical name, at least at some remove). - -Probably. Assuming nobody forgets anything. - -I'm just trying to point out that that's a huge amount of pretty -delicate mechanism. The amount of work required to make it trustworthy -looks to me to dwarf the admin tools that Bruce is complaining about. -And we only have a few people competent to do the work. (With all -due respect, Ross, if you weren't already aware of the implications -for mdblindwrt, I have to wonder what else you missed.) - -Filename == OID is so simple, reliable, and straightforward by -comparison that I think the decision is a no-brainer. - -If we could afford to sink unlimited time into this one issue then -it might make sense to do it the hard way, but we have enough -important stuff on our TODO list to keep us all busy for years --- -I cannot believe that it's an effective use of our time to do this. - - -> Hmm, what's all this with functions in catalog.c that are only called by -> smgr/md.c? seems to me that anything having to do with physical storage -> (like the path!) belongs in the smgr abstraction. - -Yeah, there's a bunch of stuff that should have been implemented by -adding new smgr entry points, but wasn't. It should be pushed down. -(I can't resist pointing out that one of those things is physical -relation rename, which will go away and not *need* to be pushed down -if we do it the way I want.) - - regards, tom lane - -From tgl@sss.pgh.pa.us Thu Jun 15 20:00:59 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id UAA01647 - for ; Thu, 15 Jun 2000 20:00:58 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id TAA21034 for ; Thu, 15 Jun 2000 19:58:30 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id TAA02283; - Thu, 15 Jun 2000 19:57:05 -0400 (EDT) -To: Bruce Momjian -cc: "Ross J. Reedstrom" , - PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <200006151935.PAA17512@candle.pha.pa.us> -References: <200006151935.PAA17512@candle.pha.pa.us> -Comments: In-reply-to Bruce Momjian - message dated "Thu, 15 Jun 2000 15:35:45 -0400" -Date: Thu, 15 Jun 2000 19:57:05 -0400 -Message-ID: <2280.961113425@sss.pgh.pa.us> -From: Tom Lane -Status: RO - -Bruce Momjian writes: ->> Gee, so dogmatic. No one besides Bruce and Hiroshi discussed this _at ->> all_ when I first put up patches two month ago. O.K., I'll do the oids ->> only version (and fix up relpath_blind) - -> Hold on. I don't think we want that work done yet. Seems even Tom is -> thinking that if Vadim is going to re-do everything later anyway, we may -> be better with a relname/oid solution that does require additional -> administration apps. - -Don't put words in my mouth, please. If we are going to throw the -work away later, it'd be foolish to do the much greater amount of -work needed to make filename=relname+OID fly than is needed for -filename=OID. - -However, I'm pretty sure I recall Vadim stating that he thought -filename=OID would be required for his smgr changes anyway... - - regards, tom lane - -From pgsql-hackers-owner+M3453@hub.org Thu Jun 15 21:01:01 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id VAA02731 - for ; Thu, 15 Jun 2000 21:01:01 -0400 (EDT) -Received: from hub.org (root@hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id UAA23469 for ; Thu, 15 Jun 2000 20:36:36 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5G0WDI97134; - Thu, 15 Jun 2000 20:32:13 -0400 (EDT) -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5G0VsI97003 - for ; Thu, 15 Jun 2000 20:31:54 -0400 (EDT) -Received: from cadzone ([126.0.1.40] (may be forged)) - by sd.tpf.co.jp (2.5 Build 2640 (Berkeley 8.8.6)/8.8.4) with SMTP - id JAA07328; Fri, 16 Jun 2000 09:26:04 +0900 -From: "Hiroshi Inoue" -To: "Bruce Momjian" , - "Tom Lane" -Cc: "PostgreSQL-development" , - "Ross J. Reedstrom" -Subject: RE: [HACKERS] Big 7.1 open items -Date: Fri, 16 Jun 2000 09:28:14 +0900 -Message-ID: <000d01bfd729$c24b29c0$2801007e@tpf.co.jp> -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-2022-jp" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 -In-Reply-To: <2260.961113232@sss.pgh.pa.us> -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 -Importance: Normal -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -> -----Original Message----- -> From: pgsql-hackers-owner@hub.org [mailto:pgsql-hackers-owner@hub.org]On -> Behalf Of Tom Lane -> -> "Ross J. Reedstrom" writes: -> > On Thu, Jun 15, 2000 at 03:11:52AM -0400, Tom Lane wrote: -> >> "Ross J. Reedstrom" writes: -> >>>> Any strong objections to the mixed relname_oid solution? -> >> -> >> Yes! -> -> > The plan here was to let VACUUM handle renaming the file, since it -> > will already have all the necessary locks. This shortens the window -> > of confusion. ALTER TABLE RENAME doesn't happen that often, really - -> > the relname is there just for human consumption, then. -> -> Yeah, I've seen tons of discussion of how if we do this, that, and -> the other thing, and be prepared to fix up some other things in case -> of crash recovery, we can make it work with filename == relname + OID -> (where relname tracks logical name, at least at some remove). -> - -I've seen little discussion of how to avoid the use of naming rule. -I've proposed many times that we should keep the information -where the table is stored in our database itself. I've never seen -clear objections to it. So I could understand my proposal is OK ? -Isn't it much more important than naming rule ? Under the -mechanism,we could easily replace bad naming rule. -And I believe that Ross's work is mostly around the mechanism -not naming rule. - -Now I like neither relname nor oid because it's not sufficient -for my purpose. - -Regards. - -Hiroshi Inoue -Inoue@tpf.co.jp - -From tgl@sss.pgh.pa.us Thu Jun 15 22:01:02 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id WAA03637 - for ; Thu, 15 Jun 2000 22:01:01 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id VAA28521 for ; Thu, 15 Jun 2000 21:58:46 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id VAA02730; - Thu, 15 Jun 2000 21:57:27 -0400 (EDT) -To: "Hiroshi Inoue" -cc: "Bruce Momjian" , - "PostgreSQL-development" , - "Ross J. Reedstrom" -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <000d01bfd729$c24b29c0$2801007e@tpf.co.jp> -References: <000d01bfd729$c24b29c0$2801007e@tpf.co.jp> -Comments: In-reply-to "Hiroshi Inoue" - message dated "Fri, 16 Jun 2000 09:28:14 +0900" -Date: Thu, 15 Jun 2000 21:57:27 -0400 -Message-ID: <2727.961120647@sss.pgh.pa.us> -From: Tom Lane -Status: ROr - -"Hiroshi Inoue" writes: -> Now I like neither relname nor oid because it's not sufficient -> for my purpose. - -We should probably not do much of anything with this issue until -we have a clearer understanding of what we want to do about -tablespaces and schemas. - -My gut feeling is that we will end up with pathnames that look -something like - -.../data/base/DBNAME/TABLESPACE/OIDOFRELATION - -(with .N attached if a segment of a large relation, of course). - -The TABLESPACE "name" should likely be an OID itself, but it wouldn't -have to be if you are willing to say that tablespaces aren't renamable. -(Come to think of it, does anyone care about being able to rename -databases? ;-)) Note that the TABLESPACE will often be a symlink -to storage on another drive, rather than a plain subdirectory of the -DBNAME, but that shouldn't be an issue at this level of discussion. - -I think that schemas probably don't enter into this. We should instead -rely on the uniqueness of OIDs to prevent filename collisions. However, -OIDs aren't really unique: different databases in an installation will -use the same OIDs for their system tables. My feeling is that we can -live with a restriction like "you can't store the system tables of -different databases in the same tablespace". Alternatively we could -avoid that issue by inverting the pathname order: - -.../data/base/TABLESPACE/DBNAME/OIDOFRELATION - -Note that in any case, system tables will have to live in a -predetermined tablespace, since you can't very well look in pg_class -to find out which tablespace pg_class lives in. Perhaps we should -just reserve a tablespace per database for system tables and forget -the whole issue. If we do that, there's not really any need for -the database in the path! Just - -.../data/base/TABLESPACE/OIDOFRELATION - -would do fine and help reduce lookup overhead. - -BTW, schemas do make things interesting for the other camp: -is it possible for the same table to be referenced by different -names in different schemas? If so, just how useful is it to pick -one of those names arbitrarily for the filename? This is an advanced -version of the main objection to using the original relname and not -updating it at RENAME TABLE --- sooner or later, the filenames are -going to be more confusing than helpful. - -Comments? Have I missed something important about schemas? - - regards, tom lane - -From pgsql-hackers-owner+M3457@hub.org Thu Jun 15 22:27:45 2000 -Received: from hub.org (root@hub.org [216.126.84.1]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id WAA04586 - for ; Thu, 15 Jun 2000 22:27:44 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5G2POI23418; - Thu, 15 Jun 2000 22:25:24 -0400 (EDT) -Received: from candle.pha.pa.us (pgman@nav-43.dsl.navpoint.com [162.33.245.46]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5G2P3I23299 - for ; Thu, 15 Jun 2000 22:25:04 -0400 (EDT) -Received: (from pgman@localhost) - by candle.pha.pa.us (8.9.0/8.9.0) id WAA04345; - Thu, 15 Jun 2000 22:24:53 -0400 (EDT) -From: Bruce Momjian -Message-Id: <200006160224.WAA04345@candle.pha.pa.us> -Subject: Re: [HACKERS] Big 7.1 open items -In-Reply-To: <2727.961120647@sss.pgh.pa.us> "from Tom Lane at Jun 15, 2000 09:57:27 - pm" -To: Tom Lane -Date: Thu, 15 Jun 2000 22:24:52 -0400 (EDT) -CC: Hiroshi Inoue , Bruce Momjian , - PostgreSQL-development , - "Ross J. Reedstrom" -X-Mailer: ELM [version 2.4ME+ PL77 (25)] -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Content-Type: text/plain; charset=US-ASCII -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -> "Hiroshi Inoue" writes: -> > Now I like neither relname nor oid because it's not sufficient -> > for my purpose. -> -> We should probably not do much of anything with this issue until -> we have a clearer understanding of what we want to do about -> tablespaces and schemas. - -Here is an analysis of our options: - - Work required Disadvantages ----------------------------------------------------------------------------- - -Keep current system no work rename/create no rollback - -relname/oid but less work new pg_class column, -no rename change filename not accurate on - rename - -relname/oid with more work complex code -rename change during -vacuum - -oid filename less work, but confusing to admins - need admin tools - --- - Bruce Momjian | http://www.op.net/~candle - pgman@candle.pha.pa.us | (610) 853-3000 - + If your life is a hard drive, | 830 Blythe Avenue - + Christ can be your backup. | Drexel Hill, Pennsylvania 19026 - -From Inoue@tpf.co.jp Thu Jun 15 22:41:50 2000 -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id WAA05230 - for ; Thu, 15 Jun 2000 22:41:48 -0400 (EDT) -Received: from cadzone ([126.0.1.40] (may be forged)) - by sd.tpf.co.jp (2.5 Build 2640 (Berkeley 8.8.6)/8.8.4) with SMTP - id LAA07495; Fri, 16 Jun 2000 11:41:43 +0900 -From: "Hiroshi Inoue" -To: "Tom Lane" -Cc: "Bruce Momjian" , - "PostgreSQL-development" , - "Ross J. Reedstrom" -Subject: RE: [HACKERS] Big 7.1 open items -Date: Fri, 16 Jun 2000 11:43:52 +0900 -Message-ID: <000201bfd73c$b52873c0$2801007e@tpf.co.jp> -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-2022-jp" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 -In-Reply-To: <2727.961120647@sss.pgh.pa.us> -Importance: Normal -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 -Status: RO - -Sorry for my previous mail. It was posted by my mistake. - -> -----Original Message----- -> From: Tom Lane [mailto:tgl@sss.pgh.pa.us] -> -> "Hiroshi Inoue" writes: -> > Now I like neither relname nor oid because it's not sufficient -> > for my purpose. -> -> We should probably not do much of anything with this issue until -> we have a clearer understanding of what we want to do about -> tablespaces and schemas. -> -> My gut feeling is that we will end up with pathnames that look -> something like -> -> .../data/base/DBNAME/TABLESPACE/OIDOFRELATION -> - -Schema is a logical concept and irrevant to physical location. -I strongly object your suggestion unless above means *default* -location. -Tablespace is an encapsulation of table allocation and the -name should be irrevant to the location basically. So above -seems very bad for me. - -Anyway I don't see any advantage in fixed mapping impleme -ntation. After renewal,we should at least have a possibility to -allocate a specific table in arbitrary separate directory. - -Regards. - -Hiroshi Inoue -Inoue@tpf.co.jp - -From Inoue@tpf.co.jp Thu Jun 15 23:31:00 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id XAA06634; - Thu, 15 Jun 2000 23:30:59 -0400 (EDT) -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id XAA03227; Thu, 15 Jun 2000 23:18:54 -0400 (EDT) -Received: from cadzone ([126.0.1.40] (may be forged)) - by sd.tpf.co.jp (2.5 Build 2640 (Berkeley 8.8.6)/8.8.4) with SMTP - id MAA07544; Fri, 16 Jun 2000 12:18:06 +0900 -From: "Hiroshi Inoue" -To: "Bruce Momjian" , "Tom Lane" -Cc: "Bruce Momjian" , - "PostgreSQL-development" , - "Ross J. Reedstrom" -Subject: RE: [HACKERS] Big 7.1 open items -Date: Fri, 16 Jun 2000 12:20:16 +0900 -Message-ID: <000401bfd741$cabea100$2801007e@tpf.co.jp> -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 -In-Reply-To: <200006160224.WAA04345@candle.pha.pa.us> -Importance: Normal -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 -Status: RO - -> -----Original Message----- -> From: Bruce Momjian [mailto:pgman@candle.pha.pa.us] -> -> > "Hiroshi Inoue" writes: -> > > Now I like neither relname nor oid because it's not sufficient -> > > for my purpose. -> > -> > We should probably not do much of anything with this issue until -> > we have a clearer understanding of what we want to do about -> > tablespaces and schemas. -> -> Here is an analysis of our options: -> -> Work required Disadvantages -> ------------------------------------------------------------------ -> ---------- -> -> Keep current system no work rename/create -> no rollback -> -> relname/oid but less work new pg_class column, -> no rename change filename not -> accurate on -> rename -> -> relname/oid with more work complex code -> rename change during -> vacuum -> -> oid filename less work, but confusing to admins -> need admin tools -> - -Please add my opinion for naming rule. - -relname/unique_id but need some work new pg_class column, -no relname change. for unique-id generation filename not relname - -Regards. - -Hiroshi Inoue -Inoue@tpf.co.jp - -From pgsql-hackers-owner+M3465@hub.org Fri Jun 16 00:01:01 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id AAA06924 - for ; Fri, 16 Jun 2000 00:01:00 -0400 (EDT) -Received: from hub.org (root@hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id XAA05470 for ; Thu, 15 Jun 2000 23:59:46 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5G3uaI10809; - Thu, 15 Jun 2000 23:56:36 -0400 (EDT) -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5G3uKI10702 - for ; Thu, 15 Jun 2000 23:56:21 -0400 (EDT) -Received: from cadzone ([126.0.1.40] (may be forged)) - by sd.tpf.co.jp (2.5 Build 2640 (Berkeley 8.8.6)/8.8.4) with SMTP - id MAA07571; Fri, 16 Jun 2000 12:55:33 +0900 -From: "Hiroshi Inoue" -To: "Tom Lane" -Cc: "PostgreSQL-development" -Subject: RE: [HACKERS] Big 7.1 open items -Date: Fri, 16 Jun 2000 12:57:44 +0900 -Message-ID: <000501bfd747$067f0220$2801007e@tpf.co.jp> -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-2022-jp" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 -In-Reply-To: <3264.961127021@sss.pgh.pa.us> -Importance: Normal -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -> -----Original Message----- -> From: Tom Lane [mailto:tgl@sss.pgh.pa.us] -> -> "Hiroshi Inoue" writes: -> > Please add my opinion for naming rule. -> -> > relname/unique_id but need some work new -> pg_class column, -> > no relname change. for unique-id generation filename not relname -> -> Why is a unique ID better than --- or even different from --- -> using the relation's OID? It seems pointless to me... -> - -For example,in the implementation of CLUSTER command, -we would need another new file for the target relation in -order to put sorted rows but don't we want to change the -OID ? It would be needed for table re-construction generally. -If I remember correectly,you once proposed OID+version -naming for the cases. - -Regards. - -Hiroshi Inoue -Inoue@tpf.co.jp - -From Inoue@tpf.co.jp Fri Jun 16 02:01:00 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id CAA08093 - for ; Fri, 16 Jun 2000 02:00:59 -0400 (EDT) -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id BAA10174 for ; Fri, 16 Jun 2000 01:34:44 -0400 (EDT) -Received: from cadzone ([126.0.1.40] (may be forged)) - by sd.tpf.co.jp (2.5 Build 2640 (Berkeley 8.8.6)/8.8.4) with SMTP - id OAA07656; Fri, 16 Jun 2000 14:33:12 +0900 -From: "Hiroshi Inoue" -To: "Tom Lane" -Cc: "Bruce Momjian" , - "PostgreSQL-development" , - "Ross J. Reedstrom" -Subject: RE: [HACKERS] Big 7.1 open items -Date: Fri, 16 Jun 2000 14:35:21 +0900 -Message-ID: <000001bfd754$a9e44f80$2801007e@tpf.co.jp> -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 -In-Reply-To: <3238.961126521@sss.pgh.pa.us> -Importance: Normal -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 -Status: RO - -> -----Original Message----- -> From: Tom Lane [mailto:tgl@sss.pgh.pa.us] -> -> "Hiroshi Inoue" writes: -> > Tablespace is an encapsulation of table allocation and the -> > name should be irrevant to the location basically. So above -> > seems very bad for me. -> > Anyway I don't see any advantage in fixed mapping impleme -> > ntation. After renewal,we should at least have a possibility to -> > allocate a specific table in arbitrary separate directory. -> -> Call a "directory" a "tablespace" and we're on the same page, -> aren't we? Actually I'd envision some kind of admin command -> "CREATE TABLESPACE foo AS /path/to/wherever". - -Yes,I think 'tablespace -> directory' is the most natural -extension under current file_per_table storage manager. -If many_tables_in_a_file storage manager is introduced,we -may be able to change the definiiton of TABLESPACE -to 'tablespace -> files' like Oracle. - -> That would make -> appropriate system catalog entries and also create a symlink -> from ".../data/base/foo" (or some such place) to the target -> directory. -> Then when we make a table in that tablespace, -> it's in the right place. Problem solved, no? -> - -I don't like symlink for dbms data files. However it may -be OK,If symlink are limited to 'tablespace->directory' -corrspondence and all tablespaces(including default -etc) are symlink. It is simple and all debugging would -be processed under tablespace_is_symlink environment. - -> It gets a little trickier if you want to be able to split -> multi-gig tables across several tablespaces, though, since -> you couldn't just append ".N" to the base table path in that -> scenario. -> - -This seems to be not that easy to solve now. -Ross doesn't change this naming rule for multi-gig -tables either in his trial. - -> I'd be interested to know what sort of facilities Oracle -> provides for managing huge tables... -> - -In my knowledge about old Oracle,one TABLESPACE -could have many DATAFILEs which could contain -many tables. - -Regards. - -Hiroshi Inoue -Inoue@tpf.co.jp - -From pgsql-hackers-owner+M3469@hub.org Fri Jun 16 02:01:03 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id CAA08109 - for ; Fri, 16 Jun 2000 02:01:02 -0400 (EDT) -Received: from hub.org (root@hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id BAA11218 for ; Fri, 16 Jun 2000 01:57:33 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5G5tLI49492; - Fri, 16 Jun 2000 01:55:21 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5G5tAI49395 - for ; Fri, 16 Jun 2000 01:55:10 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id BAA05749; - Fri, 16 Jun 2000 01:54:46 -0400 (EDT) -To: "Hiroshi Inoue" -cc: "PostgreSQL-development" -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <000501bfd747$067f0220$2801007e@tpf.co.jp> -References: <000501bfd747$067f0220$2801007e@tpf.co.jp> -Comments: In-reply-to "Hiroshi Inoue" - message dated "Fri, 16 Jun 2000 12:57:44 +0900" -Date: Fri, 16 Jun 2000 01:54:46 -0400 -Message-ID: <5746.961134886@sss.pgh.pa.us> -From: Tom Lane -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -"Hiroshi Inoue" writes: ->> Why is a unique ID better than --- or even different from --- ->> using the relation's OID? It seems pointless to me... - -> For example,in the implementation of CLUSTER command, -> we would need another new file for the target relation in -> order to put sorted rows but don't we want to change the -> OID ? It would be needed for table re-construction generally. -> If I remember correectly,you once proposed OID+version -> naming for the cases. - -Hmm, so you are thinking that the pg_class row for the table would -include this uniqueID, and then committing the pg_class update would -be the atomic action that replaces the old table contents with the -new? It does have some attraction now that I think about it. - -But there are other ways we could do the same thing. If we want to -have tablespaces, there will need to be a tablespace identifier in -each pg_class row. So we could do CLUSTER in the same way as we'd -move a table from one tablespace to another: create the new files in -the new tablespace directory, and the commit of the new pg_class row -with the new tablespace value is the atomic action that makes the new -files valid and the old files not. - -You will probably say "but I didn't want to move my table to a new -tablespace just to cluster it!" I think we could live with that, -though. A tablespace doesn't need to have any existence more concrete -than a subdirectory, in my vision of the way things would work. We -could do something like making two subdirectories of each place that -the dbadmin designates as a "tablespace", so that we make two logical -tablespaces out of what the dbadmin thinks of as one. Then we can -ping-pong between those directories to do things like clustering "in -place". - -Basically I want to keep the bottom-level mechanisms as simple and -reliable as we possibly can. The fewer concepts are known down at -the bottom, the better. If we can keep the pathname constituents -to just "tablespace" and "relation OID" we'll be in great shape --- -but each additional concept that has to be known down there is -another potential problem. - - regards, tom lane - -From pgsql-hackers-owner+M3471@hub.org Fri Jun 16 03:31:05 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id DAA12816 - for ; Fri, 16 Jun 2000 03:31:04 -0400 (EDT) -Received: from hub.org (root@hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id DAA14405 for ; Fri, 16 Jun 2000 03:03:38 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5G71YI83633; - Fri, 16 Jun 2000 03:01:34 -0400 (EDT) -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5G713I82023 - for ; Fri, 16 Jun 2000 03:01:04 -0400 (EDT) -Received: from cadzone ([126.0.1.40] (may be forged)) - by sd.tpf.co.jp (2.5 Build 2640 (Berkeley 8.8.6)/8.8.4) with SMTP - id QAA07731; Fri, 16 Jun 2000 16:00:57 +0900 -From: "Hiroshi Inoue" -To: "Tom Lane" -Cc: "PostgreSQL-development" -Subject: RE: [HACKERS] Big 7.1 open items -Date: Fri, 16 Jun 2000 16:03:06 +0900 -Message-ID: <000101bfd760$ebcee3e0$2801007e@tpf.co.jp> -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-8859-1" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook 8.5, Build 4.71.2173.0 -In-Reply-To: <5746.961134886@sss.pgh.pa.us> -Importance: Normal -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -> -----Original Message----- -> From: Tom Lane [mailto:tgl@sss.pgh.pa.us] -> -> "Hiroshi Inoue" writes: -> >> Why is a unique ID better than --- or even different from --- -> >> using the relation's OID? It seems pointless to me... -> -> > For example,in the implementation of CLUSTER command, -> > we would need another new file for the target relation in -> > order to put sorted rows but don't we want to change the -> > OID ? It would be needed for table re-construction generally. -> > If I remember correectly,you once proposed OID+version -> > naming for the cases. -> -> Hmm, so you are thinking that the pg_class row for the table would -> include this uniqueID, - -No,I just include the place where the table is stored(pathname under -current file_per_table storage manager) in the pg_class row because -I don't want to rely on table allocating rule(naming rule for current) -to access existent relation files. This has always been my main point. -Many_tables_in_a_file storage manager wouldn't be able to live without -keeping this kind of infomation. -This information(where it is stored) is diffrent from tablespace(where -to store) information. There was an idea to keep the information into -opaque entry in pg_class which only a specific storage manager -could handle. There was an idea to have a new system table which -keeps the information. and so on... - -> and then committing the pg_class update would -> be the atomic action that replaces the old table contents with the -> new? It does have some attraction now that I think about it. -> -> But there are other ways we could do the same thing. If we want to -> have tablespaces, there will need to be a tablespace identifier in -> each pg_class row. So we could do CLUSTER in the same way as we'd -> move a table from one tablespace to another: create the new files in -> the new tablespace directory, and the commit of the new pg_class row -> with the new tablespace value is the atomic action that makes the new -> files valid and the old files not. -> -> You will probably say "but I didn't want to move my table to a new -> tablespace just to cluster it!" - -Yes. - -> I think we could live with that, -> though. A tablespace doesn't need to have any existence more concrete -> than a subdirectory, in my vision of the way things would work. We -> could do something like making two subdirectories of each place that -> the dbadmin designates as a "tablespace", so that we make two logical -> tablespaces out of what the dbadmin thinks of as one. - -Certainly we could design TABLESPACE(where to store) as above. - -> Then we can -> ping-pong between those directories to do things like clustering "in -> place". -> - -But maybe we must keep the directory information where the table was -*ping-ponged* in (e.g.) pg_class. Is such an implementation cleaner or -more extensible than mine(keeping the stored place exactly) ? - -Regards. - -Hiroshi Inoue -Inoue@tpf.co.jp - -From pgsql-hackers-owner+M3473@hub.org Fri Jun 16 04:01:12 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id EAA13087 - for ; Fri, 16 Jun 2000 04:01:11 -0400 (EDT) -Received: from hub.org (root@hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id DAA16002 for ; Fri, 16 Jun 2000 03:37:24 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5G7ZZI51521; - Fri, 16 Jun 2000 03:35:35 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5G7ZEI51350 - for ; Fri, 16 Jun 2000 03:35:14 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id DAA06103; - Fri, 16 Jun 2000 03:34:47 -0400 (EDT) -To: Chris Bitmead -cc: PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <3949BCC4.8424A58F@nimrod.itg.telecom.com.au> -References: <200006142043.WAA07887@hot.jw.home> <16606.961034835@sss.pgh.pa.us> <3949BCC4.8424A58F@nimrod.itg.telecom.com.au> -Comments: In-reply-to Chris Bitmead - message dated "Fri, 16 Jun 2000 15:36:04 +1000" -Date: Fri, 16 Jun 2000 03:34:47 -0400 -Message-ID: <6100.961140887@sss.pgh.pa.us> -From: Tom Lane -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -Chris Bitmead writes: -> Tom Lane wrote: ->> I don't see a lot of value in that. Better to do something like ->> tablespaces: ->> ->> // - -> What is the benefit of having oidoftablespace in the directory path? -> Isn't tablespace an idea so you can store it somewhere completely -> different? -> Or is there some symlink idea or something? - -Exactly --- I'm assuming that the tablespace "directory" is likely -to be a symlink to some other mounted volume. The point here is -to keep the low-level file access routines from having to know very -much about tablespaces or file organization. In the above proposal, -all they need to know is the relation's OID and the name (or OID) -of the tablespace the relation's assigned to; then they can form -a valid path using a hardwired rule. There's still plenty of -flexibility of organization, but it's not necessary to know that -where the rubber meets the road (eg, when you're down inside mdblindwrt -trying to dump a dirty buffer to disk with no spare resources to find -out anything about the relation the page belongs to...) - - regards, tom lane - -From JanWieck@t-online.de Fri Jun 16 11:01:06 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id LAA28913 - for ; Fri, 16 Jun 2000 11:01:05 -0400 (EDT) -Received: from mailout05.sul.t-online.com (mailout05.sul.t-online.com [194.25.134.82]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id KAA01818 for ; Fri, 16 Jun 2000 10:46:42 -0400 (EDT) -Received: from fwd06.sul.t-online.de - by mailout05.sul.t-online.com with smtp - id 132xN9-0006ze-03; Fri, 16 Jun 2000 16:45:27 +0200 -Received: from hot.jw.home (340000654369-0001@[62.158.179.251]) by fwd06.sul.t-online.de - with esmtp id 132xMx-0E54HQC; Fri, 16 Jun 2000 16:45:15 +0200 -Received: (from wieck@localhost) - by hot.jw.home (8.8.5/8.8.5) id OAA15163; - Fri, 16 Jun 2000 14:42:12 +0200 -From: JanWieck@t-online.de (Jan Wieck) -Message-Id: <200006161242.OAA15163@hot.jw.home> -Subject: Re: [HACKERS] Big 7.1 open items -In-Reply-To: <3238.961126521@sss.pgh.pa.us> from Tom Lane at "Jun 15, 2000 11:35:21 - pm" -To: Tom Lane -Date: Fri, 16 Jun 2000 14:42:12 +0200 (MEST) -CC: Hiroshi Inoue , Bruce Momjian , - PostgreSQL-development , - "Ross J. Reedstrom" -Reply-To: Jan Wieck -X-Mailer: ELM [version 2.4ME+ PL68 (25)] -MIME-Version: 1.0 -Content-Type: text/plain; charset=US-ASCII -Content-Transfer-Encoding: 7bit -X-Sender: 340000654369-0001@t-dialin.net -Status: ROr - -Tom Lane wrote: -> -> It gets a little trickier if you want to be able to split -> multi-gig tables across several tablespaces, though, since -> you couldn't just append ".N" to the base table path in that -> scenario. -> -> I'd be interested to know what sort of facilities Oracle -> provides for managing huge tables... - - Oracle tablespaces are a collection of 1...n preallocated - files. Each table then is bound to a tablespace and - allocates extents (chunks) from those files. - - There are some per table attributes that control the extent - sizes with default values coming from the tablespace. The - initial extent size, the nextextent and the pctincrease. - There is a hardcoded limit for the number of extents a table - can have at all. In Oracle7 it was 512 (or somewhat below - - don't recall correct). Maybe that's gone with Oracle8, don't - know. - - This storage concept has IMHO a couple of advatages over - ours. - - The tablespace files are preallocated, so there will - never be a change in block allocation during runtime and - that's the base for fdatasync() beeing sufficient at - syncpoints. All what might be inaccurate after a crash is - the last modified time in the inode, and that's totally - irrelevant for Oracle. The fsck will never fail, and - anything is up to Oracle's recovery. - - The number of total tablespace files is limited to a - value that ensures, that the backends can keep them all - open all the time. It's hard to exceed that limit. A - typical SAP installation with more than 20,000 - tables/indices doesn't need more than 30 or 40 of them. - - It is perfectly prepared for raw devices, since a - tablespace in a raw device installation is simply an area - of blocks on a disk. - - There are also disadvantages. - - You can run out of space even if there are plenty GB's - free on your disks. You have to create tablespaces - explicitly. - - If you've choosen inadequate extent size parameters, you - end up with high fragmented tables (slowing down) or get - stuck with running against maxextents, where only a reorg - (export/import) helps. - - -Jan - --- - -#======================================================================# -# It's easier to get forgiveness for being wrong than for being right. # -# Let's break this rule - forgive me. # -#================================================== JanWieck@Yahoo.com # - - - -From tgl@sss.pgh.pa.us Fri Jun 16 11:00:40 2000 -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id LAA28898 - for ; Fri, 16 Jun 2000 11:00:39 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id LAA07184; - Fri, 16 Jun 2000 11:00:35 -0400 (EDT) -To: Jan Wieck -cc: Hiroshi Inoue , Bruce Momjian , - PostgreSQL-development , - "Ross J. Reedstrom" -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <200006161242.OAA15163@hot.jw.home> -References: <200006161242.OAA15163@hot.jw.home> -Comments: In-reply-to JanWieck@t-online.de (Jan Wieck) - message dated "Fri, 16 Jun 2000 14:42:12 +0200" -Date: Fri, 16 Jun 2000 11:00:35 -0400 -Message-ID: <7181.961167635@sss.pgh.pa.us> -From: Tom Lane -Status: RO - -JanWieck@t-online.de (Jan Wieck) writes: -> There are also disadvantages. - -> You can run out of space even if there are plenty GB's -> free on your disks. You have to create tablespaces -> explicitly. - -Not to mention the reverse: if I read this right, you have to suck -up your GB's long in advance of actually needing them. That's OK -for a machine that's dedicated to Oracle ... not so OK for smaller -installations, playpens, etc. - -I'm not convinced that there's anything fundamentally wrong with -doing storage allocation in Unix files the way we have been. - -(At least not when we're sitting atop a well-done filesystem, -which may leave the Linux folk out in the cold ;-).) - - regards, tom lane - -From tgl@sss.pgh.pa.us Fri Jun 16 12:01:03 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id MAA29853 - for ; Fri, 16 Jun 2000 12:01:02 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id LAA08255 for ; Fri, 16 Jun 2000 11:48:10 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id LAA07461; - Fri, 16 Jun 2000 11:46:41 -0400 (EDT) -To: Jan Wieck -cc: Hiroshi Inoue , Bruce Momjian , - PostgreSQL-development , - "Ross J. Reedstrom" -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <200006161242.OAA15163@hot.jw.home> -References: <200006161242.OAA15163@hot.jw.home> -Comments: In-reply-to JanWieck@t-online.de (Jan Wieck) - message dated "Fri, 16 Jun 2000 14:42:12 +0200" -Date: Fri, 16 Jun 2000 11:46:41 -0400 -Message-ID: <7458.961170401@sss.pgh.pa.us> -From: Tom Lane -Status: RO - -JanWieck@t-online.de (Jan Wieck) writes: -> Tom Lane wrote: ->> It gets a little trickier if you want to be able to split ->> multi-gig tables across several tablespaces, though, since ->> you couldn't just append ".N" to the base table path in that ->> scenario. ->> ->> I'd be interested to know what sort of facilities Oracle ->> provides for managing huge tables... - -> Oracle tablespaces are a collection of 1...n preallocated -> files. Each table then is bound to a tablespace and -> allocates extents (chunks) from those files. - -OK, to get back to the point here: so in Oracle, tables can't cross -tablespace boundaries, but a tablespace itself could span multiple -disks? - -Not sure if I like that better or worse than equating a tablespace -with a directory (so, presumably, all the files within it live on -one filesystem) and then trying to make tables able to span -tablespaces. We will need to do one or the other though, if we want -to have any significant improvement over the current state of affairs -for large tables. - -One way is to play the flip-the-path-ordering game some more, -and access multiple-segment tables with pathnames like this: - - .../TABLESPACE/RELATION -- first or only segment - .../TABLESPACE/N/RELATION -- N'th extension segment - -This isn't any harder for md.c to deal with than what we do now, -but by making the /N subdirectories be symlinks, the dbadmin could -easily arrange for extension segments to go on different filesystems. -Also, since /N subdirectory symlinks can be added as needed, -expanding available space by attaching more disks isn't hard. -(If the admin hasn't pre-made a /N symlink when it's needed, -I'd envision the backend just automatically creating a plain -subdirectory so that it can extend the table.) - -A limitation is that the N'th extension segments of all the relations -in a given tablespace have to be in the same place, but I don't see -that as a major objection. Worst case is you make a separate tablespace -for each of your multi-gig relations ... you're probably not going to -have a very large number of such relations, so this doesn't seem like -unmanageable admin complexity. - -We'd still want to create some tools to help the dbadmin with slinging -all these symlinks around, of course. But I think it's critical to keep -the low-level file access protocol simple and reliable, which really -means minimizing the amount of information the backend needs to know to -figure out which file to write a page in. With something like the above -you only need to know the tablespace name (or more likely OID), the -relation OID (+name or not, depending on outcome of other argument), -and the offset in the table. No worse than now from the software's -point of view. - -Comments? - - regards, tom lane - -From lockhart@alumni.caltech.edu Fri Jun 16 12:31:50 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id MAA00649 - for ; Fri, 16 Jun 2000 12:31:49 -0400 (EDT) -Received: from huey.jpl.nasa.gov (huey.jpl.nasa.gov [128.149.68.100]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id MAA13118 for ; Fri, 16 Jun 2000 12:31:52 -0400 (EDT) -Received: from golem.jpl.nasa.gov (hectic-1 [128.149.68.203]) - by huey.jpl.nasa.gov (8.8.8+Sun/8.8.8) with ESMTP id JAA15007; - Fri, 16 Jun 2000 09:27:18 -0700 (PDT) -Received: from alumni.caltech.edu (localhost.localdomain [127.0.0.1]) - by golem.jpl.nasa.gov (Postfix) with ESMTP - id DD8426F51; Fri, 16 Jun 2000 16:27:22 +0000 (UTC) -Sender: lockhart@mythos.jpl.nasa.gov -Message-ID: <394A556A.4EAC8B9A@alumni.caltech.edu> -Date: Fri, 16 Jun 2000 16:27:22 +0000 -From: Thomas Lockhart -Organization: Yes -X-Mailer: Mozilla 4.7 [en] (X11; I; Linux 2.2.14-15mdksmp i686) -X-Accept-Language: en -MIME-Version: 1.0 -To: Tom Lane -Cc: Jan Wieck , Hiroshi Inoue , - Bruce Momjian , - PostgreSQL-development , - "Ross J. Reedstrom" -Subject: Re: [HACKERS] Big 7.1 open items -References: <200006161242.OAA15163@hot.jw.home> <7458.961170401@sss.pgh.pa.us> -Content-Type: text/plain; charset=us-ascii -Content-Transfer-Encoding: 7bit -Status: RO - -> ... But I think it's critical to keep -> the low-level file access protocol simple and reliable, which really -> means minimizing the amount of information the backend needs to know -> to figure out which file to write a page in. With something like the -> above you only need to know the tablespace name (or more likely OID), -> the relation OID (+name or not, depending on outcome of other -> argument), and the offset in the table. No worse than now from the -> software's point of view. -> Comments? - -I'm probably missing the context a bit, but imho we should try hard to -stay away from symlinks as the general solution for anything. - -Sorry for being behind here, but to make sure I'm on the right page: -o tablespaces decouple storage from logical tables -o a database lives in a default tablespace, unless specified -o by default, a table will live in the default tablespace -o (eventually) a table can be split across tablespaces - -Some thoughts: -o the ability to split single tables across disks was essential for -scalability when disks were small. But with RAID, NAS, etc etc isn't -that a smaller issue now? -o "tablespaces" would implement our less-developed "with location" -feature, right? Splitting databases, whole indices and whole tables -across storage is the biggest win for this work since more users will -use the feature. -o location information needs to travel with individual tables anyway. - -From scrappy@hub.org Fri Jun 16 13:01:02 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id NAA01191; - Fri, 16 Jun 2000 13:01:01 -0400 (EDT) -Received: from thelab.hub.org (nat193.152.mpoweredpc.net [142.177.193.152]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id MAA15282; Fri, 16 Jun 2000 12:53:23 -0400 (EDT) -Received: from localhost (scrappy@localhost) - by thelab.hub.org (8.9.3/8.9.3) with ESMTP id NAA28326; - Fri, 16 Jun 2000 13:50:37 -0300 (ADT) - (envelope-from scrappy@hub.org) -X-Authentication-Warning: thelab.hub.org: scrappy owned process doing -bs -Date: Fri, 16 Jun 2000 13:50:37 -0300 (ADT) -From: The Hermit Hacker -To: Bruce Momjian -cc: Tom Lane , Hiroshi Inoue , - Bruce Momjian , - PostgreSQL-development , - "Ross J. Reedstrom" -Subject: Re: [HACKERS] Big 7.1 open items -In-Reply-To: <200006160224.WAA04345@candle.pha.pa.us> -Message-ID: -MIME-Version: 1.0 -Content-Type: TEXT/PLAIN; charset=US-ASCII -Status: RO - -On Thu, 15 Jun 2000, Bruce Momjian wrote: - -> > "Hiroshi Inoue" writes: -> > > Now I like neither relname nor oid because it's not sufficient -> > > for my purpose. -> > -> > We should probably not do much of anything with this issue until -> > we have a clearer understanding of what we want to do about -> > tablespaces and schemas. -> -> Here is an analysis of our options: -> -> Work required Disadvantages -> ---------------------------------------------------------------------------- -> -> Keep current system no work rename/create no rollback -> -> relname/oid but less work new pg_class column, -> no rename change filename not accurate on -> rename -> -> relname/oid with more work complex code -> rename change during -> vacuum -> -> oid filename less work, but confusing to admins -> need admin tools - -My vote is with Tom on this one ... oid only ... the admin should be able -to do a quick SELECT on a table to find out the OID->table mapping, and I -believe its already been pointed out that you cant' just restore one file -anyway, so it kinda negates the "server isn't running problem" ... - - - - -From tgl@sss.pgh.pa.us Fri Jun 16 13:01:01 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id NAA01188 - for ; Fri, 16 Jun 2000 13:01:01 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id MAA15530 for ; Fri, 16 Jun 2000 12:55:38 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id MAA07750; - Fri, 16 Jun 2000 12:54:00 -0400 (EDT) -To: Thomas Lockhart -cc: Jan Wieck , Hiroshi Inoue , - Bruce Momjian , - PostgreSQL-development , - "Ross J. Reedstrom" -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <394A556A.4EAC8B9A@alumni.caltech.edu> -References: <200006161242.OAA15163@hot.jw.home> <7458.961170401@sss.pgh.pa.us> <394A556A.4EAC8B9A@alumni.caltech.edu> -Comments: In-reply-to Thomas Lockhart - message dated "Fri, 16 Jun 2000 16:27:22 -0000" -Date: Fri, 16 Jun 2000 12:54:00 -0400 -Message-ID: <7747.961174440@sss.pgh.pa.us> -From: Tom Lane -Status: RO - -Thomas Lockhart writes: ->> ... But I think it's critical to keep ->> the low-level file access protocol simple and reliable, which really ->> means minimizing the amount of information the backend needs to know ->> to figure out which file to write a page in. With something like the ->> above you only need to know the tablespace name (or more likely OID), ->> the relation OID (+name or not, depending on outcome of other ->> argument), and the offset in the table. No worse than now from the ->> software's point of view. ->> Comments? - -> I'm probably missing the context a bit, but imho we should try hard to -> stay away from symlinks as the general solution for anything. - -Why? - - regards, tom lane - -From dhogaza@pacifier.com Fri Jun 16 14:55:00 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id OAA02086 - for ; Fri, 16 Jun 2000 14:54:59 -0400 (EDT) -Received: from smtp.pacifier.com (comet.pacifier.com [199.2.117.155]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id OAA26430 for ; Fri, 16 Jun 2000 14:40:00 -0400 (EDT) -Received: from desktop (dsl-dhogaza.pacifier.net [207.202.226.68]) - by smtp.pacifier.com (8.9.3/8.9.3pop) with SMTP id LAA08661; - Fri, 16 Jun 2000 11:38:36 -0700 (PDT) -Message-Id: <3.0.1.32.20000616105023.011dbdb0@mail.pacifier.com> -X-Sender: dhogaza@mail.pacifier.com -X-Mailer: Windows Eudora Pro Version 3.0.1 (32) -Date: Fri, 16 Jun 2000 10:50:23 -0700 -To: Tom Lane , Jan Wieck -From: Don Baccus -Subject: Re: [HACKERS] Big 7.1 open items -Cc: Hiroshi Inoue , Bruce Momjian , - PostgreSQL-development , - "Ross J. Reedstrom" -In-Reply-To: <7458.961170401@sss.pgh.pa.us> -References: <200006161242.OAA15163@hot.jw.home> - <200006161242.OAA15163@hot.jw.home> -Mime-Version: 1.0 -Content-Type: text/plain; charset="us-ascii" -Status: RO - -At 11:46 AM 6/16/00 -0400, Tom Lane wrote: - ->OK, to get back to the point here: so in Oracle, tables can't cross ->tablespace boundaries, - -Right, the construct AFAIK is "create table/index foo on tablespace ..." - -> but a tablespace itself could span multiple ->disks? - -Right. - ->Not sure if I like that better or worse than equating a tablespace ->with a directory (so, presumably, all the files within it live on ->one filesystem) and then trying to make tables able to span ->tablespaces. We will need to do one or the other though, if we want ->to have any significant improvement over the current state of affairs ->for large tables. - -Oracle's way does a reasonable job of isolating the datamodel -from the details of the physical layout. - -Take the OpenACS web toolkit, for instance. We could take -each module's tables and indices and assign them appropriately -to various dataspaces, then provide a separate .sql files with -only "create tablespace" statements in there. - -By modifying that one central file, the toolkit installation -could be customized to run anything from a small site (one -disk with everything on it, ala my own personal webserver at -birdnotes.net) or a very large site with many spindles, with -various index and table structures spread out widely hither -and thither. - -Given that the OpenACS datamodel is nearly 10K lines long (including -many comments, of course), being able to customize an installation -to such a degree by modifying a single file filled with "create -tablespaces" would be very attractive. - ->One way is to play the flip-the-path-ordering game some more, ->and access multiple-segment tables with pathnames like this: -> -> .../TABLESPACE/RELATION -- first or only segment -> .../TABLESPACE/N/RELATION -- N'th extension segment -> ->This isn't any harder for md.c to deal with than what we do now, ->but by making the /N subdirectories be symlinks, the dbadmin could ->easily arrange for extension segments to go on different filesystems. - -I personally dislike depending on symlinks to move stuff around. -Among other things, a pg_dump/restore (and presumably future -backup tools?) can't recreate the disk layout automatically. - ->We'd still want to create some tools to help the dbadmin with slinging ->all these symlinks around, of course. - -OK, if symlinks are simply an implementation detail hidden from the -dbadmin, and if the physical structure is kept in the db so it can -be rebuilt if necessary automatically, then I don't mind symlinks. - -> But I think it's critical to keep ->the low-level file access protocol simple and reliable, which really ->means minimizing the amount of information the backend needs to know to ->figure out which file to write a page in. With something like the above ->you only need to know the tablespace name (or more likely OID), the ->relation OID (+name or not, depending on outcome of other argument), ->and the offset in the table. No worse than now from the software's ->point of view. - -Make the code that creates and otherwise manipulates tablespaces -do the work, while keeping the low-level file access protocol simple. - -Yes, this approach sounds very good to me. - - - -- Don Baccus, Portland OR - Nature photos, on-line guides, Pacific Northwest - Rare Bird Alert Service and other goodies at - http://donb.photo.net. - -From pgsql-hackers-owner+M3500@hub.org Fri Jun 16 14:55:10 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id OAA02107 - for ; Fri, 16 Jun 2000 14:55:09 -0400 (EDT) -Received: from hub.org (root@hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id OAA26943 for ; Fri, 16 Jun 2000 14:44:12 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5GIelM05972; - Fri, 16 Jun 2000 14:40:47 -0400 (EDT) -Received: from smtp.pacifier.com (comet.pacifier.com [199.2.117.155]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5GIe5M05692 - for ; Fri, 16 Jun 2000 14:40:05 -0400 (EDT) -Received: from desktop (dsl-dhogaza.pacifier.net [207.202.226.68]) - by smtp.pacifier.com (8.9.3/8.9.3pop) with SMTP id LAA08667; - Fri, 16 Jun 2000 11:38:41 -0700 (PDT) -Message-Id: <3.0.1.32.20000616111435.01a17a10@mail.pacifier.com> -X-Sender: dhogaza@mail.pacifier.com -X-Mailer: Windows Eudora Pro Version 3.0.1 (32) -Date: Fri, 16 Jun 2000 11:14:35 -0700 -To: Thomas Lockhart , - Tom Lane -From: Don Baccus -Subject: Re: [HACKERS] Big 7.1 open items -Cc: Jan Wieck , Hiroshi Inoue , - Bruce Momjian , - PostgreSQL-development , - "Ross J. Reedstrom" -In-Reply-To: <394A556A.4EAC8B9A@alumni.caltech.edu> -References: <200006161242.OAA15163@hot.jw.home> - <7458.961170401@sss.pgh.pa.us> -Mime-Version: 1.0 -Content-Type: text/plain; charset="us-ascii" -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -At 04:27 PM 6/16/00 +0000, Thomas Lockhart wrote: - ->Sorry for being behind here, but to make sure I'm on the right page: ->o tablespaces decouple storage from logical tables ->o a database lives in a default tablespace, unless specified ->o by default, a table will live in the default tablespace ->o (eventually) a table can be split across tablespaces - -Or tablespaces across filesystems/mountpoints whatever. - ->Some thoughts: ->o the ability to split single tables across disks was essential for ->scalability when disks were small. But with RAID, NAS, etc etc isn't ->that a smaller issue now? - -Yes for size issues, I should think, especially if you have the -money for a large RAID subsystem. But for throughput performance, -control over which spindles particularly busy tables and indices -go on would still seem to be pretty relevant, when they're being -updated a lot. In order to minimize seek times. - -I really can't say how important this is in reality. Oracle-world -folks still talk about this kind of optimization being important, -but I'm not personally running any kind of database-backed website -that's busy enough or contains enough storage to worry about it. - ->o "tablespaces" would implement our less-developed "with location" ->feature, right? Splitting databases, whole indices and whole tables ->across storage is the biggest win for this work since more users will ->use the feature. ->o location information needs to travel with individual tables anyway. - - - -- Don Baccus, Portland OR - Nature photos, on-line guides, Pacific Northwest - Rare Bird Alert Service and other goodies at - http://donb.photo.net. - -From tgl@sss.pgh.pa.us Fri Jun 16 15:00:55 2000 -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id PAA02397 - for ; Fri, 16 Jun 2000 15:00:54 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id PAA08247; - Fri, 16 Jun 2000 15:00:11 -0400 (EDT) -To: Don Baccus -cc: Jan Wieck , Hiroshi Inoue , - Bruce Momjian , - PostgreSQL-development , - "Ross J. Reedstrom" -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <3.0.1.32.20000616105023.011dbdb0@mail.pacifier.com> -References: <200006161242.OAA15163@hot.jw.home> <200006161242.OAA15163@hot.jw.home> <3.0.1.32.20000616105023.011dbdb0@mail.pacifier.com> -Comments: In-reply-to Don Baccus - message dated "Fri, 16 Jun 2000 10:50:23 -0700" -Date: Fri, 16 Jun 2000 15:00:10 -0400 -Message-ID: <8244.961182010@sss.pgh.pa.us> -From: Tom Lane -Status: RO - -Don Baccus writes: ->> This isn't any harder for md.c to deal with than what we do now, ->> but by making the /N subdirectories be symlinks, the dbadmin could ->> easily arrange for extension segments to go on different filesystems. - -> I personally dislike depending on symlinks to move stuff around. -> Among other things, a pg_dump/restore (and presumably future -> backup tools?) can't recreate the disk layout automatically. - -Good point, we'd need some way of saving/restoring the tablespace -structures. - ->> We'd still want to create some tools to help the dbadmin with slinging ->> all these symlinks around, of course. - -> OK, if symlinks are simply an implementation detail hidden from the -> dbadmin, and if the physical structure is kept in the db so it can -> be rebuilt if necessary automatically, then I don't mind symlinks. - -I'm not sure about keeping it in the db --- creates a bit of a -chicken-and-egg problem doesn't it? Maybe there needs to be a -"system database" that has nailed-down pathnames (no tablespaces -for you baby) and contains the critical installation-wide tables -like pg_database, pg_user, pg_tablespace. A restore would have -to restore these tables first anyway. - -> Make the code that creates and otherwise manipulates tablespaces -> do the work, while keeping the low-level file access protocol simple. - -Right, that's the bottom line for me. - - regards, tom lane - -From reedstrm@rice.edu Fri Jun 16 16:51:50 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id QAA03689 - for ; Fri, 16 Jun 2000 16:51:49 -0400 (EDT) -Received: from wallace.ece.rice.edu (wallace.ece.rice.edu [128.42.12.154]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id PAA03409 for ; Fri, 16 Jun 2000 15:48:40 -0400 (EDT) -Received: by rice.edu - via sendmail from stdin - id (Debian Smail3.2.0.102) - for maillist@candle.pha.pa.us; Fri, 16 Jun 2000 14:35:28 -0500 (CDT) -Date: Fri, 16 Jun 2000 14:35:28 -0500 -From: "Ross J. Reedstrom" -To: Thomas Lockhart -Cc: Tom Lane , Jan Wieck , - Hiroshi Inoue , - Bruce Momjian , - PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -Message-ID: <20000616143528.A28920@rice.edu> -Mail-Followup-To: Thomas Lockhart , - Tom Lane , Jan Wieck , - Hiroshi Inoue , - Bruce Momjian , - PostgreSQL-development -References: <200006161242.OAA15163@hot.jw.home> <7458.961170401@sss.pgh.pa.us> <394A556A.4EAC8B9A@alumni.caltech.edu> -Mime-Version: 1.0 -Content-Type: text/plain; charset=iso-8859-1 -Content-Transfer-Encoding: 8bit -User-Agent: Mutt/1.0i -In-Reply-To: <394A556A.4EAC8B9A@alumni.caltech.edu>; from lockhart@alumni.caltech.edu on Fri, Jun 16, 2000 at 04:27:22PM +0000 -Status: RO - -On Fri, Jun 16, 2000 at 04:27:22PM +0000, Thomas Lockhart wrote: -> > ... But I think it's critical to keep -> > the low-level file access protocol simple and reliable, which really -> > means minimizing the amount of information the backend needs to know -> > to figure out which file to write a page in. With something like the -> > above you only need to know the tablespace name (or more likely OID), -> > the relation OID (+name or not, depending on outcome of other -> > argument), and the offset in the table. No worse than now from the -> > software's point of view. -> > Comments? - -I think the backend needs a per table token that indicates how -to get at the physical bits of the file. Whether that's a filename -alone, filename with path, oid, key to a smgr hash table or something -else, it's opaque above the smgr routines. - -Hmm, now I'm thinking, since the tablespace discussion has been reopened, -the way to go about coding all this is to reactivate the smgr code: how -about I leave the existing md smgr as is, and clone it, call it md2 or -something, and start messing with adding features there? - - -> -> I'm probably missing the context a bit, but imho we should try hard to -> stay away from symlinks as the general solution for anything. -> -> Sorry for being behind here, but to make sure I'm on the right page: -> o tablespaces decouple storage from logical tables -> o a database lives in a default tablespace, unless specified -> o by default, a table will live in the default tablespace -> o (eventually) a table can be split across tablespaces -> -> Some thoughts: -> o the ability to split single tables across disks was essential for -> scalability when disks were small. But with RAID, NAS, etc etc isn't -> that a smaller issue now? -> o "tablespaces" would implement our less-developed "with location" -> feature, right? Splitting databases, whole indices and whole tables -> across storage is the biggest win for this work since more users will -> use the feature. -> o location information needs to travel with individual tables anyway. - -I was juist thinking that that discussion needed some summation. - -Some links to historic discussion: - -This one is Vadim saying WAL will need oids names: -http://www.postgresql.org/mhonarc/pgsql-hackers/1999-11/msg00809.html - -A longer discussion kicked off by Don Baccus: -http://www.postgresql.org/mhonarc/pgsql-hackers/2000-01/msg00510.html - -Tom suggesting OIDs to allow rollback: -http://www.postgresql.org/mhonarc/pgsql-hackers/2000-03/msg00119.html - - -Martin Neumann posted an question on dataspaces: - -(can't find it in the offical archives: looks like March 2000, 10-29 is -missing. here's my copy: don't beat on it! n particular, since I threw -it together for local access, it's one _big_ index page) - -http://cooker.ir.rice.edu/postgresql/msg20257.html -(in that thread is a post where I mention blindwrites and getting rid -of GetRawDatabaseInfo) - -Martin later posted an RFD on tablespaces: - -http://cooker.ir.rice.edu/postgresql/msg20490.html - -Here's Horák Daniel with a patch for discussion, implementing dataspaces -on a per database level: - -http://cooker.ir.rice.edu/postgresql/msg20498.html - -Ross --- -Ross J. Reedstrom, Ph.D., -NSBRI Research Scientist/Programmer -Computer and Information Technology Institute -Rice University, 6100 S. Main St., Houston, TX 77005 - -From dhogaza@pacifier.com Fri Jun 16 16:51:51 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id QAA03692 - for ; Fri, 16 Jun 2000 16:51:50 -0400 (EDT) -Received: from smtp.pacifier.com (comet.pacifier.com [199.2.117.155]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id PAA02911 for ; Fri, 16 Jun 2000 15:43:13 -0400 (EDT) -Received: from desktop (dsl-dhogaza.pacifier.net [207.202.226.68]) - by smtp.pacifier.com (8.9.3/8.9.3pop) with SMTP id MAA11003; - Fri, 16 Jun 2000 12:41:50 -0700 (PDT) -Message-Id: <3.0.1.32.20000616123736.01a19910@mail.pacifier.com> -X-Sender: dhogaza@mail.pacifier.com -X-Mailer: Windows Eudora Pro Version 3.0.1 (32) -Date: Fri, 16 Jun 2000 12:37:36 -0700 -To: Tom Lane -From: Don Baccus -Subject: Re: [HACKERS] Big 7.1 open items -Cc: Jan Wieck , Hiroshi Inoue , - Bruce Momjian , - PostgreSQL-development , - "Ross J. Reedstrom" -In-Reply-To: <8244.961182010@sss.pgh.pa.us> -References: <3.0.1.32.20000616105023.011dbdb0@mail.pacifier.com> - <200006161242.OAA15163@hot.jw.home> - <200006161242.OAA15163@hot.jw.home> - <3.0.1.32.20000616105023.011dbdb0@mail.pacifier.com> -Mime-Version: 1.0 -Content-Type: text/plain; charset="us-ascii" -Status: RO - -At 03:00 PM 6/16/00 -0400, Tom Lane wrote: - ->> OK, if symlinks are simply an implementation detail hidden from the ->> dbadmin, and if the physical structure is kept in the db so it can ->> be rebuilt if necessary automatically, then I don't mind symlinks. -> ->I'm not sure about keeping it in the db --- creates a bit of a ->chicken-and-egg problem doesn't it? - -Not if the tablespace creates preceeds the tables stored in them. - -> Maybe there needs to be a ->"system database" that has nailed-down pathnames (no tablespaces ->for you baby) and contains the critical installation-wide tables ->like pg_database, pg_user, pg_tablespace. A restore would have ->to restore these tables first anyway. - -Oh, I see. Yes, when I've looked into this and have thought about -it I've assumed that there would always be a known starting point -which would contain the installation-wide tables. - ->From a practical point of view, I don't think that's really a -problem. - -I've not looked into how Oracle does this, I assume it builds -a system tablespace on one of the initial mount points you give -it when you install the thing. The paths to the mount points -are stored in specific files known to Oracle, I think. It's -been over a year (not long enough!) since I've set up Oracle... - - - - -- Don Baccus, Portland OR - Nature photos, on-line guides, Pacific Northwest - Rare Bird Alert Service and other goodies at - http://donb.photo.net. - -From pgsql-hackers-owner+M3512@hub.org Fri Jun 16 17:31:04 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id RAA04168 - for ; Fri, 16 Jun 2000 17:31:03 -0400 (EDT) -Received: from hub.org (root@hub.org [216.126.84.1]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id RAA12122 for ; Fri, 16 Jun 2000 17:09:28 -0400 (EDT) -Received: from hub.org (majordom@localhost [127.0.0.1]) - by hub.org (8.10.1/8.10.1) with SMTP id e5GL7WM02231; - Fri, 16 Jun 2000 17:07:32 -0400 (EDT) -Received: from wallace.ece.rice.edu (wallace.ece.rice.edu [128.42.12.154]) - by hub.org (8.10.1/8.10.1) with ESMTP id e5GL7EM02150 - for ; Fri, 16 Jun 2000 17:07:14 -0400 (EDT) -Received: by rice.edu - via sendmail from stdin - id (Debian Smail3.2.0.102) - for pgsql-hackers@postgresql.org; Fri, 16 Jun 2000 16:07:13 -0500 (CDT) -Date: Fri, 16 Jun 2000 16:07:13 -0500 -From: "Ross J. Reedstrom" -To: Tom Lane -Cc: pgsql-hackers@postgresql.org -Subject: Re: [HACKERS] Big 7.1 open items -Message-ID: <20000616160713.A30793@rice.edu> -Mail-Followup-To: Tom Lane , - pgsql-hackers@postgresql.org -References: <16985.961038832@sss.pgh.pa.us> <200006150321.XAA09510@candle.pha.pa.us> <20000615010312.A995@rice.edu> <18798.961053112@sss.pgh.pa.us> <20000615114519.B3939@rice.edu> <2260.961113232@sss.pgh.pa.us> -Mime-Version: 1.0 -Content-Type: text/plain; charset=us-ascii -User-Agent: Mutt/1.0i -In-Reply-To: <2260.961113232@sss.pgh.pa.us>; from tgl@sss.pgh.pa.us on Thu, Jun 15, 2000 at 07:53:52PM -0400 -X-Mailing-List: pgsql-hackers@postgresql.org -Precedence: bulk -Sender: pgsql-hackers-owner@hub.org -Status: RO - -On Thu, Jun 15, 2000 at 07:53:52PM -0400, Tom Lane wrote: -> "Ross J. Reedstrom" writes: -> > On Thu, Jun 15, 2000 at 03:11:52AM -0400, Tom Lane wrote: -> >> "Ross J. Reedstrom" writes: -> >>>> Any strong objections to the mixed relname_oid solution? -> >> -> >> Yes! -> -> > The plan here was to let VACUUM handle renaming the file, since it -> > will already have all the necessary locks. This shortens the window -> > of confusion. ALTER TABLE RENAME doesn't happen that often, really - -> > the relname is there just for human consumption, then. -> -> Yeah, I've seen tons of discussion of how if we do this, that, and -> the other thing, and be prepared to fix up some other things in case -> of crash recovery, we can make it work with filename == relname + OID -> (where relname tracks logical name, at least at some remove). -> -> Probably. Assuming nobody forgets anything. - -I agree, it seems a major undertaking, at first glance. And second. Even -third. Especially for someone who hasn't 'earned his spurs' yet. as -it were. - -> I'm just trying to point out that that's a huge amount of pretty -> delicate mechanism. The amount of work required to make it trustworthy -> looks to me to dwarf the admin tools that Bruce is complaining about. -> And we only have a few people competent to do the work. (With all -> due respect, Ross, if you weren't already aware of the implications -> for mdblindwrt, I have to wonder what else you missed.) - -Ah, you knew that comment would come back to haunt me (I have a -tendency to think out loud, even if checking and coming back latter -would be better;-) In fact, there's no problem, and never was, since the -buffer->blind.relname is filled in via RelationGetPhysicalRelationName, -just like every other path that requires direct file access. I just -didn't remember that I had in fact checked it (it's been a couple months, -and I just got back from vacation ;-) - -Actually, Once I re-checked it, the code looked very familiar. I had -spent time looking at the blind write code in the context of getting -rid of the only non-startup use of GetRawDatabaseInfo. - -As to missing things: I'm leaning heavily on Bruce's previous -work for temp tables, to seperate the two uses of relname, via the -RelationGetRelationName and RelationGetPhysicalRelationName. There are -102 uses of the first in the current code (many in elog messages), and -only 11 of the second. If I'd had to do the original work of finding -every use of relname, and catagorizing it, I agree I'm not (yet) up to -it, but I have more confidence in Bruce's (already tested) work. - -> -> Filename == OID is so simple, reliable, and straightforward by -> comparison that I think the decision is a no-brainer. -> - -Perhaps. Changing the label of the file on disk still requires finding -all the code that assumes it knows what that name is, and changing it. -Same work. - -> If we could afford to sink unlimited time into this one issue then -> it might make sense to do it the hard way, but we have enough -> important stuff on our TODO list to keep us all busy for years --- -> I cannot believe that it's an effective use of our time to do this. -> - -The joys of Open Development. You've spent a fair amount of time trying -to convince _me_ not to waste my time. Thanks, but I'm pretty bull headed -sometimes. Since I've already done something of the work, take a look -at what I've got, and then tell me I'm wasting my time, o.k.? - -> -> > Hmm, what's all this with functions in catalog.c that are only called by -> > smgr/md.c? seems to me that anything having to do with physical storage -> > (like the path!) belongs in the smgr abstraction. -> -> Yeah, there's a bunch of stuff that should have been implemented by -> adding new smgr entry points, but wasn't. It should be pushed down. -> (I can't resist pointing out that one of those things is physical -> relation rename, which will go away and not *need* to be pushed down -> if we do it the way I want.) -> - -Oh, I agree completely. In fact, As I said to Hiroshi last time this came -up, I think of the field in pg_class an an opaque token, to be filled in -by the smgr, and only used by code further up to hand back to the smgr -routines. Same should be true of the buffer->blind struct. - -Ross --- -Ross J. Reedstrom, Ph.D., -NSBRI Research Scientist/Programmer -Computer and Information Technology Institute -Rice University, 6100 S. Main St., Houston, TX 77005 - - -From Inoue@tpf.co.jp Fri Jun 16 19:31:00 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id TAA05334 - for ; Fri, 16 Jun 2000 19:30:59 -0400 (EDT) -Received: from sd.tpf.co.jp (sd.tpf.co.jp [210.161.239.34]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id TAA19834 for ; Fri, 16 Jun 2000 19:09:59 -0400 (EDT) -Received: from mcadnote1 (ppm122.noc.fukui.nsk.ne.jp [210.161.188.41]) - by sd.tpf.co.jp (2.5 Build 2640 (Berkeley 8.8.6)/8.8.4) with SMTP - id IAA08210; Sat, 17 Jun 2000 08:08:15 +0900 -From: "Hiroshi Inoue" -To: "Tom Lane" , "Jan Wieck" -Cc: "Bruce Momjian" , - "PostgreSQL-development" , - "Ross J. Reedstrom" -Subject: RE: [HACKERS] Big 7.1 open items -Date: Sat, 17 Jun 2000 08:11:08 +0900 -Message-ID: -MIME-Version: 1.0 -Content-Type: text/plain; - charset="iso-2022-jp" -Content-Transfer-Encoding: 7bit -X-Priority: 3 (Normal) -X-MSMail-Priority: Normal -X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2910.0) -In-Reply-To: <7181.961167635@sss.pgh.pa.us> -X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2919.6700 -Importance: Normal -Status: RO - -> -----Original Message----- -> From: Tom Lane [mailto:tgl@sss.pgh.pa.us] -> -> JanWieck@t-online.de (Jan Wieck) writes: -> > There are also disadvantages. -> -> > You can run out of space even if there are plenty GB's -> > free on your disks. You have to create tablespaces -> > explicitly. -> -> Not to mention the reverse: if I read this right, you have to suck -> up your GB's long in advance of actually needing them. That's OK -> for a machine that's dedicated to Oracle ... not so OK for smaller -> installations, playpens, etc. -> - -I've had an anxiety about the way like Oracle's preallocation. -It had not been easy for me to estimate the extent size in -Oracle. Maybe it would lose the simplicity of environment -settings which is one of the biggest advantage of PostgreSQL. -It seems that we should also provide not_preallocated DATAFILE -when many_tables_in_a_file storage manager is introduced. - -Regards. - -Hiroshi Inoue -Inoue@tpf.co.jp - - - -From tgl@sss.pgh.pa.us Fri Jun 16 19:31:01 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id TAA05337 - for ; Fri, 16 Jun 2000 19:31:00 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) by renoir.op.net (o1/$Revision: 1.8 $) with ESMTP id TAA20335 for ; Fri, 16 Jun 2000 19:18:26 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id TAA09274; - Fri, 16 Jun 2000 19:16:37 -0400 (EDT) -To: "Ross J. Reedstrom" -cc: Thomas Lockhart , - Jan Wieck , Hiroshi Inoue , - Bruce Momjian , - PostgreSQL-development -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: <20000616143528.A28920@rice.edu> -References: <200006161242.OAA15163@hot.jw.home> <7458.961170401@sss.pgh.pa.us> <394A556A.4EAC8B9A@alumni.caltech.edu> <20000616143528.A28920@rice.edu> -Comments: In-reply-to "Ross J. Reedstrom" - message dated "Fri, 16 Jun 2000 14:35:28 -0500" -Date: Fri, 16 Jun 2000 19:16:37 -0400 -Message-ID: <9271.961197397@sss.pgh.pa.us> -From: Tom Lane -Status: RO - -"Ross J. Reedstrom" writes: -> I think the backend needs a per table token that indicates how -> to get at the physical bits of the file. Whether that's a filename -> alone, filename with path, oid, key to a smgr hash table or something -> else, it's opaque above the smgr routines. - -Except to the commands that provide the user interface for tablespaces -and so forth. And there aren't all that many places that deal with -physical filenames anyway. It would be a good idea to try to be a -little stricter about this, but I'm not sure you can make the separation -a whole lot cleaner than it is now ... with the exception of the obvious -bogosities like "rename table" being done above the smgr level. (But, -as I said, I want to see that code go away, not just get moved into -smgr...) - -> Hmm, now I'm thinking, since the tablespace discussion has been reopened, -> the way to go about coding all this is to reactivate the smgr code: how -> about I leave the existing md smgr as is, and clone it, call it md2 or -> something, and start messing with adding features there? - -Um, well, you can't have it both ways. If you're going to change/fix -the assumptions of code above the smgr, then you've got to update md -at the same time to match your new definition of the smgr interface. -Won't do much good to have a playpen smgr if the "standard" one is -broken. - -One thing I have been thinking would be a good idea is to take the -relcache out of the bufmgr/smgr interfaces. The relcache is a -higher-level concept and ought not be known to bufmgr or smgr; they -ought to work with some low-level data structure or token for relations. -We might be able to eliminate the whole concept of "blind write" if we -do that. There are other problems with the relcache dependency: entries -in relcache can get blown away at inopportune times due to shared cache -inval, and it doesn't provide a good home for tokens for multiple -"versions" of a relation if we go with the fill-a-new-physical-file -approach to CLUSTER and so on. - -Hmm, if you replace relcache in the smgr interfaces with pointers to -an smgr-maintained data structure, that might be the same thing that -you are alluding to above about an smgr hash table. - -One thing *not* to do is add yet a third layer of data structure on -top of the ones already maintained in fd.c and md.c. Whatever extra -data might be needed here should be added to md.c's tables, I think, -and then the tokens used in the smgr interface would be pointers into -that table. - - regards, tom lane - -From tgl@sss.pgh.pa.us Fri Jun 16 19:30:43 2000 -Received: from sss2.sss.pgh.pa.us (sss.pgh.pa.us [209.114.166.2]) - by candle.pha.pa.us (8.9.0/8.9.0) with ESMTP id TAA05329 - for ; Fri, 16 Jun 2000 19:30:41 -0400 (EDT) -Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) - by sss2.sss.pgh.pa.us (8.9.3/8.9.3) with ESMTP id TAA09320; - Fri, 16 Jun 2000 19:30:26 -0400 (EDT) -To: "Hiroshi Inoue" -cc: "Jan Wieck" , - "Bruce Momjian" , - "PostgreSQL-development" , - "Ross J. Reedstrom" -Subject: Re: [HACKERS] Big 7.1 open items -In-reply-to: -References: -Comments: In-reply-to "Hiroshi Inoue" - message dated "Sat, 17 Jun 2000 08:11:08 +0900" -Date: Fri, 16 Jun 2000 19:30:25 -0400 -Message-ID: <9317.961198225@sss.pgh.pa.us> -From: Tom Lane -Status: ROr - -"Hiroshi Inoue" writes: -> It seems that we should also provide not_preallocated DATAFILE -> when many_tables_in_a_file storage manager is introduced. - -Several people in this thread have been talking like a -single-physical-file storage manager is in our future, but I can't -recall anyone saying that they were going to do such a thing or even -presenting reasons why it'd be a good idea. - -Seems to me that physical file per relation is considerably better for -our purposes. It's easier to figure out what's going on for admin and -debug work, it means less lock contention among different backends -appending concurrently to different relations, and it gives the OS a -better shot at doing effective read-ahead on sequential scans. - -So why all the enthusiasm for multi-tables-per-file? - - regards, tom lane - -From chris@bitmead.com Fri Jun 16 21:01:02 2000 -Received: from renoir.op.net (root@renoir.op.net [207.29.195.4]) - by candle.pha.pa.us (