FreeBSD Bugzilla – Attachment 157775 Details for
Bug 197992
[New port] databases/postgresql92-1c
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
Update for new version PostgreSQL DB 9.2.13
postgresql92-1c.shar (text/plain), 386.77 KB, created by
Konstantin Reznichenko
on 2015-06-15 22:33:22 UTC
(
hide
)
Description:
Update for new version PostgreSQL DB 9.2.13
Filename:
MIME Type:
Creator:
Konstantin Reznichenko
Created:
2015-06-15 22:33:22 UTC
Size:
386.77 KB
patch
obsolete
># This is a shell archive. Save it in a file, remove anything before ># this line, and then unpack it by entering "sh file". Note, it may ># create directories; files and directories will be owned by you and ># have default permissions. ># ># This archive contains: ># ># postgresql92-1c ># postgresql92-1c/pkg-plist ># postgresql92-1c/files ># postgresql92-1c/files/patch-src-backend-Makefile ># postgresql92-1c/files/502.pgsql.in ># postgresql92-1c/files/patch-1c-postgresql ># postgresql92-1c/files/patch-1c-applock ># postgresql92-1c/files/postgresql.in ># postgresql92-1c/files/patch-1c-plantuner ># postgresql92-1c/files/pkg-message.in ># postgresql92-1c/files/patch-1c-online_analyze ># postgresql92-1c/files/patch-contrib-uuid ># postgresql92-1c/files/patch-doc-Makefile ># postgresql92-1c/files/patch-doc-src-sgml-Makefile ># postgresql92-1c/files/patch-src:backend:utils:misc:postgresql.conf.sample ># postgresql92-1c/files/dot.cshrc.in ># postgresql92-1c/files/dot.profile.in ># postgresql92-1c/files/patch-1c-full ># postgresql92-1c/distinfo ># postgresql92-1c/Makefile ># postgresql92-1c/pkg-install ># postgresql92-1c/pkg-descr ># >echo c - postgresql92-1c >mkdir -p postgresql92-1c > /dev/null 2>&1 >echo x - postgresql92-1c/pkg-plist >sed 's/^X//' >postgresql92-1c/pkg-plist << '737d46d867dcbf440542b48f0c66fe19' >Xbin/clusterdb >Xbin/createdb >Xbin/createlang >Xbin/createuser >Xbin/dropdb >Xbin/droplang >Xbin/dropuser >Xbin/ecpg >Xbin/initdb >Xbin/oid2name >Xbin/pg_archivecleanup >Xbin/pg_basebackup >Xbin/pg_config >Xbin/pg_controldata >Xbin/pg_ctl >Xbin/pg_dump >Xbin/pg_dumpall >Xbin/pg_receivexlog >Xbin/pg_resetxlog >Xbin/pg_restore >Xbin/pg_standby >Xbin/pg_test_fsync >Xbin/pg_test_timing >Xbin/pg_upgrade >Xbin/pgbench >Xbin/postgres >Xbin/postmaster >Xbin/psql >Xbin/reindexdb >Xbin/vacuumdb >Xbin/vacuumlo >Xetc/periodic/daily/502.pgsql >Xinclude/ecpg_config.h >Xinclude/ecpg_informix.h >Xinclude/ecpgerrno.h >Xinclude/ecpglib.h >Xinclude/ecpgtype.h >Xinclude/libpq-events.h >Xinclude/libpq-fe.h >Xinclude/libpq/libpq-fs.h >Xinclude/pg_config.h >Xinclude/pg_config_manual.h >Xinclude/pg_config_os.h >Xinclude/pgtypes_date.h >Xinclude/pgtypes_error.h >Xinclude/pgtypes_interval.h >Xinclude/pgtypes_numeric.h >Xinclude/pgtypes_timestamp.h >Xinclude/postgres_ext.h >Xinclude/postgresql/informix/esql/datetime.h >Xinclude/postgresql/informix/esql/decimal.h >Xinclude/postgresql/informix/esql/sqltypes.h >Xinclude/postgresql/internal/c.h >Xinclude/postgresql/internal/libpq-int.h >Xinclude/postgresql/internal/libpq/pqcomm.h >Xinclude/postgresql/internal/port.h >Xinclude/postgresql/internal/postgres_fe.h >Xinclude/postgresql/internal/pqexpbuffer.h >Xinclude/postgresql/server/access/attnum.h >Xinclude/postgresql/server/access/clog.h >Xinclude/postgresql/server/access/genam.h >Xinclude/postgresql/server/access/gin.h >Xinclude/postgresql/server/access/gin_private.h >Xinclude/postgresql/server/access/gist.h >Xinclude/postgresql/server/access/gist_private.h >Xinclude/postgresql/server/access/gistscan.h >Xinclude/postgresql/server/access/hash.h >Xinclude/postgresql/server/access/heapam.h >Xinclude/postgresql/server/access/hio.h >Xinclude/postgresql/server/access/htup.h >Xinclude/postgresql/server/access/itup.h >Xinclude/postgresql/server/access/multixact.h >Xinclude/postgresql/server/access/nbtree.h >Xinclude/postgresql/server/access/printtup.h >Xinclude/postgresql/server/access/reloptions.h >Xinclude/postgresql/server/access/relscan.h >Xinclude/postgresql/server/access/rewriteheap.h >Xinclude/postgresql/server/access/rmgr.h >Xinclude/postgresql/server/access/sdir.h >Xinclude/postgresql/server/access/skey.h >Xinclude/postgresql/server/access/slru.h >Xinclude/postgresql/server/access/spgist.h >Xinclude/postgresql/server/access/spgist_private.h >Xinclude/postgresql/server/access/subtrans.h >Xinclude/postgresql/server/access/sysattr.h >Xinclude/postgresql/server/access/transam.h >Xinclude/postgresql/server/access/tupconvert.h >Xinclude/postgresql/server/access/tupdesc.h >Xinclude/postgresql/server/access/tupmacs.h >Xinclude/postgresql/server/access/tuptoaster.h >Xinclude/postgresql/server/access/twophase.h >Xinclude/postgresql/server/access/twophase_rmgr.h >Xinclude/postgresql/server/access/valid.h >Xinclude/postgresql/server/access/visibilitymap.h >Xinclude/postgresql/server/access/xact.h >Xinclude/postgresql/server/access/xlog.h >Xinclude/postgresql/server/access/xlog_internal.h >Xinclude/postgresql/server/access/xlogdefs.h >Xinclude/postgresql/server/access/xlogutils.h >Xinclude/postgresql/server/bootstrap/bootstrap.h >Xinclude/postgresql/server/c.h >Xinclude/postgresql/server/catalog/catalog.h >Xinclude/postgresql/server/catalog/catversion.h >Xinclude/postgresql/server/catalog/dependency.h >Xinclude/postgresql/server/catalog/genbki.h >Xinclude/postgresql/server/catalog/heap.h >Xinclude/postgresql/server/catalog/index.h >Xinclude/postgresql/server/catalog/indexing.h >Xinclude/postgresql/server/catalog/namespace.h >Xinclude/postgresql/server/catalog/objectaccess.h >Xinclude/postgresql/server/catalog/objectaddress.h >Xinclude/postgresql/server/catalog/pg_aggregate.h >Xinclude/postgresql/server/catalog/pg_am.h >Xinclude/postgresql/server/catalog/pg_amop.h >Xinclude/postgresql/server/catalog/pg_amproc.h >Xinclude/postgresql/server/catalog/pg_attrdef.h >Xinclude/postgresql/server/catalog/pg_attribute.h >Xinclude/postgresql/server/catalog/pg_auth_members.h >Xinclude/postgresql/server/catalog/pg_authid.h >Xinclude/postgresql/server/catalog/pg_cast.h >Xinclude/postgresql/server/catalog/pg_class.h >Xinclude/postgresql/server/catalog/pg_collation.h >Xinclude/postgresql/server/catalog/pg_collation_fn.h >Xinclude/postgresql/server/catalog/pg_constraint.h >Xinclude/postgresql/server/catalog/pg_control.h >Xinclude/postgresql/server/catalog/pg_conversion.h >Xinclude/postgresql/server/catalog/pg_conversion_fn.h >Xinclude/postgresql/server/catalog/pg_database.h >Xinclude/postgresql/server/catalog/pg_db_role_setting.h >Xinclude/postgresql/server/catalog/pg_default_acl.h >Xinclude/postgresql/server/catalog/pg_depend.h >Xinclude/postgresql/server/catalog/pg_description.h >Xinclude/postgresql/server/catalog/pg_enum.h >Xinclude/postgresql/server/catalog/pg_extension.h >Xinclude/postgresql/server/catalog/pg_foreign_data_wrapper.h >Xinclude/postgresql/server/catalog/pg_foreign_server.h >Xinclude/postgresql/server/catalog/pg_foreign_table.h >Xinclude/postgresql/server/catalog/pg_index.h >Xinclude/postgresql/server/catalog/pg_inherits.h >Xinclude/postgresql/server/catalog/pg_inherits_fn.h >Xinclude/postgresql/server/catalog/pg_language.h >Xinclude/postgresql/server/catalog/pg_largeobject.h >Xinclude/postgresql/server/catalog/pg_largeobject_metadata.h >Xinclude/postgresql/server/catalog/pg_namespace.h >Xinclude/postgresql/server/catalog/pg_opclass.h >Xinclude/postgresql/server/catalog/pg_operator.h >Xinclude/postgresql/server/catalog/pg_opfamily.h >Xinclude/postgresql/server/catalog/pg_pltemplate.h >Xinclude/postgresql/server/catalog/pg_proc.h >Xinclude/postgresql/server/catalog/pg_proc_fn.h >Xinclude/postgresql/server/catalog/pg_range.h >Xinclude/postgresql/server/catalog/pg_rewrite.h >Xinclude/postgresql/server/catalog/pg_seclabel.h >Xinclude/postgresql/server/catalog/pg_shdepend.h >Xinclude/postgresql/server/catalog/pg_shdescription.h >Xinclude/postgresql/server/catalog/pg_shseclabel.h >Xinclude/postgresql/server/catalog/pg_statistic.h >Xinclude/postgresql/server/catalog/pg_tablespace.h >Xinclude/postgresql/server/catalog/pg_trigger.h >Xinclude/postgresql/server/catalog/pg_ts_config.h >Xinclude/postgresql/server/catalog/pg_ts_config_map.h >Xinclude/postgresql/server/catalog/pg_ts_dict.h >Xinclude/postgresql/server/catalog/pg_ts_parser.h >Xinclude/postgresql/server/catalog/pg_ts_template.h >Xinclude/postgresql/server/catalog/pg_type.h >Xinclude/postgresql/server/catalog/pg_type_fn.h >Xinclude/postgresql/server/catalog/pg_user_mapping.h >Xinclude/postgresql/server/catalog/schemapg.h >Xinclude/postgresql/server/catalog/storage.h >Xinclude/postgresql/server/catalog/toasting.h >Xinclude/postgresql/server/commands/alter.h >Xinclude/postgresql/server/commands/async.h >Xinclude/postgresql/server/commands/cluster.h >Xinclude/postgresql/server/commands/collationcmds.h >Xinclude/postgresql/server/commands/comment.h >Xinclude/postgresql/server/commands/conversioncmds.h >Xinclude/postgresql/server/commands/copy.h >Xinclude/postgresql/server/commands/createas.h >Xinclude/postgresql/server/commands/dbcommands.h >Xinclude/postgresql/server/commands/defrem.h >Xinclude/postgresql/server/commands/discard.h >Xinclude/postgresql/server/commands/explain.h >Xinclude/postgresql/server/commands/extension.h >Xinclude/postgresql/server/commands/lockcmds.h >Xinclude/postgresql/server/commands/portalcmds.h >Xinclude/postgresql/server/commands/prepare.h >Xinclude/postgresql/server/commands/proclang.h >Xinclude/postgresql/server/commands/schemacmds.h >Xinclude/postgresql/server/commands/seclabel.h >Xinclude/postgresql/server/commands/sequence.h >Xinclude/postgresql/server/commands/tablecmds.h >Xinclude/postgresql/server/commands/tablespace.h >Xinclude/postgresql/server/commands/trigger.h >Xinclude/postgresql/server/commands/typecmds.h >Xinclude/postgresql/server/commands/user.h >Xinclude/postgresql/server/commands/vacuum.h >Xinclude/postgresql/server/commands/variable.h >Xinclude/postgresql/server/commands/view.h >Xinclude/postgresql/server/datatype/timestamp.h >Xinclude/postgresql/server/dynloader.h >Xinclude/postgresql/server/executor/execdebug.h >Xinclude/postgresql/server/executor/execdesc.h >Xinclude/postgresql/server/executor/executor.h >Xinclude/postgresql/server/executor/functions.h >Xinclude/postgresql/server/executor/hashjoin.h >Xinclude/postgresql/server/executor/instrument.h >Xinclude/postgresql/server/executor/nodeAgg.h >Xinclude/postgresql/server/executor/nodeAppend.h >Xinclude/postgresql/server/executor/nodeBitmapAnd.h >Xinclude/postgresql/server/executor/nodeBitmapHeapscan.h >Xinclude/postgresql/server/executor/nodeBitmapIndexscan.h >Xinclude/postgresql/server/executor/nodeBitmapOr.h >Xinclude/postgresql/server/executor/nodeCtescan.h >Xinclude/postgresql/server/executor/nodeForeignscan.h >Xinclude/postgresql/server/executor/nodeFunctionscan.h >Xinclude/postgresql/server/executor/nodeGroup.h >Xinclude/postgresql/server/executor/nodeHash.h >Xinclude/postgresql/server/executor/nodeHashjoin.h >Xinclude/postgresql/server/executor/nodeIndexonlyscan.h >Xinclude/postgresql/server/executor/nodeIndexscan.h >Xinclude/postgresql/server/executor/nodeLimit.h >Xinclude/postgresql/server/executor/nodeLockRows.h >Xinclude/postgresql/server/executor/nodeMaterial.h >Xinclude/postgresql/server/executor/nodeMergeAppend.h >Xinclude/postgresql/server/executor/nodeMergejoin.h >Xinclude/postgresql/server/executor/nodeModifyTable.h >Xinclude/postgresql/server/executor/nodeNestloop.h >Xinclude/postgresql/server/executor/nodeRecursiveunion.h >Xinclude/postgresql/server/executor/nodeResult.h >Xinclude/postgresql/server/executor/nodeSeqscan.h >Xinclude/postgresql/server/executor/nodeSetOp.h >Xinclude/postgresql/server/executor/nodeSort.h >Xinclude/postgresql/server/executor/nodeSubplan.h >Xinclude/postgresql/server/executor/nodeSubqueryscan.h >Xinclude/postgresql/server/executor/nodeTidscan.h >Xinclude/postgresql/server/executor/nodeUnique.h >Xinclude/postgresql/server/executor/nodeValuesscan.h >Xinclude/postgresql/server/executor/nodeWindowAgg.h >Xinclude/postgresql/server/executor/nodeWorktablescan.h >Xinclude/postgresql/server/executor/spi.h >Xinclude/postgresql/server/executor/spi_priv.h >Xinclude/postgresql/server/executor/tstoreReceiver.h >Xinclude/postgresql/server/executor/tuptable.h >Xinclude/postgresql/server/fmgr.h >Xinclude/postgresql/server/foreign/fdwapi.h >Xinclude/postgresql/server/foreign/foreign.h >Xinclude/postgresql/server/funcapi.h >Xinclude/postgresql/server/getaddrinfo.h >Xinclude/postgresql/server/getopt_long.h >Xinclude/postgresql/server/lib/dllist.h >Xinclude/postgresql/server/lib/stringinfo.h >Xinclude/postgresql/server/libpq/auth.h >Xinclude/postgresql/server/libpq/be-fsstubs.h >Xinclude/postgresql/server/libpq/crypt.h >Xinclude/postgresql/server/libpq/hba.h >Xinclude/postgresql/server/libpq/ip.h >Xinclude/postgresql/server/libpq/libpq-be.h >Xinclude/postgresql/server/libpq/libpq-fs.h >Xinclude/postgresql/server/libpq/libpq.h >Xinclude/postgresql/server/libpq/md5.h >Xinclude/postgresql/server/libpq/pqcomm.h >Xinclude/postgresql/server/libpq/pqformat.h >Xinclude/postgresql/server/libpq/pqsignal.h >Xinclude/postgresql/server/mb/pg_wchar.h >Xinclude/postgresql/server/miscadmin.h >Xinclude/postgresql/server/nodes/bitmapset.h >Xinclude/postgresql/server/nodes/execnodes.h >Xinclude/postgresql/server/nodes/makefuncs.h >Xinclude/postgresql/server/nodes/memnodes.h >Xinclude/postgresql/server/nodes/nodeFuncs.h >Xinclude/postgresql/server/nodes/nodes.h >Xinclude/postgresql/server/nodes/params.h >Xinclude/postgresql/server/nodes/parsenodes.h >Xinclude/postgresql/server/nodes/pg_list.h >Xinclude/postgresql/server/nodes/plannodes.h >Xinclude/postgresql/server/nodes/primnodes.h >Xinclude/postgresql/server/nodes/print.h >Xinclude/postgresql/server/nodes/readfuncs.h >Xinclude/postgresql/server/nodes/relation.h >Xinclude/postgresql/server/nodes/replnodes.h >Xinclude/postgresql/server/nodes/tidbitmap.h >Xinclude/postgresql/server/nodes/value.h >Xinclude/postgresql/server/optimizer/clauses.h >Xinclude/postgresql/server/optimizer/cost.h >Xinclude/postgresql/server/optimizer/geqo.h >Xinclude/postgresql/server/optimizer/geqo_copy.h >Xinclude/postgresql/server/optimizer/geqo_gene.h >Xinclude/postgresql/server/optimizer/geqo_misc.h >Xinclude/postgresql/server/optimizer/geqo_mutation.h >Xinclude/postgresql/server/optimizer/geqo_pool.h >Xinclude/postgresql/server/optimizer/geqo_random.h >Xinclude/postgresql/server/optimizer/geqo_recombination.h >Xinclude/postgresql/server/optimizer/geqo_selection.h >Xinclude/postgresql/server/optimizer/joininfo.h >Xinclude/postgresql/server/optimizer/pathnode.h >Xinclude/postgresql/server/optimizer/paths.h >Xinclude/postgresql/server/optimizer/placeholder.h >Xinclude/postgresql/server/optimizer/plancat.h >Xinclude/postgresql/server/optimizer/planmain.h >Xinclude/postgresql/server/optimizer/planner.h >Xinclude/postgresql/server/optimizer/predtest.h >Xinclude/postgresql/server/optimizer/prep.h >Xinclude/postgresql/server/optimizer/restrictinfo.h >Xinclude/postgresql/server/optimizer/subselect.h >Xinclude/postgresql/server/optimizer/tlist.h >Xinclude/postgresql/server/optimizer/var.h >Xinclude/postgresql/server/parser/analyze.h >Xinclude/postgresql/server/parser/gram.h >Xinclude/postgresql/server/parser/gramparse.h >Xinclude/postgresql/server/parser/keywords.h >Xinclude/postgresql/server/parser/kwlist.h >Xinclude/postgresql/server/parser/parse_agg.h >Xinclude/postgresql/server/parser/parse_clause.h >Xinclude/postgresql/server/parser/parse_coerce.h >Xinclude/postgresql/server/parser/parse_collate.h >Xinclude/postgresql/server/parser/parse_cte.h >Xinclude/postgresql/server/parser/parse_expr.h >Xinclude/postgresql/server/parser/parse_func.h >Xinclude/postgresql/server/parser/parse_node.h >Xinclude/postgresql/server/parser/parse_oper.h >Xinclude/postgresql/server/parser/parse_param.h >Xinclude/postgresql/server/parser/parse_relation.h >Xinclude/postgresql/server/parser/parse_target.h >Xinclude/postgresql/server/parser/parse_type.h >Xinclude/postgresql/server/parser/parse_utilcmd.h >Xinclude/postgresql/server/parser/parser.h >Xinclude/postgresql/server/parser/parsetree.h >Xinclude/postgresql/server/parser/scanner.h >Xinclude/postgresql/server/parser/scansup.h >Xinclude/postgresql/server/pg_config.h >Xinclude/postgresql/server/pg_config_manual.h >Xinclude/postgresql/server/pg_config_os.h >Xinclude/postgresql/server/pg_trace.h >Xinclude/postgresql/server/pgstat.h >Xinclude/postgresql/server/pgtime.h >Xinclude/postgresql/server/pl%%PG_USER%%.h >Xinclude/postgresql/server/port.h >Xinclude/postgresql/server/port/aix.h >Xinclude/postgresql/server/port/cygwin.h >Xinclude/postgresql/server/port/darwin.h >Xinclude/postgresql/server/port/freebsd.h >Xinclude/postgresql/server/port/hpux.h >Xinclude/postgresql/server/port/irix.h >Xinclude/postgresql/server/port/linux.h >Xinclude/postgresql/server/port/netbsd.h >Xinclude/postgresql/server/port/openbsd.h >Xinclude/postgresql/server/port/osf.h >Xinclude/postgresql/server/port/sco.h >Xinclude/postgresql/server/port/solaris.h >Xinclude/postgresql/server/port/unixware.h >Xinclude/postgresql/server/port/win32.h >Xinclude/postgresql/server/port/win32/arpa/inet.h >Xinclude/postgresql/server/port/win32/dlfcn.h >Xinclude/postgresql/server/port/win32/grp.h >Xinclude/postgresql/server/port/win32/netdb.h >Xinclude/postgresql/server/port/win32/netinet/in.h >Xinclude/postgresql/server/port/win32/pwd.h >Xinclude/postgresql/server/port/win32/sys/socket.h >Xinclude/postgresql/server/port/win32/sys/wait.h >Xinclude/postgresql/server/port/win32_msvc/dirent.h >Xinclude/postgresql/server/port/win32_msvc/sys/file.h >Xinclude/postgresql/server/port/win32_msvc/sys/param.h >Xinclude/postgresql/server/port/win32_msvc/sys/time.h >Xinclude/postgresql/server/port/win32_msvc/unistd.h >Xinclude/postgresql/server/port/win32_msvc/utime.h >Xinclude/postgresql/server/portability/instr_time.h >Xinclude/postgresql/server/postgres.h >Xinclude/postgresql/server/postgres_ext.h >Xinclude/postgresql/server/postgres_fe.h >Xinclude/postgresql/server/postmaster/autovacuum.h >Xinclude/postgresql/server/postmaster/bgwriter.h >Xinclude/postgresql/server/postmaster/fork_process.h >Xinclude/postgresql/server/postmaster/pgarch.h >Xinclude/postgresql/server/postmaster/postmaster.h >Xinclude/postgresql/server/postmaster/startup.h >Xinclude/postgresql/server/postmaster/syslogger.h >Xinclude/postgresql/server/postmaster/walwriter.h >Xinclude/postgresql/server/regex/regcustom.h >Xinclude/postgresql/server/regex/regerrs.h >Xinclude/postgresql/server/regex/regex.h >Xinclude/postgresql/server/regex/regguts.h >Xinclude/postgresql/server/replication/basebackup.h >Xinclude/postgresql/server/replication/syncrep.h >Xinclude/postgresql/server/replication/walprotocol.h >Xinclude/postgresql/server/replication/walreceiver.h >Xinclude/postgresql/server/replication/walsender.h >Xinclude/postgresql/server/replication/walsender_private.h >Xinclude/postgresql/server/rewrite/prs2lock.h >Xinclude/postgresql/server/rewrite/rewriteDefine.h >Xinclude/postgresql/server/rewrite/rewriteHandler.h >Xinclude/postgresql/server/rewrite/rewriteManip.h >Xinclude/postgresql/server/rewrite/rewriteRemove.h >Xinclude/postgresql/server/rewrite/rewriteSupport.h >Xinclude/postgresql/server/rusagestub.h >Xinclude/postgresql/server/snowball/header.h >Xinclude/postgresql/server/snowball/libstemmer/api.h >Xinclude/postgresql/server/snowball/libstemmer/header.h >Xinclude/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_danish.h >Xinclude/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_dutch.h >Xinclude/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_english.h >Xinclude/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_finnish.h >Xinclude/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_french.h >Xinclude/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_german.h >Xinclude/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_hungarian.h >Xinclude/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_italian.h >Xinclude/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_norwegian.h >Xinclude/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_porter.h >Xinclude/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_portuguese.h >Xinclude/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_spanish.h >Xinclude/postgresql/server/snowball/libstemmer/stem_ISO_8859_1_swedish.h >Xinclude/postgresql/server/snowball/libstemmer/stem_ISO_8859_2_romanian.h >Xinclude/postgresql/server/snowball/libstemmer/stem_KOI8_R_russian.h >Xinclude/postgresql/server/snowball/libstemmer/stem_UTF_8_danish.h >Xinclude/postgresql/server/snowball/libstemmer/stem_UTF_8_dutch.h >Xinclude/postgresql/server/snowball/libstemmer/stem_UTF_8_english.h >Xinclude/postgresql/server/snowball/libstemmer/stem_UTF_8_finnish.h >Xinclude/postgresql/server/snowball/libstemmer/stem_UTF_8_french.h >Xinclude/postgresql/server/snowball/libstemmer/stem_UTF_8_german.h >Xinclude/postgresql/server/snowball/libstemmer/stem_UTF_8_hungarian.h >Xinclude/postgresql/server/snowball/libstemmer/stem_UTF_8_italian.h >Xinclude/postgresql/server/snowball/libstemmer/stem_UTF_8_norwegian.h >Xinclude/postgresql/server/snowball/libstemmer/stem_UTF_8_porter.h >Xinclude/postgresql/server/snowball/libstemmer/stem_UTF_8_portuguese.h >Xinclude/postgresql/server/snowball/libstemmer/stem_UTF_8_romanian.h >Xinclude/postgresql/server/snowball/libstemmer/stem_UTF_8_russian.h >Xinclude/postgresql/server/snowball/libstemmer/stem_UTF_8_spanish.h >Xinclude/postgresql/server/snowball/libstemmer/stem_UTF_8_swedish.h >Xinclude/postgresql/server/snowball/libstemmer/stem_UTF_8_turkish.h >Xinclude/postgresql/server/storage/backendid.h >Xinclude/postgresql/server/storage/barrier.h >Xinclude/postgresql/server/storage/block.h >Xinclude/postgresql/server/storage/buf.h >Xinclude/postgresql/server/storage/buf_internals.h >Xinclude/postgresql/server/storage/buffile.h >Xinclude/postgresql/server/storage/bufmgr.h >Xinclude/postgresql/server/storage/bufpage.h >Xinclude/postgresql/server/storage/copydir.h >Xinclude/postgresql/server/storage/fd.h >Xinclude/postgresql/server/storage/freespace.h >Xinclude/postgresql/server/storage/fsm_internals.h >Xinclude/postgresql/server/storage/indexfsm.h >Xinclude/postgresql/server/storage/ipc.h >Xinclude/postgresql/server/storage/item.h >Xinclude/postgresql/server/storage/itemid.h >Xinclude/postgresql/server/storage/itemptr.h >Xinclude/postgresql/server/storage/large_object.h >Xinclude/postgresql/server/storage/latch.h >Xinclude/postgresql/server/storage/lmgr.h >Xinclude/postgresql/server/storage/lock.h >Xinclude/postgresql/server/storage/lwlock.h >Xinclude/postgresql/server/storage/off.h >Xinclude/postgresql/server/storage/pg_sema.h >Xinclude/postgresql/server/storage/pg_shmem.h >Xinclude/postgresql/server/storage/pmsignal.h >Xinclude/postgresql/server/storage/pos.h >Xinclude/postgresql/server/storage/predicate.h >Xinclude/postgresql/server/storage/predicate_internals.h >Xinclude/postgresql/server/storage/proc.h >Xinclude/postgresql/server/storage/procarray.h >Xinclude/postgresql/server/storage/procsignal.h >Xinclude/postgresql/server/storage/reinit.h >Xinclude/postgresql/server/storage/relfilenode.h >Xinclude/postgresql/server/storage/s_lock.h >Xinclude/postgresql/server/storage/shmem.h >Xinclude/postgresql/server/storage/sinval.h >Xinclude/postgresql/server/storage/sinvaladt.h >Xinclude/postgresql/server/storage/smgr.h >Xinclude/postgresql/server/storage/spin.h >Xinclude/postgresql/server/storage/standby.h >Xinclude/postgresql/server/tcop/dest.h >Xinclude/postgresql/server/tcop/fastpath.h >Xinclude/postgresql/server/tcop/pquery.h >Xinclude/postgresql/server/tcop/tcopdebug.h >Xinclude/postgresql/server/tcop/tcopprot.h >Xinclude/postgresql/server/tcop/utility.h >Xinclude/postgresql/server/tsearch/dicts/regis.h >Xinclude/postgresql/server/tsearch/dicts/spell.h >Xinclude/postgresql/server/tsearch/ts_cache.h >Xinclude/postgresql/server/tsearch/ts_locale.h >Xinclude/postgresql/server/tsearch/ts_public.h >Xinclude/postgresql/server/tsearch/ts_type.h >Xinclude/postgresql/server/tsearch/ts_utils.h >Xinclude/postgresql/server/utils/acl.h >Xinclude/postgresql/server/utils/array.h >Xinclude/postgresql/server/utils/ascii.h >Xinclude/postgresql/server/utils/attoptcache.h >Xinclude/postgresql/server/utils/builtins.h >Xinclude/postgresql/server/utils/bytea.h >Xinclude/postgresql/server/utils/cash.h >Xinclude/postgresql/server/utils/catcache.h >Xinclude/postgresql/server/utils/combocid.h >Xinclude/postgresql/server/utils/date.h >Xinclude/postgresql/server/utils/datetime.h >Xinclude/postgresql/server/utils/datum.h >Xinclude/postgresql/server/utils/dynahash.h >Xinclude/postgresql/server/utils/dynamic_loader.h >Xinclude/postgresql/server/utils/elog.h >Xinclude/postgresql/server/utils/errcodes.h >Xinclude/postgresql/server/utils/fmgroids.h >Xinclude/postgresql/server/utils/fmgrtab.h >Xinclude/postgresql/server/utils/formatting.h >Xinclude/postgresql/server/utils/geo_decls.h >Xinclude/postgresql/server/utils/guc.h >Xinclude/postgresql/server/utils/guc_tables.h >Xinclude/postgresql/server/utils/help_config.h >Xinclude/postgresql/server/utils/hsearch.h >Xinclude/postgresql/server/utils/inet.h >Xinclude/postgresql/server/utils/int8.h >Xinclude/postgresql/server/utils/inval.h >Xinclude/postgresql/server/utils/json.h >Xinclude/postgresql/server/utils/logtape.h >Xinclude/postgresql/server/utils/lsyscache.h >Xinclude/postgresql/server/utils/memutils.h >Xinclude/postgresql/server/utils/nabstime.h >Xinclude/postgresql/server/utils/numeric.h >Xinclude/postgresql/server/utils/palloc.h >Xinclude/postgresql/server/utils/pg_crc.h >Xinclude/postgresql/server/utils/pg_crc_tables.h >Xinclude/postgresql/server/utils/pg_locale.h >Xinclude/postgresql/server/utils/pg_lzcompress.h >Xinclude/postgresql/server/utils/pg_rusage.h >Xinclude/postgresql/server/utils/plancache.h >Xinclude/postgresql/server/utils/portal.h >Xinclude/postgresql/server/utils/probes.h >Xinclude/postgresql/server/utils/ps_status.h >Xinclude/postgresql/server/utils/rangetypes.h >Xinclude/postgresql/server/utils/rbtree.h >Xinclude/postgresql/server/utils/rel.h >Xinclude/postgresql/server/utils/relcache.h >Xinclude/postgresql/server/utils/relmapper.h >Xinclude/postgresql/server/utils/reltrigger.h >Xinclude/postgresql/server/utils/resowner.h >Xinclude/postgresql/server/utils/selfuncs.h >Xinclude/postgresql/server/utils/snapmgr.h >Xinclude/postgresql/server/utils/snapshot.h >Xinclude/postgresql/server/utils/sortsupport.h >Xinclude/postgresql/server/utils/spccache.h >Xinclude/postgresql/server/utils/syscache.h >Xinclude/postgresql/server/utils/timestamp.h >Xinclude/postgresql/server/utils/tqual.h >Xinclude/postgresql/server/utils/tuplesort.h >Xinclude/postgresql/server/utils/tuplestore.h >Xinclude/postgresql/server/utils/typcache.h >Xinclude/postgresql/server/utils/tzparser.h >Xinclude/postgresql/server/utils/uuid.h >Xinclude/postgresql/server/utils/varbit.h >Xinclude/postgresql/server/utils/xml.h >Xinclude/postgresql/server/windowapi.h >Xinclude/sql3types.h >Xinclude/sqlca.h >Xinclude/sqlda-compat.h >Xinclude/sqlda-native.h >Xinclude/sqlda.h >Xlib/libecpg.a >Xlib/libecpg.so >Xlib/libecpg.so.6 >Xlib/libecpg_compat.a >Xlib/libecpg_compat.so >Xlib/libecpg_compat.so.3 >Xlib/libpgport.a >Xlib/libpgtypes.a >Xlib/libpgtypes.so >Xlib/libpgtypes.so.3 >Xlib/libpq.a >Xlib/libpq.so >Xlib/libpq.so.5 >Xlib/postgresql/_int.so >Xlib/postgresql/adminpack.so >Xlib/postgresql/ascii_and_mic.so >Xlib/postgresql/auth_delay.so >Xlib/postgresql/auto_explain.so >Xlib/postgresql/autoinc.so >Xlib/postgresql/btree_gin.so >Xlib/postgresql/btree_gist.so >Xlib/postgresql/chkpass.so >Xlib/postgresql/citext.so >Xlib/postgresql/cube.so >Xlib/postgresql/cyrillic_and_mic.so >Xlib/postgresql/dblink.so >Xlib/postgresql/dict_int.so >Xlib/postgresql/dict_snowball.so >Xlib/postgresql/dict_xsyn.so >Xlib/postgresql/dummy_seclabel.so >Xlib/postgresql/earthdistance.so >Xlib/postgresql/euc2004_sjis2004.so >Xlib/postgresql/euc_cn_and_mic.so >Xlib/postgresql/euc_jp_and_sjis.so >Xlib/postgresql/euc_kr_and_mic.so >Xlib/postgresql/euc_tw_and_big5.so >Xlib/postgresql/fasttrun.so >Xlib/postgresql/file_fdw.so >Xlib/postgresql/fulleq.so >Xlib/postgresql/fuzzystrmatch.so >Xlib/postgresql/hstore.so >Xlib/postgresql/insert_username.so >Xlib/postgresql/isn.so >Xlib/postgresql/latin2_and_win1250.so >Xlib/postgresql/latin_and_mic.so >Xlib/postgresql/libpqwalreceiver.so >Xlib/postgresql/lo.so >Xlib/postgresql/ltree.so >Xlib/postgresql/mchar.so >Xlib/postgresql/moddatetime.so >Xlib/postgresql/online_analyze.so >Xlib/postgresql/pageinspect.so >Xlib/postgresql/passwordcheck.so >Xlib/postgresql/pg_buffercache.so >Xlib/postgresql/pg_freespacemap.so >Xlib/postgresql/pg_stat_statements.so >Xlib/postgresql/pg_trgm.so >Xlib/postgresql/pg_upgrade_support.so >Xlib/postgresql/pgcrypto.so >Xlib/postgresql/pgrowlocks.so >Xlib/postgresql/pgstattuple.so >Xlib/postgresql/pgxml.so >Xlib/postgresql/pgxs/config/install-sh >Xlib/postgresql/pgxs/src/Makefile.global >Xlib/postgresql/pgxs/src/Makefile.port >Xlib/postgresql/pgxs/src/Makefile.shlib >Xlib/postgresql/pgxs/src/makefiles/pgxs.mk >Xlib/postgresql/pgxs/src/nls-global.mk >Xlib/postgresql/plantuner.so >Xlib/postgresql/pl%%PG_USER%%.so >Xlib/postgresql/refint.so >Xlib/postgresql/seg.so >Xlib/postgresql/sslinfo.so >Xlib/postgresql/tablefunc.so >Xlib/postgresql/tcn.so >Xlib/postgresql/test_parser.so >Xlib/postgresql/timetravel.so >Xlib/postgresql/tsearch2.so >Xlib/postgresql/unaccent.so >Xlib/postgresql/utf8_and_ascii.so >Xlib/postgresql/utf8_and_big5.so >Xlib/postgresql/utf8_and_cyrillic.so >Xlib/postgresql/utf8_and_euc2004.so >Xlib/postgresql/utf8_and_euc_cn.so >Xlib/postgresql/utf8_and_euc_jp.so >Xlib/postgresql/utf8_and_euc_kr.so >Xlib/postgresql/utf8_and_euc_tw.so >Xlib/postgresql/utf8_and_gb18030.so >Xlib/postgresql/utf8_and_gbk.so >Xlib/postgresql/utf8_and_iso8859.so >Xlib/postgresql/utf8_and_iso8859_1.so >Xlib/postgresql/utf8_and_johab.so >Xlib/postgresql/utf8_and_sjis.so >Xlib/postgresql/utf8_and_sjis2004.so >Xlib/postgresql/utf8_and_uhc.so >Xlib/postgresql/utf8_and_win.so >Xlib/postgresql/uuid-ossp.so >Xman/man1/clusterdb.1.gz >Xman/man1/createdb.1.gz >Xman/man1/createlang.1.gz >Xman/man1/createuser.1.gz >Xman/man1/dropdb.1.gz >Xman/man1/droplang.1.gz >Xman/man1/dropuser.1.gz >Xman/man1/ecpg.1.gz >Xman/man1/initdb.1.gz >Xman/man1/oid2name.1.gz >Xman/man1/pg_archivecleanup.1.gz >Xman/man1/pg_basebackup.1.gz >Xman/man1/pg_config.1.gz >Xman/man1/pg_controldata.1.gz >Xman/man1/pg_ctl.1.gz >Xman/man1/pg_dump.1.gz >Xman/man1/pg_dumpall.1.gz >Xman/man1/pg_receivexlog.1.gz >Xman/man1/pg_resetxlog.1.gz >Xman/man1/pg_restore.1.gz >Xman/man1/pg_standby.1.gz >Xman/man1/pg_test_fsync.1.gz >Xman/man1/pg_test_timing.1.gz >Xman/man1/pg_upgrade.1.gz >Xman/man1/pgbench.1.gz >Xman/man1/postgres.1.gz >Xman/man1/postmaster.1.gz >Xman/man1/psql.1.gz >Xman/man1/reindexdb.1.gz >Xman/man1/vacuumdb.1.gz >Xman/man1/vacuumlo.1.gz >Xman/man3/SPI_connect.3.gz >Xman/man3/SPI_copytuple.3.gz >Xman/man3/SPI_cursor_close.3.gz >Xman/man3/SPI_cursor_fetch.3.gz >Xman/man3/SPI_cursor_find.3.gz >Xman/man3/SPI_cursor_move.3.gz >Xman/man3/SPI_cursor_open.3.gz >Xman/man3/SPI_cursor_open_with_args.3.gz >Xman/man3/SPI_cursor_open_with_paramlist.3.gz >Xman/man3/SPI_exec.3.gz >Xman/man3/SPI_execp.3.gz >Xman/man3/SPI_execute.3.gz >Xman/man3/SPI_execute_plan.3.gz >Xman/man3/SPI_execute_plan_with_paramlist.3.gz >Xman/man3/SPI_execute_with_args.3.gz >Xman/man3/SPI_finish.3.gz >Xman/man3/SPI_fname.3.gz >Xman/man3/SPI_fnumber.3.gz >Xman/man3/SPI_freeplan.3.gz >Xman/man3/SPI_freetuple.3.gz >Xman/man3/SPI_freetuptable.3.gz >Xman/man3/SPI_getargcount.3.gz >Xman/man3/SPI_getargtypeid.3.gz >Xman/man3/SPI_getbinval.3.gz >Xman/man3/SPI_getnspname.3.gz >Xman/man3/SPI_getrelname.3.gz >Xman/man3/SPI_gettype.3.gz >Xman/man3/SPI_gettypeid.3.gz >Xman/man3/SPI_getvalue.3.gz >Xman/man3/SPI_is_cursor_plan.3.gz >Xman/man3/SPI_keepplan.3.gz >Xman/man3/SPI_modifytuple.3.gz >Xman/man3/SPI_palloc.3.gz >Xman/man3/SPI_pfree.3.gz >Xman/man3/SPI_pop.3.gz >Xman/man3/SPI_prepare.3.gz >Xman/man3/SPI_prepare_cursor.3.gz >Xman/man3/SPI_prepare_params.3.gz >Xman/man3/SPI_push.3.gz >Xman/man3/SPI_repalloc.3.gz >Xman/man3/SPI_returntuple.3.gz >Xman/man3/SPI_saveplan.3.gz >Xman/man3/SPI_scroll_cursor_fetch.3.gz >Xman/man3/SPI_scroll_cursor_move.3.gz >Xman/man3/dblink.3.gz >Xman/man3/dblink_build_sql_delete.3.gz >Xman/man3/dblink_build_sql_insert.3.gz >Xman/man3/dblink_build_sql_update.3.gz >Xman/man3/dblink_cancel_query.3.gz >Xman/man3/dblink_close.3.gz >Xman/man3/dblink_connect.3.gz >Xman/man3/dblink_connect_u.3.gz >Xman/man3/dblink_disconnect.3.gz >Xman/man3/dblink_error_message.3.gz >Xman/man3/dblink_exec.3.gz >Xman/man3/dblink_fetch.3.gz >Xman/man3/dblink_get_connections.3.gz >Xman/man3/dblink_get_notify.3.gz >Xman/man3/dblink_get_pkey.3.gz >Xman/man3/dblink_get_result.3.gz >Xman/man3/dblink_is_busy.3.gz >Xman/man3/dblink_open.3.gz >Xman/man3/dblink_send_query.3.gz >Xman/man7/ABORT.7.gz >Xman/man7/ALTER_AGGREGATE.7.gz >Xman/man7/ALTER_COLLATION.7.gz >Xman/man7/ALTER_CONVERSION.7.gz >Xman/man7/ALTER_DATABASE.7.gz >Xman/man7/ALTER_DEFAULT_PRIVILEGES.7.gz >Xman/man7/ALTER_DOMAIN.7.gz >Xman/man7/ALTER_EXTENSION.7.gz >Xman/man7/ALTER_FOREIGN_DATA_WRAPPER.7.gz >Xman/man7/ALTER_FOREIGN_TABLE.7.gz >Xman/man7/ALTER_FUNCTION.7.gz >Xman/man7/ALTER_GROUP.7.gz >Xman/man7/ALTER_INDEX.7.gz >Xman/man7/ALTER_LANGUAGE.7.gz >Xman/man7/ALTER_LARGE_OBJECT.7.gz >Xman/man7/ALTER_OPERATOR.7.gz >Xman/man7/ALTER_OPERATOR_CLASS.7.gz >Xman/man7/ALTER_OPERATOR_FAMILY.7.gz >Xman/man7/ALTER_ROLE.7.gz >Xman/man7/ALTER_SCHEMA.7.gz >Xman/man7/ALTER_SEQUENCE.7.gz >Xman/man7/ALTER_SERVER.7.gz >Xman/man7/ALTER_TABLE.7.gz >Xman/man7/ALTER_TABLESPACE.7.gz >Xman/man7/ALTER_TEXT_SEARCH_CONFIGURATION.7.gz >Xman/man7/ALTER_TEXT_SEARCH_DICTIONARY.7.gz >Xman/man7/ALTER_TEXT_SEARCH_PARSER.7.gz >Xman/man7/ALTER_TEXT_SEARCH_TEMPLATE.7.gz >Xman/man7/ALTER_TRIGGER.7.gz >Xman/man7/ALTER_TYPE.7.gz >Xman/man7/ALTER_USER.7.gz >Xman/man7/ALTER_USER_MAPPING.7.gz >Xman/man7/ALTER_VIEW.7.gz >Xman/man7/ANALYZE.7.gz >Xman/man7/BEGIN.7.gz >Xman/man7/CHECKPOINT.7.gz >Xman/man7/CLOSE.7.gz >Xman/man7/CLUSTER.7.gz >Xman/man7/COMMENT.7.gz >Xman/man7/COMMIT.7.gz >Xman/man7/COMMIT_PREPARED.7.gz >Xman/man7/COPY.7.gz >Xman/man7/CREATE_AGGREGATE.7.gz >Xman/man7/CREATE_CAST.7.gz >Xman/man7/CREATE_COLLATION.7.gz >Xman/man7/CREATE_CONVERSION.7.gz >Xman/man7/CREATE_DATABASE.7.gz >Xman/man7/CREATE_DOMAIN.7.gz >Xman/man7/CREATE_EXTENSION.7.gz >Xman/man7/CREATE_FOREIGN_DATA_WRAPPER.7.gz >Xman/man7/CREATE_FOREIGN_TABLE.7.gz >Xman/man7/CREATE_FUNCTION.7.gz >Xman/man7/CREATE_GROUP.7.gz >Xman/man7/CREATE_INDEX.7.gz >Xman/man7/CREATE_LANGUAGE.7.gz >Xman/man7/CREATE_OPERATOR.7.gz >Xman/man7/CREATE_OPERATOR_CLASS.7.gz >Xman/man7/CREATE_OPERATOR_FAMILY.7.gz >Xman/man7/CREATE_ROLE.7.gz >Xman/man7/CREATE_RULE.7.gz >Xman/man7/CREATE_SCHEMA.7.gz >Xman/man7/CREATE_SEQUENCE.7.gz >Xman/man7/CREATE_SERVER.7.gz >Xman/man7/CREATE_TABLE.7.gz >Xman/man7/CREATE_TABLESPACE.7.gz >Xman/man7/CREATE_TABLE_AS.7.gz >Xman/man7/CREATE_TEXT_SEARCH_CONFIGURATION.7.gz >Xman/man7/CREATE_TEXT_SEARCH_DICTIONARY.7.gz >Xman/man7/CREATE_TEXT_SEARCH_PARSER.7.gz >Xman/man7/CREATE_TEXT_SEARCH_TEMPLATE.7.gz >Xman/man7/CREATE_TRIGGER.7.gz >Xman/man7/CREATE_TYPE.7.gz >Xman/man7/CREATE_USER.7.gz >Xman/man7/CREATE_USER_MAPPING.7.gz >Xman/man7/CREATE_VIEW.7.gz >Xman/man7/DEALLOCATE.7.gz >Xman/man7/DECLARE.7.gz >Xman/man7/DELETE.7.gz >Xman/man7/DISCARD.7.gz >Xman/man7/DO.7.gz >Xman/man7/DROP_AGGREGATE.7.gz >Xman/man7/DROP_CAST.7.gz >Xman/man7/DROP_COLLATION.7.gz >Xman/man7/DROP_CONVERSION.7.gz >Xman/man7/DROP_DATABASE.7.gz >Xman/man7/DROP_DOMAIN.7.gz >Xman/man7/DROP_EXTENSION.7.gz >Xman/man7/DROP_FOREIGN_DATA_WRAPPER.7.gz >Xman/man7/DROP_FOREIGN_TABLE.7.gz >Xman/man7/DROP_FUNCTION.7.gz >Xman/man7/DROP_GROUP.7.gz >Xman/man7/DROP_INDEX.7.gz >Xman/man7/DROP_LANGUAGE.7.gz >Xman/man7/DROP_OPERATOR.7.gz >Xman/man7/DROP_OPERATOR_CLASS.7.gz >Xman/man7/DROP_OPERATOR_FAMILY.7.gz >Xman/man7/DROP_OWNED.7.gz >Xman/man7/DROP_ROLE.7.gz >Xman/man7/DROP_RULE.7.gz >Xman/man7/DROP_SCHEMA.7.gz >Xman/man7/DROP_SEQUENCE.7.gz >Xman/man7/DROP_SERVER.7.gz >Xman/man7/DROP_TABLE.7.gz >Xman/man7/DROP_TABLESPACE.7.gz >Xman/man7/DROP_TEXT_SEARCH_CONFIGURATION.7.gz >Xman/man7/DROP_TEXT_SEARCH_DICTIONARY.7.gz >Xman/man7/DROP_TEXT_SEARCH_PARSER.7.gz >Xman/man7/DROP_TEXT_SEARCH_TEMPLATE.7.gz >Xman/man7/DROP_TRIGGER.7.gz >Xman/man7/DROP_TYPE.7.gz >Xman/man7/DROP_USER.7.gz >Xman/man7/DROP_USER_MAPPING.7.gz >Xman/man7/DROP_VIEW.7.gz >Xman/man7/END.7.gz >Xman/man7/EXECUTE.7.gz >Xman/man7/EXPLAIN.7.gz >Xman/man7/FETCH.7.gz >Xman/man7/GRANT.7.gz >Xman/man7/INSERT.7.gz >Xman/man7/LISTEN.7.gz >Xman/man7/LOAD.7.gz >Xman/man7/LOCK.7.gz >Xman/man7/MOVE.7.gz >Xman/man7/NOTIFY.7.gz >Xman/man7/PREPARE.7.gz >Xman/man7/PREPARE_TRANSACTION.7.gz >Xman/man7/REASSIGN_OWNED.7.gz >Xman/man7/REINDEX.7.gz >Xman/man7/RELEASE_SAVEPOINT.7.gz >Xman/man7/RESET.7.gz >Xman/man7/REVOKE.7.gz >Xman/man7/ROLLBACK.7.gz >Xman/man7/ROLLBACK_PREPARED.7.gz >Xman/man7/ROLLBACK_TO_SAVEPOINT.7.gz >Xman/man7/SAVEPOINT.7.gz >Xman/man7/SECURITY_LABEL.7.gz >Xman/man7/SELECT.7.gz >Xman/man7/SELECT_INTO.7.gz >Xman/man7/SET.7.gz >Xman/man7/SET_CONSTRAINTS.7.gz >Xman/man7/SET_ROLE.7.gz >Xman/man7/SET_SESSION_AUTHORIZATION.7.gz >Xman/man7/SET_TRANSACTION.7.gz >Xman/man7/SHOW.7.gz >Xman/man7/START_TRANSACTION.7.gz >Xman/man7/TABLE.7.gz >Xman/man7/TRUNCATE.7.gz >Xman/man7/UNLISTEN.7.gz >Xman/man7/UPDATE.7.gz >Xman/man7/VACUUM.7.gz >Xman/man7/VALUES.7.gz >Xman/man7/WITH.7.gz >X%%PORTDOCS%%%%DOCSDIR%%/contrib/README.fasttrun >X%%PORTDOCS%%%%DOCSDIR%%/contrib/README.fulleq >X%%PORTDOCS%%%%DOCSDIR%%/contrib/README.mchar >X%%PORTDOCS%%%%DOCSDIR%%/contrib/README.online_analyze >X%%PORTDOCS%%%%DOCSDIR%%/contrib/README.plantuner >X%%PORTDOCS%%%%DOCSDIR%%/extension/README >X%%PORTDOCS%%%%DOCSDIR%%/extension/autoinc.example >X%%PORTDOCS%%%%DOCSDIR%%/extension/insert_username.example >X%%PORTDOCS%%%%DOCSDIR%%/extension/moddatetime.example >X%%PORTDOCS%%%%DOCSDIR%%/extension/refint.example >X%%PORTDOCS%%%%DOCSDIR%%/extension/timetravel.example >Xshare/locale/cs/LC_MESSAGES/ecpg-9.2.mo >Xshare/locale/cs/LC_MESSAGES/ecpglib6-9.2.mo >Xshare/locale/cs/LC_MESSAGES/initdb-9.2.mo >Xshare/locale/cs/LC_MESSAGES/libpq5-9.2.mo >Xshare/locale/cs/LC_MESSAGES/pg_basebackup-9.2.mo >Xshare/locale/cs/LC_MESSAGES/pg_config-9.2.mo >Xshare/locale/cs/LC_MESSAGES/pg_controldata-9.2.mo >Xshare/locale/cs/LC_MESSAGES/pg_ctl-9.2.mo >Xshare/locale/cs/LC_MESSAGES/pg_dump-9.2.mo >Xshare/locale/cs/LC_MESSAGES/pg_resetxlog-9.2.mo >Xshare/locale/cs/LC_MESSAGES/pgscripts-9.2.mo >Xshare/locale/cs/LC_MESSAGES/pl%%PG_USER%%-9.2.mo >Xshare/locale/cs/LC_MESSAGES/psql-9.2.mo >Xshare/locale/de/LC_MESSAGES/ecpg-9.2.mo >Xshare/locale/de/LC_MESSAGES/ecpglib6-9.2.mo >Xshare/locale/de/LC_MESSAGES/initdb-9.2.mo >Xshare/locale/de/LC_MESSAGES/libpq5-9.2.mo >Xshare/locale/de/LC_MESSAGES/pg_basebackup-9.2.mo >Xshare/locale/de/LC_MESSAGES/pg_config-9.2.mo >Xshare/locale/de/LC_MESSAGES/pg_controldata-9.2.mo >Xshare/locale/de/LC_MESSAGES/pg_ctl-9.2.mo >Xshare/locale/de/LC_MESSAGES/pg_dump-9.2.mo >Xshare/locale/de/LC_MESSAGES/pg_resetxlog-9.2.mo >Xshare/locale/de/LC_MESSAGES/pgscripts-9.2.mo >Xshare/locale/de/LC_MESSAGES/pl%%PG_USER%%-9.2.mo >Xshare/locale/de/LC_MESSAGES/postgres-9.2.mo >Xshare/locale/de/LC_MESSAGES/psql-9.2.mo >Xshare/locale/es/LC_MESSAGES/ecpg-9.2.mo >Xshare/locale/es/LC_MESSAGES/ecpglib6-9.2.mo >Xshare/locale/es/LC_MESSAGES/initdb-9.2.mo >Xshare/locale/es/LC_MESSAGES/libpq5-9.2.mo >Xshare/locale/es/LC_MESSAGES/pg_basebackup-9.2.mo >Xshare/locale/es/LC_MESSAGES/pg_config-9.2.mo >Xshare/locale/es/LC_MESSAGES/pg_controldata-9.2.mo >Xshare/locale/es/LC_MESSAGES/pg_ctl-9.2.mo >Xshare/locale/es/LC_MESSAGES/pg_dump-9.2.mo >Xshare/locale/es/LC_MESSAGES/pg_resetxlog-9.2.mo >Xshare/locale/es/LC_MESSAGES/pgscripts-9.2.mo >Xshare/locale/es/LC_MESSAGES/pl%%PG_USER%%-9.2.mo >Xshare/locale/es/LC_MESSAGES/postgres-9.2.mo >Xshare/locale/es/LC_MESSAGES/psql-9.2.mo >Xshare/locale/fr/LC_MESSAGES/ecpg-9.2.mo >Xshare/locale/fr/LC_MESSAGES/ecpglib6-9.2.mo >Xshare/locale/fr/LC_MESSAGES/initdb-9.2.mo >Xshare/locale/fr/LC_MESSAGES/libpq5-9.2.mo >Xshare/locale/fr/LC_MESSAGES/pg_basebackup-9.2.mo >Xshare/locale/fr/LC_MESSAGES/pg_config-9.2.mo >Xshare/locale/fr/LC_MESSAGES/pg_controldata-9.2.mo >Xshare/locale/fr/LC_MESSAGES/pg_ctl-9.2.mo >Xshare/locale/fr/LC_MESSAGES/pg_dump-9.2.mo >Xshare/locale/fr/LC_MESSAGES/pg_resetxlog-9.2.mo >Xshare/locale/fr/LC_MESSAGES/pgscripts-9.2.mo >Xshare/locale/fr/LC_MESSAGES/pl%%PG_USER%%-9.2.mo >Xshare/locale/fr/LC_MESSAGES/postgres-9.2.mo >Xshare/locale/fr/LC_MESSAGES/psql-9.2.mo >Xshare/locale/it/LC_MESSAGES/ecpg-9.2.mo >Xshare/locale/it/LC_MESSAGES/ecpglib6-9.2.mo >Xshare/locale/it/LC_MESSAGES/initdb-9.2.mo >Xshare/locale/it/LC_MESSAGES/libpq5-9.2.mo >Xshare/locale/it/LC_MESSAGES/pg_basebackup-9.2.mo >Xshare/locale/it/LC_MESSAGES/pg_config-9.2.mo >Xshare/locale/it/LC_MESSAGES/pg_controldata-9.2.mo >Xshare/locale/it/LC_MESSAGES/pg_ctl-9.2.mo >Xshare/locale/it/LC_MESSAGES/pg_dump-9.2.mo >Xshare/locale/it/LC_MESSAGES/pg_resetxlog-9.2.mo >Xshare/locale/it/LC_MESSAGES/pgscripts-9.2.mo >Xshare/locale/it/LC_MESSAGES/pl%%PG_USER%%-9.2.mo >Xshare/locale/it/LC_MESSAGES/postgres-9.2.mo >Xshare/locale/it/LC_MESSAGES/psql-9.2.mo >Xshare/locale/ja/LC_MESSAGES/ecpg-9.2.mo >Xshare/locale/ja/LC_MESSAGES/ecpglib6-9.2.mo >Xshare/locale/ja/LC_MESSAGES/initdb-9.2.mo >Xshare/locale/ja/LC_MESSAGES/libpq5-9.2.mo >Xshare/locale/ja/LC_MESSAGES/pg_basebackup-9.2.mo >Xshare/locale/ja/LC_MESSAGES/pg_config-9.2.mo >Xshare/locale/ja/LC_MESSAGES/pg_controldata-9.2.mo >Xshare/locale/ja/LC_MESSAGES/pg_ctl-9.2.mo >Xshare/locale/ja/LC_MESSAGES/pg_dump-9.2.mo >Xshare/locale/ja/LC_MESSAGES/pg_resetxlog-9.2.mo >Xshare/locale/ja/LC_MESSAGES/pgscripts-9.2.mo >Xshare/locale/ja/LC_MESSAGES/pl%%PG_USER%%-9.2.mo >Xshare/locale/ja/LC_MESSAGES/postgres-9.2.mo >Xshare/locale/ja/LC_MESSAGES/psql-9.2.mo >Xshare/locale/ko/LC_MESSAGES/ecpg-9.2.mo >Xshare/locale/ko/LC_MESSAGES/initdb-9.2.mo >Xshare/locale/ko/LC_MESSAGES/pg_config-9.2.mo >Xshare/locale/ko/LC_MESSAGES/pg_resetxlog-9.2.mo >Xshare/locale/ko/LC_MESSAGES/pgscripts-9.2.mo >Xshare/locale/nb/LC_MESSAGES/pg_config-9.2.mo >Xshare/locale/pl/LC_MESSAGES/ecpg-9.2.mo >Xshare/locale/pl/LC_MESSAGES/ecpglib6-9.2.mo >Xshare/locale/pl/LC_MESSAGES/initdb-9.2.mo >Xshare/locale/pl/LC_MESSAGES/libpq5-9.2.mo >Xshare/locale/pl/LC_MESSAGES/pg_basebackup-9.2.mo >Xshare/locale/pl/LC_MESSAGES/pg_config-9.2.mo >Xshare/locale/pl/LC_MESSAGES/pg_controldata-9.2.mo >Xshare/locale/pl/LC_MESSAGES/pg_ctl-9.2.mo >Xshare/locale/pl/LC_MESSAGES/pg_dump-9.2.mo >Xshare/locale/pl/LC_MESSAGES/pg_resetxlog-9.2.mo >Xshare/locale/pl/LC_MESSAGES/pgscripts-9.2.mo >Xshare/locale/pl/LC_MESSAGES/pl%%PG_USER%%-9.2.mo >Xshare/locale/pl/LC_MESSAGES/postgres-9.2.mo >Xshare/locale/pl/LC_MESSAGES/psql-9.2.mo >Xshare/locale/pt_BR/LC_MESSAGES/ecpg-9.2.mo >Xshare/locale/pt_BR/LC_MESSAGES/ecpglib6-9.2.mo >Xshare/locale/pt_BR/LC_MESSAGES/initdb-9.2.mo >Xshare/locale/pt_BR/LC_MESSAGES/libpq5-9.2.mo >Xshare/locale/pt_BR/LC_MESSAGES/pg_basebackup-9.2.mo >Xshare/locale/pt_BR/LC_MESSAGES/pg_config-9.2.mo >Xshare/locale/pt_BR/LC_MESSAGES/pg_controldata-9.2.mo >Xshare/locale/pt_BR/LC_MESSAGES/pg_ctl-9.2.mo >Xshare/locale/pt_BR/LC_MESSAGES/pg_dump-9.2.mo >Xshare/locale/pt_BR/LC_MESSAGES/pg_resetxlog-9.2.mo >Xshare/locale/pt_BR/LC_MESSAGES/pgscripts-9.2.mo >Xshare/locale/pt_BR/LC_MESSAGES/pl%%PG_USER%%-9.2.mo >Xshare/locale/pt_BR/LC_MESSAGES/postgres-9.2.mo >Xshare/locale/pt_BR/LC_MESSAGES/psql-9.2.mo >Xshare/locale/ro/LC_MESSAGES/initdb-9.2.mo >Xshare/locale/ro/LC_MESSAGES/pg_config-9.2.mo >Xshare/locale/ro/LC_MESSAGES/pg_controldata-9.2.mo >Xshare/locale/ro/LC_MESSAGES/pg_resetxlog-9.2.mo >Xshare/locale/ro/LC_MESSAGES/pgscripts-9.2.mo >Xshare/locale/ro/LC_MESSAGES/pl%%PG_USER%%-9.2.mo >Xshare/locale/ru/LC_MESSAGES/ecpg-9.2.mo >Xshare/locale/ru/LC_MESSAGES/ecpglib6-9.2.mo >Xshare/locale/ru/LC_MESSAGES/initdb-9.2.mo >Xshare/locale/ru/LC_MESSAGES/libpq5-9.2.mo >Xshare/locale/ru/LC_MESSAGES/pg_basebackup-9.2.mo >Xshare/locale/ru/LC_MESSAGES/pg_config-9.2.mo >Xshare/locale/ru/LC_MESSAGES/pg_controldata-9.2.mo >Xshare/locale/ru/LC_MESSAGES/pg_ctl-9.2.mo >Xshare/locale/ru/LC_MESSAGES/pg_dump-9.2.mo >Xshare/locale/ru/LC_MESSAGES/pg_resetxlog-9.2.mo >Xshare/locale/ru/LC_MESSAGES/pgscripts-9.2.mo >Xshare/locale/ru/LC_MESSAGES/pl%%PG_USER%%-9.2.mo >Xshare/locale/ru/LC_MESSAGES/postgres-9.2.mo >Xshare/locale/ru/LC_MESSAGES/psql-9.2.mo >Xshare/locale/sv/LC_MESSAGES/initdb-9.2.mo >Xshare/locale/sv/LC_MESSAGES/pg_config-9.2.mo >Xshare/locale/sv/LC_MESSAGES/pg_ctl-9.2.mo >Xshare/locale/sv/LC_MESSAGES/pgscripts-9.2.mo >Xshare/locale/ta/LC_MESSAGES/pg_config-9.2.mo >Xshare/locale/tr/LC_MESSAGES/ecpg-9.2.mo >Xshare/locale/tr/LC_MESSAGES/ecpglib6-9.2.mo >Xshare/locale/tr/LC_MESSAGES/initdb-9.2.mo >Xshare/locale/tr/LC_MESSAGES/libpq5-9.2.mo >Xshare/locale/tr/LC_MESSAGES/pg_config-9.2.mo >Xshare/locale/tr/LC_MESSAGES/pg_controldata-9.2.mo >Xshare/locale/tr/LC_MESSAGES/pg_resetxlog-9.2.mo >Xshare/locale/tr/LC_MESSAGES/pgscripts-9.2.mo >Xshare/locale/zh_CN/LC_MESSAGES/ecpg-9.2.mo >Xshare/locale/zh_CN/LC_MESSAGES/ecpglib6-9.2.mo >Xshare/locale/zh_CN/LC_MESSAGES/initdb-9.2.mo >Xshare/locale/zh_CN/LC_MESSAGES/libpq5-9.2.mo >Xshare/locale/zh_CN/LC_MESSAGES/pg_basebackup-9.2.mo >Xshare/locale/zh_CN/LC_MESSAGES/pg_config-9.2.mo >Xshare/locale/zh_CN/LC_MESSAGES/pg_controldata-9.2.mo >Xshare/locale/zh_CN/LC_MESSAGES/pg_ctl-9.2.mo >Xshare/locale/zh_CN/LC_MESSAGES/pg_dump-9.2.mo >Xshare/locale/zh_CN/LC_MESSAGES/pg_resetxlog-9.2.mo >Xshare/locale/zh_CN/LC_MESSAGES/pgscripts-9.2.mo >Xshare/locale/zh_CN/LC_MESSAGES/pl%%PG_USER%%-9.2.mo >Xshare/locale/zh_CN/LC_MESSAGES/postgres-9.2.mo >Xshare/locale/zh_CN/LC_MESSAGES/psql-9.2.mo >Xshare/locale/zh_TW/LC_MESSAGES/ecpg-9.2.mo >Xshare/locale/zh_TW/LC_MESSAGES/initdb-9.2.mo >Xshare/locale/zh_TW/LC_MESSAGES/libpq5-9.2.mo >Xshare/locale/zh_TW/LC_MESSAGES/pg_config-9.2.mo >Xshare/locale/zh_TW/LC_MESSAGES/pg_controldata-9.2.mo >Xshare/locale/zh_TW/LC_MESSAGES/pg_ctl-9.2.mo >Xshare/locale/zh_TW/LC_MESSAGES/pg_resetxlog-9.2.mo >Xshare/locale/zh_TW/LC_MESSAGES/pgscripts-9.2.mo >Xshare/locale/zh_TW/LC_MESSAGES/pl%%PG_USER%%-9.2.mo >Xshare/locale/zh_TW/LC_MESSAGES/postgres-9.2.mo >Xshare/locale/zh_TW/LC_MESSAGES/psql-9.2.mo >X%%DATADIR%%/contrib/fasttrun.sql >X%%DATADIR%%/contrib/fulleq.sql >X%%DATADIR%%/contrib/mchar.sql >X%%DATADIR%%/contrib/uninstall_mchar.sql >X%%DATADIR%%/conversion_create.sql >X%%DATADIR%%/extension/adminpack--1.0.sql >X%%DATADIR%%/extension/adminpack.control >X%%DATADIR%%/extension/autoinc--1.0.sql >X%%DATADIR%%/extension/autoinc--unpackaged--1.0.sql >X%%DATADIR%%/extension/autoinc.control >X%%DATADIR%%/extension/btree_gin--1.0.sql >X%%DATADIR%%/extension/btree_gin--unpackaged--1.0.sql >X%%DATADIR%%/extension/btree_gin.control >X%%DATADIR%%/extension/btree_gist--1.0.sql >X%%DATADIR%%/extension/btree_gist--unpackaged--1.0.sql >X%%DATADIR%%/extension/btree_gist.control >X%%DATADIR%%/extension/chkpass--1.0.sql >X%%DATADIR%%/extension/chkpass--unpackaged--1.0.sql >X%%DATADIR%%/extension/chkpass.control >X%%DATADIR%%/extension/citext--1.0.sql >X%%DATADIR%%/extension/citext--unpackaged--1.0.sql >X%%DATADIR%%/extension/citext.control >X%%DATADIR%%/extension/cube--1.0.sql >X%%DATADIR%%/extension/cube--unpackaged--1.0.sql >X%%DATADIR%%/extension/cube.control >X%%DATADIR%%/extension/dblink--1.0.sql >X%%DATADIR%%/extension/dblink--unpackaged--1.0.sql >X%%DATADIR%%/extension/dblink.control >X%%DATADIR%%/extension/dict_int--1.0.sql >X%%DATADIR%%/extension/dict_int--unpackaged--1.0.sql >X%%DATADIR%%/extension/dict_int.control >X%%DATADIR%%/extension/dict_xsyn--1.0.sql >X%%DATADIR%%/extension/dict_xsyn--unpackaged--1.0.sql >X%%DATADIR%%/extension/dict_xsyn.control >X%%DATADIR%%/extension/earthdistance--1.0.sql >X%%DATADIR%%/extension/earthdistance--unpackaged--1.0.sql >X%%DATADIR%%/extension/earthdistance.control >X%%DATADIR%%/extension/file_fdw--1.0.sql >X%%DATADIR%%/extension/file_fdw.control >X%%DATADIR%%/extension/fuzzystrmatch--1.0.sql >X%%DATADIR%%/extension/fuzzystrmatch--unpackaged--1.0.sql >X%%DATADIR%%/extension/fuzzystrmatch.control >X%%DATADIR%%/extension/hstore--1.0--1.1.sql >X%%DATADIR%%/extension/hstore--1.1.sql >X%%DATADIR%%/extension/hstore--unpackaged--1.0.sql >X%%DATADIR%%/extension/hstore.control >X%%DATADIR%%/extension/insert_username--1.0.sql >X%%DATADIR%%/extension/insert_username--unpackaged--1.0.sql >X%%DATADIR%%/extension/insert_username.control >X%%DATADIR%%/extension/intagg--1.0.sql >X%%DATADIR%%/extension/intagg--unpackaged--1.0.sql >X%%DATADIR%%/extension/intagg.control >X%%DATADIR%%/extension/intarray--1.0.sql >X%%DATADIR%%/extension/intarray--unpackaged--1.0.sql >X%%DATADIR%%/extension/intarray.control >X%%DATADIR%%/extension/isn--1.0.sql >X%%DATADIR%%/extension/isn--unpackaged--1.0.sql >X%%DATADIR%%/extension/isn.control >X%%DATADIR%%/extension/lo--1.0.sql >X%%DATADIR%%/extension/lo--unpackaged--1.0.sql >X%%DATADIR%%/extension/lo.control >X%%DATADIR%%/extension/ltree--1.0.sql >X%%DATADIR%%/extension/ltree--unpackaged--1.0.sql >X%%DATADIR%%/extension/ltree.control >X%%DATADIR%%/extension/moddatetime--1.0.sql >X%%DATADIR%%/extension/moddatetime--unpackaged--1.0.sql >X%%DATADIR%%/extension/moddatetime.control >X%%DATADIR%%/extension/pageinspect--1.0.sql >X%%DATADIR%%/extension/pageinspect--unpackaged--1.0.sql >X%%DATADIR%%/extension/pageinspect.control >X%%DATADIR%%/extension/pg_buffercache--1.0.sql >X%%DATADIR%%/extension/pg_buffercache--unpackaged--1.0.sql >X%%DATADIR%%/extension/pg_buffercache.control >X%%DATADIR%%/extension/pg_freespacemap--1.0.sql >X%%DATADIR%%/extension/pg_freespacemap--unpackaged--1.0.sql >X%%DATADIR%%/extension/pg_freespacemap.control >X%%DATADIR%%/extension/pg_stat_statements--1.0--1.1.sql >X%%DATADIR%%/extension/pg_stat_statements--1.1.sql >X%%DATADIR%%/extension/pg_stat_statements--unpackaged--1.0.sql >X%%DATADIR%%/extension/pg_stat_statements.control >X%%DATADIR%%/extension/pg_trgm--1.0.sql >X%%DATADIR%%/extension/pg_trgm--unpackaged--1.0.sql >X%%DATADIR%%/extension/pg_trgm.control >X%%DATADIR%%/extension/pgcrypto--1.0.sql >X%%DATADIR%%/extension/pgcrypto--unpackaged--1.0.sql >X%%DATADIR%%/extension/pgcrypto.control >X%%DATADIR%%/extension/pgrowlocks--1.0.sql >X%%DATADIR%%/extension/pgrowlocks--unpackaged--1.0.sql >X%%DATADIR%%/extension/pgrowlocks.control >X%%DATADIR%%/extension/pgstattuple--1.0.sql >X%%DATADIR%%/extension/pgstattuple--unpackaged--1.0.sql >X%%DATADIR%%/extension/pgstattuple.control >X%%DATADIR%%/extension/pl%%PG_USER%%--1.0.sql >X%%DATADIR%%/extension/pl%%PG_USER%%--unpackaged--1.0.sql >X%%DATADIR%%/extension/pl%%PG_USER%%.control >X%%DATADIR%%/extension/refint--1.0.sql >X%%DATADIR%%/extension/refint--unpackaged--1.0.sql >X%%DATADIR%%/extension/refint.control >X%%DATADIR%%/extension/seg--1.0.sql >X%%DATADIR%%/extension/seg--unpackaged--1.0.sql >X%%DATADIR%%/extension/seg.control >X%%DATADIR%%/extension/sslinfo--1.0.sql >X%%DATADIR%%/extension/sslinfo--unpackaged--1.0.sql >X%%DATADIR%%/extension/sslinfo.control >X%%DATADIR%%/extension/tablefunc--1.0.sql >X%%DATADIR%%/extension/tablefunc--unpackaged--1.0.sql >X%%DATADIR%%/extension/tablefunc.control >X%%DATADIR%%/extension/tcn--1.0.sql >X%%DATADIR%%/extension/tcn.control >X%%DATADIR%%/extension/test_parser--1.0.sql >X%%DATADIR%%/extension/test_parser--unpackaged--1.0.sql >X%%DATADIR%%/extension/test_parser.control >X%%DATADIR%%/extension/timetravel--1.0.sql >X%%DATADIR%%/extension/timetravel--unpackaged--1.0.sql >X%%DATADIR%%/extension/timetravel.control >X%%DATADIR%%/extension/tsearch2--1.0.sql >X%%DATADIR%%/extension/tsearch2--unpackaged--1.0.sql >X%%DATADIR%%/extension/tsearch2.control >X%%DATADIR%%/extension/unaccent--1.0.sql >X%%DATADIR%%/extension/unaccent--unpackaged--1.0.sql >X%%DATADIR%%/extension/unaccent.control >X%%DATADIR%%/extension/uuid-ossp--1.0.sql >X%%DATADIR%%/extension/uuid-ossp--unpackaged--1.0.sql >X%%DATADIR%%/extension/uuid-ossp.control >X%%DATADIR%%/extension/xml2--1.0.sql >X%%DATADIR%%/extension/xml2--unpackaged--1.0.sql >X%%DATADIR%%/extension/xml2.control >X%%DATADIR%%/information_schema.sql >X%%DATADIR%%/pg_hba.conf.sample >X%%DATADIR%%/pg_ident.conf.sample >X%%DATADIR%%/pg_service.conf.sample >X%%DATADIR%%/postgres.bki >X%%DATADIR%%/postgres.description >X%%DATADIR%%/postgres.shdescription >X%%DATADIR%%/postgresql.conf.sample >X%%DATADIR%%/psqlrc.sample >X%%DATADIR%%/recovery.conf.sample >X%%DATADIR%%/snowball_create.sql >X%%DATADIR%%/sql_features.txt >X%%DATADIR%%/system_views.sql >X%%DATADIR%%/timezone/Africa/Abidjan >X%%DATADIR%%/timezone/Africa/Accra >X%%DATADIR%%/timezone/Africa/Addis_Ababa >X%%DATADIR%%/timezone/Africa/Algiers >X%%DATADIR%%/timezone/Africa/Asmara >X%%DATADIR%%/timezone/Africa/Asmera >X%%DATADIR%%/timezone/Africa/Bamako >X%%DATADIR%%/timezone/Africa/Bangui >X%%DATADIR%%/timezone/Africa/Banjul >X%%DATADIR%%/timezone/Africa/Bissau >X%%DATADIR%%/timezone/Africa/Blantyre >X%%DATADIR%%/timezone/Africa/Brazzaville >X%%DATADIR%%/timezone/Africa/Bujumbura >X%%DATADIR%%/timezone/Africa/Cairo >X%%DATADIR%%/timezone/Africa/Casablanca >X%%DATADIR%%/timezone/Africa/Ceuta >X%%DATADIR%%/timezone/Africa/Conakry >X%%DATADIR%%/timezone/Africa/Dakar >X%%DATADIR%%/timezone/Africa/Dar_es_Salaam >X%%DATADIR%%/timezone/Africa/Djibouti >X%%DATADIR%%/timezone/Africa/Douala >X%%DATADIR%%/timezone/Africa/El_Aaiun >X%%DATADIR%%/timezone/Africa/Freetown >X%%DATADIR%%/timezone/Africa/Gaborone >X%%DATADIR%%/timezone/Africa/Harare >X%%DATADIR%%/timezone/Africa/Johannesburg >X%%DATADIR%%/timezone/Africa/Juba >X%%DATADIR%%/timezone/Africa/Kampala >X%%DATADIR%%/timezone/Africa/Khartoum >X%%DATADIR%%/timezone/Africa/Kigali >X%%DATADIR%%/timezone/Africa/Kinshasa >X%%DATADIR%%/timezone/Africa/Lagos >X%%DATADIR%%/timezone/Africa/Libreville >X%%DATADIR%%/timezone/Africa/Lome >X%%DATADIR%%/timezone/Africa/Luanda >X%%DATADIR%%/timezone/Africa/Lubumbashi >X%%DATADIR%%/timezone/Africa/Lusaka >X%%DATADIR%%/timezone/Africa/Malabo >X%%DATADIR%%/timezone/Africa/Maputo >X%%DATADIR%%/timezone/Africa/Maseru >X%%DATADIR%%/timezone/Africa/Mbabane >X%%DATADIR%%/timezone/Africa/Mogadishu >X%%DATADIR%%/timezone/Africa/Monrovia >X%%DATADIR%%/timezone/Africa/Nairobi >X%%DATADIR%%/timezone/Africa/Ndjamena >X%%DATADIR%%/timezone/Africa/Niamey >X%%DATADIR%%/timezone/Africa/Nouakchott >X%%DATADIR%%/timezone/Africa/Ouagadougou >X%%DATADIR%%/timezone/Africa/Porto-Novo >X%%DATADIR%%/timezone/Africa/Sao_Tome >X%%DATADIR%%/timezone/Africa/Timbuktu >X%%DATADIR%%/timezone/Africa/Tripoli >X%%DATADIR%%/timezone/Africa/Tunis >X%%DATADIR%%/timezone/Africa/Windhoek >X%%DATADIR%%/timezone/America/Adak >X%%DATADIR%%/timezone/America/Anchorage >X%%DATADIR%%/timezone/America/Anguilla >X%%DATADIR%%/timezone/America/Antigua >X%%DATADIR%%/timezone/America/Araguaina >X%%DATADIR%%/timezone/America/Argentina/Buenos_Aires >X%%DATADIR%%/timezone/America/Argentina/Catamarca >X%%DATADIR%%/timezone/America/Argentina/ComodRivadavia >X%%DATADIR%%/timezone/America/Argentina/Cordoba >X%%DATADIR%%/timezone/America/Argentina/Jujuy >X%%DATADIR%%/timezone/America/Argentina/La_Rioja >X%%DATADIR%%/timezone/America/Argentina/Mendoza >X%%DATADIR%%/timezone/America/Argentina/Rio_Gallegos >X%%DATADIR%%/timezone/America/Argentina/Salta >X%%DATADIR%%/timezone/America/Argentina/San_Juan >X%%DATADIR%%/timezone/America/Argentina/San_Luis >X%%DATADIR%%/timezone/America/Argentina/Tucuman >X%%DATADIR%%/timezone/America/Argentina/Ushuaia >X%%DATADIR%%/timezone/America/Aruba >X%%DATADIR%%/timezone/America/Asuncion >X%%DATADIR%%/timezone/America/Atikokan >X%%DATADIR%%/timezone/America/Atka >X%%DATADIR%%/timezone/America/Bahia >X%%DATADIR%%/timezone/America/Bahia_Banderas >X%%DATADIR%%/timezone/America/Barbados >X%%DATADIR%%/timezone/America/Belem >X%%DATADIR%%/timezone/America/Belize >X%%DATADIR%%/timezone/America/Blanc-Sablon >X%%DATADIR%%/timezone/America/Boa_Vista >X%%DATADIR%%/timezone/America/Bogota >X%%DATADIR%%/timezone/America/Boise >X%%DATADIR%%/timezone/America/Buenos_Aires >X%%DATADIR%%/timezone/America/Cambridge_Bay >X%%DATADIR%%/timezone/America/Campo_Grande >X%%DATADIR%%/timezone/America/Cancun >X%%DATADIR%%/timezone/America/Caracas >X%%DATADIR%%/timezone/America/Catamarca >X%%DATADIR%%/timezone/America/Cayenne >X%%DATADIR%%/timezone/America/Cayman >X%%DATADIR%%/timezone/America/Chicago >X%%DATADIR%%/timezone/America/Chihuahua >X%%DATADIR%%/timezone/America/Coral_Harbour >X%%DATADIR%%/timezone/America/Cordoba >X%%DATADIR%%/timezone/America/Costa_Rica >X%%DATADIR%%/timezone/America/Creston >X%%DATADIR%%/timezone/America/Cuiaba >X%%DATADIR%%/timezone/America/Curacao >X%%DATADIR%%/timezone/America/Danmarkshavn >X%%DATADIR%%/timezone/America/Dawson >X%%DATADIR%%/timezone/America/Dawson_Creek >X%%DATADIR%%/timezone/America/Denver >X%%DATADIR%%/timezone/America/Detroit >X%%DATADIR%%/timezone/America/Dominica >X%%DATADIR%%/timezone/America/Edmonton >X%%DATADIR%%/timezone/America/Eirunepe >X%%DATADIR%%/timezone/America/El_Salvador >X%%DATADIR%%/timezone/America/Ensenada >X%%DATADIR%%/timezone/America/Fort_Wayne >X%%DATADIR%%/timezone/America/Fortaleza >X%%DATADIR%%/timezone/America/Glace_Bay >X%%DATADIR%%/timezone/America/Godthab >X%%DATADIR%%/timezone/America/Goose_Bay >X%%DATADIR%%/timezone/America/Grand_Turk >X%%DATADIR%%/timezone/America/Grenada >X%%DATADIR%%/timezone/America/Guadeloupe >X%%DATADIR%%/timezone/America/Guatemala >X%%DATADIR%%/timezone/America/Guayaquil >X%%DATADIR%%/timezone/America/Guyana >X%%DATADIR%%/timezone/America/Halifax >X%%DATADIR%%/timezone/America/Havana >X%%DATADIR%%/timezone/America/Hermosillo >X%%DATADIR%%/timezone/America/Indiana/Indianapolis >X%%DATADIR%%/timezone/America/Indiana/Knox >X%%DATADIR%%/timezone/America/Indiana/Marengo >X%%DATADIR%%/timezone/America/Indiana/Petersburg >X%%DATADIR%%/timezone/America/Indiana/Tell_City >X%%DATADIR%%/timezone/America/Indiana/Vevay >X%%DATADIR%%/timezone/America/Indiana/Vincennes >X%%DATADIR%%/timezone/America/Indiana/Winamac >X%%DATADIR%%/timezone/America/Indianapolis >X%%DATADIR%%/timezone/America/Inuvik >X%%DATADIR%%/timezone/America/Iqaluit >X%%DATADIR%%/timezone/America/Jamaica >X%%DATADIR%%/timezone/America/Jujuy >X%%DATADIR%%/timezone/America/Juneau >X%%DATADIR%%/timezone/America/Kentucky/Louisville >X%%DATADIR%%/timezone/America/Kentucky/Monticello >X%%DATADIR%%/timezone/America/Knox_IN >X%%DATADIR%%/timezone/America/Kralendijk >X%%DATADIR%%/timezone/America/La_Paz >X%%DATADIR%%/timezone/America/Lima >X%%DATADIR%%/timezone/America/Los_Angeles >X%%DATADIR%%/timezone/America/Louisville >X%%DATADIR%%/timezone/America/Lower_Princes >X%%DATADIR%%/timezone/America/Maceio >X%%DATADIR%%/timezone/America/Managua >X%%DATADIR%%/timezone/America/Manaus >X%%DATADIR%%/timezone/America/Marigot >X%%DATADIR%%/timezone/America/Martinique >X%%DATADIR%%/timezone/America/Matamoros >X%%DATADIR%%/timezone/America/Mazatlan >X%%DATADIR%%/timezone/America/Mendoza >X%%DATADIR%%/timezone/America/Menominee >X%%DATADIR%%/timezone/America/Merida >X%%DATADIR%%/timezone/America/Metlakatla >X%%DATADIR%%/timezone/America/Mexico_City >X%%DATADIR%%/timezone/America/Miquelon >X%%DATADIR%%/timezone/America/Moncton >X%%DATADIR%%/timezone/America/Monterrey >X%%DATADIR%%/timezone/America/Montevideo >X%%DATADIR%%/timezone/America/Montreal >X%%DATADIR%%/timezone/America/Montserrat >X%%DATADIR%%/timezone/America/Nassau >X%%DATADIR%%/timezone/America/New_York >X%%DATADIR%%/timezone/America/Nipigon >X%%DATADIR%%/timezone/America/Nome >X%%DATADIR%%/timezone/America/Noronha >X%%DATADIR%%/timezone/America/North_Dakota/Beulah >X%%DATADIR%%/timezone/America/North_Dakota/Center >X%%DATADIR%%/timezone/America/North_Dakota/New_Salem >X%%DATADIR%%/timezone/America/Ojinaga >X%%DATADIR%%/timezone/America/Panama >X%%DATADIR%%/timezone/America/Pangnirtung >X%%DATADIR%%/timezone/America/Paramaribo >X%%DATADIR%%/timezone/America/Phoenix >X%%DATADIR%%/timezone/America/Port-au-Prince >X%%DATADIR%%/timezone/America/Port_of_Spain >X%%DATADIR%%/timezone/America/Porto_Acre >X%%DATADIR%%/timezone/America/Porto_Velho >X%%DATADIR%%/timezone/America/Puerto_Rico >X%%DATADIR%%/timezone/America/Rainy_River >X%%DATADIR%%/timezone/America/Rankin_Inlet >X%%DATADIR%%/timezone/America/Recife >X%%DATADIR%%/timezone/America/Regina >X%%DATADIR%%/timezone/America/Resolute >X%%DATADIR%%/timezone/America/Rio_Branco >X%%DATADIR%%/timezone/America/Rosario >X%%DATADIR%%/timezone/America/Santa_Isabel >X%%DATADIR%%/timezone/America/Santarem >X%%DATADIR%%/timezone/America/Santiago >X%%DATADIR%%/timezone/America/Santo_Domingo >X%%DATADIR%%/timezone/America/Sao_Paulo >X%%DATADIR%%/timezone/America/Scoresbysund >X%%DATADIR%%/timezone/America/Shiprock >X%%DATADIR%%/timezone/America/Sitka >X%%DATADIR%%/timezone/America/St_Barthelemy >X%%DATADIR%%/timezone/America/St_Johns >X%%DATADIR%%/timezone/America/St_Kitts >X%%DATADIR%%/timezone/America/St_Lucia >X%%DATADIR%%/timezone/America/St_Thomas >X%%DATADIR%%/timezone/America/St_Vincent >X%%DATADIR%%/timezone/America/Swift_Current >X%%DATADIR%%/timezone/America/Tegucigalpa >X%%DATADIR%%/timezone/America/Thule >X%%DATADIR%%/timezone/America/Thunder_Bay >X%%DATADIR%%/timezone/America/Tijuana >X%%DATADIR%%/timezone/America/Toronto >X%%DATADIR%%/timezone/America/Tortola >X%%DATADIR%%/timezone/America/Vancouver >X%%DATADIR%%/timezone/America/Virgin >X%%DATADIR%%/timezone/America/Whitehorse >X%%DATADIR%%/timezone/America/Winnipeg >X%%DATADIR%%/timezone/America/Yakutat >X%%DATADIR%%/timezone/America/Yellowknife >X%%DATADIR%%/timezone/Antarctica/Casey >X%%DATADIR%%/timezone/Antarctica/Davis >X%%DATADIR%%/timezone/Antarctica/DumontDUrville >X%%DATADIR%%/timezone/Antarctica/Macquarie >X%%DATADIR%%/timezone/Antarctica/Mawson >X%%DATADIR%%/timezone/Antarctica/McMurdo >X%%DATADIR%%/timezone/Antarctica/Palmer >X%%DATADIR%%/timezone/Antarctica/Rothera >X%%DATADIR%%/timezone/Antarctica/South_Pole >X%%DATADIR%%/timezone/Antarctica/Syowa >X%%DATADIR%%/timezone/Antarctica/Troll >X%%DATADIR%%/timezone/Antarctica/Vostok >X%%DATADIR%%/timezone/Arctic/Longyearbyen >X%%DATADIR%%/timezone/Asia/Aden >X%%DATADIR%%/timezone/Asia/Almaty >X%%DATADIR%%/timezone/Asia/Amman >X%%DATADIR%%/timezone/Asia/Anadyr >X%%DATADIR%%/timezone/Asia/Aqtau >X%%DATADIR%%/timezone/Asia/Aqtobe >X%%DATADIR%%/timezone/Asia/Ashgabat >X%%DATADIR%%/timezone/Asia/Ashkhabad >X%%DATADIR%%/timezone/Asia/Baghdad >X%%DATADIR%%/timezone/Asia/Bahrain >X%%DATADIR%%/timezone/Asia/Baku >X%%DATADIR%%/timezone/Asia/Bangkok >X%%DATADIR%%/timezone/Asia/Beirut >X%%DATADIR%%/timezone/Asia/Bishkek >X%%DATADIR%%/timezone/Asia/Brunei >X%%DATADIR%%/timezone/Asia/Calcutta >X%%DATADIR%%/timezone/Asia/Choibalsan >X%%DATADIR%%/timezone/Asia/Chongqing >X%%DATADIR%%/timezone/Asia/Chungking >X%%DATADIR%%/timezone/Asia/Colombo >X%%DATADIR%%/timezone/Asia/Dacca >X%%DATADIR%%/timezone/Asia/Damascus >X%%DATADIR%%/timezone/Asia/Dhaka >X%%DATADIR%%/timezone/Asia/Dili >X%%DATADIR%%/timezone/Asia/Dubai >X%%DATADIR%%/timezone/Asia/Dushanbe >X%%DATADIR%%/timezone/Asia/Gaza >X%%DATADIR%%/timezone/Asia/Harbin >X%%DATADIR%%/timezone/Asia/Hebron >X%%DATADIR%%/timezone/Asia/Ho_Chi_Minh >X%%DATADIR%%/timezone/Asia/Hong_Kong >X%%DATADIR%%/timezone/Asia/Hovd >X%%DATADIR%%/timezone/Asia/Irkutsk >X%%DATADIR%%/timezone/Asia/Istanbul >X%%DATADIR%%/timezone/Asia/Jakarta >X%%DATADIR%%/timezone/Asia/Jayapura >X%%DATADIR%%/timezone/Asia/Jerusalem >X%%DATADIR%%/timezone/Asia/Kabul >X%%DATADIR%%/timezone/Asia/Kamchatka >X%%DATADIR%%/timezone/Asia/Karachi >X%%DATADIR%%/timezone/Asia/Kashgar >X%%DATADIR%%/timezone/Asia/Kathmandu >X%%DATADIR%%/timezone/Asia/Katmandu >X%%DATADIR%%/timezone/Asia/Khandyga >X%%DATADIR%%/timezone/Asia/Kolkata >X%%DATADIR%%/timezone/Asia/Krasnoyarsk >X%%DATADIR%%/timezone/Asia/Kuala_Lumpur >X%%DATADIR%%/timezone/Asia/Kuching >X%%DATADIR%%/timezone/Asia/Kuwait >X%%DATADIR%%/timezone/Asia/Macao >X%%DATADIR%%/timezone/Asia/Macau >X%%DATADIR%%/timezone/Asia/Magadan >X%%DATADIR%%/timezone/Asia/Makassar >X%%DATADIR%%/timezone/Asia/Manila >X%%DATADIR%%/timezone/Asia/Muscat >X%%DATADIR%%/timezone/Asia/Nicosia >X%%DATADIR%%/timezone/Asia/Novokuznetsk >X%%DATADIR%%/timezone/Asia/Novosibirsk >X%%DATADIR%%/timezone/Asia/Omsk >X%%DATADIR%%/timezone/Asia/Oral >X%%DATADIR%%/timezone/Asia/Phnom_Penh >X%%DATADIR%%/timezone/Asia/Pontianak >X%%DATADIR%%/timezone/Asia/Pyongyang >X%%DATADIR%%/timezone/Asia/Qatar >X%%DATADIR%%/timezone/Asia/Qyzylorda >X%%DATADIR%%/timezone/Asia/Rangoon >X%%DATADIR%%/timezone/Asia/Riyadh >X%%DATADIR%%/timezone/Asia/Saigon >X%%DATADIR%%/timezone/Asia/Sakhalin >X%%DATADIR%%/timezone/Asia/Samarkand >X%%DATADIR%%/timezone/Asia/Seoul >X%%DATADIR%%/timezone/Asia/Shanghai >X%%DATADIR%%/timezone/Asia/Singapore >X%%DATADIR%%/timezone/Asia/Taipei >X%%DATADIR%%/timezone/Asia/Tashkent >X%%DATADIR%%/timezone/Asia/Tbilisi >X%%DATADIR%%/timezone/Asia/Tehran >X%%DATADIR%%/timezone/Asia/Tel_Aviv >X%%DATADIR%%/timezone/Asia/Thimbu >X%%DATADIR%%/timezone/Asia/Thimphu >X%%DATADIR%%/timezone/Asia/Tokyo >X%%DATADIR%%/timezone/Asia/Ujung_Pandang >X%%DATADIR%%/timezone/Asia/Ulaanbaatar >X%%DATADIR%%/timezone/Asia/Ulan_Bator >X%%DATADIR%%/timezone/Asia/Urumqi >X%%DATADIR%%/timezone/Asia/Ust-Nera >X%%DATADIR%%/timezone/Asia/Vientiane >X%%DATADIR%%/timezone/Asia/Vladivostok >X%%DATADIR%%/timezone/Asia/Yakutsk >X%%DATADIR%%/timezone/Asia/Yekaterinburg >X%%DATADIR%%/timezone/Asia/Yerevan >X%%DATADIR%%/timezone/Atlantic/Azores >X%%DATADIR%%/timezone/Atlantic/Bermuda >X%%DATADIR%%/timezone/Atlantic/Canary >X%%DATADIR%%/timezone/Atlantic/Cape_Verde >X%%DATADIR%%/timezone/Atlantic/Faeroe >X%%DATADIR%%/timezone/Atlantic/Faroe >X%%DATADIR%%/timezone/Atlantic/Jan_Mayen >X%%DATADIR%%/timezone/Atlantic/Madeira >X%%DATADIR%%/timezone/Atlantic/Reykjavik >X%%DATADIR%%/timezone/Atlantic/South_Georgia >X%%DATADIR%%/timezone/Atlantic/St_Helena >X%%DATADIR%%/timezone/Atlantic/Stanley >X%%DATADIR%%/timezone/Australia/ACT >X%%DATADIR%%/timezone/Australia/Adelaide >X%%DATADIR%%/timezone/Australia/Brisbane >X%%DATADIR%%/timezone/Australia/Broken_Hill >X%%DATADIR%%/timezone/Australia/Canberra >X%%DATADIR%%/timezone/Australia/Currie >X%%DATADIR%%/timezone/Australia/Darwin >X%%DATADIR%%/timezone/Australia/Eucla >X%%DATADIR%%/timezone/Australia/Hobart >X%%DATADIR%%/timezone/Australia/LHI >X%%DATADIR%%/timezone/Australia/Lindeman >X%%DATADIR%%/timezone/Australia/Lord_Howe >X%%DATADIR%%/timezone/Australia/Melbourne >X%%DATADIR%%/timezone/Australia/NSW >X%%DATADIR%%/timezone/Australia/North >X%%DATADIR%%/timezone/Australia/Perth >X%%DATADIR%%/timezone/Australia/Queensland >X%%DATADIR%%/timezone/Australia/South >X%%DATADIR%%/timezone/Australia/Sydney >X%%DATADIR%%/timezone/Australia/Tasmania >X%%DATADIR%%/timezone/Australia/Victoria >X%%DATADIR%%/timezone/Australia/West >X%%DATADIR%%/timezone/Australia/Yancowinna >X%%DATADIR%%/timezone/Brazil/Acre >X%%DATADIR%%/timezone/Brazil/DeNoronha >X%%DATADIR%%/timezone/Brazil/East >X%%DATADIR%%/timezone/Brazil/West >X%%DATADIR%%/timezone/CET >X%%DATADIR%%/timezone/CST6CDT >X%%DATADIR%%/timezone/Canada/Atlantic >X%%DATADIR%%/timezone/Canada/Central >X%%DATADIR%%/timezone/Canada/East-Saskatchewan >X%%DATADIR%%/timezone/Canada/Eastern >X%%DATADIR%%/timezone/Canada/Mountain >X%%DATADIR%%/timezone/Canada/Newfoundland >X%%DATADIR%%/timezone/Canada/Pacific >X%%DATADIR%%/timezone/Canada/Saskatchewan >X%%DATADIR%%/timezone/Canada/Yukon >X%%DATADIR%%/timezone/Chile/Continental >X%%DATADIR%%/timezone/Chile/EasterIsland >X%%DATADIR%%/timezone/Cuba >X%%DATADIR%%/timezone/EET >X%%DATADIR%%/timezone/EST >X%%DATADIR%%/timezone/EST5EDT >X%%DATADIR%%/timezone/Egypt >X%%DATADIR%%/timezone/Eire >X%%DATADIR%%/timezone/Etc/GMT >X%%DATADIR%%/timezone/Etc/GMT+0 >X%%DATADIR%%/timezone/Etc/GMT+1 >X%%DATADIR%%/timezone/Etc/GMT+10 >X%%DATADIR%%/timezone/Etc/GMT+11 >X%%DATADIR%%/timezone/Etc/GMT+12 >X%%DATADIR%%/timezone/Etc/GMT+2 >X%%DATADIR%%/timezone/Etc/GMT+3 >X%%DATADIR%%/timezone/Etc/GMT+4 >X%%DATADIR%%/timezone/Etc/GMT+5 >X%%DATADIR%%/timezone/Etc/GMT+6 >X%%DATADIR%%/timezone/Etc/GMT+7 >X%%DATADIR%%/timezone/Etc/GMT+8 >X%%DATADIR%%/timezone/Etc/GMT+9 >X%%DATADIR%%/timezone/Etc/GMT-0 >X%%DATADIR%%/timezone/Etc/GMT-1 >X%%DATADIR%%/timezone/Etc/GMT-10 >X%%DATADIR%%/timezone/Etc/GMT-11 >X%%DATADIR%%/timezone/Etc/GMT-12 >X%%DATADIR%%/timezone/Etc/GMT-13 >X%%DATADIR%%/timezone/Etc/GMT-14 >X%%DATADIR%%/timezone/Etc/GMT-2 >X%%DATADIR%%/timezone/Etc/GMT-3 >X%%DATADIR%%/timezone/Etc/GMT-4 >X%%DATADIR%%/timezone/Etc/GMT-5 >X%%DATADIR%%/timezone/Etc/GMT-6 >X%%DATADIR%%/timezone/Etc/GMT-7 >X%%DATADIR%%/timezone/Etc/GMT-8 >X%%DATADIR%%/timezone/Etc/GMT-9 >X%%DATADIR%%/timezone/Etc/GMT0 >X%%DATADIR%%/timezone/Etc/Greenwich >X%%DATADIR%%/timezone/Etc/UCT >X%%DATADIR%%/timezone/Etc/UTC >X%%DATADIR%%/timezone/Etc/Universal >X%%DATADIR%%/timezone/Etc/Zulu >X%%DATADIR%%/timezone/Europe/Amsterdam >X%%DATADIR%%/timezone/Europe/Andorra >X%%DATADIR%%/timezone/Europe/Athens >X%%DATADIR%%/timezone/Europe/Belfast >X%%DATADIR%%/timezone/Europe/Belgrade >X%%DATADIR%%/timezone/Europe/Berlin >X%%DATADIR%%/timezone/Europe/Bratislava >X%%DATADIR%%/timezone/Europe/Brussels >X%%DATADIR%%/timezone/Europe/Bucharest >X%%DATADIR%%/timezone/Europe/Budapest >X%%DATADIR%%/timezone/Europe/Busingen >X%%DATADIR%%/timezone/Europe/Chisinau >X%%DATADIR%%/timezone/Europe/Copenhagen >X%%DATADIR%%/timezone/Europe/Dublin >X%%DATADIR%%/timezone/Europe/Gibraltar >X%%DATADIR%%/timezone/Europe/Guernsey >X%%DATADIR%%/timezone/Europe/Helsinki >X%%DATADIR%%/timezone/Europe/Isle_of_Man >X%%DATADIR%%/timezone/Europe/Istanbul >X%%DATADIR%%/timezone/Europe/Jersey >X%%DATADIR%%/timezone/Europe/Kaliningrad >X%%DATADIR%%/timezone/Europe/Kiev >X%%DATADIR%%/timezone/Europe/Lisbon >X%%DATADIR%%/timezone/Europe/Ljubljana >X%%DATADIR%%/timezone/Europe/London >X%%DATADIR%%/timezone/Europe/Luxembourg >X%%DATADIR%%/timezone/Europe/Madrid >X%%DATADIR%%/timezone/Europe/Malta >X%%DATADIR%%/timezone/Europe/Mariehamn >X%%DATADIR%%/timezone/Europe/Minsk >X%%DATADIR%%/timezone/Europe/Monaco >X%%DATADIR%%/timezone/Europe/Moscow >X%%DATADIR%%/timezone/Europe/Nicosia >X%%DATADIR%%/timezone/Europe/Oslo >X%%DATADIR%%/timezone/Europe/Paris >X%%DATADIR%%/timezone/Europe/Podgorica >X%%DATADIR%%/timezone/Europe/Prague >X%%DATADIR%%/timezone/Europe/Riga >X%%DATADIR%%/timezone/Europe/Rome >X%%DATADIR%%/timezone/Europe/Samara >X%%DATADIR%%/timezone/Europe/San_Marino >X%%DATADIR%%/timezone/Europe/Sarajevo >X%%DATADIR%%/timezone/Europe/Simferopol >X%%DATADIR%%/timezone/Europe/Skopje >X%%DATADIR%%/timezone/Europe/Sofia >X%%DATADIR%%/timezone/Europe/Stockholm >X%%DATADIR%%/timezone/Europe/Tallinn >X%%DATADIR%%/timezone/Europe/Tirane >X%%DATADIR%%/timezone/Europe/Tiraspol >X%%DATADIR%%/timezone/Europe/Uzhgorod >X%%DATADIR%%/timezone/Europe/Vaduz >X%%DATADIR%%/timezone/Europe/Vatican >X%%DATADIR%%/timezone/Europe/Vienna >X%%DATADIR%%/timezone/Europe/Vilnius >X%%DATADIR%%/timezone/Europe/Volgograd >X%%DATADIR%%/timezone/Europe/Warsaw >X%%DATADIR%%/timezone/Europe/Zagreb >X%%DATADIR%%/timezone/Europe/Zaporozhye >X%%DATADIR%%/timezone/Europe/Zurich >X%%DATADIR%%/timezone/Factory >X%%DATADIR%%/timezone/GB >X%%DATADIR%%/timezone/GB-Eire >X%%DATADIR%%/timezone/GMT >X%%DATADIR%%/timezone/GMT+0 >X%%DATADIR%%/timezone/GMT-0 >X%%DATADIR%%/timezone/GMT0 >X%%DATADIR%%/timezone/Greenwich >X%%DATADIR%%/timezone/HST >X%%DATADIR%%/timezone/Hongkong >X%%DATADIR%%/timezone/Iceland >X%%DATADIR%%/timezone/Indian/Antananarivo >X%%DATADIR%%/timezone/Indian/Chagos >X%%DATADIR%%/timezone/Indian/Christmas >X%%DATADIR%%/timezone/Indian/Cocos >X%%DATADIR%%/timezone/Indian/Comoro >X%%DATADIR%%/timezone/Indian/Kerguelen >X%%DATADIR%%/timezone/Indian/Mahe >X%%DATADIR%%/timezone/Indian/Maldives >X%%DATADIR%%/timezone/Indian/Mauritius >X%%DATADIR%%/timezone/Indian/Mayotte >X%%DATADIR%%/timezone/Indian/Reunion >X%%DATADIR%%/timezone/Iran >X%%DATADIR%%/timezone/Israel >X%%DATADIR%%/timezone/Jamaica >X%%DATADIR%%/timezone/Japan >X%%DATADIR%%/timezone/Kwajalein >X%%DATADIR%%/timezone/Libya >X%%DATADIR%%/timezone/MET >X%%DATADIR%%/timezone/MST >X%%DATADIR%%/timezone/MST7MDT >X%%DATADIR%%/timezone/Mexico/BajaNorte >X%%DATADIR%%/timezone/Mexico/BajaSur >X%%DATADIR%%/timezone/Mexico/General >X%%DATADIR%%/timezone/NZ >X%%DATADIR%%/timezone/NZ-CHAT >X%%DATADIR%%/timezone/Navajo >X%%DATADIR%%/timezone/PRC >X%%DATADIR%%/timezone/PST8PDT >X%%DATADIR%%/timezone/Pacific/Apia >X%%DATADIR%%/timezone/Pacific/Auckland >X%%DATADIR%%/timezone/Pacific/Chatham >X%%DATADIR%%/timezone/Pacific/Chuuk >X%%DATADIR%%/timezone/Pacific/Easter >X%%DATADIR%%/timezone/Pacific/Efate >X%%DATADIR%%/timezone/Pacific/Enderbury >X%%DATADIR%%/timezone/Pacific/Fakaofo >X%%DATADIR%%/timezone/Pacific/Fiji >X%%DATADIR%%/timezone/Pacific/Funafuti >X%%DATADIR%%/timezone/Pacific/Galapagos >X%%DATADIR%%/timezone/Pacific/Gambier >X%%DATADIR%%/timezone/Pacific/Guadalcanal >X%%DATADIR%%/timezone/Pacific/Guam >X%%DATADIR%%/timezone/Pacific/Honolulu >X%%DATADIR%%/timezone/Pacific/Johnston >X%%DATADIR%%/timezone/Pacific/Kiritimati >X%%DATADIR%%/timezone/Pacific/Kosrae >X%%DATADIR%%/timezone/Pacific/Kwajalein >X%%DATADIR%%/timezone/Pacific/Majuro >X%%DATADIR%%/timezone/Pacific/Marquesas >X%%DATADIR%%/timezone/Pacific/Midway >X%%DATADIR%%/timezone/Pacific/Nauru >X%%DATADIR%%/timezone/Pacific/Niue >X%%DATADIR%%/timezone/Pacific/Norfolk >X%%DATADIR%%/timezone/Pacific/Noumea >X%%DATADIR%%/timezone/Pacific/Pago_Pago >X%%DATADIR%%/timezone/Pacific/Palau >X%%DATADIR%%/timezone/Pacific/Pitcairn >X%%DATADIR%%/timezone/Pacific/Pohnpei >X%%DATADIR%%/timezone/Pacific/Ponape >X%%DATADIR%%/timezone/Pacific/Port_Moresby >X%%DATADIR%%/timezone/Pacific/Rarotonga >X%%DATADIR%%/timezone/Pacific/Saipan >X%%DATADIR%%/timezone/Pacific/Samoa >X%%DATADIR%%/timezone/Pacific/Tahiti >X%%DATADIR%%/timezone/Pacific/Tarawa >X%%DATADIR%%/timezone/Pacific/Tongatapu >X%%DATADIR%%/timezone/Pacific/Truk >X%%DATADIR%%/timezone/Pacific/Wake >X%%DATADIR%%/timezone/Pacific/Wallis >X%%DATADIR%%/timezone/Pacific/Yap >X%%DATADIR%%/timezone/Poland >X%%DATADIR%%/timezone/Portugal >X%%DATADIR%%/timezone/ROC >X%%DATADIR%%/timezone/ROK >X%%DATADIR%%/timezone/Singapore >X%%DATADIR%%/timezone/Turkey >X%%DATADIR%%/timezone/UCT >X%%DATADIR%%/timezone/US/Alaska >X%%DATADIR%%/timezone/US/Aleutian >X%%DATADIR%%/timezone/US/Arizona >X%%DATADIR%%/timezone/US/Central >X%%DATADIR%%/timezone/US/East-Indiana >X%%DATADIR%%/timezone/US/Eastern >X%%DATADIR%%/timezone/US/Hawaii >X%%DATADIR%%/timezone/US/Indiana-Starke >X%%DATADIR%%/timezone/US/Michigan >X%%DATADIR%%/timezone/US/Mountain >X%%DATADIR%%/timezone/US/Pacific >X%%DATADIR%%/timezone/US/Pacific-New >X%%DATADIR%%/timezone/US/Samoa >X%%DATADIR%%/timezone/UTC >X%%DATADIR%%/timezone/Universal >X%%DATADIR%%/timezone/W-SU >X%%DATADIR%%/timezone/WET >X%%DATADIR%%/timezone/Zulu >X%%DATADIR%%/timezone/posixrules >X%%DATADIR%%/timezonesets/Africa.txt >X%%DATADIR%%/timezonesets/America.txt >X%%DATADIR%%/timezonesets/Antarctica.txt >X%%DATADIR%%/timezonesets/Asia.txt >X%%DATADIR%%/timezonesets/Atlantic.txt >X%%DATADIR%%/timezonesets/Australia >X%%DATADIR%%/timezonesets/Australia.txt >X%%DATADIR%%/timezonesets/Default >X%%DATADIR%%/timezonesets/Etc.txt >X%%DATADIR%%/timezonesets/Europe.txt >X%%DATADIR%%/timezonesets/India >X%%DATADIR%%/timezonesets/Indian.txt >X%%DATADIR%%/timezonesets/Pacific.txt >X%%DATADIR%%/tsearch_data/danish.stop >X%%DATADIR%%/tsearch_data/dutch.stop >X%%DATADIR%%/tsearch_data/english.stop >X%%DATADIR%%/tsearch_data/finnish.stop >X%%DATADIR%%/tsearch_data/french.stop >X%%DATADIR%%/tsearch_data/german.stop >X%%DATADIR%%/tsearch_data/hungarian.stop >X%%DATADIR%%/tsearch_data/hunspell_sample.affix >X%%DATADIR%%/tsearch_data/ispell_sample.affix >X%%DATADIR%%/tsearch_data/ispell_sample.dict >X%%DATADIR%%/tsearch_data/italian.stop >X%%DATADIR%%/tsearch_data/norwegian.stop >X%%DATADIR%%/tsearch_data/portuguese.stop >X%%DATADIR%%/tsearch_data/russian.stop >X%%DATADIR%%/tsearch_data/spanish.stop >X%%DATADIR%%/tsearch_data/swedish.stop >X%%DATADIR%%/tsearch_data/synonym_sample.syn >X%%DATADIR%%/tsearch_data/thesaurus_sample.ths >X%%DATADIR%%/tsearch_data/turkish.stop >X%%DATADIR%%/tsearch_data/unaccent.rules >X%%DATADIR%%/tsearch_data/xsyn_sample.rules >X@exec /bin/mkdir -p %%PREFIX%%/%%PG_USER%% || /usr/bin/true >X@exec /usr/sbin/chown %%PG_USER%%:%%PG_GROUP%% %%PREFIX%%/%%PG_USER%% || /usr/bin/true >X@exec /bin/ln -s -f /usr/share/locale/en_US.UTF-8 /usr/share/locale/en_US || /usr/bin/true >X@dirrmtry etc/periodic/daily >X@dirrmtry etc/periodic >X@dirrmtry include/libpq >X@dirrmtry include/postgresql/informix/esql >X@dirrmtry include/postgresql/informix >X@dirrmtry include/postgresql/internal/libpq >X@dirrmtry include/postgresql/internal >X@dirrmtry include/postgresql/server/access >X@dirrmtry include/postgresql/server/bootstrap >X@dirrmtry include/postgresql/server/catalog >X@dirrmtry include/postgresql/server/commands >X@dirrmtry include/postgresql/server/datatype >X@dirrmtry include/postgresql/server/executor >X@dirrmtry include/postgresql/server/foreign >X@dirrmtry include/postgresql/server/lib >X@dirrmtry include/postgresql/server/libpq >X@dirrmtry include/postgresql/server/mb >X@dirrmtry include/postgresql/server/nodes >X@dirrmtry include/postgresql/server/optimizer >X@dirrmtry include/postgresql/server/parser >X@dirrmtry include/postgresql/server/port/win32/arpa >X@dirrmtry include/postgresql/server/port/win32/netinet >X@dirrmtry include/postgresql/server/port/win32/sys >X@dirrmtry include/postgresql/server/port/win32 >X@dirrmtry include/postgresql/server/port/win32_msvc/sys >X@dirrmtry include/postgresql/server/port/win32_msvc >X@dirrmtry include/postgresql/server/port >X@dirrmtry include/postgresql/server/portability >X@dirrmtry include/postgresql/server/postmaster >X@dirrmtry include/postgresql/server/regex >X@dirrmtry include/postgresql/server/replication >X@dirrmtry include/postgresql/server/rewrite >X@dirrmtry include/postgresql/server/snowball/libstemmer >X@dirrmtry include/postgresql/server/snowball >X@dirrmtry include/postgresql/server/storage >X@dirrmtry include/postgresql/server/tcop >X@dirrmtry include/postgresql/server/tsearch/dicts >X@dirrmtry include/postgresql/server/tsearch >X@dirrmtry include/postgresql/server/utils >X@dirrmtry include/postgresql/server >X@dirrmtry include/postgresql >X@dirrmtry lib/postgresql/pgxs/config >X@dirrmtry lib/postgresql/pgxs/src/makefiles >X@dirrmtry lib/postgresql/pgxs/src >X@dirrmtry lib/postgresql/pgxs >X@dirrmtry lib/postgresql >X@dirrmtry %%PG_USER%% >X%%PORTDOCS%%@dirrmtry %%DOCSDIR%%/contrib >X%%PORTDOCS%%@dirrmtry %%DOCSDIR%%/extension >X%%PORTDOCS%%@dirrmtry %%DOCSDIR%% >X@dirrmtry %%DATADIR%%/contrib >X@dirrmtry %%DATADIR%%/extension >X@dirrmtry %%DATADIR%%/timezone/Africa >X@dirrmtry %%DATADIR%%/timezone/America/Argentina >X@dirrmtry %%DATADIR%%/timezone/America/Indiana >X@dirrmtry %%DATADIR%%/timezone/America/Kentucky >X@dirrmtry %%DATADIR%%/timezone/America/North_Dakota >X@dirrmtry %%DATADIR%%/timezone/America >X@dirrmtry %%DATADIR%%/timezone/Antarctica >X@dirrmtry %%DATADIR%%/timezone/Arctic >X@dirrmtry %%DATADIR%%/timezone/Asia >X@dirrmtry %%DATADIR%%/timezone/Atlantic >X@dirrmtry %%DATADIR%%/timezone/Australia >X@dirrmtry %%DATADIR%%/timezone/Brazil >X@dirrmtry %%DATADIR%%/timezone/Canada >X@dirrmtry %%DATADIR%%/timezone/Chile >X@dirrmtry %%DATADIR%%/timezone/Etc >X@dirrmtry %%DATADIR%%/timezone/Europe >X@dirrmtry %%DATADIR%%/timezone/Indian >X@dirrmtry %%DATADIR%%/timezone/Mexico >X@dirrmtry %%DATADIR%%/timezone/Pacific >X@dirrmtry %%DATADIR%%/timezone/US >X@dirrmtry %%DATADIR%%/timezone >X@dirrmtry %%DATADIR%%/timezonesets >X@dirrmtry %%DATADIR%%/tsearch_data >X@dirrmtry %%DATADIR%% >737d46d867dcbf440542b48f0c66fe19 >echo c - postgresql92-1c/files >mkdir -p postgresql92-1c/files > /dev/null 2>&1 >echo x - postgresql92-1c/files/patch-src-backend-Makefile >sed 's/^X//' >postgresql92-1c/files/patch-src-backend-Makefile << '41a4906e94266b79c81a629404f2bc2f' >X--- src/backend/Makefile.orig 2015-06-09 19:33:16 UTC >X+++ src/backend/Makefile >X@@ -129,6 +129,8 @@ catalog/schemapg.h: | submake-schemapg >X >X $(top_builddir)/src/port/libpgport_srv.a: | submake-libpgport >X >X+symlinks: $(top_builddir)/src/include/parser/gram.h $(top_builddir)/src/include/utils/fmgroids.h $(top_builddir)/src/include/utils/probes.h >X+ >X >X # The postgres.o target is needed by the rule in Makefile.global that >X # creates the exports file when MAKE_EXPORTS = true. >41a4906e94266b79c81a629404f2bc2f >echo x - postgresql92-1c/files/502.pgsql.in >sed 's/^X//' >postgresql92-1c/files/502.pgsql.in << 'aa4e994983dcede424f3019d9b8c1a67' >X#!/bin/sh >X# >X# $FreeBSD: /tmp/pcvs/ports/databases/postgresql92-server/files/502.pgsql.in,v 1.4 2011-10-18 09:03:32 girgen Exp $ >X# >X# Maintenance shell script to vacuum and backup database >X# Put this in /usr/local/etc/periodic/daily, and it will be run >X# every night >X# >X# Written by Palle Girgensohn <girgen@pingpong.net> >X# >X# In public domain, do what you like with it, >X# and use it at your own risk... :) >X# >X >X# Define these variables in either /etc/periodic.conf or >X# /etc/periodic.conf.local to override the default values. >X# >X# daily_pgsql_backup_enable="YES" # do backup of all databases >X# daily_pgsql_backup_enable="foo bar db1 db2" # only do backup of a limited selection of databases >X# daily_pgsql_vacuum_enable="YES" # do vacuum >X >Xdaily_pgsql_user=%%PG_USER%% >Xdaily_pgsql_vacuum_args="-U ${daily_pgsql_user} -qaz" >Xdaily_pgsql_pgdump_args="-U ${daily_pgsql_user} -bF c" >Xdaily_pgsql_pgdumpall_globals_args="-U ${daily_pgsql_user}" >X# backupdir is relative to ~pgsql home directory unless it begins with a slash: >Xdaily_pgsql_backupdir="~${daily_pgsql_user}/backups" >Xdaily_pgsql_savedays="7" >X >X# If there is a global system configuration file, suck it in. >X# >Xif [ -r /etc/defaults/periodic.conf ] >Xthen >X . /etc/defaults/periodic.conf >X source_periodic_confs >Xfi >X >X# allow '~´ in dir name >Xeval backupdir=${daily_pgsql_backupdir} >X >Xrc=0 >X >Xpgsql_backup() { >X # daily_pgsql_backupdir must be writeable by user %%PG_USER%% >X # ~%%PG_USER%% is just that under normal circumstances, >X # but this might not be where you want the backups... >X if [ ! -d ${backupdir} ] ; then >X echo Creating ${backupdir} >X mkdir -m 700 ${backupdir}; chown ${daily_pgsql_user} ${backupdir} >X fi >X >X echo >X echo "PostgreSQL backups" >X >X # Protect the data >X umask 077 >X rc=$? >X now=`date "+%Y-%m-%dT%H:%M:%S"` >X file=${daily_pgsql_backupdir}/pgglobals_${now} >X su -l ${daily_pgsql_user} -c \ >X "umask 077; pg_dumpall -g ${daily_pgsql_pgdumpall_globals_args} | gzip -9 > ${file}.gz" >X >X db=$1 >X while shift; do >X echo -n " $db" >X file=${backupdir}/pgdump_${db}_${now} >X su -l ${daily_pgsql_user} -c "umask 077; pg_dump ${daily_pgsql_pgdump_args} -f ${file} ${db}" >X [ $? -gt 0 ] && rc=3 >X db=$1 >X done >X >X if [ $rc -gt 0 ]; then >X echo >X echo "Errors were reported during backup." >X fi >X >X # cleaning up old data >X find ${backupdir} \( -name 'pgdump_*' -o -name 'pgglobals_*' \) \ >X -a -mtime +${daily_pgsql_savedays} -delete >X echo >X} >X >Xcase "$daily_pgsql_backup_enable" in >X [Yy][Ee][Ss]) >X dbnames=`su -l %%PG_USER%% -c "umask 077; psql -q -t -A -d template1 -U %%PG_USER%% -c SELECT\ datname\ FROM\ pg_database\ WHERE\ datname!=\'template0\'"` >X pgsql_backup $dbnames >X ;; >X >X [Nn][Oo]) >X ;; >X >X "") >X ;; >X >X *) >X pgsql_backup $daily_pgsql_backup_enable >X ;; >Xesac >X >Xcase "$daily_pgsql_vacuum_enable" in >X [Yy][Ee][Ss]) >X >X echo >X echo "PostgreSQL vacuum" >X su -l ${daily_pgsql_user} -c "vacuumdb ${daily_pgsql_vacuum_args}" >X if [ $? -gt 0 ] >X then >X echo >X echo "Errors were reported during vacuum." >X rc=3 >X fi >X ;; >Xesac >X >Xexit $rc >aa4e994983dcede424f3019d9b8c1a67 >echo x - postgresql92-1c/files/patch-1c-postgresql >sed 's/^X//' >postgresql92-1c/files/patch-1c-postgresql << '74e3e9cb27fd66c7292ada7aec5a09c0' >X--- contrib/Makefile.orig 2014-07-21 22:12:31.000000000 +0300 >X+++ contrib/Makefile 2015-01-14 17:42:34.392163279 +0200 >X@@ -18,7 +18,9 @@ >X dict_xsyn \ >X dummy_seclabel \ >X earthdistance \ >X+ fasttrun \ >X file_fdw \ >X+ fulleq \ >X fuzzystrmatch \ >X hstore \ >X intagg \ >X@@ -26,7 +28,9 @@ >X isn \ >X lo \ >X ltree \ >X+ mchar \ >X oid2name \ >X+ online_analyze \ >X pageinspect \ >X passwordcheck \ >X pg_archivecleanup \ >X@@ -43,6 +47,7 @@ >X pgcrypto \ >X pgrowlocks \ >X pgstattuple \ >X+ plantuner \ >X seg \ >X spi \ >X tablefunc \ >X@@ -50,6 +55,7 @@ >X test_parser \ >X tsearch2 \ >X unaccent \ >X+ uuid-ossp \ >X vacuumlo >X >X ifeq ($(with_openssl),yes) >X--- ../postgresql-9.2.0.orig/src/backend/libpq/pg_hba.conf.sample Thu Aug 23 22:06:50 2012 UTC >X+++ ./src/backend/libpq/pg_hba.conf.sample Mon Sep 10 07:25:38 2012 UTC >X@@ -79,11 +79,12 @@ >X @remove-line-for-nolocal@# "local" is for Unix domain socket connections only >X @remove-line-for-nolocal@local all all @authmethodlocal@ >X # IPv4 local connections: >X-host all all 127.0.0.1/32 @authmethodhost@ >X+#host all all 127.0.0.1/32 @authmethodhost@ >X+host all all 0.0.0.0/0 @authmethodhost@ >X # IPv6 local connections: >X-host all all ::1/128 @authmethodhost@ >X+host all all ::1/128 @authmethodhost@ >X # Allow replication connections from localhost, by a user with the >X # replication privilege. >X @remove-line-for-nolocal@#local replication @default_username@ @authmethodlocal@ >X-#host replication @default_username@ 127.0.0.1/32 @authmethodhost@ >X-#host replication @default_username@ ::1/128 @authmethodhost@ >X+#host replication @default_username@ 127.0.0.1/32 @authmethodhost@ >X+#host replication @default_username@ ::1/128 @authmethodhost@ >X >X--- ../postgresql-9.2.0.orig/src/backend/utils/misc/postgresql.conf.sample Thu Sep 6 21:26:18 2012 UTC >X+++ ./src/backend/utils/misc/postgresql.conf.sample Tue Sep 11 13:37:37 2012 UTC >X@@ -56,7 +56,7 @@ >X >X # - Connection Settings - >X >X-#listen_addresses = 'localhost' # what IP address(es) to listen on; >X+listen_addresses = '*' # what IP address(es) to listen on; >X # comma-separated list of addresses; >X # defaults to 'localhost'; use '*' for all >X # (change requires restart) >X@@ -132,7 +132,7 @@ >X >X #max_files_per_process = 1000 # min 25 >X # (change requires restart) >X-#shared_preload_libraries = '' # (change requires restart) >X+#shared_preload_libraries = 'online_analyze, plantuner' # (change requires restart) >X >X # - Cost-Based Vacuum Delay - >X >X@@ -263,7 +263,7 @@ >X #cpu_tuple_cost = 0.01 # same scale as above >X #cpu_index_tuple_cost = 0.005 # same scale as above >X #cpu_operator_cost = 0.0025 # same scale as above >X-#effective_cache_size = 128MB >X+effective_cache_size = 512MB >X >X # - Genetic Query Optimizer - >X >X@@ -528,7 +528,7 @@ >X #------------------------------------------------------------------------------ >X >X #deadlock_timeout = 1s >X-#max_locks_per_transaction = 64 # min 10 >X+max_locks_per_transaction = 150 # min 10 >X # (change requires restart) >X # Note: Each lock table slot uses ~270 bytes of shared memory, and there are >X # max_locks_per_transaction * (max_connections + max_prepared_transactions) >X@@ -546,11 +546,11 @@ >X #array_nulls = on >X #backslash_quote = safe_encoding # on, off, or safe_encoding >X #default_with_oids = off >X-#escape_string_warning = on >X+escape_string_warning = off >X #lo_compat_privileges = off >X #quote_all_identifiers = off >X #sql_inheritance = on >X-#standard_conforming_strings = on >X+standard_conforming_strings = off >X #synchronize_seqscans = on >X >X # - Other Platforms and Clients - >X@@ -570,4 +570,10 @@ >X # CUSTOMIZED OPTIONS >X #------------------------------------------------------------------------------ >X >X-# Add settings for extensions here >X+online_analyze.threshold = 50 >X+online_analyze.scale_factor = 0.1 >X+online_analyze.enable = off >X+online_analyze.verbose = off >X+online_analyze.min_interval = 10000 >X+online_analyze.table_type = 'temporary' >X+plantuner.fix_empty_table = true >X >74e3e9cb27fd66c7292ada7aec5a09c0 >echo x - postgresql92-1c/files/patch-1c-applock >sed 's/^X//' >postgresql92-1c/files/patch-1c-applock << 'f4ad4064ccfb4221752be08955f88470' >X--- ../postgresql-9.2.0.orig/src/backend/parser/gram.y 2011-09-09 01:13:28.000000000 +0400 >X+++ ./src/backend/parser/gram.y 2011-09-14 21:38:48.694882400 +0400 >X@@ -488,7 +488,7 @@ >X >X /* ordinary key words in alphabetical order */ >X %token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER >X- AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC >X+ AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY APPLICATION ARRAY AS ASC >X ASSERTION ASSIGNMENT ASYMMETRIC AT ATTRIBUTE AUTHORIZATION >X >X BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT >X@@ -8139,6 +8139,8 @@ >X lock_type: ACCESS SHARE { $$ = AccessShareLock; } >X | ROW SHARE { $$ = RowShareLock; } >X | ROW EXCLUSIVE { $$ = RowExclusiveLock; } >X+ | APPLICATION SHARE { $$ = ApplicationShareLock; } >X+ | APPLICATION EXCLUSIVE { $$ = ApplicationExclusiveLock; } >X | SHARE UPDATE EXCLUSIVE { $$ = ShareUpdateExclusiveLock; } >X | SHARE { $$ = ShareLock; } >X | SHARE ROW EXCLUSIVE { $$ = ShareRowExclusiveLock; } >X@@ -11828,6 +11830,7 @@ >X | ALSO >X | ALTER >X | ALWAYS >X+ | APPLICATION >X | ASSERTION >X | ASSIGNMENT >X | AT >X--- --- ../postgresql-9.2.0.orig/src/backend/storage/lmgr/lock.c Thu Aug 23 22:06:50 2012 UTC >X+++ ./src/backend/storage/lmgr/lock.c Mon Sep 10 07:35:10 2012 UTC >X@@ -96,8 +96,14 @@ >X (1 << AccessShareLock) | (1 << RowShareLock) | >X (1 << RowExclusiveLock) | (1 << ShareUpdateExclusiveLock) | >X (1 << ShareLock) | (1 << ShareRowExclusiveLock) | >X- (1 << ExclusiveLock) | (1 << AccessExclusiveLock) >X+ (1 << ExclusiveLock) | (1 << AccessExclusiveLock), >X+ >X+ /* ApplicationShareLock*/ >X+ (1 << ApplicationExclusiveLock), >X+ >X >X+ /* ApplicationExclusiveLock*/ >X+ (1 << ApplicationExclusiveLock | 1 << ApplicationShareLock) >X }; >X >X /* Names of lock modes, for debug printouts */ >X@@ -111,7 +117,9 @@ >X "ShareLock", >X "ShareRowExclusiveLock", >X "ExclusiveLock", >X- "AccessExclusiveLock" >X+ "AccessExclusiveLock", >X+ "ApplicationShareLock", >X+ "ApplicationExclusiveLock" >X }; >X >X #ifndef LOCK_DEBUG >X@@ -119,7 +127,7 @@ >X #endif >X >X static const LockMethodData default_lockmethod = { >X- AccessExclusiveLock, /* highest valid lock mode number */ >X+ ApplicationExclusiveLock, /* highest valid lock mode number */ >X LockConflicts, >X lock_mode_names, >X #ifdef LOCK_DEBUG >X@@ -130,7 +138,7 @@ >X }; >X >X static const LockMethodData user_lockmethod = { >X- AccessExclusiveLock, /* highest valid lock mode number */ >X+ ApplicationExclusiveLock, /* highest valid lock mode number */ >X LockConflicts, >X lock_mode_names, >X #ifdef LOCK_DEBUG >X--- ../postgresql-9.2.0.orig/src/include/parser/kwlist.h 2011-09-09 01:13:28.000000000 +0400 >X+++ ./src/include/parser/kwlist.h 2011-09-14 19:40:30.858423500 +0400 >X@@ -42,6 +42,7 @@ >X PG_KEYWORD("analyze", ANALYZE, RESERVED_KEYWORD) >X PG_KEYWORD("and", AND, RESERVED_KEYWORD) >X PG_KEYWORD("any", ANY, RESERVED_KEYWORD) >X+PG_KEYWORD("application", APPLICATION, UNRESERVED_KEYWORD) >X PG_KEYWORD("array", ARRAY, RESERVED_KEYWORD) >X PG_KEYWORD("as", AS, RESERVED_KEYWORD) >X PG_KEYWORD("asc", ASC, RESERVED_KEYWORD) >X >X--- ../postgresql-9.2.0_orig/src/include/storage/lock.h 2011-09-09 01:13:28.000000000 +0400 >X+++ ./src/include/storage/lock.h 2011-09-14 19:40:30.905223600 +0400 >X@@ -87,7 +87,7 @@ >X typedef int LOCKMODE; >X >X /* MAX_LOCKMODES cannot be larger than the # of bits in LOCKMASK */ >X-#define MAX_LOCKMODES 10 >X+#define MAX_LOCKMODES 12 >X >X #define LOCKBIT_ON(lockmode) (1 << (lockmode)) >X #define LOCKBIT_OFF(lockmode) (~(1 << (lockmode))) >X@@ -156,6 +156,9 @@ >X #define AccessExclusiveLock 8 /* ALTER TABLE, DROP TABLE, VACUUM >X * FULL, and unqualified LOCK TABLE */ >X >X+#define ApplicationShareLock 9 /* requested explicitly */ >X+#define ApplicationExclusiveLock 10 /* requested explicitly */ >X+ >X >X /* >X * LOCKTAG is the key information needed to look up a LOCK item in the >f4ad4064ccfb4221752be08955f88470 >echo x - postgresql92-1c/files/postgresql.in >sed 's/^X//' >postgresql92-1c/files/postgresql.in << 'd8dc43c117fdd391ad9f62f5df776818' >X#!/bin/sh >X >X# $FreeBSD$ >X# >X# PROVIDE: postgresql >X# REQUIRE: LOGIN >X# KEYWORD: shutdown >X# >X# Add the following line to /etc/rc.conf to enable PostgreSQL: >X# >X# postgresql_enable="YES" >X# # optional >X# postgresql_data="%%PREFIX%%/%%PG_USER%%/data" >X# postgresql_flags="-w -s -m fast" >X# postgresql_initdb_flags="--encoding=utf-8 --lc-collate=C" >X# postgresql_class="default" >X# postgresql_profiles="" >X# >X# See %%PREFIX%%/share/doc/postgresql/README for more info >X# >X# This scripts takes one of the following commands: >X# >X# start stop restart reload status initdb >X# >X# For postmaster startup options, edit ${postgresql_data}/postgresql.conf >X >Xcommand=%%PREFIX%%/bin/pg_ctl >X >X. /etc/rc.subr >X >Xload_rc_config postgresql >X >X# set defaults >Xpostgresql_enable=${postgresql_enable:-"NO"} >Xpostgresql_flags=${postgresql_flags:-"-w -s -m fast"} >Xpostgresql_user=${postgresql_user:-"%%PG_USER%%"} >Xeval postgresql_data=${postgresql_data:-"~${postgresql_user}/data"} >Xpostgresql_class=${postgresql_class:-"default"} >X#postgresql_initdb_flags=${postgresql_initdb_flags:-"--encoding=utf-8 --lc-collate=C"} >Xpostgresql_initdb_flags=${postgresql_initdb_flags:-"--encoding=utf-8"} >X >Xname=postgresql >Xrcvar=postgresql_enable >Xextra_commands="reload initdb" >X >Xstart_cmd="postgresql_command start" >Xstop_cmd="postgresql_command stop" >Xrestart_cmd="postgresql_command restart" >Xreload_cmd="postgresql_command reload" >Xstatus_cmd="postgresql_command status" >X >Xinitdb_cmd="postgresql_initdb" >X >Xif [ "$1" = "initdb" ]; then >X if [ -n "$2" ]; then >X postgresql_initdb_flags=${postgresql_initdb_flags}" --locale=$2" >X fi >Xfi >X >Xif [ -n "$2" ]; then >X profile="$2" >X if [ "x${postgresql_profiles}" != "x" ]; then >X eval postgresql_data="\${postgresql_${profile}_data:-}" >X if [ "x${postgresql_data}" = "x" ]; then >X echo "You must define a data directory (postgresql_${profile}_data)" >X exit 1 >X fi >X eval postgresql_enable="\${postgresql_${profile}_enable:-${postgresql_enable}} >X eval postgresql_data="\${postgresql_${profile}_data:-${postgresql_data}} >X eval postgresql_flags="\${postgresql_${profile}_flags:-${postgresql_flags}}" >X eval postgresql_initdb_flags="\${postgresql_${profile}_initdb_flags:-${postgresql_initdb_flags}}" >X fi >Xelse >X if [ "x${postgresql_profiles}" != "x" -a "x$1" != "x" ]; then >X for profile in ${postgresql_profiles}; do >X eval _enable="\${postgresql_${profile}_enable}" >X case "x${_enable:-${postgresql_enable}}" in >X x|x[Nn][Oo]|x[Nn][Oo][Nn][Ee]) >X continue >X ;; >X x[Yy][Ee][Ss]) >X ;; >X *) >X if test -z "$_enable"; then >X _var=postgresql_enable >X else >X _var=postgresql_"${profile}"_enable >X fi >X echo "Bad value" \ >X "'${_enable:-${postgresql_enable}}'" \ >X "for ${_var}. " \ >X "Profile ${profile} skipped." >X continue >X ;; >X esac >X echo "===> postgresql profile: ${profile}" >X %%PREFIX%%/etc/rc.d/postgresql $1 ${profile} >X retcode="$?" >X if [ "0${retcode}" -ne 0 ]; then >X failed="${profile} (${retcode}) ${failed:-}" >X else >X success="${profile} ${success:-}" >X fi >X done >X exit 0 >X fi >Xfi >X >Xcommand_args="-D ${postgresql_data} ${postgresql_flags}" >X >Xpostgresql_command() >X{ >X su -l ${postgresql_user} -c "exec ${command} ${command_args} ${rc_arg}" >X} >X >Xpostgresql_initdb() >X{ >X if [ -n "$3" ]; then >X postgresql_initdb_flags=${postgresql_initdb_flags:-"--locale=$3"} >X else >X postgresql_initdb_flags=${postgresql_initdb_flags:-"--locale=C"} >X fi >X su -l -c ${postgresql_class} ${postgresql_user} -c "exec %%PREFIX%%/bin/initdb ${postgresql_initdb_flags} -D ${postgresql_data}" >X} >X >Xrun_rc_command "$1" >d8dc43c117fdd391ad9f62f5df776818 >echo x - postgresql92-1c/files/patch-1c-plantuner >sed 's/^X//' >postgresql92-1c/files/patch-1c-plantuner << '5a457c3e72dc2cff0da0c64be456d9d1' >Xdiff -urN ../postgresql-9.2.0.orig/contrib/plantuner\COPYRIGHT ./contrib/plantuner/COPYRIGHT >X--- ../postgresql-9.2.0.orig/contrib/plantuner/COPYRIGHT Thu Jan 01 04:00:00 1970 >X+++ ./contrib/plantuner/COPYRIGHT Mon Sep 17 20:00:32 2012 >X@@ -0,0 +1,29 @@ >X+/* >X+ * Copyright (c) 2009 Teodor Sigaev <teodor@sigaev.ru> >X+ * All rights reserved. >X+ * >X+ * Redistribution and use in source and binary forms, with or without >X+ * modification, are permitted provided that the following conditions >X+ * are met: >X+ * 1. Redistributions of source code must retain the above copyright >X+ * notice, this list of conditions and the following disclaimer. >X+ * 2. Redistributions in binary form must reproduce the above copyright >X+ * notice, this list of conditions and the following disclaimer in the >X+ * documentation and/or other materials provided with the distribution. >X+ * 3. Neither the name of the author nor the names of any co-contributors >X+ * may be used to endorse or promote products derived from this software >X+ * without specific prior written permission. >X+ * >X+ * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS >X+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED >X+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >X+ * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY >X+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >X+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE >X+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >X+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER >X+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR >X+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN >X+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >X+ */ >X+ >Xdiff -urN ../postgresql-9.2.0.orig/contrib/plantuner/expected/plantuner.out ./contrib/plantuner/expected/plantuner.out >X--- ../postgresql-9.2.0.orig/contrib/plantuner/expected/plantuner.out Thu Jan 01 04:00:00 1970 >X+++ ./contrib/plantuner/expected/plantuner.out Mon Sep 17 20:00:32 2012 >X@@ -0,0 +1,49 @@ >X+LOAD 'plantuner'; >X+SHOW plantuner.disable_index; >X+ plantuner.disable_index >X+------------------------- >X+ >X+(1 row) >X+ >X+CREATE TABLE wow (i int, j int); >X+CREATE INDEX i_idx ON wow (i); >X+CREATE INDEX j_idx ON wow (j); >X+SET enable_seqscan=off; >X+SELECT * FROM wow; >X+ i | j >X+---+--- >X+(0 rows) >X+ >X+SET plantuner.disable_index="i_idx, j_idx"; >X+SELECT * FROM wow; >X+ i | j >X+---+--- >X+(0 rows) >X+ >X+SHOW plantuner.disable_index; >X+ plantuner.disable_index >X+---------------------------- >X+ public.i_idx, public.j_idx >X+(1 row) >X+ >X+SET plantuner.disable_index="i_idx, nonexistent, public.j_idx, wow"; >X+WARNING: 'nonexistent' does not exist >X+WARNING: 'wow' is not an index >X+SHOW plantuner.disable_index; >X+ plantuner.disable_index >X+---------------------------- >X+ public.i_idx, public.j_idx >X+(1 row) >X+ >X+SET plantuner.enable_index="i_idx"; >X+SHOW plantuner.enable_index; >X+ plantuner.enable_index >X+------------------------ >X+ public.i_idx >X+(1 row) >X+ >X+SELECT * FROM wow; >X+ i | j >X+---+--- >X+(0 rows) >X+ >Xdiff -urN ../postgresql-9.2.0.orig/contrib/plantuner/Makefile ./contrib/plantuner/Makefile >X--- ../postgresql-9.2.0.orig/contrib/plantuner/Makefile Thu Jan 01 04:00:00 1970 >X+++ ./contrib/plantuner/Makefile Mon Sep 17 20:00:32 2012 >X@@ -0,0 +1,15 @@ >X+MODULE_big = plantuner >X+DOCS = README.plantuner >X+REGRESS = plantuner >X+OBJS=plantuner.o >X+ >X+ifdef USE_PGXS >X+PGXS = $(shell pg_config --pgxs) >X+include $(PGXS) >X+else >X+subdir = contrib/plantuner >X+top_builddir = ../.. >X+include $(top_builddir)/src/Makefile.global >X+ >X+include $(top_srcdir)/contrib/contrib-global.mk >X+endif >Xdiff -urN ../postgresql-9.2.0.orig/contrib/plantuner/plantuner.c ./contrib/plantuner/plantuner.c >X--- ../postgresql-9.2.0.orig/contrib/plantuner/plantuner.c Thu Jan 01 04:00:00 1970 >X+++ ./contrib/plantuner/plantuner.c Mon Sep 17 20:00:32 2012 >X@@ -0,0 +1,378 @@ >X+/* >X+ * Copyright (c) 2009 Teodor Sigaev <teodor@sigaev.ru> >X+ * All rights reserved. >X+ * >X+ * Redistribution and use in source and binary forms, with or without >X+ * modification, are permitted provided that the following conditions >X+ * are met: >X+ * 1. Redistributions of source code must retain the above copyright >X+ * notice, this list of conditions and the following disclaimer. >X+ * 2. Redistributions in binary form must reproduce the above copyright >X+ * notice, this list of conditions and the following disclaimer in the >X+ * documentation and/or other materials provided with the distribution. >X+ * 3. Neither the name of the author nor the names of any co-contributors >X+ * may be used to endorse or promote products derived from this software >X+ * without specific prior written permission. >X+ * >X+ * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS >X+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED >X+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >X+ * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY >X+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >X+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE >X+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >X+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER >X+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR >X+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN >X+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >X+ */ >X+ >X+#include <postgres.h> >X+ >X+#include <fmgr.h> >X+#include <access/heapam.h> >X+#include <catalog/namespace.h> >X+#include <catalog/pg_class.h> >X+#include <nodes/pg_list.h> >X+#include <optimizer/plancat.h> >X+#include <storage/bufmgr.h> >X+#include <utils/builtins.h> >X+#include <utils/guc.h> >X+#include <utils/lsyscache.h> >X+#include <utils/rel.h> >X+ >X+PG_MODULE_MAGIC; >X+ >X+static int nDisabledIndexes = 0; >X+static Oid *disabledIndexes = NULL; >X+static char *disableIndexesOutStr = ""; >X+ >X+static int nEnabledIndexes = 0; >X+static Oid *enabledIndexes = NULL; >X+static char *enableIndexesOutStr = ""; >X+ >X+get_relation_info_hook_type prevHook = NULL; >X+static bool fix_empty_table = false; >X+ >X+ >X+static const char * >X+indexesAssign(const char * newval, bool doit, GucSource source, bool isDisable) >X+{ >X+ char *rawname; >X+ List *namelist; >X+ ListCell *l; >X+ Oid *newOids = NULL; >X+ int nOids = 0, >X+ i = 0; >X+ >X+ rawname = pstrdup(newval); >X+ >X+ if (!SplitIdentifierString(rawname, ',', &namelist)) >X+ goto cleanup; >X+ >X+ if (doit) >X+ { >X+ nOids = list_length(namelist); >X+ newOids = malloc(sizeof(Oid) * (nOids+1)); >X+ if (!newOids) >X+ elog(ERROR,"could not allocate %d bytes", (int)(sizeof(Oid) * (nOids+1))); >X+ } >X+ >X+ foreach(l, namelist) >X+ { >X+ char *curname = (char *) lfirst(l); >X+#if PG_VERSION_NUM >= 90200 >X+ Oid indexOid = RangeVarGetRelid(makeRangeVarFromNameList(stringToQualifiedNameList(curname)), >X+ NoLock, true); >X+#else >X+ Oid indexOid = RangeVarGetRelid(makeRangeVarFromNameList(stringToQualifiedNameList(curname)), >X+ true); >X+#endif >X+ >X+ if (indexOid == InvalidOid) >X+ { >X+#if PG_VERSION_NUM >= 90100 >X+ if (doit == false) >X+#endif >X+ elog(WARNING,"'%s' does not exist", curname); >X+ continue; >X+ } >X+ else if ( get_rel_relkind(indexOid) != RELKIND_INDEX ) >X+ { >X+#if PG_VERSION_NUM >= 90100 >X+ if (doit == false) >X+#endif >X+ elog(WARNING,"'%s' is not an index", curname); >X+ continue; >X+ } >X+ else if (doit) >X+ { >X+ newOids[i++] = indexOid; >X+ } >X+ } >X+ >X+ if (doit) >X+ { >X+ if (isDisable) >X+ { >X+ nDisabledIndexes = nOids; >X+ disabledIndexes = newOids; >X+ } >X+ else >X+ { >X+ nEnabledIndexes = nOids; >X+ enabledIndexes = newOids; >X+ } >X+ } >X+ >X+ pfree(rawname); >X+ list_free(namelist); >X+ >X+ return newval; >X+ >X+cleanup: >X+ if (newOids) >X+ free(newOids); >X+ pfree(rawname); >X+ list_free(namelist); >X+ return NULL; >X+} >X+ >X+static const char * >X+assignDisabledIndexes(const char * newval, bool doit, GucSource source) >X+{ >X+ return indexesAssign(newval, doit, source, true); >X+} >X+ >X+static const char * >X+assignEnabledIndexes(const char * newval, bool doit, GucSource source) >X+{ >X+ return indexesAssign(newval, doit, source, false); >X+} >X+ >X+#if PG_VERSION_NUM >= 90100 >X+ >X+static bool >X+checkDisabledIndexes(char **newval, void **extra, GucSource source) >X+{ >X+ char *val; >X+ >X+ val = (char*)indexesAssign(*newval, false, source, true); >X+ >X+ if (val) >X+ { >X+ *newval = val; >X+ return true; >X+ } >X+ >X+ return false; >X+} >X+ >X+static bool >X+checkEnabledIndexes(char **newval, void **extra, GucSource source) >X+{ >X+ char *val; >X+ >X+ val = (char*)indexesAssign(*newval, false, source, false); >X+ >X+ if (val) >X+ { >X+ *newval = val; >X+ return true; >X+ } >X+ >X+ return false; >X+} >X+ >X+static void >X+assignDisabledIndexesNew(const char *newval, void *extra) >X+{ >X+ assignDisabledIndexes(newval, true, PGC_S_USER /* doesn't matter */); >X+} >X+ >X+static void >X+assignEnabledIndexesNew(const char *newval, void *extra) >X+{ >X+ assignEnabledIndexes(newval, true, PGC_S_USER /* doesn't matter */); >X+} >X+ >X+#endif >X+ >X+static void >X+indexFilter(PlannerInfo *root, Oid relationObjectId, bool inhparent, RelOptInfo *rel) { >X+ int i; >X+ >X+ for(i=0;i<nDisabledIndexes;i++) >X+ { >X+ ListCell *l; >X+ >X+ foreach(l, rel->indexlist) >X+ { >X+ IndexOptInfo *info = (IndexOptInfo*)lfirst(l); >X+ >X+ if (disabledIndexes[i] == info->indexoid) >X+ { >X+ int j; >X+ >X+ for(j=0; j<nEnabledIndexes; j++) >X+ if (enabledIndexes[j] == info->indexoid) >X+ break; >X+ >X+ if (j >= nEnabledIndexes) >X+ rel->indexlist = list_delete_ptr(rel->indexlist, info); >X+ >X+ break; >X+ } >X+ } >X+ } >X+} >X+ >X+static void >X+execPlantuner(PlannerInfo *root, Oid relationObjectId, bool inhparent, RelOptInfo *rel) { >X+ Relation relation; >X+ >X+ relation = heap_open(relationObjectId, NoLock); >X+ if (relation->rd_rel->relkind == RELKIND_RELATION) >X+ { >X+ if (fix_empty_table && RelationGetNumberOfBlocks(relation) == 0) >X+ { >X+ /* >X+ * estimate_rel_size() could be too pessimistic for particular >X+ * workload >X+ */ >X+ rel->pages = 0.0; >X+ rel->tuples = 0.0; >X+ } >X+ >X+ indexFilter(root, relationObjectId, inhparent, rel); >X+ } >X+ heap_close(relation, NoLock); >X+ >X+ /* >X+ * Call next hook if it exists >X+ */ >X+ if (prevHook) >X+ prevHook(root, relationObjectId, inhparent, rel); >X+} >X+ >X+static const char* >X+IndexFilterShow(Oid* indexes, int nIndexes) >X+{ >X+ char *val, *ptr; >X+ int i, >X+ len; >X+ >X+ len = 1 /* \0 */ + nIndexes * (2 * NAMEDATALEN + 2 /* ', ' */ + 1 /* . */); >X+ ptr = val = palloc(len); >X+ >X+ *ptr =(char)'\0'; >X+ for(i=0; i<nIndexes; i++) >X+ { >X+ char *relname = get_rel_name(indexes[i]); >X+ Oid nspOid = get_rel_namespace(indexes[i]); >X+ char *nspname = get_namespace_name(nspOid); >X+ >X+ if ( relname == NULL || nspOid == InvalidOid || nspname == NULL ) >X+ continue; >X+ >X+ ptr += snprintf(ptr, len - (ptr - val), "%s%s.%s", >X+ (i==0) ? "" : ", ", >X+ nspname, >X+ relname); >X+ } >X+ >X+ return val; >X+} >X+ >X+static const char* >X+disabledIndexFilterShow(void) >X+{ >X+ return IndexFilterShow(disabledIndexes, nDisabledIndexes); >X+} >X+ >X+static const char* >X+enabledIndexFilterShow(void) >X+{ >X+ return IndexFilterShow(enabledIndexes, nEnabledIndexes); >X+} >X+ >X+void _PG_init(void); >X+void >X+_PG_init(void) >X+{ >X+ DefineCustomStringVariable( >X+ "plantuner.forbid_index", >X+ "List of forbidden indexes (deprecated)", >X+ "Listed indexes will not be used in queries (deprecated, use plantuner.disable_index)", >X+ &disableIndexesOutStr, >X+ "", >X+ PGC_USERSET, >X+ 0, >X+#if PG_VERSION_NUM >= 90100 >X+ checkDisabledIndexes, >X+ assignDisabledIndexesNew, >X+#else >X+ assignDisabledIndexes, >X+#endif >X+ disabledIndexFilterShow >X+ ); >X+ >X+ DefineCustomStringVariable( >X+ "plantuner.disable_index", >X+ "List of disabled indexes", >X+ "Listed indexes will not be used in queries", >X+ &disableIndexesOutStr, >X+ "", >X+ PGC_USERSET, >X+ 0, >X+#if PG_VERSION_NUM >= 90100 >X+ checkDisabledIndexes, >X+ assignDisabledIndexesNew, >X+#else >X+ assignDisabledIndexes, >X+#endif >X+ disabledIndexFilterShow >X+ ); >X+ >X+ DefineCustomStringVariable( >X+ "plantuner.enable_index", >X+ "List of enabled indexes (overload plantuner.disable_index)", >X+ "Listed indexes which could be used in queries even they are listed in plantuner.disable_index", >X+ &enableIndexesOutStr, >X+ "", >X+ PGC_USERSET, >X+ 0, >X+#if PG_VERSION_NUM >= 90100 >X+ checkEnabledIndexes, >X+ assignEnabledIndexesNew, >X+#else >X+ assignEnabledIndexes, >X+#endif >X+ enabledIndexFilterShow >X+ ); >X+ >X+ DefineCustomBoolVariable( >X+ "plantuner.fix_empty_table", >X+ "Sets to zero estimations for empty tables", >X+ "Sets to zero estimations for empty or newly created tables", >X+ &fix_empty_table, >X+#if PG_VERSION_NUM >= 80400 >X+ fix_empty_table, >X+#endif >X+ PGC_USERSET, >X+#if PG_VERSION_NUM >= 80400 >X+ GUC_NOT_IN_SAMPLE, >X+#if PG_VERSION_NUM >= 90100 >X+ NULL, >X+#endif >X+#endif >X+ NULL, >X+ NULL >X+ ); >X+ >X+ if (get_relation_info_hook != execPlantuner ) >X+ { >X+ prevHook = get_relation_info_hook; >X+ get_relation_info_hook = execPlantuner; >X+ } >X+} >Xdiff -urN ../postgresql-9.2.0.orig/contrib/plantuner/README.plantuner ./contrib/plantuner/README.plantuner >X--- ../postgresql-9.2.0.orig/contrib/plantuner/README.plantuner Thu Jan 01 04:00:00 1970 >X+++ ./contrib/plantuner/README.plantuner Mon Sep 17 20:00:32 2012 >X@@ -0,0 +1,96 @@ >X+Plantuner - enable planner hints >X+ >X+ contrib/plantuner is a contribution module for PostgreSQL 8.4+, which >X+ enable planner hints. >X+ >X+ All work was done by Teodor Sigaev (teodor@sigaev.ru) and Oleg Bartunov >X+ (oleg@sai.msu.su). >X+ >X+ Sponsor: Nomao project (http://www.nomao.com) >X+ >X+Motivation >X+ >X+ Whether somebody think it's bad or not, but sometime it's very >X+ interesting to be able to control planner (provide hints, which tells >X+ optimizer to ignore its algorithm in part), which is currently >X+ impossible in POstgreSQL. Oracle, for example, has over 120 hints, SQL >X+ Server also provides hints. >X+ >X+ This first version of plantuner provides a possibility to hide >X+ specified indexes from PostgreSQL planner, so it will not use them. >X+ >X+ There are many situation, when developer want to temporarily disable >X+ specific index(es), without dropping them, or to instruct planner to >X+ use specific index. >X+ >X+ Next, for some workload PostgreSQL could be too pessimistic for >X+ newly created tables and assumes much more rows in table than >X+ it actually has. If plantuner.fix_empty_table GUC variable is set >X+ to true then module will set to zero number of pages/tuples of >X+ table which hasn't blocks in file. >X+ >X+Installation >X+ >X+ * Get latest source of plantuner from CVS Repository >X+ * gmake && gmake install && gmake installcheck >X+ >X+Syntax >X+ plantuner.forbid_index (deprecated) >X+ plantuner.disable_index >X+ List of indexes invisible to planner >X+ plantuner.enable_index >X+ List of indexes visible to planner even they are hided >X+ by plantuner.disable_index. >X+ >X+Usage >X+ >X+ To enable the module you can either load shared library 'plantuner' in >X+ psql session or specify 'shared_preload_libraries' option in >X+ postgresql.conf. >X+=# LOAD 'plantuner'; >X+=# create table test(id int); >X+=# create index id_idx on test(id); >X+=# create index id_idx2 on test(id); >X+=# \d test >X+ Table "public.test" >X+ Column | Type | Modifiers >X+--------+---------+----------- >X+ id | integer | >X+Indexes: >X+ "id_idx" btree (id) >X+ "id_idx2" btree (id) >X+=# explain select id from test where id=1; >X+ QUERY PLAN >X+----------------------------------------------------------------------- >X+ Bitmap Heap Scan on test (cost=4.34..15.03 rows=12 width=4) >X+ Recheck Cond: (id = 1) >X+ -> Bitmap Index Scan on id_idx2 (cost=0.00..4.34 rows=12 width=0) >X+ Index Cond: (id = 1) >X+(4 rows) >X+=# set enable_seqscan=off; >X+=# set plantuner.disable_index='id_idx2'; >X+=# explain select id from test where id=1; >X+ QUERY PLAN >X+---------------------------------------------------------------------- >X+ Bitmap Heap Scan on test (cost=4.34..15.03 rows=12 width=4) >X+ Recheck Cond: (id = 1) >X+ -> Bitmap Index Scan on id_idx (cost=0.00..4.34 rows=12 width=0) >X+ Index Cond: (id = 1) >X+(4 rows) >X+=# set plantuner.disable_index='id_idx2,id_idx'; >X+=# explain select id from test where id=1; >X+ QUERY PLAN >X+------------------------------------------------------------------------- >X+ Seq Scan on test (cost=10000000000.00..10000000040.00 rows=12 width=4) >X+ Filter: (id = 1) >X+(2 rows) >X+=# set plantuner.enable_index='id_idx'; >X+=# explain select id from test where id=1; >X+ QUERY PLAN >X+----------------------------------------------------------------------- >X+ Bitmap Heap Scan on test (cost=4.34..15.03 rows=12 width=4) >X+ Recheck Cond: (id = 1) >X+ -> Bitmap Index Scan on id_idx (cost=0.00..4.34 rows=12 width=0) >X+ Index Cond: (id = 1) >X+(4 rows) >X+ >Xdiff -urN ../postgresql-9.2.0.orig/contrib/plantuner/results/plantuner.out ./contrib/plantuner/results/plantuner.out >X--- ../postgresql-9.2.0.orig/contrib/plantuner/results/plantuner.out Thu Jan 01 04:00:00 1970 >X+++ ./contrib/plantuner/results/plantuner.out Tue Sep 18 11:59:30 2012 >X@@ -0,0 +1,49 @@ >X+LOAD 'plantuner'; >X+SHOW plantuner.disable_index; >X+ plantuner.disable_index >X+------------------------- >X+ >X+(1 row) >X+ >X+CREATE TABLE wow (i int, j int); >X+CREATE INDEX i_idx ON wow (i); >X+CREATE INDEX j_idx ON wow (j); >X+SET enable_seqscan=off; >X+SELECT * FROM wow; >X+ i | j >X+---+--- >X+(0 rows) >X+ >X+SET plantuner.disable_index="i_idx, j_idx"; >X+SELECT * FROM wow; >X+ i | j >X+---+--- >X+(0 rows) >X+ >X+SHOW plantuner.disable_index; >X+ plantuner.disable_index >X+---------------------------- >X+ public.i_idx, public.j_idx >X+(1 row) >X+ >X+SET plantuner.disable_index="i_idx, nonexistent, public.j_idx, wow"; >X+WARNING: 'nonexistent' does not exist >X+WARNING: 'wow' is not an index >X+SHOW plantuner.disable_index; >X+ plantuner.disable_index >X+---------------------------- >X+ public.i_idx, public.j_idx >X+(1 row) >X+ >X+SET plantuner.enable_index="i_idx"; >X+SHOW plantuner.enable_index; >X+ plantuner.enable_index >X+------------------------ >X+ public.i_idx >X+(1 row) >X+ >X+SELECT * FROM wow; >X+ i | j >X+---+--- >X+(0 rows) >X+ >Xdiff -urN ../postgresql-9.2.0.orig/contrib/plantuner/sql/plantuner.sql ./contrib/plantuner/sql/plantuner.sql >X--- ../postgresql-9.2.0.orig/contrib/plantuner/sql/plantuner.sql Thu Jan 01 04:00:00 1970 >X+++ ./contrib/plantuner/sql/plantuner.sql Mon Sep 17 20:00:32 2012 >X@@ -0,0 +1,27 @@ >X+LOAD 'plantuner'; >X+ >X+SHOW plantuner.disable_index; >X+ >X+CREATE TABLE wow (i int, j int); >X+CREATE INDEX i_idx ON wow (i); >X+CREATE INDEX j_idx ON wow (j); >X+ >X+SET enable_seqscan=off; >X+ >X+SELECT * FROM wow; >X+ >X+SET plantuner.disable_index="i_idx, j_idx"; >X+ >X+SELECT * FROM wow; >X+ >X+SHOW plantuner.disable_index; >X+ >X+SET plantuner.disable_index="i_idx, nonexistent, public.j_idx, wow"; >X+ >X+SHOW plantuner.disable_index; >X+ >X+SET plantuner.enable_index="i_idx"; >X+ >X+SHOW plantuner.enable_index; >X+ >X+SELECT * FROM wow; >5a457c3e72dc2cff0da0c64be456d9d1 >echo x - postgresql92-1c/files/pkg-message.in >sed 's/^X//' >postgresql92-1c/files/pkg-message.in << '304cb34a6dc37773cd01c6c36f5303b7' >XFor procedural languages and postgresql functions, please note that >Xyou might have to update them when updating the server. >X >XIf you have many tables and many clients running, consider raising >Xkern.maxfiles using sysctl(8), or reconfigure your kernel >Xappropriately. >X >XThe port is set up to use autovacuum for new databases, but you might >Xalso want to vacuum and perhaps backup your database regularly. There >Xis a periodic script, %%PREFIX%%/etc/periodic/daily/502.pgsql, that >Xyou may find useful. You can use it to backup and perfom vacuum on all >Xdatabases nightly. Per default, it perfoms `vacuum analyze'. See the >Xscript for instructions. For autovacuum settings, please review >X~pgsql/data/postgresql.conf. >X >XTo allow many simultaneous connections to your PostgreSQL server, you >Xshould raise the SystemV shared memory limits in your kernel. Here are >Xexample values for allowing up to 180 clients (configurations in >Xpostgresql.conf also needed, of course): >X options SYSVSHM >X options SYSVSEM >X options SYSVMSG >X options SHMMAXPGS=65536 >X options SEMMNI=40 >X options SEMMNS=240 >X options SEMUME=40 >X options SEMMNU=120 >X >XIf you plan to access your PostgreSQL server using ODBC, please >Xconsider running the SQL script %%PREFIX%%/share/postgresql/odbc.sql >Xto get the functions required for ODBC compliance. >X >XPlease note that if you use the rc script, >X%%PREFIX%%/etc/rc.d/postgresql, to initialize the database, unicode >X(UTF-8) will be used to store character data by default. Set >Xpostgresql_initdb_flags or use login.conf settings described below to >Xalter this behaviour. See the start rc script for more info. >X >XTo set limits, environment stuff like locale and collation and other >Xthings, you can set up a class in /etc/login.conf before initializing >Xthe database. Add something similar to this to /etc/login.conf: >X--- >Xpostgres:\ >X :lang=en_US.UTF-8:\ >X :setenv=LC_COLLATE=C:\ >X :tc=default: >X--- >Xand run `cap_mkdb /etc/login.conf'. >XThen add 'postgresql_class="postgres"' to /etc/rc.conf. >X >XYou can also specify the locale by using the script RC (eg uk_ua.UTF-8) >X >X====================================================================== >X >XTo initialize the database, run >X >X %%PREFIX%%/etc/rc.d/postgresql initdb [locale] >X >XYou can then start PostgreSQL by running: >X >X %%PREFIX%%/etc/rc.d/postgresql start >X >XFor postmaster settings, see ~pgsql/data/postgresql.conf >X >XNB. FreeBSD's PostgreSQL port logs to syslog by default >X See ~pgsql/data/postgresql.conf for more info >X >X====================================================================== >X >XTo run PostgreSQL at startup, add >X'postgresql_enable="YES"' to /etc/rc.conf >X >304cb34a6dc37773cd01c6c36f5303b7 >echo x - postgresql92-1c/files/patch-1c-online_analyze >sed 's/^X//' >postgresql92-1c/files/patch-1c-online_analyze << '47e4f19f57876df3300d9003e88244b4' >Xdiff -urN ../postgresql-9.2.0.orig/contrib/online_analyze/COPYRIGHT ./contrib/online_analyze/COPYRIGHT >X--- ../postgresql-9.2.0.orig/contrib/online_analyze/COPYRIGHT Thu Jan 01 04:00:00 1970 >X+++ ./contrib/online_analyze/COPYRIGHT Tue Sep 25 17:13:16 2012 >X@@ -0,0 +1,29 @@ >X+/* >X+ * Copyright (c) 2011 Teodor Sigaev <teodor@sigaev.ru> >X+ * All rights reserved. >X+ * >X+ * Redistribution and use in source and binary forms, with or without >X+ * modification, are permitted provided that the following conditions >X+ * are met: >X+ * 1. Redistributions of source code must retain the above copyright >X+ * notice, this list of conditions and the following disclaimer. >X+ * 2. Redistributions in binary form must reproduce the above copyright >X+ * notice, this list of conditions and the following disclaimer in the >X+ * documentation and/or other materials provided with the distribution. >X+ * 3. Neither the name of the author nor the names of any co-contributors >X+ * may be used to endorse or promote products derived from this software >X+ * without specific prior written permission. >X+ * >X+ * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS >X+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED >X+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >X+ * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY >X+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >X+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE >X+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >X+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER >X+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR >X+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN >X+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >X+ */ >X+ >Xdiff -urN ../postgresql-9.2.0.orig/contrib/online_analyze/Makefile ./contrib/online_analyze/Makefile >X--- ../postgresql-9.2.0.orig/contrib/online_analyze/Makefile Thu Jan 01 04:00:00 1970 >X+++ ./contrib/online_analyze/Makefile Tue Sep 25 17:13:16 2012 >X@@ -0,0 +1,16 @@ >X+MODULE_big = online_analyze >X+OBJS = online_analyze.o >X+#DATA_built = online_analyze.sql >X+DOCS = README.online_analyze >X+#REGRESS = online_analyze >X+ >X+ifdef USE_PGXS >X+PGXS := $(shell pg_config --pgxs) >X+include $(PGXS) >X+else >X+subdir = contrib/online_analyze >X+top_builddir = ../.. >X+include $(top_builddir)/src/Makefile.global >X+include $(top_srcdir)/contrib/contrib-global.mk >X+endif >X+ >Xdiff -urN ../postgresql-9.2.0.orig/contrib/online_analyze/online_analyze.c ./contrib/online_analyze/online_analyze.c >X--- ../postgresql-9.2.0.orig/contrib/online_analyze/online_analyze.c Thu Jan 01 04:00:00 1970 >X+++ ./contrib/online_analyze/online_analyze.c Tue Sep 25 17:13:16 2012 >X@@ -0,0 +1,723 @@ >X+/* >X+ * Copyright (c) 2011 Teodor Sigaev <teodor@sigaev.ru> >X+ * All rights reserved. >X+ * >X+ * Redistribution and use in source and binary forms, with or without >X+ * modification, are permitted provided that the following conditions >X+ * are met: >X+ * 1. Redistributions of source code must retain the above copyright >X+ * notice, this list of conditions and the following disclaimer. >X+ * 2. Redistributions in binary form must reproduce the above copyright >X+ * notice, this list of conditions and the following disclaimer in the >X+ * documentation and/or other materials provided with the distribution. >X+ * 3. Neither the name of the author nor the names of any co-contributors >X+ * may be used to endorse or promote products derived from this software >X+ * without specific prior written permission. >X+ * >X+ * THIS SOFTWARE IS PROVIDED BY CONTRIBUTORS ``AS IS'' AND ANY EXPRESS >X+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED >X+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >X+ * ARE DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY >X+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >X+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE >X+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >X+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER >X+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR >X+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN >X+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >X+ */ >X+ >X+#include "postgres.h" >X+ >X+#include "pgstat.h" >X+#include "catalog/namespace.h" >X+#include "commands/vacuum.h" >X+#include "executor/executor.h" >X+#include "nodes/nodes.h" >X+#include "nodes/parsenodes.h" >X+#include "storage/bufmgr.h" >X+#include "utils/builtins.h" >X+#include "utils/lsyscache.h" >X+#include "utils/guc.h" >X+#if PG_VERSION_NUM >= 90200 >X+#include "catalog/pg_class.h" >X+#include "nodes/primnodes.h" >X+#include "tcop/utility.h" >X+#include "utils/rel.h" >X+#include "utils/relcache.h" >X+#include "utils/timestamp.h" >X+#endif >X+ >X+#ifdef PG_MODULE_MAGIC >X+PG_MODULE_MAGIC; >X+#endif >X+ >X+static bool online_analyze_enable = true; >X+static bool online_analyze_verbose = true; >X+static double online_analyze_scale_factor = 0.1; >X+static int online_analyze_threshold = 50; >X+static double online_analyze_min_interval = 10000; >X+ >X+static ExecutorEnd_hook_type oldExecutorEndHook = NULL; >X+#if PG_VERSION_NUM >= 90200 >X+static ProcessUtility_hook_type oldProcessUtilityHook = NULL; >X+#endif >X+ >X+typedef enum >X+{ >X+ OATT_ALL = 0x03, >X+ OATT_PERSISTENT = 0x01, >X+ OATT_TEMPORARY = 0x02, >X+ OATT_NONE = 0x00 >X+} OnlineAnalyzeTableType; >X+ >X+static const struct config_enum_entry online_analyze_table_type_options[] = >X+{ >X+ {"all", OATT_ALL, false}, >X+ {"persistent", OATT_PERSISTENT, false}, >X+ {"temporary", OATT_TEMPORARY, false}, >X+ {"none", OATT_NONE, false}, >X+ {NULL, 0, false}, >X+}; >X+ >X+static int online_analyze_table_type = (int)OATT_ALL; >X+ >X+typedef struct TableList { >X+ int nTables; >X+ Oid *tables; >X+ char *tableStr; >X+} TableList; >X+ >X+static TableList excludeTables = {0, NULL, NULL}; >X+static TableList includeTables = {0, NULL, NULL}; >X+ >X+static int >X+oid_cmp(const void *a, const void *b) >X+{ >X+ if (*(Oid*)a == *(Oid*)b) >X+ return 0; >X+ return (*(Oid*)a > *(Oid*)b) ? 1 : -1; >X+} >X+ >X+static const char * >X+tableListAssign(const char * newval, bool doit, TableList *tbl) >X+{ >X+ char *rawname; >X+ List *namelist; >X+ ListCell *l; >X+ Oid *newOids = NULL; >X+ int nOids = 0, >X+ i = 0; >X+ >X+ rawname = pstrdup(newval); >X+ >X+ if (!SplitIdentifierString(rawname, ',', &namelist)) >X+ goto cleanup; >X+ >X+ if (doit) >X+ { >X+ nOids = list_length(namelist); >X+ newOids = malloc(sizeof(Oid) * (nOids+1)); >X+ if (!newOids) >X+ elog(ERROR,"could not allocate %d bytes", (int)(sizeof(Oid) * (nOids+1))); >X+ } >X+ >X+ foreach(l, namelist) >X+ { >X+ char *curname = (char *) lfirst(l); >X+#if PG_VERSION_NUM >= 90200 >X+ Oid relOid = RangeVarGetRelid(makeRangeVarFromNameList(stringToQualifiedNameList(curname)), >X+ NoLock, true); >X+#else >X+ Oid relOid = RangeVarGetRelid(makeRangeVarFromNameList(stringToQualifiedNameList(curname)), >X+ true); >X+#endif >X+ >X+ if (relOid == InvalidOid) >X+ { >X+#if PG_VERSION_NUM >= 90100 >X+ if (doit == false) >X+#endif >X+ elog(WARNING,"'%s' does not exist", curname); >X+ continue; >X+ } >X+ else if ( get_rel_relkind(relOid) != RELKIND_RELATION ) >X+ { >X+#if PG_VERSION_NUM >= 90100 >X+ if (doit == false) >X+#endif >X+ elog(WARNING,"'%s' is not an table", curname); >X+ continue; >X+ } >X+ else if (doit) >X+ { >X+ newOids[i++] = relOid; >X+ } >X+ } >X+ >X+ if (doit) >X+ { >X+ tbl->nTables = i; >X+ if (tbl->tables) >X+ free(tbl->tables); >X+ tbl->tables = newOids; >X+ if (tbl->nTables > 1) >X+ qsort(tbl->tables, tbl->nTables, sizeof(tbl->tables[0]), oid_cmp); >X+ } >X+ >X+ pfree(rawname); >X+ list_free(namelist); >X+ >X+ return newval; >X+ >X+cleanup: >X+ if (newOids) >X+ free(newOids); >X+ pfree(rawname); >X+ list_free(namelist); >X+ return NULL; >X+} >X+ >X+#if PG_VERSION_NUM >= 90100 >X+static bool >X+excludeTablesCheck(char **newval, void **extra, GucSource source) >X+{ >X+ char *val; >X+ >X+ val = (char*)tableListAssign(*newval, false, &excludeTables); >X+ >X+ if (val) >X+ { >X+ *newval = val; >X+ return true; >X+ } >X+ >X+ return false; >X+} >X+ >X+static void >X+excludeTablesAssign(const char *newval, void *extra) >X+{ >X+ tableListAssign(newval, true, &excludeTables); >X+} >X+ >X+static bool >X+includeTablesCheck(char **newval, void **extra, GucSource source) >X+{ >X+ char *val; >X+ >X+ val = (char*)tableListAssign(*newval, false, &includeTables); >X+ >X+ if (val) >X+ { >X+ *newval = val; >X+ return true; >X+ } >X+ >X+ return false; >X+} >X+ >X+static void >X+includeTablesAssign(const char *newval, void *extra) >X+{ >X+ tableListAssign(newval, true, &excludeTables); >X+} >X+ >X+#else /* PG_VERSION_NUM < 90100 */ >X+ >X+static const char * >X+excludeTablesAssign(const char * newval, bool doit, GucSource source) >X+{ >X+ return tableListAssign(newval, doit, &excludeTables); >X+} >X+ >X+static const char * >X+includeTablesAssign(const char * newval, bool doit, GucSource source) >X+{ >X+ return tableListAssign(newval, doit, &includeTables); >X+} >X+ >X+#endif >X+ >X+static const char* >X+tableListShow(TableList *tbl) >X+{ >X+ char *val, *ptr; >X+ int i, >X+ len; >X+ >X+ len = 1 /* \0 */ + tbl->nTables * (2 * NAMEDATALEN + 2 /* ', ' */ + 1 /* . */); >X+ ptr = val = palloc(len); >X+ *ptr ='\0'; >X+ for(i=0; i<tbl->nTables; i++) >X+ { >X+ char *relname = get_rel_name(tbl->tables[i]); >X+ Oid nspOid = get_rel_namespace(tbl->tables[i]); >X+ char *nspname = get_namespace_name(nspOid); >X+ >X+ if ( relname == NULL || nspOid == InvalidOid || nspname == NULL ) >X+ continue; >X+ >X+ ptr += snprintf(ptr, len - (ptr - val), "%s%s.%s", >X+ (i==0) ? "" : ", ", >X+ nspname, relname); >X+ } >X+ >X+ return val; >X+} >X+ >X+static const char* >X+excludeTablesShow(void) >X+{ >X+ return tableListShow(&excludeTables); >X+} >X+ >X+static const char* >X+includeTablesShow(void) >X+{ >X+ return tableListShow(&includeTables); >X+} >X+ >X+static bool >X+matchOid(TableList *tbl, Oid oid) >X+{ >X+ Oid *StopLow = tbl->tables, >X+ *StopHigh = tbl->tables + tbl->nTables, >X+ *StopMiddle; >X+ >X+ /* Loop invariant: StopLow <= val < StopHigh */ >X+ while (StopLow < StopHigh) >X+ { >X+ StopMiddle = StopLow + ((StopHigh - StopLow) >> 1); >X+ >X+ if (*StopMiddle == oid) >X+ return true; >X+ else if (*StopMiddle < oid) >X+ StopLow = StopMiddle + 1; >X+ else >X+ StopHigh = StopMiddle; >X+ } >X+ >X+ return false; >X+} >X+ >X+static void >X+makeAnalyze(Oid relOid, CmdType operation, uint32 naffected) >X+{ >X+ PgStat_StatTabEntry *tabentry; >X+ TimestampTz now = GetCurrentTimestamp(); >X+ >X+ if (relOid == InvalidOid) >X+ return; >X+ >X+ if (get_rel_relkind(relOid) != RELKIND_RELATION) >X+ return; >X+ >X+ tabentry = pgstat_fetch_stat_tabentry(relOid); >X+ >X+#if PG_VERSION_NUM >= 90000 >X+#define changes_since_analyze(t) ((t)->changes_since_analyze) >X+#else >X+#define changes_since_analyze(t) ((t)->n_live_tuples + (t)->n_dead_tuples - (t)->last_anl_tuples) >X+#endif >X+ >X+ if ( >X+ tabentry == NULL /* a new table */ || >X+ ( >X+ /* do not analyze too often, if both stamps are exceeded the go */ >X+ TimestampDifferenceExceeds(tabentry->analyze_timestamp, now, online_analyze_min_interval) && >X+ TimestampDifferenceExceeds(tabentry->autovac_analyze_timestamp, now, online_analyze_min_interval) && >X+ /* be in sync with relation_needs_vacanalyze */ >X+ ((double)(changes_since_analyze(tabentry) + naffected)) >= >X+ online_analyze_scale_factor * ((double)(tabentry->n_dead_tuples + tabentry->n_live_tuples)) + >X+ (double)online_analyze_threshold >X+ ) >X+ ) >X+ { >X+ VacuumStmt vacstmt; >X+ TimestampTz startStamp, endStamp; >X+ >X+ memset(&startStamp, 0, sizeof(startStamp)); /* keep compiler quiet */ >X+ >X+ /* >X+ * includeTables overwrites excludeTables >X+ */ >X+ switch(online_analyze_table_type) >X+ { >X+ case OATT_ALL: >X+ if (matchOid(&excludeTables, relOid) == true && matchOid(&includeTables, relOid) == false) >X+ return; >X+ break; >X+ case OATT_NONE: >X+ if (matchOid(&includeTables, relOid) == false) >X+ return; >X+ break; >X+ case OATT_TEMPORARY: >X+ case OATT_PERSISTENT: >X+ default: >X+ { >X+ Relation rel; >X+ OnlineAnalyzeTableType reltype; >X+ >X+ rel = RelationIdGetRelation(relOid); >X+ reltype = >X+#if PG_VERSION_NUM >= 90100 >X+ (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP) >X+#else >X+ (rel->rd_istemp || rel->rd_islocaltemp) >X+#endif >X+ ? OATT_TEMPORARY : OATT_PERSISTENT; >X+ RelationClose(rel); >X+ >X+ /* >X+ * skip analyze if relation's type doesn't not match online_analyze_table_type >X+ */ >X+ if ((online_analyze_table_type & reltype) == 0 || matchOid(&excludeTables, relOid) == true) >X+ { >X+ if (matchOid(&includeTables, relOid) == false) >X+ return; >X+ } >X+ } >X+ break; >X+ } >X+ >X+ vacstmt.type = T_VacuumStmt; >X+ vacstmt.freeze_min_age = -1; >X+ vacstmt.freeze_table_age = -1; /* ??? */ >X+ vacstmt.relation = NULL; >X+ vacstmt.va_cols = NIL; >X+ >X+#if PG_VERSION_NUM >= 90000 >X+ vacstmt.options = VACOPT_ANALYZE; >X+ if (online_analyze_verbose) >X+ vacstmt.options |= VACOPT_VERBOSE; >X+#else >X+ vacstmt.vacuum = vacstmt.full = false; >X+ vacstmt.analyze = true; >X+ vacstmt.verbose = online_analyze_verbose; >X+#endif >X+ >X+ if (online_analyze_verbose) >X+ startStamp = GetCurrentTimestamp(); >X+ >X+ analyze_rel(relOid, &vacstmt >X+#if PG_VERSION_NUM >= 90018 >X+ , true >X+#endif >X+ , GetAccessStrategy(BAS_VACUUM) >X+#if (PG_VERSION_NUM >= 90000) && (PG_VERSION_NUM < 90004) >X+ , true >X+#endif >X+ ); >X+ >X+ if (online_analyze_verbose) >X+ { >X+ long secs; >X+ int microsecs; >X+ >X+ endStamp = GetCurrentTimestamp(); >X+ TimestampDifference(startStamp, endStamp, &secs, µsecs); >X+ elog(INFO, "analyze \"%s\" took %.02f seconds", >X+ get_rel_name(relOid), ((double)secs) + ((double)microsecs)/1.0e6); >X+ } >X+ >X+ >X+ if (tabentry == NULL) >X+ { >X+ /* new table */ >X+ pgstat_clear_snapshot(); >X+ } >X+ else >X+ { >X+ /* update last analyze timestamp in local memory of backend */ >X+ tabentry->analyze_timestamp = now; >X+ } >X+ } >X+#if PG_VERSION_NUM >= 90000 >X+ else if (tabentry != NULL) >X+ { >X+ tabentry->changes_since_analyze += naffected; >X+ } >X+#endif >X+} >X+ >X+extern PGDLLIMPORT void onlineAnalyzeHooker(QueryDesc *queryDesc); >X+void >X+onlineAnalyzeHooker(QueryDesc *queryDesc) >X+{ >X+ uint32 naffected = 0; >X+ >X+ if (queryDesc->estate) >X+ naffected = queryDesc->estate->es_processed; >X+ >X+ if (online_analyze_enable && queryDesc->plannedstmt && >X+ (queryDesc->operation == CMD_INSERT || >X+ queryDesc->operation == CMD_UPDATE || >X+ queryDesc->operation == CMD_DELETE >X+#if PG_VERSION_NUM < 90200 >X+ || (queryDesc->operation == CMD_SELECT && queryDesc->plannedstmt->intoClause) >X+#endif >X+ )) >X+ { >X+#if PG_VERSION_NUM < 90200 >X+ if (queryDesc->operation == CMD_SELECT) >X+ { >X+ Oid relOid = RangeVarGetRelid(queryDesc->plannedstmt->intoClause->rel, true); >X+ >X+ makeAnalyze(relOid, queryDesc->operation, naffected); >X+ } >X+ else >X+#endif >X+ if (queryDesc->plannedstmt->resultRelations && >X+ queryDesc->plannedstmt->rtable) >X+ { >X+ ListCell *l; >X+ >X+ foreach(l, queryDesc->plannedstmt->resultRelations) >X+ { >X+ int n = lfirst_int(l); >X+ RangeTblEntry *rte = list_nth(queryDesc->plannedstmt->rtable, n-1); >X+ >X+ if (rte->rtekind == RTE_RELATION) >X+ makeAnalyze(rte->relid, queryDesc->operation, naffected); >X+ } >X+ } >X+ } >X+ >X+ if (oldExecutorEndHook) >X+ oldExecutorEndHook(queryDesc); >X+ else >X+ standard_ExecutorEnd(queryDesc); >X+} >X+ >X+#if PG_VERSION_NUM >= 90200 >X+static void >X+onlineAnalyzeHookerUtility(Node *parsetree, const char *queryString, >X+#if PG_VERSION_NUM >= 90300 >X+ ProcessUtilityContext context, ParamListInfo params, >X+#else >X+ ParamListInfo params, bool isTopLevel, >X+#endif >X+ DestReceiver *dest, char *completionTag) { >X+ RangeVar *tblname = NULL; >X+ >X+ if (IsA(parsetree, CreateTableAsStmt) && ((CreateTableAsStmt*)parsetree)->into) >X+ tblname = (RangeVar*)copyObject(((CreateTableAsStmt*)parsetree)->into->rel); >X+ >X+ if (oldProcessUtilityHook) >X+ oldProcessUtilityHook(parsetree, queryString, >X+#if PG_VERSION_NUM >= 90300 >X+ context, params, >X+#else >X+ params, isTopLevel, >X+#endif >X+ dest, completionTag); >X+ else >X+ standard_ProcessUtility(parsetree, queryString, >X+#if PG_VERSION_NUM >= 90300 >X+ context, params, >X+#else >X+ params, isTopLevel, >X+#endif >X+ dest, completionTag); >X+ >X+ if (tblname) { >X+ Oid tblOid = RangeVarGetRelid(tblname, NoLock, true); >X+ >X+ makeAnalyze(tblOid, CMD_INSERT, 0); >X+ } >X+} >X+#endif >X+ >X+void _PG_init(void); >X+void >X+_PG_init(void) >X+{ >X+ oldExecutorEndHook = ExecutorEnd_hook; >X+ >X+ ExecutorEnd_hook = onlineAnalyzeHooker; >X+ >X+#if PG_VERSION_NUM >= 90200 >X+ oldProcessUtilityHook = ProcessUtility_hook; >X+ >X+ ProcessUtility_hook = onlineAnalyzeHookerUtility; >X+#endif >X+ >X+ >X+ DefineCustomBoolVariable( >X+ "online_analyze.enable", >X+ "Enable on-line analyze", >X+ "Enables analyze of table directly after insert/update/delete/select into", >X+ &online_analyze_enable, >X+#if PG_VERSION_NUM >= 80400 >X+ online_analyze_enable, >X+#endif >X+ PGC_USERSET, >X+#if PG_VERSION_NUM >= 80400 >X+ GUC_NOT_IN_SAMPLE, >X+#if PG_VERSION_NUM >= 90100 >X+ NULL, >X+#endif >X+#endif >X+ NULL, >X+ NULL >X+ ); >X+ >X+ DefineCustomBoolVariable( >X+ "online_analyze.verbose", >X+ "Verbosity of on-line analyze", >X+ "Make ANALYZE VERBOSE after table's changes", >X+ &online_analyze_verbose, >X+#if PG_VERSION_NUM >= 80400 >X+ online_analyze_verbose, >X+#endif >X+ PGC_USERSET, >X+#if PG_VERSION_NUM >= 80400 >X+ GUC_NOT_IN_SAMPLE, >X+#if PG_VERSION_NUM >= 90100 >X+ NULL, >X+#endif >X+#endif >X+ NULL, >X+ NULL >X+ ); >X+ >X+ DefineCustomRealVariable( >X+ "online_analyze.scale_factor", >X+ "fraction of table size to start on-line analyze", >X+ "fraction of table size to start on-line analyze", >X+ &online_analyze_scale_factor, >X+#if PG_VERSION_NUM >= 80400 >X+ online_analyze_scale_factor, >X+#endif >X+ 0.0, >X+ 1.0, >X+ PGC_USERSET, >X+#if PG_VERSION_NUM >= 80400 >X+ GUC_NOT_IN_SAMPLE, >X+#if PG_VERSION_NUM >= 90100 >X+ NULL, >X+#endif >X+#endif >X+ NULL, >X+ NULL >X+ ); >X+ >X+ DefineCustomIntVariable( >X+ "online_analyze.threshold", >X+ "min number of row updates before on-line analyze", >X+ "min number of row updates before on-line analyze", >X+ &online_analyze_threshold, >X+#if PG_VERSION_NUM >= 80400 >X+ online_analyze_threshold, >X+#endif >X+ 0, >X+ 0x7fffffff, >X+ PGC_USERSET, >X+#if PG_VERSION_NUM >= 80400 >X+ GUC_NOT_IN_SAMPLE, >X+#if PG_VERSION_NUM >= 90100 >X+ NULL, >X+#endif >X+#endif >X+ NULL, >X+ NULL >X+ ); >X+ >X+ DefineCustomRealVariable( >X+ "online_analyze.min_interval", >X+ "minimum time interval between analyze call (in milliseconds)", >X+ "minimum time interval between analyze call (in milliseconds)", >X+ &online_analyze_min_interval, >X+#if PG_VERSION_NUM >= 80400 >X+ online_analyze_min_interval, >X+#endif >X+ 0.0, >X+ 1e30, >X+ PGC_USERSET, >X+#if PG_VERSION_NUM >= 80400 >X+ GUC_NOT_IN_SAMPLE, >X+#if PG_VERSION_NUM >= 90100 >X+ NULL, >X+#endif >X+#endif >X+ NULL, >X+ NULL >X+ ); >X+ >X+ DefineCustomEnumVariable( >X+ "online_analyze.table_type", >X+ "Type(s) of table for online analyze: all(default), persistent, temporary, none", >X+ NULL, >X+ &online_analyze_table_type, >X+#if PG_VERSION_NUM >= 80400 >X+ online_analyze_table_type, >X+#endif >X+ online_analyze_table_type_options, >X+ PGC_USERSET, >X+#if PG_VERSION_NUM >= 80400 >X+ GUC_NOT_IN_SAMPLE, >X+#if PG_VERSION_NUM >= 90100 >X+ NULL, >X+#endif >X+#endif >X+ NULL, >X+ NULL >X+ ); >X+ >X+ DefineCustomStringVariable( >X+ "online_analyze.exclude_tables", >X+ "List of tables which will not online analyze", >X+ NULL, >X+ &excludeTables.tableStr, >X+#if PG_VERSION_NUM >= 80400 >X+ "", >X+#endif >X+ PGC_USERSET, >X+ 0, >X+#if PG_VERSION_NUM >= 90100 >X+ excludeTablesCheck, >X+ excludeTablesAssign, >X+#else >X+ excludeTablesAssign, >X+#endif >X+ excludeTablesShow >X+ ); >X+ >X+ DefineCustomStringVariable( >X+ "online_analyze.include_tables", >X+ "List of tables which will online analyze", >X+ NULL, >X+ &includeTables.tableStr, >X+#if PG_VERSION_NUM >= 80400 >X+ "", >X+#endif >X+ PGC_USERSET, >X+ 0, >X+#if PG_VERSION_NUM >= 90100 >X+ includeTablesCheck, >X+ includeTablesAssign, >X+#else >X+ includeTablesAssign, >X+#endif >X+ includeTablesShow >X+ ); >X+} >X+ >X+void _PG_fini(void); >X+void >X+_PG_fini(void) >X+{ >X+ ExecutorEnd_hook = oldExecutorEndHook; >X+#if PG_VERSION_NUM >= 90200 >X+ ProcessUtility_hook = oldProcessUtilityHook; >X+#endif >X+ >X+ if (excludeTables.tables) >X+ free(excludeTables.tables); >X+ if (includeTables.tables) >X+ free(includeTables.tables); >X+ >X+ excludeTables.tables = includeTables.tables = NULL; >X+ excludeTables.nTables = includeTables.nTables = 0; >X+} >Xdiff -urN ../postgresql-9.2.0.orig/contrib/online_analyze/README.online_analyze ./contrib/online_analyze/README.online_analyze >X--- ../postgresql-9.2.0.orig/contrib/online_analyze/README.online_analyze Thu Jan 01 04:00:00 1970 >X+++ ./contrib/online_analyze/README.online_analyze Tue Sep 25 17:13:16 2012 >X@@ -0,0 +1,36 @@ >X+Module makes an analyze call immediately after INSERT/UPDATE/DELETE/SELECT INTO >X+for affected table(s). >X+ >X+Supported versionsi of PostgreSQL: 8.4.*, 9.0.*, 9.1.* >X+ >X+Usage: LOAD 'online_analyze'; >X+ >X+Custom variables (defaults values are shown): >X+online_analyze.enable = on >X+ Enables on-line analyze >X+ >X+online_analyze.verbose = on >X+ Execute ANALYZE VERBOSE >X+ >X+online_analyze.scale_factor = 0.1 >X+ Fraction of table size to start on-line analyze (similar to >X+ autovacuum_analyze_scale_factor) >X+ >X+online_analyze.threshold = 50 >X+ Min number of row updates before on-line analyze (similar to >X+ autovacuum_analyze_threshold) >X+ >X+online_analyze.min_interval = 10000 >X+ Minimum time interval between analyze call per table (in milliseconds) >X+ >X+online_analyze.table_type = "all" >X+ Type(s) of table for online analyze: all, persistent, temporary, none >X+ >X+online_analyze.exclude_tables = "" >X+ List of tables which will not online analyze >X+ >X+online_analyze.include_tables = "" >X+ List of tables which will online analyze >X+ online_analyze.include_tables overwrites online_analyze.exclude_tables. >X+ >X+Author: Teodor Sigaev <teodor@sigaev.ru> >47e4f19f57876df3300d9003e88244b4 >echo x - postgresql92-1c/files/patch-contrib-uuid >sed 's/^X//' >postgresql92-1c/files/patch-contrib-uuid << '2e95d2c2266579f44fdcc0e1f0a53fb4' >X--- contrib/uuid-ossp/Makefile.orig 2014-07-21 20:12:31.000000000 +0100 >X+++ contrib/uuid-ossp/Makefile 2014-07-30 18:15:36.370934674 +0100 >X@@ -1,12 +1,14 @@ >X # contrib/uuid-ossp/Makefile >X+# modified using http://pgfoundry.org/projects/uuid-freebsd/ >X+# to actually not use ossp, since uuid methods are all >X+# built in into libc in FreeBSD /girgen@ >X >X MODULE_big = uuid-ossp >X OBJS = uuid-ossp.o >X >X EXTENSION = uuid-ossp >X DATA = uuid-ossp--1.0.sql uuid-ossp--unpackaged--1.0.sql >X- >X-SHLIB_LINK += $(OSSP_UUID_LIBS) >X+SHLIB_LINK = -lmd >X >X ifdef USE_PGXS >X PG_CONFIG = pg_config >X--- contrib/uuid-ossp/uuid-ossp.c.orig 2014-07-21 20:12:31.000000000 +0100 >X+++ contrib/uuid-ossp/uuid-ossp.c 2014-07-30 18:15:44.843935308 +0100 >X@@ -6,6 +6,10 @@ >X * >X * contrib/uuid-ossp/uuid-ossp.c >X * >X+ * Modified to use FreeBSD's built in uuid instead of ossp: >X+ * Copyright (c) 2009 Andrew Gierth >X+ * >X+ * URL: http://pgfoundry.org/projects/uuid-freebsd >X *------------------------------------------------------------------------- >X */ >X >X@@ -14,27 +18,14 @@ >X #include "utils/builtins.h" >X #include "utils/uuid.h" >X >X-/* >X- * There's some confusion over the location of the uuid.h header file. >X- * On Debian, it's installed as ossp/uuid.h, while on Fedora, or if you >X- * install ossp-uuid from a tarball, it's installed as uuid.h. Don't know >X- * what other systems do. >X- */ >X-#ifdef HAVE_OSSP_UUID_H >X-#include <ossp/uuid.h> >X-#else >X-#ifdef HAVE_UUID_H >X-#include <uuid.h> >X-#else >X-#error OSSP uuid.h not found >X-#endif >X-#endif >X- >X-/* better both be 16 */ >X-#if (UUID_LEN != UUID_LEN_BIN) >X-#error UUID length mismatch >X-#endif >X+/* OS has a uuid_hash that conflicts with ours; kill it*/ >X+/* explicit path since we do _not_ want to get any other version */ >X+#define uuid_hash freebsd_uuid_hash >X+#include "/usr/include/uuid.h" >X+#undef uuid_hash >X >X+#include <md5.h> >X+#include <sha.h> >X >X PG_MODULE_MAGIC; >X >X@@ -64,177 +55,175 @@ >X PG_FUNCTION_INFO_V1(uuid_generate_v4); >X PG_FUNCTION_INFO_V1(uuid_generate_v5); >X >X-static void >X-pguuid_complain(uuid_rc_t rc) >X-{ >X- char *err = uuid_error(rc); >X- >X- if (err != NULL) >X- ereport(ERROR, >X- (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), >X- errmsg("OSSP uuid library failure: %s", err))); >X- else >X- ereport(ERROR, >X- (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), >X- errmsg("OSSP uuid library failure: error code %d", rc))); >X-} >X+/* we assume that the string representation is portable and that the >X+ * native binary representation might not be. But for *ns, we assume >X+ * that pg's internal storage of uuids is the simple byte-oriented >X+ * binary format. */ >X >X-/* >X- * We create a uuid_t object just once per session and re-use it for all >X- * operations in this module. OSSP UUID caches the system MAC address and >X- * other state in this object. Reusing the object has a number of benefits: >X- * saving the cycles needed to fetch the system MAC address over and over, >X- * reducing the amount of entropy we draw from /dev/urandom, and providing a >X- * positive guarantee that successive generated V1-style UUIDs don't collide. >X- * (On a machine fast enough to generate multiple UUIDs per microsecond, >X- * or whatever the system's wall-clock resolution is, we'd otherwise risk >X- * collisions whenever random initialization of the uuid_t's clock sequence >X- * value chanced to produce duplicates.) >X- * >X- * However: when we're doing V3 or V5 UUID creation, uuid_make needs two >X- * uuid_t objects, one holding the namespace UUID and one for the result. >X- * It's unspecified whether it's safe to use the same uuid_t for both cases, >X- * so let's cache a second uuid_t for use as the namespace holder object. >X- */ >X-static uuid_t * >X-get_cached_uuid_t(int which) >X+static Datum >X+internal_uuid_create(int v, unsigned char *ns, char *ptr, int len) >X { >X- static uuid_t *cached_uuid[2] = {NULL, NULL}; >X+ char strbuf[40]; >X >X- if (cached_uuid[which] == NULL) >X+ switch (v) >X { >X- uuid_rc_t rc; >X+ case 0: /* constant-value uuids: nil, or namespace uuids */ >X+ strlcpy(strbuf, ptr, 37); >X+ break; >X >X- rc = uuid_create(&cached_uuid[which]); >X- if (rc != UUID_RC_OK) >X- { >X- cached_uuid[which] = NULL; >X- pguuid_complain(rc); >X- } >X+ case 4: default: /* random uuid */ >X+ { >X+ sprintf(strbuf, "%08lx-%04x-%04x-%04x-%04x%08lx", >X+ (unsigned long) arc4random(), >X+ (unsigned) (arc4random() & 0xffff), >X+ (unsigned) ((arc4random() & 0xfff) | 0x4000), >X+ (unsigned) ((arc4random() & 0x3fff) | 0x8000), >X+ (unsigned) (arc4random() & 0xffff), >X+ (unsigned long) arc4random()); >X+ break; >X } >X- return cached_uuid[which]; >X-} >X+ >X+ case 1: /* time/node-based uuids */ >X+ { >X+ uuid_t uu; >X+ uint32_t status = uuid_s_ok; >X+ char *str = NULL; >X >X-static char * >X-uuid_to_string(const uuid_t *uuid) >X-{ >X- char *buf = palloc(UUID_LEN_STR + 1); >X- void *ptr = buf; >X- size_t len = UUID_LEN_STR + 1; >X- uuid_rc_t rc; >X+ uuid_create(&uu, &status); >X >X- rc = uuid_export(uuid, UUID_FMT_STR, &ptr, &len); >X- if (rc != UUID_RC_OK) >X- pguuid_complain(rc); >X+ if (status == uuid_s_ok) >X+ { >X+ uuid_to_string(&uu, &str, &status); >X+ if (status == uuid_s_ok) >X+ { >X+ strlcpy(strbuf, str, 37); >X >X- return buf; >X-} >X+ /* PTR, if set, replaces the trailing characters of the uuid; >X+ * this is to support v1mc, where a random multicast MAC is >X+ * used instead of the physical one >X+ */ >X+ >X+ if (ptr && len <= 36) >X+ strcpy(strbuf + (36 - len), ptr); >X+ } >X+ if (str) >X+ free(str); >X+ } >X >X+ if (status != uuid_s_ok) >X+ { >X+ ereport(ERROR, >X+ (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION), >X+ errmsg("FreeBSD uuid library failure: %d", (int) status))); >X+ } >X+ >X+ break; >X+ } >X >X-static void >X-string_to_uuid(const char *str, uuid_t *uuid) >X-{ >X- uuid_rc_t rc; >X+ case 3: /* namespace-based MD5 uuids */ >X+ { >X+ /* we could use pg's md5(), but we're already pulling in libmd */ >X+ MD5_CTX ctx; >X+ unsigned char buf[16]; >X+ >X+ MD5Init(&ctx); >X+ MD5Update(&ctx, ns, 16); >X+ MD5Update(&ctx, (unsigned char *)ptr, len); >X+ MD5Final(buf, &ctx); >X+ >X+ sprintf(strbuf, >X+ "%02x%02x%02x%02x-" >X+ "%02x%02x-%02x%02x-%02x%02x-" >X+ "%02x%02x%02x%02x%02x%02x", >X+ buf[0], buf[1], buf[2], buf[3], >X+ buf[4], buf[5], ((buf[6] & 0xf) | 0x30), buf[7], >X+ ((buf[8] & 0x3F) | 0x80), buf[9], buf[10], buf[11], >X+ buf[12], buf[13], buf[14], buf[15]); >X >X- rc = uuid_import(uuid, UUID_FMT_STR, str, UUID_LEN_STR + 1); >X- if (rc != UUID_RC_OK) >X- pguuid_complain(rc); >X-} >X+ break; >X+ } >X+ >X+ case 5: /* namespace-based SHA1 uuids */ >X+ { >X+ SHA_CTX ctx; >X+ unsigned char buf[20]; >X >X+ SHA1_Init(&ctx); >X+ SHA1_Update(&ctx, ns, 16); >X+ SHA1_Update(&ctx, (unsigned char *)ptr, len); >X+ SHA1_Final(buf, &ctx); >X+ >X+ sprintf(strbuf, >X+ "%02x%02x%02x%02x-" >X+ "%02x%02x-%02x%02x-%02x%02x-" >X+ "%02x%02x%02x%02x%02x%02x", >X+ buf[0], buf[1], buf[2], buf[3], >X+ buf[4], buf[5], ((buf[6] & 0xf) | 0x30), buf[7], >X+ ((buf[8] & 0x3F) | 0x80), buf[9], buf[10], buf[11], >X+ buf[12], buf[13], buf[14], buf[15]); >X >X-static Datum >X-special_uuid_value(const char *name) >X-{ >X- uuid_t *uuid = get_cached_uuid_t(0); >X- char *str; >X- uuid_rc_t rc; >X- >X- rc = uuid_load(uuid, name); >X- if (rc != UUID_RC_OK) >X- pguuid_complain(rc); >X- str = uuid_to_string(uuid); >X+ break; >X+ } >X+ } >X >X- return DirectFunctionCall1(uuid_in, CStringGetDatum(str)); >X+ return DirectFunctionCall1(uuid_in, CStringGetDatum(strbuf)); >X } >X >X >X Datum >X uuid_nil(PG_FUNCTION_ARGS) >X { >X- return special_uuid_value("nil"); >X+ return internal_uuid_create(0, NULL, "00000000-0000-0000-0000-000000000000", 36); >X } >X >X >X Datum >X uuid_ns_dns(PG_FUNCTION_ARGS) >X { >X- return special_uuid_value("ns:DNS"); >X+ return internal_uuid_create(0, NULL, "6ba7b810-9dad-11d1-80b4-00c04fd430c8", 36); >X } >X >X >X Datum >X uuid_ns_url(PG_FUNCTION_ARGS) >X { >X- return special_uuid_value("ns:URL"); >X+ return internal_uuid_create(0, NULL, "6ba7b811-9dad-11d1-80b4-00c04fd430c8", 36); >X } >X >X >X Datum >X uuid_ns_oid(PG_FUNCTION_ARGS) >X { >X- return special_uuid_value("ns:OID"); >X+ return internal_uuid_create(0, NULL, "6ba7b812-9dad-11d1-80b4-00c04fd430c8", 36); >X } >X >X >X Datum >X uuid_ns_x500(PG_FUNCTION_ARGS) >X { >X- return special_uuid_value("ns:X500"); >X-} >X- >X- >X-static Datum >X-uuid_generate_internal(int mode, const uuid_t *ns, const char *name) >X-{ >X- uuid_t *uuid = get_cached_uuid_t(0); >X- char *str; >X- uuid_rc_t rc; >X- >X- rc = uuid_make(uuid, mode, ns, name); >X- if (rc != UUID_RC_OK) >X- pguuid_complain(rc); >X- str = uuid_to_string(uuid); >X- >X- return DirectFunctionCall1(uuid_in, CStringGetDatum(str)); >X+ return internal_uuid_create(0, NULL, "6ba7b814-9dad-11d1-80b4-00c04fd430c8", 36); >X } >X >X >X Datum >X uuid_generate_v1(PG_FUNCTION_ARGS) >X { >X- return uuid_generate_internal(UUID_MAKE_V1, NULL, NULL); >X+ return internal_uuid_create(1, NULL, NULL, 0); >X } >X >X >X Datum >X uuid_generate_v1mc(PG_FUNCTION_ARGS) >X { >X- return uuid_generate_internal(UUID_MAKE_V1 | UUID_MAKE_MC, NULL, NULL); >X-} >X- >X- >X-static Datum >X-uuid_generate_v35_internal(int mode, pg_uuid_t *ns, text *name) >X-{ >X- uuid_t *ns_uuid = get_cached_uuid_t(1); >X- >X- string_to_uuid(DatumGetCString(DirectFunctionCall1(uuid_out, >X- UUIDPGetDatum(ns))), >X- ns_uuid); >X+ char buf[20]; >X >X- return uuid_generate_internal(mode, >X- ns_uuid, >X- text_to_cstring(name)); >X+ sprintf(buf, "-%04x-%04x%08lx", >X+ (unsigned)((arc4random() & 0x3FFF) | 0x8000), >X+ /* set IEEE802 multicast and local-admin bits */ >X+ (unsigned)((arc4random() & 0xffff) | 0x0300), >X+ (unsigned long) arc4random()); >X+ >X+ return internal_uuid_create(1, NULL, buf, 18); >X } >X >X >X@@ -244,14 +233,15 @@ >X pg_uuid_t *ns = PG_GETARG_UUID_P(0); >X text *name = PG_GETARG_TEXT_P(1); >X >X- return uuid_generate_v35_internal(UUID_MAKE_V3, ns, name); >X+ return internal_uuid_create(3, (unsigned char *)ns, >X+ VARDATA(name), VARSIZE(name) - VARHDRSZ); >X } >X >X >X Datum >X uuid_generate_v4(PG_FUNCTION_ARGS) >X { >X- return uuid_generate_internal(UUID_MAKE_V4, NULL, NULL); >X+ return internal_uuid_create(4, NULL, NULL, 0); >X } >X >X >X@@ -261,5 +251,6 @@ >X pg_uuid_t *ns = PG_GETARG_UUID_P(0); >X text *name = PG_GETARG_TEXT_P(1); >X >X- return uuid_generate_v35_internal(UUID_MAKE_V5, ns, name); >X+ return internal_uuid_create(5, (unsigned char *)ns, >X+ VARDATA(name), VARSIZE(name) - VARHDRSZ); >X } >2e95d2c2266579f44fdcc0e1f0a53fb4 >echo x - postgresql92-1c/files/patch-doc-Makefile >sed 's/^X//' >postgresql92-1c/files/patch-doc-Makefile << 'f429c5c2ebfb9edca2ad54df8260b9a9' >X--- doc/src/sgml/Makefile.orig 2010-06-12 23:40:31.000000000 +0200 >X+++ doc/src/sgml/Makefile 2010-09-19 22:07:11.210759927 +0200 >X@@ -15,14 +15,14 @@ >X >X # Make "html" the default target, since that is what most people tend >X # to want to use. >X-html: >X+man: >X >X subdir = doc/src/sgml >X top_builddir = ../../.. >X include $(top_builddir)/src/Makefile.global >X >X >X-all: html man >X+all: man >X >X distprep: html distprep-man >X >X@@ -285,7 +285,7 @@ >X ## Install >X ## >X >X-install: install-html >X+##install: install-html >X >X ifneq ($(PORTNAME), sco) >X install: install-man >f429c5c2ebfb9edca2ad54df8260b9a9 >echo x - postgresql92-1c/files/patch-doc-src-sgml-Makefile >sed 's/^X//' >postgresql92-1c/files/patch-doc-src-sgml-Makefile << 'ac718c31cd1ecd2462c41d9d42278c59' >X--- doc/src/sgml/Makefile.orig 2015-06-15 21:56:43 UTC >X+++ doc/src/sgml/Makefile >X@@ -71,8 +71,6 @@ override SPFLAGS += -wall -wno-unused-pa >X ## Man pages >X ## >X >X-man distprep-man: man-stamp >X- >X man-stamp: stylesheet-man.xsl postgres.xml >X $(XSLTPROC) $(XSLTPROCFLAGS) $(XSLTPROC_MAN_FLAGS) $^ >X touch $@ >X@@ -293,7 +291,7 @@ install: install-man >X endif >X >X installdirs: >X- $(MKDIR_P) '$(DESTDIR)$(htmldir)'/html $(addprefix '$(DESTDIR)$(mandir)'/man, 1 3 $(sqlmansectnum)) >X+ $(MKDIR_P) $(addprefix '$(DESTDIR)$(mandir)'/man, 1 3 $(sqlmansectnum)) >X >X uninstall: >X rm -f '$(DESTDIR)$(htmldir)/html/'* $(addprefix '$(DESTDIR)$(mandir)'/man, 1/* 3/* $(sqlmansectnum)/*) >ac718c31cd1ecd2462c41d9d42278c59 >echo x - postgresql92-1c/files/patch-src:backend:utils:misc:postgresql.conf.sample >sed 's/^X//' >postgresql92-1c/files/patch-src:backend:utils:misc:postgresql.conf.sample << '61d4de89f610652bbc8e0b55896290af' >X--- src/backend/utils/misc/postgresql.conf.sample.orig 2010-10-01 16:25:44.000000000 +0200 >X+++ src/backend/utils/misc/postgresql.conf.sample 2010-10-05 07:37:35.626282933 +0200 >X@@ -256,6 +256,7 @@ >X >X # - Where to Log - >X >X+log_destination = 'syslog' >X #log_destination = 'stderr' # Valid values are combinations of >X # stderr, csvlog, syslog, and eventlog, >X # depending on platform. csvlog >X@@ -394,6 +396,9 @@ >X #track_counts = on >X #track_functions = none # none, pl, all >X #track_activity_query_size = 1024 # (change requires restart) >X+ >X+# On FreeBSD, this is a performance hog, so keep it off if you need speed >X+update_process_title = off >X #update_process_title = on >X #stats_temp_directory = 'pg_stat_tmp' >X >61d4de89f610652bbc8e0b55896290af >echo x - postgresql92-1c/files/dot.cshrc.in >sed 's/^X//' >postgresql92-1c/files/dot.cshrc.in << '437165b28f7635272bd4eb8fde5386dc' >Xsetenv PGLIB %%PREFIX%%/lib >X >X# note: PGDATA can be overridden by the -D startup option >Xsetenv PGDATA $HOME/data >X >X#You might want to set some locale stuff here >Xsetenv PGDATESTYLE European >X#setenv LC_ALL sv_SE.ISO_8859-1 >X >X# if you want to make regression tests use this TZ >X#setenv TZ PST8PDT >437165b28f7635272bd4eb8fde5386dc >echo x - postgresql92-1c/files/dot.profile.in >sed 's/^X//' >postgresql92-1c/files/dot.profile.in << 'edba3f94a454ac2fd178a7844df5558b' >XPGLIB=%%PREFIX%%/lib >X >X# note: PGDATA can be overridden by the -D startup option >XPGDATA=${HOME}/data >X >Xexport PATH PGLIB PGDATA >X >X# if you use the periodic script from share/postgresql/502.pgsql, you >X# can set these >X#PGDUMP_ARGS="-b -F c" >X#PGBACKUPDIR=${HOME}/backups >X#PGBACKUP_SAVE_DAYS=7 >X#export PGBACKUPDIR PGDUMP_ARGS PGBACKUP_SAVE_DAYS >X >X#You might want to set some locale stuff here >XPGDATESTYLE=European >X#LC_ALL=sv_SE.ISO_8859-1 >X#export PGDATESTYLE LC_ALL >X >X# if you want to make regression tests use this TZ >X#TZ=PST8PDT >X#export TZ >edba3f94a454ac2fd178a7844df5558b >echo x - postgresql92-1c/files/patch-1c-full >sed 's/^X//' >postgresql92-1c/files/patch-1c-full << '0bcb39c9431c594561482fe120de68b6' >Xdiff --git a/contrib/fasttrun/Makefile b/contrib/fasttrun/Makefile >Xnew file mode 100644 >Xindex 0000000..06c47a1 >X--- /dev/null >X+++ contrib/fasttrun/Makefile >X@@ -0,0 +1,15 @@ >X+MODULE_big = fasttrun >X+OBJS = fasttrun.o >X+DATA_built = fasttrun.sql >X+DOCS = README.fasttrun >X+REGRESS = fasttrun >X+ >X+ifdef USE_PGXS >X+PGXS := $(shell pg_config --pgxs) >X+include $(PGXS) >X+else >X+subdir = contrib/fasttrun >X+top_builddir = ../.. >X+include $(top_builddir)/src/Makefile.global >X+include $(top_srcdir)/contrib/contrib-global.mk >X+endif >Xdiff --git a/contrib/fasttrun/README.fasttrun b/contrib/fasttrun/README.fasttrun >Xnew file mode 100644 >Xindex 0000000..4b1dfdc >X--- /dev/null >X+++ contrib/fasttrun/README.fasttrun >X@@ -0,0 +1,17 @@ >X+select fasttruncate('TABLE_NAME'); >X+ >X+Function truncates the temporary table and doesn't grow >X+pg_class size. >X+ >X+Warning: function isn't transaction safe! >X+ >X+For tests: >X+create or replace function f() returns void as $$ >X+begin >X+for i in 1..1000 >X+loop >X+ PERFORM fasttruncate('tt1'); >X+end loop; >X+end; >X+$$ language plpgsql; >X+ >Xdiff --git a/contrib/fasttrun/expected/fasttrun.out b/contrib/fasttrun/expected/fasttrun.out >Xnew file mode 100644 >Xindex 0000000..9914e77 >X--- /dev/null >X+++ contrib/fasttrun/expected/fasttrun.out >X@@ -0,0 +1,115 @@ >X+\set ECHO none >X+create table persist ( a int ); >X+insert into persist values (1); >X+select fasttruncate('persist'); >X+ERROR: Relation isn't a temporary table >X+insert into persist values (2); >X+select * from persist order by a; >X+ a >X+--- >X+ 1 >X+ 2 >X+(2 rows) >X+ >X+create temp table temp1 (a int); >X+insert into temp1 values (1); >X+BEGIN; >X+create temp table temp2 (a int); >X+insert into temp2 values (1); >X+select * from temp1 order by a; >X+ a >X+--- >X+ 1 >X+(1 row) >X+ >X+select * from temp2 order by a; >X+ a >X+--- >X+ 1 >X+(1 row) >X+ >X+insert into temp1 (select * from generate_series(1,10000)); >X+insert into temp2 (select * from generate_series(1,11000)); >X+analyze temp2; >X+select relname, relpages>0, reltuples>0 from pg_class where relname in ('temp1', 'temp2') order by relname; >X+ relname | ?column? | ?column? >X+---------+----------+---------- >X+ temp1 | f | f >X+ temp2 | t | t >X+(2 rows) >X+ >X+select fasttruncate('temp1'); >X+ fasttruncate >X+-------------- >X+ >X+(1 row) >X+ >X+select fasttruncate('temp2'); >X+ fasttruncate >X+-------------- >X+ >X+(1 row) >X+ >X+insert into temp1 values (-2); >X+insert into temp2 values (-2); >X+select * from temp1 order by a; >X+ a >X+---- >X+ -2 >X+(1 row) >X+ >X+select * from temp2 order by a; >X+ a >X+---- >X+ -2 >X+(1 row) >X+ >X+COMMIT; >X+select * from temp1 order by a; >X+ a >X+---- >X+ -2 >X+(1 row) >X+ >X+select * from temp2 order by a; >X+ a >X+---- >X+ -2 >X+(1 row) >X+ >X+select relname, relpages>0, reltuples>0 from pg_class where relname in ('temp1', 'temp2') order by relname; >X+ relname | ?column? | ?column? >X+---------+----------+---------- >X+ temp1 | f | f >X+ temp2 | f | f >X+(2 rows) >X+ >X+select fasttruncate('temp1'); >X+ fasttruncate >X+-------------- >X+ >X+(1 row) >X+ >X+select fasttruncate('temp2'); >X+ fasttruncate >X+-------------- >X+ >X+(1 row) >X+ >X+select * from temp1 order by a; >X+ a >X+--- >X+(0 rows) >X+ >X+select * from temp2 order by a; >X+ a >X+--- >X+(0 rows) >X+ >X+select relname, relpages>0, reltuples>0 from pg_class where relname in ('temp1', 'temp2') order by relname; >X+ relname | ?column? | ?column? >X+---------+----------+---------- >X+ temp1 | f | f >X+ temp2 | f | f >X+(2 rows) >X+ >Xdiff --git a/contrib/fasttrun/fasttrun.c b/contrib/fasttrun/fasttrun.c >Xnew file mode 100644 >Xindex 0000000..e9407e3 >X--- /dev/null >X+++ contrib/fasttrun/fasttrun.c >X@@ -0,0 +1,73 @@ >X+#include "postgres.h" >X+ >X+#include "access/genam.h" >X+#include "access/heapam.h" >X+#include "miscadmin.h" >X+#include "storage/lmgr.h" >X+#include "storage/bufmgr.h" >X+#include "catalog/namespace.h" >X+#include "utils/lsyscache.h" >X+#include "utils/builtins.h" >X+#include <fmgr.h> >X+#include <funcapi.h> >X+#include <access/heapam.h> >X+#include <catalog/pg_type.h> >X+#include <catalog/heap.h> >X+#include <commands/vacuum.h> >X+ >X+#ifdef PG_MODULE_MAGIC >X+PG_MODULE_MAGIC; >X+#endif >X+ >X+PG_FUNCTION_INFO_V1(fasttruncate); >X+Datum fasttruncate(PG_FUNCTION_ARGS); >X+Datum >X+fasttruncate(PG_FUNCTION_ARGS) { >X+ text *name=PG_GETARG_TEXT_P(0); >X+ char *relname; >X+ List *relname_list; >X+ RangeVar *relvar; >X+ Oid relOid; >X+ Relation rel; >X+ bool makeanalyze = false; >X+ >X+ relname = palloc( VARSIZE(name) + 1); >X+ memcpy(relname, VARDATA(name), VARSIZE(name)-VARHDRSZ); >X+ relname[ VARSIZE(name)-VARHDRSZ ] = '\0'; >X+ >X+ relname_list = stringToQualifiedNameList(relname); >X+ relvar = makeRangeVarFromNameList(relname_list); >X+ relOid = RangeVarGetRelid(relvar, AccessExclusiveLock, false); >X+ >X+ if ( get_rel_relkind(relOid) != RELKIND_RELATION ) >X+ elog(ERROR,"Relation isn't a ordinary table"); >X+ >X+ rel = heap_open(relOid, NoLock); >X+ >X+ if ( !isTempNamespace(get_rel_namespace(relOid)) ) >X+ elog(ERROR,"Relation isn't a temporary table"); >X+ >X+ heap_truncate(list_make1_oid(relOid)); >X+ >X+ if ( rel->rd_rel->relpages > 0 || rel->rd_rel->reltuples > 0 ) >X+ makeanalyze = true; >X+ >X+ /* >X+ * heap_truncate doesn't unlock the table, >X+ * so we should unlock it. >X+ */ >X+ >X+ heap_close(rel, AccessExclusiveLock); >X+ >X+ if ( makeanalyze ) { >X+ VacuumStmt *vac = makeNode(VacuumStmt); >X+ >X+ vac->options = VACOPT_ANALYZE; >X+ vac->relation = relvar; >X+ >X+ vacuum(vac, relOid, false, >X+ GetAccessStrategy(BAS_VACUUM), false, false); >X+ } >X+ >X+ PG_RETURN_VOID(); >X+} >Xdiff --git a/contrib/fasttrun/fasttrun.sql.in b/contrib/fasttrun/fasttrun.sql.in >Xnew file mode 100644 >Xindex 0000000..0895c77 >X--- /dev/null >X+++ contrib/fasttrun/fasttrun.sql.in >X@@ -0,0 +1,8 @@ >X+BEGIN; >X+ >X+ >X+CREATE OR REPLACE FUNCTION fasttruncate(text) >X+RETURNS void AS 'MODULE_PATHNAME' >X+LANGUAGE C RETURNS NULL ON NULL INPUT VOLATILE; >X+ >X+COMMIT; >Xdiff --git a/contrib/fasttrun/sql/fasttrun.sql b/contrib/fasttrun/sql/fasttrun.sql >Xnew file mode 100644 >Xindex 0000000..73beaf4 >X--- /dev/null >X+++ contrib/fasttrun/sql/fasttrun.sql >X@@ -0,0 +1,50 @@ >X+\set ECHO none >X+\i fasttrun.sql >X+\set ECHO all >X+ >X+create table persist ( a int ); >X+insert into persist values (1); >X+select fasttruncate('persist'); >X+insert into persist values (2); >X+select * from persist order by a; >X+ >X+create temp table temp1 (a int); >X+insert into temp1 values (1); >X+ >X+BEGIN; >X+ >X+create temp table temp2 (a int); >X+insert into temp2 values (1); >X+ >X+select * from temp1 order by a; >X+select * from temp2 order by a; >X+ >X+insert into temp1 (select * from generate_series(1,10000)); >X+insert into temp2 (select * from generate_series(1,11000)); >X+ >X+analyze temp2; >X+select relname, relpages>0, reltuples>0 from pg_class where relname in ('temp1', 'temp2') order by relname; >X+ >X+select fasttruncate('temp1'); >X+select fasttruncate('temp2'); >X+ >X+insert into temp1 values (-2); >X+insert into temp2 values (-2); >X+ >X+select * from temp1 order by a; >X+select * from temp2 order by a; >X+ >X+COMMIT; >X+ >X+select * from temp1 order by a; >X+select * from temp2 order by a; >X+ >X+select relname, relpages>0, reltuples>0 from pg_class where relname in ('temp1', 'temp2') order by relname; >X+ >X+select fasttruncate('temp1'); >X+select fasttruncate('temp2'); >X+ >X+select * from temp1 order by a; >X+select * from temp2 order by a; >X+ >X+select relname, relpages>0, reltuples>0 from pg_class where relname in ('temp1', 'temp2') order by relname; >Xdiff --git a/contrib/fulleq/Makefile b/contrib/fulleq/Makefile >Xnew file mode 100644 >Xindex 0000000..bc8bdd2 >X--- /dev/null >X+++ contrib/fulleq/Makefile >X@@ -0,0 +1,32 @@ >X+MODULE_big = fulleq >X+OBJS = fulleq.o >X+DATA_built = fulleq.sql >X+DOCS = README.fulleq >X+REGRESS = fulleq >X+ >X+ARGTYPE = bool bytea char name int8 int2 int2vector int4 text \ >X+ oid xid cid oidvector float4 float8 abstime reltime macaddr \ >X+ inet cidr varchar date time timestamp timestamptz \ >X+ interval timetz >X+ >X+EXTRA_CLEAN = fulleq.sql.in >X+ >X+ifdef USE_PGXS >X+PGXS := $(shell pg_config --pgxs) >X+include $(PGXS) >X+else >X+subdir = contrib/fulleq >X+top_builddir = ../.. >X+include $(top_builddir)/src/Makefile.global >X+include $(top_srcdir)/contrib/contrib-global.mk >X+endif >X+ >X+fulleq.sql.in: fulleq.sql.in.in >X+ echo 'BEGIN;' > $@ >X+ echo 'SET search_path = public;' >> $@ >X+ for type in $(ARGTYPE); \ >X+ do \ >X+ sed -e "s/ARGTYPE/$$type/g" < $< >> $@; \ >X+ done >X+ echo 'COMMIT;' >> $@ >X+ >Xdiff --git a/contrib/fulleq/README.fulleq b/contrib/fulleq/README.fulleq >Xnew file mode 100644 >Xindex 0000000..a677c49 >X--- /dev/null >X+++ contrib/fulleq/README.fulleq >X@@ -0,0 +1,3 @@ >X+Introduce operator == which returns true when >X+operands are equal or both are nulls. >X+ >Xdiff --git a/contrib/fulleq/expected/fulleq.out b/contrib/fulleq/expected/fulleq.out >Xnew file mode 100644 >Xindex 0000000..4842d8c >X--- /dev/null >X+++ contrib/fulleq/expected/fulleq.out >X@@ -0,0 +1,61 @@ >X+\set ECHO none >X+select 4::int == 4; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 4::int == 5; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 4::int == NULL; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select NULL::int == 5; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select NULL::int == NULL; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select '4'::text == '4'; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select '4'::text == '5'; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select '4'::text == NULL; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select NULL::text == '5'; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select NULL::text == NULL; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >Xdiff --git a/contrib/fulleq/fulleq.c b/contrib/fulleq/fulleq.c >Xnew file mode 100644 >Xindex 0000000..8e8e17b >X--- /dev/null >X+++ contrib/fulleq/fulleq.c >X@@ -0,0 +1,72 @@ >X+#include "postgres.h" >X+#include "fmgr.h" >X+#include "access/hash.h" >X+#include "utils/builtins.h" >X+#include "utils/bytea.h" >X+#include "utils/int8.h" >X+#include "utils/nabstime.h" >X+#include "utils/timestamp.h" >X+#include "utils/date.h" >X+ >X+#ifdef PG_MODULE_MAGIC >X+PG_MODULE_MAGIC; >X+#endif >X+ >X+#define NULLHASHVALUE (-2147483647) >X+ >X+#define FULLEQ_FUNC(type, cmpfunc, hashfunc) \ >X+PG_FUNCTION_INFO_V1( isfulleq_##type ); \ >X+Datum isfulleq_##type(PG_FUNCTION_ARGS); \ >X+Datum \ >X+isfulleq_##type(PG_FUNCTION_ARGS) { \ >X+ if ( PG_ARGISNULL(0) && PG_ARGISNULL(1) ) \ >X+ PG_RETURN_BOOL(true); \ >X+ else if ( PG_ARGISNULL(0) || PG_ARGISNULL(1) ) \ >X+ PG_RETURN_BOOL(false); \ >X+ \ >X+ PG_RETURN_DATUM( DirectFunctionCall2( cmpfunc, \ >X+ PG_GETARG_DATUM(0), \ >X+ PG_GETARG_DATUM(1) \ >X+ ) ); \ >X+} \ >X+ \ >X+PG_FUNCTION_INFO_V1( fullhash_##type ); \ >X+Datum fullhash_##type(PG_FUNCTION_ARGS); \ >X+Datum \ >X+fullhash_##type(PG_FUNCTION_ARGS) { \ >X+ if ( PG_ARGISNULL(0) ) \ >X+ PG_RETURN_INT32(NULLHASHVALUE); \ >X+ \ >X+ PG_RETURN_DATUM( DirectFunctionCall1( hashfunc, \ >X+ PG_GETARG_DATUM(0) \ >X+ ) ); \ >X+} >X+ >X+ >X+FULLEQ_FUNC( bool , booleq , hashchar ); >X+FULLEQ_FUNC( bytea , byteaeq , hashvarlena ); >X+FULLEQ_FUNC( char , chareq , hashchar ); >X+FULLEQ_FUNC( name , nameeq , hashname ); >X+FULLEQ_FUNC( int8 , int8eq , hashint8 ); >X+FULLEQ_FUNC( int2 , int2eq , hashint2 ); >X+FULLEQ_FUNC( int2vector , int2vectoreq , hashint2vector ); >X+FULLEQ_FUNC( int4 , int4eq , hashint4 ); >X+FULLEQ_FUNC( text , texteq , hashtext ); >X+FULLEQ_FUNC( oid , oideq , hashoid ); >X+FULLEQ_FUNC( xid , xideq , hashint4 ); >X+FULLEQ_FUNC( cid , cideq , hashint4 ); >X+FULLEQ_FUNC( oidvector , oidvectoreq , hashoidvector ); >X+FULLEQ_FUNC( float4 , float4eq , hashfloat4 ); >X+FULLEQ_FUNC( float8 , float8eq , hashfloat8 ); >X+FULLEQ_FUNC( abstime , abstimeeq , hashint4 ); >X+FULLEQ_FUNC( reltime , reltimeeq , hashint4 ); >X+FULLEQ_FUNC( macaddr , macaddr_eq , hashmacaddr ); >X+FULLEQ_FUNC( inet , network_eq , hashinet ); >X+FULLEQ_FUNC( cidr , network_eq , hashinet ); >X+FULLEQ_FUNC( varchar , texteq , hashtext ); >X+FULLEQ_FUNC( date , date_eq , hashint4 ); >X+FULLEQ_FUNC( time , time_eq , hashfloat8 ); >X+FULLEQ_FUNC( timestamp , timestamp_eq , hashfloat8 ); >X+FULLEQ_FUNC( timestamptz , timestamp_eq , hashfloat8 ); >X+FULLEQ_FUNC( interval , interval_eq , interval_hash ); >X+FULLEQ_FUNC( timetz , timetz_eq , timetz_hash ); >Xdiff --git a/contrib/fulleq/fulleq.sql.in.in b/contrib/fulleq/fulleq.sql.in.in >Xnew file mode 100644 >Xindex 0000000..55e980e >X--- /dev/null >X+++ contrib/fulleq/fulleq.sql.in.in >X@@ -0,0 +1,26 @@ >X+-- For ARGTYPE >X+ >X+CREATE OR REPLACE FUNCTION isfulleq_ARGTYPE(ARGTYPE, ARGTYPE) >X+RETURNS bool AS 'MODULE_PATHNAME' >X+LANGUAGE C CALLED ON NULL INPUT IMMUTABLE; >X+ >X+CREATE OR REPLACE FUNCTION fullhash_ARGTYPE(ARGTYPE) >X+RETURNS int4 AS 'MODULE_PATHNAME' >X+LANGUAGE C CALLED ON NULL INPUT IMMUTABLE; >X+ >X+ >X+CREATE OPERATOR == ( >X+ LEFTARG = ARGTYPE, >X+ RIGHTARG = ARGTYPE, >X+ PROCEDURE = isfulleq_ARGTYPE, >X+ COMMUTATOR = '==', >X+ RESTRICT = eqsel, >X+ JOIN = eqjoinsel, >X+ HASHES >X+); >X+ >X+CREATE OPERATOR CLASS ARGTYPE_fill_ops >X+ FOR TYPE ARGTYPE USING hash AS >X+ OPERATOR 1 ==, >X+ FUNCTION 1 fullhash_ARGTYPE(ARGTYPE); >X+ >Xdiff --git a/contrib/fulleq/sql/fulleq.sql b/contrib/fulleq/sql/fulleq.sql >Xnew file mode 100644 >Xindex 0000000..02b192c >X--- /dev/null >X+++ contrib/fulleq/sql/fulleq.sql >X@@ -0,0 +1,16 @@ >X+\set ECHO none >X+\i fulleq.sql >X+\set ECHO all >X+ >X+select 4::int == 4; >X+select 4::int == 5; >X+select 4::int == NULL; >X+select NULL::int == 5; >X+select NULL::int == NULL; >X+ >X+select '4'::text == '4'; >X+select '4'::text == '5'; >X+select '4'::text == NULL; >X+select NULL::text == '5'; >X+select NULL::text == NULL; >X+ >Xdiff --git a/contrib/mchar/Changes b/contrib/mchar/Changes >Xnew file mode 100644 >Xindex 0000000..b597ee7 >X--- /dev/null >X+++ contrib/mchar/Changes >X@@ -0,0 +1,19 @@ >X+0.17 add == operation: >X+ a == b => ( a = b or a is null and b is null ) >X+0.16 fix pg_dump - now mchar in pg_catalog scheme, not public >X+ fix bug in mvarchar_substr() >X+0.15 add upper()/lower() >X+0.14 Add ESCAPE for LIKE, SIMILAR TO [ESCAPE], POSIX regexp >X+0.13 Outer binary format is now different from >X+ inner: it's just a UTF-16 string >X+0.12 Fix copy binary >X+0.11 Force UTF-8 convertor if server_encoding='UTF8' >X+0.10 add (mchar|mvarchar)_(send|recv) functions to >X+ allow binary copying. Note: that functions >X+ don't recode values. >X+0.9 index support for like, improve recoding functions >X+0.8 initial suport for like optimizioation with index: >X+ still thres no algo to find the nearest greater string >X+0.7 hash indexes and enable a hash joins >X+0.6 implicit casting mchar-mvarchar >X+ cross type comparison operations >Xdiff --git a/contrib/mchar/Makefile b/contrib/mchar/Makefile >Xnew file mode 100644 >Xindex 0000000..27302df >X--- /dev/null >X+++ contrib/mchar/Makefile >X@@ -0,0 +1,27 @@ >X+MODULE_big = mchar >X+OBJS = mchar_io.o mchar_proc.o mchar_op.o mchar_recode.o \ >X+ mchar_like.o >X+DATA_built = mchar.sql >X+DATA = uninstall_mchar.sql >X+DOCS = README.mchar >X+REGRESS = init mchar mvarchar mm like compat >X+ >X+PG_CPPFLAGS=-I/usr/local/include >X+ >X+ifdef USE_PGXS >X+PGXS := $(shell pg_config --pgxs) >X+include $(PGXS) >X+else >X+subdir = contrib/mchar >X+top_builddir = ../.. >X+include $(top_builddir)/src/Makefile.global >X+include $(top_srcdir)/contrib/contrib-global.mk >X+endif >X+ >X+ifeq ($(PORTNAME),win32) >X+ICUNAME=icuin >X+else >X+ICUNAME=icui18n >X+endif >X+ >X+SHLIB_LINK += -L/usr/local/lib -licuuc -l$(ICUNAME) -Wl,-rpath,'$$ORIGIN' >Xdiff --git a/contrib/mchar/README.mchar b/contrib/mchar/README.mchar >Xnew file mode 100644 >Xindex 0000000..479a7d1 >X--- /dev/null >X+++ contrib/mchar/README.mchar >X@@ -0,0 +1,20 @@ >X+MCHAR & VARCHAR >X+ type modifier >X+ length() >X+ substr(str, pos[, length]) >X+ || - concatenation with any (mchar,mvarchar) arguments >X+ < <= = >= > - case-insensitive comparisons (libICU) >X+ &< &<= &= &>= &> - case-sensitive comparisons (libICU) >X+ implicit casting mchar<->mvarchar >X+ B-tree and hash index >X+ LIKE [ESCAPE] >X+ SIMILAR TO [ESCAPE] >X+ ~ (POSIX regexp) >X+ index support for LIKE >X+ >X+ >X+Authors: >X+ Oleg Bartunov <oleg@sai.msu.ru> >X+ Teodor Sigaev <teodor@sigaev.ru> >X+ >X+ >Xdiff --git a/contrib/mchar/data/ch.sql b/contrib/mchar/data/ch.sql >Xnew file mode 100644 >Xindex 0000000..4ff7722 >X--- /dev/null >X+++ contrib/mchar/data/ch.sql >X@@ -0,0 +1,11 @@ >X+create table ch ( >X+ chcol mchar(32) >X+) without oids; >X+ >X+insert into ch values('abcd'); >X+insert into ch values('AbcD'); >X+insert into ch values('abcz'); >X+insert into ch values('defg'); >X+insert into ch values('dEfg'); >X+insert into ch values('ee'); >X+insert into ch values('Ee'); >Xdiff --git a/contrib/mchar/data/chvch.sql b/contrib/mchar/data/chvch.sql >Xnew file mode 100644 >Xindex 0000000..34ceb75 >X--- /dev/null >X+++ contrib/mchar/data/chvch.sql >X@@ -0,0 +1,9 @@ >X+create table chvch ( >X+ ch mchar(12), >X+ vch mvarchar(12) >X+) without oids; >X+ >X+insert into chvch values('No spaces', 'No spaces'); >X+insert into chvch values('One space ', 'One space '); >X+insert into chvch values('1 space', '1 space '); >X+ >Xdiff --git a/contrib/mchar/expected/compat.out b/contrib/mchar/expected/compat.out >Xnew file mode 100644 >Xindex 0000000..480a286 >X--- /dev/null >X+++ contrib/mchar/expected/compat.out >X@@ -0,0 +1,66 @@ >X+--- table based checks >X+select '<' || ch || '>', '<' || vch || '>' from chvch; >X+ ?column? | ?column? >X+----------------+-------------- >X+ <No spaces > | <No spaces> >X+ <One space > | <One space > >X+ <1 space > | <1 space > >X+(3 rows) >X+ >X+select * from chvch where vch = 'One space'; >X+ ch | vch >X+--------------+------------ >X+ One space | One space >X+(1 row) >X+ >X+select * from chvch where vch = 'One space '; >X+ ch | vch >X+--------------+------------ >X+ One space | One space >X+(1 row) >X+ >X+select * from ch where chcol = 'abcd' order by chcol; >X+ chcol >X+---------------------------------- >X+ abcd >X+ AbcD >X+(2 rows) >X+ >X+select * from ch t1 join ch t2 on t1.chcol = t2.chcol order by t1.chcol, t2.chcol; >X+ chcol | chcol >X+----------------------------------+---------------------------------- >X+ abcd | AbcD >X+ abcd | abcd >X+ AbcD | AbcD >X+ AbcD | abcd >X+ abcz | abcz >X+ defg | dEfg >X+ defg | defg >X+ dEfg | dEfg >X+ dEfg | defg >X+ ee | Ee >X+ ee | ee >X+ Ee | Ee >X+ Ee | ee >X+(13 rows) >X+ >X+select * from ch where chcol > 'abcd' and chcol<'ee'; >X+ chcol >X+---------------------------------- >X+ abcz >X+ defg >X+ dEfg >X+(3 rows) >X+ >X+select * from ch order by chcol; >X+ chcol >X+---------------------------------- >X+ abcd >X+ AbcD >X+ abcz >X+ defg >X+ dEfg >X+ ee >X+ Ee >X+(7 rows) >X+ >Xdiff --git a/contrib/mchar/expected/init.out b/contrib/mchar/expected/init.out >Xnew file mode 100644 >Xindex 0000000..d648344 >X--- /dev/null >X+++ contrib/mchar/expected/init.out >X@@ -0,0 +1,15 @@ >X+-- >X+-- first, define the datatype. Turn off echoing so that expected file >X+-- does not depend on contents of mchar.sql. >X+-- >X+\set ECHO none >X+psql:mchar.sql:20: NOTICE: type "mchar" is not yet defined >X+DETAIL: Creating a shell type definition. >X+psql:mchar.sql:25: NOTICE: argument type mchar is only a shell >X+psql:mchar.sql:30: NOTICE: argument type mchar is only a shell >X+psql:mchar.sql:35: NOTICE: return type mchar is only a shell >X+psql:mchar.sql:59: NOTICE: type "mvarchar" is not yet defined >X+DETAIL: Creating a shell type definition. >X+psql:mchar.sql:64: NOTICE: argument type mvarchar is only a shell >X+psql:mchar.sql:69: NOTICE: argument type mvarchar is only a shell >X+psql:mchar.sql:74: NOTICE: return type mvarchar is only a shell >Xdiff --git a/contrib/mchar/expected/like.out b/contrib/mchar/expected/like.out >Xnew file mode 100644 >Xindex 0000000..3a57082 >X--- /dev/null >X+++ contrib/mchar/expected/like.out >X@@ -0,0 +1,791 @@ >X+-- simplest examples >X+-- E061-04 like predicate >X+SELECT 'hawkeye'::mchar LIKE 'h%' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'hawkeye'::mchar NOT LIKE 'h%' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'hawkeye'::mchar LIKE 'H%' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'hawkeye'::mchar NOT LIKE 'H%' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'hawkeye'::mchar LIKE 'indio%' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'hawkeye'::mchar NOT LIKE 'indio%' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'hawkeye'::mchar LIKE 'h%eye' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'hawkeye'::mchar NOT LIKE 'h%eye' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'indio'::mchar LIKE '_ndio' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'indio'::mchar NOT LIKE '_ndio' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'indio'::mchar LIKE 'in__o' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'indio'::mchar NOT LIKE 'in__o' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'indio'::mchar LIKE 'in_o' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'indio'::mchar NOT LIKE 'in_o' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'hawkeye'::mvarchar LIKE 'h%' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'hawkeye'::mvarchar NOT LIKE 'h%' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'hawkeye'::mvarchar LIKE 'H%' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'hawkeye'::mvarchar NOT LIKE 'H%' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'hawkeye'::mvarchar LIKE 'indio%' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'hawkeye'::mvarchar NOT LIKE 'indio%' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'hawkeye'::mvarchar LIKE 'h%eye' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'hawkeye'::mvarchar NOT LIKE 'h%eye' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'indio'::mvarchar LIKE '_ndio' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'indio'::mvarchar NOT LIKE '_ndio' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'indio'::mvarchar LIKE 'in__o' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'indio'::mvarchar NOT LIKE 'in__o' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'indio'::mvarchar LIKE 'in_o' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'indio'::mvarchar NOT LIKE 'in_o' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+-- unused escape character >X+SELECT 'hawkeye'::mchar LIKE 'h%'::mchar ESCAPE '#' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'hawkeye'::mchar NOT LIKE 'h%'::mchar ESCAPE '#' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'indio'::mchar LIKE 'ind_o'::mchar ESCAPE '$' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'indio'::mchar NOT LIKE 'ind_o'::mchar ESCAPE '$' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+-- escape character >X+-- E061-05 like predicate with escape clause >X+SELECT 'h%'::mchar LIKE 'h#%'::mchar ESCAPE '#' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'h%'::mchar NOT LIKE 'h#%'::mchar ESCAPE '#' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'h%wkeye'::mchar LIKE 'h#%'::mchar ESCAPE '#' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'h%wkeye'::mchar NOT LIKE 'h#%'::mchar ESCAPE '#' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'h%wkeye'::mchar LIKE 'h#%%'::mchar ESCAPE '#' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'h%wkeye'::mchar NOT LIKE 'h#%%'::mchar ESCAPE '#' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'h%awkeye'::mchar LIKE 'h#%a%k%e'::mchar ESCAPE '#' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'h%awkeye'::mchar NOT LIKE 'h#%a%k%e'::mchar ESCAPE '#' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'indio'::mchar LIKE '_ndio'::mchar ESCAPE '$' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'indio'::mchar NOT LIKE '_ndio'::mchar ESCAPE '$' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'i_dio'::mchar LIKE 'i$_d_o'::mchar ESCAPE '$' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'i_dio'::mchar NOT LIKE 'i$_d_o'::mchar ESCAPE '$' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'i_dio'::mchar LIKE 'i$_nd_o'::mchar ESCAPE '$' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'i_dio'::mchar NOT LIKE 'i$_nd_o'::mchar ESCAPE '$' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'i_dio'::mchar LIKE 'i$_d%o'::mchar ESCAPE '$' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'i_dio'::mchar NOT LIKE 'i$_d%o'::mchar ESCAPE '$' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+-- escape character same as pattern character >X+SELECT 'maca'::mchar LIKE 'm%aca' ESCAPE '%'::mchar AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'maca'::mchar NOT LIKE 'm%aca' ESCAPE '%'::mchar AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'ma%a'::mchar LIKE 'm%a%%a' ESCAPE '%'::mchar AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'ma%a'::mchar NOT LIKE 'm%a%%a' ESCAPE '%'::mchar AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'bear'::mchar LIKE 'b_ear' ESCAPE '_'::mchar AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'bear'::mchar NOT LIKE 'b_ear'::mchar ESCAPE '_' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'be_r'::mchar LIKE 'b_e__r' ESCAPE '_'::mchar AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'be_r'::mchar NOT LIKE 'b_e__r' ESCAPE '_'::mchar AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'be_r'::mchar LIKE '__e__r' ESCAPE '_'::mchar AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'be_r'::mchar NOT LIKE '__e__r'::mchar ESCAPE '_' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+-- unused escape character >X+SELECT 'hawkeye'::mvarchar LIKE 'h%'::mvarchar ESCAPE '#' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'hawkeye'::mvarchar NOT LIKE 'h%'::mvarchar ESCAPE '#' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'indio'::mvarchar LIKE 'ind_o'::mvarchar ESCAPE '$' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'indio'::mvarchar NOT LIKE 'ind_o'::mvarchar ESCAPE '$' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+-- escape character >X+-- E061-05 like predicate with escape clause >X+SELECT 'h%'::mvarchar LIKE 'h#%'::mvarchar ESCAPE '#' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'h%'::mvarchar NOT LIKE 'h#%'::mvarchar ESCAPE '#' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'h%wkeye'::mvarchar LIKE 'h#%'::mvarchar ESCAPE '#' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'h%wkeye'::mvarchar NOT LIKE 'h#%'::mvarchar ESCAPE '#' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'h%wkeye'::mvarchar LIKE 'h#%%'::mvarchar ESCAPE '#' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'h%wkeye'::mvarchar NOT LIKE 'h#%%'::mvarchar ESCAPE '#' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'h%awkeye'::mvarchar LIKE 'h#%a%k%e'::mvarchar ESCAPE '#' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'h%awkeye'::mvarchar NOT LIKE 'h#%a%k%e'::mvarchar ESCAPE '#' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'indio'::mvarchar LIKE '_ndio'::mvarchar ESCAPE '$' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'indio'::mvarchar NOT LIKE '_ndio'::mvarchar ESCAPE '$' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'i_dio'::mvarchar LIKE 'i$_d_o'::mvarchar ESCAPE '$' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'i_dio'::mvarchar NOT LIKE 'i$_d_o'::mvarchar ESCAPE '$' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'i_dio'::mvarchar LIKE 'i$_nd_o'::mvarchar ESCAPE '$' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'i_dio'::mvarchar NOT LIKE 'i$_nd_o'::mvarchar ESCAPE '$' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'i_dio'::mvarchar LIKE 'i$_d%o'::mvarchar ESCAPE '$' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'i_dio'::mvarchar NOT LIKE 'i$_d%o'::mvarchar ESCAPE '$' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+-- escape character same as pattern character >X+SELECT 'maca'::mvarchar LIKE 'm%aca' ESCAPE '%'::mvarchar AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'maca'::mvarchar NOT LIKE 'm%aca' ESCAPE '%'::mvarchar AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'ma%a'::mvarchar LIKE 'm%a%%a' ESCAPE '%'::mvarchar AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'ma%a'::mvarchar NOT LIKE 'm%a%%a' ESCAPE '%'::mvarchar AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'bear'::mvarchar LIKE 'b_ear' ESCAPE '_'::mvarchar AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'bear'::mvarchar NOT LIKE 'b_ear'::mvarchar ESCAPE '_' AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'be_r'::mvarchar LIKE 'b_e__r' ESCAPE '_'::mvarchar AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'be_r'::mvarchar NOT LIKE 'b_e__r' ESCAPE '_'::mvarchar AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'be_r'::mvarchar LIKE '__e__r' ESCAPE '_'::mvarchar AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'be_r'::mvarchar NOT LIKE '__e__r'::mvarchar ESCAPE '_' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+-- similar to >X+SELECT 'abc'::mchar SIMILAR TO 'abc'::mchar AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'abc'::mchar SIMILAR TO 'a'::mchar AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'abc'::mchar SIMILAR TO '%(b|d)%'::mchar AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'abc'::mchar SIMILAR TO '(b|c)%'::mchar AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'h%'::mchar SIMILAR TO 'h#%'::mchar AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'h%'::mchar SIMILAR TO 'h#%'::mchar ESCAPE '#' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'abc'::mvarchar SIMILAR TO 'abc'::mvarchar AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'abc'::mvarchar SIMILAR TO 'a'::mvarchar AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'abc'::mvarchar SIMILAR TO '%(b|d)%'::mvarchar AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+SELECT 'abc'::mvarchar SIMILAR TO '(b|c)%'::mvarchar AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'h%'::mvarchar SIMILAR TO 'h#%'::mvarchar AS "false"; >X+ false >X+------- >X+ f >X+(1 row) >X+ >X+SELECT 'h%'::mvarchar SIMILAR TO 'h#%'::mvarchar ESCAPE '#' AS "true"; >X+ true >X+------ >X+ t >X+(1 row) >X+ >X+-- index support >X+SELECT * from ch where chcol like 'aB_d' order by chcol using &<; >X+ chcol >X+---------------------------------- >X+ AbcD >X+ abcd >X+(2 rows) >X+ >X+SELECT * from ch where chcol like 'aB%d' order by chcol using &<; >X+ chcol >X+---------------------------------- >X+ AbcD >X+ abcd >X+(2 rows) >X+ >X+SELECT * from ch where chcol like 'aB%' order by chcol using &<; >X+ chcol >X+---------------------------------- >X+ AbcD >X+ abcd >X+ abcz >X+(3 rows) >X+ >X+SELECT * from ch where chcol like '%BC%' order by chcol using &<; >X+ chcol >X+---------------------------------- >X+ AbcD >X+ abcd >X+ abcz >X+(3 rows) >X+ >X+set enable_seqscan = off; >X+SELECT * from ch where chcol like 'aB_d' order by chcol using &<; >X+ chcol >X+---------------------------------- >X+ AbcD >X+ abcd >X+(2 rows) >X+ >X+SELECT * from ch where chcol like 'aB%d' order by chcol using &<; >X+ chcol >X+---------------------------------- >X+ AbcD >X+ abcd >X+(2 rows) >X+ >X+SELECT * from ch where chcol like 'aB%' order by chcol using &<; >X+ chcol >X+---------------------------------- >X+ AbcD >X+ abcd >X+ abcz >X+(3 rows) >X+ >X+SELECT * from ch where chcol like '%BC%' order by chcol using &<; >X+ chcol >X+---------------------------------- >X+ AbcD >X+ abcd >X+ abcz >X+(3 rows) >X+ >X+set enable_seqscan = on; >X+create table testt (f1 mchar(10)); >X+insert into testt values ('Abc-000001'); >X+insert into testt values ('Abc-000002'); >X+insert into testt values ('0000000001'); >X+insert into testt values ('0000000002'); >X+select f1 from testt where f1::mvarchar like E'Abc\\-%'::mvarchar; >X+ f1 >X+------------ >X+ Abc-000001 >X+ Abc-000002 >X+(2 rows) >X+ >X+select * from testt where f1::mchar like E'Abc\\-%'::mchar; >X+ f1 >X+------------ >X+ Abc-000001 >X+ Abc-000002 >X+(2 rows) >X+ >X+create index testindex on testt(f1); >X+set enable_seqscan=off; >X+select f1 from testt where f1::mvarchar like E'Abc\\-%'::mvarchar; >X+ f1 >X+------------ >X+ Abc-000001 >X+ Abc-000002 >X+(2 rows) >X+ >X+select * from testt where f1::mchar like E'Abc\\-%'::mchar; >X+ f1 >X+------------ >X+ Abc-000001 >X+ Abc-000002 >X+(2 rows) >X+ >X+set enable_seqscan = on; >X+drop table testt; >X+create table testt (f1 mvarchar(10)); >X+insert into testt values ('Abc-000001'); >X+insert into testt values ('Abc-000002'); >X+insert into testt values ('0000000001'); >X+insert into testt values ('0000000002'); >X+select f1 from testt where f1::mvarchar like E'Abc\\-%'::mvarchar; >X+ f1 >X+------------ >X+ Abc-000001 >X+ Abc-000002 >X+(2 rows) >X+ >X+select * from testt where f1::mchar like E'Abc\\-%'::mchar; >X+ f1 >X+------------ >X+ Abc-000001 >X+ Abc-000002 >X+(2 rows) >X+ >X+select * from testt where f1::mchar like E'Abc\\- %'::mchar; >X+ f1 >X+------------ >X+ Abc-000001 >X+ Abc-000002 >X+(2 rows) >X+ >X+select * from testt where f1::mchar like E' %'::mchar; >X+ f1 >X+------------ >X+ Abc-000001 >X+ Abc-000002 >X+ 0000000001 >X+ 0000000002 >X+(4 rows) >X+ >X+create index testindex on testt(f1); >X+set enable_seqscan=off; >X+select f1 from testt where f1::mvarchar like E'Abc\\-%'::mvarchar; >X+ f1 >X+------------ >X+ Abc-000001 >X+ Abc-000002 >X+(2 rows) >X+ >X+select * from testt where f1::mchar like E'Abc\\-%'::mchar; >X+ f1 >X+------------ >X+ Abc-000001 >X+ Abc-000002 >X+(2 rows) >X+ >X+select * from testt where f1::mchar like E'Abc\\- %'::mchar; >X+ f1 >X+------------ >X+ Abc-000001 >X+ Abc-000002 >X+(2 rows) >X+ >X+select * from testt where f1::mchar like E' %'::mchar; >X+ f1 >X+------------ >X+ 0000000001 >X+ 0000000002 >X+ Abc-000001 >X+ Abc-000002 >X+(4 rows) >X+ >X+set enable_seqscan = on; >X+drop table testt; >X+CREATE TABLE test ( code mchar(5) NOT NULL ); >X+insert into test values('1111 '); >X+insert into test values('111 '); >X+insert into test values('11 '); >X+insert into test values('1 '); >X+SELECT * FROM test WHERE code LIKE ('% '); >X+ code >X+------- >X+ 1 >X+(1 row) >X+ >Xdiff --git a/contrib/mchar/expected/mchar.out b/contrib/mchar/expected/mchar.out >Xnew file mode 100644 >Xindex 0000000..c587424 >X--- /dev/null >X+++ contrib/mchar/expected/mchar.out >X@@ -0,0 +1,363 @@ >X+-- I/O tests >X+select '1'::mchar; >X+ mchar >X+------- >X+ 1 >X+(1 row) >X+ >X+select '2 '::mchar; >X+ mchar >X+------- >X+ 2 >X+(1 row) >X+ >X+select '10 '::mchar; >X+ mchar >X+------- >X+ 10 >X+(1 row) >X+ >X+select '1'::mchar(2); >X+ mchar >X+------- >X+ 1 >X+(1 row) >X+ >X+select '2 '::mchar(2); >X+ mchar >X+------- >X+ 2 >X+(1 row) >X+ >X+select '3 '::mchar(2); >X+ mchar >X+------- >X+ 3 >X+(1 row) >X+ >X+select '10 '::mchar(2); >X+ mchar >X+------- >X+ 10 >X+(1 row) >X+ >X+select ' '::mchar(10); >X+ mchar >X+------------ >X+ >X+(1 row) >X+ >X+select ' '::mchar; >X+ mchar >X+------- >X+ >X+(1 row) >X+ >X+-- operations & functions >X+select length('1'::mchar); >X+ length >X+-------- >X+ 1 >X+(1 row) >X+ >X+select length('2 '::mchar); >X+ length >X+-------- >X+ 1 >X+(1 row) >X+ >X+select length('10 '::mchar); >X+ length >X+-------- >X+ 2 >X+(1 row) >X+ >X+select length('1'::mchar(2)); >X+ length >X+-------- >X+ 1 >X+(1 row) >X+ >X+select length('2 '::mchar(2)); >X+ length >X+-------- >X+ 1 >X+(1 row) >X+ >X+select length('3 '::mchar(2)); >X+ length >X+-------- >X+ 1 >X+(1 row) >X+ >X+select length('10 '::mchar(2)); >X+ length >X+-------- >X+ 2 >X+(1 row) >X+ >X+select length(' '::mchar(10)); >X+ length >X+-------- >X+ 0 >X+(1 row) >X+ >X+select length(' '::mchar); >X+ length >X+-------- >X+ 0 >X+(1 row) >X+ >X+select 'asd'::mchar(10) || '>'::mchar(10); >X+ ?column? >X+---------------------- >X+ asd > >X+(1 row) >X+ >X+select length('asd'::mchar(10) || '>'::mchar(10)); >X+ length >X+-------- >X+ 11 >X+(1 row) >X+ >X+select 'asd'::mchar(2) || '>'::mchar(10); >X+ ?column? >X+-------------- >X+ as> >X+(1 row) >X+ >X+select length('asd'::mchar(2) || '>'::mchar(10)); >X+ length >X+-------- >X+ 3 >X+(1 row) >X+ >X+-- Comparisons >X+select 'asdf'::mchar = 'aSdf'::mchar; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mchar = 'aSdf '::mchar; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mchar = 'aSdf 1'::mchar(4); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mchar = 'aSdf 1'::mchar(5); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mchar = 'aSdf 1'::mchar(6); >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mchar(3) = 'aSdf 1'::mchar(5); >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mchar(3) = 'aSdf 1'::mchar(3); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mchar < 'aSdf'::mchar; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mchar < 'aSdf '::mchar; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mchar < 'aSdf 1'::mchar(4); >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mchar < 'aSdf 1'::mchar(5); >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mchar < 'aSdf 1'::mchar(6); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mchar <= 'aSdf'::mchar; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mchar <= 'aSdf '::mchar; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mchar <= 'aSdf 1'::mchar(4); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mchar <= 'aSdf 1'::mchar(5); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mchar <= 'aSdf 1'::mchar(6); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mchar >= 'aSdf'::mchar; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mchar >= 'aSdf '::mchar; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mchar >= 'aSdf 1'::mchar(4); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mchar >= 'aSdf 1'::mchar(5); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mchar >= 'aSdf 1'::mchar(6); >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mchar > 'aSdf'::mchar; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mchar > 'aSdf '::mchar; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mchar > 'aSdf 1'::mchar(4); >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mchar > 'aSdf 1'::mchar(5); >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mchar > 'aSdf 1'::mchar(6); >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select max(ch) from chvch; >X+ max >X+-------------- >X+ One space >X+(1 row) >X+ >X+select min(ch) from chvch; >X+ min >X+-------------- >X+ 1 space >X+(1 row) >X+ >X+select substr('1234567890'::mchar, 3) = '34567890' as "34567890"; >X+ 34567890 >X+---------- >X+ f >X+(1 row) >X+ >X+select substr('1234567890'::mchar, 4, 3) = '456' as "456"; >X+ 456 >X+----- >X+ t >X+(1 row) >X+ >X+select lower('asdfASDF'::mchar); >X+ lower >X+---------- >X+ asdfasdf >X+(1 row) >X+ >X+select upper('asdfASDF'::mchar); >X+ upper >X+---------- >X+ ASDFASDF >X+(1 row) >X+ >X+select 'asd'::mchar == 'aSd'::mchar; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asd'::mchar == 'aCd'::mchar; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asd'::mchar == NULL; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select NULL == 'aCd'::mchar; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select NULL::mchar == NULL; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >Xdiff --git a/contrib/mchar/expected/mm.out b/contrib/mchar/expected/mm.out >Xnew file mode 100644 >Xindex 0000000..fa2e924 >X--- /dev/null >X+++ contrib/mchar/expected/mm.out >X@@ -0,0 +1,805 @@ >X+select 'asd'::mchar::mvarchar; >X+ mvarchar >X+---------- >X+ asd >X+(1 row) >X+ >X+select 'asd '::mchar::mvarchar; >X+ mvarchar >X+---------- >X+ asd >X+(1 row) >X+ >X+select 'asd'::mchar(2)::mvarchar; >X+ mvarchar >X+---------- >X+ as >X+(1 row) >X+ >X+select 'asd '::mchar(2)::mvarchar; >X+ mvarchar >X+---------- >X+ as >X+(1 row) >X+ >X+select 'asd'::mchar(5)::mvarchar; >X+ mvarchar >X+---------- >X+ asd >X+(1 row) >X+ >X+select 'asd '::mchar(5)::mvarchar; >X+ mvarchar >X+---------- >X+ asd >X+(1 row) >X+ >X+select 'asd'::mchar::mvarchar(2); >X+ mvarchar >X+---------- >X+ as >X+(1 row) >X+ >X+select 'asd '::mchar::mvarchar(2); >X+ mvarchar >X+---------- >X+ as >X+(1 row) >X+ >X+select 'asd'::mchar(2)::mvarchar(2); >X+ mvarchar >X+---------- >X+ as >X+(1 row) >X+ >X+select 'asd '::mchar(2)::mvarchar(2); >X+ mvarchar >X+---------- >X+ as >X+(1 row) >X+ >X+select 'asd'::mchar(5)::mvarchar(2); >X+ mvarchar >X+---------- >X+ as >X+(1 row) >X+ >X+select 'asd '::mchar(5)::mvarchar(2); >X+ mvarchar >X+---------- >X+ as >X+(1 row) >X+ >X+select 'asd'::mchar::mvarchar(5); >X+ mvarchar >X+---------- >X+ asd >X+(1 row) >X+ >X+select 'asd '::mchar::mvarchar(5); >X+ mvarchar >X+---------- >X+ asd >X+(1 row) >X+ >X+select 'asd'::mchar(2)::mvarchar(5); >X+ mvarchar >X+---------- >X+ as >X+(1 row) >X+ >X+select 'asd '::mchar(2)::mvarchar(5); >X+ mvarchar >X+---------- >X+ as >X+(1 row) >X+ >X+select 'asd'::mchar(5)::mvarchar(5); >X+ mvarchar >X+---------- >X+ asd >X+(1 row) >X+ >X+select 'asd '::mchar(5)::mvarchar(5); >X+ mvarchar >X+---------- >X+ asd >X+(1 row) >X+ >X+select 'asd'::mvarchar::mchar; >X+ mchar >X+------- >X+ asd >X+(1 row) >X+ >X+select 'asd '::mvarchar::mchar; >X+ mchar >X+------- >X+ asd >X+(1 row) >X+ >X+select 'asd'::mvarchar(2)::mchar; >X+ mchar >X+------- >X+ as >X+(1 row) >X+ >X+select 'asd '::mvarchar(2)::mchar; >X+ mchar >X+------- >X+ as >X+(1 row) >X+ >X+select 'asd'::mvarchar(5)::mchar; >X+ mchar >X+------- >X+ asd >X+(1 row) >X+ >X+select 'asd '::mvarchar(5)::mchar; >X+ mchar >X+------- >X+ asd >X+(1 row) >X+ >X+select 'asd'::mvarchar::mchar(2); >X+ mchar >X+------- >X+ as >X+(1 row) >X+ >X+select 'asd '::mvarchar::mchar(2); >X+ mchar >X+------- >X+ as >X+(1 row) >X+ >X+select 'asd'::mvarchar(2)::mchar(2); >X+ mchar >X+------- >X+ as >X+(1 row) >X+ >X+select 'asd '::mvarchar(2)::mchar(2); >X+ mchar >X+------- >X+ as >X+(1 row) >X+ >X+select 'asd'::mvarchar(5)::mchar(2); >X+ mchar >X+------- >X+ as >X+(1 row) >X+ >X+select 'asd '::mvarchar(5)::mchar(2); >X+ mchar >X+------- >X+ as >X+(1 row) >X+ >X+select 'asd'::mvarchar::mchar(5); >X+ mchar >X+------- >X+ asd >X+(1 row) >X+ >X+select 'asd '::mvarchar::mchar(5); >X+ mchar >X+------- >X+ asd >X+(1 row) >X+ >X+select 'asd'::mvarchar(2)::mchar(5); >X+ mchar >X+------- >X+ as >X+(1 row) >X+ >X+select 'asd '::mvarchar(2)::mchar(5); >X+ mchar >X+------- >X+ as >X+(1 row) >X+ >X+select 'asd'::mvarchar(5)::mchar(5); >X+ mchar >X+------- >X+ asd >X+(1 row) >X+ >X+select 'asd '::mvarchar(5)::mchar(5); >X+ mchar >X+------- >X+ asd >X+(1 row) >X+ >X+select 'asd'::mchar || '123'; >X+ ?column? >X+---------- >X+ asd123 >X+(1 row) >X+ >X+select 'asd'::mchar || '123'::mchar; >X+ ?column? >X+---------- >X+ asd123 >X+(1 row) >X+ >X+select 'asd'::mchar || '123'::mvarchar; >X+ ?column? >X+---------- >X+ asd123 >X+(1 row) >X+ >X+select 'asd '::mchar || '123'; >X+ ?column? >X+---------- >X+ asd123 >X+(1 row) >X+ >X+select 'asd '::mchar || '123'::mchar; >X+ ?column? >X+---------- >X+ asd123 >X+(1 row) >X+ >X+select 'asd '::mchar || '123'::mvarchar; >X+ ?column? >X+---------- >X+ asd123 >X+(1 row) >X+ >X+select 'asd '::mchar || '123 '; >X+ ?column? >X+---------- >X+ asd123 >X+(1 row) >X+ >X+select 'asd '::mchar || '123 '::mchar; >X+ ?column? >X+---------- >X+ asd123 >X+(1 row) >X+ >X+select 'asd '::mchar || '123 '::mvarchar; >X+ ?column? >X+---------- >X+ asd123 >X+(1 row) >X+ >X+select 'asd'::mvarchar || '123'; >X+ ?column? >X+---------- >X+ asd123 >X+(1 row) >X+ >X+select 'asd'::mvarchar || '123'::mchar; >X+ ?column? >X+---------- >X+ asd123 >X+(1 row) >X+ >X+select 'asd'::mvarchar || '123'::mvarchar; >X+ ?column? >X+---------- >X+ asd123 >X+(1 row) >X+ >X+select 'asd '::mvarchar || '123'; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mvarchar || '123'::mchar; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mvarchar || '123'::mvarchar; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mvarchar || '123 '; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mvarchar || '123 '::mchar; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mvarchar || '123 '::mvarchar; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd'::mchar(2) || '123'; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd'::mchar(2) || '123'::mchar; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd'::mchar(2) || '123'::mvarchar; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd '::mchar(2) || '123'; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd '::mchar(2) || '123'::mchar; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd '::mchar(2) || '123'::mvarchar; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd '::mchar(2) || '123 '; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd '::mchar(2) || '123 '::mchar; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd '::mchar(2) || '123 '::mvarchar; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd'::mvarchar(2) || '123'; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd'::mvarchar(2) || '123'::mchar; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd'::mvarchar(2) || '123'::mvarchar; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd '::mvarchar(2) || '123'; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd '::mvarchar(2) || '123'::mchar; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd '::mvarchar(2) || '123'::mvarchar; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd '::mvarchar(2) || '123 '; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd '::mvarchar(2) || '123 '::mchar; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd '::mvarchar(2) || '123 '::mvarchar; >X+ ?column? >X+---------- >X+ as123 >X+(1 row) >X+ >X+select 'asd'::mchar(4) || '143'; >X+ ?column? >X+---------- >X+ asd 143 >X+(1 row) >X+ >X+select 'asd'::mchar(4) || '123'::mchar; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd'::mchar(4) || '123'::mvarchar; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mchar(4) || '123'; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mchar(4) || '123'::mchar; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mchar(4) || '123'::mvarchar; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mchar(4) || '123 '; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mchar(4) || '123 '::mchar; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mchar(4) || '123 '::mvarchar; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd'::mvarchar(4) || '123'; >X+ ?column? >X+---------- >X+ asd123 >X+(1 row) >X+ >X+select 'asd'::mvarchar(4) || '123'::mchar; >X+ ?column? >X+---------- >X+ asd123 >X+(1 row) >X+ >X+select 'asd'::mvarchar(4) || '123'::mvarchar; >X+ ?column? >X+---------- >X+ asd123 >X+(1 row) >X+ >X+select 'asd '::mvarchar(4) || '123'; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mvarchar(4) || '123'::mchar; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mvarchar(4) || '123'::mvarchar; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mvarchar(4) || '123 '; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mvarchar(4) || '123 '::mchar; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mvarchar(4) || '123 '::mvarchar; >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mvarchar(4) || '123 '::mchar(4); >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mvarchar(4) || '123 '::mvarchar(4); >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mvarchar(4) || '123'::mchar(4); >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 'asd '::mvarchar(4) || '123'::mvarchar(4); >X+ ?column? >X+---------- >X+ asd 123 >X+(1 row) >X+ >X+select 1 where 'f'::mchar='F'::mvarchar; >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'f'::mchar='F '::mvarchar; >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'f '::mchar='F'::mvarchar; >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'f '::mchar='F '::mvarchar; >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'f'::mchar='F'::mvarchar(2); >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'f'::mchar='F '::mvarchar(2); >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'f '::mchar='F'::mvarchar(2); >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'f '::mchar='F '::mvarchar(2); >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'f'::mchar(2)='F'::mvarchar; >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'f'::mchar(2)='F '::mvarchar; >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'f '::mchar(2)='F'::mvarchar; >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'f '::mchar(2)='F '::mvarchar; >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'f'::mchar(2)='F'::mvarchar(2); >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'f'::mchar(2)='F '::mvarchar(2); >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'f '::mchar(2)='F'::mvarchar(2); >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'f '::mchar(2)='F '::mvarchar(2); >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'foo'::mchar='FOO'::mvarchar; >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'foo'::mchar='FOO '::mvarchar; >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'foo '::mchar='FOO'::mvarchar; >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'foo '::mchar='FOO '::mvarchar; >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'foo'::mchar='FOO'::mvarchar(2); >X+ ?column? >X+---------- >X+(0 rows) >X+ >X+select 1 where 'foo'::mchar='FOO '::mvarchar(2); >X+ ?column? >X+---------- >X+(0 rows) >X+ >X+select 1 where 'foo '::mchar='FOO'::mvarchar(2); >X+ ?column? >X+---------- >X+(0 rows) >X+ >X+select 1 where 'foo '::mchar='FOO '::mvarchar(2); >X+ ?column? >X+---------- >X+(0 rows) >X+ >X+select 1 where 'foo'::mchar(2)='FOO'::mvarchar; >X+ ?column? >X+---------- >X+(0 rows) >X+ >X+select 1 where 'foo'::mchar(2)='FOO '::mvarchar; >X+ ?column? >X+---------- >X+(0 rows) >X+ >X+select 1 where 'foo '::mchar(2)='FOO'::mvarchar; >X+ ?column? >X+---------- >X+(0 rows) >X+ >X+select 1 where 'foo '::mchar(2)='FOO '::mvarchar; >X+ ?column? >X+---------- >X+(0 rows) >X+ >X+select 1 where 'foo'::mchar(2)='FOO'::mvarchar(2); >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'foo'::mchar(2)='FOO '::mvarchar(2); >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'foo '::mchar(2)='FOO'::mvarchar(2); >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+select 1 where 'foo '::mchar(2)='FOO '::mvarchar(2); >X+ ?column? >X+---------- >X+ 1 >X+(1 row) >X+ >X+Select 'f'::mchar(1) Union Select 'o'::mvarchar(1); >X+ mchar >X+------- >X+ f >X+ o >X+(2 rows) >X+ >X+Select 'f'::mvarchar(1) Union Select 'o'::mchar(1); >X+ mvarchar >X+---------- >X+ f >X+ o >X+(2 rows) >X+ >X+select * from chvch where ch=vch; >X+ ch | vch >X+--------------+------------ >X+ No spaces | No spaces >X+ One space | One space >X+ 1 space | 1 space >X+(3 rows) >X+ >X+select ch.* from ch, (select 'dEfg'::mvarchar as q) as p where chcol > p.q; >X+ chcol >X+---------------------------------- >X+ ee >X+ Ee >X+(2 rows) >X+ >X+create index qq on ch (chcol); >X+set enable_seqscan=off; >X+select ch.* from ch, (select 'dEfg'::mvarchar as q) as p where chcol > p.q; >X+ chcol >X+---------------------------------- >X+ ee >X+ Ee >X+(2 rows) >X+ >X+set enable_seqscan=on; >X+--\copy chvch to 'results/chvch.dump' binary >X+--truncate table chvch; >X+--\copy chvch from 'results/chvch.dump' binary >X+--test joins >X+CREATE TABLE a (mchar2 MCHAR(2) NOT NULL); >X+CREATE TABLE c (mvarchar255 mvarchar NOT NULL); >X+SELECT * FROM a, c WHERE mchar2 = mvarchar255; >X+ mchar2 | mvarchar255 >X+--------+------------- >X+(0 rows) >X+ >X+SELECT * FROM a, c WHERE mvarchar255 = mchar2; >X+ mchar2 | mvarchar255 >X+--------+------------- >X+(0 rows) >X+ >X+DROP TABLE a; >X+DROP TABLE c; >Xdiff --git a/contrib/mchar/expected/mvarchar.out b/contrib/mchar/expected/mvarchar.out >Xnew file mode 100644 >Xindex 0000000..5c866b4 >X--- /dev/null >X+++ contrib/mchar/expected/mvarchar.out >X@@ -0,0 +1,363 @@ >X+-- I/O tests >X+select '1'::mvarchar; >X+ mvarchar >X+---------- >X+ 1 >X+(1 row) >X+ >X+select '2 '::mvarchar; >X+ mvarchar >X+---------- >X+ 2 >X+(1 row) >X+ >X+select '10 '::mvarchar; >X+ mvarchar >X+-------------- >X+ 10 >X+(1 row) >X+ >X+select '1'::mvarchar(2); >X+ mvarchar >X+---------- >X+ 1 >X+(1 row) >X+ >X+select '2 '::mvarchar(2); >X+ mvarchar >X+---------- >X+ 2 >X+(1 row) >X+ >X+select '3 '::mvarchar(2); >X+ mvarchar >X+---------- >X+ 3 >X+(1 row) >X+ >X+select '10 '::mvarchar(2); >X+ mvarchar >X+---------- >X+ 10 >X+(1 row) >X+ >X+select ' '::mvarchar(10); >X+ mvarchar >X+------------ >X+ >X+(1 row) >X+ >X+select ' '::mvarchar; >X+ mvarchar >X+-------------------- >X+ >X+(1 row) >X+ >X+-- operations & functions >X+select length('1'::mvarchar); >X+ length >X+-------- >X+ 1 >X+(1 row) >X+ >X+select length('2 '::mvarchar); >X+ length >X+-------- >X+ 1 >X+(1 row) >X+ >X+select length('10 '::mvarchar); >X+ length >X+-------- >X+ 2 >X+(1 row) >X+ >X+select length('1'::mvarchar(2)); >X+ length >X+-------- >X+ 1 >X+(1 row) >X+ >X+select length('2 '::mvarchar(2)); >X+ length >X+-------- >X+ 1 >X+(1 row) >X+ >X+select length('3 '::mvarchar(2)); >X+ length >X+-------- >X+ 1 >X+(1 row) >X+ >X+select length('10 '::mvarchar(2)); >X+ length >X+-------- >X+ 2 >X+(1 row) >X+ >X+select length(' '::mvarchar(10)); >X+ length >X+-------- >X+ 0 >X+(1 row) >X+ >X+select length(' '::mvarchar); >X+ length >X+-------- >X+ 0 >X+(1 row) >X+ >X+select 'asd'::mvarchar(10) || '>'::mvarchar(10); >X+ ?column? >X+---------- >X+ asd> >X+(1 row) >X+ >X+select length('asd'::mvarchar(10) || '>'::mvarchar(10)); >X+ length >X+-------- >X+ 4 >X+(1 row) >X+ >X+select 'asd'::mvarchar(2) || '>'::mvarchar(10); >X+ ?column? >X+---------- >X+ as> >X+(1 row) >X+ >X+select length('asd'::mvarchar(2) || '>'::mvarchar(10)); >X+ length >X+-------- >X+ 3 >X+(1 row) >X+ >X+-- Comparisons >X+select 'asdf'::mvarchar = 'aSdf'::mvarchar; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mvarchar = 'aSdf '::mvarchar; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mvarchar = 'aSdf 1'::mvarchar(4); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mvarchar = 'aSdf 1'::mvarchar(5); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mvarchar = 'aSdf 1'::mvarchar(6); >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mvarchar(3) = 'aSdf 1'::mvarchar(5); >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mvarchar(3) = 'aSdf 1'::mvarchar(3); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mvarchar < 'aSdf'::mvarchar; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mvarchar < 'aSdf '::mvarchar; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mvarchar < 'aSdf 1'::mvarchar(4); >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mvarchar < 'aSdf 1'::mvarchar(5); >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mvarchar < 'aSdf 1'::mvarchar(6); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mvarchar <= 'aSdf'::mvarchar; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mvarchar <= 'aSdf '::mvarchar; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mvarchar <= 'aSdf 1'::mvarchar(4); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mvarchar <= 'aSdf 1'::mvarchar(5); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mvarchar <= 'aSdf 1'::mvarchar(6); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mvarchar >= 'aSdf'::mvarchar; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mvarchar >= 'aSdf '::mvarchar; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mvarchar >= 'aSdf 1'::mvarchar(4); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mvarchar >= 'aSdf 1'::mvarchar(5); >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asdf'::mvarchar >= 'aSdf 1'::mvarchar(6); >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mvarchar > 'aSdf'::mvarchar; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mvarchar > 'aSdf '::mvarchar; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mvarchar > 'aSdf 1'::mvarchar(4); >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mvarchar > 'aSdf 1'::mvarchar(5); >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asdf'::mvarchar > 'aSdf 1'::mvarchar(6); >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select max(vch) from chvch; >X+ max >X+------------ >X+ One space >X+(1 row) >X+ >X+select min(vch) from chvch; >X+ min >X+---------- >X+ 1 space >X+(1 row) >X+ >X+select substr('1234567890'::mvarchar, 3) = '34567890' as "34567890"; >X+ 34567890 >X+---------- >X+ f >X+(1 row) >X+ >X+select substr('1234567890'::mvarchar, 4, 3) = '456' as "456"; >X+ 456 >X+----- >X+ t >X+(1 row) >X+ >X+select lower('asdfASDF'::mvarchar); >X+ lower >X+---------- >X+ asdfasdf >X+(1 row) >X+ >X+select upper('asdfASDF'::mvarchar); >X+ upper >X+---------- >X+ ASDFASDF >X+(1 row) >X+ >X+select 'asd'::mvarchar == 'aSd'::mvarchar; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >X+select 'asd'::mvarchar == 'aCd'::mvarchar; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select 'asd'::mvarchar == NULL; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select NULL == 'aCd'::mvarchar; >X+ ?column? >X+---------- >X+ f >X+(1 row) >X+ >X+select NULL::mvarchar == NULL; >X+ ?column? >X+---------- >X+ t >X+(1 row) >X+ >Xdiff --git a/contrib/mchar/mchar.h b/contrib/mchar/mchar.h >Xnew file mode 100644 >Xindex 0000000..9e48500 >X--- /dev/null >X+++ contrib/mchar/mchar.h >X@@ -0,0 +1,63 @@ >X+#ifndef __MCHAR_H__ >X+#define __MCHAR_H__ >X+ >X+#include "postgres.h" >X+#include "mb/pg_wchar.h" >X+#include "utils/builtins.h" >X+#include "unicode/uchar.h" >X+#include "unicode/ustring.h" >X+ >X+ >X+typedef struct { >X+ int4 len; >X+ int4 typmod; >X+ UChar data[1]; >X+} MChar; >X+ >X+#define MCHARHDRSZ offsetof(MChar, data) >X+#define MCHARLENGTH(m) ( VARSIZE(m)-MCHARHDRSZ ) >X+#define UCHARLENGTH(m) ( MCHARLENGTH(m)/sizeof(UChar) ) >X+ >X+#define DatumGetMChar(m) ((MChar*)DatumGetPointer(m)) >X+#define MCharGetDatum(m) PointerGetDatum(m) >X+ >X+#define PG_GETARG_MCHAR(n) DatumGetMChar(PG_DETOAST_DATUM(PG_GETARG_DATUM(n))) >X+#define PG_GETARG_MCHAR_COPY(n) DatumGetMChar(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(n))) >X+ >X+#define PG_RETURN_MCHAR(m) PG_RETURN_POINTER(m) >X+ >X+typedef struct { >X+ int4 len; >X+ UChar data[1]; >X+} MVarChar; >X+ >X+#define MVARCHARHDRSZ offsetof(MVarChar, data) >X+#define MVARCHARLENGTH(m) ( VARSIZE(m)-MVARCHARHDRSZ ) >X+#define UVARCHARLENGTH(m) ( MVARCHARLENGTH(m)/sizeof(UChar) ) >X+ >X+#define DatumGetMVarChar(m) ((MVarChar*)DatumGetPointer(m)) >X+#define MVarCharGetDatum(m) PointerGetDatum(m) >X+ >X+#define PG_GETARG_MVARCHAR(n) DatumGetMVarChar(PG_DETOAST_DATUM(PG_GETARG_DATUM(n))) >X+#define PG_GETARG_MVARCHAR_COPY(n) DatumGetMVarChar(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(n))) >X+ >X+#define PG_RETURN_MVARCHAR(m) PG_RETURN_POINTER(m) >X+ >X+ >X+int Char2UChar(const char * src, int srclen, UChar *dst); >X+int UChar2Char(const UChar * src, int srclen, char *dst); >X+int UChar2Wchar(UChar * src, int srclen, pg_wchar *dst); >X+int UCharCompare(UChar * a, int alen, UChar *b, int blen); >X+int UCharCaseCompare(UChar * a, int alen, UChar *b, int blen); >X+ >X+void FillWhiteSpace( UChar *dst, int n ); >X+ >X+int lengthWithoutSpaceVarChar(MVarChar *m); >X+int lengthWithoutSpaceChar(MChar *m); >X+ >X+extern Datum mchar_hash(PG_FUNCTION_ARGS); >X+extern Datum mvarchar_hash(PG_FUNCTION_ARGS); >X+ >X+int m_isspace(UChar c); /* is == ' ' */ >X+ >X+#endif >Xdiff --git a/contrib/mchar/mchar.sql.in b/contrib/mchar/mchar.sql.in >Xnew file mode 100644 >Xindex 0000000..b5ef4e6 >X--- /dev/null >X+++ contrib/mchar/mchar.sql.in >X@@ -0,0 +1,1328 @@ >X+SET search_path = public; >X+ >X+BEGIN; >X+ >X+-- I/O functions >X+ >X+CREATE FUNCTION mchartypmod_in(cstring[]) >X+RETURNS int4 >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchartypmod_out(int4) >X+RETURNS cstring >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_in(cstring) >X+RETURNS mchar >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_out(mchar) >X+RETURNS cstring >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_send(mchar) >X+RETURNS bytea >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_recv(internal) >X+RETURNS mchar >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE TYPE mchar ( >X+ INTERNALLENGTH = -1, >X+ INPUT = mchar_in, >X+ OUTPUT = mchar_out, >X+ TYPMOD_IN = mchartypmod_in, >X+ TYPMOD_OUT = mchartypmod_out, >X+ RECEIVE = mchar_recv, >X+ SEND = mchar_send, >X+ STORAGE = extended >X+); >X+ >X+CREATE FUNCTION mchar(mchar, integer, boolean) >X+RETURNS mchar >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE CAST (mchar as mchar) >X+WITH FUNCTION mchar(mchar, integer, boolean) as IMPLICIT; >X+ >X+CREATE FUNCTION mvarchar_in(cstring) >X+RETURNS mvarchar >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_out(mvarchar) >X+RETURNS cstring >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_send(mvarchar) >X+RETURNS bytea >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_recv(internal) >X+RETURNS mvarchar >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE TYPE mvarchar ( >X+ INTERNALLENGTH = -1, >X+ INPUT = mvarchar_in, >X+ OUTPUT = mvarchar_out, >X+ TYPMOD_IN = mchartypmod_in, >X+ TYPMOD_OUT = mchartypmod_out, >X+ RECEIVE = mvarchar_recv, >X+ SEND = mvarchar_send, >X+ STORAGE = extended >X+); >X+ >X+CREATE FUNCTION mvarchar(mvarchar, integer, boolean) >X+RETURNS mvarchar >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE CAST (mvarchar as mvarchar) >X+WITH FUNCTION mvarchar(mvarchar, integer, boolean) as IMPLICIT; >X+ >X+--Operations and functions >X+ >X+CREATE FUNCTION length(mchar) >X+RETURNS int4 >X+AS 'MODULE_PATHNAME', 'mchar_length' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION upper(mchar) >X+RETURNS mchar >X+AS 'MODULE_PATHNAME', 'mchar_upper' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION lower(mchar) >X+RETURNS mchar >X+AS 'MODULE_PATHNAME', 'mchar_lower' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_hash(mchar) >X+RETURNS int4 >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_concat(mchar, mchar) >X+RETURNS mchar >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE OPERATOR || ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mchar_concat >X+); >X+ >X+CREATE FUNCTION mchar_like(mchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_notlike(mchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE OPERATOR ~~ ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mchar_like, >X+ RESTRICT = likesel, >X+ JOIN = likejoinsel, >X+ NEGATOR = '!~~' >X+); >X+ >X+CREATE OPERATOR !~~ ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mchar_notlike, >X+ RESTRICT = nlikesel, >X+ JOIN = nlikejoinsel, >X+ NEGATOR = '~~' >X+); >X+ >X+CREATE FUNCTION mchar_regexeq(mchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_regexne(mchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE OPERATOR ~ ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mchar_regexeq, >X+ RESTRICT = regexeqsel, >X+ JOIN = regexeqjoinsel, >X+ NEGATOR = '!~' >X+); >X+ >X+CREATE OPERATOR !~ ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mchar_regexne, >X+ RESTRICT = regexnesel, >X+ JOIN = regexnejoinsel, >X+ NEGATOR = '~' >X+); >X+ >X+CREATE FUNCTION similar_escape(mchar, mchar) >X+RETURNS mchar >X+AS 'MODULE_PATHNAME', 'mchar_similar_escape' >X+LANGUAGE C IMMUTABLE; >X+ >X+CREATE FUNCTION length(mvarchar) >X+RETURNS int4 >X+AS 'MODULE_PATHNAME', 'mvarchar_length' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION upper(mvarchar) >X+RETURNS mvarchar >X+AS 'MODULE_PATHNAME', 'mvarchar_upper' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION lower(mvarchar) >X+RETURNS mvarchar >X+AS 'MODULE_PATHNAME', 'mvarchar_lower' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_hash(mvarchar) >X+RETURNS int4 >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_concat(mvarchar, mvarchar) >X+RETURNS mvarchar >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE OPERATOR || ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mvarchar_concat >X+); >X+ >X+CREATE FUNCTION mvarchar_like(mvarchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION like_escape(mvarchar, mvarchar) >X+RETURNS mvarchar >X+AS 'MODULE_PATHNAME', 'mvarchar_like_escape' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_notlike(mvarchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE OPERATOR ~~ ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mvarchar_like, >X+ RESTRICT = likesel, >X+ JOIN = likejoinsel, >X+ NEGATOR = '!~~' >X+); >X+ >X+CREATE OPERATOR !~~ ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mvarchar_notlike, >X+ RESTRICT = nlikesel, >X+ JOIN = nlikejoinsel, >X+ NEGATOR = '~~' >X+); >X+ >X+CREATE FUNCTION mvarchar_regexeq(mvarchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_regexne(mvarchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE OPERATOR ~ ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mvarchar_regexeq, >X+ RESTRICT = regexeqsel, >X+ JOIN = regexeqjoinsel, >X+ NEGATOR = '!~' >X+); >X+ >X+CREATE OPERATOR !~ ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mvarchar_regexne, >X+ RESTRICT = regexnesel, >X+ JOIN = regexnejoinsel, >X+ NEGATOR = '~' >X+); >X+ >X+CREATE FUNCTION similar_escape(mvarchar, mvarchar) >X+RETURNS mvarchar >X+AS 'MODULE_PATHNAME', 'mvarchar_similar_escape' >X+LANGUAGE C IMMUTABLE; >X+ >X+CREATE FUNCTION substr (mchar, int4) >X+RETURNS mchar >X+AS 'MODULE_PATHNAME', 'mchar_substring_no_len' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION substr (mchar, int4, int4) >X+RETURNS mchar >X+AS 'MODULE_PATHNAME', 'mchar_substring' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION substr (mvarchar, int4) >X+RETURNS mvarchar >X+AS 'MODULE_PATHNAME', 'mvarchar_substring_no_len' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION substr (mvarchar, int4, int4) >X+RETURNS mvarchar >X+AS 'MODULE_PATHNAME', 'mvarchar_substring' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+-- Comparing >X+-- MCHAR >X+ >X+CREATE FUNCTION mchar_icase_cmp(mchar, mchar) >X+RETURNS int4 >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_icase_eq(mchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_icase_ne(mchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_icase_lt(mchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_icase_le(mchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_icase_gt(mchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_icase_ge(mchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+ >X+CREATE OPERATOR < ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mchar_icase_lt, >X+ COMMUTATOR = '>', >X+ NEGATOR = '>=', >X+ RESTRICT = scalarltsel, >X+ JOIN = scalarltjoinsel >X+); >X+ >X+CREATE OPERATOR > ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mchar_icase_gt, >X+ COMMUTATOR = '<', >X+ NEGATOR = '<=', >X+ RESTRICT = scalargtsel, >X+ JOIN = scalargtjoinsel >X+); >X+ >X+CREATE OPERATOR <= ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mchar_icase_le, >X+ COMMUTATOR = '>=', >X+ NEGATOR = '>', >X+ RESTRICT = scalarltsel, >X+ JOIN = scalarltjoinsel >X+); >X+ >X+CREATE OPERATOR >= ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mchar_icase_ge, >X+ COMMUTATOR = '<=', >X+ NEGATOR = '<', >X+ RESTRICT = scalargtsel, >X+ JOIN = scalargtjoinsel >X+); >X+ >X+CREATE OPERATOR = ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mchar_icase_eq, >X+ COMMUTATOR = '=', >X+ NEGATOR = '<>', >X+ RESTRICT = eqsel, >X+ JOIN = eqjoinsel, >X+ SORT1 = '<', >X+ SORT2 = '<', >X+ HASHES >X+); >X+ >X+CREATE OPERATOR <> ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mchar_icase_ne, >X+ COMMUTATOR = '<>', >X+ NEGATOR = '=', >X+ RESTRICT = neqsel, >X+ JOIN = neqjoinsel >X+); >X+ >X+CREATE FUNCTION mchar_case_cmp(mchar, mchar) >X+RETURNS int4 >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_case_eq(mchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_case_ne(mchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_case_lt(mchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_case_le(mchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_case_gt(mchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_case_ge(mchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+ >X+CREATE OPERATOR &< ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mchar_case_lt, >X+ COMMUTATOR = '&>', >X+ NEGATOR = '&>=', >X+ RESTRICT = scalarltsel, >X+ JOIN = scalarltjoinsel >X+); >X+ >X+CREATE OPERATOR &> ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mchar_case_gt, >X+ COMMUTATOR = '&<', >X+ NEGATOR = '&<=', >X+ RESTRICT = scalargtsel, >X+ JOIN = scalargtjoinsel >X+); >X+ >X+CREATE OPERATOR &<= ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mchar_case_le, >X+ COMMUTATOR = '&>=', >X+ NEGATOR = '&>', >X+ RESTRICT = scalarltsel, >X+ JOIN = scalarltjoinsel >X+); >X+ >X+CREATE OPERATOR &>= ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mchar_case_ge, >X+ COMMUTATOR = '&<=', >X+ NEGATOR = '&<', >X+ RESTRICT = scalargtsel, >X+ JOIN = scalargtjoinsel >X+); >X+ >X+CREATE OPERATOR &= ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mchar_case_eq, >X+ COMMUTATOR = '&=', >X+ NEGATOR = '&<>', >X+ RESTRICT = eqsel, >X+ JOIN = eqjoinsel, >X+ SORT1 = '&<', >X+ SORT2 = '&<' >X+); >X+ >X+CREATE OPERATOR &<> ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mchar_case_ne, >X+ COMMUTATOR = '&<>', >X+ NEGATOR = '&=', >X+ RESTRICT = neqsel, >X+ JOIN = neqjoinsel >X+); >X+ >X+--MVARCHAR >X+ >X+CREATE FUNCTION mvarchar_icase_cmp(mvarchar, mvarchar) >X+RETURNS int4 >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_icase_eq(mvarchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_icase_ne(mvarchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_icase_lt(mvarchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_icase_le(mvarchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_icase_gt(mvarchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_icase_ge(mvarchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+ >X+CREATE OPERATOR < ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mvarchar_icase_lt, >X+ COMMUTATOR = '>', >X+ NEGATOR = '>=', >X+ RESTRICT = scalarltsel, >X+ JOIN = scalarltjoinsel >X+); >X+ >X+CREATE OPERATOR > ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mvarchar_icase_gt, >X+ COMMUTATOR = '<', >X+ NEGATOR = '<=', >X+ RESTRICT = scalargtsel, >X+ JOIN = scalargtjoinsel >X+); >X+ >X+CREATE OPERATOR <= ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mvarchar_icase_le, >X+ COMMUTATOR = '>=', >X+ NEGATOR = '>', >X+ RESTRICT = scalarltsel, >X+ JOIN = scalarltjoinsel >X+); >X+ >X+CREATE OPERATOR >= ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mvarchar_icase_ge, >X+ COMMUTATOR = '<=', >X+ NEGATOR = '<', >X+ RESTRICT = scalargtsel, >X+ JOIN = scalargtjoinsel >X+); >X+ >X+CREATE OPERATOR = ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mvarchar_icase_eq, >X+ COMMUTATOR = '=', >X+ NEGATOR = '<>', >X+ RESTRICT = eqsel, >X+ JOIN = eqjoinsel, >X+ SORT1 = '<', >X+ SORT2 = '<', >X+ HASHES >X+); >X+ >X+CREATE OPERATOR <> ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mvarchar_icase_ne, >X+ COMMUTATOR = '<>', >X+ NEGATOR = '=', >X+ RESTRICT = neqsel, >X+ JOIN = neqjoinsel >X+); >X+ >X+CREATE FUNCTION mvarchar_case_cmp(mvarchar, mvarchar) >X+RETURNS int4 >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_case_eq(mvarchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_case_ne(mvarchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_case_lt(mvarchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_case_le(mvarchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_case_gt(mvarchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mvarchar_case_ge(mvarchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+ >X+CREATE OPERATOR &< ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mvarchar_case_lt, >X+ COMMUTATOR = '&>', >X+ NEGATOR = '&>=', >X+ RESTRICT = scalarltsel, >X+ JOIN = scalarltjoinsel >X+); >X+ >X+CREATE OPERATOR &> ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mvarchar_case_gt, >X+ COMMUTATOR = '&<', >X+ NEGATOR = '&<=', >X+ RESTRICT = scalargtsel, >X+ JOIN = scalargtjoinsel >X+); >X+ >X+CREATE OPERATOR &<= ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mvarchar_case_le, >X+ COMMUTATOR = '&>=', >X+ NEGATOR = '&>', >X+ RESTRICT = scalarltsel, >X+ JOIN = scalarltjoinsel >X+); >X+ >X+CREATE OPERATOR &>= ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mvarchar_case_ge, >X+ COMMUTATOR = '&<=', >X+ NEGATOR = '&<', >X+ RESTRICT = scalargtsel, >X+ JOIN = scalargtjoinsel >X+); >X+ >X+CREATE OPERATOR &= ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mvarchar_case_eq, >X+ COMMUTATOR = '&=', >X+ NEGATOR = '&<>', >X+ RESTRICT = eqsel, >X+ JOIN = eqjoinsel, >X+ SORT1 = '&<', >X+ SORT2 = '&<' >X+); >X+ >X+CREATE OPERATOR &<> ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mvarchar_case_ne, >X+ COMMUTATOR = '&<>', >X+ NEGATOR = '&=', >X+ RESTRICT = neqsel, >X+ JOIN = neqjoinsel >X+); >X+ >X+-- MCHAR <> MVARCHAR >X+ >X+CREATE FUNCTION mc_mv_icase_cmp(mchar, mvarchar) >X+RETURNS int4 >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mc_mv_icase_eq(mchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mc_mv_icase_ne(mchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mc_mv_icase_lt(mchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mc_mv_icase_le(mchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mc_mv_icase_gt(mchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mc_mv_icase_ge(mchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+ >X+CREATE OPERATOR < ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mc_mv_icase_lt, >X+ COMMUTATOR = '>', >X+ NEGATOR = '>=', >X+ RESTRICT = scalarltsel, >X+ JOIN = scalarltjoinsel >X+); >X+ >X+CREATE OPERATOR > ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mc_mv_icase_gt, >X+ COMMUTATOR = '<', >X+ NEGATOR = '<=', >X+ RESTRICT = scalargtsel, >X+ JOIN = scalargtjoinsel >X+); >X+ >X+CREATE OPERATOR <= ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mc_mv_icase_le, >X+ COMMUTATOR = '>=', >X+ NEGATOR = '>', >X+ RESTRICT = scalarltsel, >X+ JOIN = scalarltjoinsel >X+); >X+ >X+CREATE OPERATOR >= ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mc_mv_icase_ge, >X+ COMMUTATOR = '<=', >X+ NEGATOR = '<', >X+ RESTRICT = scalargtsel, >X+ JOIN = scalargtjoinsel >X+); >X+ >X+CREATE OPERATOR = ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mc_mv_icase_eq, >X+ COMMUTATOR = '=', >X+ NEGATOR = '<>', >X+ RESTRICT = eqsel, >X+ JOIN = eqjoinsel, >X+ SORT1 = '<', >X+ SORT2 = '<' >X+); >X+ >X+CREATE OPERATOR <> ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mc_mv_icase_ne, >X+ COMMUTATOR = '<>', >X+ NEGATOR = '=', >X+ RESTRICT = neqsel, >X+ JOIN = neqjoinsel >X+); >X+ >X+CREATE FUNCTION mc_mv_case_cmp(mchar, mvarchar) >X+RETURNS int4 >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mc_mv_case_eq(mchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mc_mv_case_ne(mchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mc_mv_case_lt(mchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mc_mv_case_le(mchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mc_mv_case_gt(mchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mc_mv_case_ge(mchar, mvarchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+ >X+CREATE OPERATOR &< ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mc_mv_case_lt, >X+ COMMUTATOR = '&>', >X+ NEGATOR = '&>=', >X+ RESTRICT = scalarltsel, >X+ JOIN = scalarltjoinsel >X+); >X+ >X+CREATE OPERATOR &> ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mc_mv_case_gt, >X+ COMMUTATOR = '&<', >X+ NEGATOR = '&<=', >X+ RESTRICT = scalargtsel, >X+ JOIN = scalargtjoinsel >X+); >X+ >X+CREATE OPERATOR &<= ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mc_mv_case_le, >X+ COMMUTATOR = '&>=', >X+ NEGATOR = '&>', >X+ RESTRICT = scalarltsel, >X+ JOIN = scalarltjoinsel >X+); >X+ >X+CREATE OPERATOR &>= ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mc_mv_case_ge, >X+ COMMUTATOR = '&<=', >X+ NEGATOR = '&<', >X+ RESTRICT = scalargtsel, >X+ JOIN = scalargtjoinsel >X+); >X+ >X+CREATE OPERATOR &= ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mc_mv_case_eq, >X+ COMMUTATOR = '&=', >X+ NEGATOR = '&<>', >X+ RESTRICT = eqsel, >X+ JOIN = eqjoinsel, >X+ SORT1 = '&<', >X+ SORT2 = '&<' >X+); >X+ >X+CREATE OPERATOR &<> ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mc_mv_case_ne, >X+ COMMUTATOR = '&<>', >X+ NEGATOR = '&=', >X+ RESTRICT = neqsel, >X+ JOIN = neqjoinsel >X+); >X+ >X+-- MVARCHAR <> MCHAR >X+ >X+CREATE FUNCTION mv_mc_icase_cmp(mvarchar, mchar) >X+RETURNS int4 >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mv_mc_icase_eq(mvarchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mv_mc_icase_ne(mvarchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mv_mc_icase_lt(mvarchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mv_mc_icase_le(mvarchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mv_mc_icase_gt(mvarchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mv_mc_icase_ge(mvarchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+ >X+CREATE OPERATOR < ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mv_mc_icase_lt, >X+ COMMUTATOR = '>', >X+ NEGATOR = '>=', >X+ RESTRICT = scalarltsel, >X+ JOIN = scalarltjoinsel >X+); >X+ >X+CREATE OPERATOR > ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mv_mc_icase_gt, >X+ COMMUTATOR = '<', >X+ NEGATOR = '<=', >X+ RESTRICT = scalargtsel, >X+ JOIN = scalargtjoinsel >X+); >X+ >X+CREATE OPERATOR <= ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mv_mc_icase_le, >X+ COMMUTATOR = '>=', >X+ NEGATOR = '>', >X+ RESTRICT = scalarltsel, >X+ JOIN = scalarltjoinsel >X+); >X+ >X+CREATE OPERATOR >= ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mv_mc_icase_ge, >X+ COMMUTATOR = '<=', >X+ NEGATOR = '<', >X+ RESTRICT = scalargtsel, >X+ JOIN = scalargtjoinsel >X+); >X+ >X+CREATE OPERATOR = ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mv_mc_icase_eq, >X+ COMMUTATOR = '=', >X+ NEGATOR = '<>', >X+ RESTRICT = eqsel, >X+ JOIN = eqjoinsel, >X+ SORT1 = '<', >X+ SORT2 = '<' >X+); >X+ >X+CREATE OPERATOR <> ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mv_mc_icase_ne, >X+ COMMUTATOR = '<>', >X+ NEGATOR = '=', >X+ RESTRICT = neqsel, >X+ JOIN = neqjoinsel >X+); >X+ >X+CREATE FUNCTION mv_mc_case_cmp(mvarchar, mchar) >X+RETURNS int4 >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mv_mc_case_eq(mvarchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mv_mc_case_ne(mvarchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mv_mc_case_lt(mvarchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mv_mc_case_le(mvarchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mv_mc_case_gt(mvarchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mv_mc_case_ge(mvarchar, mchar) >X+RETURNS bool >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+ >X+CREATE OPERATOR &< ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mv_mc_case_lt, >X+ COMMUTATOR = '&>', >X+ NEGATOR = '&>=', >X+ RESTRICT = scalarltsel, >X+ JOIN = scalarltjoinsel >X+); >X+ >X+CREATE OPERATOR &> ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mv_mc_case_gt, >X+ COMMUTATOR = '&<', >X+ NEGATOR = '&<=', >X+ RESTRICT = scalargtsel, >X+ JOIN = scalargtjoinsel >X+); >X+ >X+CREATE OPERATOR &<= ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mv_mc_case_le, >X+ COMMUTATOR = '&>=', >X+ NEGATOR = '&>', >X+ RESTRICT = scalarltsel, >X+ JOIN = scalarltjoinsel >X+); >X+ >X+CREATE OPERATOR &>= ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mv_mc_case_ge, >X+ COMMUTATOR = '&<=', >X+ NEGATOR = '&<', >X+ RESTRICT = scalargtsel, >X+ JOIN = scalargtjoinsel >X+); >X+ >X+CREATE OPERATOR &= ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mv_mc_case_eq, >X+ COMMUTATOR = '&=', >X+ NEGATOR = '&<>', >X+ RESTRICT = eqsel, >X+ JOIN = eqjoinsel, >X+ SORT1 = '&<', >X+ SORT2 = '&<' >X+); >X+ >X+CREATE OPERATOR &<> ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mv_mc_case_ne, >X+ COMMUTATOR = '&<>', >X+ NEGATOR = '&=', >X+ RESTRICT = neqsel, >X+ JOIN = neqjoinsel >X+); >X+ >X+-- MCHAR - VARCHAR operations >X+ >X+CREATE FUNCTION mchar_mvarchar_concat(mchar, mvarchar) >X+RETURNS mvarchar >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE OPERATOR || ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = mchar_mvarchar_concat >X+); >X+ >X+CREATE FUNCTION mvarchar_mchar_concat(mvarchar, mchar) >X+RETURNS mvarchar >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE OPERATOR || ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = mvarchar_mchar_concat >X+); >X+ >X+CREATE FUNCTION mvarchar_mchar(mvarchar, integer, boolean) >X+RETURNS mchar >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE CAST (mvarchar as mchar) >X+WITH FUNCTION mvarchar_mchar(mvarchar, integer, boolean) as IMPLICIT; >X+ >X+CREATE FUNCTION mchar_mvarchar(mchar, integer, boolean) >X+RETURNS mvarchar >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE CAST (mchar as mvarchar) >X+WITH FUNCTION mchar_mvarchar(mchar, integer, boolean) as IMPLICIT; >X+ >X+-- Aggregates >X+ >X+CREATE FUNCTION mchar_larger(mchar, mchar) >X+RETURNS mchar >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE AGGREGATE max ( >X+ BASETYPE = mchar, >X+ SFUNC = mchar_larger, >X+ STYPE = mchar, >X+ SORTOP = '>' >X+); >X+ >X+CREATE FUNCTION mchar_smaller(mchar, mchar) >X+RETURNS mchar >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE AGGREGATE min ( >X+ BASETYPE = mchar, >X+ SFUNC = mchar_smaller, >X+ STYPE = mchar, >X+ SORTOP = '<' >X+); >X+ >X+CREATE FUNCTION mvarchar_larger(mvarchar, mvarchar) >X+RETURNS mvarchar >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE AGGREGATE max ( >X+ BASETYPE = mvarchar, >X+ SFUNC = mvarchar_larger, >X+ STYPE = mvarchar, >X+ SORTOP = '>' >X+); >X+ >X+CREATE FUNCTION mvarchar_smaller(mvarchar, mvarchar) >X+RETURNS mvarchar >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE AGGREGATE min ( >X+ BASETYPE = mvarchar, >X+ SFUNC = mvarchar_smaller, >X+ STYPE = mvarchar, >X+ SORTOP = '<' >X+); >X+ >X+-- B-tree support >X+CREATE OPERATOR FAMILY icase_ops USING btree; >X+CREATE OPERATOR FAMILY case_ops USING btree; >X+ >X+CREATE OPERATOR CLASS mchar_icase_ops >X+DEFAULT FOR TYPE mchar USING btree FAMILY icase_ops AS >X+ OPERATOR 1 < , >X+ OPERATOR 2 <= , >X+ OPERATOR 3 = , >X+ OPERATOR 4 >= , >X+ OPERATOR 5 > , >X+ FUNCTION 1 mchar_icase_cmp(mchar, mchar), >X+ OPERATOR 1 < (mchar, mvarchar), >X+ OPERATOR 2 <= (mchar, mvarchar), >X+ OPERATOR 3 = (mchar, mvarchar), >X+ OPERATOR 4 >= (mchar, mvarchar), >X+ OPERATOR 5 > (mchar, mvarchar), >X+ FUNCTION 1 mc_mv_icase_cmp(mchar, mvarchar); >X+ >X+CREATE OPERATOR CLASS mchar_case_ops >X+FOR TYPE mchar USING btree FAMILY case_ops AS >X+ OPERATOR 1 &< , >X+ OPERATOR 2 &<= , >X+ OPERATOR 3 &= , >X+ OPERATOR 4 &>= , >X+ OPERATOR 5 &> , >X+ FUNCTION 1 mchar_case_cmp(mchar, mchar), >X+ OPERATOR 1 &< (mchar, mvarchar), >X+ OPERATOR 2 &<= (mchar, mvarchar), >X+ OPERATOR 3 &= (mchar, mvarchar), >X+ OPERATOR 4 &>= (mchar, mvarchar), >X+ OPERATOR 5 &> (mchar, mvarchar), >X+ FUNCTION 1 mc_mv_case_cmp(mchar, mvarchar); >X+ >X+CREATE OPERATOR CLASS mchar_icase_ops >X+DEFAULT FOR TYPE mchar USING hash AS >X+ OPERATOR 1 = , >X+ FUNCTION 1 mchar_hash(mchar); >X+ >X+CREATE OPERATOR CLASS mvarchar_icase_ops >X+DEFAULT FOR TYPE mvarchar USING btree FAMILY icase_ops AS >X+ OPERATOR 1 < , >X+ OPERATOR 2 <= , >X+ OPERATOR 3 = , >X+ OPERATOR 4 >= , >X+ OPERATOR 5 > , >X+ FUNCTION 1 mvarchar_icase_cmp(mvarchar, mvarchar), >X+ OPERATOR 1 < (mvarchar, mchar), >X+ OPERATOR 2 <= (mvarchar, mchar), >X+ OPERATOR 3 = (mvarchar, mchar), >X+ OPERATOR 4 >= (mvarchar, mchar), >X+ OPERATOR 5 > (mvarchar, mchar), >X+ FUNCTION 1 mv_mc_icase_cmp(mvarchar, mchar); >X+ >X+CREATE OPERATOR CLASS mvarchar_case_ops >X+FOR TYPE mvarchar USING btree FAMILY case_ops AS >X+ OPERATOR 1 &< , >X+ OPERATOR 2 &<= , >X+ OPERATOR 3 &= , >X+ OPERATOR 4 &>= , >X+ OPERATOR 5 &> , >X+ FUNCTION 1 mvarchar_case_cmp(mvarchar, mvarchar), >X+ OPERATOR 1 &< (mvarchar, mchar), >X+ OPERATOR 2 &<= (mvarchar, mchar), >X+ OPERATOR 3 &= (mvarchar, mchar), >X+ OPERATOR 4 &>= (mvarchar, mchar), >X+ OPERATOR 5 &> (mvarchar, mchar), >X+ FUNCTION 1 mv_mc_case_cmp(mvarchar, mchar); >X+ >X+CREATE OPERATOR CLASS mvarchar_icase_ops >X+DEFAULT FOR TYPE mvarchar USING hash AS >X+ OPERATOR 1 = , >X+ FUNCTION 1 mvarchar_hash(mvarchar); >X+ >X+ >X+-- Index support for LIKE >X+ >X+CREATE FUNCTION mchar_pattern_fixed_prefix(internal, internal, internal) >X+RETURNS int4 >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE FUNCTION mchar_greaterstring(internal) >X+RETURNS internal >X+AS 'MODULE_PATHNAME' >X+LANGUAGE C IMMUTABLE RETURNS NULL ON NULL INPUT; >X+ >X+CREATE OR REPLACE FUNCTION isfulleq_mchar(mchar, mchar) >X+RETURNS bool AS 'MODULE_PATHNAME' >X+LANGUAGE C CALLED ON NULL INPUT IMMUTABLE; >X+ >X+CREATE OR REPLACE FUNCTION fullhash_mchar(mchar) >X+RETURNS int4 AS 'MODULE_PATHNAME' >X+LANGUAGE C CALLED ON NULL INPUT IMMUTABLE; >X+ >X+ >X+CREATE OPERATOR == ( >X+ LEFTARG = mchar, >X+ RIGHTARG = mchar, >X+ PROCEDURE = isfulleq_mchar, >X+ COMMUTATOR = '==', >X+ RESTRICT = eqsel, >X+ JOIN = eqjoinsel, >X+ HASHES >X+); >X+ >X+CREATE OPERATOR CLASS mchar_fill_ops >X+ FOR TYPE mchar USING hash AS >X+ OPERATOR 1 ==, >X+ FUNCTION 1 fullhash_mchar(mchar); >X+ >X+CREATE OR REPLACE FUNCTION isfulleq_mvarchar(mvarchar, mvarchar) >X+RETURNS bool AS 'MODULE_PATHNAME' >X+LANGUAGE C CALLED ON NULL INPUT IMMUTABLE; >X+ >X+CREATE OR REPLACE FUNCTION fullhash_mvarchar(mvarchar) >X+RETURNS int4 AS 'MODULE_PATHNAME' >X+LANGUAGE C CALLED ON NULL INPUT IMMUTABLE; >X+ >X+ >X+CREATE OPERATOR == ( >X+ LEFTARG = mvarchar, >X+ RIGHTARG = mvarchar, >X+ PROCEDURE = isfulleq_mvarchar, >X+ COMMUTATOR = '==', >X+ RESTRICT = eqsel, >X+ JOIN = eqjoinsel, >X+ HASHES >X+); >X+ >X+CREATE OPERATOR CLASS mvarchar_fill_ops >X+ FOR TYPE mvarchar USING hash AS >X+ OPERATOR 1 ==, >X+ FUNCTION 1 fullhash_mvarchar(mvarchar); >X+ >X+COMMIT; >X+SET search_path = public; >X+ >Xdiff --git a/contrib/mchar/mchar_io.c b/contrib/mchar/mchar_io.c >Xnew file mode 100644 >Xindex 0000000..70f63ce >X--- /dev/null >X+++ contrib/mchar/mchar_io.c >X@@ -0,0 +1,372 @@ >X+#include "mchar.h" >X+#include "mb/pg_wchar.h" >X+#include "fmgr.h" >X+#include "libpq/pqformat.h" >X+#include <utils/array.h> >X+ >X+#ifdef PG_MODULE_MAGIC >X+PG_MODULE_MAGIC; >X+#endif >X+ >X+PG_FUNCTION_INFO_V1(mchar_in); >X+Datum mchar_in(PG_FUNCTION_ARGS); >X+PG_FUNCTION_INFO_V1(mchar_out); >X+Datum mchar_out(PG_FUNCTION_ARGS); >X+PG_FUNCTION_INFO_V1(mchar); >X+Datum mchar(PG_FUNCTION_ARGS); >X+ >X+PG_FUNCTION_INFO_V1(mvarchar_in); >X+Datum mvarchar_in(PG_FUNCTION_ARGS); >X+PG_FUNCTION_INFO_V1(mvarchar_out); >X+Datum mvarchar_out(PG_FUNCTION_ARGS); >X+PG_FUNCTION_INFO_V1(mvarchar); >X+Datum mvarchar(PG_FUNCTION_ARGS); >X+ >X+PG_FUNCTION_INFO_V1(mchartypmod_in); >X+Datum mchartypmod_in(PG_FUNCTION_ARGS); >X+Datum >X+mchartypmod_in(PG_FUNCTION_ARGS) { >X+ ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0); >X+ int32 *tl; >X+ int n; >X+ >X+ tl = ArrayGetIntegerTypmods(ta, &n); >X+ >X+ if (n != 1) >X+ ereport(ERROR, >X+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE), >X+ errmsg("invalid type modifier"))); >X+ if (*tl < 1) >X+ ereport(ERROR, >X+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE), >X+ errmsg("length for type mchar/mvarchar must be at least 1"))); >X+ >X+ return *tl; >X+} >X+ >X+PG_FUNCTION_INFO_V1(mchartypmod_out); >X+Datum mchartypmod_out(PG_FUNCTION_ARGS); >X+Datum >X+mchartypmod_out(PG_FUNCTION_ARGS) { >X+ int32 typmod = PG_GETARG_INT32(0); >X+ char *res = (char *) palloc(64); >X+ >X+ if (typmod >0) >X+ snprintf(res, 64, "(%d)", (int) (typmod)); >X+ else >X+ *res = '\0'; >X+ >X+ PG_RETURN_CSTRING( res ); >X+} >X+ >X+static void >X+mchar_strip( MChar * m, int atttypmod ) { >X+ int maxlen; >X+ >X+ if ( atttypmod<=0 ) { >X+ atttypmod =-1; >X+ } else { >X+ int charlen = u_countChar32( m->data, UCHARLENGTH(m) ); >X+ >X+ if ( charlen > atttypmod ) { >X+ int i=0; >X+ U16_FWD_N( m->data, i, UCHARLENGTH(m), atttypmod); >X+ SET_VARSIZE( m, sizeof(UChar) * i + MCHARHDRSZ ); >X+ } >X+ } >X+ >X+ m->typmod = atttypmod; >X+ >X+ maxlen = UCHARLENGTH(m); >X+ while( maxlen>0 && m_isspace( m->data[ maxlen-1 ] ) ) >X+ maxlen--; >X+ >X+ SET_VARSIZE(m, sizeof(UChar) * maxlen + MCHARHDRSZ); >X+} >X+ >X+ >X+Datum >X+mchar_in(PG_FUNCTION_ARGS) { >X+ char *s = PG_GETARG_CSTRING(0); >X+#ifdef NOT_USED >X+ Oid typelem = PG_GETARG_OID(1); >X+#endif >X+ int32 atttypmod = PG_GETARG_INT32(2); >X+ MChar *result; >X+ int4 slen = strlen(s), rlen; >X+ >X+ pg_verifymbstr(s, slen, false); >X+ >X+ result = (MChar*)palloc( MCHARHDRSZ + slen * sizeof(UChar) * 4 /* upper limit of length */ ); >X+ rlen = Char2UChar( s, slen, result->data ); >X+ SET_VARSIZE(result, sizeof(UChar) * rlen + MCHARHDRSZ); >X+ >X+ mchar_strip(result, atttypmod); >X+ >X+ PG_RETURN_MCHAR(result); >X+} >X+ >X+Datum >X+mchar_out(PG_FUNCTION_ARGS) { >X+ MChar *in = PG_GETARG_MCHAR(0); >X+ char *out; >X+ size_t size, inlen = UCHARLENGTH(in); >X+ size_t charlen = u_countChar32(in->data, inlen); >X+ >X+ Assert( in->typmod < 0 || charlen<=in->typmod ); >X+ size = ( in->typmod < 0 ) ? inlen : in->typmod; >X+ size *= pg_database_encoding_max_length(); >X+ >X+ out = (char*)palloc( size+1 ); >X+ size = UChar2Char( in->data, inlen, out ); >X+ >X+ if ( in->typmod>0 && charlen < in->typmod ) { >X+ memset( out+size, ' ', in->typmod - charlen); >X+ size += in->typmod - charlen; >X+ } >X+ >X+ out[size] = '\0'; >X+ >X+ PG_FREE_IF_COPY(in,0); >X+ >X+ PG_RETURN_CSTRING(out); >X+} >X+ >X+Datum >X+mchar(PG_FUNCTION_ARGS) { >X+ MChar *source = PG_GETARG_MCHAR(0); >X+ MChar *result; >X+ int32 typmod = PG_GETARG_INT32(1); >X+#ifdef NOT_USED >X+ bool isExplicit = PG_GETARG_BOOL(2); >X+#endif >X+ >X+ result = palloc( VARSIZE(source) ); >X+ memcpy( result, source, VARSIZE(source) ); >X+ PG_FREE_IF_COPY(source,0); >X+ >X+ mchar_strip(result, typmod); >X+ >X+ PG_RETURN_MCHAR(result); >X+} >X+ >X+Datum >X+mvarchar_in(PG_FUNCTION_ARGS) { >X+ char *s = PG_GETARG_CSTRING(0); >X+#ifdef NOT_USED >X+ Oid typelem = PG_GETARG_OID(1); >X+#endif >X+ int32 atttypmod = PG_GETARG_INT32(2); >X+ MVarChar *result; >X+ int4 slen = strlen(s), rlen; >X+ >X+ pg_verifymbstr(s, slen, false); >X+ >X+ result = (MVarChar*)palloc( MVARCHARHDRSZ + slen * sizeof(UChar) * 2 /* upper limit of length */ ); >X+ rlen = Char2UChar( s, slen, result->data ); >X+ SET_VARSIZE(result, sizeof(UChar) * rlen + MVARCHARHDRSZ); >X+ >X+ if ( atttypmod > 0 && atttypmod < u_countChar32(result->data, UVARCHARLENGTH(result)) ) >X+ elog(ERROR,"value too long for type mvarchar(%d)", atttypmod); >X+ >X+ PG_RETURN_MVARCHAR(result); >X+} >X+ >X+Datum >X+mvarchar_out(PG_FUNCTION_ARGS) { >X+ MVarChar *in = PG_GETARG_MVARCHAR(0); >X+ char *out; >X+ size_t size = UVARCHARLENGTH(in); >X+ >X+ size *= pg_database_encoding_max_length(); >X+ >X+ out = (char*)palloc( size+1 ); >X+ size = UChar2Char( in->data, UVARCHARLENGTH(in), out ); >X+ >X+ out[size] = '\0'; >X+ >X+ PG_FREE_IF_COPY(in,0); >X+ >X+ PG_RETURN_CSTRING(out); >X+} >X+ >X+static void >X+mvarchar_strip(MVarChar *m, int atttypmod) { >X+ int charlen = u_countChar32(m->data, UVARCHARLENGTH(m)); >X+ >X+ if ( atttypmod>=0 && atttypmod < charlen ) { >X+ int i=0; >X+ U16_FWD_N( m->data, i, charlen, atttypmod); >X+ SET_VARSIZE(m, sizeof(UChar) * i + MVARCHARHDRSZ); >X+ } >X+} >X+ >X+Datum >X+mvarchar(PG_FUNCTION_ARGS) { >X+ MVarChar *source = PG_GETARG_MVARCHAR(0); >X+ MVarChar *result; >X+ int32 typmod = PG_GETARG_INT32(1); >X+ bool isExplicit = PG_GETARG_BOOL(2); >X+ int charlen = u_countChar32(source->data, UVARCHARLENGTH(source)); >X+ >X+ result = palloc( VARSIZE(source) ); >X+ memcpy( result, source, VARSIZE(source) ); >X+ PG_FREE_IF_COPY(source,0); >X+ >X+ if ( typmod>=0 && typmod < charlen ) { >X+ if ( isExplicit ) >X+ mvarchar_strip(result, typmod); >X+ else >X+ elog(ERROR,"value too long for type mvarchar(%d)", typmod); >X+ } >X+ >X+ PG_RETURN_MVARCHAR(result); >X+} >X+ >X+PG_FUNCTION_INFO_V1(mvarchar_mchar); >X+Datum mvarchar_mchar(PG_FUNCTION_ARGS); >X+Datum >X+mvarchar_mchar(PG_FUNCTION_ARGS) { >X+ MVarChar *source = PG_GETARG_MVARCHAR(0); >X+ MChar *result; >X+ int32 typmod = PG_GETARG_INT32(1); >X+#ifdef NOT_USED >X+ bool isExplicit = PG_GETARG_BOOL(2); >X+#endif >X+ >X+ result = palloc( MVARCHARLENGTH(source) + MCHARHDRSZ ); >X+ SET_VARSIZE(result, MVARCHARLENGTH(source) + MCHARHDRSZ); >X+ memcpy( result->data, source->data, MVARCHARLENGTH(source)); >X+ >X+ PG_FREE_IF_COPY(source,0); >X+ >X+ mchar_strip( result, typmod ); >X+ >X+ PG_RETURN_MCHAR(result); >X+} >X+ >X+PG_FUNCTION_INFO_V1(mchar_mvarchar); >X+Datum mchar_mvarchar(PG_FUNCTION_ARGS); >X+Datum >X+mchar_mvarchar(PG_FUNCTION_ARGS) { >X+ MChar *source = PG_GETARG_MCHAR(0); >X+ MVarChar *result; >X+ int32 typmod = PG_GETARG_INT32(1); >X+ int32 scharlen = u_countChar32(source->data, UCHARLENGTH(source)); >X+ int32 curlen = 0, maxcharlen; >X+#ifdef NOT_USED >X+ bool isExplicit = PG_GETARG_BOOL(2); >X+#endif >X+ >X+ maxcharlen = (source->typmod > 0) ? source->typmod : scharlen; >X+ >X+ result = palloc( MVARCHARHDRSZ + sizeof(UChar) * 2 * maxcharlen ); >X+ >X+ curlen = UCHARLENGTH( source ); >X+ if ( curlen > 0 ) >X+ memcpy( result->data, source->data, MCHARLENGTH(source) ); >X+ if ( source->typmod > 0 && scharlen < source->typmod ) { >X+ FillWhiteSpace( result->data + curlen, source->typmod-scharlen ); >X+ curlen += source->typmod-scharlen; >X+ } >X+ SET_VARSIZE(result, MVARCHARHDRSZ + curlen *sizeof(UChar)); >X+ >X+ PG_FREE_IF_COPY(source,0); >X+ >X+ mvarchar_strip( result, typmod ); >X+ >X+ PG_RETURN_MCHAR(result); >X+} >X+ >X+PG_FUNCTION_INFO_V1(mchar_send); >X+Datum mchar_send(PG_FUNCTION_ARGS); >X+Datum >X+mchar_send(PG_FUNCTION_ARGS) { >X+ MChar *in = PG_GETARG_MCHAR(0); >X+ size_t inlen = UCHARLENGTH(in); >X+ size_t charlen = u_countChar32(in->data, inlen); >X+ StringInfoData buf; >X+ >X+ Assert( in->typmod < 0 || charlen<=in->typmod ); >X+ >X+ pq_begintypsend(&buf); >X+ pq_sendbytes(&buf, (char*)in->data, inlen * sizeof(UChar) ); >X+ >X+ if ( in->typmod>0 && charlen < in->typmod ) { >X+ int nw = in->typmod - charlen; >X+ UChar *white = palloc( sizeof(UChar) * nw ); >X+ >X+ FillWhiteSpace( white, nw ); >X+ pq_sendbytes(&buf, (char*)white, sizeof(UChar) * nw); >X+ pfree(white); >X+ } >X+ >X+ PG_FREE_IF_COPY(in,0); >X+ >X+ PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); >X+} >X+ >X+PG_FUNCTION_INFO_V1(mchar_recv); >X+Datum mchar_recv(PG_FUNCTION_ARGS); >X+Datum >X+mchar_recv(PG_FUNCTION_ARGS) { >X+ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); >X+ MChar *res; >X+ int nbytes; >X+#ifdef NOT_USED >X+ Oid typelem = PG_GETARG_OID(1); >X+#endif >X+ int32 atttypmod = PG_GETARG_INT32(2); >X+ >X+ nbytes = buf->len - buf->cursor; >X+ res = (MChar*)palloc( nbytes + MCHARHDRSZ ); >X+ res->len = nbytes + MCHARHDRSZ; >X+ res->typmod = -1; >X+ SET_VARSIZE(res, res->len); >X+ pq_copymsgbytes(buf, (char*)res->data, nbytes); >X+ >X+ mchar_strip( res, atttypmod ); >X+ >X+ PG_RETURN_MCHAR(res); >X+} >X+ >X+PG_FUNCTION_INFO_V1(mvarchar_send); >X+Datum mvarchar_send(PG_FUNCTION_ARGS); >X+Datum >X+mvarchar_send(PG_FUNCTION_ARGS) { >X+ MVarChar *in = PG_GETARG_MVARCHAR(0); >X+ size_t inlen = UVARCHARLENGTH(in); >X+ StringInfoData buf; >X+ >X+ pq_begintypsend(&buf); >X+ pq_sendbytes(&buf, (char*)in->data, inlen * sizeof(UChar) ); >X+ >X+ PG_FREE_IF_COPY(in,0); >X+ >X+ PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); >X+} >X+ >X+PG_FUNCTION_INFO_V1(mvarchar_recv); >X+Datum mvarchar_recv(PG_FUNCTION_ARGS); >X+Datum >X+mvarchar_recv(PG_FUNCTION_ARGS) { >X+ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); >X+ MVarChar *res; >X+ int nbytes; >X+#ifdef NOT_USED >X+ Oid typelem = PG_GETARG_OID(1); >X+#endif >X+ int32 atttypmod = PG_GETARG_INT32(2); >X+ >X+ nbytes = buf->len - buf->cursor; >X+ res = (MVarChar*)palloc( nbytes + MVARCHARHDRSZ ); >X+ res->len = nbytes + MVARCHARHDRSZ; >X+ SET_VARSIZE(res, res->len); >X+ pq_copymsgbytes(buf, (char*)res->data, nbytes); >X+ >X+ mvarchar_strip( res, atttypmod ); >X+ >X+ PG_RETURN_MVARCHAR(res); >X+} >X+ >X+ >Xdiff --git a/contrib/mchar/mchar_like.c b/contrib/mchar/mchar_like.c >Xnew file mode 100644 >Xindex 0000000..82f87a1 >X--- /dev/null >X+++ contrib/mchar/mchar_like.c >X@@ -0,0 +1,862 @@ >X+#include "mchar.h" >X+#include "mb/pg_wchar.h" >X+ >X+#include "catalog/pg_collation.h" >X+#include "utils/selfuncs.h" >X+#include "nodes/primnodes.h" >X+#include "nodes/makefuncs.h" >X+#include "regex/regex.h" >X+ >X+/* >X+** Originally written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986. >X+** Rich $alz is now <rsalz@bbn.com>. >X+** Special thanks to Lars Mathiesen <thorinn@diku.dk> for the LABORT code. >X+** >X+** This code was shamelessly stolen from the "pql" code by myself and >X+** slightly modified :) >X+** >X+** All references to the word "star" were replaced by "percent" >X+** All references to the word "wild" were replaced by "like" >X+** >X+** All the nice shell RE matching stuff was replaced by just "_" and "%" >X+** >X+** As I don't have a copy of the SQL standard handy I wasn't sure whether >X+** to leave in the '\' escape character handling. >X+** >X+** Keith Parks. <keith@mtcc.demon.co.uk> >X+** >X+** SQL92 lets you specify the escape character by saying >X+** LIKE <pattern> ESCAPE <escape character>. We are a small operation >X+** so we force you to use '\'. - ay 7/95 >X+** >X+** Now we have the like_escape() function that converts patterns with >X+** any specified escape character (or none at all) to the internal >X+** default escape character, which is still '\'. - tgl 9/2000 >X+** >X+** The code is rewritten to avoid requiring null-terminated strings, >X+** which in turn allows us to leave out some memcpy() operations. >X+** This code should be faster and take less memory, but no promises... >X+** - thomas 2000-08-06 >X+** >X+** Adopted for UTF-16 by teodor >X+*/ >X+ >X+#define LIKE_TRUE 1 >X+#define LIKE_FALSE 0 >X+#define LIKE_ABORT (-1) >X+ >X+ >X+static int >X+uchareq(UChar *p1, UChar *p2) { >X+ int l1=0, l2=0; >X+ /* >X+ * Count length of char: >X+ * We suppose that string is correct!! >X+ */ >X+ U16_FWD_1(p1, l1, 2); >X+ U16_FWD_1(p2, l2, 2); >X+ >X+ return (UCharCaseCompare(p1, l1, p2, l2)==0) ? 1 : 0; >X+} >X+ >X+#define NextChar(p, plen) \ >X+ do { \ >X+ int __l = 0; \ >X+ U16_FWD_1((p), __l, (plen));\ >X+ (p) +=__l; \ >X+ (plen) -=__l; \ >X+ } while(0) >X+ >X+#define CopyAdvChar(dst, src, srclen) \ >X+ do { \ >X+ int __l = 0; \ >X+ U16_FWD_1((src), __l, (srclen));\ >X+ (srclen) -= __l; \ >X+ while (__l-- > 0) \ >X+ *(dst)++ = *(src)++; \ >X+ } while (0) >X+ >X+ >X+static UChar UCharPercent = 0; >X+static UChar UCharBackSlesh = 0; >X+static UChar UCharUnderLine = 0; >X+static UChar UCharStar = 0; >X+static UChar UCharDotDot = 0; >X+static UChar UCharUp = 0; >X+static UChar UCharLBracket = 0; >X+static UChar UCharQ = 0; >X+static UChar UCharRBracket = 0; >X+static UChar UCharDollar = 0; >X+static UChar UCharDot = 0; >X+static UChar UCharLFBracket = 0; >X+static UChar UCharRFBracket = 0; >X+static UChar UCharQuote = 0; >X+static UChar UCharSpace = 0; >X+ >X+#define MkUChar(uc, c) do { \ >X+ char __c = (c); \ >X+ u_charsToUChars( &__c, &(uc), 1 ); \ >X+} while(0) >X+ >X+#define SET_UCHAR if ( UCharPercent == 0 ) { \ >X+ MkUChar( UCharPercent, '%' ); \ >X+ MkUChar( UCharBackSlesh, '\\' ); \ >X+ MkUChar( UCharUnderLine, '_' ); \ >X+ MkUChar( UCharStar, '*' ); \ >X+ MkUChar( UCharDotDot, ':' ); \ >X+ MkUChar( UCharUp, '^' ); \ >X+ MkUChar( UCharLBracket, '(' ); \ >X+ MkUChar( UCharQ, '?' ); \ >X+ MkUChar( UCharRBracket, ')' ); \ >X+ MkUChar( UCharDollar, '$' ); \ >X+ MkUChar( UCharDot, '.' ); \ >X+ MkUChar( UCharLFBracket, '{' ); \ >X+ MkUChar( UCharRFBracket, '}' ); \ >X+ MkUChar( UCharQuote, '"' ); \ >X+ MkUChar( UCharSpace, ' ' ); \ >X+ } >X+ >X+int >X+m_isspace(UChar c) { >X+ SET_UCHAR; >X+ >X+ return (c == UCharSpace); >X+} >X+ >X+static int >X+MatchUChar(UChar *t, int tlen, UChar *p, int plen) { >X+ SET_UCHAR; >X+ >X+ /* Fast path for match-everything pattern */ >X+ if ((plen == 1) && (*p == UCharPercent)) >X+ return LIKE_TRUE; >X+ >X+ while ((tlen > 0) && (plen > 0)) { >X+ if (*p == UCharBackSlesh) { >X+ /* Next pattern char must match literally, whatever it is */ >X+ NextChar(p, plen); >X+ if ((plen <= 0) || !uchareq(t, p)) >X+ return LIKE_FALSE; >X+ } else if (*p == UCharPercent) { >X+ /* %% is the same as % according to the SQL standard */ >X+ /* Advance past all %'s */ >X+ while ((plen > 0) && (*p == UCharPercent)) >X+ NextChar(p, plen); >X+ /* Trailing percent matches everything. */ >X+ if (plen <= 0) >X+ return LIKE_TRUE; >X+ >X+ /* >X+ * Otherwise, scan for a text position at which we can match the >X+ * rest of the pattern. >X+ */ >X+ while (tlen > 0) { >X+ /* >X+ * Optimization to prevent most recursion: don't recurse >X+ * unless first pattern char might match this text char. >X+ */ >X+ if (uchareq(t, p) || (*p == UCharBackSlesh) || (*p == UCharUnderLine)) { >X+ int matched = MatchUChar(t, tlen, p, plen); >X+ >X+ if (matched != LIKE_FALSE) >X+ return matched; /* TRUE or ABORT */ >X+ } >X+ >X+ NextChar(t, tlen); >X+ } >X+ >X+ /* >X+ * End of text with no match, so no point in trying later places >X+ * to start matching this pattern. >X+ */ >X+ return LIKE_ABORT; >X+ } if ((*p != UCharUnderLine) && !uchareq(t, p)) { >X+ /* >X+ * Not the single-character wildcard and no explicit match? Then >X+ * time to quit... >X+ */ >X+ return LIKE_FALSE; >X+ } >X+ >X+ NextChar(t, tlen); >X+ NextChar(p, plen); >X+ } >X+ >X+ if (tlen > 0) >X+ return LIKE_FALSE; /* end of pattern, but not of text */ >X+ >X+ /* End of input string. Do we have matching pattern remaining? */ >X+ while ((plen > 0) && (*p == UCharPercent)) /* allow multiple %'s at end of >X+ * pattern */ >X+ NextChar(p, plen); >X+ if (plen <= 0) >X+ return LIKE_TRUE; >X+ >X+ /* >X+ * End of text with no match, so no point in trying later places to start >X+ * matching this pattern. >X+ */ >X+ >X+ return LIKE_ABORT; >X+} >X+ >X+PG_FUNCTION_INFO_V1( mvarchar_like ); >X+Datum mvarchar_like( PG_FUNCTION_ARGS ); >X+Datum >X+mvarchar_like( PG_FUNCTION_ARGS ) { >X+ MVarChar *str = PG_GETARG_MVARCHAR(0); >X+ MVarChar *pat = PG_GETARG_MVARCHAR(1); >X+ bool result; >X+ >X+ result = MatchUChar( str->data, UVARCHARLENGTH(str), pat->data, UVARCHARLENGTH(pat) ); >X+ >X+ PG_FREE_IF_COPY(str,0); >X+ PG_FREE_IF_COPY(pat,1); >X+ >X+ PG_RETURN_BOOL(result == LIKE_TRUE); >X+} >X+ >X+PG_FUNCTION_INFO_V1( mvarchar_notlike ); >X+Datum mvarchar_notlike( PG_FUNCTION_ARGS ); >X+Datum >X+mvarchar_notlike( PG_FUNCTION_ARGS ) { >X+ bool res = DatumGetBool( DirectFunctionCall2( >X+ mvarchar_like, >X+ PG_GETARG_DATUM(0), >X+ PG_GETARG_DATUM(1) >X+ )); >X+ PG_RETURN_BOOL( !res ); >X+} >X+ >X+/* >X+ * Removes trailing spaces in '111 %' pattern >X+ */ >X+static UChar * >X+removeTrailingSpaces( UChar *src, int srclen, int *dstlen, bool *isSpecialLast) { >X+ UChar* dst = src; >X+ UChar *ptr, *dptr, *markptr; >X+ >X+ *dstlen = srclen; >X+ ptr = src + srclen-1; >X+ SET_UCHAR; >X+ >X+ *isSpecialLast = ( srclen > 0 && (u_isspace(*ptr) || *ptr == UCharPercent || *ptr == UCharUnderLine ) ) ? true : false; >X+ while( ptr>=src ) { >X+ if ( *ptr == UCharPercent || *ptr == UCharUnderLine ) { >X+ if ( ptr==src ) >X+ return dst; /* first character */ >X+ >X+ if ( *(ptr-1) == UCharBackSlesh ) >X+ return dst; /* use src as is */ >X+ >X+ if ( u_isspace( *(ptr-1) ) ) { >X+ ptr--; >X+ break; /* % or _ is after space which should be removed */ >X+ } >X+ } else { >X+ return dst; >X+ } >X+ ptr--; >X+ } >X+ >X+ markptr = ptr+1; >X+ dst = (UChar*)palloc( sizeof(UChar) * srclen ); >X+ >X+ /* find last non-space character */ >X+ while( ptr>=src && u_isspace(*ptr) ) >X+ ptr--; >X+ >X+ dptr = dst + (ptr-src+1); >X+ >X+ if ( ptr>=src ) >X+ memcpy( dst, src, sizeof(UChar) * (ptr-src+1) ); >X+ >X+ while( markptr - src < srclen ) { >X+ *dptr = *markptr; >X+ dptr++; >X+ markptr++; >X+ } >X+ >X+ *dstlen = dptr - dst; >X+ return dst; >X+} >X+ >X+static UChar* >X+addTrailingSpace( MChar *src, int *newlen ) { >X+ int scharlen = u_countChar32(src->data, UCHARLENGTH(src)); >X+ >X+ if ( src->typmod > scharlen ) { >X+ UChar *res = (UChar*) palloc( sizeof(UChar) * (UCHARLENGTH(src) + src->typmod) ); >X+ >X+ memcpy( res, src->data, sizeof(UChar) * UCHARLENGTH(src)); >X+ FillWhiteSpace( res+UCHARLENGTH(src), src->typmod - scharlen ); >X+ >X+ *newlen = src->typmod; >X+ >X+ return res; >X+ } else { >X+ *newlen = UCHARLENGTH(src); >X+ return src->data; >X+ } >X+} >X+ >X+PG_FUNCTION_INFO_V1( mchar_like ); >X+Datum mchar_like( PG_FUNCTION_ARGS ); >X+Datum >X+mchar_like( PG_FUNCTION_ARGS ) { >X+ MChar *str = PG_GETARG_MCHAR(0); >X+ MVarChar *pat = PG_GETARG_MVARCHAR(1); >X+ bool result, isNeedAdd = false; >X+ UChar *cleaned, *filled; >X+ int clen=0, flen=0; >X+ >X+ cleaned = removeTrailingSpaces(pat->data, UVARCHARLENGTH(pat), &clen, &isNeedAdd); >X+ if ( isNeedAdd ) >X+ filled = addTrailingSpace(str, &flen); >X+ else { >X+ filled = str->data; >X+ flen = UCHARLENGTH(str); >X+ } >X+ >X+ result = MatchUChar( filled, flen, cleaned, clen ); >X+ >X+ if ( pat->data != cleaned ) >X+ pfree( cleaned ); >X+ if ( str->data != filled ) >X+ pfree( filled ); >X+ >X+ PG_FREE_IF_COPY(str,0); >X+ PG_FREE_IF_COPY(pat,1); >X+ >X+ >X+ PG_RETURN_BOOL(result == LIKE_TRUE); >X+} >X+ >X+PG_FUNCTION_INFO_V1( mchar_notlike ); >X+Datum mchar_notlike( PG_FUNCTION_ARGS ); >X+Datum >X+mchar_notlike( PG_FUNCTION_ARGS ) { >X+ bool res = DatumGetBool( DirectFunctionCall2( >X+ mchar_like, >X+ PG_GETARG_DATUM(0), >X+ PG_GETARG_DATUM(1) >X+ )); >X+ >X+ PG_RETURN_BOOL( !res ); >X+} >X+ >X+ >X+ >X+PG_FUNCTION_INFO_V1( mchar_pattern_fixed_prefix ); >X+Datum mchar_pattern_fixed_prefix( PG_FUNCTION_ARGS ); >X+Datum >X+mchar_pattern_fixed_prefix( PG_FUNCTION_ARGS ) { >X+ Const *patt = (Const*)PG_GETARG_POINTER(0); >X+ Pattern_Type ptype = (Pattern_Type)PG_GETARG_INT32(1); >X+ Const **prefix = (Const**)PG_GETARG_POINTER(2); >X+ UChar *spatt; >X+ int4 slen, prefixlen=0, restlen=0, i=0; >X+ MVarChar *sprefix; >X+ MVarChar *srest; >X+ Pattern_Prefix_Status status = Pattern_Prefix_None; >X+ >X+ *prefix = NULL; >X+ >X+ if ( ptype != Pattern_Type_Like ) >X+ PG_RETURN_INT32(Pattern_Prefix_None); >X+ >X+ SET_UCHAR; >X+ >X+ spatt = ((MVarChar*)DatumGetPointer(patt->constvalue))->data; >X+ slen = UVARCHARLENGTH( DatumGetPointer(patt->constvalue) ); >X+ >X+ sprefix = (MVarChar*)palloc( MCHARHDRSZ /*The biggest hdr!! */ + sizeof(UChar) * slen ); >X+ srest = (MVarChar*)palloc( MCHARHDRSZ /*The biggest hdr!! */ + sizeof(UChar) * slen ); >X+ >X+ while( prefixlen < slen && i < slen ) { >X+ if ( spatt[i] == UCharPercent || spatt[i] == UCharUnderLine ) >X+ break; >X+ else if ( spatt[i] == UCharBackSlesh ) { >X+ i++; >X+ if ( i>= slen ) >X+ break; >X+ } >X+ sprefix->data[ prefixlen++ ] = spatt[i++]; >X+ } >X+ >X+ while( prefixlen > 0 ) { >X+ if ( ! u_isspace( sprefix->data[ prefixlen-1 ] ) ) >X+ break; >X+ prefixlen--; >X+ } >X+ >X+ if ( prefixlen == 0 ) >X+ PG_RETURN_INT32(Pattern_Prefix_None); >X+ >X+ for(;i<slen;i++) >X+ srest->data[ restlen++ ] = spatt[i]; >X+ >X+ SET_VARSIZE(sprefix, sizeof(UChar) * prefixlen + MVARCHARHDRSZ); >X+ SET_VARSIZE(srest, sizeof(UChar) * restlen + MVARCHARHDRSZ); >X+ >X+ *prefix = makeConst( patt->consttype, -1, DEFAULT_COLLATION_OID, VARSIZE(sprefix), PointerGetDatum(sprefix), false, false ); >X+ >X+ if ( prefixlen == slen ) /* in LIKE, an empty pattern is an exact match! */ >X+ status = Pattern_Prefix_Exact; >X+ else if ( prefixlen > 0 ) >X+ status = Pattern_Prefix_Partial; >X+ >X+ PG_RETURN_INT32( status ); >X+} >X+ >X+static bool >X+checkCmp( UChar *left, int32 leftlen, UChar *right, int32 rightlen ) { >X+ >X+ return (UCharCaseCompare( left, leftlen, right, rightlen) < 0 ) ? true : false; >X+} >X+ >X+ >X+PG_FUNCTION_INFO_V1( mchar_greaterstring ); >X+Datum mchar_greaterstring( PG_FUNCTION_ARGS ); >X+Datum >X+mchar_greaterstring( PG_FUNCTION_ARGS ) { >X+ Const *patt = (Const*)PG_GETARG_POINTER(0); >X+ char *src = (char*)DatumGetPointer( patt->constvalue ); >X+ int dstlen, srclen = VARSIZE(src); >X+ char *dst = palloc( srclen ); >X+ UChar *ptr, *srcptr; >X+ >X+ memcpy( dst, src, srclen ); >X+ >X+ srclen = dstlen = UVARCHARLENGTH( dst ); >X+ ptr = ((MVarChar*)dst)->data; >X+ srcptr = ((MVarChar*)src)->data; >X+ >X+ while( dstlen > 0 ) { >X+ UChar *lastchar = ptr + dstlen - 1; >X+ >X+ if ( !U16_IS_LEAD( *lastchar ) ) { >X+ while( *lastchar<0xffff ) { >X+ >X+ (*lastchar)++; >X+ >X+ if ( ublock_getCode(*lastchar) == UBLOCK_INVALID_CODE || !checkCmp( srcptr, srclen, ptr, dstlen ) ) >X+ continue; >X+ else { >X+ SET_VARSIZE(dst, sizeof(UChar) * dstlen + MVARCHARHDRSZ); >X+ >X+ PG_RETURN_POINTER( makeConst( patt->consttype, -1, DEFAULT_COLLATION_OID, VARSIZE(dst), PointerGetDatum(dst), false, false ) ); >X+ } >X+ } >X+ } >X+ >X+ dstlen--; >X+ } >X+ >X+ PG_RETURN_POINTER(NULL); >X+} >X+ >X+static int >X+do_like_escape( UChar *pat, int plen, UChar *esc, int elen, UChar *result) { >X+ UChar *p = pat,*e =esc ,*r; >X+ bool afterescape; >X+ >X+ r = result; >X+ SET_UCHAR; >X+ >X+ if ( elen == 0 ) { >X+ /* >X+ * No escape character is wanted. Double any backslashes in the >X+ * pattern to make them act like ordinary characters. >X+ */ >X+ while (plen > 0) { >X+ if (*p == UCharBackSlesh ) >X+ *r++ = UCharBackSlesh; >X+ CopyAdvChar(r, p, plen); >X+ } >X+ } else { >X+ /* >X+ * The specified escape must be only a single character. >X+ */ >X+ NextChar(e, elen); >X+ >X+ if (elen != 0) >X+ ereport(ERROR, >X+ (errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE), >X+ errmsg("invalid escape string"), >X+ errhint("Escape string must be empty or one character."))); >X+ >X+ e = esc; >X+ >X+ /* >X+ * If specified escape is '\', just copy the pattern as-is. >X+ */ >X+ if ( *e == UCharBackSlesh ) { >X+ memcpy(result, pat, plen * sizeof(UChar)); >X+ return plen; >X+ } >X+ >X+ /* >X+ * Otherwise, convert occurrences of the specified escape character to >X+ * '\', and double occurrences of '\' --- unless they immediately >X+ * follow an escape character! >X+ */ >X+ afterescape = false; >X+ >X+ while (plen > 0) { >X+ if ( uchareq(p,e) && !afterescape) { >X+ *r++ = UCharBackSlesh; >X+ NextChar(p, plen); >X+ afterescape = true; >X+ } else if ( *p == UCharBackSlesh ) { >X+ *r++ = UCharBackSlesh; >X+ if (!afterescape) >X+ *r++ = UCharBackSlesh; >X+ NextChar(p, plen); >X+ afterescape = false; >X+ } else { >X+ CopyAdvChar(r, p, plen); >X+ afterescape = false; >X+ } >X+ } >X+ } >X+ >X+ return ( r - result ); >X+} >X+ >X+PG_FUNCTION_INFO_V1( mvarchar_like_escape ); >X+Datum mvarchar_like_escape( PG_FUNCTION_ARGS ); >X+Datum >X+mvarchar_like_escape( PG_FUNCTION_ARGS ) { >X+ MVarChar *pat = PG_GETARG_MVARCHAR(0); >X+ MVarChar *esc = PG_GETARG_MVARCHAR(1); >X+ MVarChar *result; >X+ >X+ result = (MVarChar*)palloc( MVARCHARHDRSZ + sizeof(UChar)*2*UVARCHARLENGTH(pat) ); >X+ result->len = MVARCHARHDRSZ + do_like_escape( pat->data, UVARCHARLENGTH(pat), >X+ esc->data, UVARCHARLENGTH(esc), >X+ result->data ) * sizeof(UChar); >X+ >X+ SET_VARSIZE(result, result->len); >X+ PG_FREE_IF_COPY(pat,0); >X+ PG_FREE_IF_COPY(esc,1); >X+ >X+ PG_RETURN_MVARCHAR(result); >X+} >X+ >X+#define RE_CACHE_SIZE 32 >X+typedef struct ReCache { >X+ UChar *pattern; >X+ int length; >X+ int flags; >X+ regex_t re; >X+} ReCache; >X+ >X+static int num_res = 0; >X+static ReCache re_array[RE_CACHE_SIZE]; /* cached re's */ >X+static const int mchar_regex_flavor = REG_ADVANCED | REG_ICASE; >X+ >X+static regex_t * >X+RE_compile_and_cache(UChar *text_re, int text_re_len, int cflags) { >X+ pg_wchar *pattern; >X+ size_t pattern_len; >X+ int i; >X+ int regcomp_result; >X+ ReCache re_temp; >X+ char errMsg[128]; >X+ >X+ >X+ for (i = 0; i < num_res; i++) { >X+ if ( re_array[i].length == text_re_len && >X+ re_array[i].flags == cflags && >X+ memcmp(re_array[i].pattern, text_re, sizeof(UChar)*text_re_len) == 0 ) { >X+ >X+ /* Found, move it to front */ >X+ if ( i>0 ) { >X+ re_temp = re_array[i]; >X+ memmove(&re_array[1], &re_array[0], i * sizeof(ReCache)); >X+ re_array[0] = re_temp; >X+ } >X+ >X+ return &re_array[0].re; >X+ } >X+ } >X+ >X+ pattern = (pg_wchar *) palloc((1 + text_re_len) * sizeof(pg_wchar)); >X+ pattern_len = UChar2Wchar(text_re, text_re_len, pattern); >X+ >X+ regcomp_result = pg_regcomp(&re_temp.re, >X+ pattern, >X+ pattern_len, >X+ cflags, >X+ DEFAULT_COLLATION_OID); >X+ pfree( pattern ); >X+ >X+ if (regcomp_result != REG_OKAY) { >X+ pg_regerror(regcomp_result, &re_temp.re, errMsg, sizeof(errMsg)); >X+ ereport(ERROR, >X+ (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION), >X+ errmsg("invalid regular expression: %s", errMsg))); >X+ } >X+ >X+ re_temp.pattern = malloc( text_re_len*sizeof(UChar) ); >X+ if ( re_temp.pattern == NULL ) >X+ elog(ERROR,"Out of memory"); >X+ >X+ memcpy(re_temp.pattern, text_re, text_re_len*sizeof(UChar) ); >X+ re_temp.length = text_re_len; >X+ re_temp.flags = cflags; >X+ >X+ if (num_res >= RE_CACHE_SIZE) { >X+ --num_res; >X+ Assert(num_res < RE_CACHE_SIZE); >X+ pg_regfree(&re_array[num_res].re); >X+ free(re_array[num_res].pattern); >X+ } >X+ >X+ if (num_res > 0) >X+ memmove(&re_array[1], &re_array[0], num_res * sizeof(ReCache)); >X+ >X+ re_array[0] = re_temp; >X+ num_res++; >X+ >X+ return &re_array[0].re; >X+} >X+ >X+static bool >X+RE_compile_and_execute(UChar *pat, int pat_len, UChar *dat, int dat_len, >X+ int cflags, int nmatch, regmatch_t *pmatch) { >X+ pg_wchar *data; >X+ size_t data_len; >X+ int regexec_result; >X+ regex_t *re; >X+ char errMsg[128]; >X+ >X+ data = (pg_wchar *) palloc((1+dat_len) * sizeof(pg_wchar)); >X+ data_len = UChar2Wchar(dat, dat_len, data); >X+ >X+ re = RE_compile_and_cache(pat, pat_len, cflags); >X+ >X+ regexec_result = pg_regexec(re, >X+ data, >X+ data_len, >X+ 0, >X+ NULL, >X+ nmatch, >X+ pmatch, >X+ 0); >X+ pfree(data); >X+ >X+ if (regexec_result != REG_OKAY && regexec_result != REG_NOMATCH) { >X+ /* re failed??? */ >X+ pg_regerror(regexec_result, re, errMsg, sizeof(errMsg)); >X+ ereport(ERROR, >X+ (errcode(ERRCODE_INVALID_REGULAR_EXPRESSION), >X+ errmsg("regular expression failed: %s", errMsg))); >X+ } >X+ >X+ return (regexec_result == REG_OKAY); >X+} >X+ >X+PG_FUNCTION_INFO_V1( mchar_regexeq ); >X+Datum mchar_regexeq( PG_FUNCTION_ARGS ); >X+Datum >X+mchar_regexeq( PG_FUNCTION_ARGS ) { >X+ MChar *t = PG_GETARG_MCHAR(0); >X+ MChar *p = PG_GETARG_MCHAR(1); >X+ bool res; >X+ >X+ res = RE_compile_and_execute(p->data, UCHARLENGTH(p), >X+ t->data, UCHARLENGTH(t), >X+ mchar_regex_flavor, >X+ 0, NULL); >X+ PG_FREE_IF_COPY(t, 0); >X+ PG_FREE_IF_COPY(p, 1); >X+ >X+ PG_RETURN_BOOL(res); >X+} >X+ >X+PG_FUNCTION_INFO_V1( mchar_regexne ); >X+Datum mchar_regexne( PG_FUNCTION_ARGS ); >X+Datum >X+mchar_regexne( PG_FUNCTION_ARGS ) { >X+ MChar *t = PG_GETARG_MCHAR(0); >X+ MChar *p = PG_GETARG_MCHAR(1); >X+ bool res; >X+ >X+ res = RE_compile_and_execute(p->data, UCHARLENGTH(p), >X+ t->data, UCHARLENGTH(t), >X+ mchar_regex_flavor, >X+ 0, NULL); >X+ PG_FREE_IF_COPY(t, 0); >X+ PG_FREE_IF_COPY(p, 1); >X+ >X+ PG_RETURN_BOOL(!res); >X+} >X+ >X+PG_FUNCTION_INFO_V1( mvarchar_regexeq ); >X+Datum mvarchar_regexeq( PG_FUNCTION_ARGS ); >X+Datum >X+mvarchar_regexeq( PG_FUNCTION_ARGS ) { >X+ MVarChar *t = PG_GETARG_MVARCHAR(0); >X+ MVarChar *p = PG_GETARG_MVARCHAR(1); >X+ bool res; >X+ >X+ res = RE_compile_and_execute(p->data, UVARCHARLENGTH(p), >X+ t->data, UVARCHARLENGTH(t), >X+ mchar_regex_flavor, >X+ 0, NULL); >X+ PG_FREE_IF_COPY(t, 0); >X+ PG_FREE_IF_COPY(p, 1); >X+ >X+ PG_RETURN_BOOL(res); >X+} >X+ >X+PG_FUNCTION_INFO_V1( mvarchar_regexne ); >X+Datum mvarchar_regexne( PG_FUNCTION_ARGS ); >X+Datum >X+mvarchar_regexne( PG_FUNCTION_ARGS ) { >X+ MVarChar *t = PG_GETARG_MVARCHAR(0); >X+ MVarChar *p = PG_GETARG_MVARCHAR(1); >X+ bool res; >X+ >X+ res = RE_compile_and_execute(p->data, UVARCHARLENGTH(p), >X+ t->data, UVARCHARLENGTH(t), >X+ mchar_regex_flavor, >X+ 0, NULL); >X+ PG_FREE_IF_COPY(t, 0); >X+ PG_FREE_IF_COPY(p, 1); >X+ >X+ PG_RETURN_BOOL(!res); >X+} >X+ >X+static int >X+do_similar_escape(UChar *p, int plen, UChar *e, int elen, UChar *result) { >X+ UChar *r; >X+ bool afterescape = false; >X+ int nquotes = 0; >X+ >X+ SET_UCHAR; >X+ >X+ if (e==NULL || elen <0 ) { >X+ e = &UCharBackSlesh; >X+ elen = 1; >X+ } else { >X+ if ( elen == 0 ) >X+ e = NULL; >X+ else if ( elen != 1) >X+ ereport(ERROR, >X+ (errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE), >X+ errmsg("invalid escape string"), >X+ errhint("Escape string must be empty or one character."))); >X+ } >X+ >X+ /* >X+ * Look explanation of following in ./utils/adt/regexp.c >X+ */ >X+ r = result; >X+ >X+ *r++ = UCharStar; >X+ *r++ = UCharStar; >X+ *r++ = UCharStar; >X+ *r++ = UCharDotDot; >X+ *r++ = UCharUp; >X+ *r++ = UCharLBracket; >X+ *r++ = UCharQ; >X+ *r++ = UCharDotDot; >X+ >X+ while( plen>0 ) { >X+ if (afterescape) { >X+ if ( *p == UCharQuote ) { >X+ *r++ = ((nquotes++ % 2) == 0) ? UCharLBracket : UCharRBracket; >X+ } else { >X+ *r++ = UCharBackSlesh; >X+ *r++ = *p; >X+ } >X+ afterescape = false; >X+ } else if ( e && *p == *e ) { >X+ afterescape = true; >X+ } else if ( *p == UCharPercent ) { >X+ *r++ = UCharDot; >X+ *r++ = UCharStar; >X+ } else if ( *p == UCharUnderLine ) { >X+ *r++ = UCharDot; >X+ } else if ( *p == UCharBackSlesh || *p == UCharDot || *p == UCharQ || *p == UCharLFBracket ) { >X+ *r++ = UCharBackSlesh; >X+ *r++ = *p; >X+ } else >X+ *r++ = *p; >X+ >X+ p++, plen--; >X+ } >X+ >X+ *r++ = UCharRBracket; >X+ *r++ = UCharDollar; >X+ >X+ return r-result; >X+} >X+ >X+PG_FUNCTION_INFO_V1( mchar_similar_escape ); >X+Datum mchar_similar_escape( PG_FUNCTION_ARGS ); >X+Datum >X+mchar_similar_escape( PG_FUNCTION_ARGS ) { >X+ MChar *pat; >X+ MChar *esc; >X+ MChar *result; >X+ >X+ if (PG_ARGISNULL(0)) >X+ PG_RETURN_NULL(); >X+ pat = PG_GETARG_MCHAR(0); >X+ >X+ if (PG_ARGISNULL(1)) { >X+ esc = NULL; >X+ } else { >X+ esc = PG_GETARG_MCHAR(1); >X+ } >X+ >X+ result = (MChar*)palloc( MCHARHDRSZ + sizeof(UChar)*(10 + 2*UCHARLENGTH(pat)) ); >X+ result->len = MCHARHDRSZ + do_similar_escape( pat->data, UCHARLENGTH(pat), >X+ (esc) ? esc->data : NULL, (esc) ? UCHARLENGTH(esc) : -1, >X+ result->data ) * sizeof(UChar); >X+ result->typmod=-1; >X+ >X+ SET_VARSIZE(result, result->len); >X+ PG_FREE_IF_COPY(pat,0); >X+ if ( esc ) >X+ PG_FREE_IF_COPY(esc,1); >X+ >X+ PG_RETURN_MCHAR(result); >X+} >X+ >X+PG_FUNCTION_INFO_V1( mvarchar_similar_escape ); >X+Datum mvarchar_similar_escape( PG_FUNCTION_ARGS ); >X+Datum >X+mvarchar_similar_escape( PG_FUNCTION_ARGS ) { >X+ MVarChar *pat; >X+ MVarChar *esc; >X+ MVarChar *result; >X+ >X+ if (PG_ARGISNULL(0)) >X+ PG_RETURN_NULL(); >X+ pat = PG_GETARG_MVARCHAR(0); >X+ >X+ if (PG_ARGISNULL(1)) { >X+ esc = NULL; >X+ } else { >X+ esc = PG_GETARG_MVARCHAR(1); >X+ } >X+ >X+ result = (MVarChar*)palloc( MVARCHARHDRSZ + sizeof(UChar)*(10 + 2*UVARCHARLENGTH(pat)) ); >X+ result->len = MVARCHARHDRSZ + do_similar_escape( pat->data, UVARCHARLENGTH(pat), >X+ (esc) ? esc->data : NULL, (esc) ? UVARCHARLENGTH(esc) : -1, >X+ result->data ) * sizeof(UChar); >X+ >X+ SET_VARSIZE(result, result->len); >X+ PG_FREE_IF_COPY(pat,0); >X+ if ( esc ) >X+ PG_FREE_IF_COPY(esc,1); >X+ >X+ PG_RETURN_MVARCHAR(result); >X+} >X+ >X+#define RE_CACHE_SIZE 32 >Xdiff --git a/contrib/mchar/mchar_op.c b/contrib/mchar/mchar_op.c >Xnew file mode 100644 >Xindex 0000000..4694d9c >X--- /dev/null >X+++ contrib/mchar/mchar_op.c >X@@ -0,0 +1,449 @@ >X+#include "mchar.h" >X+ >X+int >X+lengthWithoutSpaceVarChar(MVarChar *m) { >X+ int l = UVARCHARLENGTH(m); >X+ >X+ while( l>0 && m_isspace( m->data[ l-1 ] ) ) >X+ l--; >X+ >X+ return l; >X+} >X+ >X+int >X+lengthWithoutSpaceChar(MChar *m) { >X+ int l = UCHARLENGTH(m); >X+ >X+ while( l>0 && m_isspace( m->data[ l-1 ] ) ) >X+ l--; >X+ >X+ return l; >X+} >X+ >X+static inline int >X+mchar_icase_compare( MChar *a, MChar *b ) { >X+ return UCharCaseCompare( >X+ a->data, lengthWithoutSpaceChar(a), >X+ b->data, lengthWithoutSpaceChar(b) >X+ ); >X+} >X+ >X+static inline int >X+mchar_case_compare( MChar *a, MChar *b ) { >X+ return UCharCompare( >X+ a->data, lengthWithoutSpaceChar(a), >X+ b->data, lengthWithoutSpaceChar(b) >X+ ); >X+} >X+ >X+#define MCHARCMPFUNC( c, type, action, ret ) \ >X+PG_FUNCTION_INFO_V1( mchar_##c##_##type ); \ >X+Datum mchar_##c##_##type(PG_FUNCTION_ARGS);\ >X+Datum \ >X+mchar_##c##_##type(PG_FUNCTION_ARGS) { \ >X+ MChar *a = PG_GETARG_MCHAR(0); \ >X+ MChar *b = PG_GETARG_MCHAR(1); \ >X+ int res = mchar_##c##_compare(a,b); \ >X+ \ >X+ PG_FREE_IF_COPY(a,0); \ >X+ PG_FREE_IF_COPY(b,1); \ >X+ PG_RETURN_##ret( res action 0 ); \ >X+} >X+ >X+ >X+MCHARCMPFUNC( case, eq, ==, BOOL ) >X+MCHARCMPFUNC( case, ne, !=, BOOL ) >X+MCHARCMPFUNC( case, lt, <, BOOL ) >X+MCHARCMPFUNC( case, le, <=, BOOL ) >X+MCHARCMPFUNC( case, ge, >=, BOOL ) >X+MCHARCMPFUNC( case, gt, >, BOOL ) >X+MCHARCMPFUNC( case, cmp, +, INT32 ) >X+ >X+MCHARCMPFUNC( icase, eq, ==, BOOL ) >X+MCHARCMPFUNC( icase, ne, !=, BOOL ) >X+MCHARCMPFUNC( icase, lt, <, BOOL ) >X+MCHARCMPFUNC( icase, le, <=, BOOL ) >X+MCHARCMPFUNC( icase, ge, >=, BOOL ) >X+MCHARCMPFUNC( icase, gt, >, BOOL ) >X+MCHARCMPFUNC( icase, cmp, +, INT32 ) >X+ >X+PG_FUNCTION_INFO_V1( mchar_larger ); >X+Datum mchar_larger( PG_FUNCTION_ARGS ); >X+Datum >X+mchar_larger( PG_FUNCTION_ARGS ) { >X+ MChar *a = PG_GETARG_MCHAR(0); >X+ MChar *b = PG_GETARG_MCHAR(1); >X+ MChar *r; >X+ >X+ r = ( mchar_icase_compare(a,b) > 0 ) ? a : b; >X+ >X+ PG_RETURN_MCHAR(r); >X+} >X+ >X+PG_FUNCTION_INFO_V1( mchar_smaller ); >X+Datum mchar_smaller( PG_FUNCTION_ARGS ); >X+Datum >X+mchar_smaller( PG_FUNCTION_ARGS ) { >X+ MChar *a = PG_GETARG_MCHAR(0); >X+ MChar *b = PG_GETARG_MCHAR(1); >X+ MChar *r; >X+ >X+ r = ( mchar_icase_compare(a,b) < 0 ) ? a : b; >X+ >X+ PG_RETURN_MCHAR(r); >X+} >X+ >X+ >X+PG_FUNCTION_INFO_V1( mchar_concat ); >X+Datum mchar_concat( PG_FUNCTION_ARGS ); >X+Datum >X+mchar_concat( PG_FUNCTION_ARGS ) { >X+ MChar *a = PG_GETARG_MCHAR(0); >X+ MChar *b = PG_GETARG_MCHAR(1); >X+ MChar *result; >X+ int maxcharlen, curlen; >X+ int acharlen = u_countChar32(a->data, UCHARLENGTH(a)), >X+ bcharlen = u_countChar32(b->data, UCHARLENGTH(b)); >X+ >X+ >X+ maxcharlen = ((a->typmod<=0) ? acharlen : a->typmod) + >X+ ((b->typmod<=0) ? bcharlen : b->typmod); >X+ >X+ result = (MChar*)palloc( MCHARHDRSZ + sizeof(UChar) * 2 * maxcharlen ); >X+ >X+ curlen = UCHARLENGTH( a ); >X+ if ( curlen > 0 ) >X+ memcpy( result->data, a->data, MCHARLENGTH(a) ); >X+ if ( a->typmod > 0 && acharlen < a->typmod ) { >X+ FillWhiteSpace( result->data + curlen, a->typmod-acharlen ); >X+ curlen += a->typmod-acharlen; >X+ } >X+ >X+ if ( UCHARLENGTH(b) > 0 ) { >X+ memcpy( result->data + curlen, b->data, MCHARLENGTH( b ) ); >X+ curlen += UCHARLENGTH( b ); >X+ } >X+ if ( b->typmod > 0 && bcharlen < b->typmod ) { >X+ FillWhiteSpace( result->data + curlen, b->typmod-bcharlen ); >X+ curlen += b->typmod-bcharlen; >X+ } >X+ >X+ >X+ result->typmod = -1; >X+ SET_VARSIZE(result, sizeof(UChar) * curlen + MCHARHDRSZ); >X+ >X+ PG_FREE_IF_COPY(a,0); >X+ PG_FREE_IF_COPY(b,1); >X+ >X+ PG_RETURN_MCHAR(result); >X+} >X+ >X+static inline int >X+mvarchar_icase_compare( MVarChar *a, MVarChar *b ) { >X+ >X+ return UCharCaseCompare( >X+ a->data, lengthWithoutSpaceVarChar(a), >X+ b->data, lengthWithoutSpaceVarChar(b) >X+ ); >X+} >X+ >X+static inline int >X+mvarchar_case_compare( MVarChar *a, MVarChar *b ) { >X+ return UCharCompare( >X+ a->data, lengthWithoutSpaceVarChar(a), >X+ b->data, lengthWithoutSpaceVarChar(b) >X+ ); >X+} >X+ >X+#define MVARCHARCMPFUNC( c, type, action, ret ) \ >X+PG_FUNCTION_INFO_V1( mvarchar_##c##_##type ); \ >X+Datum mvarchar_##c##_##type(PG_FUNCTION_ARGS); \ >X+Datum \ >X+mvarchar_##c##_##type(PG_FUNCTION_ARGS) { \ >X+ MVarChar *a = PG_GETARG_MVARCHAR(0); \ >X+ MVarChar *b = PG_GETARG_MVARCHAR(1); \ >X+ int res = mvarchar_##c##_compare(a,b); \ >X+ \ >X+ PG_FREE_IF_COPY(a,0); \ >X+ PG_FREE_IF_COPY(b,1); \ >X+ PG_RETURN_##ret( res action 0 ); \ >X+} >X+ >X+ >X+MVARCHARCMPFUNC( case, eq, ==, BOOL ) >X+MVARCHARCMPFUNC( case, ne, !=, BOOL ) >X+MVARCHARCMPFUNC( case, lt, <, BOOL ) >X+MVARCHARCMPFUNC( case, le, <=, BOOL ) >X+MVARCHARCMPFUNC( case, ge, >=, BOOL ) >X+MVARCHARCMPFUNC( case, gt, >, BOOL ) >X+MVARCHARCMPFUNC( case, cmp, +, INT32 ) >X+ >X+MVARCHARCMPFUNC( icase, eq, ==, BOOL ) >X+MVARCHARCMPFUNC( icase, ne, !=, BOOL ) >X+MVARCHARCMPFUNC( icase, lt, <, BOOL ) >X+MVARCHARCMPFUNC( icase, le, <=, BOOL ) >X+MVARCHARCMPFUNC( icase, ge, >=, BOOL ) >X+MVARCHARCMPFUNC( icase, gt, >, BOOL ) >X+MVARCHARCMPFUNC( icase, cmp, +, INT32 ) >X+ >X+PG_FUNCTION_INFO_V1( mvarchar_larger ); >X+Datum mvarchar_larger( PG_FUNCTION_ARGS ); >X+Datum >X+mvarchar_larger( PG_FUNCTION_ARGS ) { >X+ MVarChar *a = PG_GETARG_MVARCHAR(0); >X+ MVarChar *b = PG_GETARG_MVARCHAR(1); >X+ MVarChar *r; >X+ >X+ r = ( mvarchar_icase_compare(a,b) > 0 ) ? a : b; >X+ >X+ PG_RETURN_MVARCHAR(r); >X+} >X+ >X+PG_FUNCTION_INFO_V1( mvarchar_smaller ); >X+Datum mvarchar_smaller( PG_FUNCTION_ARGS ); >X+Datum >X+mvarchar_smaller( PG_FUNCTION_ARGS ) { >X+ MVarChar *a = PG_GETARG_MVARCHAR(0); >X+ MVarChar *b = PG_GETARG_MVARCHAR(1); >X+ MVarChar *r; >X+ >X+ r = ( mvarchar_icase_compare(a,b) < 0 ) ? a : b; >X+ >X+ PG_RETURN_MVARCHAR(r); >X+} >X+ >X+PG_FUNCTION_INFO_V1( mvarchar_concat ); >X+Datum mvarchar_concat( PG_FUNCTION_ARGS ); >X+Datum >X+mvarchar_concat( PG_FUNCTION_ARGS ) { >X+ MVarChar *a = PG_GETARG_MVARCHAR(0); >X+ MVarChar *b = PG_GETARG_MVARCHAR(1); >X+ MVarChar *result; >X+ int curlen; >X+ int acharlen = u_countChar32(a->data, UVARCHARLENGTH(a)), >X+ bcharlen = u_countChar32(b->data, UVARCHARLENGTH(b)); >X+ >X+ result = (MVarChar*)palloc( MVARCHARHDRSZ + sizeof(UChar) * 2 * (acharlen + bcharlen) ); >X+ >X+ curlen = UVARCHARLENGTH( a ); >X+ if ( curlen > 0 ) >X+ memcpy( result->data, a->data, MVARCHARLENGTH(a) ); >X+ >X+ if ( UVARCHARLENGTH(b) > 0 ) { >X+ memcpy( result->data + curlen, b->data, MVARCHARLENGTH( b ) ); >X+ curlen += UVARCHARLENGTH( b ); >X+ } >X+ >X+ SET_VARSIZE(result, sizeof(UChar) * curlen + MVARCHARHDRSZ); >X+ >X+ PG_FREE_IF_COPY(a,0); >X+ PG_FREE_IF_COPY(b,1); >X+ >X+ PG_RETURN_MVARCHAR(result); >X+} >X+ >X+PG_FUNCTION_INFO_V1( mchar_mvarchar_concat ); >X+Datum mchar_mvarchar_concat( PG_FUNCTION_ARGS ); >X+Datum >X+mchar_mvarchar_concat( PG_FUNCTION_ARGS ) { >X+ MChar *a = PG_GETARG_MCHAR(0); >X+ MVarChar *b = PG_GETARG_MVARCHAR(1); >X+ MVarChar *result; >X+ int curlen, maxcharlen; >X+ int acharlen = u_countChar32(a->data, UCHARLENGTH(a)), >X+ bcharlen = u_countChar32(b->data, UVARCHARLENGTH(b)); >X+ >X+ maxcharlen = ((a->typmod<=0) ? acharlen : a->typmod) + bcharlen; >X+ >X+ result = (MVarChar*)palloc( MVARCHARHDRSZ + sizeof(UChar) * 2 * maxcharlen ); >X+ >X+ curlen = UCHARLENGTH( a ); >X+ if ( curlen > 0 ) >X+ memcpy( result->data, a->data, MCHARLENGTH(a) ); >X+ if ( a->typmod > 0 && acharlen < a->typmod ) { >X+ FillWhiteSpace( result->data + curlen, a->typmod-acharlen ); >X+ curlen += a->typmod-acharlen; >X+ } >X+ >X+ if ( UVARCHARLENGTH(b) > 0 ) { >X+ memcpy( result->data + curlen, b->data, MVARCHARLENGTH( b ) ); >X+ curlen += UVARCHARLENGTH( b ); >X+ } >X+ >X+ SET_VARSIZE(result, sizeof(UChar) * curlen + MVARCHARHDRSZ); >X+ >X+ PG_FREE_IF_COPY(a,0); >X+ PG_FREE_IF_COPY(b,1); >X+ >X+ PG_RETURN_MVARCHAR(result); >X+} >X+ >X+PG_FUNCTION_INFO_V1( mvarchar_mchar_concat ); >X+Datum mvarchar_mchar_concat( PG_FUNCTION_ARGS ); >X+Datum >X+mvarchar_mchar_concat( PG_FUNCTION_ARGS ) { >X+ MVarChar *a = PG_GETARG_MVARCHAR(0); >X+ MChar *b = PG_GETARG_MCHAR(1); >X+ MVarChar *result; >X+ int curlen, maxcharlen; >X+ int acharlen = u_countChar32(a->data, UVARCHARLENGTH(a)), >X+ bcharlen = u_countChar32(b->data, UCHARLENGTH(b)); >X+ >X+ maxcharlen = acharlen + ((b->typmod<=0) ? bcharlen : b->typmod); >X+ >X+ result = (MVarChar*)palloc( MVARCHARHDRSZ + sizeof(UChar) * 2 * maxcharlen ); >X+ >X+ curlen = UVARCHARLENGTH( a ); >X+ if ( curlen > 0 ) >X+ memcpy( result->data, a->data, MVARCHARLENGTH(a) ); >X+ >X+ if ( UCHARLENGTH(b) > 0 ) { >X+ memcpy( result->data + curlen, b->data, MCHARLENGTH( b ) ); >X+ curlen += UCHARLENGTH( b ); >X+ } >X+ if ( b->typmod > 0 && bcharlen < b->typmod ) { >X+ FillWhiteSpace( result->data + curlen, b->typmod-bcharlen ); >X+ curlen += b->typmod-bcharlen; >X+ } >X+ >X+ SET_VARSIZE(result, sizeof(UChar) * curlen + MVARCHARHDRSZ); >X+ >X+ PG_FREE_IF_COPY(a,0); >X+ PG_FREE_IF_COPY(b,1); >X+ >X+ PG_RETURN_MVARCHAR(result); >X+} >X+ >X+/* >X+ * mchar <> mvarchar >X+ */ >X+static inline int >X+mc_mv_icase_compare( MChar *a, MVarChar *b ) { >X+ return UCharCaseCompare( >X+ a->data, lengthWithoutSpaceChar(a), >X+ b->data, lengthWithoutSpaceVarChar(b) >X+ ); >X+} >X+ >X+static inline int >X+mc_mv_case_compare( MChar *a, MVarChar *b ) { >X+ return UCharCompare( >X+ a->data, lengthWithoutSpaceChar(a), >X+ b->data, lengthWithoutSpaceVarChar(b) >X+ ); >X+} >X+ >X+#define MC_MV_CHARCMPFUNC( c, type, action, ret ) \ >X+PG_FUNCTION_INFO_V1( mc_mv_##c##_##type ); \ >X+Datum mc_mv_##c##_##type(PG_FUNCTION_ARGS);\ >X+Datum \ >X+mc_mv_##c##_##type(PG_FUNCTION_ARGS) { \ >X+ MChar *a = PG_GETARG_MCHAR(0); \ >X+ MVarChar *b = PG_GETARG_MVARCHAR(1); \ >X+ int res = mc_mv_##c##_compare(a,b); \ >X+ \ >X+ PG_FREE_IF_COPY(a,0); \ >X+ PG_FREE_IF_COPY(b,1); \ >X+ PG_RETURN_##ret( res action 0 ); \ >X+} >X+ >X+ >X+MC_MV_CHARCMPFUNC( case, eq, ==, BOOL ) >X+MC_MV_CHARCMPFUNC( case, ne, !=, BOOL ) >X+MC_MV_CHARCMPFUNC( case, lt, <, BOOL ) >X+MC_MV_CHARCMPFUNC( case, le, <=, BOOL ) >X+MC_MV_CHARCMPFUNC( case, ge, >=, BOOL ) >X+MC_MV_CHARCMPFUNC( case, gt, >, BOOL ) >X+MC_MV_CHARCMPFUNC( case, cmp, +, INT32 ) >X+ >X+MC_MV_CHARCMPFUNC( icase, eq, ==, BOOL ) >X+MC_MV_CHARCMPFUNC( icase, ne, !=, BOOL ) >X+MC_MV_CHARCMPFUNC( icase, lt, <, BOOL ) >X+MC_MV_CHARCMPFUNC( icase, le, <=, BOOL ) >X+MC_MV_CHARCMPFUNC( icase, ge, >=, BOOL ) >X+MC_MV_CHARCMPFUNC( icase, gt, >, BOOL ) >X+MC_MV_CHARCMPFUNC( icase, cmp, +, INT32 ) >X+ >X+/* >X+ * mvarchar <> mchar >X+ */ >X+static inline int >X+mv_mc_icase_compare( MVarChar *a, MChar *b ) { >X+ return UCharCaseCompare( >X+ a->data, lengthWithoutSpaceVarChar(a), >X+ b->data, lengthWithoutSpaceChar(b) >X+ ); >X+} >X+ >X+static inline int >X+mv_mc_case_compare( MVarChar *a, MChar *b ) { >X+ return UCharCompare( >X+ a->data, lengthWithoutSpaceVarChar(a), >X+ b->data, lengthWithoutSpaceChar(b) >X+ ); >X+} >X+ >X+#define MV_MC_CHARCMPFUNC( c, type, action, ret ) \ >X+PG_FUNCTION_INFO_V1( mv_mc_##c##_##type ); \ >X+Datum mv_mc_##c##_##type(PG_FUNCTION_ARGS);\ >X+Datum \ >X+mv_mc_##c##_##type(PG_FUNCTION_ARGS) { \ >X+ MVarChar *a = PG_GETARG_MVARCHAR(0); \ >X+ MChar *b = PG_GETARG_MCHAR(1); \ >X+ int res = mv_mc_##c##_compare(a,b); \ >X+ \ >X+ PG_FREE_IF_COPY(a,0); \ >X+ PG_FREE_IF_COPY(b,1); \ >X+ PG_RETURN_##ret( res action 0 ); \ >X+} >X+ >X+ >X+MV_MC_CHARCMPFUNC( case, eq, ==, BOOL ) >X+MV_MC_CHARCMPFUNC( case, ne, !=, BOOL ) >X+MV_MC_CHARCMPFUNC( case, lt, <, BOOL ) >X+MV_MC_CHARCMPFUNC( case, le, <=, BOOL ) >X+MV_MC_CHARCMPFUNC( case, ge, >=, BOOL ) >X+MV_MC_CHARCMPFUNC( case, gt, >, BOOL ) >X+MV_MC_CHARCMPFUNC( case, cmp, +, INT32 ) >X+ >X+MV_MC_CHARCMPFUNC( icase, eq, ==, BOOL ) >X+MV_MC_CHARCMPFUNC( icase, ne, !=, BOOL ) >X+MV_MC_CHARCMPFUNC( icase, lt, <, BOOL ) >X+MV_MC_CHARCMPFUNC( icase, le, <=, BOOL ) >X+MV_MC_CHARCMPFUNC( icase, ge, >=, BOOL ) >X+MV_MC_CHARCMPFUNC( icase, gt, >, BOOL ) >X+MV_MC_CHARCMPFUNC( icase, cmp, +, INT32 ) >X+ >X+#define NULLHASHVALUE (-2147483647) >X+ >X+#define FULLEQ_FUNC(type, cmpfunc, hashfunc) \ >X+PG_FUNCTION_INFO_V1( isfulleq_##type ); \ >X+Datum isfulleq_##type(PG_FUNCTION_ARGS); \ >X+Datum \ >X+isfulleq_##type(PG_FUNCTION_ARGS) { \ >X+ if ( PG_ARGISNULL(0) && PG_ARGISNULL(1) ) \ >X+ PG_RETURN_BOOL(true); \ >X+ else if ( PG_ARGISNULL(0) || PG_ARGISNULL(1) ) \ >X+ PG_RETURN_BOOL(false); \ >X+ \ >X+ PG_RETURN_DATUM( DirectFunctionCall2( cmpfunc, \ >X+ PG_GETARG_DATUM(0), \ >X+ PG_GETARG_DATUM(1) \ >X+ ) ); \ >X+} \ >X+ \ >X+PG_FUNCTION_INFO_V1( fullhash_##type ); \ >X+Datum fullhash_##type(PG_FUNCTION_ARGS); \ >X+Datum \ >X+fullhash_##type(PG_FUNCTION_ARGS) { \ >X+ if ( PG_ARGISNULL(0) ) \ >X+ PG_RETURN_INT32(NULLHASHVALUE); \ >X+ \ >X+ PG_RETURN_DATUM( DirectFunctionCall1( hashfunc, \ >X+ PG_GETARG_DATUM(0) \ >X+ ) ); \ >X+} >X+ >X+FULLEQ_FUNC( mchar, mchar_icase_eq, mchar_hash ); >X+FULLEQ_FUNC( mvarchar, mvarchar_icase_eq, mvarchar_hash ); >X+ >Xdiff --git a/contrib/mchar/mchar_proc.c b/contrib/mchar/mchar_proc.c >Xnew file mode 100644 >Xindex 0000000..54ef9d5 >X--- /dev/null >X+++ contrib/mchar/mchar_proc.c >X@@ -0,0 +1,339 @@ >X+#include "mchar.h" >X+#include "mb/pg_wchar.h" >X+#include "access/hash.h" >X+ >X+PG_FUNCTION_INFO_V1(mchar_length); >X+Datum mchar_length(PG_FUNCTION_ARGS); >X+ >X+Datum >X+mchar_length(PG_FUNCTION_ARGS) { >X+ MChar *m = PG_GETARG_MCHAR(0); >X+ int4 l = UCHARLENGTH(m); >X+ >X+ while( l>0 && m_isspace( m->data[ l-1 ] ) ) >X+ l--; >X+ >X+ l = u_countChar32(m->data, l); >X+ >X+ PG_FREE_IF_COPY(m,0); >X+ >X+ PG_RETURN_INT32(l); >X+} >X+ >X+PG_FUNCTION_INFO_V1(mvarchar_length); >X+Datum mvarchar_length(PG_FUNCTION_ARGS); >X+ >X+Datum >X+mvarchar_length(PG_FUNCTION_ARGS) { >X+ MVarChar *m = PG_GETARG_MVARCHAR(0); >X+ int4 l = UVARCHARLENGTH(m); >X+ >X+ while( l>0 && m_isspace( m->data[ l-1 ] ) ) >X+ l--; >X+ >X+ l = u_countChar32(m->data, l); >X+ >X+ PG_FREE_IF_COPY(m,0); >X+ >X+ PG_RETURN_INT32(l); >X+} >X+ >X+static int32 >X+uchar_substring( >X+ UChar *str, int32 strl, >X+ int32 start, int32 length, bool length_not_specified, >X+ UChar *dst) { >X+ int32 S = start-1; /* start position */ >X+ int32 S1; /* adjusted start position */ >X+ int32 L1; /* adjusted substring length */ >X+ int32 subbegin=0, subend=0; >X+ >X+ S1 = Max(S, 0); >X+ if (length_not_specified) >X+ L1 = -1; >X+ else { >X+ /* end position */ >X+ int32 E = S + length; >X+ >X+ /* >X+ * A negative value for L is the only way for the end position to >X+ * be before the start. SQL99 says to throw an error. >X+ */ >X+ >X+ if (E < S) >X+ ereport(ERROR, >X+ (errcode(ERRCODE_SUBSTRING_ERROR), >X+ errmsg("negative substring length not allowed"))); >X+ >X+ /* >X+ * A zero or negative value for the end position can happen if the >X+ * start was negative or one. SQL99 says to return a zero-length >X+ * string. >X+ */ >X+ if (E < 0) >X+ return 0; >X+ >X+ L1 = E - S1; >X+ } >X+ >X+ U16_FWD_N( str, subbegin, strl, S1 ); >X+ if ( subbegin >= strl ) >X+ return 0; >X+ subend = subbegin; >X+ U16_FWD_N( str, subend, strl, L1 ); >X+ >X+ memcpy( dst, str+subbegin, sizeof(UChar)*(subend-subbegin) ); >X+ >X+ return subend-subbegin; >X+} >X+ >X+PG_FUNCTION_INFO_V1(mchar_substring); >X+Datum mchar_substring(PG_FUNCTION_ARGS); >X+Datum >X+mchar_substring(PG_FUNCTION_ARGS) { >X+ MChar *src = PG_GETARG_MCHAR(0); >X+ MChar *dst; >X+ int32 length; >X+ >X+ dst = (MChar*)palloc( VARSIZE(src) ); >X+ length = uchar_substring( >X+ src->data, UCHARLENGTH(src), >X+ PG_GETARG_INT32(1), PG_GETARG_INT32(2), false, >X+ dst->data); >X+ >X+ dst->typmod = src->typmod; >X+ SET_VARSIZE(dst, MCHARHDRSZ + length *sizeof(UChar)); >X+ >X+ PG_FREE_IF_COPY(src, 0); >X+ PG_RETURN_MCHAR(dst); >X+} >X+ >X+PG_FUNCTION_INFO_V1(mchar_substring_no_len); >X+Datum mchar_substring_no_len(PG_FUNCTION_ARGS); >X+Datum >X+mchar_substring_no_len(PG_FUNCTION_ARGS) { >X+ MChar *src = PG_GETARG_MCHAR(0); >X+ MChar *dst; >X+ int32 length; >X+ >X+ dst = (MChar*)palloc( VARSIZE(src) ); >X+ length = uchar_substring( >X+ src->data, UCHARLENGTH(src), >X+ PG_GETARG_INT32(1), -1, true, >X+ dst->data); >X+ >X+ dst->typmod = src->typmod; >X+ SET_VARSIZE(dst, MCHARHDRSZ + length *sizeof(UChar)); >X+ >X+ PG_FREE_IF_COPY(src, 0); >X+ PG_RETURN_MCHAR(dst); >X+} >X+ >X+PG_FUNCTION_INFO_V1(mvarchar_substring); >X+Datum mvarchar_substring(PG_FUNCTION_ARGS); >X+Datum >X+mvarchar_substring(PG_FUNCTION_ARGS) { >X+ MVarChar *src = PG_GETARG_MVARCHAR(0); >X+ MVarChar *dst; >X+ int32 length; >X+ >X+ dst = (MVarChar*)palloc( VARSIZE(src) ); >X+ length = uchar_substring( >X+ src->data, UVARCHARLENGTH(src), >X+ PG_GETARG_INT32(1), PG_GETARG_INT32(2), false, >X+ dst->data); >X+ >X+ SET_VARSIZE(dst, MVARCHARHDRSZ + length *sizeof(UChar)); >X+ >X+ PG_FREE_IF_COPY(src, 0); >X+ PG_RETURN_MVARCHAR(dst); >X+} >X+ >X+PG_FUNCTION_INFO_V1(mvarchar_substring_no_len); >X+Datum mvarchar_substring_no_len(PG_FUNCTION_ARGS); >X+Datum >X+mvarchar_substring_no_len(PG_FUNCTION_ARGS) { >X+ MVarChar *src = PG_GETARG_MVARCHAR(0); >X+ MVarChar *dst; >X+ int32 length; >X+ >X+ dst = (MVarChar*)palloc( VARSIZE(src) ); >X+ length = uchar_substring( >X+ src->data, UVARCHARLENGTH(src), >X+ PG_GETARG_INT32(1), -1, true, >X+ dst->data); >X+ >X+ SET_VARSIZE(dst, MVARCHARHDRSZ + length *sizeof(UChar)); >X+ >X+ PG_FREE_IF_COPY(src, 0); >X+ PG_RETURN_MVARCHAR(dst); >X+} >X+ >X+static Datum >X+hash_uchar( UChar *s, int len ) { >X+ int32 length; >X+ UErrorCode err = 0; >X+ UChar *d; >X+ Datum res; >X+ >X+ if ( len == 0 ) >X+ return hash_any( NULL, 0 ); >X+ >X+ err = 0; >X+ d = (UChar*) palloc( sizeof(UChar) * len * 2 ); >X+ length = u_strFoldCase(d, len*2, s, len, U_FOLD_CASE_DEFAULT, &err); >X+ >X+ if ( U_FAILURE(err) ) >X+ elog(ERROR,"ICU u_strFoldCase fails and returns %d (%s)", err, u_errorName(err)); >X+ >X+ res = hash_any( (unsigned char*) d, length * sizeof(UChar) ); >X+ >X+ pfree(d); >X+ return res; >X+} >X+ >X+PG_FUNCTION_INFO_V1(mvarchar_hash); >X+Datum >X+mvarchar_hash(PG_FUNCTION_ARGS) { >X+ MVarChar *src = PG_GETARG_MVARCHAR(0); >X+ Datum res; >X+ >X+ res = hash_uchar( src->data, lengthWithoutSpaceVarChar(src) ); >X+ >X+ PG_FREE_IF_COPY(src, 0); >X+ PG_RETURN_DATUM( res ); >X+} >X+ >X+PG_FUNCTION_INFO_V1(mchar_hash); >X+Datum >X+mchar_hash(PG_FUNCTION_ARGS) { >X+ MChar *src = PG_GETARG_MCHAR(0); >X+ Datum res; >X+ >X+ res = hash_uchar( src->data, lengthWithoutSpaceChar(src) ); >X+ >X+ PG_FREE_IF_COPY(src, 0); >X+ PG_RETURN_DATUM( res ); >X+} >X+ >X+PG_FUNCTION_INFO_V1(mchar_upper); >X+Datum mchar_upper(PG_FUNCTION_ARGS); >X+Datum >X+mchar_upper(PG_FUNCTION_ARGS) { >X+ MChar *src = PG_GETARG_MCHAR(0); >X+ MChar *dst = (MChar*)palloc( VARSIZE(src) * 2 ); >X+ >X+ dst->len = MCHARHDRSZ; >X+ dst->typmod = src->typmod; >X+ if ( UCHARLENGTH(src) != 0 ) { >X+ int length; >X+ UErrorCode err=0; >X+ >X+ length = u_strToUpper( dst->data, VARSIZE(src) * 2 - MCHARHDRSZ, >X+ src->data, UCHARLENGTH(src), >X+ NULL, &err ); >X+ >X+ Assert( length <= VARSIZE(src) * 2 - MCHARHDRSZ ); >X+ >X+ if ( U_FAILURE(err) ) >X+ elog(ERROR,"ICU u_strToUpper fails and returns %d (%s)", err, u_errorName(err)); >X+ >X+ dst->len += sizeof(UChar) * length; >X+ } >X+ >X+ SET_VARSIZE( dst, dst->len ); >X+ PG_FREE_IF_COPY(src, 0); >X+ PG_RETURN_MCHAR( dst ); >X+} >X+ >X+PG_FUNCTION_INFO_V1(mchar_lower); >X+Datum mchar_lower(PG_FUNCTION_ARGS); >X+Datum >X+mchar_lower(PG_FUNCTION_ARGS) { >X+ MChar *src = PG_GETARG_MCHAR(0); >X+ MChar *dst = (MChar*)palloc( VARSIZE(src) * 2 ); >X+ >X+ dst->len = MCHARHDRSZ; >X+ dst->typmod = src->typmod; >X+ if ( UCHARLENGTH(src) != 0 ) { >X+ int length; >X+ UErrorCode err=0; >X+ >X+ length = u_strToLower( dst->data, VARSIZE(src) * 2 - MCHARHDRSZ, >X+ src->data, UCHARLENGTH(src), >X+ NULL, &err ); >X+ >X+ Assert( length <= VARSIZE(src) * 2 - MCHARHDRSZ ); >X+ >X+ if ( U_FAILURE(err) ) >X+ elog(ERROR,"ICU u_strToLower fails and returns %d (%s)", err, u_errorName(err)); >X+ >X+ dst->len += sizeof(UChar) * length; >X+ } >X+ >X+ SET_VARSIZE( dst, dst->len ); >X+ PG_FREE_IF_COPY(src, 0); >X+ PG_RETURN_MCHAR( dst ); >X+} >X+ >X+PG_FUNCTION_INFO_V1(mvarchar_upper); >X+Datum mvarchar_upper(PG_FUNCTION_ARGS); >X+Datum >X+mvarchar_upper(PG_FUNCTION_ARGS) { >X+ MVarChar *src = PG_GETARG_MVARCHAR(0); >X+ MVarChar *dst = (MVarChar*)palloc( VARSIZE(src) * 2 ); >X+ >X+ dst->len = MVARCHARHDRSZ; >X+ >X+ if ( UVARCHARLENGTH(src) != 0 ) { >X+ int length; >X+ UErrorCode err=0; >X+ >X+ length = u_strToUpper( dst->data, VARSIZE(src) * 2 - MVARCHARHDRSZ, >X+ src->data, UVARCHARLENGTH(src), >X+ NULL, &err ); >X+ >X+ Assert( length <= VARSIZE(src) * 2 - MVARCHARHDRSZ ); >X+ >X+ if ( U_FAILURE(err) ) >X+ elog(ERROR,"ICU u_strToUpper fails and returns %d (%s)", err, u_errorName(err)); >X+ >X+ dst->len += sizeof(UChar) * length; >X+ } >X+ >X+ SET_VARSIZE( dst, dst->len ); >X+ PG_FREE_IF_COPY(src, 0); >X+ PG_RETURN_MVARCHAR( dst ); >X+} >X+ >X+PG_FUNCTION_INFO_V1(mvarchar_lower); >X+Datum mvarchar_lower(PG_FUNCTION_ARGS); >X+Datum >X+mvarchar_lower(PG_FUNCTION_ARGS) { >X+ MVarChar *src = PG_GETARG_MVARCHAR(0); >X+ MVarChar *dst = (MVarChar*)palloc( VARSIZE(src) * 2 ); >X+ >X+ dst->len = MVARCHARHDRSZ; >X+ >X+ if ( UVARCHARLENGTH(src) != 0 ) { >X+ int length; >X+ UErrorCode err=0; >X+ >X+ length = u_strToLower( dst->data, VARSIZE(src) * 2 - MVARCHARHDRSZ, >X+ src->data, UVARCHARLENGTH(src), >X+ NULL, &err ); >X+ >X+ Assert( length <= VARSIZE(src) * 2 - MVARCHARHDRSZ ); >X+ >X+ if ( U_FAILURE(err) ) >X+ elog(ERROR,"ICU u_strToLower fails and returns %d (%s)", err, u_errorName(err)); >X+ >X+ dst->len += sizeof(UChar) * length; >X+ } >X+ >X+ SET_VARSIZE( dst, dst->len ); >X+ PG_FREE_IF_COPY(src, 0); >X+ PG_RETURN_MVARCHAR( dst ); >X+} >X+ >X+ >Xdiff --git a/contrib/mchar/mchar_recode.c b/contrib/mchar/mchar_recode.c >Xnew file mode 100644 >Xindex 0000000..d4f3659 >X--- /dev/null >X+++ contrib/mchar/mchar_recode.c >X@@ -0,0 +1,142 @@ >X+#include "mchar.h" >X+ >X+#include "unicode/ucol.h" >X+#include "unicode/ucnv.h" >X+ >X+static UConverter *cnvDB = NULL; >X+static UCollator *colCaseInsensitive = NULL; >X+static UCollator *colCaseSensitive = NULL; >X+ >X+static void >X+createUObjs() { >X+ if ( !cnvDB ) { >X+ UErrorCode err = 0; >X+ >X+ if ( GetDatabaseEncoding() == PG_UTF8 ) >X+ cnvDB = ucnv_open("UTF8", &err); >X+ else >X+ cnvDB = ucnv_open(NULL, &err); >X+ if ( U_FAILURE(err) || cnvDB == NULL ) >X+ elog(ERROR,"ICU ucnv_open returns %d (%s)", err, u_errorName(err)); >X+ } >X+ >X+ if ( !colCaseInsensitive ) { >X+ UErrorCode err = 0; >X+ >X+ colCaseInsensitive = ucol_open("", &err); >X+ if ( U_FAILURE(err) || cnvDB == NULL ) { >X+ if ( colCaseSensitive ) >X+ ucol_close( colCaseSensitive ); >X+ colCaseSensitive = NULL; >X+ elog(ERROR,"ICU ucol_open returns %d (%s)", err, u_errorName(err)); >X+ } >X+ >X+ ucol_setStrength( colCaseInsensitive, UCOL_SECONDARY ); >X+ } >X+ >X+ if ( !colCaseSensitive ) { >X+ UErrorCode err = 0; >X+ >X+ colCaseSensitive = ucol_open("", &err); >X+ if ( U_FAILURE(err) || cnvDB == NULL ) { >X+ if ( colCaseSensitive ) >X+ ucol_close( colCaseSensitive ); >X+ colCaseSensitive = NULL; >X+ elog(ERROR,"ICU ucol_open returns %d (%s)", err, u_errorName(err)); >X+ } >X+ >X+ ucol_setAttribute(colCaseSensitive, UCOL_CASE_FIRST, UCOL_UPPER_FIRST, &err); >X+ if (U_FAILURE(err)) { >X+ if ( colCaseSensitive ) >X+ ucol_close( colCaseSensitive ); >X+ colCaseSensitive = NULL; >X+ elog(ERROR,"ICU ucol_setAttribute returns %d (%s)", err, u_errorName(err)); >X+ } >X+ } >X+} >X+ >X+int >X+Char2UChar(const char * src, int srclen, UChar *dst) { >X+ int dstlen=0; >X+ UErrorCode err = 0; >X+ >X+ createUObjs(); >X+ dstlen = ucnv_toUChars( cnvDB, dst, srclen*4, src, srclen, &err ); >X+ if ( U_FAILURE(err)) >X+ elog(ERROR,"ICU ucnv_toUChars returns %d (%s)", err, u_errorName(err)); >X+ >X+ return dstlen; >X+} >X+ >X+int >X+UChar2Char(const UChar * src, int srclen, char *dst) { >X+ int dstlen=0; >X+ UErrorCode err = 0; >X+ >X+ createUObjs(); >X+ dstlen = ucnv_fromUChars( cnvDB, dst, srclen*4, src, srclen, &err ); >X+ if ( U_FAILURE(err) ) >X+ elog(ERROR,"ICU ucnv_fromUChars returns %d (%s)", err, u_errorName(err)); >X+ >X+ return dstlen; >X+} >X+ >X+int >X+UChar2Wchar(UChar * src, int srclen, pg_wchar *dst) { >X+ int dstlen=0; >X+ char *utf = palloc(sizeof(char)*srclen*4); >X+ >X+ dstlen = UChar2Char(src, srclen, utf); >X+ dstlen = pg_mb2wchar_with_len( utf, dst, dstlen ); >X+ pfree(utf); >X+ >X+ return dstlen; >X+} >X+ >X+static UChar UCharWhiteSpace = 0; >X+ >X+void >X+FillWhiteSpace( UChar *dst, int n ) { >X+ if ( UCharWhiteSpace == 0 ) { >X+ int len; >X+ UErrorCode err = 0; >X+ >X+ u_strFromUTF8( &UCharWhiteSpace, 1, &len, " ", 1, &err); >X+ >X+ Assert( len==1 ); >X+ Assert( !U_FAILURE(err) ); >X+ } >X+ >X+ while( n-- > 0 ) >X+ *dst++ = UCharWhiteSpace; >X+} >X+ >X+int >X+UCharCaseCompare(UChar * a, int alen, UChar *b, int blen) { >X+ int len = Min(alen, blen); >X+ int res; >X+ >X+ createUObjs(); >X+ >X+ res = (int)ucol_strcoll( colCaseInsensitive, >X+ a, len, >X+ b, len); >X+ if ( res == 0 && alen != blen ) >X+ return (alen > blen) ? 1 : - 1; >X+ return res; >X+} >X+ >X+int >X+UCharCompare(UChar * a, int alen, UChar *b, int blen) { >X+ int len = Min(alen, blen); >X+ int res; >X+ >X+ createUObjs(); >X+ >X+ res = (int)ucol_strcoll( colCaseSensitive, >X+ a, len, >X+ b, len); >X+ if ( res == 0 && alen != blen ) >X+ return (alen > blen) ? 1 : - 1; >X+ return res; >X+} >Xdiff --git a/contrib/mchar/sql/compat.sql b/contrib/mchar/sql/compat.sql >Xnew file mode 100644 >Xindex 0000000..d5b6a98 >X--- /dev/null >X+++ contrib/mchar/sql/compat.sql >X@@ -0,0 +1,11 @@ >X+--- table based checks >X+ >X+select '<' || ch || '>', '<' || vch || '>' from chvch; >X+select * from chvch where vch = 'One space'; >X+select * from chvch where vch = 'One space '; >X+ >X+select * from ch where chcol = 'abcd' order by chcol; >X+select * from ch t1 join ch t2 on t1.chcol = t2.chcol order by t1.chcol, t2.chcol; >X+select * from ch where chcol > 'abcd' and chcol<'ee'; >X+select * from ch order by chcol; >X+ >Xdiff --git a/contrib/mchar/sql/init.sql b/contrib/mchar/sql/init.sql >Xnew file mode 100644 >Xindex 0000000..f295427 >X--- /dev/null >X+++ contrib/mchar/sql/init.sql >X@@ -0,0 +1,14 @@ >X+ >X+-- >X+-- first, define the datatype. Turn off echoing so that expected file >X+-- does not depend on contents of mchar.sql. >X+-- >X+ >X+\set ECHO none >X+\i mchar.sql >X+--- load for table based checks >X+SET search_path = public; >X+\i data/chvch.sql >X+\i data/ch.sql >X+\set ECHO all >X+ >Xdiff --git a/contrib/mchar/sql/like.sql b/contrib/mchar/sql/like.sql >Xnew file mode 100644 >Xindex 0000000..aebf924 >X--- /dev/null >X+++ contrib/mchar/sql/like.sql >X@@ -0,0 +1,216 @@ >X+-- simplest examples >X+-- E061-04 like predicate >X+SELECT 'hawkeye'::mchar LIKE 'h%' AS "true"; >X+SELECT 'hawkeye'::mchar NOT LIKE 'h%' AS "false"; >X+ >X+SELECT 'hawkeye'::mchar LIKE 'H%' AS "true"; >X+SELECT 'hawkeye'::mchar NOT LIKE 'H%' AS "false"; >X+ >X+SELECT 'hawkeye'::mchar LIKE 'indio%' AS "false"; >X+SELECT 'hawkeye'::mchar NOT LIKE 'indio%' AS "true"; >X+ >X+SELECT 'hawkeye'::mchar LIKE 'h%eye' AS "true"; >X+SELECT 'hawkeye'::mchar NOT LIKE 'h%eye' AS "false"; >X+ >X+SELECT 'indio'::mchar LIKE '_ndio' AS "true"; >X+SELECT 'indio'::mchar NOT LIKE '_ndio' AS "false"; >X+ >X+SELECT 'indio'::mchar LIKE 'in__o' AS "true"; >X+SELECT 'indio'::mchar NOT LIKE 'in__o' AS "false"; >X+ >X+SELECT 'indio'::mchar LIKE 'in_o' AS "false"; >X+SELECT 'indio'::mchar NOT LIKE 'in_o' AS "true"; >X+ >X+SELECT 'hawkeye'::mvarchar LIKE 'h%' AS "true"; >X+SELECT 'hawkeye'::mvarchar NOT LIKE 'h%' AS "false"; >X+ >X+SELECT 'hawkeye'::mvarchar LIKE 'H%' AS "true"; >X+SELECT 'hawkeye'::mvarchar NOT LIKE 'H%' AS "false"; >X+ >X+SELECT 'hawkeye'::mvarchar LIKE 'indio%' AS "false"; >X+SELECT 'hawkeye'::mvarchar NOT LIKE 'indio%' AS "true"; >X+ >X+SELECT 'hawkeye'::mvarchar LIKE 'h%eye' AS "true"; >X+SELECT 'hawkeye'::mvarchar NOT LIKE 'h%eye' AS "false"; >X+ >X+SELECT 'indio'::mvarchar LIKE '_ndio' AS "true"; >X+SELECT 'indio'::mvarchar NOT LIKE '_ndio' AS "false"; >X+ >X+SELECT 'indio'::mvarchar LIKE 'in__o' AS "true"; >X+SELECT 'indio'::mvarchar NOT LIKE 'in__o' AS "false"; >X+ >X+SELECT 'indio'::mvarchar LIKE 'in_o' AS "false"; >X+SELECT 'indio'::mvarchar NOT LIKE 'in_o' AS "true"; >X+ >X+-- unused escape character >X+SELECT 'hawkeye'::mchar LIKE 'h%'::mchar ESCAPE '#' AS "true"; >X+SELECT 'hawkeye'::mchar NOT LIKE 'h%'::mchar ESCAPE '#' AS "false"; >X+ >X+SELECT 'indio'::mchar LIKE 'ind_o'::mchar ESCAPE '$' AS "true"; >X+SELECT 'indio'::mchar NOT LIKE 'ind_o'::mchar ESCAPE '$' AS "false"; >X+ >X+-- escape character >X+-- E061-05 like predicate with escape clause >X+SELECT 'h%'::mchar LIKE 'h#%'::mchar ESCAPE '#' AS "true"; >X+SELECT 'h%'::mchar NOT LIKE 'h#%'::mchar ESCAPE '#' AS "false"; >X+ >X+SELECT 'h%wkeye'::mchar LIKE 'h#%'::mchar ESCAPE '#' AS "false"; >X+SELECT 'h%wkeye'::mchar NOT LIKE 'h#%'::mchar ESCAPE '#' AS "true"; >X+ >X+SELECT 'h%wkeye'::mchar LIKE 'h#%%'::mchar ESCAPE '#' AS "true"; >X+SELECT 'h%wkeye'::mchar NOT LIKE 'h#%%'::mchar ESCAPE '#' AS "false"; >X+ >X+SELECT 'h%awkeye'::mchar LIKE 'h#%a%k%e'::mchar ESCAPE '#' AS "true"; >X+SELECT 'h%awkeye'::mchar NOT LIKE 'h#%a%k%e'::mchar ESCAPE '#' AS "false"; >X+ >X+SELECT 'indio'::mchar LIKE '_ndio'::mchar ESCAPE '$' AS "true"; >X+SELECT 'indio'::mchar NOT LIKE '_ndio'::mchar ESCAPE '$' AS "false"; >X+ >X+SELECT 'i_dio'::mchar LIKE 'i$_d_o'::mchar ESCAPE '$' AS "true"; >X+SELECT 'i_dio'::mchar NOT LIKE 'i$_d_o'::mchar ESCAPE '$' AS "false"; >X+ >X+SELECT 'i_dio'::mchar LIKE 'i$_nd_o'::mchar ESCAPE '$' AS "false"; >X+SELECT 'i_dio'::mchar NOT LIKE 'i$_nd_o'::mchar ESCAPE '$' AS "true"; >X+ >X+SELECT 'i_dio'::mchar LIKE 'i$_d%o'::mchar ESCAPE '$' AS "true"; >X+SELECT 'i_dio'::mchar NOT LIKE 'i$_d%o'::mchar ESCAPE '$' AS "false"; >X+ >X+-- escape character same as pattern character >X+SELECT 'maca'::mchar LIKE 'm%aca' ESCAPE '%'::mchar AS "true"; >X+SELECT 'maca'::mchar NOT LIKE 'm%aca' ESCAPE '%'::mchar AS "false"; >X+ >X+SELECT 'ma%a'::mchar LIKE 'm%a%%a' ESCAPE '%'::mchar AS "true"; >X+SELECT 'ma%a'::mchar NOT LIKE 'm%a%%a' ESCAPE '%'::mchar AS "false"; >X+ >X+SELECT 'bear'::mchar LIKE 'b_ear' ESCAPE '_'::mchar AS "true"; >X+SELECT 'bear'::mchar NOT LIKE 'b_ear'::mchar ESCAPE '_' AS "false"; >X+ >X+SELECT 'be_r'::mchar LIKE 'b_e__r' ESCAPE '_'::mchar AS "true"; >X+SELECT 'be_r'::mchar NOT LIKE 'b_e__r' ESCAPE '_'::mchar AS "false"; >X+ >X+SELECT 'be_r'::mchar LIKE '__e__r' ESCAPE '_'::mchar AS "false"; >X+SELECT 'be_r'::mchar NOT LIKE '__e__r'::mchar ESCAPE '_' AS "true"; >X+ >X+-- unused escape character >X+SELECT 'hawkeye'::mvarchar LIKE 'h%'::mvarchar ESCAPE '#' AS "true"; >X+SELECT 'hawkeye'::mvarchar NOT LIKE 'h%'::mvarchar ESCAPE '#' AS "false"; >X+ >X+SELECT 'indio'::mvarchar LIKE 'ind_o'::mvarchar ESCAPE '$' AS "true"; >X+SELECT 'indio'::mvarchar NOT LIKE 'ind_o'::mvarchar ESCAPE '$' AS "false"; >X+ >X+-- escape character >X+-- E061-05 like predicate with escape clause >X+SELECT 'h%'::mvarchar LIKE 'h#%'::mvarchar ESCAPE '#' AS "true"; >X+SELECT 'h%'::mvarchar NOT LIKE 'h#%'::mvarchar ESCAPE '#' AS "false"; >X+ >X+SELECT 'h%wkeye'::mvarchar LIKE 'h#%'::mvarchar ESCAPE '#' AS "false"; >X+SELECT 'h%wkeye'::mvarchar NOT LIKE 'h#%'::mvarchar ESCAPE '#' AS "true"; >X+ >X+SELECT 'h%wkeye'::mvarchar LIKE 'h#%%'::mvarchar ESCAPE '#' AS "true"; >X+SELECT 'h%wkeye'::mvarchar NOT LIKE 'h#%%'::mvarchar ESCAPE '#' AS "false"; >X+ >X+SELECT 'h%awkeye'::mvarchar LIKE 'h#%a%k%e'::mvarchar ESCAPE '#' AS "true"; >X+SELECT 'h%awkeye'::mvarchar NOT LIKE 'h#%a%k%e'::mvarchar ESCAPE '#' AS "false"; >X+ >X+SELECT 'indio'::mvarchar LIKE '_ndio'::mvarchar ESCAPE '$' AS "true"; >X+SELECT 'indio'::mvarchar NOT LIKE '_ndio'::mvarchar ESCAPE '$' AS "false"; >X+ >X+SELECT 'i_dio'::mvarchar LIKE 'i$_d_o'::mvarchar ESCAPE '$' AS "true"; >X+SELECT 'i_dio'::mvarchar NOT LIKE 'i$_d_o'::mvarchar ESCAPE '$' AS "false"; >X+ >X+SELECT 'i_dio'::mvarchar LIKE 'i$_nd_o'::mvarchar ESCAPE '$' AS "false"; >X+SELECT 'i_dio'::mvarchar NOT LIKE 'i$_nd_o'::mvarchar ESCAPE '$' AS "true"; >X+ >X+SELECT 'i_dio'::mvarchar LIKE 'i$_d%o'::mvarchar ESCAPE '$' AS "true"; >X+SELECT 'i_dio'::mvarchar NOT LIKE 'i$_d%o'::mvarchar ESCAPE '$' AS "false"; >X+ >X+-- escape character same as pattern character >X+SELECT 'maca'::mvarchar LIKE 'm%aca' ESCAPE '%'::mvarchar AS "true"; >X+SELECT 'maca'::mvarchar NOT LIKE 'm%aca' ESCAPE '%'::mvarchar AS "false"; >X+ >X+SELECT 'ma%a'::mvarchar LIKE 'm%a%%a' ESCAPE '%'::mvarchar AS "true"; >X+SELECT 'ma%a'::mvarchar NOT LIKE 'm%a%%a' ESCAPE '%'::mvarchar AS "false"; >X+ >X+SELECT 'bear'::mvarchar LIKE 'b_ear' ESCAPE '_'::mvarchar AS "true"; >X+SELECT 'bear'::mvarchar NOT LIKE 'b_ear'::mvarchar ESCAPE '_' AS "false"; >X+ >X+SELECT 'be_r'::mvarchar LIKE 'b_e__r' ESCAPE '_'::mvarchar AS "true"; >X+SELECT 'be_r'::mvarchar NOT LIKE 'b_e__r' ESCAPE '_'::mvarchar AS "false"; >X+ >X+SELECT 'be_r'::mvarchar LIKE '__e__r' ESCAPE '_'::mvarchar AS "false"; >X+SELECT 'be_r'::mvarchar NOT LIKE '__e__r'::mvarchar ESCAPE '_' AS "true"; >X+ >X+-- similar to >X+ >X+SELECT 'abc'::mchar SIMILAR TO 'abc'::mchar AS "true"; >X+SELECT 'abc'::mchar SIMILAR TO 'a'::mchar AS "false"; >X+SELECT 'abc'::mchar SIMILAR TO '%(b|d)%'::mchar AS "true"; >X+SELECT 'abc'::mchar SIMILAR TO '(b|c)%'::mchar AS "false"; >X+SELECT 'h%'::mchar SIMILAR TO 'h#%'::mchar AS "false"; >X+SELECT 'h%'::mchar SIMILAR TO 'h#%'::mchar ESCAPE '#' AS "true"; >X+ >X+SELECT 'abc'::mvarchar SIMILAR TO 'abc'::mvarchar AS "true"; >X+SELECT 'abc'::mvarchar SIMILAR TO 'a'::mvarchar AS "false"; >X+SELECT 'abc'::mvarchar SIMILAR TO '%(b|d)%'::mvarchar AS "true"; >X+SELECT 'abc'::mvarchar SIMILAR TO '(b|c)%'::mvarchar AS "false"; >X+SELECT 'h%'::mvarchar SIMILAR TO 'h#%'::mvarchar AS "false"; >X+SELECT 'h%'::mvarchar SIMILAR TO 'h#%'::mvarchar ESCAPE '#' AS "true"; >X+ >X+-- index support >X+ >X+SELECT * from ch where chcol like 'aB_d' order by chcol using &<; >X+SELECT * from ch where chcol like 'aB%d' order by chcol using &<; >X+SELECT * from ch where chcol like 'aB%' order by chcol using &<; >X+SELECT * from ch where chcol like '%BC%' order by chcol using &<; >X+set enable_seqscan = off; >X+SELECT * from ch where chcol like 'aB_d' order by chcol using &<; >X+SELECT * from ch where chcol like 'aB%d' order by chcol using &<; >X+SELECT * from ch where chcol like 'aB%' order by chcol using &<; >X+SELECT * from ch where chcol like '%BC%' order by chcol using &<; >X+set enable_seqscan = on; >X+ >X+ >X+create table testt (f1 mchar(10)); >X+insert into testt values ('Abc-000001'); >X+insert into testt values ('Abc-000002'); >X+insert into testt values ('0000000001'); >X+insert into testt values ('0000000002'); >X+ >X+select f1 from testt where f1::mvarchar like E'Abc\\-%'::mvarchar; >X+select * from testt where f1::mchar like E'Abc\\-%'::mchar; >X+create index testindex on testt(f1); >X+set enable_seqscan=off; >X+select f1 from testt where f1::mvarchar like E'Abc\\-%'::mvarchar; >X+select * from testt where f1::mchar like E'Abc\\-%'::mchar; >X+set enable_seqscan = on; >X+drop table testt; >X+ >X+create table testt (f1 mvarchar(10)); >X+insert into testt values ('Abc-000001'); >X+insert into testt values ('Abc-000002'); >X+insert into testt values ('0000000001'); >X+insert into testt values ('0000000002'); >X+ >X+select f1 from testt where f1::mvarchar like E'Abc\\-%'::mvarchar; >X+select * from testt where f1::mchar like E'Abc\\-%'::mchar; >X+select * from testt where f1::mchar like E'Abc\\- %'::mchar; >X+select * from testt where f1::mchar like E' %'::mchar; >X+create index testindex on testt(f1); >X+set enable_seqscan=off; >X+select f1 from testt where f1::mvarchar like E'Abc\\-%'::mvarchar; >X+select * from testt where f1::mchar like E'Abc\\-%'::mchar; >X+select * from testt where f1::mchar like E'Abc\\- %'::mchar; >X+select * from testt where f1::mchar like E' %'::mchar; >X+set enable_seqscan = on; >X+drop table testt; >X+ >X+ >X+CREATE TABLE test ( code mchar(5) NOT NULL ); >X+insert into test values('1111 '); >X+insert into test values('111 '); >X+insert into test values('11 '); >X+insert into test values('1 '); >X+ >X+SELECT * FROM test WHERE code LIKE ('% '); >X+ >X+ >Xdiff --git a/contrib/mchar/sql/mchar.sql b/contrib/mchar/sql/mchar.sql >Xnew file mode 100644 >Xindex 0000000..640f166 >X--- /dev/null >X+++ contrib/mchar/sql/mchar.sql >X@@ -0,0 +1,81 @@ >X+-- I/O tests >X+ >X+select '1'::mchar; >X+select '2 '::mchar; >X+select '10 '::mchar; >X+ >X+select '1'::mchar(2); >X+select '2 '::mchar(2); >X+select '3 '::mchar(2); >X+select '10 '::mchar(2); >X+ >X+select ' '::mchar(10); >X+select ' '::mchar; >X+ >X+-- operations & functions >X+ >X+select length('1'::mchar); >X+select length('2 '::mchar); >X+select length('10 '::mchar); >X+ >X+select length('1'::mchar(2)); >X+select length('2 '::mchar(2)); >X+select length('3 '::mchar(2)); >X+select length('10 '::mchar(2)); >X+ >X+select length(' '::mchar(10)); >X+select length(' '::mchar); >X+ >X+select 'asd'::mchar(10) || '>'::mchar(10); >X+select length('asd'::mchar(10) || '>'::mchar(10)); >X+select 'asd'::mchar(2) || '>'::mchar(10); >X+select length('asd'::mchar(2) || '>'::mchar(10)); >X+ >X+-- Comparisons >X+ >X+select 'asdf'::mchar = 'aSdf'::mchar; >X+select 'asdf'::mchar = 'aSdf '::mchar; >X+select 'asdf'::mchar = 'aSdf 1'::mchar(4); >X+select 'asdf'::mchar = 'aSdf 1'::mchar(5); >X+select 'asdf'::mchar = 'aSdf 1'::mchar(6); >X+select 'asdf'::mchar(3) = 'aSdf 1'::mchar(5); >X+select 'asdf'::mchar(3) = 'aSdf 1'::mchar(3); >X+ >X+select 'asdf'::mchar < 'aSdf'::mchar; >X+select 'asdf'::mchar < 'aSdf '::mchar; >X+select 'asdf'::mchar < 'aSdf 1'::mchar(4); >X+select 'asdf'::mchar < 'aSdf 1'::mchar(5); >X+select 'asdf'::mchar < 'aSdf 1'::mchar(6); >X+ >X+select 'asdf'::mchar <= 'aSdf'::mchar; >X+select 'asdf'::mchar <= 'aSdf '::mchar; >X+select 'asdf'::mchar <= 'aSdf 1'::mchar(4); >X+select 'asdf'::mchar <= 'aSdf 1'::mchar(5); >X+select 'asdf'::mchar <= 'aSdf 1'::mchar(6); >X+ >X+select 'asdf'::mchar >= 'aSdf'::mchar; >X+select 'asdf'::mchar >= 'aSdf '::mchar; >X+select 'asdf'::mchar >= 'aSdf 1'::mchar(4); >X+select 'asdf'::mchar >= 'aSdf 1'::mchar(5); >X+select 'asdf'::mchar >= 'aSdf 1'::mchar(6); >X+ >X+select 'asdf'::mchar > 'aSdf'::mchar; >X+select 'asdf'::mchar > 'aSdf '::mchar; >X+select 'asdf'::mchar > 'aSdf 1'::mchar(4); >X+select 'asdf'::mchar > 'aSdf 1'::mchar(5); >X+select 'asdf'::mchar > 'aSdf 1'::mchar(6); >X+ >X+select max(ch) from chvch; >X+select min(ch) from chvch; >X+ >X+select substr('1234567890'::mchar, 3) = '34567890' as "34567890"; >X+select substr('1234567890'::mchar, 4, 3) = '456' as "456"; >X+ >X+select lower('asdfASDF'::mchar); >X+select upper('asdfASDF'::mchar); >X+ >X+select 'asd'::mchar == 'aSd'::mchar; >X+select 'asd'::mchar == 'aCd'::mchar; >X+select 'asd'::mchar == NULL; >X+select NULL == 'aCd'::mchar; >X+select NULL::mchar == NULL; >Xdiff --git a/contrib/mchar/sql/mm.sql b/contrib/mchar/sql/mm.sql >Xnew file mode 100644 >Xindex 0000000..c16aaa1 >X--- /dev/null >X+++ contrib/mchar/sql/mm.sql >X@@ -0,0 +1,185 @@ >X+select 'asd'::mchar::mvarchar; >X+select 'asd '::mchar::mvarchar; >X+select 'asd'::mchar(2)::mvarchar; >X+select 'asd '::mchar(2)::mvarchar; >X+select 'asd'::mchar(5)::mvarchar; >X+select 'asd '::mchar(5)::mvarchar; >X+select 'asd'::mchar::mvarchar(2); >X+select 'asd '::mchar::mvarchar(2); >X+select 'asd'::mchar(2)::mvarchar(2); >X+select 'asd '::mchar(2)::mvarchar(2); >X+select 'asd'::mchar(5)::mvarchar(2); >X+select 'asd '::mchar(5)::mvarchar(2); >X+select 'asd'::mchar::mvarchar(5); >X+select 'asd '::mchar::mvarchar(5); >X+select 'asd'::mchar(2)::mvarchar(5); >X+select 'asd '::mchar(2)::mvarchar(5); >X+select 'asd'::mchar(5)::mvarchar(5); >X+select 'asd '::mchar(5)::mvarchar(5); >X+ >X+select 'asd'::mvarchar::mchar; >X+select 'asd '::mvarchar::mchar; >X+select 'asd'::mvarchar(2)::mchar; >X+select 'asd '::mvarchar(2)::mchar; >X+select 'asd'::mvarchar(5)::mchar; >X+select 'asd '::mvarchar(5)::mchar; >X+select 'asd'::mvarchar::mchar(2); >X+select 'asd '::mvarchar::mchar(2); >X+select 'asd'::mvarchar(2)::mchar(2); >X+select 'asd '::mvarchar(2)::mchar(2); >X+select 'asd'::mvarchar(5)::mchar(2); >X+select 'asd '::mvarchar(5)::mchar(2); >X+select 'asd'::mvarchar::mchar(5); >X+select 'asd '::mvarchar::mchar(5); >X+select 'asd'::mvarchar(2)::mchar(5); >X+select 'asd '::mvarchar(2)::mchar(5); >X+select 'asd'::mvarchar(5)::mchar(5); >X+select 'asd '::mvarchar(5)::mchar(5); >X+ >X+select 'asd'::mchar || '123'; >X+select 'asd'::mchar || '123'::mchar; >X+select 'asd'::mchar || '123'::mvarchar; >X+ >X+select 'asd '::mchar || '123'; >X+select 'asd '::mchar || '123'::mchar; >X+select 'asd '::mchar || '123'::mvarchar; >X+ >X+select 'asd '::mchar || '123 '; >X+select 'asd '::mchar || '123 '::mchar; >X+select 'asd '::mchar || '123 '::mvarchar; >X+ >X+ >X+select 'asd'::mvarchar || '123'; >X+select 'asd'::mvarchar || '123'::mchar; >X+select 'asd'::mvarchar || '123'::mvarchar; >X+ >X+select 'asd '::mvarchar || '123'; >X+select 'asd '::mvarchar || '123'::mchar; >X+select 'asd '::mvarchar || '123'::mvarchar; >X+ >X+select 'asd '::mvarchar || '123 '; >X+select 'asd '::mvarchar || '123 '::mchar; >X+select 'asd '::mvarchar || '123 '::mvarchar; >X+ >X+ >X+select 'asd'::mchar(2) || '123'; >X+select 'asd'::mchar(2) || '123'::mchar; >X+select 'asd'::mchar(2) || '123'::mvarchar; >X+ >X+ >X+select 'asd '::mchar(2) || '123'; >X+select 'asd '::mchar(2) || '123'::mchar; >X+select 'asd '::mchar(2) || '123'::mvarchar; >X+ >X+ >X+select 'asd '::mchar(2) || '123 '; >X+select 'asd '::mchar(2) || '123 '::mchar; >X+select 'asd '::mchar(2) || '123 '::mvarchar; >X+ >X+select 'asd'::mvarchar(2) || '123'; >X+select 'asd'::mvarchar(2) || '123'::mchar; >X+select 'asd'::mvarchar(2) || '123'::mvarchar; >X+ >X+select 'asd '::mvarchar(2) || '123'; >X+select 'asd '::mvarchar(2) || '123'::mchar; >X+select 'asd '::mvarchar(2) || '123'::mvarchar; >X+ >X+select 'asd '::mvarchar(2) || '123 '; >X+select 'asd '::mvarchar(2) || '123 '::mchar; >X+select 'asd '::mvarchar(2) || '123 '::mvarchar; >X+ >X+select 'asd'::mchar(4) || '143'; >X+select 'asd'::mchar(4) || '123'::mchar; >X+select 'asd'::mchar(4) || '123'::mvarchar; >X+ >X+select 'asd '::mchar(4) || '123'; >X+select 'asd '::mchar(4) || '123'::mchar; >X+select 'asd '::mchar(4) || '123'::mvarchar; >X+ >X+select 'asd '::mchar(4) || '123 '; >X+select 'asd '::mchar(4) || '123 '::mchar; >X+select 'asd '::mchar(4) || '123 '::mvarchar; >X+ >X+select 'asd'::mvarchar(4) || '123'; >X+select 'asd'::mvarchar(4) || '123'::mchar; >X+select 'asd'::mvarchar(4) || '123'::mvarchar; >X+ >X+select 'asd '::mvarchar(4) || '123'; >X+select 'asd '::mvarchar(4) || '123'::mchar; >X+select 'asd '::mvarchar(4) || '123'::mvarchar; >X+ >X+select 'asd '::mvarchar(4) || '123 '; >X+select 'asd '::mvarchar(4) || '123 '::mchar; >X+select 'asd '::mvarchar(4) || '123 '::mvarchar; >X+ >X+ >X+select 'asd '::mvarchar(4) || '123 '::mchar(4); >X+select 'asd '::mvarchar(4) || '123 '::mvarchar(4); >X+select 'asd '::mvarchar(4) || '123'::mchar(4); >X+select 'asd '::mvarchar(4) || '123'::mvarchar(4); >X+ >X+ >X+select 1 where 'f'::mchar='F'::mvarchar; >X+select 1 where 'f'::mchar='F '::mvarchar; >X+select 1 where 'f '::mchar='F'::mvarchar; >X+select 1 where 'f '::mchar='F '::mvarchar; >X+ >X+select 1 where 'f'::mchar='F'::mvarchar(2); >X+select 1 where 'f'::mchar='F '::mvarchar(2); >X+select 1 where 'f '::mchar='F'::mvarchar(2); >X+select 1 where 'f '::mchar='F '::mvarchar(2); >X+ >X+select 1 where 'f'::mchar(2)='F'::mvarchar; >X+select 1 where 'f'::mchar(2)='F '::mvarchar; >X+select 1 where 'f '::mchar(2)='F'::mvarchar; >X+select 1 where 'f '::mchar(2)='F '::mvarchar; >X+ >X+select 1 where 'f'::mchar(2)='F'::mvarchar(2); >X+select 1 where 'f'::mchar(2)='F '::mvarchar(2); >X+select 1 where 'f '::mchar(2)='F'::mvarchar(2); >X+select 1 where 'f '::mchar(2)='F '::mvarchar(2); >X+ >X+select 1 where 'foo'::mchar='FOO'::mvarchar; >X+select 1 where 'foo'::mchar='FOO '::mvarchar; >X+select 1 where 'foo '::mchar='FOO'::mvarchar; >X+select 1 where 'foo '::mchar='FOO '::mvarchar; >X+ >X+select 1 where 'foo'::mchar='FOO'::mvarchar(2); >X+select 1 where 'foo'::mchar='FOO '::mvarchar(2); >X+select 1 where 'foo '::mchar='FOO'::mvarchar(2); >X+select 1 where 'foo '::mchar='FOO '::mvarchar(2); >X+ >X+select 1 where 'foo'::mchar(2)='FOO'::mvarchar; >X+select 1 where 'foo'::mchar(2)='FOO '::mvarchar; >X+select 1 where 'foo '::mchar(2)='FOO'::mvarchar; >X+select 1 where 'foo '::mchar(2)='FOO '::mvarchar; >X+ >X+select 1 where 'foo'::mchar(2)='FOO'::mvarchar(2); >X+select 1 where 'foo'::mchar(2)='FOO '::mvarchar(2); >X+select 1 where 'foo '::mchar(2)='FOO'::mvarchar(2); >X+select 1 where 'foo '::mchar(2)='FOO '::mvarchar(2); >X+ >X+Select 'f'::mchar(1) Union Select 'o'::mvarchar(1); >X+Select 'f'::mvarchar(1) Union Select 'o'::mchar(1); >X+ >X+select * from chvch where ch=vch; >X+ >X+select ch.* from ch, (select 'dEfg'::mvarchar as q) as p where chcol > p.q; >X+create index qq on ch (chcol); >X+set enable_seqscan=off; >X+select ch.* from ch, (select 'dEfg'::mvarchar as q) as p where chcol > p.q; >X+set enable_seqscan=on; >X+ >X+ >X+--\copy chvch to 'results/chvch.dump' binary >X+--truncate table chvch; >X+--\copy chvch from 'results/chvch.dump' binary >X+ >X+--test joins >X+CREATE TABLE a (mchar2 MCHAR(2) NOT NULL); >X+CREATE TABLE c (mvarchar255 mvarchar NOT NULL); >X+SELECT * FROM a, c WHERE mchar2 = mvarchar255; >X+SELECT * FROM a, c WHERE mvarchar255 = mchar2; >X+DROP TABLE a; >X+DROP TABLE c; >X+ >Xdiff --git a/contrib/mchar/sql/mvarchar.sql b/contrib/mchar/sql/mvarchar.sql >Xnew file mode 100644 >Xindex 0000000..91b0981 >X--- /dev/null >X+++ contrib/mchar/sql/mvarchar.sql >X@@ -0,0 +1,82 @@ >X+-- I/O tests >X+ >X+select '1'::mvarchar; >X+select '2 '::mvarchar; >X+select '10 '::mvarchar; >X+ >X+select '1'::mvarchar(2); >X+select '2 '::mvarchar(2); >X+select '3 '::mvarchar(2); >X+select '10 '::mvarchar(2); >X+ >X+select ' '::mvarchar(10); >X+select ' '::mvarchar; >X+ >X+-- operations & functions >X+ >X+select length('1'::mvarchar); >X+select length('2 '::mvarchar); >X+select length('10 '::mvarchar); >X+ >X+select length('1'::mvarchar(2)); >X+select length('2 '::mvarchar(2)); >X+select length('3 '::mvarchar(2)); >X+select length('10 '::mvarchar(2)); >X+ >X+select length(' '::mvarchar(10)); >X+select length(' '::mvarchar); >X+ >X+select 'asd'::mvarchar(10) || '>'::mvarchar(10); >X+select length('asd'::mvarchar(10) || '>'::mvarchar(10)); >X+select 'asd'::mvarchar(2) || '>'::mvarchar(10); >X+select length('asd'::mvarchar(2) || '>'::mvarchar(10)); >X+ >X+-- Comparisons >X+ >X+select 'asdf'::mvarchar = 'aSdf'::mvarchar; >X+select 'asdf'::mvarchar = 'aSdf '::mvarchar; >X+select 'asdf'::mvarchar = 'aSdf 1'::mvarchar(4); >X+select 'asdf'::mvarchar = 'aSdf 1'::mvarchar(5); >X+select 'asdf'::mvarchar = 'aSdf 1'::mvarchar(6); >X+select 'asdf'::mvarchar(3) = 'aSdf 1'::mvarchar(5); >X+select 'asdf'::mvarchar(3) = 'aSdf 1'::mvarchar(3); >X+ >X+select 'asdf'::mvarchar < 'aSdf'::mvarchar; >X+select 'asdf'::mvarchar < 'aSdf '::mvarchar; >X+select 'asdf'::mvarchar < 'aSdf 1'::mvarchar(4); >X+select 'asdf'::mvarchar < 'aSdf 1'::mvarchar(5); >X+select 'asdf'::mvarchar < 'aSdf 1'::mvarchar(6); >X+ >X+select 'asdf'::mvarchar <= 'aSdf'::mvarchar; >X+select 'asdf'::mvarchar <= 'aSdf '::mvarchar; >X+select 'asdf'::mvarchar <= 'aSdf 1'::mvarchar(4); >X+select 'asdf'::mvarchar <= 'aSdf 1'::mvarchar(5); >X+select 'asdf'::mvarchar <= 'aSdf 1'::mvarchar(6); >X+ >X+select 'asdf'::mvarchar >= 'aSdf'::mvarchar; >X+select 'asdf'::mvarchar >= 'aSdf '::mvarchar; >X+select 'asdf'::mvarchar >= 'aSdf 1'::mvarchar(4); >X+select 'asdf'::mvarchar >= 'aSdf 1'::mvarchar(5); >X+select 'asdf'::mvarchar >= 'aSdf 1'::mvarchar(6); >X+ >X+select 'asdf'::mvarchar > 'aSdf'::mvarchar; >X+select 'asdf'::mvarchar > 'aSdf '::mvarchar; >X+select 'asdf'::mvarchar > 'aSdf 1'::mvarchar(4); >X+select 'asdf'::mvarchar > 'aSdf 1'::mvarchar(5); >X+select 'asdf'::mvarchar > 'aSdf 1'::mvarchar(6); >X+ >X+select max(vch) from chvch; >X+select min(vch) from chvch; >X+ >X+select substr('1234567890'::mvarchar, 3) = '34567890' as "34567890"; >X+select substr('1234567890'::mvarchar, 4, 3) = '456' as "456"; >X+ >X+select lower('asdfASDF'::mvarchar); >X+select upper('asdfASDF'::mvarchar); >X+ >X+select 'asd'::mvarchar == 'aSd'::mvarchar; >X+select 'asd'::mvarchar == 'aCd'::mvarchar; >X+select 'asd'::mvarchar == NULL; >X+select NULL == 'aCd'::mvarchar; >X+select NULL::mvarchar == NULL; >X+ >Xdiff --git a/contrib/mchar/uninstall_mchar.sql b/contrib/mchar/uninstall_mchar.sql >Xnew file mode 100644 >Xindex 0000000..59f61e2 >X--- /dev/null >X+++ contrib/mchar/uninstall_mchar.sql >X@@ -0,0 +1,9 @@ >X+SET search_path = public; >X+BEGIN; >X+ >X+DROP FUNCTION mchar_pattern_fixed_prefix(internal, internal, internal); >X+DROP FUNCTION mchar_greaterstring(internal); >X+DROP TYPE MCHAR CASCADE; >X+DROP TYPE MVARCHAR CASCADE; >X+ >X+COMMIT; >Xdiff -ur src/backend/nodes/outfuncs.c src/backend/nodes/outfuncs.c >X--- src/backend/nodes/outfuncs.c 2014-07-21 22:12:31.000000000 +0300 >X+++ src/backend/nodes/outfuncs.c 2015-01-14 19:50:20.000000000 +0200 >X@@ -1582,6 +1582,7 @@ >X _outPathInfo(str, (const Path *) node); >X >X WRITE_NODE_FIELD(subpaths); >X+ WRITE_BOOL_FIELD(pull_tlist); >X } >X >X static void >Xdiff -ur src/backend/optimizer/path/allpaths.c src/backend/optimizer/path/allpaths.c >X--- src/backend/optimizer/path/allpaths.c 2014-07-21 22:12:31.000000000 +0300 >X+++ src/backend/optimizer/path/allpaths.c 2015-01-14 20:00:06.000000000 +0200 >X@@ -385,6 +385,9 @@ >X /* Consider index scans */ >X create_index_paths(root, rel); >X >X+ /* Consider index scans with rewrited quals */ >X+ keybased_rewrite_index_paths(root, rel); >X+ >X /* Consider TID scans */ >X create_tidscan_paths(root, rel); >X >X@@ -782,7 +785,7 @@ >X * (Note: this is correct even if we have zero or one live subpath due to >X * constraint exclusion.) >X */ >X- add_path(rel, (Path *) create_append_path(rel, subpaths, NULL)); >X+ add_path(rel, (Path *) create_append_path(rel, subpaths, NULL, false, NIL)); >X >X /* >X * Build unparameterized MergeAppend paths based on the collected list of >X@@ -830,7 +833,7 @@ >X >X if (subpaths_valid) >X add_path(rel, (Path *) >X- create_append_path(rel, subpaths, required_outer)); >X+ create_append_path(rel, subpaths, required_outer, false, NIL)); >X } >X >X /* Select cheapest paths */ >X@@ -1059,7 +1062,7 @@ >X /* Discard any pre-existing paths; no further need for them */ >X rel->pathlist = NIL; >X >X- add_path(rel, (Path *) create_append_path(rel, NIL, NULL)); >X+ add_path(rel, (Path *) create_append_path(rel, NIL, NULL, false, NIL)); >X >X /* Select cheapest path (pretty easy in this case...) */ >X set_cheapest(rel); >Xdiff -ur src/backend/optimizer/path/indxpath.c src/backend/optimizer/path/indxpath.c >X--- src/backend/optimizer/path/indxpath.c 2014-07-21 22:12:31.000000000 +0300 >X+++ src/backend/optimizer/path/indxpath.c 2015-01-14 22:42:37.000000000 +0200 >X@@ -38,6 +38,13 @@ >X #include "utils/pg_locale.h" >X #include "utils/selfuncs.h" >X >X+/* >X+ * index support for LIKE mchar >X+ */ >X+#include "fmgr.h" >X+#include "utils/lsyscache.h" >X+#include "utils/syscache.h" >X+#include "parser/parse_type.h" >X >X #define IsBooleanOpfamily(opfamily) \ >X ((opfamily) == BOOL_BTREE_FAM_OID || (opfamily) == BOOL_HASH_FAM_OID) >X@@ -2936,6 +2943,208 @@ >X return false; >X } >X >X+ /**************************************************************************** >X+ * ---- ROUTINES FOR "SPECIAL" INDEXABLE OPERATORS FOR >X+ * SPECIAL USER_DEFINED TYPES ---- >X+ * -- teodor >X+ ****************************************************************************/ >X+ >X+static Oid mmPFPOid = InvalidOid; >X+static Oid mmGTOid = InvalidOid; >X+static Oid mcharOid = InvalidOid; >X+static Oid mvarcharOid = InvalidOid; >X+ >X+static bool >X+fillMCharOIDS() { >X+ CatCList *catlist; >X+ HeapTuple tup; >X+ char *funcname = "mchar_pattern_fixed_prefix"; >X+ int n_members; >X+ >X+ catlist = SearchSysCacheList(PROCNAMEARGSNSP, 1, >X+ CStringGetDatum(funcname), >X+ 0, 0, 0); >X+ n_members = catlist->n_members; >X+ >X+ if ( n_members != 1 ) { >X+ ReleaseSysCacheList(catlist); >X+ if ( n_members > 1 ) >X+ elog(ERROR,"There are %d candidates for '%s' function'", n_members, funcname); >X+ return false; >X+ } >X+ >X+ tup = &catlist->members[0]->tuple; >X+ >X+ if ( HeapTupleGetOid(tup) != mmPFPOid ) { >X+ TypeName *typename; >X+ Type typtup; >X+ char *quals_funcname = "mchar_greaterstring"; >X+ Oid tmp_mmPFPOid = HeapTupleGetOid(tup); >X+ >X+ ReleaseSysCacheList(catlist); >X+ >X+ typename = makeTypeName("mchar"); >X+ typtup = LookupTypeName(NULL, typename, NULL); >X+ if ( typtup ) { >X+ mcharOid = typeTypeId(typtup); >X+ ReleaseSysCache(typtup); >X+ } >X+ >X+ typename = makeTypeName("mvarchar"); >X+ typtup = LookupTypeName(NULL, typename, NULL); >X+ if ( typtup ) { >X+ mvarcharOid = typeTypeId(typtup); >X+ ReleaseSysCache(typtup); >X+ } >X+ >X+ >X+ if ( mcharOid == InvalidOid || mvarcharOid == InvalidOid ) { >X+ elog(LOG,"Can't find mchar/mvarvarchar types: mchar=%d mvarchar=%d", >X+ mcharOid, mvarcharOid); >X+ return false; >X+ } >X+ >X+ catlist = SearchSysCacheList(PROCNAMEARGSNSP, 1, >X+ CStringGetDatum(quals_funcname), >X+ 0, 0, 0); >X+ n_members = catlist->n_members; >X+ >X+ if ( n_members != 1 ) { >X+ ReleaseSysCacheList(catlist); >X+ if ( n_members > 1 ) >X+ elog(ERROR,"There are %d candidates for '%s' function'", n_members, quals_funcname); >X+ return false; >X+ } >X+ >X+ tup = &catlist->members[0]->tuple; >X+ mmGTOid = HeapTupleGetOid(tup); >X+ mmPFPOid = tmp_mmPFPOid; >X+ } >X+ >X+ ReleaseSysCacheList(catlist); >X+ >X+ return true; >X+} >X+ >X+static Pattern_Prefix_Status >X+mchar_pattern_fixed_prefix(Oid opOid, Oid opfamilyOid, Const *patt, Pattern_Type ptype, >X+ Const **prefix, Oid *leftTypeOid) { >X+ HeapTuple tup; >X+ Form_pg_operator oprForm; >X+ bool isMCharLike = true; >X+ >X+ if ( !fillMCharOIDS() ) >X+ return Pattern_Prefix_None; >X+ >X+ tup = SearchSysCache(OPEROID, opOid, 0, 0, 0); >X+ oprForm = (Form_pg_operator) GETSTRUCT(tup); >X+ >X+ if ( strncmp(oprForm->oprname.data, "~~", 2) != 0 ) >X+ isMCharLike = false; >X+ >X+ if ( oprForm->oprright != mvarcharOid ) >X+ isMCharLike = false; >X+ >X+ if ( !( oprForm->oprleft == mcharOid || oprForm->oprleft == mvarcharOid ) ) >X+ isMCharLike = false; >X+ >X+ if ( patt->consttype != mvarcharOid ) >X+ isMCharLike = false; >X+ >X+ if (leftTypeOid) >X+ *leftTypeOid = oprForm->oprleft; >X+ >X+ ReleaseSysCache(tup); >X+ >X+ if ( !isMCharLike ) >X+ return Pattern_Prefix_None; >X+ >X+ if ( opfamilyOid != InvalidOid ) { >X+ Form_pg_opfamily claForm; >X+ >X+ tup = SearchSysCache(OPFAMILYOID, opfamilyOid, 0, 0, 0); >X+ claForm = (Form_pg_opfamily) GETSTRUCT(tup); >X+ >X+ if ( claForm->opfmethod != BTREE_AM_OID ) >X+ isMCharLike = false; >X+ >X+ if ( mcharOid && strncmp(claForm->opfname.data, "icase_ops", 9 /* strlen(icase_ops) */ ) != 0 ) >X+ isMCharLike = false; >X+ >X+ ReleaseSysCache(tup); >X+ } >X+ >X+ if ( !isMCharLike ) >X+ return Pattern_Prefix_None; >X+ >X+ return (Pattern_Prefix_Status)DatumGetInt32( OidFunctionCall3( >X+ mmPFPOid, >X+ PointerGetDatum( patt ), >X+ Int32GetDatum( ptype ), >X+ PointerGetDatum( prefix ) >X+ ) ); >X+} >X+ >X+static Oid >X+get_opclass_member_mchar(Oid opclass, Oid leftTypeOid, int strategy) { >X+ Oid oproid; >X+ >X+ oproid = get_opfamily_member(opclass, leftTypeOid, mvarcharOid, strategy); >X+ >X+ if ( oproid == InvalidOid ) >X+ elog(ERROR, "no operator for opclass %u for strategy %u for left type %u", opclass, strategy, leftTypeOid); >X+ >X+ return oproid; >X+} >X+ >X+static List * >X+mchar_prefix_quals(Node *leftop, Oid leftTypeOid, Oid opclass, >X+ Const *prefix_const, Pattern_Prefix_Status pstatus) { >X+ Oid oproid; >X+ Expr *expr; >X+ List *result; >X+ Const *greaterstr; >X+ >X+ Assert(pstatus != Pattern_Prefix_None); >X+ if ( pstatus == Pattern_Prefix_Exact ) { >X+ oproid = get_opclass_member_mchar(opclass, leftTypeOid, BTEqualStrategyNumber); >X+ >X+ expr = make_opclause(oproid, BOOLOID, false, >X+ (Expr *) leftop, (Expr *) prefix_const, >X+ InvalidOid, InvalidOid); >X+ result = list_make1(make_simple_restrictinfo(expr)); >X+ return result; >X+ } >X+ >X+ /* We can always say "x >= prefix". */ >X+ oproid = get_opclass_member_mchar(opclass, leftTypeOid, BTGreaterEqualStrategyNumber); >X+ >X+ expr = make_opclause(oproid, BOOLOID, false, >X+ (Expr *) leftop, (Expr *) prefix_const, >X+ InvalidOid, InvalidOid); >X+ result = list_make1(make_simple_restrictinfo(expr)); >X+ >X+ /* If we can create a string larger than the prefix, we can say >X+ * "x < greaterstr". */ >X+ >X+ greaterstr = (Const*)DatumGetPointer( OidFunctionCall1( >X+ mmGTOid, >X+ PointerGetDatum( prefix_const ) >X+ ) ); >X+ >X+ if (greaterstr) { >X+ oproid = get_opclass_member_mchar(opclass, leftTypeOid, BTLessStrategyNumber); >X+ >X+ expr = make_opclause(oproid, BOOLOID, false, >X+ (Expr *) leftop, (Expr *) greaterstr, >X+ InvalidOid, InvalidOid); >X+ result = lappend(result, make_simple_restrictinfo(expr)); >X+ } >X+ >X+ return result; >X+} >X+ >X+ >X /**************************************************************************** >X * ---- ROUTINES FOR "SPECIAL" INDEXABLE OPERATORS ---- >X ****************************************************************************/ >X@@ -3128,9 +3337,16 @@ >X pfree(prefix); >X } >X >X- /* done if the expression doesn't look indexable */ >X- if (!isIndexable) >X+ if ( !isIndexable ) { >X+ /* done if the expression doesn't look indexable, >X+ but we should previously check it for mchar/mvarchar types */ >X+ if ( mchar_pattern_fixed_prefix(expr_op, InvalidOid, >X+ patt, Pattern_Type_Like, >X+ &prefix, NULL) != Pattern_Prefix_None ) { >X+ return true; >X+ } >X return false; >X+ } >X >X /* >X * Must also check that index's opfamily supports the operators we will >X@@ -3381,6 +3597,14 @@ >X Const *patt = (Const *) rightop; >X Const *prefix = NULL; >X Pattern_Prefix_Status pstatus; >X+ Oid leftTypeOid; >X+ >X+ pstatus = mchar_pattern_fixed_prefix(expr_op, opfamily, >X+ patt, Pattern_Type_Like, >X+ &prefix, &leftTypeOid); >X+ >X+ if ( pstatus != Pattern_Prefix_None ) >X+ return mchar_prefix_quals(leftop, leftTypeOid, opfamily, prefix, pstatus); >X >X /* >X * LIKE and regex operators are not members of any btree index opfamily, >Xdiff -ur src/backend/optimizer/path/joinrels.c src/backend/optimizer/path/joinrels.c >X--- src/backend/optimizer/path/joinrels.c 2014-07-21 22:12:31.000000000 +0300 >X+++ src/backend/optimizer/path/joinrels.c 2015-01-14 22:45:18.000000000 +0200 >X@@ -979,7 +979,7 @@ >X rel->pathlist = NIL; >X >X /* Set up the dummy path */ >X- add_path(rel, (Path *) create_append_path(rel, NIL, NULL)); >X+ add_path(rel, (Path *) create_append_path(rel, NIL, NULL, false, NIL)); >X >X /* Set or update cheapest_total_path and related fields */ >X set_cheapest(rel); >Xdiff -ur src/backend/optimizer/path/orindxpath.c src/backend/optimizer/path/orindxpath.c >X--- src/backend/optimizer/path/orindxpath.c 2014-07-21 22:12:31.000000000 +0300 >X+++ src/backend/optimizer/path/orindxpath.c 2015-01-14 22:53:18.000000000 +0200 >X@@ -15,10 +15,58 @@ >X >X #include "postgres.h" >X >X+#include "access/skey.h" >X+#include "catalog/pg_am.h" >X #include "optimizer/cost.h" >X+#include "optimizer/clauses.h" >X #include "optimizer/paths.h" >X+#include "optimizer/pathnode.h" >X+#include "optimizer/planmain.h" >X+#include "optimizer/predtest.h" >X #include "optimizer/restrictinfo.h" >X+#include "utils/lsyscache.h" >X >X+typedef struct CKey { >X+ RestrictInfo *rinfo; /* original rinfo */ >X+ int n; /* IndexPath's number in bitmapquals */ >X+ OpExpr *normalizedexpr; /* expression with Var on left */ >X+ Var *var; >X+ Node *value; >X+ Oid opfamily; >X+ int strategy; >X+ uint8 strategyMask; >X+} CKey; >X+#define BTMASK(x) ( 1<<(x) ) >X+ >X+static List* find_common_quals( BitmapOrPath *path ); >X+static RestrictInfo* unionOperation(CKey *key); >X+static BitmapOrPath* cleanup_nested_quals( PlannerInfo *root, RelOptInfo *rel, BitmapOrPath *path ); >X+static List* sortIndexScans( List* ipaths ); >X+static List* reverseScanDirIdxPaths(List *indexPaths); >X+static IndexPath* reverseScanDirIdxPath(IndexPath *ipath); >X+ >X+#define IS_LESS(a) ( (a) == BTLessStrategyNumber || (a)== BTLessEqualStrategyNumber ) >X+#define IS_GREATER(a) ( (a) == BTGreaterStrategyNumber || (a) == BTGreaterEqualStrategyNumber ) >X+#define IS_ONE_DIRECTION(a,b) ( \ >X+ ( IS_LESS(a) && IS_LESS(b) ) \ >X+ || \ >X+ ( IS_GREATER(a) && IS_GREATER(b) ) \ >X+) >X+ >X+typedef struct ExExpr { >X+ OpExpr *expr; >X+ Oid opfamily; >X+ Oid lefttype; >X+ Oid righttype; >X+ int strategy; >X+ int attno; >X+} ExExpr; >X+ >X+ >X+typedef struct IndexPathEx { >X+ IndexPath *path; >X+ List *preparedquals; /* list of ExExpr */ >X+} IndexPathEx; >X >X /*---------- >X * create_or_index_quals >X@@ -185,3 +233,912 @@ >X /* Tell caller to recompute partial index status and rowcount estimate */ >X return true; >X } >X+ >X+ >X+/*---------- >X+ * keybased_rewrite_or_index_quals >X+ * Examine join OR-of-AND quals to see if any useful common restriction >X+ * clauses can be extracted. If so, try to use for creating new index paths. >X+ * >X+ * For example consider >X+ * WHERE ( a.x=5 and a.y>10 ) OR a.x>5 >X+ * and there is an index on a.x or (a.x, a.y). So, plan >X+ * will be seqscan or BitmapOr(IndexPath,IndexPath) >X+ * So, we can add some restriction: >X+ * WHERE (( a.x=5 and a.y>10 ) OR a.x>5) AND a.x>=5 >X+ * and plan may be so >X+ * Index Scan (a.x>=5) >X+ * Filter( (( a.x=5 and a.y>10 ) OR a.x>5) ) >X+ * >X+ * We don't want to add new clauses to baserestrictinfo, just >X+ * use it as index quals. >X+ * >X+ * Next thing which it possible to test is use append of >X+ * searches instead of OR. >X+ * For example consider >X+ * WHERE ( a.x=5 and a.y>10 ) OR a.x>6 >X+ * and there is an index on (a.x) (a.x, a.y) >X+ * So, we can suggest follow plan: >X+ * Append >X+ * Filter ( a.x=5 and a.y>10 ) OR (a.x>6) >X+ * Index Scan (a.x=5) --in case of index on (a.x) >X+ * Index Scan (a.x>6) >X+ * For that we should proof that index quals isn't overlapped, >X+ * also, some index quals may be containedi in other, so it can be eliminated >X+ */ >X+ >X+void >X+keybased_rewrite_index_paths(PlannerInfo *root, RelOptInfo *rel) >X+{ >X+ BitmapOrPath *bestpath = NULL; >X+ ListCell *i; >X+ List *commonquals; >X+ AppendPath *appendidxpath; >X+ List *indexPaths; >X+ IndexOptInfo *index; >X+ >X+ foreach(i, rel->baserestrictinfo) >X+ { >X+ RestrictInfo *rinfo = (RestrictInfo *) lfirst(i); >X+ >X+ if (restriction_is_or_clause(rinfo) && >X+ !rinfo->outerjoin_delayed) >X+ { >X+ /* >X+ * Use the generate_bitmap_or_paths() machinery to estimate the >X+ * value of each OR clause. We can use regular restriction >X+ * clauses along with the OR clause contents to generate >X+ * indexquals. We pass outer_rel = NULL so that sub-clauses >X+ * that are actually joins will be ignored. >X+ */ >X+ List *orpaths; >X+ ListCell *k; >X+ >X+ orpaths = generate_bitmap_or_paths(root, rel, >X+ list_make1(rinfo), >X+ rel->baserestrictinfo, >X+ true); >X+ >X+ /* Locate the cheapest OR path */ >X+ foreach(k, orpaths) >X+ { >X+ BitmapOrPath *path = (BitmapOrPath *) lfirst(k); >X+ >X+ Assert(IsA(path, BitmapOrPath)); >X+ if (bestpath == NULL || >X+ path->path.total_cost < bestpath->path.total_cost) >X+ { >X+ bestpath = path; >X+ } >X+ } >X+ } >X+ } >X+ >X+ /* Fail if no suitable clauses found */ >X+ if (bestpath == NULL) >X+ return; >X+ >X+ commonquals = find_common_quals(bestpath); >X+ /* Found quals with the same args, but with, may be, different >X+ operations */ >X+ if ( commonquals != NULL ) { >X+ List *addon=NIL; >X+ >X+ foreach(i, commonquals) { >X+ CKey *key = (CKey*)lfirst(i); >X+ RestrictInfo *rinfo; >X+ >X+ /* >X+ * get 'union' of operation for key >X+ */ >X+ rinfo = unionOperation(key); >X+ if ( rinfo ) >X+ addon = lappend(addon, rinfo); >X+ } >X+ >X+ /* >X+ * Ok, we found common quals and union it, so we will try to >X+ * create new possible index paths >X+ */ >X+ if ( addon ) { >X+ List *origbaserestrictinfo = list_copy(rel->baserestrictinfo); >X+ >X+ rel->baserestrictinfo = list_concat(rel->baserestrictinfo, addon); >X+ >X+ create_index_paths(root, rel); >X+ >X+ rel->baserestrictinfo = origbaserestrictinfo; >X+ } >X+ } >X+ >X+ /* >X+ * Check if indexquals isn't overlapped and all index scan >X+ * are on the same index. >X+ */ >X+ if ( (bestpath = cleanup_nested_quals( root, rel, bestpath )) == NULL ) >X+ return; >X+ >X+ if (IsA(bestpath, IndexPath)) { >X+ IndexPath *ipath = (IndexPath*)bestpath; >X+ >X+ Assert(list_length(ipath->indexquals) == list_length(ipath->indexqualcols)); >X+ /* >X+ * It's possible to do only one index scan :) >X+ */ >X+ index = ipath->indexinfo; >X+ >X+ if ( root->query_pathkeys != NIL && index->sortopfamily && OidIsValid(index->sortopfamily[0]) ) >X+ { >X+ List *pathkeys; >X+ >X+ pathkeys = build_index_pathkeys(root, index, >X+ ForwardScanDirection); >X+ pathkeys = truncate_useless_pathkeys(root, rel, >X+ pathkeys); >X+ >X+ ipath->path.pathkeys = pathkeys; >X+ add_path(rel, (Path *) ipath); >X+ >X+ /* >X+ * add path ordered in backward direction if our pathkeys >X+ * is still unusable... >X+ */ >X+ if ( pathkeys == NULL || pathkeys_useful_for_ordering(root, pathkeys) == 0 ) >X+ { >X+ pathkeys = build_index_pathkeys(root, index, >X+ BackwardScanDirection); >X+ pathkeys = truncate_useless_pathkeys(root, rel, >X+ pathkeys); >X+ >X+ ipath = reverseScanDirIdxPath( ipath ); >X+ >X+ ipath->path.pathkeys = pathkeys; >X+ add_path(rel, (Path *) ipath); >X+ } >X+ } else >X+ add_path(rel, (Path *) ipath); >X+ return; >X+ } >X+ >X+ /* recount costs */ >X+ foreach(i, bestpath->bitmapquals ) { >X+ IndexPath *ipath = (IndexPath*)lfirst(i); >X+ >X+ Assert( IsA(ipath, IndexPath) ); >X+ Assert(list_length(ipath->indexquals) == list_length(ipath->indexqualcols)); >X+ ipath->path.rows = rel->tuples * clauselist_selectivity(root, >X+ ipath->indexquals, >X+ rel->relid, >X+ JOIN_INNER, >X+ NULL); >X+ ipath->path.rows = clamp_row_est(ipath->path.rows); >X+ cost_index(ipath, root, 1); >X+ } >X+ >X+ /* >X+ * Check if append index can suggest ordering of result >X+ * >X+ * Also, we should say to AppendPath about targetlist: >X+ * target list will be taked from indexscan >X+ */ >X+ index = ((IndexPath*)linitial(bestpath->bitmapquals))->indexinfo; >X+ if ( root->query_pathkeys != NIL && index->sortopfamily && OidIsValid(index->sortopfamily[0]) && >X+ (indexPaths = sortIndexScans( bestpath->bitmapquals )) !=NULL ) { >X+ List *pathkeys; >X+ >X+ pathkeys = build_index_pathkeys(root, index, >X+ ForwardScanDirection); >X+ pathkeys = truncate_useless_pathkeys(root, rel, >X+ pathkeys); >X+ >X+ appendidxpath = create_append_path(rel, indexPaths, NULL, true, pathkeys); >X+ add_path(rel, (Path *) appendidxpath); >X+ >X+ /* >X+ * add path ordered in backward direction if our pathkeys >X+ * is still unusable... >X+ */ >X+ if ( pathkeys == NULL || pathkeys_useful_for_ordering(root, pathkeys) == 0 ) { >X+ >X+ pathkeys = build_index_pathkeys(root, index, >X+ BackwardScanDirection); >X+ pathkeys = truncate_useless_pathkeys(root, rel, >X+ pathkeys); >X+ >X+ indexPaths = reverseScanDirIdxPaths(indexPaths); >X+ appendidxpath = create_append_path(rel, indexPaths, NULL, true, pathkeys); >X+ add_path(rel, (Path *) appendidxpath); >X+ } >X+ } else { >X+ appendidxpath = create_append_path(rel, bestpath->bitmapquals, NULL, true, NIL); >X+ add_path(rel, (Path *) appendidxpath); >X+ } >X+} >X+ >X+/* >X+ * transformToCkey - transform RestrictionInfo >X+ * to CKey struct. Fucntion checks possibility and correctness of >X+ * RestrictionInfo to use it as common key, normalizes >X+ * expression and "caches" some information. Note, >X+ * original RestrictInfo isn't touched >X+ */ >X+ >X+static CKey* >X+transformToCkey( IndexOptInfo *index, RestrictInfo* rinfo, int indexcol) { >X+ CKey *key; >X+ OpExpr *expr = (OpExpr*)rinfo->clause; >X+ >X+ if ( rinfo->outerjoin_delayed ) >X+ return NULL; >X+ >X+ if ( !IsA(expr, OpExpr) ) >X+ return NULL; >X+ >X+ if ( contain_mutable_functions((Node*)expr) ) >X+ return NULL; >X+ >X+ if ( list_length( expr->args ) != 2 ) >X+ return NULL; >X+ >X+ key = (CKey*)palloc(sizeof(CKey)); >X+ key->rinfo = rinfo; >X+ >X+ key->normalizedexpr = (OpExpr*)copyObject( expr ); >X+ if (!bms_equal(rinfo->left_relids, index->rel->relids)) >X+ CommuteOpExpr(key->normalizedexpr); >X+ >X+ /* >X+ * fix_indexqual_operand returns copy of object >X+ */ >X+ key->var = (Var*)fix_indexqual_operand(linitial(key->normalizedexpr->args), index, indexcol); >X+ Assert( IsA(key->var, Var) ); >X+ >X+ key->opfamily = index->opfamily[ key->var->varattno - 1 ]; >X+ >X+ /* restore varattno, because it may be different in different index */ >X+ key->var->varattno = key->var->varoattno; >X+ >X+ key->value = (Node*)lsecond(key->normalizedexpr->args); >X+ >X+ key->strategy = get_op_opfamily_strategy( key->normalizedexpr->opno, key->opfamily); >X+ Assert( key->strategy != InvalidStrategy ); >X+ >X+ key->strategyMask = BTMASK(key->strategy); >X+ >X+ return key; >X+} >X+ >X+/* >X+ * get_index_quals - get list of quals in >X+ * CKeys form >X+ */ >X+ >X+static List* >X+get_index_quals(IndexPath *path, int cnt) { >X+ ListCell *i, *c; >X+ List *quals = NIL; >X+ >X+ Assert(list_length(path->indexquals) == list_length(path->indexqualcols)); >X+ forboth(i, path->indexquals, c, path->indexqualcols) { >X+ CKey *k = transformToCkey( path->indexinfo, (RestrictInfo*)lfirst(i), lfirst_int(c) ); >X+ if ( k ) { >X+ k->n = cnt; >X+ quals = lappend(quals, k); >X+ } >X+ } >X+ return quals; >X+} >X+ >X+/* >X+ * extract all quals from bitmapquals->indexquals for >X+ */ >X+static List* >X+find_all_quals( BitmapOrPath *path, int *counter ) { >X+ ListCell *i,*j; >X+ List *allquals = NIL; >X+ >X+ *counter = 0; >X+ >X+ foreach(i, path->bitmapquals ) >X+ { >X+ Path *subpath = (Path *) lfirst(i); >X+ >X+ if ( IsA(subpath, BitmapAndPath) ) { >X+ foreach(j, ((BitmapAndPath*)subpath)->bitmapquals) { >X+ Path *subsubpath = (Path *) lfirst(i); >X+ >X+ if ( IsA(subsubpath, IndexPath) ) { >X+ if ( ((IndexPath*)subsubpath)->indexinfo->relam != BTREE_AM_OID ) >X+ return NIL; >X+ allquals = list_concat(allquals, get_index_quals( (IndexPath*)subsubpath, *counter )); >X+ } else >X+ return NIL; >X+ } >X+ } else if ( IsA(subpath, IndexPath) ) { >X+ if ( ((IndexPath*)subpath)->indexinfo->relam != BTREE_AM_OID ) >X+ return NIL; >X+ allquals = list_concat(allquals, get_index_quals( (IndexPath*)subpath, *counter )); >X+ } else >X+ return NIL; >X+ >X+ (*counter)++; >X+ } >X+ >X+ return allquals; >X+} >X+ >X+/* >X+ * Compares aruments of operation >X+ */ >X+static bool >X+iseqCKeyArgs( CKey *a, CKey *b ) { >X+ if ( a->opfamily != b->opfamily ) >X+ return false; >X+ >X+ if ( !equal( a->value, b->value ) ) >X+ return false; >X+ >X+ if ( !equal( a->var, b->var ) ) >X+ return false; >X+ >X+ return true; >X+} >X+ >X+/* >X+ * Count entries of CKey with the same arguments >X+ */ >X+static int >X+count_entry( List *allquals, CKey *tocmp ) { >X+ ListCell *i; >X+ int curcnt=0; >X+ >X+ foreach(i, allquals) { >X+ CKey *key = lfirst(i); >X+ >X+ if ( key->n == curcnt ) { >X+ continue; >X+ } else if ( key->n == curcnt+1 ) { >X+ if ( iseqCKeyArgs( key, tocmp ) ) { >X+ tocmp->strategyMask |= key->strategyMask; >X+ curcnt++; >X+ } >X+ } else >X+ return -1; >X+ } >X+ >X+ return curcnt+1; >X+} >X+ >X+/* >X+ * Finds all CKey with the same arguments >X+ */ >X+static List* >X+find_common_quals( BitmapOrPath *path ) { >X+ List *allquals; >X+ List *commonquals = NIL; >X+ ListCell *i; >X+ int counter; >X+ >X+ if ( (allquals = find_all_quals( path, &counter ))==NIL ) >X+ return NIL; >X+ >X+ foreach(i, allquals) { >X+ CKey *key = lfirst(i); >X+ >X+ if ( key->n != 0 ) >X+ break; >X+ >X+ if ( counter == count_entry(allquals, key) ) >X+ commonquals = lappend( commonquals, key ); >X+ } >X+ >X+ return commonquals; >X+} >X+ >X+/* >X+ * unionOperation - make RestrictInfo with combined operation >X+ */ >X+ >X+static RestrictInfo* >X+unionOperation(CKey *key) { >X+ RestrictInfo *rinfo; >X+ Oid lefttype, righttype; >X+ int strategy; >X+ >X+ switch( key->strategyMask ) { >X+ case BTMASK(BTLessStrategyNumber): >X+ case BTMASK(BTLessEqualStrategyNumber): >X+ case BTMASK(BTEqualStrategyNumber): >X+ case BTMASK(BTGreaterEqualStrategyNumber): >X+ case BTMASK(BTGreaterStrategyNumber): >X+ /* trivial case */ >X+ break; >X+ case BTMASK(BTLessStrategyNumber) | BTMASK(BTLessEqualStrategyNumber): >X+ case BTMASK(BTLessStrategyNumber) | BTMASK(BTLessEqualStrategyNumber) | BTMASK(BTEqualStrategyNumber): >X+ case BTMASK(BTLessStrategyNumber) | BTMASK(BTEqualStrategyNumber): >X+ case BTMASK(BTLessEqualStrategyNumber) | BTMASK(BTEqualStrategyNumber): >X+ /* any subset of <, <=, = can be unioned with <= */ >X+ key->strategy = BTLessEqualStrategyNumber; >X+ break; >X+ case BTMASK(BTGreaterEqualStrategyNumber) | BTMASK(BTGreaterStrategyNumber): >X+ case BTMASK(BTEqualStrategyNumber) | BTMASK(BTGreaterEqualStrategyNumber) | BTMASK(BTGreaterStrategyNumber): >X+ case BTMASK(BTEqualStrategyNumber) | BTMASK(BTGreaterStrategyNumber): >X+ case BTMASK(BTEqualStrategyNumber) | BTMASK(BTGreaterEqualStrategyNumber): >X+ /* any subset of >, >=, = can be unioned with >= */ >X+ key->strategy = BTGreaterEqualStrategyNumber; >X+ break; >X+ default: >X+ /* >X+ * Can't make common restrict qual >X+ */ >X+ return NULL; >X+ } >X+ >X+ get_op_opfamily_properties(key->normalizedexpr->opno, key->opfamily, false, >X+ &strategy, &lefttype, &righttype); >X+ >X+ if ( strategy != key->strategy ) { >X+ /* >X+ * We should check because it's possible to have "strange" >X+ * opfamilies - without some strategies... >X+ */ >X+ key->normalizedexpr->opno = get_opfamily_member(key->opfamily, lefttype, righttype, key->strategy); >X+ >X+ if ( key->normalizedexpr->opno == InvalidOid ) >X+ return NULL; >X+ >X+ key->normalizedexpr->opfuncid = get_opcode( key->normalizedexpr->opno ); >X+ Assert ( key->normalizedexpr->opfuncid != InvalidOid ); >X+ } >X+ >X+ rinfo = make_simple_restrictinfo((Expr*)key->normalizedexpr); >X+ >X+ return rinfo; >X+} >X+ >X+/* >X+ * Remove unneeded RestrioctionInfo nodes as it >X+ * needed by predicate_*_by() >X+ */ >X+static void >X+make_predicate(List *indexquals, List *indexqualcols, List **preds, List **predcols) { >X+ ListCell *i, *c; >X+ >X+ *preds = NIL; >X+ *predcols = NIL; >X+ >X+ forboth(i, indexquals, c, indexqualcols) >X+ { >X+ RestrictInfo *rinfo = lfirst(i); >X+ OpExpr *expr = (OpExpr*)rinfo->clause; >X+ >X+ if ( rinfo->outerjoin_delayed ) >X+ continue; >X+ >X+ if ( !IsA(expr, OpExpr) ) >X+ continue; >X+ >X+ if ( list_length( expr->args ) != 2 ) >X+ continue; >X+ >X+ *preds = lappend(*preds, rinfo); >X+ *predcols = lappend(*predcols, lfirst(c)); >X+ } >X+} >X+ >X+#define CELL_GET_QUALS(x) ( ((IndexPath*)lfirst(x))->indexquals ) >X+#define CELL_GET_CLAUSES(x) ( ((IndexPath*)lfirst(x))->indexclauses ) >X+ >X+static List* >X+listRInfo2OpExpr(List *listRInfo) { >X+ ListCell *i; >X+ List *listOpExpr=NULL; >X+ >X+ foreach(i, listRInfo) >X+ { >X+ RestrictInfo *rinfo = lfirst(i); >X+ OpExpr *expr = (OpExpr*)rinfo->clause; >X+ >X+ listOpExpr = lappend(listOpExpr, expr); >X+ } >X+ >X+ return listOpExpr; >X+} >X+ >X+/* >X+ * returns list of all nested quals >X+ */ >X+static List* >X+contained_quals(List *nested, List* quals, ListCell *check) { >X+ ListCell *i; >X+ List *checkpred; >X+ >X+ if ( list_member_ptr( nested, lfirst(check) ) ) >X+ return nested; >X+ >X+ if (equal(CELL_GET_QUALS(check), CELL_GET_CLAUSES(check)) == false) >X+ return nested; >X+ >X+ checkpred = listRInfo2OpExpr(CELL_GET_QUALS(check)); >X+ >X+ if ( contain_mutable_functions((Node*)checkpred) ) >X+ return nested; >X+ >X+ foreach(i, quals ) >X+ { >X+ if ( check == i ) >X+ continue; >X+ >X+ if ( list_member_ptr( nested, lfirst(i) ) ) >X+ continue; >X+ >X+ if ( equal(CELL_GET_QUALS(i), CELL_GET_CLAUSES(i)) && >X+ predicate_implied_by( checkpred, CELL_GET_QUALS(i) ) ) >X+ nested = lappend( nested, lfirst(i) ); >X+ } >X+ return nested; >X+} >X+ >X+/* >X+ * Checks that one row can be in several quals. >X+ * It's guaranteed by predicate_refuted_by() >X+ */ >X+static bool >X+is_intersect(ListCell *check) { >X+ ListCell *i; >X+ List *checkpred=NULL; >X+ >X+ checkpred=listRInfo2OpExpr(CELL_GET_QUALS(check)); >X+ Assert( checkpred != NULL ); >X+ >X+ for_each_cell(i, check) { >X+ if ( i==check ) >X+ continue; >X+ >X+ if ( predicate_refuted_by( checkpred, CELL_GET_QUALS(i) ) == false ) >X+ return true; >X+ } >X+ >X+ return false; >X+} >X+ >X+/* >X+ * Removes nested quals and gurantees that quals are not intersected, >X+ * ie one row can't satisfy to several quals. It's open a possibility of >X+ * Append node using instead of BitmapOr >X+ */ >X+static BitmapOrPath* >X+cleanup_nested_quals( PlannerInfo *root, RelOptInfo *rel, BitmapOrPath *path ) { >X+ ListCell *i; >X+ IndexOptInfo *index=NULL; >X+ List *nested = NULL; >X+ >X+ /* >X+ * check all path to use only one index >X+ */ >X+ foreach(i, path->bitmapquals ) >X+ { >X+ >X+ if ( IsA(lfirst(i), IndexPath) ) { >X+ List *preds, *predcols; >X+ IndexPath *subpath = (IndexPath *) lfirst(i); >X+ >X+ if ( subpath->indexinfo->relam != BTREE_AM_OID ) >X+ return NULL; >X+ >X+ if ( index == NULL ) >X+ index = subpath->indexinfo; >X+ else if ( index->indexoid != subpath->indexinfo->indexoid ) >X+ return NULL; >X+ >X+ /* >X+ * work only with optimizable quals >X+ */ >X+ Assert(list_length(subpath->indexquals) == list_length(subpath->indexqualcols)); >X+ make_predicate(subpath->indexquals, subpath->indexqualcols, &preds, &predcols); >X+ if (preds == NIL) >X+ return NULL; >X+ subpath->indexquals = preds; >X+ subpath->indexqualcols = predcols; >X+ Assert(list_length(subpath->indexquals) == list_length(subpath->indexqualcols)); >X+ } else >X+ return NULL; >X+ } >X+ >X+ /* >X+ * eliminate nested quals >X+ */ >X+ foreach(i, path->bitmapquals ) { >X+ nested = contained_quals(nested, path->bitmapquals, i); >X+ } >X+ >X+ if ( nested != NIL ) { >X+ path->bitmapquals = list_difference_ptr( path->bitmapquals, nested ); >X+ >X+ Assert( list_length( path->bitmapquals )>0 ); >X+ >X+ /* >X+ * All quals becomes only one after eliminating nested quals >X+ */ >X+ if (list_length( path->bitmapquals ) == 1) >X+ return (BitmapOrPath*)linitial(path->bitmapquals); >X+ } >X+ >X+ /* >X+ * Checks for intersection >X+ */ >X+ foreach(i, path->bitmapquals ) { >X+ if ( is_intersect( i ) ) >X+ return NULL; >X+ } >X+ >X+ return path; >X+} >X+ >X+/* >X+ * Checks if whole result of one simple operation is contained >X+ * in another >X+ */ >X+static int >X+simpleCmpExpr( ExExpr *a, ExExpr *b ) { >X+ if ( predicate_implied_by((List*)a->expr, (List*)b->expr) ) >X+ /* >X+ * a:( Var < 15 ) > b:( Var <= 10 ) >X+ */ >X+ return 1; >X+ else if ( predicate_implied_by((List*)b->expr, (List*)a->expr) ) >X+ /* >X+ * a:( Var <= 10 ) < b:( Var < 15 ) >X+ */ >X+ return -1; >X+ else >X+ return 0; >X+} >X+ >X+/* >X+ * Trys to define where is equation - on left or right side >X+ * a(< 10) b(=11) - on right >X+ * a(> 10) b(=9) - on left >X+ * a(= 10) b(=11) - on right >X+ * a(= 10) b(=9) - on left >X+ * Any other - result is 0; >X+ */ >X+static int >X+cmpEqExpr( ExExpr *a, ExExpr *b ) { >X+ Oid oldop = b->expr->opno; >X+ int res=0; >X+ >X+ b->expr->opno = get_opfamily_member(b->opfamily, b->lefttype, b->righttype, BTLessStrategyNumber); >X+ if ( b->expr->opno != InvalidOid ) { >X+ b->expr->opfuncid = get_opcode( b->expr->opno ); >X+ res = simpleCmpExpr(a,b); >X+ } >X+ >X+ if ( res == 0 ) { >X+ b->expr->opno = get_opfamily_member(b->opfamily, b->lefttype, b->righttype, BTGreaterStrategyNumber); >X+ if ( b->expr->opno != InvalidOid ) { >X+ b->expr->opfuncid = get_opcode( b->expr->opno ); >X+ res = -simpleCmpExpr(a,b); >X+ } >X+ } >X+ >X+ b->expr->opno = oldop; >X+ b->expr->opfuncid = get_opcode( b->expr->opno ); >X+ >X+ return res; >X+} >X+ >X+/* >X+ * Is result of a contained in result of b or on the contrary? >X+ */ >X+static int >X+cmpNegCmp( ExExpr *a, ExExpr *b ) { >X+ Oid oldop = b->expr->opno; >X+ int res = 0; >X+ >X+ b->expr->opno = get_negator( b->expr->opno ); >X+ if ( b->expr->opno != InvalidOid ) { >X+ b->expr->opfuncid = get_opcode( b->expr->opno ); >X+ res = simpleCmpExpr(a,b); >X+ } >X+ >X+ b->expr->opno = oldop; >X+ b->expr->opfuncid = get_opcode( b->expr->opno ); >X+ >X+ return ( IS_LESS(a->strategy) ) ? res : -res; >X+} >X+ >X+/* >X+ * Returns 1 if whole result of a is on left comparing with result of b >X+ * Returns -1 if whole result of a is on right comparing with result of b >X+ * Return 0 if it's impossible to define or results is overlapped >X+ * Expressions should use the same attribute of index and should be >X+ * a simple: just one operation with index. >X+ */ >X+static int >X+cmpExpr( ExExpr *a, ExExpr *b ) { >X+ int res; >X+ >X+ /* >X+ * If a and b are overlapped, we can't decide which one is >X+ * lefter or righter >X+ */ >X+ if ( IS_ONE_DIRECTION(a->strategy, b->strategy) || predicate_refuted_by((List*)a->expr, (List*)b->expr) == false ) >X+ return 0; >X+ >X+ /* >X+ * In this place it's impossible to have a row which satisfies >X+ * a and b expressions, so we will try to find relatiove position of that results >X+ */ >X+ if ( b->strategy == BTEqualStrategyNumber ) { >X+ return -cmpEqExpr(a, b); /* Covers cases with any operations in a */ >X+ } else if ( a->strategy == BTEqualStrategyNumber ) { >X+ return cmpEqExpr(b, a); >X+ } else if ( (res = cmpNegCmp(a, b)) == 0 ) { /* so, a(<10) b(>20) */ >X+ res = -cmpNegCmp(b, a); >X+ } >X+ >X+ return res; >X+} >X+ >X+/* >X+ * Try to define positions of result which satisfy indexquals a and b per >X+ * one index's attribute. >X+ */ >X+static int >X+cmpColumnQuals( List *a, List *b, int attno ) { >X+ int res = 0; >X+ ListCell *ai, *bi; >X+ >X+ foreach(ai, a) { >X+ ExExpr *ae = (ExExpr*)lfirst(ai); >X+ >X+ if ( attno != ae->attno ) >X+ continue; >X+ >X+ foreach(bi, b) { >X+ ExExpr *be = (ExExpr*)lfirst(bi); >X+ >X+ if ( attno != be->attno ) >X+ continue; >X+ >X+ if ((res=cmpExpr(ae, be))!=0) >X+ return res; >X+ } >X+ } >X+ >X+ return 0; >X+} >X+ >X+static IndexOptInfo *sortingIndex = NULL; >X+static bool volatile unableToDefine = false; >X+ >X+/* >X+ * Compare result of two indexquals. >X+ * Warinig: it use PG_RE_THROW(), so any call should be wrapped with >X+ * PG_TRY(). Try/catch construction is used here for minimize unneeded >X+ * actions when sorting is impossible >X+ */ >X+static int >X+cmpIndexPathEx(const void *a, const void *b) { >X+ IndexPathEx *aipe = (IndexPathEx*)a; >X+ IndexPathEx *bipe = (IndexPathEx*)b; >X+ int attno, res = 0; >X+ >X+ for(attno=1; res==0 && attno<=sortingIndex->ncolumns; attno++) >X+ res=cmpColumnQuals(aipe->preparedquals, bipe->preparedquals, attno); >X+ >X+ if ( res==0 ) { >X+ unableToDefine = true; >X+ PG_RE_THROW(); /* it should be PG_THROW(), but it's the same */ >X+ } >X+ >X+ return res; >X+} >X+ >X+/* >X+ * Initialize lists of operation in useful form >X+ */ >X+static List* >X+prepareQuals(IndexOptInfo *index, List *indexquals, List *indexqualcols) { >X+ ListCell *i, *c; >X+ List *res=NULL; >X+ ExExpr *ex; >X+ >X+ Assert(list_length(indexquals) == list_length(indexqualcols)); >X+ forboth(i, indexquals, c, indexqualcols) >X+ { >X+ RestrictInfo *rinfo = lfirst(i); >X+ OpExpr *expr = (OpExpr*)rinfo->clause; >X+ >X+ if ( rinfo->outerjoin_delayed ) >X+ return NULL; >X+ >X+ if ( !IsA(expr, OpExpr) ) >X+ return NULL; >X+ >X+ if ( list_length( expr->args ) != 2 ) >X+ return NULL; >X+ >X+ if ( contain_mutable_functions((Node*)expr) ) >X+ return NULL; >X+ >X+ ex = (ExExpr*)palloc(sizeof(ExExpr)); >X+ ex->expr = (OpExpr*)copyObject( expr ); >X+ if (!bms_equal(rinfo->left_relids, index->rel->relids)) >X+ CommuteOpExpr(ex->expr); >X+ linitial(ex->expr->args) = fix_indexqual_operand(linitial(ex->expr->args), index, lfirst_int(c)); >X+ ex->attno = ((Var*)linitial(ex->expr->args))->varattno; >X+ ex->opfamily = index->opfamily[ ex->attno - 1 ]; >X+ get_op_opfamily_properties( ex->expr->opno, ex->opfamily, false, >X+ &ex->strategy, &ex->lefttype, &ex->righttype); >X+ >X+ >X+ res = lappend(res, ex); >X+ } >X+ >X+ return res; >X+} >X+ >X+/* >X+ * sortIndexScans - sorts index scans to get sorted results. >X+ * Function supposed that index is the same for all >X+ * index scans >X+ */ >X+static List* >X+sortIndexScans( List* ipaths ) { >X+ ListCell *i; >X+ int j=0; >X+ IndexPathEx *ipe = (IndexPathEx*)palloc( sizeof(IndexPathEx)*list_length(ipaths) ); >X+ List *orderedPaths = NIL; >X+ IndexOptInfo *index = ((IndexPath*)linitial(ipaths))->indexinfo; >X+ >X+ foreach(i, ipaths) { >X+ ipe[j].path = (IndexPath*)lfirst(i); >X+ ipe[j].preparedquals = prepareQuals( index, ipe[j].path->indexquals, ipe[j].path->indexqualcols ); >X+ >X+ if (ipe[j].preparedquals == NULL) >X+ return NULL; >X+ j++; >X+ } >X+ >X+ sortingIndex = index; >X+ unableToDefine = false; >X+ PG_TRY(); { >X+ qsort(ipe, list_length(ipaths), sizeof(IndexPathEx), cmpIndexPathEx); >X+ } PG_CATCH(); { >X+ if ( unableToDefine == false ) >X+ PG_RE_THROW(); /* not our problem */ >X+ } PG_END_TRY(); >X+ >X+ if ( unableToDefine == true ) >X+ return NULL; >X+ >X+ for(j=0;j<list_length(ipaths);j++) >X+ orderedPaths = lappend(orderedPaths, ipe[j].path); >X+ >X+ return orderedPaths; >X+} >X+ >X+static IndexPath* >X+reverseScanDirIdxPath(IndexPath *ipath) { >X+ IndexPath *n = makeNode(IndexPath); >X+ >X+ *n = *ipath; >X+ >X+ n->indexscandir = BackwardScanDirection; >X+ >X+ return n; >X+} >X+ >X+static List* >X+reverseScanDirIdxPaths(List *indexPaths) { >X+ List *idxpath = NIL; >X+ ListCell *i; >X+ >X+ foreach(i, indexPaths) { >X+ idxpath = lcons(reverseScanDirIdxPath( (IndexPath*)lfirst(i) ), idxpath); >X+ } >X+ >X+ return idxpath; >X+} >Xdiff -ur src/backend/optimizer/path/pathkeys.c src/backend/optimizer/path/pathkeys.c >X--- src/backend/optimizer/path/pathkeys.c 2014-07-21 22:12:31.000000000 +0300 >X+++ src/backend/optimizer/path/pathkeys.c 2015-01-14 22:55:44.000000000 +0200 >X@@ -1429,7 +1429,7 @@ >X * no good to order by just the first key(s) of the requested ordering. >X * So the result is always either 0 or list_length(root->query_pathkeys). >X */ >X-static int >X+int >X pathkeys_useful_for_ordering(PlannerInfo *root, List *pathkeys) >X { >X if (root->query_pathkeys == NIL) >Xdiff -ur src/backend/optimizer/plan/createplan.c src/backend/optimizer/plan/createplan.c >X--- src/backend/optimizer/plan/createplan.c 2014-07-21 22:12:31.000000000 +0300 >X+++ src/backend/optimizer/plan/createplan.c 2015-01-14 23:05:39.000000000 +0200 >X@@ -86,7 +86,6 @@ >X static Node *replace_nestloop_params_mutator(Node *node, PlannerInfo *root); >X static List *fix_indexqual_references(PlannerInfo *root, IndexPath *index_path); >X static List *fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path); >X-static Node *fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol); >X static List *get_switched_clauses(List *clauses, Relids outerrelids); >X static List *order_qual_clauses(PlannerInfo *root, List *clauses); >X static void copy_path_costsize(Plan *dest, Path *src); >X@@ -664,7 +663,7 @@ >X create_append_plan(PlannerInfo *root, AppendPath *best_path) >X { >X Append *plan; >X- List *tlist = build_relation_tlist(best_path->path.parent); >X+ List *tlist; >X List *subplans = NIL; >X ListCell *subpaths; >X >X@@ -680,6 +679,7 @@ >X if (best_path->subpaths == NIL) >X { >X /* Generate a Result plan with constant-FALSE gating qual */ >X+ tlist = build_relation_tlist(best_path->path.parent); >X return (Plan *) make_result(root, >X tlist, >X (Node *) list_make1(makeBoolConst(false, >X@@ -695,6 +695,11 @@ >X subplans = lappend(subplans, create_plan_recurse(root, subpath)); >X } >X >X+ if ( best_path->pull_tlist ) { >X+ tlist = copyObject( ((Plan*)linitial(subplans))->targetlist ); >X+ } else >X+ tlist = build_relation_tlist(best_path->path.parent); >X+ >X plan = make_append(subplans, tlist); >X >X return (Plan *) plan; >X@@ -2798,7 +2803,7 @@ >X * Most of the code here is just for sanity cross-checking that the given >X * expression actually matches the index column it's claimed to. >X */ >X-static Node * >X+Node * >X fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol) >X { >X Var *result; >Xdiff -ur src/backend/optimizer/plan/setrefs.c src/backend/optimizer/plan/setrefs.c >X--- src/backend/optimizer/plan/setrefs.c 2014-07-21 22:12:31.000000000 +0300 >X+++ src/backend/optimizer/plan/setrefs.c 2015-01-14 23:09:30.000000000 +0200 >X@@ -1553,6 +1553,10 @@ >X { >X Var *var = (Var *) node; >X >X+ /* join_references_mutator already checks this node */ >X+ if ( var->varno == OUTER_VAR ) >X+ return (Node*)copyObject(var); >X+ >X /* First look for the var in the input tlists */ >X newvar = search_indexed_tlist_for_var(var, >X context->outer_itlist, >X@@ -1562,6 +1566,9 @@ >X return (Node *) newvar; >X if (context->inner_itlist) >X { >X+ if ( var->varno == INNER_VAR ) >X+ return (Node*)copyObject(var); >X+ >X newvar = search_indexed_tlist_for_var(var, >X context->inner_itlist, >X INNER_VAR, >Xdiff -ur src/backend/optimizer/util/pathnode.c src/backend/optimizer/util/pathnode.c >X--- src/backend/optimizer/util/pathnode.c 2014-07-21 22:12:31.000000000 +0300 >X+++ src/backend/optimizer/util/pathnode.c 2015-01-14 23:14:26.000000000 +0200 >X@@ -923,7 +923,7 @@ >X * Note that we must handle subpaths = NIL, representing a dummy access path. >X */ >X AppendPath * >X-create_append_path(RelOptInfo *rel, List *subpaths, Relids required_outer) >X+create_append_path(RelOptInfo *rel, List *subpaths, Relids required_outer, bool pull_tlist, List *pathkeys) >X { >X AppendPath *pathnode = makeNode(AppendPath); >X ListCell *l; >X@@ -932,8 +932,10 @@ >X pathnode->path.parent = rel; >X pathnode->path.param_info = get_appendrel_parampathinfo(rel, >X required_outer); >X- pathnode->path.pathkeys = NIL; /* result is always considered >X- * unsorted */ >X+ pathnode->path.pathkeys = pathkeys; /* !=NIL in case of append OR index scans */ >X+ >X+ pathnode->subpaths = subpaths; >X+ pathnode->pull_tlist = pull_tlist; >X pathnode->subpaths = subpaths; >X >X /* >Xdiff -ur src/backend/parser/gram.y src/backend/parser/gram.y >X--- src/backend/parser/gram.y 2014-07-21 22:12:31.000000000 +0300 >X+++ src/backend/parser/gram.y 2015-01-14 23:22:03.000000000 +0200 >X@@ -10164,7 +10164,7 @@ >X | a_expr LIKE a_expr ESCAPE a_expr >X { >X FuncCall *n = makeNode(FuncCall); >X- n->funcname = SystemFuncName("like_escape"); >X+ n->funcname = list_make1(makeString("like_escape")); >X n->args = list_make2($3, $5); >X n->agg_order = NIL; >X n->agg_star = FALSE; >X@@ -10179,7 +10179,7 @@ >X | a_expr NOT LIKE a_expr ESCAPE a_expr >X { >X FuncCall *n = makeNode(FuncCall); >X- n->funcname = SystemFuncName("like_escape"); >X+ n->funcname = list_make1(makeString("like_escape")); >X n->args = list_make2($4, $6); >X n->agg_order = NIL; >X n->agg_star = FALSE; >X@@ -10194,7 +10194,7 @@ >X | a_expr ILIKE a_expr ESCAPE a_expr >X { >X FuncCall *n = makeNode(FuncCall); >X- n->funcname = SystemFuncName("like_escape"); >X+ n->funcname = list_make1(makeString("like_escape")); >X n->args = list_make2($3, $5); >X n->agg_order = NIL; >X n->agg_star = FALSE; >X@@ -10209,7 +10209,7 @@ >X | a_expr NOT ILIKE a_expr ESCAPE a_expr >X { >X FuncCall *n = makeNode(FuncCall); >X- n->funcname = SystemFuncName("like_escape"); >X+ n->funcname = list_make1(makeString("like_escape")); >X n->args = list_make2($4, $6); >X n->agg_order = NIL; >X n->agg_star = FALSE; >X@@ -10223,7 +10223,7 @@ >X | a_expr SIMILAR TO a_expr %prec SIMILAR >X { >X FuncCall *n = makeNode(FuncCall); >X- n->funcname = SystemFuncName("similar_escape"); >X+ n->funcname = list_make1(makeString("similar_escape")); >X n->args = list_make2($4, makeNullAConst(-1)); >X n->agg_order = NIL; >X n->agg_star = FALSE; >X@@ -10236,7 +10236,7 @@ >X | a_expr SIMILAR TO a_expr ESCAPE a_expr >X { >X FuncCall *n = makeNode(FuncCall); >X- n->funcname = SystemFuncName("similar_escape"); >X+ n->funcname = list_make1(makeString("similar_escape")); >X n->args = list_make2($4, $6); >X n->agg_order = NIL; >X n->agg_star = FALSE; >X@@ -10249,7 +10249,7 @@ >X | a_expr NOT SIMILAR TO a_expr %prec SIMILAR >X { >X FuncCall *n = makeNode(FuncCall); >X- n->funcname = SystemFuncName("similar_escape"); >X+ n->funcname = list_make1(makeString("similar_escape")); >X n->args = list_make2($5, makeNullAConst(-1)); >X n->agg_order = NIL; >X n->agg_star = FALSE; >X@@ -10262,7 +10262,7 @@ >X | a_expr NOT SIMILAR TO a_expr ESCAPE a_expr >X { >X FuncCall *n = makeNode(FuncCall); >X- n->funcname = SystemFuncName("similar_escape"); >X+ n->funcname = list_make1(makeString("similar_escape")); >X n->args = list_make2($5, $7); >X n->agg_order = NIL; >X n->agg_star = FALSE; >Xdiff -ur src/include/nodes/relation.h src/include/nodes/relation.h >X--- src/include/nodes/relation.h 2014-07-21 22:12:31.000000000 +0300 >X+++ src/include/nodes/relation.h 2015-01-14 23:27:59.000000000 +0200 >X@@ -868,6 +868,11 @@ >X { >X Path path; >X List *subpaths; /* list of component Paths */ >X+ bool pull_tlist; /* if = true, create_append_plan() >X+ should get targetlist from any >X+ subpath - they are the same, >X+ because the only place - append >X+ index scan for range OR */ >X } AppendPath; >X >X #define IS_DUMMY_PATH(p) \ >Xdiff -ur src/include/optimizer/pathnode.h src/include/optimizer/pathnode.h >X--- src/include/optimizer/pathnode.h 2014-07-21 22:12:31.000000000 +0300 >X+++ src/include/optimizer/pathnode.h 2015-01-14 23:30:04.000000000 +0200 >X@@ -57,7 +57,7 @@ >X extern TidPath *create_tidscan_path(PlannerInfo *root, RelOptInfo *rel, >X List *tidquals); >X extern AppendPath *create_append_path(RelOptInfo *rel, List *subpaths, >X- Relids required_outer); >X+ Relids required_outer, bool pull_tlist, List *pathkeys); >X extern MergeAppendPath *create_merge_append_path(PlannerInfo *root, >X RelOptInfo *rel, >X List *subpaths, >Xdiff -ur src/include/optimizer/paths.h src/include/optimizer/paths.h >X--- src/include/optimizer/paths.h 2014-07-21 22:12:31.000000000 +0300 >X+++ src/include/optimizer/paths.h 2015-01-14 23:32:58.000000000 +0200 >X@@ -69,6 +69,7 @@ >X * additional routines for indexable OR clauses >X */ >X extern bool create_or_index_quals(PlannerInfo *root, RelOptInfo *rel); >X+extern void keybased_rewrite_index_paths(PlannerInfo *root, RelOptInfo *rel); >X >X /* >X * tidpath.h >X@@ -186,6 +187,7 @@ >X extern List *make_inner_pathkeys_for_merge(PlannerInfo *root, >X List *mergeclauses, >X List *outer_pathkeys); >X+extern int pathkeys_useful_for_ordering(PlannerInfo *root, List *pathkeys); >X extern List *truncate_useless_pathkeys(PlannerInfo *root, >X RelOptInfo *rel, >X List *pathkeys); >Xdiff -ur src/include/optimizer/planmain.h src/include/optimizer/planmain.h >X--- src/include/optimizer/planmain.h 2014-07-21 22:12:31.000000000 +0300 >X+++ src/include/optimizer/planmain.h 2015-01-14 23:36:49.000000000 +0200 >X@@ -87,7 +87,7 @@ >X List *resultRelations, List *subplans, List *returningLists, >X List *rowMarks, int epqParam); >X extern bool is_projection_capable_plan(Plan *plan); >X- >X+extern Node * fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol); >X /* >X * prototypes for plan/initsplan.c >X */ >Xdiff -ur src/test/regress/expected/create_index.out src/test/regress/expected/create_index.out >X--- src/test/regress/expected/create_index.out 2014-07-21 22:12:31.000000000 +0300 >X+++ src/test/regress/expected/create_index.out 2015-01-14 23:39:30.000000000 +0200 >X@@ -2625,18 +2625,12 @@ >X EXPLAIN (COSTS OFF) >X SELECT * FROM tenk1 >X WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42); >X- QUERY PLAN >X------------------------------------------------------------------------------------------------------------------------------------------ >X- Bitmap Heap Scan on tenk1 >X- Recheck Cond: (((thousand = 42) AND (tenthous = 1)) OR ((thousand = 42) AND (tenthous = 3)) OR ((thousand = 42) AND (tenthous = 42))) >X- -> BitmapOr >X- -> Bitmap Index Scan on tenk1_thous_tenthous >X- Index Cond: ((thousand = 42) AND (tenthous = 1)) >X- -> Bitmap Index Scan on tenk1_thous_tenthous >X- Index Cond: ((thousand = 42) AND (tenthous = 3)) >X- -> Bitmap Index Scan on tenk1_thous_tenthous >X- Index Cond: ((thousand = 42) AND (tenthous = 42)) >X-(9 rows) >X+ QUERY PLAN >X+----------------------------------------------------------------- >X+ Index Scan using tenk1_thous_tenthous on tenk1 >X+ Index Cond: ((thousand = 42) AND (thousand = 42)) >X+ Filter: ((tenthous = 1) OR (tenthous = 3) OR (tenthous = 42)) >X+(3 rows) >X >X SELECT * FROM tenk1 >X WHERE thousand = 42 AND (tenthous = 1 OR tenthous = 3 OR tenthous = 42); >Xdiff -ur src/test/regress/expected/select.out src/test/regress/expected/select.out >X--- src/test/regress/expected/select.out 2014-07-21 22:12:31.000000000 +0300 >X+++ src/test/regress/expected/select.out 2015-01-14 23:44:41.000000000 +0200 >X@@ -518,6 +518,124 @@ >X (9 rows) >X >X -- >X+-- test order by NULLS (FIRST|LAST) >X+-- >X+select unique1, unique2 into onek_with_null from onek; >X+insert into onek_with_null (unique1,unique2) values (NULL, -1), (NULL, NULL); >X+select * from onek_with_null order by unique1 nulls first , unique2 limit 3; >X+ unique1 | unique2 >X+---------+--------- >X+ | -1 >X+ | >X+ 0 | 998 >X+(3 rows) >X+ >X+select * from onek_with_null order by unique1 nulls last , unique2 limit 3; >X+ unique1 | unique2 >X+---------+--------- >X+ 0 | 998 >X+ 1 | 214 >X+ 2 | 326 >X+(3 rows) >X+ >X+select * from onek_with_null order by unique1 nulls first , unique2 nulls first limit 3; >X+ unique1 | unique2 >X+---------+--------- >X+ | >X+ | -1 >X+ 0 | 998 >X+(3 rows) >X+ >X+select * from onek_with_null order by unique1 nulls last , unique2 nulls first limit 3; >X+ unique1 | unique2 >X+---------+--------- >X+ 0 | 998 >X+ 1 | 214 >X+ 2 | 326 >X+(3 rows) >X+ >X+select * from onek_with_null order by unique1 nulls first , unique2 nulls last limit 3; >X+ unique1 | unique2 >X+---------+--------- >X+ | -1 >X+ | >X+ 0 | 998 >X+(3 rows) >X+ >X+select * from onek_with_null order by unique1 nulls last , unique2 nulls last limit 3; >X+ unique1 | unique2 >X+---------+--------- >X+ 0 | 998 >X+ 1 | 214 >X+ 2 | 326 >X+(3 rows) >X+ >X+select * from onek_with_null order by unique1 desc nulls first , unique2 desc limit 3; >X+ unique1 | unique2 >X+---------+--------- >X+ | >X+ | -1 >X+ 999 | 152 >X+(3 rows) >X+ >X+select * from onek_with_null order by unique1 desc nulls last , unique2 desc limit 3; >X+ unique1 | unique2 >X+---------+--------- >X+ 999 | 152 >X+ 998 | 549 >X+ 997 | 21 >X+(3 rows) >X+ >X+select * from onek_with_null order by unique1 desc nulls first , unique2 desc nulls first limit 3; >X+ unique1 | unique2 >X+---------+--------- >X+ | >X+ | -1 >X+ 999 | 152 >X+(3 rows) >X+ >X+select * from onek_with_null order by unique1 desc nulls last , unique2 desc nulls first limit 3; >X+ unique1 | unique2 >X+---------+--------- >X+ 999 | 152 >X+ 998 | 549 >X+ 997 | 21 >X+(3 rows) >X+ >X+select * from onek_with_null order by unique1 desc nulls first , unique2 desc nulls last limit 3; >X+ unique1 | unique2 >X+---------+--------- >X+ | -1 >X+ | >X+ 999 | 152 >X+(3 rows) >X+ >X+select * from onek_with_null order by unique1 desc nulls last , unique2 desc nulls last limit 3; >X+ unique1 | unique2 >X+---------+--------- >X+ 999 | 152 >X+ 998 | 549 >X+ 997 | 21 >X+(3 rows) >X+ >X+select unique1 as u1, unique2 as u2 from onek_with_null order by u1 nulls first , u2 nulls first limit 3; >X+ u1 | u2 >X+----+----- >X+ | >X+ | -1 >X+ 0 | 998 >X+(3 rows) >X+ >X+select unique1 as u1, unique2 as u2 from onek_with_null order by u1 asc nulls first , u2 desc nulls first limit 3; >X+ u1 | u2 >X+----+----- >X+ | >X+ | -1 >X+ 0 | 998 >X+(3 rows) >X+ >X+drop table onek_with_null; >X+-- >X -- Test ORDER BY options >X -- >X CREATE TEMP TABLE foo (f1 int); >Xdiff -ur src/test/regress/sql/select.sql src/test/regress/sql/select.sql >X--- src/test/regress/sql/select.sql 2014-07-21 22:12:31.000000000 +0300 >X+++ src/test/regress/sql/select.sql 2015-01-14 23:47:00.000000000 +0200 >X@@ -149,6 +149,33 @@ >X TABLE int8_tbl; >X >X -- >X+-- test order by NULLS (FIRST|LAST) >X+-- >X+ >X+select unique1, unique2 into onek_with_null from onek; >X+insert into onek_with_null (unique1,unique2) values (NULL, -1), (NULL, NULL); >X+ >X+ >X+select * from onek_with_null order by unique1 nulls first , unique2 limit 3; >X+select * from onek_with_null order by unique1 nulls last , unique2 limit 3; >X+select * from onek_with_null order by unique1 nulls first , unique2 nulls first limit 3; >X+select * from onek_with_null order by unique1 nulls last , unique2 nulls first limit 3; >X+select * from onek_with_null order by unique1 nulls first , unique2 nulls last limit 3; >X+select * from onek_with_null order by unique1 nulls last , unique2 nulls last limit 3; >X+ >X+select * from onek_with_null order by unique1 desc nulls first , unique2 desc limit 3; >X+select * from onek_with_null order by unique1 desc nulls last , unique2 desc limit 3; >X+select * from onek_with_null order by unique1 desc nulls first , unique2 desc nulls first limit 3; >X+select * from onek_with_null order by unique1 desc nulls last , unique2 desc nulls first limit 3; >X+select * from onek_with_null order by unique1 desc nulls first , unique2 desc nulls last limit 3; >X+select * from onek_with_null order by unique1 desc nulls last , unique2 desc nulls last limit 3; >X+ >X+select unique1 as u1, unique2 as u2 from onek_with_null order by u1 nulls first , u2 nulls first limit 3; >X+select unique1 as u1, unique2 as u2 from onek_with_null order by u1 asc nulls first , u2 desc nulls first limit 3; >X+ >X+drop table onek_with_null; >X+ >X+-- >X -- Test ORDER BY options >X -- >X >Xdiff -ur src/tools/msvc/Mkvcbuild.pm src/tools/msvc/Mkvcbuild.pm >X--- src/tools/msvc/Mkvcbuild.pm 2014-07-21 22:12:31.000000000 +0300 >X+++ src/tools/msvc/Mkvcbuild.pm 2015-01-14 23:48:48.000000000 +0200 >X@@ -35,7 +35,7 @@ >X 'pg_standby', 'pg_archivecleanup', >X 'pg_test_fsync', 'pg_test_timing', >X 'pg_upgrade', 'vacuumlo'); >X-my $contrib_extralibs = { 'pgbench' => ['wsock32.lib'] }; >X+my $contrib_extralibs = { 'pgbench' => ['wsock32.lib'], 'mchar' => ['icuin.lib', 'icuuc.lib'] }; >X my $contrib_extraincludes = >X { 'tsearch2' => ['contrib/tsearch2'], 'dblink' => ['src/backend'] }; >X my $contrib_extrasource = { >0bcb39c9431c594561482fe120de68b6 >echo x - postgresql92-1c/distinfo >sed 's/^X//' >postgresql92-1c/distinfo << 'b7f561cbd0455dcbe22909444aa0871a' >XSHA256 (postgresql/postgresql-9.2.13.tar.bz2) = 5dcbd6209a8c0f508504fa433486583a42caaa240c823e1b3576db8a72db6a44 >XSIZE (postgresql/postgresql-9.2.13.tar.bz2) = 16401289 >XSHA256 (postgresql/pg-929-icu-2015-04-18.diff.gz) = 9aff1ba25fbe5892a3868bff516df685531c85901c360548e38bf2e5fa0e14ab >XSIZE (postgresql/pg-929-icu-2015-04-18.diff.gz) = 4469 >b7f561cbd0455dcbe22909444aa0871a >echo x - postgresql92-1c/Makefile >sed 's/^X//' >postgresql92-1c/Makefile << '01e32f40e053120fb028eb524a3d6b30' >X# $FreeBSD$ >X >XPORTNAME= postgresql >XDISTVERSION= 9.2.13 >XPORTREVISION?= 0 >XCATEGORIES= databases >XMASTER_SITES= PGSQL >XMASTER_SITE_SUBDIR= source/v${DISTVERSION} >XPKGNAMESUFFIX?= ${DISTVERSION:R:S/.//}-1C >X >XMAINTAINER= kotadr@gmail.com >XCOMMENT= Database server for business applications platform 1C: Enterprise >X >XCONFLICTS?= ${PORTNAME}-client-[^${PORTVERSION:R:R}].* \ >X ${PORTNAME}-client-9.[^${PORTVERSION:R:E}].* \ >X ${PORTNAME}-contrib-[^${PORTVERSION:R:R}].* \ >X ${PORTNAME}-contrib-9.[^${PORTVERSION:R:E}].* \ >X ${PORTNAME}-server-[^${PORTVERSION:R:R}].* \ >X ${PORTNAME}-server-9.[^${PORTVERSION:R:E}].* >X >XWRKSRC= ${WRKDIR}/postgresql-${DISTVERSION} >XDIST_SUBDIR= postgresql >X >XICU_PATCHFILE?= pg-929-icu-2015-04-18.diff.gz >X >XPKGINSTALL?= ${PKGDIR}/pkg-install >XUSES+= bison readline tar:bzip2 >XUSE_LDCONFIG= yes >X >X.if !defined(NO_BUILD) >XUSES+= gmake >XGNU_CONFIGURE= yes >X.endif >X >XPG_USER= pgsql >XPG_GROUP= pgsql >XPG_UID= 70 >X >XLDFLAGS+= -L${LOCALBASE}/lib ${PTHREAD_LIBS} -L${PREFIX}/lib >XINCLUDES+= -I${LOCALBASE}/include >XCONFIGURE_ARGS+=--with-libraries=${PREFIX}/lib \ >X --with-includes=${PREFIX}/include --enable-thread-safety \ >X --with-libxslt --with-libxml --with-openssl >X >XCONFIGURE_ENV+= INCLUDES="${INCLUDES}" \ >X PTHREAD_CFLAGS="${PTHREAD_CFLAGS}" \ >X PTHREAD_LIBS="${PTHREAD_LIBS}" \ >X LDFLAGS_SL="${LDFLAGS_SL}" >XCFLAGS+= ${PTHREAD_CFLAGS} >X >XPLIST= ${PKGDIR}/pkg-plist >X >XINSTALL_DIRS?= config src/include src/interfaces src/port src/bin/pg_dump \ >X src/bin/psql src/bin/scripts src/bin/pg_config doc \ >X src/makefiles src/timezone src/backend \ >X src/backend/utils/mb/conversion_procs src/backend/snowball \ >X src/backend/replication/libpqwalreceiver src/bin/initdb \ >X src/bin/pg_ctl src/bin/pg_controldata src/bin/pg_resetxlog \ >X src/pl src/bin/pg_basebackup src/port contrib >XBUILD_DIRS?= ${INSTALL_DIRS} >X >XLIB_DEPENDS+= libxslt.so:${PORTSDIR}/textproc/libxslt \ >X libxml2.so:${PORTSDIR}/textproc/libxml2 >X >XUSE_RC_SUBR= postgresql >XUSERS= ${PG_USER} >XGROUPS= ${PG_GROUP} >XSUB_FILES+= 502.pgsql >X >XMAKE_ENV= PATH=${PREFIX}/bin:${PATH} >XCONFIGURE_ENV+= PATH=${PREFIX}/bin:${PATH} >X >XOPTIONS_DEFINE+= NLS DTRACE PAM LDAP GSSAPI OPT_CFLAGS TZDATA DEBUG >X >XNLS_DESC= Use internationalized messages >XDTRACE_DESC= Build with DTrace probes >XPAM_DESC= Build with PAM Support >XLDAP_DESC= Build with LDAP authentication support >XGSSAPI_DESC= Build with GSSAPI support >XOPT_CFLAGS_DESC= Builds with compiler optimizations (-O3) >XTZDATA_DESC= Use internal timezone database >XDEBUG_DESC= Builds with debugging symbols >X >X# See http://people.freebsd.org/~girgen/postgresql-icu/README.html for more info >XOPTIONS_DEFINE+= ICU >XICU_DESC= Use ICU for unicode collation >X >X# See http://www.freebsd.org/cgi/query-pr.cgi?pr=ports/76999 for more info >X# (requires dump/restore if modified.) >XOPTIONS_DEFINE+= INTDATE >XINTDATE_DESC= Builds with 64-bit date/time type (for 1C > 8.3.2) >X >XOPTIONS_DEFINE+= SSL >XSSL_DESC= Build with OpenSSL support >X >XOPTIONS_DEFAULT= NLS TZDATA SSL ICU >X >X.include <bsd.port.options.mk> >X >X.if ${PORT_OPTIONS:MSSL} >XUSE_OPENSSL= yes >XCONFIGURE_ARGS+=--with-openssl >X.endif >X >X.if ${PORT_OPTIONS:MICU} || make(makesum) >XUSE_AUTOTOOLS= autoconf >XCONFIGURE_ARGS+=--with-icu >XPATCH_SITES+= http://people.freebsd.org/~girgen/postgresql-icu/:icu >XPATCHFILES+= ${ICU_PATCHFILE}:icu >XLIB_DEPENDS+= libicudata.so:${PORTSDIR}/devel/icu >X.endif >X >XPATCH_DIST_STRIP=-p1 >X >X. if ${PORT_OPTIONS:MDTRACE} >XCONFIGURE_ARGS+=--enable-dtrace >XLDFLAGS+=-lelf >X. if ${OSVERSION} < 900021 >XIGNORE= need userland DTrace support found in FreeBSD 9.0 >X. endif >X. endif >X >X. if ${PORT_OPTIONS:MPAM} >XCONFIGURE_ARGS+=--with-pam >X. endif >X >X. if ${PORT_OPTIONS:MLDAP} >X. if defined (SERVER_ONLY) >XCONFIGURE_ARGS+=--with-ldap >XUSE_OPENLDAP= yes >X. endif >X. endif >X >X. if ${PORT_OPTIONS:MTZDATA} >XPLIST_SUB+= TZDATA="" >X. else >XCONFIGURE_ARGS+=--with-system-tzdata=/usr/share/zoneinfo >XPLIST_SUB+= TZDATA="@comment " >X. endif >X >X. if empty(PORT_OPTIONS:MINTDATE) >XCONFIGURE_ARGS+=--disable-integer-datetimes >X. endif >X >X. if ${PORT_OPTIONS:MNLS} >XCONFIGURE_ARGS+=--enable-nls >XPLIST_SUB+= GETTEXT="" >XUSES+= gettext >X. else >XCONFIGURE_ARGS+=--disable-nls >XPLIST_SUB+= GETTEXT="@comment " >X. endif >X >X. if ${PORT_OPTIONS:MOPT_CFLAGS} >XCFLAGS+= -O3 -funroll-loops >X. endif >X >X. if ${PORT_OPTIONS:MDEBUG} >XCONFIGURE_ARGS+=--enable-debug >XINSTALL_TARGET= install >X. else >XINSTALL_TARGET= install-strip >X. endif >X >X.if ${PORT_OPTIONS:MGSSAPI} >XCONFIGURE_ARGS+=--with-gssapi >XLDFLAGS+= -lgssapi >XLDFLAGS_SL+= -lgssapi >X.else >XCONFIGURE_ARGS+=--without-gssapi >X.endif >X >XPLIST_SUB+= PG_USER=${PG_USER} \ >X PG_GROUP=${PG_GROUP} >XSUB_LIST+= PG_GROUP=${PG_GROUP} \ >X PG_USER=${PG_USER} \ >X PG_UID=${PG_UID} >X >X# For testing files in FILESDIR >X.include <bsd.port.pre.mk> >X >Xpre-build: >X @${SH} ${PKGINSTALL} ${PORTNAME} PRE-INSTALL >X >X.if !defined(NO_BUILD) && !target(do-build) >X >Xdo-build: >X @ cd ${WRKSRC}/src/backend && ${SETENV} ${MAKE_ENV} ${MAKE_CMD} symlinks >X @ for dir in ${BUILD_DIRS}; do \ >X cd ${WRKSRC}/$${dir} && ${SETENV} ${MAKE_ENV} ${MAKE_CMD}; \ >X done >X >X. if exists(${FILESDIR}/pkg-message.in) >XSUB_FILES+= pkg-message >XPKGMESSAGE= ${WRKSRC}/pkg-message >X. endif >X >Xpost-patch: >X. if ${PORT_OPTIONS:MICU} >X @${REINPLACE_CMD} -E -e \ >X "s|^(m4_if.*)2.6[0-9](.*Autoconf version )2.6[0-9]|\1${AUTOCONF_VERSION}\2${AUTOCONF_VERSION}|g" \ >X ${WRKSRC}/configure.in >X. endif >X >Xdo-install: >X @for dir in ${INSTALL_DIRS}; do \ >X cd ${WRKSRC}/$${dir} && \ >X ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} ${INSTALL_TARGET}; \ >X done >X @ ${MKDIR} ${STAGEDIR}${PREFIX}/share/postgresql ;\ >X ${MKDIR} ${STAGEDIR}${PREFIX}/etc/periodic/daily ;\ >X ${INSTALL_SCRIPT} ${WRKDIR}/502.pgsql \ >X ${STAGEDIR}${PREFIX}/etc/periodic/daily >X ${MKDIR} ${STAGEDIR}${PREFIX}/${PG_USER} >X ${MKDIR} ${STAGEDIR}/usr/share/locale >X ${LN} -sf /usr/share/locale/en_US.UTF-8 ${STAGEDIR}/usr/share/locale/en_US >X @ cd ${WRKSRC}/src && ${SETENV} ${MAKE_ENV} ${MAKE_CMD} ${MAKE_ARGS} install-local >X @ if [ -r ${PKGMESSAGE} ]; then \ >X ${MKDIR} ${STAGEDIR}${DOCSDIR} ;\ >X ${INSTALL_DATA} ${PKGMESSAGE} ${STAGEDIR}${DOCSDIR}/README ;\ >X fi >X.endif # !NO_BUILD >X >Xpost-install: >X @- ${INSTALL_DATA} ${WRKSRC}/contrib/README ${STAGEDIR}${DOCSDIR}/extension/README >X >Xcheck: >X @if [ `id -u` != 0 ] ; then \ >X ${ECHO} "Running postgresql regressions tests" ;\ >X cd ${WRKSRC}; ${MAKE_CMD} check ;\ >X else \ >X ${ECHO} "You cannot run regression tests when postgresql is built as user root." ; \ >X ${ECHO} "Clean and rebuild the port as a regular user to run the tests." ;\ >X fi >X >X.include <bsd.port.post.mk> >01e32f40e053120fb028eb524a3d6b30 >echo x - postgresql92-1c/pkg-install >sed 's/^X//' >postgresql92-1c/pkg-install << '70597793d073c107f3fab95852c34c4f' >X#! /bin/sh >X >X# $FreeBSD: tags/RELEASE_10_1_0/databases/postgresql92-server/pkg-install-server 340719 2014-01-22 15:52:06Z mat $ >X >XPATH=/bin:/usr/bin:/usr/sbin >X >Xbackupwarning() { >Xcat <<EOF >X >X ======================= BACKUP YOUR DATA! ========================= >X As always, backup your data before upgrading. If the upgrade leads >X to a higher minor revision (e.g. 9.1.x -> 9.2), a dump and restore >X of all databases is required. This is *NOT* done by the port! >X >X Press ctrl-C *now* if you need to pg_dump. >X =================================================================== >XEOF >X sleep 5 >X} >X >Xcase $2 in >XPRE-INSTALL) >X backupwarning >X ;; >Xesac >70597793d073c107f3fab95852c34c4f >echo x - postgresql92-1c/pkg-descr >sed 's/^X//' >postgresql92-1c/pkg-descr << '511cc9ab950dee2c4c4a443b5f02c151' >XPostgreSQL database server with additional patches to work with business >Xapplications platform 1C:Enterprise: >X >X - Patch contains additional expansion modules and the >X necessary changes to the database, adding the >X functionality needed to work with 1C: Enterprise server >X - Patch modifies the startup / shutdown scripts and >X configuration files PostgreSQL to improve performance when >X working with 1C: Enterprise server >X - Patch fixes the problem by using locks AUTOVACUUM >X - Patch for gathering statistics on tables immediately after >X the operations INSERT / UPDATE / DELETE / SELECT INTO. >X - Patch for evaluation optimizer number of rows in the table >X is empty >X >XThis port is unofficial and developer 1C Company does not have any relation >Xto it. Work software 1C with the FreeBSD operating system officially is not >Xsupported and has not been tested. >511cc9ab950dee2c4c4a443b5f02c151 >exit >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 197992
:
153446
| 157775